Java Code Examples for org.apache.calcite.sql.SqlKind#EQUALS

The following examples show how to use org.apache.calcite.sql.SqlKind#EQUALS . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: OLAPJoinRel.java    From kylin with Apache License 2.0 6 votes vote down vote up
void translateJoinColumn(RexCall condition, Multimap<TblColRef, TblColRef> joinColumns) {
    SqlKind kind = condition.getOperator().getKind();
    if (kind == SqlKind.AND) {
        for (RexNode operand : condition.getOperands()) {
            RexCall subCond = (RexCall) operand;
            translateJoinColumn(subCond, joinColumns);
        }
    } else if (kind == SqlKind.EQUALS) {
        List<RexNode> operands = condition.getOperands();
        RexInputRef op0 = (RexInputRef) operands.get(0);
        TblColRef col0 = columnRowType.getColumnByIndex(op0.getIndex());
        RexInputRef op1 = (RexInputRef) operands.get(1);
        TblColRef col1 = columnRowType.getColumnByIndex(op1.getIndex());
        // map left => right
        if (op0.getIndex() < columnRowTypeLeftRightCut)
            joinColumns.put(col0, col1);
        else
            joinColumns.put(col1, col0);
    }
}
 
Example 2
Source File: OLAPJoinRel.java    From kylin-on-parquet-v2 with Apache License 2.0 6 votes vote down vote up
void translateJoinColumn(RexCall condition, Multimap<TblColRef, TblColRef> joinColumns) {
    SqlKind kind = condition.getOperator().getKind();
    if (kind == SqlKind.AND) {
        for (RexNode operand : condition.getOperands()) {
            RexCall subCond = (RexCall) operand;
            translateJoinColumn(subCond, joinColumns);
        }
    } else if (kind == SqlKind.EQUALS) {
        List<RexNode> operands = condition.getOperands();
        RexInputRef op0 = (RexInputRef) operands.get(0);
        TblColRef col0 = columnRowType.getColumnByIndex(op0.getIndex());
        RexInputRef op1 = (RexInputRef) operands.get(1);
        TblColRef col1 = columnRowType.getColumnByIndex(op1.getIndex());
        // map left => right
        if (op0.getIndex() < columnRowTypeLeftRightCut)
            joinColumns.put(col0, col1);
        else
            joinColumns.put(col1, col0);
    }
}
 
Example 3
Source File: RexUtil.java    From Bats with Apache License 2.0 6 votes vote down vote up
private static <C extends RexNode> void gatherConstraints(Class<C> clazz, RexNode predicate, Map<RexNode, C> map,
        Set<RexNode> excludeSet, RexBuilder rexBuilder) {
    if (predicate.getKind() != SqlKind.EQUALS && predicate.getKind() != SqlKind.IS_NULL) {
        decompose(excludeSet, predicate);
        return;
    }
    final List<RexNode> operands = ((RexCall) predicate).getOperands();
    final RexNode left;
    final RexNode right;
    if (predicate.getKind() == SqlKind.EQUALS) {
        left = operands.get(0);
        right = operands.get(1);
    } else { // is null
        left = operands.get(0);
        if (!left.getType().isNullable()) {
            // There's no sense in inferring $0=null when $0 is not nullable
            return;
        }
        right = rexBuilder.makeNullLiteral(left.getType());
    }
    // Note that literals are immutable too, and they can only be compared
    // through values.
    gatherConstraint(clazz, left, right, map, excludeSet, rexBuilder);
    gatherConstraint(clazz, right, left, map, excludeSet, rexBuilder);
}
 
Example 4
Source File: JoinPrel.java    From Bats with Apache License 2.0 6 votes vote down vote up
/**
 * 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.AggregateRemoveRule}
 * @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))));
  }
}
 
Example 5
Source File: RelMdPredicates.java    From Bats with Apache License 2.0 5 votes vote down vote up
private boolean isAlwaysTrue(RexNode predicate) {
  if (predicate instanceof RexCall) {
    RexCall c = (RexCall) predicate;
    if (c.getOperator().getKind() == SqlKind.EQUALS) {
      int lPos = pos(c.getOperands().get(0));
      int rPos = pos(c.getOperands().get(1));
      return lPos != -1 && lPos == rPos;
    }
  }
  return predicate.isAlwaysTrue();
}
 
Example 6
Source File: RexUtil.java    From kylin with Apache License 2.0 5 votes vote down vote up
public static CompareTupleFilter.CompareResultType getCompareResultType(RexCall whenCall) {
    List<RexNode> operands = whenCall.getOperands();
    if (SqlKind.EQUALS == whenCall.getKind() && operands != null && operands.size() == 2) {
        if (operands.get(0).equals(operands.get(1))) {
            return CompareTupleFilter.CompareResultType.AlwaysTrue;
        }

        if (isConstant(operands.get(0)) && isConstant(operands.get(1))) {
            return CompareTupleFilter.CompareResultType.AlwaysFalse;
        }
    }
    return CompareTupleFilter.CompareResultType.Unknown;
}
 
Example 7
Source File: RelMdPredicates.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public Void visitCall(RexCall call) {
  if (call.getOperator().getKind() == SqlKind.EQUALS) {
    int lPos = pos(call.getOperands().get(0));
    int rPos = pos(call.getOperands().get(1));
    if (lPos != -1 && rPos != -1) {
      markAsEquivalent(lPos, rPos);
      equalityPredicates.add(call);
    }
  }
  return null;
}
 
Example 8
Source File: RelOptUtil.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Deprecated // to be removed before 2.0
public static boolean analyzeSimpleEquiJoin(
    LogicalJoin join,
    int[] joinFieldOrdinals) {
  RexNode joinExp = join.getCondition();
  if (joinExp.getKind() != SqlKind.EQUALS) {
    return false;
  }
  RexCall binaryExpression = (RexCall) joinExp;
  RexNode leftComparand = binaryExpression.operands.get(0);
  RexNode rightComparand = binaryExpression.operands.get(1);
  if (!(leftComparand instanceof RexInputRef)) {
    return false;
  }
  if (!(rightComparand instanceof RexInputRef)) {
    return false;
  }

  final int leftFieldCount =
      join.getLeft().getRowType().getFieldCount();
  RexInputRef leftFieldAccess = (RexInputRef) leftComparand;
  if (!(leftFieldAccess.getIndex() < leftFieldCount)) {
    // left field must access left side of join
    return false;
  }

  RexInputRef rightFieldAccess = (RexInputRef) rightComparand;
  if (!(rightFieldAccess.getIndex() >= leftFieldCount)) {
    // right field must access right side of join
    return false;
  }

  joinFieldOrdinals[0] = leftFieldAccess.getIndex();
  joinFieldOrdinals[1] = rightFieldAccess.getIndex() - leftFieldCount;
  return true;
}
 
Example 9
Source File: MysqlSideFunction.java    From alchemy with Apache License 2.0 5 votes vote down vote up
private String modifySql(SideTable sideTable) throws SqlParseException {
    SqlParser.Config config = SqlParser.configBuilder().setLex(Lex.MYSQL).build();
    SqlParser sqlParser = SqlParser.create(sideTable.getSql(), config);
    SqlNode sqlNode = sqlParser.parseStmt();
    if (SqlKind.SELECT != sqlNode.getKind()) {
        throw new UnsupportedOperationException(
            "MysqlAsyncReqRow only support query sql, sql:" + sideTable.getSql());
    }
    SqlSelect sqlSelect = (SqlSelect)sqlNode;
    SqlNode whereNode = sqlSelect.getWhere();
    SqlBinaryOperator and = new SqlBinaryOperator("AND", SqlKind.AND, 24, true,
        ReturnTypes.BOOLEAN_NULLABLE_OPTIMIZED, InferTypes.BOOLEAN, OperandTypes.BOOLEAN_BOOLEAN);
    List<SqlBasicCall> conditionNodes = createConditionNodes(sideTable.getConditions(), sideTable.getSideAlias());
    List<SqlNode> nodes = new ArrayList<>();
    nodes.addAll(conditionNodes);
    if (whereNode != null) {
        nodes.add(whereNode);
    } else {
        SqlBinaryOperator equal = new SqlBinaryOperator("=", SqlKind.EQUALS, 30, true, ReturnTypes.BOOLEAN_NULLABLE,
            InferTypes.FIRST_KNOWN, OperandTypes.COMPARABLE_UNORDERED_COMPARABLE_UNORDERED);
        SqlBasicCall andEqual
            = new SqlBasicCall(equal, SideParser.createEqualNodes(SqlKind.AND), new SqlParserPos(0, 0));
        nodes.add(andEqual);
    }
    SqlBasicCall sqlBasicCall
        = new SqlBasicCall(and, nodes.toArray(new SqlNode[nodes.size()]), new SqlParserPos(0, 0));
    sqlSelect.setWhere(sqlBasicCall);
    return sqlSelect.toString();
}
 
Example 10
Source File: SideParser.java    From alchemy with Apache License 2.0 5 votes vote down vote up
public static List<String> findConditionFields(SqlNode conditionNode, String specifyTableName){
    List<SqlNode> sqlNodeList = Lists.newArrayList();
    if(conditionNode.getKind() == SqlKind.AND){
        sqlNodeList.addAll(Lists.newArrayList(((SqlBasicCall)conditionNode).getOperands()));
    }else{
        sqlNodeList.add(conditionNode);
    }

    List<String> conditionFields = Lists.newArrayList();
    for(SqlNode sqlNode : sqlNodeList){
        if(sqlNode.getKind() != SqlKind.EQUALS){
            throw new RuntimeException("not equal operator.");
        }
        SqlIdentifier left = (SqlIdentifier)((SqlBasicCall)sqlNode).getOperands()[0];
        SqlIdentifier right = (SqlIdentifier)((SqlBasicCall)sqlNode).getOperands()[1];

        String leftTableName = left.names.get(0);
        String rightTableName = right.names.get(0);

        String tableCol;
        if(leftTableName.equalsIgnoreCase(specifyTableName)){
            tableCol = left.names.get(1);
        }else if(rightTableName.equalsIgnoreCase(specifyTableName)){
            tableCol = right.names.get(1);
        }else{
            throw new RuntimeException(String.format("side table:%s join condition is wrong", specifyTableName));
        }
        conditionFields.add(tableCol);
    }

    return conditionFields;
}
 
Example 11
Source File: DrillRelOptUtil.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Returns whether the join condition is a simple equi-join or not. A simple equi-join is
 * defined as an two-table equality join (no self-join)
 * @param join : input join
 * @param joinFieldOrdinals: join field ordinal w.r.t. the underlying inputs to the join
 * @return TRUE if the join is a simple equi-join (not a self-join), FALSE otherwise
 * */
public static boolean analyzeSimpleEquiJoin(Join join, int[] joinFieldOrdinals) {
    RexNode joinExp = join.getCondition();
    if (joinExp.getKind() != SqlKind.EQUALS) {
        return false;
    } else {
        RexCall binaryExpression = (RexCall) joinExp;
        RexNode leftComparand = binaryExpression.getOperands().get(0);
        RexNode rightComparand = binaryExpression.getOperands().get(1);
        if (!(leftComparand instanceof RexInputRef)) {
            return false;
        } else if (!(rightComparand instanceof RexInputRef)) {
            return false;
        } else {
            int leftFieldCount = join.getLeft().getRowType().getFieldCount();
            int rightFieldCount = join.getRight().getRowType().getFieldCount();
            RexInputRef leftFieldAccess = (RexInputRef) leftComparand;
            RexInputRef rightFieldAccess = (RexInputRef) rightComparand;
            if (leftFieldAccess.getIndex() >= leftFieldCount + rightFieldCount
                    || rightFieldAccess.getIndex() >= leftFieldCount + rightFieldCount) {
                return false;
            }
            /* Both columns reference same table */
            if ((leftFieldAccess.getIndex() >= leftFieldCount && rightFieldAccess.getIndex() >= leftFieldCount)
                    || (leftFieldAccess.getIndex() < leftFieldCount
                            && rightFieldAccess.getIndex() < leftFieldCount)) {
                return false;
            } else {
                if (leftFieldAccess.getIndex() < leftFieldCount) {
                    joinFieldOrdinals[0] = leftFieldAccess.getIndex();
                    joinFieldOrdinals[1] = rightFieldAccess.getIndex() - leftFieldCount;
                } else {
                    joinFieldOrdinals[0] = rightFieldAccess.getIndex();
                    joinFieldOrdinals[1] = leftFieldAccess.getIndex() - leftFieldCount;
                }
                return true;
            }
        }
    }
}
 
Example 12
Source File: RelOptUtil.java    From Bats with Apache License 2.0 5 votes vote down vote up
private static void splitCorrelatedFilterCondition(LogicalFilter filter, RexNode condition,
        List<RexInputRef> joinKeys, List<RexNode> correlatedJoinKeys, List<RexNode> nonEquiList) {
    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);
            }
            return;
        }

        if (call.getOperator().getKind() == SqlKind.EQUALS) {
            final List<RexNode> operands = call.getOperands();
            RexNode op0 = operands.get(0);
            RexNode op1 = operands.get(1);

            if (!(RexUtil.containsInputRef(op0)) && (op1 instanceof RexInputRef)) {
                correlatedJoinKeys.add(op0);
                joinKeys.add((RexInputRef) op1);
                return;
            } else if ((op0 instanceof RexInputRef) && !(RexUtil.containsInputRef(op1))) {
                joinKeys.add((RexInputRef) 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);
}
 
Example 13
Source File: RelOptUtil.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Deprecated // to be removed before 2.0
public static boolean analyzeSimpleEquiJoin(LogicalJoin join, int[] joinFieldOrdinals) {
    RexNode joinExp = join.getCondition();
    if (joinExp.getKind() != SqlKind.EQUALS) {
        return false;
    }
    RexCall binaryExpression = (RexCall) joinExp;
    RexNode leftComparand = binaryExpression.getOperands().get(0);
    RexNode rightComparand = binaryExpression.getOperands().get(1);
    if (!(leftComparand instanceof RexInputRef)) {
        return false;
    }
    if (!(rightComparand instanceof RexInputRef)) {
        return false;
    }

    final int leftFieldCount = join.getLeft().getRowType().getFieldCount();
    RexInputRef leftFieldAccess = (RexInputRef) leftComparand;
    if (!(leftFieldAccess.getIndex() < leftFieldCount)) {
        // left field must access left side of join
        return false;
    }

    RexInputRef rightFieldAccess = (RexInputRef) rightComparand;
    if (!(rightFieldAccess.getIndex() >= leftFieldCount)) {
        // right field must access right side of join
        return false;
    }

    joinFieldOrdinals[0] = leftFieldAccess.getIndex();
    joinFieldOrdinals[1] = rightFieldAccess.getIndex() - leftFieldCount;
    return true;
}
 
Example 14
Source File: RelOptUtil.java    From calcite with Apache License 2.0 5 votes vote down vote up
private static RexCall doCollapseExpandedIsNotDistinctFromCaseExpr(final RexCall call,
    final RexBuilder rexBuilder) {
  if (call.getKind() != SqlKind.CASE || call.getOperands().size() != 5) {
    return call;
  }

  final RexNode op0 = call.getOperands().get(0);
  final RexNode op1 = call.getOperands().get(1);
  final RexNode op2 = call.getOperands().get(2);
  final RexNode op3 = call.getOperands().get(3);
  final RexNode op4 = call.getOperands().get(4);

  if (!(op0 instanceof RexCall) || !(op1 instanceof RexCall) || !(op2 instanceof RexCall)
      || !(op3 instanceof RexCall) || !(op4 instanceof RexCall)) {
    return call;
  }

  RexCall ifCall = (RexCall) op0;
  RexCall thenCall = (RexCall) op1;
  RexCall elseIfCall = (RexCall) op2;
  RexCall elseIfThenCall = (RexCall) op3;
  RexCall elseCall = (RexCall) op4;

  if (ifCall.getKind() != SqlKind.IS_NULL
      || thenCall.getKind() != SqlKind.IS_NULL
      || elseIfCall.getKind() != SqlKind.IS_NULL
      || elseIfThenCall.getKind() != SqlKind.IS_NULL
      || elseCall.getKind() != SqlKind.EQUALS) {
    return call;
  }

  if (!ifCall.equals(elseIfThenCall)
      || !thenCall.equals(elseIfCall)) {
    return call;
  }

  return doCollapseExpandedIsNotDistinctFrom(rexBuilder, call, ifCall, elseIfCall, elseCall);
}
 
Example 15
Source File: RelMdPredicates.java    From calcite with Apache License 2.0 5 votes vote down vote up
private boolean isAlwaysTrue(RexNode predicate) {
  if (predicate instanceof RexCall) {
    RexCall c = (RexCall) predicate;
    if (c.getOperator().getKind() == SqlKind.EQUALS) {
      int lPos = pos(c.getOperands().get(0));
      int rPos = pos(c.getOperands().get(1));
      return lPos != -1 && lPos == rPos;
    }
  }
  return predicate.isAlwaysTrue();
}
 
Example 16
Source File: RelMdPredicates.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override public Void visitCall(RexCall call) {
  if (call.getOperator().getKind() == SqlKind.EQUALS) {
    int lPos = pos(call.getOperands().get(0));
    int rPos = pos(call.getOperands().get(1));
    if (lPos != -1 && rPos != -1) {
      markAsEquivalent(lPos, rPos);
      equalityPredicates.add(call);
    }
  }
  return null;
}
 
Example 17
Source File: IndexPlanUtils.java    From Bats with Apache License 2.0 4 votes vote down vote up
/**
 * Build collation property for the 'upper' project, the one above the filter
 * @param projectRexs
 * @param inputCollation
 * @param indexInfo
 * @param collationFilterMap
 * @return the output RelCollation
 */
public static RelCollation buildCollationUpperProject(List<RexNode> projectRexs,
                                                      RelCollation inputCollation, FunctionalIndexInfo indexInfo,
                                                      Map<Integer, List<RexNode>> collationFilterMap) {
  List<RelFieldCollation> outputFieldCollations = Lists.newArrayList();

  if (inputCollation != null) {
    List<RelFieldCollation> inputFieldCollations = inputCollation.getFieldCollations();
    if (!indexInfo.hasFunctional()) {
      for (int projectExprIdx = 0; projectExprIdx < projectRexs.size(); projectExprIdx++) {
        RexNode n = projectRexs.get(projectExprIdx);
        if (n instanceof RexInputRef) {
          RexInputRef ref = (RexInputRef)n;
          boolean eligibleForCollation = true;
          int maxIndex = getIndexFromCollation(ref.getIndex(), inputFieldCollations);
          if (maxIndex < 0) {
            eligibleForCollation = false;
            continue;
          }
          // check if the prefix has equality conditions
          for (int i = 0; i < maxIndex; i++) {
            int fieldIdx = inputFieldCollations.get(i).getFieldIndex();
            List<RexNode> conditions = collationFilterMap != null ? collationFilterMap.get(fieldIdx) : null;
            if ((conditions == null || conditions.size() == 0) &&
                i < maxIndex-1) {
              // if an intermediate column has no filter condition, it would select all values
              // of that column, so a subsequent column cannot be eligible for collation
              eligibleForCollation = false;
              break;
            } else {
              for (RexNode r : conditions) {
                if (!(r.getKind() == SqlKind.EQUALS)) {
                  eligibleForCollation = false;
                  break;
                }
              }
            }
          }
          // for every projected expr, if it is eligible for collation, get the
          // corresponding field collation from the input
          if (eligibleForCollation) {
            for (RelFieldCollation c : inputFieldCollations) {
              if (ref.getIndex() == c.getFieldIndex()) {
                RelFieldCollation outFieldCollation = new RelFieldCollation(projectExprIdx, c.getDirection(), c.nullDirection);
                outputFieldCollations.add(outFieldCollation);
              }
            }
          }
        }
      }
    } else {
      // TODO: handle functional index
    }
  }
  return RelCollations.of(outputFieldCollations);
}
 
Example 18
Source File: RexImplicationChecker.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Looks at the usage of variables in first and second conjunction to decide
 * whether this kind of expression is currently supported for proving first
 * implies second.
 *
 * <ol>
 * <li>Variables should be used only once in both the conjunction against
 * given set of operations only: &gt;, &lt;, &le;, &ge;, =; &ne;.
 *
 * <li>All the variables used in second condition should be used even in the
 * first.
 *
 * <li>If operator used for variable in first is op1 and op2 for second, then
 * we support these combination for conjunction (op1, op2) then op1, op2
 * belongs to one of the following sets:
 *
 * <ul>
 *    <li>(&lt;, &le;) X (&lt;, &le;) <i>note: X represents cartesian product</i>
 *    <li>(&gt; / &ge;) X (&gt;, &ge;)
 *    <li>(=) X (&gt;, &ge;, &lt;, &le;, =, &ne;)
 *    <li>(&ne;, =)
 * </ul>
 *
 * <li>We support at most 2 operators to be be used for a variable in first
 * and second usages.
 *
 * </ol>
 *
 * @return whether input usage pattern is supported
 */
private boolean checkSupport(InputUsageFinder firstUsageFinder,
    InputUsageFinder secondUsageFinder) {
  final Map<RexInputRef, InputRefUsage<SqlOperator, RexNode>> firstUsageMap =
      firstUsageFinder.usageMap;
  final Map<RexInputRef, InputRefUsage<SqlOperator, RexNode>> secondUsageMap =
      secondUsageFinder.usageMap;

  for (Map.Entry<RexInputRef, InputRefUsage<SqlOperator, RexNode>> entry
      : secondUsageMap.entrySet()) {
    final InputRefUsage<SqlOperator, RexNode> secondUsage = entry.getValue();
    final List<Pair<SqlOperator, RexNode>> secondUsageList = secondUsage.usageList;
    final int secondLen = secondUsageList.size();

    if (secondUsage.usageCount != secondLen || secondLen > 2) {
      return false;
    }

    final InputRefUsage<SqlOperator, RexNode> firstUsage =
        firstUsageMap.get(entry.getKey());

    if (firstUsage == null
        || firstUsage.usageList.size() != firstUsage.usageCount
        || firstUsage.usageCount > 2) {
      return false;
    }

    final List<Pair<SqlOperator, RexNode>> firstUsageList = firstUsage.usageList;
    final int firstLen = firstUsageList.size();

    final SqlKind fKind = firstUsageList.get(0).getKey().getKind();
    final SqlKind sKind = secondUsageList.get(0).getKey().getKind();
    final SqlKind fKind2 =
        (firstUsageList.size() == 2) ? firstUsageList.get(1).getKey().getKind() : null;
    final SqlKind sKind2 =
        (secondUsageList.size() == 2) ? secondUsageList.get(1).getKey().getKind() : null;

    if (firstLen == 2 && secondLen == 2
        && !(isEquivalentOp(fKind, sKind) && isEquivalentOp(fKind2, sKind2))
        && !(isEquivalentOp(fKind, sKind2) && isEquivalentOp(fKind2, sKind))) {
      return false;
    } else if (firstLen == 1 && secondLen == 1
        && fKind != SqlKind.EQUALS && !isSupportedUnaryOperators(sKind)
        && !isEquivalentOp(fKind, sKind)) {
      return false;
    } else if (firstLen == 1 && secondLen == 2 && fKind != SqlKind.EQUALS) {
      return false;
    } else if (firstLen == 2 && secondLen == 1) {
      // Allow only cases like
      // x < 30 and x < 40 implies x < 70
      // x > 30 and x < 40 implies x < 70
      // But disallow cases like
      // x > 30 and x > 40 implies x < 70
      if (!isOppositeOp(fKind, fKind2) && !isSupportedUnaryOperators(sKind)
          && !(isEquivalentOp(fKind, fKind2) && isEquivalentOp(fKind, sKind))) {
        return false;
      }
    }
  }

  return true;
}
 
Example 19
Source File: RelOptUtil.java    From calcite with Apache License 2.0 4 votes vote down vote up
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();
    }

    // "=" and "IS NOT DISTINCT FROM" are the same except for how they
    // 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);
  }
}
 
Example 20
Source File: RelOptUtil.java    From Bats with Apache License 2.0 4 votes vote down vote up
private static void splitCorrelatedFilterCondition(LogicalFilter 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);
}