use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall in project hive by apache.
the class HiveRelOptUtil method getNewRelFieldCollations.
/**
* Map Sort and SortExchange keys to the specified Project columns.
* @param project the Project
* @param sortCollation current collation in Sort
* @param cluster RelOptCluster
* @return new collation should be used in the Sort
*/
public static List<RelFieldCollation> getNewRelFieldCollations(HiveProject project, RelCollation sortCollation, RelOptCluster cluster) {
// Determine mapping between project input and output fields.
// In Hive, Sort is always based on RexInputRef
// HiveSort*PullUpConstantsRule should remove constants (RexLiteral)
// We only need to check if project can contain all the positions that sortCollation needs.
final Mappings.TargetMapping map = RelOptUtil.permutationIgnoreCast(project.getProjects(), project.getInput().getRowType()).inverse();
Set<Integer> needed = new HashSet<>();
for (RelFieldCollation fc : sortCollation.getFieldCollations()) {
needed.add(fc.getFieldIndex());
final RexNode node = project.getProjects().get(map.getTarget(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(RexUtil.apply(map, sortCollation)));
if (cast.getOperator().getMonotonicity(binding) == SqlMonotonicity.NOT_MONOTONIC) {
return null;
}
}
}
Map<Integer, Integer> m = new HashMap<>();
for (int projPos = 0; projPos < project.getProjects().size(); projPos++) {
RexNode expr = project.getProjects().get(projPos);
if (expr instanceof RexInputRef) {
Set<Integer> positions = HiveCalciteUtil.getInputRefs(expr);
if (positions.size() <= 1) {
int parentPos = positions.iterator().next();
if (needed.contains(parentPos)) {
m.put(parentPos, projPos);
needed.remove(parentPos);
}
}
}
}
if (!needed.isEmpty()) {
return null;
}
List<RelFieldCollation> fieldCollations = new ArrayList<>();
for (RelFieldCollation fc : sortCollation.getFieldCollations()) {
fieldCollations.add(new RelFieldCollation(m.get(fc.getFieldIndex()), fc.direction, fc.nullDirection));
}
return fieldCollations;
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall in project hive by apache.
the class HiveRelOptUtil method splitCorrelatedFilterCondition.
private static void splitCorrelatedFilterCondition(Filter filter, RexNode condition, List<RexNode> joinKeys, List<RexNode> correlatedJoinKeys, List<RexNode> nonEquiList, boolean extractCorrelatedFieldAccess) {
if (condition instanceof RexCall) {
RexCall call = (RexCall) condition;
if (call.getOperator().getKind() == SqlKind.AND) {
for (RexNode operand : call.getOperands()) {
splitCorrelatedFilterCondition(filter, operand, joinKeys, correlatedJoinKeys, nonEquiList, extractCorrelatedFieldAccess);
}
return;
}
if (call.getOperator().getKind() == SqlKind.EQUALS) {
final List<RexNode> operands = call.getOperands();
RexNode op0 = operands.get(0);
RexNode op1 = operands.get(1);
if (extractCorrelatedFieldAccess) {
if (!RexUtil.containsFieldAccess(op0) && (op1 instanceof RexFieldAccess)) {
joinKeys.add(op0);
correlatedJoinKeys.add(op1);
return;
} else if ((op0 instanceof RexFieldAccess) && !RexUtil.containsFieldAccess(op1)) {
correlatedJoinKeys.add(op0);
joinKeys.add(op1);
return;
}
} else {
if (!(RexUtil.containsInputRef(op0)) && (op1 instanceof RexInputRef)) {
correlatedJoinKeys.add(op0);
joinKeys.add(op1);
return;
} else if ((op0 instanceof RexInputRef) && !(RexUtil.containsInputRef(op1))) {
joinKeys.add(op0);
correlatedJoinKeys.add(op1);
return;
}
}
}
}
// 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.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.beam.vendor.calcite.v1_28_0.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.beam.vendor.calcite.v1_28_0.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;
}
}
}
}
Aggregations