use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelCollation in project calcite by apache.
the class RelFieldTrimmer method trimChild.
/**
* Trims the fields of an input relational expression.
*
* @param rel Relational expression
* @param input Input relational expression, whose fields to trim
* @param fieldsUsed Bitmap of fields needed by the consumer
* @return New relational expression and its field mapping
*/
protected TrimResult trimChild(RelNode rel, RelNode input, final ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
final ImmutableBitSet.Builder fieldsUsedBuilder = fieldsUsed.rebuild();
// Fields that define the collation cannot be discarded.
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
final ImmutableList<RelCollation> collations = mq.collations(input);
for (RelCollation collation : collations) {
for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
fieldsUsedBuilder.set(fieldCollation.getFieldIndex());
}
}
// fields.
for (final CorrelationId correlation : rel.getVariablesSet()) {
rel.accept(new CorrelationReferenceFinder() {
protected RexNode handle(RexFieldAccess fieldAccess) {
final RexCorrelVariable v = (RexCorrelVariable) fieldAccess.getReferenceExpr();
if (v.id.equals(correlation)) {
fieldsUsedBuilder.set(fieldAccess.getField().getIndex());
}
return fieldAccess;
}
});
}
return dispatchTrimFields(input, fieldsUsedBuilder.build(), extraFields);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelCollation in project calcite by apache.
the class RelFieldTrimmer method trimFields.
/**
* Variant of {@link #trimFields(RelNode, ImmutableBitSet, Set)} for
* {@link org.apache.calcite.rel.core.Sort}.
*/
public TrimResult trimFields(Sort sort, ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
final RelDataType rowType = sort.getRowType();
final int fieldCount = rowType.getFieldCount();
final RelCollation collation = sort.getCollation();
final RelNode input = sort.getInput();
// We use the fields used by the consumer, plus any fields used as sort
// keys.
final ImmutableBitSet.Builder inputFieldsUsed = fieldsUsed.rebuild();
for (RelFieldCollation field : collation.getFieldCollations()) {
inputFieldsUsed.set(field.getFieldIndex());
}
// Create input with trimmed columns.
final Set<RelDataTypeField> inputExtraFields = Collections.emptySet();
TrimResult trimResult = trimChild(sort, input, inputFieldsUsed.build(), inputExtraFields);
RelNode newInput = trimResult.left;
final Mapping inputMapping = trimResult.right;
// there's nothing we can do.
if (newInput == input && inputMapping.isIdentity() && fieldsUsed.cardinality() == fieldCount) {
return result(sort, Mappings.createIdentity(fieldCount));
}
// leave the Sort unchanged in case we have dynamic limits
if (sort.offset instanceof RexDynamicParam || sort.fetch instanceof RexDynamicParam) {
return result(sort, inputMapping);
}
relBuilder.push(newInput);
final int offset = sort.offset == null ? 0 : RexLiteral.intValue(sort.offset);
final int fetch = sort.fetch == null ? -1 : RexLiteral.intValue(sort.fetch);
final ImmutableList<RexNode> fields = relBuilder.fields(RexUtil.apply(inputMapping, collation));
relBuilder.sortLimit(offset, fetch, fields);
// needs them for its condition.
return result(relBuilder.build(), inputMapping);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelCollation in project calcite by apache.
the class CalcitePrepareImpl method prepare2_.
<T> CalciteSignature<T> prepare2_(Context context, Query<T> query, Type elementType, long maxRowCount, CalciteCatalogReader catalogReader, RelOptPlanner planner) {
final JavaTypeFactory typeFactory = context.getTypeFactory();
final EnumerableRel.Prefer prefer;
if (elementType == Object[].class) {
prefer = EnumerableRel.Prefer.ARRAY;
} else {
prefer = EnumerableRel.Prefer.CUSTOM;
}
final Convention resultConvention = enableBindable ? BindableConvention.INSTANCE : EnumerableConvention.INSTANCE;
final CalcitePreparingStmt preparingStmt = new CalcitePreparingStmt(this, context, catalogReader, typeFactory, context.getRootSchema(), prefer, planner, resultConvention, createConvertletTable());
final RelDataType x;
final Prepare.PreparedResult preparedResult;
final Meta.StatementType statementType;
if (query.sql != null) {
final CalciteConnectionConfig config = context.config();
final SqlParser.ConfigBuilder parserConfig = createParserConfig().setQuotedCasing(config.quotedCasing()).setUnquotedCasing(config.unquotedCasing()).setQuoting(config.quoting()).setConformance(config.conformance()).setCaseSensitive(config.caseSensitive());
final SqlParserImplFactory parserFactory = config.parserFactory(SqlParserImplFactory.class, null);
if (parserFactory != null) {
parserConfig.setParserFactory(parserFactory);
}
SqlParser parser = createParser(query.sql, parserConfig);
SqlNode sqlNode;
try {
sqlNode = parser.parseStmt();
statementType = getStatementType(sqlNode.getKind());
} catch (SqlParseException e) {
throw new RuntimeException("parse failed: " + e.getMessage(), e);
}
Hook.PARSE_TREE.run(new Object[] { query.sql, sqlNode });
if (sqlNode.getKind().belongsTo(SqlKind.DDL)) {
executeDdl(context, sqlNode);
return new CalciteSignature<>(query.sql, ImmutableList.<AvaticaParameter>of(), ImmutableMap.<String, Object>of(), null, ImmutableList.<ColumnMetaData>of(), Meta.CursorFactory.OBJECT, null, ImmutableList.<RelCollation>of(), -1, null, Meta.StatementType.OTHER_DDL);
}
final SqlValidator validator = createSqlValidator(context, catalogReader);
validator.setIdentifierExpansion(true);
validator.setDefaultNullCollation(config.defaultNullCollation());
preparedResult = preparingStmt.prepareSql(sqlNode, Object.class, validator, true);
switch(sqlNode.getKind()) {
case INSERT:
case DELETE:
case UPDATE:
case EXPLAIN:
// FIXME: getValidatedNodeType is wrong for DML
x = RelOptUtil.createDmlRowType(sqlNode.getKind(), typeFactory);
break;
default:
x = validator.getValidatedNodeType(sqlNode);
}
} else if (query.queryable != null) {
x = context.getTypeFactory().createType(elementType);
preparedResult = preparingStmt.prepareQueryable(query.queryable, x);
statementType = getStatementType(preparedResult);
} else {
assert query.rel != null;
x = query.rel.getRowType();
preparedResult = preparingStmt.prepareRel(query.rel);
statementType = getStatementType(preparedResult);
}
final List<AvaticaParameter> parameters = new ArrayList<>();
final RelDataType parameterRowType = preparedResult.getParameterRowType();
for (RelDataTypeField field : parameterRowType.getFieldList()) {
RelDataType type = field.getType();
parameters.add(new AvaticaParameter(false, getPrecision(type), getScale(type), getTypeOrdinal(type), getTypeName(type), getClassName(type), field.getName()));
}
RelDataType jdbcType = makeStruct(typeFactory, x);
final List<List<String>> originList = preparedResult.getFieldOrigins();
final List<ColumnMetaData> columns = getColumnMetaDataList(typeFactory, x, jdbcType, originList);
Class resultClazz = null;
if (preparedResult instanceof Typed) {
resultClazz = (Class) ((Typed) preparedResult).getElementType();
}
final Meta.CursorFactory cursorFactory = preparingStmt.resultConvention == BindableConvention.INSTANCE ? Meta.CursorFactory.ARRAY : Meta.CursorFactory.deduce(columns, resultClazz);
// noinspection unchecked
final Bindable<T> bindable = preparedResult.getBindable(cursorFactory);
return new CalciteSignature<>(query.sql, parameters, preparingStmt.internalParameters, jdbcType, columns, cursorFactory, context.getRootSchema(), preparedResult instanceof Prepare.PreparedResultImpl ? ((Prepare.PreparedResultImpl) preparedResult).collations : ImmutableList.<RelCollation>of(), maxRowCount, bindable, statementType);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelCollation in project calcite by apache.
the class SortProjectTransposeRule method onMatch.
// ~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
final Sort sort = call.rel(0);
final Project project = call.rel(1);
final RelOptCluster cluster = project.getCluster();
if (sort.getConvention() != project.getConvention()) {
return;
}
// Determine mapping between project input and output fields. If sort
// relies on non-trivial expressions, we can't push.
final Mappings.TargetMapping map = RelOptUtil.permutationIgnoreCast(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)) {
// Check whether it is a monotonic preserving cast, otherwise we cannot push
final RexCall cast = (RexCall) node;
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;
}
}
}
final RelCollation newCollation = cluster.traitSet().canonize(RexUtil.apply(map, sort.getCollation()));
final Sort newSort = sort.copy(sort.getTraitSet().replace(newCollation), project.getInput(), newCollation, sort.offset, sort.fetch);
RelNode newProject = project.copy(sort.getTraitSet(), ImmutableList.<RelNode>of(newSort));
// Not only is newProject equivalent to sort;
// newSort is equivalent to project's input
// (but only if the sort is not also applying an offset/limit).
Map<RelNode, RelNode> equiv;
if (sort.offset == null && sort.fetch == null && cluster.getPlanner().getRelTraitDefs().contains(RelCollationTraitDef.INSTANCE)) {
equiv = ImmutableMap.of((RelNode) newSort, project.getInput());
} else {
equiv = ImmutableMap.of();
}
call.transformTo(newProject, equiv);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelCollation in project calcite by apache.
the class SortRemoveRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
if (!call.getPlanner().getRelTraitDefs().contains(RelCollationTraitDef.INSTANCE)) {
// Collation is not an active trait.
return;
}
final Sort sort = call.rel(0);
if (sort.offset != null || sort.fetch != null) {
// Don't remove sort if would also remove OFFSET or LIMIT.
return;
}
// Express the "sortedness" requirement in terms of a collation trait and
// we can get rid of the sort. This allows us to use rels that just happen
// to be sorted but get the same effect.
final RelCollation collation = sort.getCollation();
assert collation == sort.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE);
final RelTraitSet traits = sort.getInput().getTraitSet().replace(collation);
call.transformTo(convert(sort.getInput(), traits));
}
Aggregations