Пример #1
0
        internal override void PropagateDataTypesForOutSchema()
        {
            // Output for JOIN depends on type of the join
            // For LEFT join, attributes becomes non-nullable
            // For CROSS join or INNER join, attributes type remains unchanged after join
            if (Type == JoinType.Left)
            {
                var prevLeftSchema  = InOperatorLeft.OutputSchema;
                var prevRightSchema = InOperatorRight.OutputSchema;

                var fieldMapping = new Dictionary <Field, Field>();
                foreach (var outField in OutputSchema)
                {
                    var inFieldMatches = InputSchema.Where(f => f.FieldAlias == outField.FieldAlias);
                    Debug.Assert(InputSchema.Where(f => f.FieldAlias == outField.FieldAlias).Count() == 1); // must have match in IN for any OUT field
                    var inField = inFieldMatches.First();
                    // we made it that left schema LEFT OUTTER JOIN with right schema always
                    var isFromRight = !prevLeftSchema.Any(f => f.FieldAlias == inField.FieldAlias);

                    // copy over the schema first
                    outField.Copy(inField);

                    // make adjustment for outter join
                    if (inField is ValueField)
                    {
                        Debug.Assert(outField.GetType() == inField.GetType()); // join doesn't alter field types
                        var outFieldSingleField = outField as ValueField;

                        if (isFromRight && !TypeHelper.CanAssignNullToType(outFieldSingleField.FieldType))
                        {
                            // make it nullable variant of the original type
                            outFieldSingleField.FieldType = TypeHelper.GetNullableTypeForType(outFieldSingleField.FieldType);
                        }
                    }
                    else
                    {
                        Debug.Assert(outField is EntityField);
                        var outEntCapFields = (outField as EntityField).EncapsulatedFields;

                        if (isFromRight)
                        {
                            foreach (var outEntCapField in outEntCapFields)
                            {
                                if (!TypeHelper.CanAssignNullToType(outEntCapField.FieldType))
                                {
                                    // make it nullable variant of the original type
                                    outEntCapField.FieldType = TypeHelper.GetNullableTypeForType(outEntCapField.FieldType);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                base.PropagateDataTypesForOutSchema();
            }
        }
Пример #2
0
        public override Type EvaluateType()
        {
            var innerType = InnerExpression.EvaluateType();
            var canBeNull = TypeHelper.CanAssignNullToType(innerType);

            switch (Function.FunctionName)
            {
            case Common.Function.ToFloat:
                return(canBeNull ? typeof(float?) : typeof(float));

            case Common.Function.ToString:
                return(typeof(string));

            case Common.Function.ToBoolean:
                return(canBeNull ? typeof(bool?) : typeof(bool));

            case Common.Function.ToInteger:
                return(canBeNull ? typeof(int?) : typeof(int));

            case Common.Function.ToDouble:
                return(canBeNull ? typeof(long?) : typeof(long));

            case Common.Function.ToLong:
                return(canBeNull ? typeof(double?) : typeof(double));

            case Common.Function.Not:
                return(canBeNull ? typeof(bool?) : typeof(bool));

            case Common.Function.StringContains:
            case Common.Function.StringStartsWith:
            case Common.Function.StringEndsWith:
            case Common.Function.IsNull:
            case Common.Function.IsNotNull:
                return(typeof(bool));

            case Common.Function.StringSize:
                return(typeof(int));

            default:
                // treat all the rest as type preserving, e.g.
                // trim, ltrim ....
                return(InnerExpression.EvaluateType());
            }
        }