/** * Derives the list of column names suitable for NATURAL JOIN. These are the columns that occur * exactly once on each side of the join. * * @param leftRowType Row type of left input to the join * @param rightRowType Row type of right input to the join * @return List of columns that occur once on each side */ public static List<String> deriveNaturalJoinColumnList( RelDataType leftRowType, RelDataType rightRowType) { List<String> naturalColumnNames = new ArrayList<String>(); final List<String> leftNames = leftRowType.getFieldNames(); final List<String> rightNames = rightRowType.getFieldNames(); for (String name : leftNames) { if ((Collections.frequency(leftNames, name) == 1) && (Collections.frequency(rightNames, name) == 1)) { naturalColumnNames.add(name); } } return naturalColumnNames; }
private List<AggregateCall> transformAggCalls( RelDataTypeFactory typeFactory, int nGroupCols, List<AggregateCall> origCalls) { List<AggregateCall> newCalls = new ArrayList<AggregateCall>(); int iInput = nGroupCols; for (AggregateCall origCall : origCalls) { if (origCall.isDistinct() || !SUPPORTED_AGGREGATES.containsKey(origCall.getAggregation().getClass())) { return null; } Aggregation aggFun; RelDataType aggType; if (origCall.getAggregation().getName().equals("COUNT")) { aggFun = new SqlSumEmptyIsZeroAggFunction(origCall.getType()); SqlAggFunction af = (SqlAggFunction) aggFun; final AggregateRelBase.AggCallBinding binding = new AggregateRelBase.AggCallBinding( typeFactory, af, Collections.singletonList(origCall.getType()), nGroupCols); // count(any) is always not null, however nullability of sum might // depend on the number of columns in GROUP BY. // Here we use SUM0 since we are sure we will not face nullable // inputs nor we'll face empty set. aggType = af.inferReturnType(binding); } else { aggFun = origCall.getAggregation(); aggType = origCall.getType(); } AggregateCall newCall = new AggregateCall( aggFun, origCall.isDistinct(), Collections.singletonList(iInput), aggType, origCall.getName()); newCalls.add(newCall); ++iInput; } return newCalls; }
public static void getSchemaObjectMonikers( SqlValidatorCatalogReader catalogReader, List<String> names, List<SqlMoniker> hints) { // Assume that the last name is 'dummy' or similar. List<String> subNames = Util.skipLast(names); hints.addAll(catalogReader.getAllSchemaObjectNames(subNames)); // If the name has length 0, try prepending the name of the default // schema. So, the empty name would yield a list of tables in the // default schema, as well as a list of schemas from the above code. if (subNames.size() == 0) { hints.addAll( catalogReader.getAllSchemaObjectNames( Collections.singletonList(catalogReader.getSchemaName()))); } }
public void onMatch(RelOptRuleCall call) { ProjectRel project = (ProjectRel) call.rels[0]; List<RexNode> expList = new ArrayList<RexNode>(Arrays.asList(project.getChildExps())); if (reduceExpressions(project, expList)) { call.transformTo( new ProjectRel( project.getCluster(), project.getChild(), expList.toArray(new RexNode[expList.size()]), project.getRowType(), ProjectRel.Flags.Boxed, Collections.<RelCollation>emptyList())); // New plan is absolutely better than old plan. call.getPlanner().setImportance(project, 0.0); } }