public static List <QueryNode> FlattenBinaryQuery(BinaryQuery binaryQuery) { List <QueryNode> inputList = new List <QueryNode>(); inputList.Add(binaryQuery.Left); inputList.Add(binaryQuery.Right); bool atLeastOneExpanded; do { atLeastOneExpanded = false; for (int i = inputList.Count - 1; i >= 0; i--) { BinaryQuery inputAsBinaryQuery = inputList[i] as BinaryQuery; if (inputAsBinaryQuery != null && inputAsBinaryQuery.Op == binaryQuery.Op) { inputList.RemoveAt(i); inputList.Insert(i, inputAsBinaryQuery.Left); inputList.Insert(i + 1, inputAsBinaryQuery.Right); atLeastOneExpanded = true; } } } while (atLeastOneExpanded); return(inputList); }
private static bool VisitBinaryQuery(BinaryQuery node1, BinaryQuery node2) { return(node2 != null && node1.Op == node2.Op && Visit(node1.Left, node2.Left) && Visit(node1.Right, node2.Right)); }
private QueryNode ParseIntersectionalQuery() { QueryNode leftQuery = ParseSelectQuery(); if (leftQuery == null) { return(null); } while (_token.Id == TokenId.INTERSECT) { NextToken(); QueryNode rightQuery = ParseSelectQuery(); if (rightQuery == null) { return(null); } BinaryQuery binaryQuery = new BinaryQuery(); binaryQuery.Op = BinaryQueryOperator.Intersect; binaryQuery.Left = leftQuery; binaryQuery.Right = rightQuery; leftQuery = binaryQuery; } return(leftQuery); }
public override AstElement Clone(Dictionary<AstElement, AstElement> alreadyClonedElements) { BinaryQuery result = new BinaryQuery(); result.Left = (QueryNode)_left.Clone(alreadyClonedElements); result.Right = (QueryNode)_right.Clone(alreadyClonedElements); result.Op = _op; return result; }
public override AstElement Clone(Dictionary <AstElement, AstElement> alreadyClonedElements) { BinaryQuery result = new BinaryQuery(); result.Left = (QueryNode)_left.Clone(alreadyClonedElements); result.Right = (QueryNode)_right.Clone(alreadyClonedElements); result.Op = _op; return(result); }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { if (query.Op == BinaryQueryOperator.Union) { _containsUnion = true; } return(base.VisitBinaryQuery(query)); }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { _xmlWriter.WriteStartElement("binaryQuery"); _xmlWriter.WriteAttributeString("op", query.Op.ToString()); WriteAstNode("left", query.Left); WriteAstNode("right", query.Right); _xmlWriter.WriteEndElement(); return(query); }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { base.VisitBinaryQuery(query); if (ErrorReporter.ErrorsSeen) return query; SelectColumn[] leftSelectColumns = query.Left.GetColumns(); SelectColumn[] rightSelectColumns = query.Right.GetColumns(); if (leftSelectColumns.Length != rightSelectColumns.Length) { ErrorReporter.DifferentExpressionCountInBinaryQuery(); } else { // Check that all column expressions share a common type. // // If the types are not equal an CAST node is inserted in the tree. // To do this and to support good error reporting we first try to find // the best common type. Any needed conversions or type errors are // ignored. Type[] commonTypes = new Type[leftSelectColumns.Length]; for (int i = 0; i < leftSelectColumns.Length; i++) { Type leftType = leftSelectColumns[i].Expression.ExpressionType; Type rightType = rightSelectColumns[i].Expression.ExpressionType; commonTypes[i] = Binder.ChooseBetterTypeConversion(leftType, rightType); } // Now we know that commonType is the best type for all column expressions. // // Insert cast nodes for all expressions that have a different type but are // implicit convertible and report errors for all expressions that not convertible. for (int i = 0; i < leftSelectColumns.Length; i++) { SelectColumn leftSelectColumn = leftSelectColumns[i]; SelectColumn rightSelectColumn = rightSelectColumns[i]; leftSelectColumn.Expression = Binder.ConvertExpressionIfRequired(leftSelectColumn.Expression, commonTypes[i]); rightSelectColumn.Expression = Binder.ConvertExpressionIfRequired(rightSelectColumn.Expression, commonTypes[i]); } } return query; }
private QueryNode ParseUnifiedOrExceptionalQuery() { QueryNode leftQuery = ParseIntersectionalQuery(); if (leftQuery == null) { return(null); } while (_token.Id == TokenId.UNION || _token.Id == TokenId.EXCEPT) { BinaryQueryOperator op; if (_token.Id == TokenId.EXCEPT) { op = BinaryQueryOperator.Except; } else { if (_lookahead.Id != TokenId.ALL) { op = BinaryQueryOperator.Union; } else { op = BinaryQueryOperator.UnionAll; NextToken(); } } NextToken(); QueryNode rightQuery = ParseIntersectionalQuery(); if (rightQuery == null) { return(null); } BinaryQuery binaryQuery = new BinaryQuery(); binaryQuery.Op = op; binaryQuery.Left = leftQuery; binaryQuery.Right = rightQuery; leftQuery = binaryQuery; } return(leftQuery); }
public static QueryNode CombineQueries(List <QueryNode> members, BinaryQueryOperator combineOperator) { if (members.Count == 0) { return(null); } QueryNode currentNode = members[0]; for (int i = 1; i < members.Count; i++) { BinaryQuery binaryQuery = new BinaryQuery(); binaryQuery.Left = currentNode; binaryQuery.Right = members[i]; binaryQuery.Op = combineOperator; currentNode = binaryQuery; } return(currentNode); }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { base.VisitBinaryQuery(query); EnsureQueryHasNoOrderByUnlessTopSpecified(query.Left); EnsureQueryHasNoOrderByUnlessTopSpecified(query.Right); // Except for UNION ALL any binary operator requires that all // column data types are comparable. if (query.Op != BinaryQueryOperator.UnionAll) { foreach (SelectColumn columnSource in query.GetColumns()) { if (!CheckIfTypeIsComparable(columnSource.Expression.ExpressionType)) { _errorReporter.InvalidDataTypeInUnion(columnSource.Expression.ExpressionType, query.Op); } } } return(query); }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { bool leftNeedsParentheses = query.Left is BinaryQuery; bool rightNeedsParentheses = query.Right is BinaryQuery; if (leftNeedsParentheses) { _writer.Write("("); _writer.Indent += QUERY_INDENT; _writer.WriteLine(); } Visit(query.Left); if (leftNeedsParentheses) { _writer.Indent -= QUERY_INDENT; _writer.WriteLine(); _writer.Write(")"); } _writer.WriteLine(); switch (query.Op) { case BinaryQueryOperator.Union: _writer.Write(UNION); break; case BinaryQueryOperator.UnionAll: _writer.Write(UNIONALL); break; case BinaryQueryOperator.Intersect: _writer.Write(INTERSECT); break; case BinaryQueryOperator.Except: _writer.Write(EXCEPT); break; default: ExceptionBuilder.UnhandledCaseLabel(query.Op); break; } _writer.WriteLine(); if (rightNeedsParentheses) { _writer.Write("("); _writer.Indent += QUERY_INDENT; _writer.WriteLine(); } Visit(query.Right); if (rightNeedsParentheses) { _writer.Indent -= QUERY_INDENT; _writer.WriteLine(); _writer.Write(")"); } return query; }
private QueryNode ParseIntersectionalQuery() { QueryNode leftQuery = ParseSelectQuery(); if (leftQuery == null) return null; while (_token.Id == TokenId.INTERSECT) { NextToken(); QueryNode rightQuery = ParseSelectQuery(); if (rightQuery == null) return null; BinaryQuery binaryQuery = new BinaryQuery(); binaryQuery.Op = BinaryQueryOperator.Intersect; binaryQuery.Left = leftQuery; binaryQuery.Right = rightQuery; leftQuery = binaryQuery; } return leftQuery; }
private QueryNode ParseUnifiedOrExceptionalQuery() { QueryNode leftQuery = ParseIntersectionalQuery(); if (leftQuery == null) return null; while (_token.Id == TokenId.UNION || _token.Id == TokenId.EXCEPT) { BinaryQueryOperator op; if (_token.Id == TokenId.EXCEPT) { op = BinaryQueryOperator.Except; } else { if (_lookahead.Id != TokenId.ALL) { op = BinaryQueryOperator.Union; } else { op = BinaryQueryOperator.UnionAll; NextToken(); } } NextToken(); QueryNode rightQuery = ParseIntersectionalQuery(); if (rightQuery == null) return null; BinaryQuery binaryQuery = new BinaryQuery(); binaryQuery.Op = op; binaryQuery.Left = leftQuery; binaryQuery.Right = rightQuery; leftQuery = binaryQuery; } return leftQuery; }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { bool leftNeedsParentheses = query.Left is BinaryQuery; bool rightNeedsParentheses = query.Right is BinaryQuery; if (leftNeedsParentheses) { _writer.Write("("); _writer.Indent += QUERY_INDENT; _writer.WriteLine(); } Visit(query.Left); if (leftNeedsParentheses) { _writer.Indent -= QUERY_INDENT; _writer.WriteLine(); _writer.Write(")"); } _writer.WriteLine(); switch (query.Op) { case BinaryQueryOperator.Union: _writer.Write(UNION); break; case BinaryQueryOperator.UnionAll: _writer.Write(UNIONALL); break; case BinaryQueryOperator.Intersect: _writer.Write(INTERSECT); break; case BinaryQueryOperator.Except: _writer.Write(EXCEPT); break; default: ExceptionBuilder.UnhandledCaseLabel(query.Op); break; } _writer.WriteLine(); if (rightNeedsParentheses) { _writer.Write("("); _writer.Indent += QUERY_INDENT; _writer.WriteLine(); } Visit(query.Right); if (rightNeedsParentheses) { _writer.Indent -= QUERY_INDENT; _writer.WriteLine(); _writer.Write(")"); } return(query); }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { switch (query.Op) { case BinaryQueryOperator.Intersect: case BinaryQueryOperator.Except: { ResultAlgebraNode left = ((ResultAlgebraNode)ConvertAstNode(query.Left)); ResultAlgebraNode right = ((ResultAlgebraNode)ConvertAstNode(query.Right)); // Create distinct sort SortAlgebraNode sortAlgebraNode = new SortAlgebraNode(); sortAlgebraNode.Distinct = true; sortAlgebraNode.Input = left; sortAlgebraNode.SortEntries = left.OutputList; sortAlgebraNode.SortOrders = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length); // Insert left (anti) semi join to (except) intersect left and right. ExpressionBuilder expressionBuilder = new ExpressionBuilder(); for (int i = 0; i < left.OutputList.Length; i++) { RowBufferEntryExpression leftExpr = new RowBufferEntryExpression(); leftExpr.RowBufferEntry = left.OutputList[i]; RowBufferEntryExpression rightExpr = new RowBufferEntryExpression(); rightExpr.RowBufferEntry = right.OutputList[i]; expressionBuilder.Push(leftExpr); expressionBuilder.Push(rightExpr); expressionBuilder.PushBinary(BinaryOperator.Equal); expressionBuilder.Push(leftExpr); expressionBuilder.PushIsNull(); expressionBuilder.Push(rightExpr); expressionBuilder.PushIsNull(); expressionBuilder.PushBinary(BinaryOperator.LogicalAnd); expressionBuilder.PushBinary(BinaryOperator.LogicalOr); } expressionBuilder.PushNAry(LogicalOperator.And); ExpressionNode joinCondition = expressionBuilder.Pop(); JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode(); if (query.Op == BinaryQueryOperator.Intersect) { joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftSemiJoin; } else { joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin; } joinAlgebraNode.Left = sortAlgebraNode; joinAlgebraNode.Right = right; joinAlgebraNode.Predicate = joinCondition; SetLastAlgebraNode(joinAlgebraNode); ResultAlgebraNode resultAlgebraNode = new ResultAlgebraNode(); resultAlgebraNode.Input = GetLastAlgebraNode(); resultAlgebraNode.OutputList = left.OutputList; resultAlgebraNode.ColumnNames = left.ColumnNames; SetLastAlgebraNode(resultAlgebraNode); break; } case BinaryQueryOperator.Union: case BinaryQueryOperator.UnionAll: { // Build a flat list with all inputs. List <QueryNode> inputList = AstUtil.FlattenBinaryQuery(query); AlgebraNode[] inputs = new AlgebraNode[inputList.Count]; for (int i = 0; i < inputs.Length; i++) { inputs[i] = ConvertAstNode(inputList[i]); } int outputColumnCount = inputs[0].OutputList.Length; UnitedValueDefinition[] definedValues = new UnitedValueDefinition[outputColumnCount]; List <RowBufferEntry> definedValueEntries = new List <RowBufferEntry>(); for (int i = 0; i < outputColumnCount; i++) { RowBufferEntry rowBufferEntry = new RowBufferEntry(inputs[0].OutputList[i].DataType); definedValueEntries.Add(rowBufferEntry); UnitedValueDefinition definedValue = new UnitedValueDefinition(); definedValue.Target = rowBufferEntry; List <RowBufferEntry> dependencies = new List <RowBufferEntry>(); foreach (ResultAlgebraNode node in inputs) { dependencies.Add(node.OutputList[i]); } definedValue.DependendEntries = dependencies.ToArray(); definedValues[i] = definedValue; } ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode(); concatAlgebraNode.Inputs = inputs; concatAlgebraNode.DefinedValues = definedValues; SetLastAlgebraNode(concatAlgebraNode); if (query.Op == BinaryQueryOperator.Union) { SortAlgebraNode sortAlgebraNode = new SortAlgebraNode(); sortAlgebraNode.Distinct = true; sortAlgebraNode.Input = GetLastAlgebraNode(); sortAlgebraNode.SortEntries = definedValueEntries.ToArray(); sortAlgebraNode.SortOrders = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length); SetLastAlgebraNode(sortAlgebraNode); } ResultAlgebraNode unionResultAlgebraNode = new ResultAlgebraNode(); unionResultAlgebraNode.Input = GetLastAlgebraNode(); unionResultAlgebraNode.ColumnNames = ((ResultAlgebraNode)inputs[0]).ColumnNames; unionResultAlgebraNode.OutputList = definedValueEntries.ToArray(); SetLastAlgebraNode(unionResultAlgebraNode); break; } } return(query); }
public static QueryNode CombineQueries(List<QueryNode> members, BinaryQueryOperator combineOperator) { if (members.Count == 0) return null; QueryNode currentNode = members[0]; for (int i = 1; i < members.Count; i++) { BinaryQuery binaryQuery = new BinaryQuery(); binaryQuery.Left = currentNode; binaryQuery.Right = members[i]; binaryQuery.Op = combineOperator; currentNode = binaryQuery; } return currentNode; }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { switch (query.Op) { case BinaryQueryOperator.Intersect: case BinaryQueryOperator.Except: { ResultAlgebraNode left = ((ResultAlgebraNode)ConvertAstNode(query.Left)); ResultAlgebraNode right = ((ResultAlgebraNode)ConvertAstNode(query.Right)); // Create distinct sort SortAlgebraNode sortAlgebraNode = new SortAlgebraNode(); sortAlgebraNode.Distinct = true; sortAlgebraNode.Input = left; sortAlgebraNode.SortEntries = left.OutputList; sortAlgebraNode.SortOrders = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length); // Insert left (anti) semi join to (except) intersect left and right. ExpressionBuilder expressionBuilder = new ExpressionBuilder(); for (int i = 0; i < left.OutputList.Length; i++) { RowBufferEntryExpression leftExpr = new RowBufferEntryExpression(); leftExpr.RowBufferEntry = left.OutputList[i]; RowBufferEntryExpression rightExpr = new RowBufferEntryExpression(); rightExpr.RowBufferEntry = right.OutputList[i]; expressionBuilder.Push(leftExpr); expressionBuilder.Push(rightExpr); expressionBuilder.PushBinary(BinaryOperator.Equal); expressionBuilder.Push(leftExpr); expressionBuilder.PushIsNull(); expressionBuilder.Push(rightExpr); expressionBuilder.PushIsNull(); expressionBuilder.PushBinary(BinaryOperator.LogicalAnd); expressionBuilder.PushBinary(BinaryOperator.LogicalOr); } expressionBuilder.PushNAry(LogicalOperator.And); ExpressionNode joinCondition = expressionBuilder.Pop(); JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode(); if (query.Op == BinaryQueryOperator.Intersect) joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftSemiJoin; else joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin; joinAlgebraNode.Left = sortAlgebraNode; joinAlgebraNode.Right = right; joinAlgebraNode.Predicate = joinCondition; SetLastAlgebraNode(joinAlgebraNode); ResultAlgebraNode resultAlgebraNode = new ResultAlgebraNode(); resultAlgebraNode.Input = GetLastAlgebraNode(); resultAlgebraNode.OutputList = left.OutputList; resultAlgebraNode.ColumnNames = left.ColumnNames; SetLastAlgebraNode(resultAlgebraNode); break; } case BinaryQueryOperator.Union: case BinaryQueryOperator.UnionAll: { // Build a flat list with all inputs. List<QueryNode> inputList = AstUtil.FlattenBinaryQuery(query); AlgebraNode[] inputs = new AlgebraNode[inputList.Count]; for (int i = 0; i < inputs.Length; i++) inputs[i] = ConvertAstNode(inputList[i]); int outputColumnCount = inputs[0].OutputList.Length; UnitedValueDefinition[] definedValues = new UnitedValueDefinition[outputColumnCount]; List<RowBufferEntry> definedValueEntries = new List<RowBufferEntry>(); for (int i = 0; i < outputColumnCount; i++) { RowBufferEntry rowBufferEntry = new RowBufferEntry(inputs[0].OutputList[i].DataType); definedValueEntries.Add(rowBufferEntry); UnitedValueDefinition definedValue = new UnitedValueDefinition(); definedValue.Target = rowBufferEntry; List<RowBufferEntry> dependencies = new List<RowBufferEntry>(); foreach (ResultAlgebraNode node in inputs) dependencies.Add(node.OutputList[i]); definedValue.DependendEntries = dependencies.ToArray(); definedValues[i] = definedValue; } ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode(); concatAlgebraNode.Inputs = inputs; concatAlgebraNode.DefinedValues = definedValues; SetLastAlgebraNode(concatAlgebraNode); if (query.Op == BinaryQueryOperator.Union) { SortAlgebraNode sortAlgebraNode = new SortAlgebraNode(); sortAlgebraNode.Distinct = true; sortAlgebraNode.Input = GetLastAlgebraNode(); sortAlgebraNode.SortEntries = definedValueEntries.ToArray(); sortAlgebraNode.SortOrders = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length); SetLastAlgebraNode(sortAlgebraNode); } ResultAlgebraNode unionResultAlgebraNode = new ResultAlgebraNode(); unionResultAlgebraNode.Input = GetLastAlgebraNode(); unionResultAlgebraNode.ColumnNames = ((ResultAlgebraNode)inputs[0]).ColumnNames; unionResultAlgebraNode.OutputList = definedValueEntries.ToArray(); SetLastAlgebraNode(unionResultAlgebraNode); break; } } return query; }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { base.VisitBinaryQuery (query); EnsureQueryHasNoOrderByUnlessTopSpecified(query.Left); EnsureQueryHasNoOrderByUnlessTopSpecified(query.Right); // Except for UNION ALL any binary operator requires that all // column data types are comparable. if (query.Op != BinaryQueryOperator.UnionAll) { foreach (SelectColumn columnSource in query.GetColumns()) { if (!CheckIfTypeIsComparable(columnSource.Expression.ExpressionType)) _errorReporter.InvalidDataTypeInUnion(columnSource.Expression.ExpressionType, query.Op); } } return query; }
private static bool VisitBinaryQuery(BinaryQuery node1, BinaryQuery node2) { return node2 != null && node1.Op == node2.Op && Visit(node1.Left, node2.Left) && Visit(node1.Right, node2.Right); }
public virtual QueryNode VisitBinaryQuery(BinaryQuery query) { query.Left = VisitQuery(query.Left); query.Right = VisitQuery(query.Right); return query; }
public virtual QueryNode VisitBinaryQuery(BinaryQuery query) { query.Left = VisitQuery(query.Left); query.Right = VisitQuery(query.Right); return(query); }
public static List<QueryNode> FlattenBinaryQuery(BinaryQuery binaryQuery) { List<QueryNode> inputList = new List<QueryNode>(); inputList.Add(binaryQuery.Left); inputList.Add(binaryQuery.Right); bool atLeastOneExpanded; do { atLeastOneExpanded = false; for (int i = inputList.Count - 1; i >= 0; i--) { BinaryQuery inputAsBinaryQuery = inputList[i] as BinaryQuery; if (inputAsBinaryQuery != null && inputAsBinaryQuery.Op == binaryQuery.Op) { inputList.RemoveAt(i); inputList.Insert(i, inputAsBinaryQuery.Left); inputList.Insert(i + 1, inputAsBinaryQuery.Right); atLeastOneExpanded = true; } } } while (atLeastOneExpanded); return inputList; }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { if (query.Op == BinaryQueryOperator.Union) _containsUnion = true; return base.VisitBinaryQuery(query); }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { _xmlWriter.WriteStartElement("binaryQuery"); _xmlWriter.WriteAttributeString("op", query.Op.ToString()); WriteAstNode("left", query.Left); WriteAstNode("right", query.Right); _xmlWriter.WriteEndElement(); return query; }