use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexBuilder in project calcite by apache.
the class RelBuilder method call.
/**
* Creates a call to a scalar operator.
*/
private RexNode call(SqlOperator operator, List<RexNode> operandList) {
final RexBuilder builder = cluster.getRexBuilder();
final RelDataType type = builder.deriveReturnType(operator, operandList);
if (type == null) {
throw new IllegalArgumentException("cannot derive type: " + operator + "; operands: " + Lists.transform(operandList, FN_TYPE));
}
return builder.makeCall(type, operator, operandList);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexBuilder in project calcite by apache.
the class RelOptUtil method createRenameRel.
// to be removed before 2.0
@Deprecated
public static RelNode createRenameRel(RelDataType outputType, RelNode rel) {
RelDataType inputType = rel.getRowType();
List<RelDataTypeField> inputFields = inputType.getFieldList();
int n = inputFields.size();
List<RelDataTypeField> outputFields = outputType.getFieldList();
assert outputFields.size() == n : "rename: field count mismatch: in=" + inputType + ", out" + outputType;
final List<Pair<RexNode, String>> renames = new ArrayList<>();
for (Pair<RelDataTypeField, RelDataTypeField> pair : Pair.zip(inputFields, outputFields)) {
final RelDataTypeField inputField = pair.left;
final RelDataTypeField outputField = pair.right;
assert inputField.getType().equals(outputField.getType());
final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
renames.add(Pair.<RexNode, String>of(rexBuilder.makeInputRef(inputField.getType(), inputField.getIndex()), outputField.getName()));
}
final RelBuilder relBuilder = RelFactories.LOGICAL_BUILDER.create(rel.getCluster(), null);
return relBuilder.push(rel).project(Pair.left(renames), Pair.right(renames), true).build();
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexBuilder in project calcite by apache.
the class RelOptUtil method createExistsPlan.
/**
* Creates a plan suitable for use in <code>EXISTS</code> or <code>IN</code>
* statements.
*
* @see org.apache.calcite.sql2rel.SqlToRelConverter#convertExists
*
* @param seekRel A query rel, for example the resulting rel from 'select *
* from emp' or 'values (1,2,3)' or '('Foo', 34)'.
* @param subQueryType Sub-query type
* @param logic Whether to use 2- or 3-valued boolean logic
* @param notIn Whether the operator is NOT IN
* @param relBuilder Builder for relational expressions
*
* @return A pair of a relational expression which outer joins a boolean
* condition column, and a numeric offset. The offset is 2 if column 0 is
* the number of rows and column 1 is the number of rows with not-null keys;
* 0 otherwise.
*/
public static Exists createExistsPlan(RelNode seekRel, SubQueryType subQueryType, Logic logic, boolean notIn, RelBuilder relBuilder) {
switch(subQueryType) {
case SCALAR:
return new Exists(seekRel, false, true);
}
switch(logic) {
case TRUE_FALSE_UNKNOWN:
case UNKNOWN_AS_TRUE:
if (notIn && !containsNullableFields(seekRel)) {
logic = Logic.TRUE_FALSE;
}
}
RelNode ret = seekRel;
final RelOptCluster cluster = seekRel.getCluster();
final RexBuilder rexBuilder = cluster.getRexBuilder();
final int keyCount = ret.getRowType().getFieldCount();
final boolean outerJoin = notIn || logic == RelOptUtil.Logic.TRUE_FALSE_UNKNOWN;
if (!outerJoin) {
final LogicalAggregate aggregate = LogicalAggregate.create(ret, ImmutableBitSet.range(keyCount), null, ImmutableList.<AggregateCall>of());
return new Exists(aggregate, false, false);
}
// for IN/NOT IN, it needs to output the fields
final List<RexNode> exprs = new ArrayList<>();
if (subQueryType == SubQueryType.IN) {
for (int i = 0; i < keyCount; i++) {
exprs.add(rexBuilder.makeInputRef(ret, i));
}
}
final int projectedKeyCount = exprs.size();
exprs.add(rexBuilder.makeLiteral(true));
ret = relBuilder.push(ret).project(exprs).build();
final AggregateCall aggCall = AggregateCall.create(SqlStdOperatorTable.MIN, false, false, ImmutableList.of(projectedKeyCount), -1, projectedKeyCount, ret, null, null);
ret = LogicalAggregate.create(ret, ImmutableBitSet.range(projectedKeyCount), null, ImmutableList.of(aggCall));
switch(logic) {
case TRUE_FALSE_UNKNOWN:
case UNKNOWN_AS_TRUE:
return new Exists(ret, true, true);
default:
return new Exists(ret, false, true);
}
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexBuilder in project calcite by apache.
the class RelOptUtil method splitJoinCondition.
private static void splitJoinCondition(List<RelDataTypeField> sysFieldList, List<RelNode> inputs, RexNode condition, List<List<RexNode>> joinKeys, List<Integer> filterNulls, List<SqlOperator> rangeOp, List<RexNode> nonEquiList) {
final int sysFieldCount = sysFieldList.size();
final RelOptCluster cluster = inputs.get(0).getCluster();
final RexBuilder rexBuilder = cluster.getRexBuilder();
final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
final ImmutableBitSet[] inputsRange = new ImmutableBitSet[inputs.size()];
int totalFieldCount = 0;
for (int i = 0; i < inputs.size(); i++) {
final int firstField = totalFieldCount + sysFieldCount;
totalFieldCount = firstField + inputs.get(i).getRowType().getFieldCount();
inputsRange[i] = ImmutableBitSet.range(firstField, totalFieldCount);
}
// adjustment array
int[] adjustments = new int[totalFieldCount];
for (int i = 0; i < inputs.size(); i++) {
final int adjustment = inputsRange[i].nextSetBit(0);
for (int j = adjustment; j < inputsRange[i].length(); j++) {
adjustments[j] = -adjustment;
}
}
if (condition instanceof RexCall) {
RexCall call = (RexCall) condition;
if (call.getKind() == SqlKind.AND) {
for (RexNode operand : call.getOperands()) {
splitJoinCondition(sysFieldList, inputs, operand, joinKeys, filterNulls, rangeOp, nonEquiList);
}
return;
}
RexNode leftKey = null;
RexNode rightKey = null;
int leftInput = 0;
int rightInput = 0;
List<RelDataTypeField> leftFields = null;
List<RelDataTypeField> rightFields = null;
boolean reverse = false;
call = collapseExpandedIsNotDistinctFromExpr(call, rexBuilder);
SqlKind kind = call.getKind();
// Only consider range operators if we haven't already seen one
if ((kind == SqlKind.EQUALS) || (filterNulls != null && kind == SqlKind.IS_NOT_DISTINCT_FROM) || (rangeOp != null && rangeOp.isEmpty() && (kind == SqlKind.GREATER_THAN || kind == SqlKind.GREATER_THAN_OR_EQUAL || kind == SqlKind.LESS_THAN || kind == SqlKind.LESS_THAN_OR_EQUAL))) {
final List<RexNode> operands = call.getOperands();
RexNode op0 = operands.get(0);
RexNode op1 = operands.get(1);
final ImmutableBitSet projRefs0 = InputFinder.bits(op0);
final ImmutableBitSet projRefs1 = InputFinder.bits(op1);
boolean foundBothInputs = false;
for (int i = 0; i < inputs.size() && !foundBothInputs; i++) {
if (projRefs0.intersects(inputsRange[i]) && projRefs0.union(inputsRange[i]).equals(inputsRange[i])) {
if (leftKey == null) {
leftKey = op0;
leftInput = i;
leftFields = inputs.get(leftInput).getRowType().getFieldList();
} else {
rightKey = op0;
rightInput = i;
rightFields = inputs.get(rightInput).getRowType().getFieldList();
reverse = true;
foundBothInputs = true;
}
} else if (projRefs1.intersects(inputsRange[i]) && projRefs1.union(inputsRange[i]).equals(inputsRange[i])) {
if (leftKey == null) {
leftKey = op1;
leftInput = i;
leftFields = inputs.get(leftInput).getRowType().getFieldList();
} else {
rightKey = op1;
rightInput = i;
rightFields = inputs.get(rightInput).getRowType().getFieldList();
foundBothInputs = true;
}
}
}
if ((leftKey != null) && (rightKey != null)) {
// replace right Key input ref
rightKey = rightKey.accept(new RelOptUtil.RexInputConverter(rexBuilder, rightFields, rightFields, adjustments));
// left key only needs to be adjusted if there are system
// fields, but do it for uniformity
leftKey = leftKey.accept(new RelOptUtil.RexInputConverter(rexBuilder, leftFields, leftFields, adjustments));
RelDataType leftKeyType = leftKey.getType();
RelDataType rightKeyType = rightKey.getType();
if (leftKeyType != rightKeyType) {
// perform casting
RelDataType targetKeyType = typeFactory.leastRestrictive(ImmutableList.of(leftKeyType, rightKeyType));
if (targetKeyType == null) {
throw new AssertionError("Cannot find common type for join keys " + leftKey + " (type " + leftKeyType + ") and " + rightKey + " (type " + rightKeyType + ")");
}
if (leftKeyType != targetKeyType) {
leftKey = rexBuilder.makeCast(targetKeyType, leftKey);
}
if (rightKeyType != targetKeyType) {
rightKey = rexBuilder.makeCast(targetKeyType, rightKey);
}
}
}
}
if ((rangeOp == null) && ((leftKey == null) || (rightKey == null))) {
// no equality join keys found yet:
// try transforming the condition to
// equality "join" conditions, e.g.
// f(LHS) > 0 ===> ( f(LHS) > 0 ) = TRUE,
// and make the RHS produce TRUE, but only if we're strictly
// looking for equi-joins
final ImmutableBitSet projRefs = InputFinder.bits(condition);
leftKey = null;
rightKey = null;
boolean foundInput = false;
for (int i = 0; i < inputs.size() && !foundInput; i++) {
if (inputsRange[i].contains(projRefs)) {
leftInput = i;
leftFields = inputs.get(leftInput).getRowType().getFieldList();
leftKey = condition.accept(new RelOptUtil.RexInputConverter(rexBuilder, leftFields, leftFields, adjustments));
rightKey = rexBuilder.makeLiteral(true);
// effectively performing an equality comparison
kind = SqlKind.EQUALS;
foundInput = true;
}
}
}
if ((leftKey != null) && (rightKey != null)) {
// found suitable join keys
// add them to key list, ensuring that if there is a
// non-equi join predicate, it appears at the end of the
// key list; also mark the null filtering property
addJoinKey(joinKeys.get(leftInput), leftKey, (rangeOp != null) && !rangeOp.isEmpty());
addJoinKey(joinKeys.get(rightInput), rightKey, (rangeOp != null) && !rangeOp.isEmpty());
if (filterNulls != null && kind == SqlKind.EQUALS) {
// nulls are considered not matching for equality comparison
// add the position of the most recently inserted key
filterNulls.add(joinKeys.get(leftInput).size() - 1);
}
if (rangeOp != null && kind != SqlKind.EQUALS && kind != SqlKind.IS_DISTINCT_FROM) {
if (reverse) {
kind = kind.reverse();
}
rangeOp.add(op(kind, call.getOperator()));
}
return;
}
// else fall through and add this condition as nonEqui condition
}
// The operator is not of RexCall type
// So we fail. Fall through.
// Add this condition to the list of non-equi-join conditions.
nonEquiList.add(condition);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexBuilder in project calcite by apache.
the class RelOptUtil method projectJoinInputs.
// to be removed before 2.0
@Deprecated
public static void projectJoinInputs(RelNode[] inputRels, List<RexNode> leftJoinKeys, List<RexNode> rightJoinKeys, int systemColCount, List<Integer> leftKeys, List<Integer> rightKeys, List<Integer> outputProj) {
RelNode leftRel = inputRels[0];
RelNode rightRel = inputRels[1];
final RelOptCluster cluster = leftRel.getCluster();
final RexBuilder rexBuilder = cluster.getRexBuilder();
final RelDataTypeSystem typeSystem = cluster.getTypeFactory().getTypeSystem();
int origLeftInputSize = leftRel.getRowType().getFieldCount();
int origRightInputSize = rightRel.getRowType().getFieldCount();
final List<RexNode> newLeftFields = new ArrayList<>();
final List<String> newLeftFieldNames = new ArrayList<>();
final List<RexNode> newRightFields = new ArrayList<>();
final List<String> newRightFieldNames = new ArrayList<>();
int leftKeyCount = leftJoinKeys.size();
int rightKeyCount = rightJoinKeys.size();
int i;
for (i = 0; i < systemColCount; i++) {
outputProj.add(i);
}
for (i = 0; i < origLeftInputSize; i++) {
final RelDataTypeField field = leftRel.getRowType().getFieldList().get(i);
newLeftFields.add(rexBuilder.makeInputRef(field.getType(), i));
newLeftFieldNames.add(field.getName());
outputProj.add(systemColCount + i);
}
int newLeftKeyCount = 0;
for (i = 0; i < leftKeyCount; i++) {
RexNode leftKey = leftJoinKeys.get(i);
if (leftKey instanceof RexInputRef) {
// already added to the projected left fields
// only need to remember the index in the join key list
leftKeys.add(((RexInputRef) leftKey).getIndex());
} else {
newLeftFields.add(leftKey);
newLeftFieldNames.add(null);
leftKeys.add(origLeftInputSize + newLeftKeyCount);
newLeftKeyCount++;
}
}
int leftFieldCount = origLeftInputSize + newLeftKeyCount;
for (i = 0; i < origRightInputSize; i++) {
final RelDataTypeField field = rightRel.getRowType().getFieldList().get(i);
newRightFields.add(rexBuilder.makeInputRef(field.getType(), i));
newRightFieldNames.add(field.getName());
outputProj.add(systemColCount + leftFieldCount + i);
}
int newRightKeyCount = 0;
for (i = 0; i < rightKeyCount; i++) {
RexNode rightKey = rightJoinKeys.get(i);
if (rightKey instanceof RexInputRef) {
// already added to the projected left fields
// only need to remember the index in the join key list
rightKeys.add(((RexInputRef) rightKey).getIndex());
} else {
newRightFields.add(rightKey);
newRightFieldNames.add(null);
rightKeys.add(origRightInputSize + newRightKeyCount);
newRightKeyCount++;
}
}
final RelBuilder relBuilder = RelFactories.LOGICAL_BUILDER.create(cluster, null);
// fields
if (newLeftKeyCount > 0) {
leftRel = relBuilder.push(leftRel).project(newLeftFields, newLeftFieldNames, true).build();
}
if (newRightKeyCount > 0) {
rightRel = relBuilder.push(rightRel).project(newRightFields, newRightFieldNames).build();
}
inputRels[0] = leftRel;
inputRels[1] = rightRel;
}
Aggregations