private BoundarySpec getWindowBound(RexWindowBound wb) { BoundarySpec boundarySpec; if (wb.isCurrentRow()) { boundarySpec = new BoundarySpec(Direction.CURRENT); } else { final Direction direction; final int amt; if (wb.isPreceding()) { direction = Direction.PRECEDING; } else { direction = Direction.FOLLOWING; } if (wb.isUnbounded()) { amt = BoundarySpec.UNBOUNDED_AMOUNT; } else { amt = RexLiteral.intValue(wb.getOffset()); } boundarySpec = new BoundarySpec(direction, amt); } return boundarySpec; }
private BoundarySpec getWindowBound(RexWindowBound wb) { BoundarySpec boundarySpec; if (wb.isCurrentRow()) { boundarySpec = new BoundarySpec(Direction.CURRENT); } else { final Direction direction; final int amt; if (wb.isPreceding()) { direction = Direction.PRECEDING; } else { direction = Direction.FOLLOWING; } if (wb.isUnbounded()) { amt = BoundarySpec.UNBOUNDED_AMOUNT; } else { amt = RexLiteral.intValue(wb.getOffset()); } boundarySpec = new BoundarySpec(direction, amt); } return boundarySpec; }
private ASTNode getWindowBound(RexWindowBound wb) { ASTNode wbAST = null; if (wb.isCurrentRow()) { wbAST = ASTBuilder.createAST(HiveParser.KW_CURRENT, "CURRENT"); } else { if (wb.isPreceding()) wbAST = ASTBuilder.createAST(HiveParser.KW_PRECEDING, "PRECEDING"); else wbAST = ASTBuilder.createAST(HiveParser.KW_FOLLOWING, "FOLLOWING"); if (wb.isUnbounded()) { wbAST.addChild(ASTBuilder.createAST(HiveParser.KW_UNBOUNDED, "UNBOUNDED")); } else { ASTNode offset = wb.getOffset().accept(this); wbAST.addChild(offset); } } return wbAST; }
private ASTNode getWindowBound(RexWindowBound wb) { ASTNode wbAST = null; if (wb.isCurrentRow()) { wbAST = ASTBuilder.createAST(HiveParser.KW_CURRENT, "CURRENT"); } else { if (wb.isPreceding()) wbAST = ASTBuilder.createAST(HiveParser.KW_PRECEDING, "PRECEDING"); else wbAST = ASTBuilder.createAST(HiveParser.KW_FOLLOWING, "FOLLOWING"); if (wb.isUnbounded()) { wbAST.addChild(ASTBuilder.createAST(HiveParser.KW_UNBOUNDED, "UNBOUNDED")); } else { ASTNode offset = wb.getOffset().accept(this); wbAST.addChild(offset); } } return wbAST; }
public static Bound newBound(RexWindowBound windowBound) { return new Bound(windowBound.isUnbounded(), windowBound.isCurrentRow() ? 0 : Long.MIN_VALUE); //TODO: Get offset to work } }
public static Bound newBound(RexWindowBound windowBound) { return new Bound(windowBound.isUnbounded(), windowBound.isCurrentRow() ? 0 : Long.MIN_VALUE); //TODO: Get offset to work } }
private Pair<Expression, Expression> getRowCollationKey( BlockBuilder builder, PhysType inputPhysType, Group group, int windowIdx) { if (!(group.isRows || (group.upperBound.isUnbounded() && group.lowerBound.isUnbounded()))) { Pair<Expression, Expression> pair = inputPhysType.generateCollationKey( group.collation().getFieldCollations()); // optimize=false to prevent inlining of object create into for-loops return Pair.of( builder.append("keySelector" + windowIdx, pair.left, false), builder.append("keyComparator" + windowIdx, pair.right, false)); } else { return Pair.of(null, null); } }
private Pair<Expression, Expression> getRowCollationKey( BlockBuilder builder, PhysType inputPhysType, Group group, int windowIdx) { if (!(group.isRows || (group.upperBound.isUnbounded() && group.lowerBound.isUnbounded()))) { Pair<Expression, Expression> pair = inputPhysType.generateCollationKey( group.collation().getFieldCollations()); // optimize=false to prevent inlining of object create into for-loops return Pair.of( builder.append("keySelector" + windowIdx, pair.left, false), builder.append("keyComparator" + windowIdx, pair.right, false)); } else { return Pair.of(null, null); } }
private SqlNode createSqlWindowBound(RexWindowBound rexWindowBound) { if (rexWindowBound.isCurrentRow()) { return SqlWindow.createCurrentRow(POS); } if (rexWindowBound.isPreceding()) { if (rexWindowBound.isUnbounded()) { return SqlWindow.createUnboundedPreceding(POS); } else { SqlNode literal = toSql(null, rexWindowBound.getOffset()); return SqlWindow.createPreceding(literal, POS); } } if (rexWindowBound.isFollowing()) { if (rexWindowBound.isUnbounded()) { return SqlWindow.createUnboundedFollowing(POS); } else { SqlNode literal = toSql(null, rexWindowBound.getOffset()); return SqlWindow.createFollowing(literal, POS); } } throw new AssertionError("Unsupported Window bound: " + rexWindowBound); }
private SqlNode createSqlWindowBound(RexWindowBound rexWindowBound) { if (rexWindowBound.isCurrentRow()) { return SqlWindow.createCurrentRow(POS); } if (rexWindowBound.isPreceding()) { if (rexWindowBound.isUnbounded()) { return SqlWindow.createUnboundedPreceding(POS); } else { SqlNode literal = toSql(null, rexWindowBound.getOffset()); return SqlWindow.createPreceding(literal, POS); } } if (rexWindowBound.isFollowing()) { if (rexWindowBound.isUnbounded()) { return SqlWindow.createUnboundedFollowing(POS); } else { SqlNode literal = toSql(null, rexWindowBound.getOffset()); return SqlWindow.createFollowing(literal, POS); } } throw new AssertionError("Unsupported Window bound: " + rexWindowBound); }
/** * 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. } }
private BoundarySpec getWindowBound(RexWindowBound wb, boolean isRows) { BoundarySpec boundarySpec; if (wb.isCurrentRow()) { boundarySpec = new CurrentRowSpec(); } else { final Direction direction; final int amt; if (wb.isPreceding()) { direction = Direction.PRECEDING; } else { direction = Direction.FOLLOWING; } if (wb.isUnbounded()) { amt = BoundarySpec.UNBOUNDED_AMOUNT; } else { amt = RexLiteral.intValue(wb.getOffset()); } if (isRows) { boundarySpec = new RangeBoundarySpec(direction, amt); } else { boundarySpec = new ValueBoundarySpec(direction, amt); } } return boundarySpec; }
private ASTNode getWindowBound(RexWindowBound wb) { ASTNode wbAST = null; if (wb.isCurrentRow()) { wbAST = ASTBuilder.createAST(HiveParser.KW_CURRENT, "CURRENT"); } else { if (wb.isPreceding()) wbAST = ASTBuilder.createAST(HiveParser.KW_PRECEDING, "PRECEDING"); else wbAST = ASTBuilder.createAST(HiveParser.KW_FOLLOWING, "FOLLOWING"); if (wb.isUnbounded()) { wbAST.addChild(ASTBuilder.createAST(HiveParser.KW_UNBOUNDED, "UNBOUNDED")); } else { ASTNode offset = wb.getOffset().accept(this); wbAST.addChild(offset); } } return wbAST; }
Expression keySelector, Expression keyComparator) { RexWindowBound bound = lower ? group.lowerBound : group.upperBound; if (bound.isUnbounded()) { return bound.isPreceding() ? min_ : max_;
Expression keySelector, Expression keyComparator) { RexWindowBound bound = lower ? group.lowerBound : group.upperBound; if (bound.isUnbounded()) { return bound.isPreceding() ? min_ : max_;
} else { Expression startTmp = group.lowerBound.isUnbounded() || startUnchecked == i_ ? startUnchecked : builder4.append("startTmp", startUnchecked, minX)); Expression endTmp = group.upperBound.isUnbounded() || endUnchecked == i_ ? endUnchecked : builder4.append("endTmp", group.lowerBound.isUnbounded() && group.lowerBound.isPreceding() ? Expressions.constant(false) : Expressions.notEqual(startX, prevStart);
} else { Expression startTmp = group.lowerBound.isUnbounded() || startUnchecked == i_ ? startUnchecked : builder4.append("startTmp", startUnchecked, minX)); Expression endTmp = group.upperBound.isUnbounded() || endUnchecked == i_ ? endUnchecked : builder4.append("endTmp", group.lowerBound.isUnbounded() && group.lowerBound.isPreceding() ? Expressions.constant(false) : Expressions.notEqual(startX, prevStart);