use of org.apache.calcite.rex.RexCall in project hive by apache.
the class PlanModifierUtil method fixTopOBSchema.
protected static void fixTopOBSchema(final RelNode rootRel, Pair<RelNode, RelNode> topSelparentPair, List<FieldSchema> resultSchema, boolean replaceProject) throws CalciteSemanticException {
if (!(topSelparentPair.getKey() instanceof Sort) || !HiveCalciteUtil.orderRelNode(topSelparentPair.getKey())) {
return;
}
HiveSortLimit obRel = (HiveSortLimit) topSelparentPair.getKey();
Project obChild = (Project) topSelparentPair.getValue();
if (obChild.getRowType().getFieldCount() <= resultSchema.size()) {
return;
}
RelDataType rt = obChild.getRowType();
@SuppressWarnings({ "unchecked", "rawtypes" }) Set<Integer> collationInputRefs = new HashSet(RelCollations.ordinals(obRel.getCollation()));
ImmutableMap.Builder<Integer, RexNode> inputRefToCallMapBldr = ImmutableMap.builder();
for (int i = resultSchema.size(); i < rt.getFieldCount(); i++) {
if (collationInputRefs.contains(i)) {
RexNode obyExpr = obChild.getProjects().get(i);
if (obyExpr instanceof RexCall) {
LOG.debug("Old RexCall : " + obyExpr);
obyExpr = adjustOBSchema((RexCall) obyExpr, obChild, resultSchema);
LOG.debug("New RexCall : " + obyExpr);
}
inputRefToCallMapBldr.put(i, obyExpr);
}
}
ImmutableMap<Integer, RexNode> inputRefToCallMap = inputRefToCallMapBldr.build();
if ((obChild.getRowType().getFieldCount() - inputRefToCallMap.size()) != resultSchema.size()) {
LOG.error(generateInvalidSchemaMessage(obChild, resultSchema, inputRefToCallMap.size()));
throw new CalciteSemanticException("Result Schema didn't match Optimized Op Tree Schema");
}
if (replaceProject) {
// This removes order-by only expressions from the projections.
HiveProject replacementProjectRel = HiveProject.create(obChild.getInput(), obChild.getProjects().subList(0, resultSchema.size()), obChild.getRowType().getFieldNames().subList(0, resultSchema.size()));
obRel.replaceInput(0, replacementProjectRel);
}
obRel.setInputRefToCallMap(inputRefToCallMap);
}
use of org.apache.calcite.rex.RexCall in project hive by apache.
the class HiveRelMdRowCount method canHandleJoin.
/*
* 1. Join condition must be an Equality Predicate.
* 2. both sides must reference 1 column.
* 3. If needed flip the columns.
*/
private static Pair<Integer, Integer> canHandleJoin(Join joinRel, List<RexNode> leftFilters, List<RexNode> rightFilters, List<RexNode> joinFilters) {
/*
* If after classifying filters there is more than 1 joining predicate, we
* don't handle this. Return null.
*/
if (joinFilters.size() != 1) {
return null;
}
RexNode joinCond = joinFilters.get(0);
int leftColIdx;
int rightColIdx;
if (!(joinCond instanceof RexCall)) {
return null;
}
if (((RexCall) joinCond).getOperator() != SqlStdOperatorTable.EQUALS) {
return null;
}
ImmutableBitSet leftCols = RelOptUtil.InputFinder.bits(((RexCall) joinCond).getOperands().get(0));
ImmutableBitSet rightCols = RelOptUtil.InputFinder.bits(((RexCall) joinCond).getOperands().get(1));
if (leftCols.cardinality() != 1 || rightCols.cardinality() != 1) {
return null;
}
int nFieldsLeft = joinRel.getLeft().getRowType().getFieldList().size();
int nFieldsRight = joinRel.getRight().getRowType().getFieldList().size();
int nSysFields = joinRel.getSystemFieldList().size();
ImmutableBitSet rightFieldsBitSet = ImmutableBitSet.range(nSysFields + nFieldsLeft, nSysFields + nFieldsLeft + nFieldsRight);
/*
* flip column references if join condition specified in reverse order to
* join sources.
*/
if (rightFieldsBitSet.contains(leftCols)) {
ImmutableBitSet t = leftCols;
leftCols = rightCols;
rightCols = t;
}
leftColIdx = leftCols.nextSetBit(0) - nSysFields;
rightColIdx = rightCols.nextSetBit(0) - (nSysFields + nFieldsLeft);
return new Pair<Integer, Integer>(leftColIdx, rightColIdx);
}
use of org.apache.calcite.rex.RexCall in project hive by apache.
the class HiveRelDecorrelator method findCorrelationEquivalent.
/**
* Finds a {@link RexInputRef} that is equivalent to a {@link CorRef},
* and if found, throws a {@link Util.FoundOne}.
*/
private void findCorrelationEquivalent(CorRef correlation, RexNode e) throws Util.FoundOne {
if (e instanceof RexCall) {
switch(e.getKind()) {
case AND:
for (RexNode operand : ((RexCall) e).getOperands()) {
findCorrelationEquivalent(correlation, operand);
}
default:
final RexCall call = (RexCall) e;
final List<RexNode> operands = call.getOperands();
if (operands.size() == 2) {
if (references(operands.get(0), correlation) && operands.get(1) instanceof RexInputRef) {
// required we should rather generate value generator
if (e.getKind() != SqlKind.EQUALS && (boolean) valueGen.peek()) {
return;
}
throw new Util.FoundOne(Pair.of(((RexInputRef) operands.get(1)).getIndex(), Pair.of(((RexCall) e).getOperator(), true)));
}
if (references(operands.get(1), correlation) && operands.get(0) instanceof RexInputRef) {
// required we should rather generate value generator
if (e.getKind() != SqlKind.EQUALS && (boolean) valueGen.peek()) {
return;
}
throw new Util.FoundOne(Pair.of(((RexInputRef) operands.get(0)).getIndex(), Pair.of(((RexCall) e).getOperator(), false)));
}
break;
}
}
}
}
use of org.apache.calcite.rex.RexCall in project hive by apache.
the class HiveJdbcImplementor method convertConditionToSqlNode.
/**
* Converts a {@link RexNode} condition into a {@link SqlNode}.
*
* @param node Join condition
* @param leftContext Left context
* @param rightContext Right context
* @param leftFieldCount Number of fields on left result
* @return SqlNode that represents the condition
*/
public static SqlNode convertConditionToSqlNode(RexNode node, Context leftContext, Context rightContext, int leftFieldCount) {
// throw an Exception
if (node.isAlwaysTrue()) {
return SqlLiteral.createBoolean(true, POS);
}
if (node.isAlwaysFalse()) {
return SqlLiteral.createBoolean(false, POS);
}
if (node instanceof RexInputRef) {
Context joinContext = leftContext.implementor().joinContext(leftContext, rightContext);
return joinContext.toSql(null, node);
}
if (!(node instanceof RexCall)) {
throw new AssertionError(node);
}
final List<RexNode> operands;
final SqlOperator op;
final Context joinContext;
switch(node.getKind()) {
case AND:
case OR:
operands = ((RexCall) node).getOperands();
op = ((RexCall) node).getOperator();
SqlNode sqlCondition = null;
for (RexNode operand : operands) {
SqlNode x = convertConditionToSqlNode(operand, leftContext, rightContext, leftFieldCount);
if (sqlCondition == null) {
sqlCondition = x;
} else {
sqlCondition = op.createCall(POS, sqlCondition, x);
}
}
return sqlCondition;
case EQUALS:
case IS_NOT_DISTINCT_FROM:
case NOT_EQUALS:
case GREATER_THAN:
case GREATER_THAN_OR_EQUAL:
case LESS_THAN:
case LESS_THAN_OR_EQUAL:
node = stripCastFromString(node);
operands = ((RexCall) node).getOperands();
op = ((RexCall) node).getOperator();
if (operands.size() == 2 && operands.get(0) instanceof RexInputRef && operands.get(1) instanceof RexInputRef) {
final RexInputRef op0 = (RexInputRef) operands.get(0);
final RexInputRef op1 = (RexInputRef) operands.get(1);
if (op0.getIndex() < leftFieldCount && op1.getIndex() >= leftFieldCount) {
// Arguments were of form 'op0 = op1'
return op.createCall(POS, leftContext.field(op0.getIndex()), rightContext.field(op1.getIndex() - leftFieldCount));
}
if (op1.getIndex() < leftFieldCount && op0.getIndex() >= leftFieldCount) {
// Arguments were of form 'op1 = op0'
return reverseOperatorDirection(op).createCall(POS, leftContext.field(op1.getIndex()), rightContext.field(op0.getIndex() - leftFieldCount));
}
}
joinContext = leftContext.implementor().joinContext(leftContext, rightContext);
return joinContext.toSql(null, node);
case IS_NULL:
case IS_NOT_NULL:
operands = ((RexCall) node).getOperands();
if (operands.size() == 1 && operands.get(0) instanceof RexInputRef) {
op = ((RexCall) node).getOperator();
final RexInputRef op0 = (RexInputRef) operands.get(0);
if (op0.getIndex() < leftFieldCount) {
return op.createCall(POS, leftContext.field(op0.getIndex()));
} else {
return op.createCall(POS, rightContext.field(op0.getIndex() - leftFieldCount));
}
}
joinContext = leftContext.implementor().joinContext(leftContext, rightContext);
return joinContext.toSql(null, node);
default:
joinContext = leftContext.implementor().joinContext(leftContext, rightContext);
return joinContext.toSql(null, node);
}
}
use of org.apache.calcite.rex.RexCall in project hive by apache.
the class HiveJdbcImplementor method stripCastFromString.
/**
* Removes cast from string.
*
* <p>For example, {@code x > CAST('2015-01-07' AS DATE)}
* becomes {@code x > '2015-01-07'}.
*/
private static RexNode stripCastFromString(RexNode node) {
switch(node.getKind()) {
case EQUALS:
case IS_NOT_DISTINCT_FROM:
case NOT_EQUALS:
case GREATER_THAN:
case GREATER_THAN_OR_EQUAL:
case LESS_THAN:
case LESS_THAN_OR_EQUAL:
final RexCall call = (RexCall) node;
final RexNode o0 = call.operands.get(0);
final RexNode o1 = call.operands.get(1);
if (o0.getKind() == SqlKind.CAST && o1.getKind() != SqlKind.CAST) {
final RexNode o0b = ((RexCall) o0).getOperands().get(0);
switch(o0b.getType().getSqlTypeName()) {
case CHAR:
case VARCHAR:
return call.clone(call.getType(), ImmutableList.of(o0b, o1));
}
}
if (o1.getKind() == SqlKind.CAST && o0.getKind() != SqlKind.CAST) {
final RexNode o1b = ((RexCall) o1).getOperands().get(0);
switch(o1b.getType().getSqlTypeName()) {
case CHAR:
case VARCHAR:
return call.clone(call.getType(), ImmutableList.of(o0, o1b));
}
}
}
return node;
}
Aggregations