use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project drill by axbaretto.
the class JoinPrel method buildJoinConditions.
/**
* Build the list of join conditions for this join.
* A join condition is built only for equality and IS NOT DISTINCT FROM comparisons. The difference is:
* null == null is FALSE whereas null IS NOT DISTINCT FROM null is TRUE
* For a use case of the IS NOT DISTINCT FROM comparison, see
* {@link org.apache.calcite.rel.rules.RemoveDistinctAggregateRule}
* @param conditions populated list of join conditions
* @param leftFields join fields from the left input
* @param rightFields join fields from the right input
*/
protected void buildJoinConditions(List<JoinCondition> conditions, List<String> leftFields, List<String> rightFields, List<Integer> leftKeys, List<Integer> rightKeys) {
List<RexNode> conjuncts = RelOptUtil.conjunctions(this.getCondition());
short i = 0;
for (Pair<Integer, Integer> pair : Pair.zip(leftKeys, rightKeys)) {
final RexNode conditionExpr = conjuncts.get(i++);
final SqlKind kind = conditionExpr.getKind();
if (kind != SqlKind.EQUALS && kind != SqlKind.IS_NOT_DISTINCT_FROM) {
throw UserException.unsupportedError().message("Unsupported comparator in join condition %s", conditionExpr).build(logger);
}
conditions.add(new JoinCondition(kind.toString(), FieldReference.getWithQuotedRef(leftFields.get(pair.left)), FieldReference.getWithQuotedRef(rightFields.get(pair.right))));
}
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project hive by apache.
the class FilterSelectivityEstimator method visitCall.
@Override
public Double visitCall(RexCall call) {
if (!deep) {
return 1.0;
}
/*
* Ignore any predicates on partition columns because we have already
* accounted for these in the Table row count.
*/
if (isPartitionPredicate(call, this.childRel)) {
return 1.0;
}
Double selectivity = null;
SqlKind op = getOp(call);
switch(op) {
case AND:
{
selectivity = computeConjunctionSelectivity(call);
break;
}
case OR:
{
selectivity = computeDisjunctionSelectivity(call);
break;
}
case NOT:
case NOT_EQUALS:
{
selectivity = computeNotEqualitySelectivity(call);
break;
}
case IS_NOT_NULL:
{
if (childRel instanceof HiveTableScan) {
double noOfNulls = getMaxNulls(call, (HiveTableScan) childRel);
double totalNoOfTuples = mq.getRowCount(childRel);
if (totalNoOfTuples >= noOfNulls) {
selectivity = (totalNoOfTuples - noOfNulls) / Math.max(totalNoOfTuples, 1);
} else {
// If we are running explain, we will print the warning in the console
// and the log files. Otherwise, we just print it in the log files.
HiveConfPlannerContext ctx = childRel.getCluster().getPlanner().getContext().unwrap(HiveConfPlannerContext.class);
String msg = "Invalid statistics: Number of null values > number of tuples. " + "Consider recomputing statistics for table: " + ((RelOptHiveTable) childRel.getTable()).getHiveTableMD().getFullyQualifiedName();
if (ctx.isExplainPlan()) {
SessionState.getConsole().printError("WARNING: " + msg);
}
LOG.warn(msg);
selectivity = ((double) 1 / (double) 3);
}
} else {
selectivity = computeNotEqualitySelectivity(call);
}
break;
}
case LESS_THAN_OR_EQUAL:
case GREATER_THAN_OR_EQUAL:
case LESS_THAN:
case GREATER_THAN:
{
selectivity = ((double) 1 / (double) 3);
break;
}
case IN:
{
// TODO: 1) check for duplicates 2) We assume in clause values to be
// present in NDV which may not be correct (Range check can find it) 3) We
// assume values in NDV set is uniformly distributed over col values
// (account for skewness - histogram).
selectivity = computeFunctionSelectivity(call);
if (selectivity != null) {
selectivity = selectivity * (call.operands.size() - 1);
if (selectivity <= 0.0) {
selectivity = 0.10;
} else if (selectivity >= 1.0) {
selectivity = 1.0;
}
}
break;
}
default:
selectivity = computeFunctionSelectivity(call);
}
return selectivity;
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project hive by apache.
the class FilterSelectivityEstimator method getOp.
private SqlKind getOp(RexCall call) {
SqlKind op = call.getKind();
if (call.getKind().equals(SqlKind.OTHER_FUNCTION) && SqlTypeUtil.inBooleanFamily(call.getType())) {
SqlOperator sqlOp = call.getOperator();
String opName = (sqlOp != null) ? sqlOp.getName() : "";
if (opName.equalsIgnoreCase("in")) {
op = SqlKind.IN;
}
}
return op;
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project hive by apache.
the class HiveRelOptUtil 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) throws CalciteSemanticException {
final int sysFieldCount = sysFieldList.size();
final RelOptCluster cluster = inputs.get(0).getCluster();
final RexBuilder rexBuilder = cluster.getRexBuilder();
if (condition instanceof RexCall) {
RexCall call = (RexCall) condition;
if (call.getOperator() == SqlStdOperatorTable.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;
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);
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);
}
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)) {
// 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;
}
}
// 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 using Hive rules
TypeInfo rType = TypeConverter.convert(rightKeyType);
TypeInfo lType = TypeConverter.convert(leftKeyType);
TypeInfo tgtType = FunctionRegistry.getCommonClassForComparison(lType, rType);
if (tgtType == null) {
throw new CalciteSemanticException("Cannot find common type for join keys " + leftKey + " (type " + leftKeyType + ") and " + rightKey + " (type " + rightKeyType + ")");
}
RelDataType targetKeyType = TypeConverter.convert(tgtType, rexBuilder.getTypeFactory());
if (leftKeyType != targetKeyType && TypeInfoUtils.isConversionRequiredForComparison(tgtType, lType)) {
leftKey = rexBuilder.makeCast(targetKeyType, leftKey);
}
if (rightKeyType != targetKeyType && TypeInfoUtils.isConversionRequiredForComparison(tgtType, rType)) {
rightKey = rexBuilder.makeCast(targetKeyType, rightKey);
}
}
}
}
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 = reverse(kind);
}
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.sql.SqlKind in project calcite by apache.
the class RelOptUtil method splitJoinCondition.
private static void splitJoinCondition(final RexBuilder rexBuilder, final int leftFieldCount, RexNode condition, List<Integer> leftKeys, List<Integer> rightKeys, List<Boolean> filterNulls, List<RexNode> nonEquiList) {
if (condition instanceof RexCall) {
RexCall call = (RexCall) condition;
SqlKind kind = call.getKind();
if (kind == SqlKind.AND) {
for (RexNode operand : call.getOperands()) {
splitJoinCondition(rexBuilder, leftFieldCount, operand, leftKeys, rightKeys, filterNulls, nonEquiList);
}
return;
}
if (filterNulls != null) {
call = collapseExpandedIsNotDistinctFromExpr(call, rexBuilder);
kind = call.getKind();
}
// treat nulls.
if (kind == SqlKind.EQUALS || (filterNulls != null && kind == SqlKind.IS_NOT_DISTINCT_FROM)) {
final List<RexNode> operands = call.getOperands();
if ((operands.get(0) instanceof RexInputRef) && (operands.get(1) instanceof RexInputRef)) {
RexInputRef op0 = (RexInputRef) operands.get(0);
RexInputRef op1 = (RexInputRef) operands.get(1);
RexInputRef leftField;
RexInputRef rightField;
if ((op0.getIndex() < leftFieldCount) && (op1.getIndex() >= leftFieldCount)) {
// Arguments were of form 'op0 = op1'
leftField = op0;
rightField = op1;
} else if ((op1.getIndex() < leftFieldCount) && (op0.getIndex() >= leftFieldCount)) {
// Arguments were of form 'op1 = op0'
leftField = op1;
rightField = op0;
} else {
nonEquiList.add(condition);
return;
}
leftKeys.add(leftField.getIndex());
rightKeys.add(rightField.getIndex() - leftFieldCount);
if (filterNulls != null) {
filterNulls.add(kind == SqlKind.EQUALS);
}
return;
}
// Arguments were not field references, one from each side, so
// we fail. Fall through.
}
}
// Add this condition to the list of non-equi-join conditions.
if (!condition.isAlwaysTrue()) {
nonEquiList.add(condition);
}
}
Aggregations