use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class SqlToRelConverter method collectInsertTargets.
/**
* Given an INSERT statement, collects the list of names to be populated and
* the expressions to put in them.
*
* @param call Insert statement
* @param sourceRef Expression representing a row from the source
* relational expression
* @param targetColumnNames List of target column names, to be populated
* @param columnExprs List of expressions, to be populated
*/
protected void collectInsertTargets(SqlInsert call, final RexNode sourceRef, final List<String> targetColumnNames, List<RexNode> columnExprs) {
final RelOptTable targetTable = getTargetTable(call);
final RelDataType tableRowType = targetTable.getRowType();
SqlNodeList targetColumnList = call.getTargetColumnList();
if (targetColumnList == null) {
if (validator.getConformance().isInsertSubsetColumnsAllowed()) {
final RelDataType targetRowType = typeFactory.createStructType(tableRowType.getFieldList().subList(0, sourceRef.getType().getFieldCount()));
targetColumnNames.addAll(targetRowType.getFieldNames());
} else {
targetColumnNames.addAll(tableRowType.getFieldNames());
}
} else {
for (int i = 0; i < targetColumnList.size(); i++) {
SqlIdentifier id = (SqlIdentifier) targetColumnList.get(i);
RelDataTypeField field = SqlValidatorUtil.getTargetField(tableRowType, typeFactory, id, catalogReader, targetTable);
assert field != null : "column " + id.toString() + " not found";
targetColumnNames.add(field.getName());
}
}
final Blackboard bb = createInsertBlackboard(targetTable, sourceRef, targetColumnNames);
// Next, assign expressions for generated columns.
final List<ColumnStrategy> strategies = targetTable.getColumnStrategies();
for (String columnName : targetColumnNames) {
final int i = tableRowType.getFieldNames().indexOf(columnName);
final RexNode expr;
switch(strategies.get(i)) {
case STORED:
final InitializerExpressionFactory f = Util.first(targetTable.unwrap(InitializerExpressionFactory.class), NullInitializerExpressionFactory.INSTANCE);
expr = f.newColumnDefaultValue(targetTable, i, bb);
break;
case VIRTUAL:
expr = null;
break;
default:
expr = bb.nameToNodeMap.get(columnName);
}
columnExprs.add(expr);
}
// Remove virtual columns from the list.
for (int i = 0; i < targetColumnNames.size(); i++) {
if (columnExprs.get(i) == null) {
columnExprs.remove(i);
targetColumnNames.remove(i);
--i;
}
}
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class SqlToRelConverter method createSource.
/**
* Wraps a relational expression in the projects and filters implied by
* a {@link ModifiableView}.
*
* <p>The input relational expression is suitable for inserting into the view,
* and the returned relational expression is suitable for inserting into its
* delegate table.
*
* <p>In principle, the delegate table of a view might be another modifiable
* view, and if so, the process can be repeated.
*/
private RelNode createSource(RelOptTable targetTable, RelNode source, ModifiableView modifiableView, RelDataType delegateRowType) {
final ImmutableIntList mapping = modifiableView.getColumnMapping();
assert mapping.size() == targetTable.getRowType().getFieldCount();
// For columns represented in the mapping, the expression is just a field
// reference.
final Map<Integer, RexNode> projectMap = new HashMap<>();
final List<RexNode> filters = new ArrayList<>();
for (int i = 0; i < mapping.size(); i++) {
int target = mapping.get(i);
if (target >= 0) {
projectMap.put(target, RexInputRef.of(i, source.getRowType()));
}
}
// For columns that are not in the mapping, and have a constraint of the
// form "column = value", the expression is the literal "value".
//
// If a column has multiple constraints, the extra ones will become a
// filter.
final RexNode constraint = modifiableView.getConstraint(rexBuilder, delegateRowType);
RelOptUtil.inferViewPredicates(projectMap, filters, constraint);
final List<Pair<RexNode, String>> projects = new ArrayList<>();
for (RelDataTypeField field : delegateRowType.getFieldList()) {
RexNode node = projectMap.get(field.getIndex());
if (node == null) {
node = rexBuilder.makeNullLiteral(field.getType());
}
projects.add(Pair.of(rexBuilder.ensureType(field.getType(), node, false), field.getName()));
}
return relBuilder.push(source).projectNamed(Pair.left(projects), Pair.right(projects), false).filter(filters).build();
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class SqlToRelConverter method convertIdentifier.
private void convertIdentifier(Blackboard bb, SqlIdentifier id, SqlNodeList extendedColumns) {
final SqlValidatorNamespace fromNamespace = validator.getNamespace(id).resolve();
if (fromNamespace.getNode() != null) {
convertFrom(bb, fromNamespace.getNode());
return;
}
final String datasetName = datasetStack.isEmpty() ? null : datasetStack.peek();
final boolean[] usedDataset = { false };
RelOptTable table = SqlValidatorUtil.getRelOptTable(fromNamespace, catalogReader, datasetName, usedDataset);
if (extendedColumns != null && extendedColumns.size() > 0) {
assert table != null;
final SqlValidatorTable validatorTable = table.unwrap(SqlValidatorTable.class);
final List<RelDataTypeField> extendedFields = SqlValidatorUtil.getExtendedColumns(validator.getTypeFactory(), validatorTable, extendedColumns);
table = table.extend(extendedFields);
}
final RelNode tableRel;
if (config.isConvertTableAccess()) {
tableRel = toRel(table);
} else {
tableRel = LogicalTableScan.create(cluster, table);
}
bb.setRoot(tableRel, true);
if (usedDataset[0]) {
bb.setDataset(datasetName);
}
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class RelDecorrelator method decorrelateRel.
/**
* Rewrite LogicalProject.
*
* @param rel the project rel to rewrite
*/
public Frame decorrelateRel(LogicalProject rel) {
//
// Rewrite logic:
//
// 1. Pass along any correlated variables coming from the input.
//
final RelNode oldInput = rel.getInput();
Frame frame = getInvoke(oldInput, rel);
if (frame == null) {
// If input has not been rewritten, do not rewrite this rel.
return null;
}
final List<RexNode> oldProjects = rel.getProjects();
final List<RelDataTypeField> relOutput = rel.getRowType().getFieldList();
// Project projects the original expressions,
// plus any correlated variables the input wants to pass along.
final List<Pair<RexNode, String>> projects = Lists.newArrayList();
// and produce the correlated variables in the new output.
if (cm.mapRefRelToCorRef.containsKey(rel)) {
frame = decorrelateInputWithValueGenerator(rel, frame);
}
// Project projects the original expressions
final Map<Integer, Integer> mapOldToNewOutputs = new HashMap<>();
int newPos;
for (newPos = 0; newPos < oldProjects.size(); newPos++) {
projects.add(newPos, Pair.of(decorrelateExpr(currentRel, map, cm, oldProjects.get(newPos)), relOutput.get(newPos).getName()));
mapOldToNewOutputs.put(newPos, newPos);
}
// Project any correlated variables the input wants to pass along.
final SortedMap<CorDef, Integer> corDefOutputs = new TreeMap<>();
for (Map.Entry<CorDef, Integer> entry : frame.corDefOutputs.entrySet()) {
projects.add(RexInputRef.of2(entry.getValue(), frame.r.getRowType().getFieldList()));
corDefOutputs.put(entry.getKey(), newPos);
newPos++;
}
RelNode newProject = relBuilder.push(frame.r).projectNamed(Pair.left(projects), Pair.right(projects), true).build();
return register(rel, newProject, mapOldToNewOutputs, corDefOutputs);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class RelDecorrelator method decorrelateRel.
/**
* Rewrites a {@link LogicalAggregate}.
*
* @param rel Aggregate to rewrite
*/
public Frame decorrelateRel(LogicalAggregate rel) {
if (rel.getGroupType() != Aggregate.Group.SIMPLE) {
throw new AssertionError(Bug.CALCITE_461_FIXED);
}
// Aggregate itself should not reference corVars.
assert !cm.mapRefRelToCorRef.containsKey(rel);
final RelNode oldInput = rel.getInput();
final Frame frame = getInvoke(oldInput, rel);
if (frame == null) {
// If input has not been rewritten, do not rewrite this rel.
return null;
}
final RelNode newInput = frame.r;
// map from newInput
Map<Integer, Integer> mapNewInputToProjOutputs = new HashMap<>();
final int oldGroupKeyCount = rel.getGroupSet().cardinality();
// Project projects the original expressions,
// plus any correlated variables the input wants to pass along.
final List<Pair<RexNode, String>> projects = Lists.newArrayList();
List<RelDataTypeField> newInputOutput = newInput.getRowType().getFieldList();
int newPos = 0;
// oldInput has the original group by keys in the front.
final NavigableMap<Integer, RexLiteral> omittedConstants = new TreeMap<>();
for (int i = 0; i < oldGroupKeyCount; i++) {
final RexLiteral constant = projectedLiteral(newInput, i);
if (constant != null) {
// Exclude constants. Aggregate({true}) occurs because Aggregate({})
// would generate 1 row even when applied to an empty table.
omittedConstants.put(i, constant);
continue;
}
int newInputPos = frame.oldToNewOutputs.get(i);
projects.add(RexInputRef.of2(newInputPos, newInputOutput));
mapNewInputToProjOutputs.put(newInputPos, newPos);
newPos++;
}
final SortedMap<CorDef, Integer> corDefOutputs = new TreeMap<>();
if (!frame.corDefOutputs.isEmpty()) {
// position oldGroupKeyCount.
for (Map.Entry<CorDef, Integer> entry : frame.corDefOutputs.entrySet()) {
projects.add(RexInputRef.of2(entry.getValue(), newInputOutput));
corDefOutputs.put(entry.getKey(), newPos);
mapNewInputToProjOutputs.put(entry.getValue(), newPos);
newPos++;
}
}
// add the remaining fields
final int newGroupKeyCount = newPos;
for (int i = 0; i < newInputOutput.size(); i++) {
if (!mapNewInputToProjOutputs.containsKey(i)) {
projects.add(RexInputRef.of2(i, newInputOutput));
mapNewInputToProjOutputs.put(i, newPos);
newPos++;
}
}
assert newPos == newInputOutput.size();
// This Project will be what the old input maps to,
// replacing any previous mapping from old input).
RelNode newProject = relBuilder.push(newInput).projectNamed(Pair.left(projects), Pair.right(projects), true).build();
// update mappings:
// oldInput ----> newInput
//
// newProject
// |
// oldInput ----> newInput
//
// is transformed to
//
// oldInput ----> newProject
// |
// newInput
Map<Integer, Integer> combinedMap = Maps.newHashMap();
for (Integer oldInputPos : frame.oldToNewOutputs.keySet()) {
combinedMap.put(oldInputPos, mapNewInputToProjOutputs.get(frame.oldToNewOutputs.get(oldInputPos)));
}
register(oldInput, newProject, combinedMap, corDefOutputs);
// now it's time to rewrite the Aggregate
final ImmutableBitSet newGroupSet = ImmutableBitSet.range(newGroupKeyCount);
List<AggregateCall> newAggCalls = Lists.newArrayList();
List<AggregateCall> oldAggCalls = rel.getAggCallList();
int oldInputOutputFieldCount = rel.getGroupSet().cardinality();
int newInputOutputFieldCount = newGroupSet.cardinality();
int i = -1;
for (AggregateCall oldAggCall : oldAggCalls) {
++i;
List<Integer> oldAggArgs = oldAggCall.getArgList();
List<Integer> aggArgs = Lists.newArrayList();
// for the argument.
for (int oldPos : oldAggArgs) {
aggArgs.add(combinedMap.get(oldPos));
}
final int filterArg = oldAggCall.filterArg < 0 ? oldAggCall.filterArg : combinedMap.get(oldAggCall.filterArg);
newAggCalls.add(oldAggCall.adaptTo(newProject, aggArgs, filterArg, oldGroupKeyCount, newGroupKeyCount));
// The old to new output position mapping will be the same as that
// of newProject, plus any aggregates that the oldAgg produces.
combinedMap.put(oldInputOutputFieldCount + i, newInputOutputFieldCount + i);
}
relBuilder.push(LogicalAggregate.create(newProject, newGroupSet, null, newAggCalls));
if (!omittedConstants.isEmpty()) {
final List<RexNode> postProjects = new ArrayList<>(relBuilder.fields());
for (Map.Entry<Integer, RexLiteral> entry : omittedConstants.descendingMap().entrySet()) {
postProjects.add(entry.getKey() + frame.corDefOutputs.size(), entry.getValue());
}
relBuilder.project(postProjects);
}
// located at the same position as the input newProject.
return register(rel, relBuilder.build(), combinedMap, corDefOutputs);
}
Aggregations