/** * Factory method that creates a join. * A subclass can override to use a different kind of join. * * @param left Left input * @param right Right input * @param condition Join condition * @param joinType Join type * @param variablesStopped Set of names of variables which are set by the * LHS and used by the RHS and are not available to * nodes above this JoinRel in the tree * @return A relational expression representing a join */ protected RelNode createJoin( RelNode left, RelNode right, RexNode condition, JoinRelType joinType, Set<String> variablesStopped) { return new JoinRel( cluster, left, right, condition, joinType, variablesStopped); }
/** * Creates an AggregateRel. * * <p>In case the aggregate rel changes the order in which it projects * fields, the <code>groupExprProjection</code> parameter is provided, and * the implementation of this method may modify it. * * <p>The <code>sortedCount</code> parameter is the number of expressions * known to be monotonic. These expressions must be on the leading edge of * the grouping keys. The default implementation of this method ignores this * parameter. * * @param bb Blackboard * @param groupSet Bit set of ordinals of grouping columns * @param aggCalls Array of calls to aggregate functions * @return AggregateRel */ protected RelNode createAggregate( Blackboard bb, BitSet groupSet, List<AggregateCall> aggCalls) { return new AggregateRel( cluster, bb.root, groupSet, aggCalls); }
RelDataTypeField getRootField(RexInputRef inputRef) { int fieldOffset = inputRef.getIndex(); for (RelNode input : inputs) { RelDataType rowType = input.getRowType(); if (rowType == null) { // TODO: remove this once leastRestrictive // is correctly implemented return null; } if (fieldOffset < rowType.getFieldCount()) { return rowType.getFieldList().get(fieldOffset); } fieldOffset -= rowType.getFieldCount(); } throw new AssertionError(); }
SqlNode fetch) { if (select.getOrderList() == null) { assert collation.getFieldCollations().isEmpty(); if (offset == null && fetch == null) { return; new SortRel( cluster, cluster.traitSetOf(Convention.NONE, collation), final RelDataType rowType = bb.root.getRowType(); final int fieldCount = rowType.getFieldCount() - orderExprList.size(); new ProjectRel( cluster, cluster.traitSetOf(RelCollationImpl.PRESERVE),
((ProjectRel) insertRel.getInput(0)).getProjects(); if (insertRel.getInput(0).getInput(0) instanceof ProjectRel) { level2InsertExprs = ((ProjectRel) insertRel.getInput(0).getInput(0)) .getProjects(); JoinRel joinRel = (JoinRel) mergeSourceRel.getInput(0); int nSourceFields = joinRel.getLeft().getRowType().getFieldCount(); List<RexNode> projects = new ArrayList<RexNode>(); for (int level1Idx = 0; level1Idx < nLevel1Exprs; level1Idx++) { final ProjectRel project = (ProjectRel) mergeSourceRel; projects.addAll( Util.skip(project.getProjects(), nSourceFields)); RelOptUtil.createProject(joinRel, projects, null, true); return new TableModificationRel( cluster, targetTable,
setRoot(rel, false); return rexBuilder.makeRangeReference( root.getRowType(), 0, false); final int origLeftInputCount = root.getRowType().getFieldCount(); if (leftKeys != null) { List<RexNode> newLeftInputExpr = Lists.newArrayList(); final int rightOffset = root.getRowType().getFieldCount() - newLeftInput.getRowType().getFieldCount(); final List<Integer> rightKeys = Util.range(rightOffset, rightOffset + leftJoinKeys.size()); int leftFieldCount = root.getRowType().getFieldCount(); final RelNode join = createJoin( && joinType == JoinRelType.LEFT) { final int leftKeyCount = leftKeys.size(); int rightFieldLength = rel.getRowType().getFieldCount(); assert leftKeyCount == rightFieldLength - 1; } else { return rexBuilder.makeRangeReference( rel.getRowType(), leftFieldCount, joinType.generatesNullsOnRight());
final ProjectRelBase left = (ProjectRelBase) join.getLeft(); final RelNode leftLeft = ((JoinRelBase) left.getInput(0)).getLeft(); final int leftLeftCount = leftLeft.getRowType().getFieldCount(); final RelDataType nullableBooleanType = typeFactory.createTypeWithNullability( final RexNode ckRef = rexBuilder.makeInputRef(root, leftLeftCount + 1); final RexNode iRef = rexBuilder.makeInputRef(root, root.getRowType().getFieldCount() - 1); rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, iRef), trueLiteral); final JoinInfo joinInfo = join.analyzeCondition(); for (int leftKey : joinInfo.leftKeys) { final RexNode kRef = rexBuilder.makeInputRef(root, leftKey);
final List<RexNode> list = Lists.newArrayList(); for (String name : nameList) { final RelDataType leftRowType = leftRel.getRowType(); RelDataTypeField leftField = catalogReader.field(leftRowType, name); RexNode left = leftField.getType(), leftField.getIndex()); final RelDataType rightRowType = rightRel.getRowType(); RelDataTypeField rightField = catalogReader.field(rightRowType, name);
/** * Adds an expression, deducing an appropriate name if possible. * * @param expr Expression * @param name Suggested name */ private void addExpr(RexNode expr, String name) { convertedInputExprs.add(expr); if ((name == null) && (expr instanceof RexInputRef)) { final int i = ((RexInputRef) expr).getIndex(); name = bb.root.getRowType().getFieldList().get(i).getName(); } if (convertedInputExprNames.contains(name)) { // In case like 'SELECT ... GROUP BY x, y, x', don't add // name 'x' twice. name = null; } convertedInputExprNames.add(name); }
final RelNode seek = converted.left.getInput(0); // fragile final int keyCount = leftKeys.size(); final List<Integer> args = ImmutableIntList.range(0, keyCount); AggregateRel aggregate = new AggregateRel(cluster, seek, BitSets.of(), ImmutableList.of( new AggregateCall(SqlStdOperatorTable.COUNT, false, ImmutableList.<Integer>of(), longType, null), new AggregateCall(SqlStdOperatorTable.COUNT, false, args, longType, null))); JoinRel join = new JoinRel(cluster, bb.root, aggregate, rexBuilder.makeLiteral(true), JoinRelType.INNER, ImmutableSet.<String>of());
public void flatten( List<RelNode> rels, int systemFieldCount, int[] start, List<Pair<RelNode, Integer>> relOffsetList) { for (RelNode rel : rels) { if (leaves.contains(rel)) { relOffsetList.add( Pair.of(rel, start[0])); start[0] += rel.getRowType().getFieldCount(); } else { if (rel instanceof JoinRel || rel instanceof AggregateRel) { start[0] += systemFieldCount; } flatten( rel.getInputs(), systemFieldCount, start, relOffsetList); } } }
private void checkConvertedType(SqlNode query, RelNode result) { if (!query.isA(SqlKind.DML)) { // Verify that conversion from SQL to relational algebra did // not perturb any type information. (We can't do this if the // SQL statement is something like an INSERT which has no // validator type information associated with its result, // hence the namespace check above.) RelDataType convertedRowType = result.getRowType(); if (!checkConvertedRowType(query, convertedRowType)) { RelDataType validatedRowType = validator.getValidatedNodeType(query); validatedRowType = uniquifyFields(validatedRowType); throw Util.newInternal( "Conversion to relational algebra failed to preserve " + "datatypes:\n" + "validated type:\n" + validatedRowType.getFullTypeString() + "\nconverted type:\n" + convertedRowType.getFullTypeString() + "\nrel:\n" + RelOptUtil.toString(result)); } } }
false); return new TableModificationRel( cluster, targetTable,
return new UnionRel( cluster, ImmutableList.of(left, right), return new IntersectRel( cluster, ImmutableList.of(left, right), return new MinusRel( cluster, ImmutableList.of(left, right),
/** * Creates an expression with which to reference the expression whose * offset in its from-list is {@code offset}. */ RexNode lookup( int offset, LookupContext lookupContext) { Pair<RelNode, Integer> pair = lookupContext.findRel(offset); return rexBuilder.makeRangeReference( pair.left.getRowType(), pair.right, false); }
private RelNode convertDelete(SqlDelete call) { RelOptTable targetTable = getTargetTable(call); RelNode sourceRel = convertSelect(call.getSourceSelect()); return new TableModificationRel( cluster, targetTable, catalogReader, sourceRel, TableModificationRel.Operation.DELETE, null, false); }
private RelNode convertCursor(Blackboard bb, SubQuery subQuery) { final SqlCall cursorCall = (SqlCall) subQuery.node; assert cursorCall.operandCount() == 1; SqlNode query = cursorCall.operand(0); RelNode converted = convertQuery(query, false, false); int iCursor = bb.cursors.size(); bb.cursors.add(converted); subQuery.expr = new RexInputRef( iCursor, converted.getRowType()); return converted; }
private RelNode convertUpdate(SqlUpdate call) { RelOptTable targetTable = getTargetTable(call); // convert update column list from SqlIdentifier to String List<String> targetColumnNameList = new ArrayList<String>(); for (SqlNode node : call.getTargetColumnList()) { SqlIdentifier id = (SqlIdentifier) node; String name = id.getSimple(); targetColumnNameList.add(name); } RelNode sourceRel = convertSelect(call.getSourceSelect()); return new TableModificationRel( cluster, targetTable, catalogReader, sourceRel, TableModificationRel.Operation.UPDATE, targetColumnNameList, false); }