private static Set<Integer> getCommonPartitionCols(List<RexNode> projections) { RexOver overClause; boolean firstOverClause = true; Set<Integer> commonPartitionKeys = new HashSet<Integer>(); for (RexNode expr : projections) { if (expr instanceof RexOver) { overClause = (RexOver) expr; if (firstOverClause) { firstOverClause = false; commonPartitionKeys.addAll(getPartitionCols(overClause.getWindow().partitionKeys)); } else { commonPartitionKeys.retainAll(getPartitionCols(overClause.getWindow().partitionKeys)); } } } return commonPartitionKeys; }
private static Set<Integer> getCommonPartitionCols(List<RexNode> projections) { RexOver overClause; boolean firstOverClause = true; Set<Integer> commonPartitionKeys = new HashSet<Integer>(); for (RexNode expr : projections) { if (expr instanceof RexOver) { overClause = (RexOver) expr; if (firstOverClause) { firstOverClause = false; commonPartitionKeys.addAll(getPartitionCols(overClause.getWindow().partitionKeys)); } else { commonPartitionKeys.retainAll(getPartitionCols(overClause.getWindow().partitionKeys)); } } } return commonPartitionKeys; }
public Boolean visitOver(RexOver over) { if (!visitCall(over)) { return false; } final RexWindow window = over.getWindow(); for (RexFieldCollation orderKey : window.orderKeys) { if (!((RexNode) orderKey.left).accept(this)) { return false; } } for (RexNode partitionKey : window.partitionKeys) { if (!partitionKey.accept(this)) { return false; } } return true; }
for (RexNode partitionKey : rexOverNode.getWindow().partitionKeys) { if (partitionKey instanceof RexInputRef && ((RexInputRef)partitionKey).getIndex() >= groupingFields) { for (RexFieldCollation orderKey : rexOverNode.getWindow().orderKeys) { if (orderKey.left instanceof RexInputRef && ((RexInputRef)orderKey.left).getIndex() >= groupingFields) {
for (RexNode partitionKey : rexOverNode.getWindow().partitionKeys) { if (partitionKey instanceof RexInputRef && ((RexInputRef)partitionKey).getIndex() >= groupingFields) { for (RexFieldCollation orderKey : rexOverNode.getWindow().orderKeys) { if (orderKey.left instanceof RexInputRef && ((RexInputRef)orderKey.left).getIndex() >= groupingFields) {
@Override public ASTNode visitOver(RexOver over) { if (!deep) { return null; } // 1. Translate the UDAF final ASTNode wUDAFAst = visitCall(over); // 2. Add TOK_WINDOW as child of UDAF ASTNode wSpec = ASTBuilder.createAST(HiveParser.TOK_WINDOWSPEC, "TOK_WINDOWSPEC"); wUDAFAst.addChild(wSpec); // 3. Add Part Spec & Range Spec as child of TOK_WINDOW final RexWindow window = over.getWindow(); final ASTNode wPSpecAst = getPSpecAST(window); final ASTNode wRangeAst = getWindowRangeAST(window); if (wPSpecAst != null) wSpec.addChild(wPSpecAst); if (wRangeAst != null) wSpec.addChild(wRangeAst); return wUDAFAst; }
@Override public ASTNode visitOver(RexOver over) { if (!deep) { return null; } // 1. Translate the UDAF final ASTNode wUDAFAst = visitCall(over); // 2. Add TOK_WINDOW as child of UDAF ASTNode wSpec = ASTBuilder.createAST(HiveParser.TOK_WINDOWSPEC, "TOK_WINDOWSPEC"); wUDAFAst.addChild(wSpec); // 3. Add Part Spec & Range Spec as child of TOK_WINDOW final RexWindow window = over.getWindow(); final ASTNode wPSpecAst = getPSpecAST(window); final ASTNode wRangeAst = getWindowRangeAST(window); if (wPSpecAst != null) wSpec.addChild(wPSpecAst); if (wRangeAst != null) wSpec.addChild(wRangeAst); return wUDAFAst; }
final RexWindow window = over.getWindow();
final RexWindow window = over.getWindow();
/** * Indicates if the given OVER clause has a window frame that is automatically added by * Calcite if the frame is not specified. */ public static boolean hasDefaultFrame(RexOver over) { // When Calcite parses an OVER clause with no frame, // it inject a 'default' frame depending on the function. // 1. For ROW_NUMBER(), it generates ROWS UNBOUNDED PRECEDING and CURRENT ROW. // 2. For others, it generates RANGE UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING if unsorted. // 3. If it's not ROW_NUMBER(), and it is sorted, Calcite uses RANGE UNBOUNDED PRECEDING AND CURRENT ROW // Adding these unnecessary frames cause some RDBMSes (eg SQL Server) to fail. // // This code happens in SqlToRelConverter.convertOver(), SqlValidatorImpl.resolveWindow(), // and SqlWindow.create()/SqlWindow.populateBounds(). return // Note: intentionally not simplifying this boolean for clarity. (over.getAggOperator() == SqlStdOperatorTable.ROW_NUMBER && over.getWindow().isRows() && over.getWindow().getLowerBound().isUnbounded() && over.getWindow().getLowerBound().isPreceding() && over.getWindow().getUpperBound().isCurrentRow()) // First condition. || (!over.getWindow().isRows() && over.getWindow().orderKeys.isEmpty() && over.getWindow().getLowerBound().isUnbounded() && over.getWindow().getLowerBound().isPreceding() && over.getWindow().getUpperBound().isUnbounded() && over.getWindow().getUpperBound().isFollowing()) // Second condition. || (!over.getWindow().isRows() && !over.getWindow().orderKeys.isEmpty() && over.getWindow().getLowerBound().isUnbounded() && over.getWindow().getLowerBound().isPreceding() && !over.getWindow().getUpperBound().isUnbounded() && over.getWindow().getUpperBound().isCurrentRow()); // Third condition. } }
public RexNode visitOver(RexOver over) { boolean[] update = {false}; List<RexNode> clonedOperands = visitList(over.operands, update); RexWindow window = visitWindow(over.getWindow()); if (update[0] || (window != over.getWindow())) { // REVIEW jvs 8-Mar-2005: This doesn't take into account // the fact that a rewrite may have changed the result type. // To do that, we would need to take a RexBuilder and // watch out for special operators like CAST and NEW where // the type is embedded in the original call. return new RexOver( over.getType(), over.getAggOperator(), clonedOperands, window, over.isDistinct()); } else { return over; } }
@Override public RexNode visitOver(RexOver over, P arg) { boolean[] update = {false}; List<RexNode> clonedOperands = visitList(over.operands, update, arg); RexWindow window = visitWindow(over.getWindow(), arg); if (update[0] || (window != over.getWindow())) { // REVIEW jvs 8-Mar-2005: This doesn't take into account // the fact that a rewrite may have changed the result type. // To do that, we would need to take a RexBuilder and // watch out for special operators like CAST and NEW where // the type is embedded in the original call. return new RexOver( over.getType(), over.getAggOperator(), clonedOperands, window, over.isDistinct()); } else { return over; } }
public RexNode visitOver(RexOver over) { boolean[] update = {false}; List<RexNode> clonedOperands = visitList(over.operands, update); RexWindow window = visitWindow(over.getWindow()); if (update[0] || (window != over.getWindow())) { // REVIEW jvs 8-Mar-2005: This doesn't take into account // the fact that a rewrite may have changed the result type. // To do that, we would need to take a RexBuilder and // watch out for special operators like CAST and NEW where // the type is embedded in the original call. return new RexOver( over.getType(), over.getAggOperator(), clonedOperands, window, over.isDistinct()); } else { return over; } }
public R visitOver(RexOver over) { R r = visitCall(over); if (!deep) { return null; } final RexWindow window = over.getWindow(); for (RexFieldCollation orderKey : window.orderKeys) { orderKey.left.accept(this); } for (RexNode partitionKey : window.partitionKeys) { partitionKey.accept(this); } window.getLowerBound().accept(this); window.getUpperBound().accept(this); return r; }
public R visitOver(RexOver over) { R r = visitCall(over); if (!deep) { return null; } final RexWindow window = over.getWindow(); for (RexFieldCollation orderKey : window.orderKeys) { orderKey.left.accept(this); } for (RexNode partitionKey : window.partitionKeys) { partitionKey.accept(this); } window.getLowerBound().accept(this); window.getUpperBound().accept(this); return r; }
private static void addWindows( Multimap<WindowKey, RexOver> windowMap, RexOver over, final int inputFieldCount) { final RexWindow aggWindow = over.getWindow(); // Look up or create a window. RelCollation orderKeys = getCollation( Lists.newArrayList( Util.filter(aggWindow.orderKeys, rexFieldCollation -> // If ORDER BY references constant (i.e. RexInputRef), // then we can ignore such ORDER BY key. rexFieldCollation.left instanceof RexLocalRef))); ImmutableBitSet groupSet = ImmutableBitSet.of(getProjectOrdinals(aggWindow.partitionKeys)); final int groupLength = groupSet.length(); if (inputFieldCount < groupLength) { // If PARTITION BY references constant, we can ignore such partition key. // All the inputs after inputFieldCount are literals, thus we can clear. groupSet = groupSet.except(ImmutableBitSet.range(inputFieldCount, groupLength)); } WindowKey windowKey = new WindowKey( groupSet, orderKeys, aggWindow.isRows(), aggWindow.getLowerBound(), aggWindow.getUpperBound()); windowMap.put(windowKey, over); } }
private static void addWindows( Multimap<WindowKey, RexOver> windowMap, RexOver over, final int inputFieldCount) { final RexWindow aggWindow = over.getWindow(); // Look up or create a window. RelCollation orderKeys = getCollation( Lists.newArrayList( Util.filter(aggWindow.orderKeys, rexFieldCollation -> // If ORDER BY references constant (i.e. RexInputRef), // then we can ignore such ORDER BY key. rexFieldCollation.left instanceof RexLocalRef))); ImmutableBitSet groupSet = ImmutableBitSet.of(getProjectOrdinals(aggWindow.partitionKeys)); final int groupLength = groupSet.length(); if (inputFieldCount < groupLength) { // If PARTITION BY references constant, we can ignore such partition key. // All the inputs after inputFieldCount are literals, thus we can clear. groupSet = groupSet.except(ImmutableBitSet.range(inputFieldCount, groupLength)); } WindowKey windowKey = new WindowKey( groupSet, orderKeys, aggWindow.isRows(), aggWindow.getLowerBound(), aggWindow.getUpperBound()); windowMap.put(windowKey, over); } }
@Override public ASTNode visitOver(RexOver over) { if (!deep) { return null; } // 1. Translate the UDAF final ASTNode wUDAFAst = visitCall(over); // 2. Add TOK_WINDOW as child of UDAF ASTNode wSpec = ASTBuilder.createAST(HiveParser.TOK_WINDOWSPEC, "TOK_WINDOWSPEC"); wUDAFAst.addChild(wSpec); // 3. Add Part Spec & Range Spec as child of TOK_WINDOW final RexWindow window = over.getWindow(); final ASTNode wPSpecAst = getPSpecAST(window); final ASTNode wRangeAst = getWindowRangeAST(window); if (wPSpecAst != null) wSpec.addChild(wPSpecAst); if (wRangeAst != null) wSpec.addChild(wRangeAst); return wUDAFAst; }
private SqlCall toSql(RexProgram program, RexOver rexOver) { final RexWindow rexWindow = rexOver.getWindow(); final SqlNodeList partitionList = new SqlNodeList( toSql(program, rexWindow.partitionKeys), POS);
@Override public ExprNodeDesc visitOver(RexOver over) { if (!deep) { return null; } final RexWindow window = over.getWindow(); final WindowSpec windowSpec = new WindowSpec(); final PartitioningSpec partitioningSpec = getPSpec(window); windowSpec.setPartitioning(partitioningSpec); final WindowFrameSpec windowFrameSpec = getWindowRange(window); windowSpec.setWindowFrame(windowFrameSpec); wfs = new WindowFunctionSpec(); wfs.setWindowSpec(windowSpec); final Schema schema = new Schema(tabAlias, inputRowType.getFieldList()); final ASTNode wUDAFAst = new ASTConverter.RexVisitor(schema).visitOver(over); wfs.setExpression(wUDAFAst); ASTNode nameNode = (ASTNode) wUDAFAst.getChild(0); wfs.setName(nameNode.getText()); for(int i=1; i < wUDAFAst.getChildCount()-1; i++) { ASTNode child = (ASTNode) wUDAFAst.getChild(i); wfs.addArg(child); } wfs.setAlias(columnAlias); RelDataTypeField f = outputRowType.getField(columnAlias, false, false); return new ExprNodeColumnDesc(TypeConverter.convert(f.getType()), columnAlias, tabAlias, false); }