use of org.apache.calcite.rex.RexFieldAccess in project flink by apache.
the class RelDecorrelator method checkCorVars.
/**
* Checks whether the correlations in projRel and filter are related to the correlated variables
* provided by corRel.
*
* @param correlate Correlate
* @param project The original Project as the RHS input of the join
* @param filter Filter
* @param correlatedJoinKeys Correlated join keys
* @return true if filter and proj only references corVar provided by corRel
*/
private boolean checkCorVars(Correlate correlate, Project project, Filter filter, List<RexFieldAccess> correlatedJoinKeys) {
if (filter != null) {
assert correlatedJoinKeys != null;
// check that all correlated refs in the filter condition are
// used in the join(as field access).
Set<CorRef> corVarInFilter = Sets.newHashSet(cm.mapRefRelToCorRef.get(filter));
for (RexFieldAccess correlatedJoinKey : correlatedJoinKeys) {
corVarInFilter.remove(cm.mapFieldAccessToCorRef.get(correlatedJoinKey));
}
if (!corVarInFilter.isEmpty()) {
return false;
}
// Check that the correlated variables referenced in these
// comparisons do come from the Correlate.
corVarInFilter.addAll(cm.mapRefRelToCorRef.get(filter));
for (CorRef corVar : corVarInFilter) {
if (cm.mapCorToCorRel.get(corVar.corr) != correlate) {
return false;
}
}
}
// of the correlate.
if ((project != null) && cm.mapRefRelToCorRef.containsKey(project)) {
for (CorRef corVar : cm.mapRefRelToCorRef.get(project)) {
if (cm.mapCorToCorRel.get(corVar.corr) != correlate) {
return false;
}
}
}
return true;
}
use of org.apache.calcite.rex.RexFieldAccess in project flink by apache.
the class PythonMapMergeRule method isFlattenCalc.
private boolean isFlattenCalc(List<RexNode> middleProjects, int inputRowFieldCount) {
if (inputRowFieldCount != middleProjects.size()) {
return false;
}
for (int i = 0; i < inputRowFieldCount; i++) {
RexNode middleProject = middleProjects.get(i);
if (middleProject instanceof RexFieldAccess) {
RexFieldAccess rexField = ((RexFieldAccess) middleProject);
if (rexField.getField().getIndex() != i) {
return false;
}
RexNode expr = rexField.getReferenceExpr();
if (expr instanceof RexInputRef) {
if (((RexInputRef) expr).getIndex() != 0) {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
return true;
}
use of org.apache.calcite.rex.RexFieldAccess in project flink by apache.
the class PythonCorrelateSplitRule method createNewFieldNames.
private List<String> createNewFieldNames(RelDataType rowType, RexBuilder rexBuilder, int primitiveFieldCount, ArrayBuffer<RexNode> extractedRexNodes, List<RexNode> calcProjects) {
for (int i = 0; i < primitiveFieldCount; i++) {
calcProjects.add(RexInputRef.of(i, rowType));
}
// change RexCorrelVariable to RexInputRef.
RexDefaultVisitor<RexNode> visitor = new RexDefaultVisitor<RexNode>() {
@Override
public RexNode visitFieldAccess(RexFieldAccess fieldAccess) {
RexNode expr = fieldAccess.getReferenceExpr();
if (expr instanceof RexCorrelVariable) {
RelDataTypeField field = fieldAccess.getField();
return new RexInputRef(field.getIndex(), field.getType());
} else {
return rexBuilder.makeFieldAccess(expr.accept(this), fieldAccess.getField().getIndex());
}
}
@Override
public RexNode visitNode(RexNode rexNode) {
return rexNode;
}
};
// add the fields of the extracted rex calls.
Iterator<RexNode> iterator = extractedRexNodes.iterator();
while (iterator.hasNext()) {
RexNode rexNode = iterator.next();
if (rexNode instanceof RexCall) {
RexCall rexCall = (RexCall) rexNode;
List<RexNode> newProjects = rexCall.getOperands().stream().map(x -> x.accept(visitor)).collect(Collectors.toList());
RexCall newRexCall = rexCall.clone(rexCall.getType(), newProjects);
calcProjects.add(newRexCall);
} else {
calcProjects.add(rexNode);
}
}
List<String> nameList = new LinkedList<>();
for (int i = 0; i < primitiveFieldCount; i++) {
nameList.add(rowType.getFieldNames().get(i));
}
Iterator<Object> indicesIterator = extractedRexNodes.indices().iterator();
while (indicesIterator.hasNext()) {
nameList.add("f" + indicesIterator.next());
}
return SqlValidatorUtil.uniquify(nameList, rexBuilder.getTypeFactory().getTypeSystem().isSchemaCaseSensitive());
}
use of org.apache.calcite.rex.RexFieldAccess in project calcite by apache.
the class RelJson method toJson.
private Object toJson(RexNode node) {
final Map<String, Object> map;
switch(node.getKind()) {
case FIELD_ACCESS:
map = jsonBuilder.map();
final RexFieldAccess fieldAccess = (RexFieldAccess) node;
map.put("field", fieldAccess.getField().getName());
map.put("expr", toJson(fieldAccess.getReferenceExpr()));
return map;
case LITERAL:
final RexLiteral literal = (RexLiteral) node;
final Object value2 = literal.getValue2();
if (value2 == null) {
// Special treatment for null literal because (1) we wouldn't want
// 'null' to be confused as an empty expression and (2) for null
// literals we need an explicit type.
map = jsonBuilder.map();
map.put("literal", null);
map.put("type", literal.getTypeName().name());
return map;
}
return value2;
case INPUT_REF:
case LOCAL_REF:
map = jsonBuilder.map();
map.put("input", ((RexSlot) node).getIndex());
map.put("name", ((RexSlot) node).getName());
return map;
case CORREL_VARIABLE:
map = jsonBuilder.map();
map.put("correl", ((RexCorrelVariable) node).getName());
map.put("type", toJson(node.getType()));
return map;
default:
if (node instanceof RexCall) {
final RexCall call = (RexCall) node;
map = jsonBuilder.map();
map.put("op", toJson(call.getOperator()));
final List<Object> list = jsonBuilder.list();
for (RexNode operand : call.getOperands()) {
list.add(toJson(operand));
}
map.put("operands", list);
switch(node.getKind()) {
case CAST:
map.put("type", toJson(node.getType()));
}
if (call.getOperator() instanceof SqlFunction) {
if (((SqlFunction) call.getOperator()).getFunctionType().isUserDefined()) {
map.put("class", call.getOperator().getClass().getName());
}
}
return map;
}
throw new UnsupportedOperationException("unknown rex " + node);
}
}
use of org.apache.calcite.rex.RexFieldAccess in project calcite by apache.
the class SqlToRelConverter method getCorrelationUse.
private CorrelationUse getCorrelationUse(Blackboard bb, final RelNode r0) {
final Set<CorrelationId> correlatedVariables = RelOptUtil.getVariablesUsed(r0);
if (correlatedVariables.isEmpty()) {
return null;
}
final ImmutableBitSet.Builder requiredColumns = ImmutableBitSet.builder();
final List<CorrelationId> correlNames = Lists.newArrayList();
// All correlations must refer the same namespace since correlation
// produces exactly one correlation source.
// The same source might be referenced by different variables since
// DeferredLookups are not de-duplicated at create time.
SqlValidatorNamespace prevNs = null;
for (CorrelationId correlName : correlatedVariables) {
DeferredLookup lookup = mapCorrelToDeferred.get(correlName);
RexFieldAccess fieldAccess = lookup.getFieldAccess(correlName);
String originalRelName = lookup.getOriginalRelName();
String originalFieldName = fieldAccess.getField().getName();
final SqlNameMatcher nameMatcher = lookup.bb.scope.getValidator().getCatalogReader().nameMatcher();
final SqlValidatorScope.ResolvedImpl resolved = new SqlValidatorScope.ResolvedImpl();
lookup.bb.scope.resolve(ImmutableList.of(originalRelName), nameMatcher, false, resolved);
assert resolved.count() == 1;
final SqlValidatorScope.Resolve resolve = resolved.only();
final SqlValidatorNamespace foundNs = resolve.namespace;
final RelDataType rowType = resolve.rowType();
final int childNamespaceIndex = resolve.path.steps().get(0).i;
final SqlValidatorScope ancestorScope = resolve.scope;
boolean correlInCurrentScope = ancestorScope == bb.scope;
if (!correlInCurrentScope) {
continue;
}
if (prevNs == null) {
prevNs = foundNs;
} else {
assert prevNs == foundNs : "All correlation variables should resolve" + " to the same namespace." + " Prev ns=" + prevNs + ", new ns=" + foundNs;
}
int namespaceOffset = 0;
if (childNamespaceIndex > 0) {
// of output types from all the preceding namespaces
assert ancestorScope instanceof ListScope;
List<SqlValidatorNamespace> children = ((ListScope) ancestorScope).getChildren();
for (int i = 0; i < childNamespaceIndex; i++) {
SqlValidatorNamespace child = children.get(i);
namespaceOffset += child.getRowType().getFieldCount();
}
}
RexFieldAccess topLevelFieldAccess = fieldAccess;
while (topLevelFieldAccess.getReferenceExpr() instanceof RexFieldAccess) {
topLevelFieldAccess = (RexFieldAccess) topLevelFieldAccess.getReferenceExpr();
}
final RelDataTypeField field = rowType.getFieldList().get(topLevelFieldAccess.getField().getIndex() - namespaceOffset);
int pos = namespaceOffset + field.getIndex();
assert field.getType() == topLevelFieldAccess.getField().getType();
assert pos != -1;
if (bb.mapRootRelToFieldProjection.containsKey(bb.root)) {
// bb.root is an aggregate and only projects group by
// keys.
Map<Integer, Integer> exprProjection = bb.mapRootRelToFieldProjection.get(bb.root);
// the root of the outer relation.
if (exprProjection.containsKey(pos)) {
pos = exprProjection.get(pos);
} else {
// correl not grouped
throw new AssertionError("Identifier '" + originalRelName + "." + originalFieldName + "' is not a group expr");
}
}
requiredColumns.set(pos);
correlNames.add(correlName);
}
if (correlNames.isEmpty()) {
// None of the correlating variables originated in this scope.
return null;
}
RelNode r = r0;
if (correlNames.size() > 1) {
// The same table was referenced more than once.
// So we deduplicate.
r = DeduplicateCorrelateVariables.go(rexBuilder, correlNames.get(0), Util.skip(correlNames), r0);
// Add new node to leaves.
leaves.add(r);
}
return new CorrelationUse(correlNames.get(0), requiredColumns.build(), r);
}
Aggregations