예제 #1
0
        public override ExpressionNode VisitUnaryExpression(UnaryExpression expression)
        {
            base.VisitUnaryExpression(expression);

            ConstantExpression operandAsConstant = expression.Operand as ConstantExpression;

            if (operandAsConstant != null)
            {
                // Ok, lets compute the result

                if (operandAsConstant.IsNullValue)
                {
                    return(LiteralExpression.FromTypedNull(expression.ExpressionType));
                }

                try
                {
                    return(LiteralExpression.FromTypedValue(expression.GetValue(), expression.ExpressionType));
                }
                catch (RuntimeException ex)
                {
                    _errorReporter.CannotFoldConstants(ex);
                }
            }

            // If we getting here we return the orginal one.

            return(expression);
        }
예제 #2
0
        public override ExpressionNode VisitCastExpression(CastExpression expression)
        {
            base.VisitCastExpression(expression);

            if (!Binder.ConversionNeeded(expression.Expression.ExpressionType, expression.ExpressionType))
            {
                return(expression.Expression);
            }

            ConstantExpression expressionAsConstant = expression.Expression as ConstantExpression;

            if (expressionAsConstant != null)
            {
                if (expressionAsConstant.IsNullValue)
                {
                    return(LiteralExpression.FromTypedNull(expression.ExpressionType));
                }

                try
                {
                    return(LiteralExpression.FromTypedValue(expression.GetValue(), expression.ExpressionType));
                }
                catch (RuntimeException ex)
                {
                    _errorReporter.CannotFoldConstants(ex);
                }
            }

            return(expression);
        }
예제 #3
0
        private static AlgebraNode PadLeftWithNullsOnRightSide(JoinAlgebraNode node, RowBufferCreationMode rowBufferCreationMode)
        {
            ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();

            computeScalarAlgebraNode.Input = node.Left;

            List <RowBufferEntry> outputList = new List <RowBufferEntry>();

            outputList.AddRange(node.Left.OutputList);

            List <ComputedValueDefinition> definedValues = new List <ComputedValueDefinition>();

            foreach (RowBufferEntry rowBufferEntry in node.Right.OutputList)
            {
                ComputedValueDefinition definedValue = new ComputedValueDefinition();

                if (rowBufferCreationMode == RowBufferCreationMode.KeepExisting)
                {
                    definedValue.Target = rowBufferEntry;
                }
                else
                {
                    definedValue.Target = new RowBufferEntry(rowBufferEntry.DataType);
                }

                definedValue.Expression = LiteralExpression.FromTypedNull(rowBufferEntry.DataType);
                definedValues.Add(definedValue);
                outputList.Add(definedValue.Target);
            }

            computeScalarAlgebraNode.DefinedValues = definedValues.ToArray();
            computeScalarAlgebraNode.OutputList    = outputList.ToArray();

            return(computeScalarAlgebraNode);
        }
예제 #4
0
        private ExpressionNode ConvertExpressionIfRequired(ExpressionNode expression, Type targetType, bool enableDownCast)
        {
            if (expression.ExpressionType == typeof(DBNull))
            {
                return(LiteralExpression.FromTypedNull(targetType));
            }

            if (ConversionNeeded(expression.ExpressionType, targetType))
            {
                MethodInfo methodInfo = GetImplicitConversionMethod(expression.ExpressionType, targetType);

                if (methodInfo == null)
                {
                    methodInfo = GetExplicitConversionMethod(expression.ExpressionType, targetType);
                }

                if (methodInfo != null)
                {
                    CastExpression result = new CastExpression(expression, targetType);
                    result.ConvertMethod = methodInfo;
                    return(result);
                }

                if (enableDownCast && AllowsDownCast(expression.ExpressionType, targetType))
                {
                    CastExpression result = new CastExpression(expression, targetType);
                    return(result);
                }

                // Conversion not possible, report an error.
                _errorReporter.CannotCast(expression, targetType);
            }

            return(expression);
        }
예제 #5
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            base.VisitJoinAlgebraNode(node);

            if (node.Op == JoinAlgebraNode.JoinOperator.FullOuterJoin)
            {
                // TODO: Check if we could represent this join condition by an hash match operator

                JoinAlgebraNode leftOuterJoinNode = new JoinAlgebraNode();
                leftOuterJoinNode.Op         = JoinAlgebraNode.JoinOperator.LeftOuterJoin;
                leftOuterJoinNode.Predicate  = (ExpressionNode)node.Predicate.Clone();
                leftOuterJoinNode.Left       = (AlgebraNode)node.Left.Clone();
                leftOuterJoinNode.Right      = (AlgebraNode)node.Right.Clone();
                leftOuterJoinNode.OutputList = ArrayHelpers.Clone(node.OutputList);

                List <RowBufferEntry> swappedOutputList = new List <RowBufferEntry>();
                swappedOutputList.AddRange(node.Right.OutputList);
                swappedOutputList.AddRange(node.Left.OutputList);

                JoinAlgebraNode leftAntiSemiJoinNode = new JoinAlgebraNode();
                leftAntiSemiJoinNode.Op         = JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin;
                leftAntiSemiJoinNode.Predicate  = (ExpressionNode)node.Predicate.Clone();
                leftAntiSemiJoinNode.Left       = (AlgebraNode)node.Right.Clone();
                leftAntiSemiJoinNode.Right      = (AlgebraNode)node.Left.Clone();
                leftAntiSemiJoinNode.OutputList = swappedOutputList.ToArray();

                List <ComputedValueDefinition> computeScalareDefinedValues = new List <ComputedValueDefinition>();
                foreach (RowBufferEntry rowBufferEntry in node.Left.OutputList)
                {
                    ComputedValueDefinition definedValue = new ComputedValueDefinition();
                    definedValue.Target     = rowBufferEntry;
                    definedValue.Expression = LiteralExpression.FromTypedNull(rowBufferEntry.DataType);
                    computeScalareDefinedValues.Add(definedValue);
                }

                ComputeScalarAlgebraNode computeScalarNode = new ComputeScalarAlgebraNode();
                computeScalarNode.Input         = leftAntiSemiJoinNode;
                computeScalarNode.DefinedValues = computeScalareDefinedValues.ToArray();
                computeScalarNode.OutputList    = swappedOutputList.ToArray();

                List <UnitedValueDefinition> concatDefinedValues = new List <UnitedValueDefinition>();
                for (int i = 0; i < node.OutputList.Length; i++)
                {
                    RowBufferEntry        rowBufferEntry     = node.OutputList[i];
                    UnitedValueDefinition concatDefinedValue = new UnitedValueDefinition();
                    concatDefinedValue.Target           = rowBufferEntry;
                    concatDefinedValue.DependendEntries = new RowBufferEntry[] { node.OutputList[i], node.OutputList[i] };
                    concatDefinedValues.Add(concatDefinedValue);
                }

                ConcatAlgebraNode concatenationNode = new ConcatAlgebraNode();
                concatenationNode.Inputs        = new AlgebraNode[] { leftOuterJoinNode, computeScalarNode };
                concatenationNode.DefinedValues = concatDefinedValues.ToArray();
                concatenationNode.OutputList    = swappedOutputList.ToArray();

                return(concatenationNode);
            }

            return(node);
        }
예제 #6
0
        public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression)
        {
            base.VisitFunctionInvocationExpression(expression);

            // Constant folding must not be applied if the function is non-deterministic.
            if (!expression.Function.IsDeterministic)
            {
                return(expression);
            }

            // Check if all arguments are constants or at least one argument
            // is null.

            ConstantExpression[] constantArguments = new ConstantExpression[expression.Arguments.Length];
            bool allArgumentsAreConstants          = true;

            for (int i = 0; i < constantArguments.Length; i++)
            {
                constantArguments[i] = expression.Arguments[i] as ConstantExpression;

                if (constantArguments[i] == null)
                {
                    // Ok, one argument is not a constant
                    // But don't stop: If an argument is null we can still calculate the result!
                    allArgumentsAreConstants = false;
                }
                else if (constantArguments[i].IsNullValue)
                {
                    // We found a null. That means the invocation will also yield null.
                    return(LiteralExpression.FromTypedNull(expression.ExpressionType));
                }
            }

            if (allArgumentsAreConstants)
            {
                try
                {
                    return(LiteralExpression.FromTypedValue(expression.GetValue(), expression.ExpressionType));
                }
                catch (RuntimeException ex)
                {
                    _errorReporter.CannotFoldConstants(ex);
                }
            }

            return(expression);
        }
예제 #7
0
        public override ExpressionNode VisitCaseExpression(CaseExpression expression)
        {
            base.VisitCaseExpression(expression);

            // NOTE: It must be a searched CASE. The normalizer should have normalized it already.
            //
            // Remove all WHEN expressions that are allays FALSE or NULL.
            // AND
            // Cut off all WHENs trailing an expression that is always true.

            List <ExpressionNode> whenExpressions = new List <ExpressionNode>();
            List <ExpressionNode> thenExpressions = new List <ExpressionNode>();

            for (int i = 0; i < expression.WhenExpressions.Length; i++)
            {
                if (AstUtil.IsNull(expression.WhenExpressions[i]))
                {
                    // A WHEN expression is always null.
                    continue;
                }

                ConstantExpression whenAsBooleanConstant = expression.WhenExpressions[i] as ConstantExpression;

                if (whenAsBooleanConstant != null)
                {
                    if (!whenAsBooleanConstant.AsBoolean)
                    {
                        // A WHEN expression is always false.
                        //
                        // We remove this part from the case expression by not adding to
                        // whenExpressions and thenExpressions.
                        continue;
                    }
                    else
                    {
                        // A WHEN expression is always true.
                        //
                        // We replace the ELSE expression by the THEN expression and
                        // cut off the rest.

                        expression.ElseExpression = expression.ThenExpressions[i];
                        break;
                    }
                }

                whenExpressions.Add(expression.WhenExpressions[i]);
                thenExpressions.Add(expression.ThenExpressions[i]);
            }

            if (whenExpressions.Count == 0)
            {
                // This means the first WHEN expression was always false
                // or all WHEN expressions are either FALSE or NULL.
                //
                // We replace the case expression by the else expression
                // or by NULL.

                if (expression.ElseExpression != null)
                {
                    return(expression.ElseExpression);
                }

                return(LiteralExpression.FromTypedNull(expression.ExpressionType));
            }

            expression.WhenExpressions = whenExpressions.ToArray();
            expression.ThenExpressions = thenExpressions.ToArray();

            return(expression);
        }