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); }
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); }
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); }
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); }
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); }
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); }
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); }