public RelNode align(Aggregate rel, List<RelFieldCollation> collations) { // 1) We extract the group by positions that are part of the collations and // sort them so they respect it LinkedHashSet<Integer> aggregateColumnsOrder = new LinkedHashSet<>(); ImmutableList.Builder<RelFieldCollation> propagateCollations = ImmutableList.builder(); if (rel.getGroupType() == Group.SIMPLE && !collations.isEmpty()) { for (RelFieldCollation c : collations) { if (c.getFieldIndex() < rel.getGroupCount()) { // Group column found if (aggregateColumnsOrder.add(c.getFieldIndex())) { propagateCollations.add(c.copy(rel.getGroupSet().nth(c.getFieldIndex()))); } } } } for (int i = 0; i < rel.getGroupCount(); i++) { if (!aggregateColumnsOrder.contains(i)) { // Not included in the input collations, but can be propagated as this Aggregate // will enforce it propagateCollations.add(new RelFieldCollation(rel.getGroupSet().nth(i))); } } // 2) We propagate final RelNode child = dispatchAlign(rel.getInput(), propagateCollations.build()); // 3) We annotate the Aggregate operator with this info final HiveAggregate newAggregate = (HiveAggregate) rel.copy(rel.getTraitSet(), ImmutableList.of(child)); newAggregate.setAggregateColumnsOrder(aggregateColumnsOrder); return newAggregate; }
Operator<?> inputOp = inputOpAf.inputs.get(0); Operator<?> resultOp = inputOpAf.inputs.get(0); StringBuilder order = new StringBuilder(); StringBuilder nullOrder = new StringBuilder(); for (RelFieldCollation sortInfo : sortRel.getCollation().getFieldCollations()) { int sortColumnPos = sortInfo.getFieldIndex(); ColumnInfo columnInfo = new ColumnInfo(inputOp.getSchema().getSignature() .get(sortColumnPos)); columnInfo.getInternalName(), columnInfo.getTabAlias(), columnInfo.getIsVirtualCol()); sortCols.add(sortColumn); if (sortInfo.getDirection() == RelFieldCollation.Direction.DESCENDING) { order.append("-"); } else { } else { nullOrder.append(sortInfo.getDirection() == RelFieldCollation.Direction.DESCENDING ? "z" : "a");
public RelNode align(Join rel, List<RelFieldCollation> collations) { ImmutableList.Builder<RelFieldCollation> propagateCollationsLeft = ImmutableList.builder(); ImmutableList.Builder<RelFieldCollation> propagateCollationsRight = ImmutableList.builder(); final int nLeftColumns = rel.getLeft().getRowType().getFieldList().size(); Map<Integer,RexNode> idxToConjuncts = new HashMap<>(); Map<Integer,Integer> refToRef = new HashMap<>(); RexNode equals = idxToConjuncts.get(c.getFieldIndex()); if (equals != null) { conjuncts.add(equals); idxToConjuncts.remove(c.getFieldIndex()); idxToConjuncts.remove(refToRef.get(c.getFieldIndex())); if (c.getFieldIndex() < nLeftColumns) { propagateCollationsLeft.add(c.copy(c.getFieldIndex())); propagateCollationsRight.add(c.copy(refToRef.get(c.getFieldIndex()) - nLeftColumns)); } else { propagateCollationsLeft.add(c.copy(refToRef.get(c.getFieldIndex()))); propagateCollationsRight.add(c.copy(c.getFieldIndex() - nLeftColumns)); propagateCollationsLeft.add(new RelFieldCollation(e.getKey())); propagateCollationsRight.add(new RelFieldCollation(refToRef.get(e.getKey()) - nLeftColumns)); } else { propagateCollationsLeft.add(new RelFieldCollation(refToRef.get(e.getKey()))); propagateCollationsRight.add(new RelFieldCollation(e.getKey() - nLeftColumns));
public RelNode align(Aggregate rel, List<RelFieldCollation> collations) { // 1) We extract the group by positions that are part of the collations and // sort them so they respect it LinkedHashSet<Integer> aggregateColumnsOrder = new LinkedHashSet<>(); ImmutableList.Builder<RelFieldCollation> propagateCollations = ImmutableList.builder(); if (!rel.indicator && !collations.isEmpty()) { for (RelFieldCollation c : collations) { if (c.getFieldIndex() < rel.getGroupCount()) { // Group column found if (aggregateColumnsOrder.add(c.getFieldIndex())) { propagateCollations.add(c.copy(rel.getGroupSet().nth(c.getFieldIndex()))); } } } } for (int i = 0; i < rel.getGroupCount(); i++) { if (!aggregateColumnsOrder.contains(i)) { // Not included in the input collations, but can be propagated as this Aggregate // will enforce it propagateCollations.add(new RelFieldCollation(rel.getGroupSet().nth(i))); } } // 2) We propagate final RelNode child = dispatchAlign(rel.getInput(), propagateCollations.build()); // 3) We annotate the Aggregate operator with this info final HiveAggregate newAggregate = (HiveAggregate) rel.copy(rel.getTraitSet(), ImmutableList.of(child)); newAggregate.setAggregateColumnsOrder(aggregateColumnsOrder); return newAggregate; }
final List<RelCollation> inputCollations = mq.collations(input); if (inputCollations == null || inputCollations.isEmpty()) { return ImmutableList.of(); final RexCall call = (RexCall) project.e; final RexCallBinding binding = RexCallBinding.create(input.getCluster().getTypeFactory(), call, inputCollations); targetsWithMonotonicity.put(project.i, call.getOperator().getMonotonicity(binding)); loop: for (RelCollation ic : inputCollations) { if (ic.getFieldCollations().isEmpty()) { continue; for (RelFieldCollation ifc : ic.getFieldCollations()) { final Collection<Integer> integers = targets.get(ifc.getFieldIndex()); if (integers.isEmpty()) { continue loop; // cannot do this collation fieldCollations.add(ifc.copy(integers.iterator().next())); default: fieldCollationsForRexCalls.add( new RelFieldCollation(entry.getKey(), RelFieldCollation.Direction.of(value))); break; return ImmutableList.copyOf(collations);
RelCollations.of(new RelFieldCollation(0), new RelFieldCollation(1)); collations = RelMdCollation.sort(collation); assertThat(collations.size(), equalTo(1)); assertThat(collations.get(0).getFieldCollations().size(), equalTo(2)); ImmutableList.of(rexBuilder.makeInputRef(empSort, 1), rexBuilder.makeLiteral("foo"), rexBuilder.makeInputRef(empSort, 0), collations = RelMdCollation.project(mq, empSort, projects); assertThat(collations.size(), equalTo(1)); assertThat(collations.get(0).getFieldCollations().size(), equalTo(2)); assertThat(collations.get(0).getFieldCollations().get(0).getFieldIndex(), equalTo(2)); assertThat(collations.get(0).getFieldCollations().get(1).getFieldIndex(), equalTo(0)); ImmutableList.of("a", "b", "c", "d")); RelCollations.of(new RelFieldCollation(0), new RelFieldCollation(1)); final Sort deptSort = LogicalSort.create(deptScan, deptCollation, null, null); LogicalValues.create(cluster, rowType, tuples.build()); assertThat(mq.collations(values), equalTo(collations));
private Statistic buildStatistic() { if (stats != null || primaryKey == -1) { return stats; } Direction dir = primaryKeyMonotonicity == INCREASING ? ASCENDING : DESCENDING; RelFieldCollation collation = new RelFieldCollation(primaryKey, dir, NullDirection.UNSPECIFIED); return Statistics.of(fields.size(), ImmutableList.of(ImmutableBitSet.of(primaryKey)), ImmutableList.of(RelCollations.of(collation))); }
public static RelCollation of(List<RelFieldCollation> fieldCollations) { if (Util.isDistinct(ordinals(fieldCollations))) { return new RelCollationImpl(ImmutableList.copyOf(fieldCollations)); } // Remove field collations whose field has already been seen final ImmutableList.Builder<RelFieldCollation> builder = ImmutableList.builder(); final Set<Integer> set = new HashSet<>(); for (RelFieldCollation fieldCollation : fieldCollations) { if (set.add(fieldCollation.getFieldIndex())) { builder.add(fieldCollation); } } return new RelCollationImpl(builder.build()); }
project.getProjects(), project.getInput().getRowType()); for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) { if (map.getTargetOpt(fc.getFieldIndex()) < 0) { return; final RexNode node = project.getProjects().get(fc.getFieldIndex()); if (node.isA(SqlKind.CAST)) { final RexCallBinding binding = RexCallBinding.create(cluster.getTypeFactory(), cast, ImmutableList.of(RelCollations.of(RexUtil.apply(map, fc)))); if (cast.getOperator().getMonotonicity(binding) == SqlMonotonicity.NOT_MONOTONIC) { return; project.copy( sort.getTraitSet(), ImmutableList.of(newSort));
project.getProjects(), project.getInput().getRowType()).inverse(); Set<Integer> needed = new HashSet<>(); for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) { needed.add(fc.getFieldIndex()); final RexNode node = project.getProjects().get(map.getTarget(fc.getFieldIndex())); if (node.isA(SqlKind.CAST)) { final RexCallBinding binding = RexCallBinding.create(cluster.getTypeFactory(), cast, ImmutableList.of(RexUtil.apply(map, sort.getCollation()))); if (cast.getOperator().getMonotonicity(binding) == SqlMonotonicity.NOT_MONOTONIC) { return; for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) { fieldCollations.add(new RelFieldCollation(m.get(fc.getFieldIndex()), fc.direction, fc.nullDirection)); final RelNode newProject = project.copy(sort.getInput().getTraitSet(), ImmutableList.<RelNode>of(sort.getInput())); final HiveSortLimit newSort = sort.copy(newProject.getTraitSet(), newProject, newCollation, sort.offset, sort.fetch);
final Sort sort = call.rel(1); final int count = sort.getInput().getRowType().getFieldCount(); if (count == 1) { List<RelDataTypeField> fields = sort.getInput().getRowType().getFieldList(); List<Pair<RexNode, String>> newChildExprs = new ArrayList<>(); List<RexNode> topChildExprs = new ArrayList<>(); RelOptUtil.permutation(Pair.left(newChildExprs), sort.getInput().getRowType()).inverse(); List<RelFieldCollation> fieldCollations = new ArrayList<>(); for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) { final int target = mapping.getTargetOpt(fc.getFieldIndex()); if (target < 0) { fieldCollations.add(fc.copy(target)); topChildExprs = ImmutableList.copyOf(RexUtil.apply(mapping, topChildExprs));
/** Returns references to fields for a given collation. */ public ImmutableList<RexNode> fields(RelCollation collation) { final ImmutableList.Builder<RexNode> nodes = ImmutableList.builder(); for (RelFieldCollation fieldCollation : collation.getFieldCollations()) { RexNode node = field(fieldCollation.getFieldIndex()); switch (fieldCollation.direction) { case DESCENDING: node = desc(node); } switch (fieldCollation.nullDirection) { case FIRST: node = nullsFirst(node); break; case LAST: node = nullsLast(node); break; } nodes.add(node); } return nodes.build(); }
if (i < rels.size() && rels.get(i) instanceof Filter) { filterRel = (Filter) rels.get(i++); groupSet = aggregate.getGroupSet(); aggCalls = aggregate.getAggCallList(); aggNames = Util.skip(aggregate.getRowType().getFieldNames(), groupSet.cardinality()); collationIndexes = new ArrayList<>(); collationDirections = new ArrayList<>(); for (RelFieldCollation fCol : sort.collation.getFieldCollations()) { collationIndexes.add(fCol.getFieldIndex()); collationDirections.add(fCol.getDirection()); if (sort.getRowType().getFieldList().get(fCol.getFieldIndex()).getType().getFamily() == SqlTypeFamily.NUMERIC) { numericCollationBitSetBuilder.set(fCol.getFieldIndex());
final List<String> childFields = getInput().getRowType().getFieldNames(); checkState(groups.size() == 1, "Only one window is expected in WindowPrel"); Group window = groups.get(0); List<NamedExpression> withins = Lists.newArrayList(); List<NamedExpression> aggs = Lists.newArrayList(); for (RelFieldCollation fieldCollation : window.orderKeys.getFieldCollations()) { orderings.add(new Order.Ordering(fieldCollation.getDirection(), new FieldReference(childFields.get(fieldCollation.getFieldIndex())), fieldCollation.nullDirection));
if (root.rel instanceof LogicalProject) { rootPrj = (LogicalProject) root.rel; } else if (root.rel instanceof LogicalSort && root.rel.getInput(0) instanceof LogicalProject) { rootPrj = (LogicalProject) root.rel.getInput(0); rootSort = (LogicalSort) root.rel; } else { List<String> inFields = inType.getFieldNames(); List<RexNode> projExp = new ArrayList<>(); List<Pair<Integer, String>> projFields = new ArrayList<>(); for (int i = 0; i < root.validatedRowType.getFieldList().size(); i++) { if (root.validatedRowType.getFieldNames().get(i).startsWith("_KY_")) hiddenColumnExists = true; List<RelFieldCollation> fieldCollations = originalCollation.getFieldCollations(); ImmutableList.Builder<RelFieldCollation> newFieldCollations = ImmutableList.builder(); for (RelFieldCollation fieldCollation : fieldCollations) { if(projFieldMapping.containsKey(fieldCollation.getFieldIndex())) { newFieldCollations.add(fieldCollation.copy(projFieldMapping.get(fieldCollation.getFieldIndex()))); } else { newFieldCollations.add(fieldCollation); newCollation = RelCollationImpl.of(newFieldCollations.build()); rootSort = LogicalSort.create(rootPrj, newCollation, rootSort.offset, rootSort.fetch);
public RelWriter explainTerms(RelWriter pw) { super.explainTerms(pw); assert fieldExps.size() == collation.getFieldCollations().size(); if (pw.nest()) { pw.item("collation", collation); } else { for (Ord<RexNode> ord : Ord.zip(fieldExps)) { pw.item("sort" + ord.i, ord.e); } for (Ord<RelFieldCollation> ord : Ord.zip(collation.getFieldCollations())) { pw.item("dir" + ord.i, ord.e.shortString()); } } pw.itemIf("offset", offset, offset != null); pw.itemIf("fetch", fetch, fetch != null); return pw; } }
/** Returns a string representation of this collation, suitably terse given * that it will appear in plan traces. Examples: * "[]", "[2]", "[0 DESC, 1]", "[0 DESC, 1 ASC NULLS LAST]". */ public String toString() { Iterator<RelFieldCollation> it = fieldCollations.iterator(); if (! it.hasNext()) { return "[]"; } StringBuilder sb = new StringBuilder(); sb.append('['); for (;;) { RelFieldCollation e = it.next(); sb.append(e.getFieldIndex()); if (e.direction != RelFieldCollation.Direction.ASCENDING || e.nullDirection != e.direction.defaultNullDirection()) { sb.append(' ').append(e.shortString()); } if (!it.hasNext()) { return sb.append(']').toString(); } sb.append(',').append(' '); } }
public int compareTo(@Nonnull RelMultipleTrait o) { final RelCollationImpl that = (RelCollationImpl) o; final UnmodifiableIterator<RelFieldCollation> iterator = that.fieldCollations.iterator(); for (RelFieldCollation f : fieldCollations) { if (!iterator.hasNext()) { return 1; } final RelFieldCollation f2 = iterator.next(); int c = Utilities.compare(f.getFieldIndex(), f2.getFieldIndex()); if (c != 0) { return c; } } return iterator.hasNext() ? -1 : 0; }
public static List<Ordering> getOrdering(RelCollation collation, RelDataType rowType) { List<Ordering> orderExpr = Lists.newArrayList(); final List<String> childFields = rowType.getFieldNames(); for (RelFieldCollation fc: collation.getFieldCollations() ) { FieldReference fr = new FieldReference(childFields.get(fc.getFieldIndex()), false); orderExpr.add(new Ordering(fc.getDirection(), fr, fc.nullDirection)); } return orderExpr; }
if (sortLimit.getCollation() != RelCollations.EMPTY) { for (RelFieldCollation relFieldCollation : sortLimit.getCollation().getFieldCollations()) { if (relFieldCollation.getFieldIndex() >= join.getLeft().getRowType().getFieldCount()) { return false; if (sortLimit.getCollation() != RelCollations.EMPTY) { for (RelFieldCollation relFieldCollation : sortLimit.getCollation().getFieldCollations()) { if (relFieldCollation.getFieldIndex() < join.getLeft().getRowType().getFieldCount()) { return false;