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

The following examples show how to use org.apache.calcite.sql.SqlKind#AND . 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-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 2
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 3
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 4
Source File: FindPartitionConditions.java    From Bats with Apache License 2.0 5 votes vote down vote up
private void popOpStackAndBuildFilter() {
  // Parsing a special expression; handled holistically by the parent
  if (holisticExpression > 0) {
    return;
  }
  OpState currentOp = opStack.pop();
  int size = currentOp.getChildren().size();
  RexNode newFilter = null;
  if (size >= 1) {
    if (size == 1 && currentOp.getOp() instanceof SqlBinaryOperator) {
      /* The only operator for which we allow partial pushes is AND.
       * For all other operators we clear the children if one of the
       * children is a no push.
       */
      if (currentOp.getOp().getKind() == SqlKind.AND) {
        newFilter = currentOp.getChildren().get(0);
        for (OpState opState : opStack) {
          if (opState.getOp().getKind() == SqlKind.NOT) {
            //AND under NOT should not get pushed
            newFilter = null;
          }
        }

      }
    } else {
      newFilter = builder.makeCall(currentOp.getOp(), currentOp.getChildren());
    }
  }

  if (newFilter != null) {
    // add this new filter to my parent boolean operator's children
    if (!opStack.isEmpty()) {
      OpState parentOp = opStack.peek();
      parentOp.addChild(newFilter);
    } else {
      resultCondition = newFilter;
    }
  }
}
 
Example 5
Source File: RewriteAsBinaryOperators.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override
public RexNode visitCall(RexCall call) {
  SqlOperator op = call.getOperator();
  SqlKind kind = op.getKind();
  RelDataType type = call.getType();
  if (kind == SqlKind.OR || kind == SqlKind.AND) {
    if (call.getOperands().size() > 2) {
      List<RexNode> children = new ArrayList<>(call.getOperands());
      RexNode left = children.remove(0).accept(this);
      RexNode right = builder.makeCall(type, op, children).accept(this);
      return builder.makeCall(type, op, ImmutableList.of(left, right));
    }
  }
  return builder.makeCall(type, op, visitChildren(call));
}
 
Example 6
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 7
Source File: SideParser.java    From alchemy with Apache License 2.0 5 votes vote down vote up
public static SqlNode[] createEqualNodes(SqlKind sqlKind) {
    SqlNode[] nodes = new SqlNode[2];
    if (SqlKind.AND == sqlKind) {
        nodes[0] = SqlLiteral.createExactNumeric("1", new SqlParserPos(0, 0));
        nodes[1] = SqlLiteral.createExactNumeric("1", new SqlParserPos(0, 0));
    } else {
        nodes[0] = SqlLiteral.createExactNumeric("0", new SqlParserPos(0, 0));
        nodes[1] = SqlLiteral.createExactNumeric("1", new SqlParserPos(0, 0));
    }
    return nodes;
}
 
Example 8
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 9
Source File: RewriteAsBinaryOperators.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public RexNode visitCall(RexCall call) {
  SqlOperator op = call.getOperator();
  SqlKind kind = op.getKind();
  RelDataType type = call.getType();
  if (kind == SqlKind.OR || kind == SqlKind.AND) {
    if (call.getOperands().size() > 2) {
      List<RexNode> children = new ArrayList<>(call.getOperands());
      RexNode left = children.remove(0).accept(this);
      RexNode right = builder.makeCall(type, op, children).accept(this);
      return builder.makeCall(type, op, ImmutableList.of(left, right));
    }
  }
  return builder.makeCall(type, op, visitChildren(call));
}
 
Example 10
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);
}
 
Example 11
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 12
Source File: RelOptUtil.java    From calcite with Apache License 2.0 4 votes vote down vote up
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);
}
 
Example 13
Source File: RelOptUtil.java    From calcite with Apache License 2.0 4 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 14
Source File: PredicateAnalyzer.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Process a call which is a binary operation, transforming into an equivalent
 * query expression. Note that the incoming call may be either a simple binary
 * expression, such as {@code foo > 5}, or it may be several simple expressions connected
 * by {@code AND} or {@code OR} operators, such as {@code foo > 5 AND bar = 'abc' AND 'rot' < 1}
 *
 * @param call existing call
 * @return evaluated expression
 */
private QueryExpression binary(RexCall call) {

  // if AND/OR, do special handling
  if (call.getKind() == SqlKind.AND || call.getKind() == SqlKind.OR) {
    return andOr(call);
  }

  checkForIncompatibleDateTimeOperands(call);

  Preconditions.checkState(call.getOperands().size() == 2);
  final Expression a = call.getOperands().get(0).accept(this);
  final Expression b = call.getOperands().get(1).accept(this);

  final SwapResult pair = swap(a, b);
  final boolean swapped = pair.isSwapped();

  // For _id and _index columns, only equals/not_equals work!
  if (isColumn(pair.getKey(), call, ElasticsearchConstants.ID, false)
      || isColumn(pair.getKey(), call, ElasticsearchConstants.INDEX, false)
      || isColumn(pair.getKey(), call, ElasticsearchConstants.UID, false)) {
    switch (call.getKind()) {
    case EQUALS:
    case NOT_EQUALS:
      break;
    default:
      throw new PredicateAnalyzerException(
          "Cannot handle " + call.getKind() + " expression for _id field, " + call);
    }
  }

  switch (call.getKind()) {
  case CONTAINS:
    return QueryExpression.create(pair.getKey()).contains(pair.getValue());
  case LIKE:
    throw new UnsupportedOperationException("LIKE not yet supported");
  case EQUALS:
    return QueryExpression.create(pair.getKey()).equals(pair.getValue());
  case NOT_EQUALS:
    return QueryExpression.create(pair.getKey()).notEquals(pair.getValue());
  case GREATER_THAN:
    if (swapped) {
      return QueryExpression.create(pair.getKey()).lt(pair.getValue());
    }
    return QueryExpression.create(pair.getKey()).gt(pair.getValue());
  case GREATER_THAN_OR_EQUAL:
    if (swapped) {
      return QueryExpression.create(pair.getKey()).lte(pair.getValue());
    }
    return QueryExpression.create(pair.getKey()).gte(pair.getValue());
  case LESS_THAN:
    if (swapped) {
      return QueryExpression.create(pair.getKey()).gt(pair.getValue());
    }
    return QueryExpression.create(pair.getKey()).lt(pair.getValue());
  case LESS_THAN_OR_EQUAL:
    if (swapped) {
      return QueryExpression.create(pair.getKey()).gte(pair.getValue());
    }
    return QueryExpression.create(pair.getKey()).lte(pair.getValue());
  default:
    break;
  }
  String message = String.format(Locale.ROOT, "Unable to handle call: [%s]", call);
  throw new PredicateAnalyzerException(message);
}
 
Example 15
Source File: PredicateAnalyzer.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
/**
 * Process a call which is a binary operation, transforming into an equivalent
 * query expression. Note that the incoming call may be either a simple binary
 * expression, such as 'foo > 5', or it may be several simple expressions connected
 * by 'AND' or 'OR' operators, such as 'foo > 5 AND bar = 'abc' AND 'rot' < 1'.
 */
private QueryExpression binary(RexCall call) {

  // if AND/OR, do special handling
  if (call.getKind() == SqlKind.AND || call.getKind() == SqlKind.OR) {
    return andOr(call);
  }

  checkForIncompatibleDateTimeOperands(call);

  Preconditions.checkState(call.getOperands().size() == 2);
  final Expression a = call.getOperands().get(0).accept(this);
  final Expression b = call.getOperands().get(1).accept(this);

  final SwapResult pair = swap(a, b);
  final boolean swapped = pair.isSwapped();

  // For _id and _index columns, only equals/not_equals work!
  if (isColumn(pair.getKey(), call, ElasticsearchConstants.ID, false)
    || isColumn(pair.getKey(), call, ElasticsearchConstants.INDEX, false)
    || isColumn(pair.getKey(), call, ElasticsearchConstants.UID, false)) {
    switch (call.getKind()) {
      case EQUALS:
      case NOT_EQUALS:
        break;
      default:
        throw new PredicateAnalyzerException("Cannot handle " + call.getKind() + " expression for _id field, " + call);
    }
  }

 // Fields cannot be queried without being indexed
  final NamedFieldExpression fieldExpression = (NamedFieldExpression) pair.getKey();
  if (fieldExpression.getAnnotation() != null && fieldExpression.getAnnotation().isNotIndexed()) {
    throw new PredicateAnalyzerException("Cannot handle " + call.getKind() + " expression because indexing is disabled, " + call);
  }

  // Analyzed text fields and normalized keyword fields cannot be pushed down unless allowed in settings
  if (!config.isAllowPushdownOnNormalizedOrAnalyzedFields() &&
      fieldExpression.getAnnotation() != null && fieldExpression.getType().isText() &&
      (fieldExpression.getAnnotation().isAnalyzed() || fieldExpression.getAnnotation().isNormalized())) {
    throw new PredicateAnalyzerException(
        "Cannot handle " + call.getKind() + " expression because text or keyword field is analyzed or normalized, " + call);
  }

  switch (call.getKind()) {
    case LIKE:
      // LIKE/regexp cannot handle metadata columns
      isMeta(pair.getKey(), call, true);
      String sqlRegex = RegexpUtil.sqlToRegexLike(pair.getValue().stringValue());
      RexLiteral sqlRegexLiteral = rexBuilder.makeLiteral(sqlRegex);
      LiteralExpression sqlRegexExpression = new LiteralExpression(sqlRegexLiteral);
      SqlLikeOperator likeOperator = (SqlLikeOperator) call.getOperator();
      if (likeOperator.isNegated()) {
        return QueryExpression.create(pair.getKey()).notLike(sqlRegexExpression);
      } else {
        return QueryExpression.create(pair.getKey()).like(sqlRegexExpression);
      }
    case EQUALS:
      return QueryExpression.create(pair.getKey()).equals(pair.getValue());
    case NOT_EQUALS:
      return QueryExpression.create(pair.getKey()).notEquals(pair.getValue());
    case GREATER_THAN:
      if (swapped) {
        return QueryExpression.create(pair.getKey()).lt(pair.getValue());
      }
      return QueryExpression.create(pair.getKey()).gt(pair.getValue());
    case GREATER_THAN_OR_EQUAL:
      if (swapped) {
        return QueryExpression.create(pair.getKey()).lte(pair.getValue());
      }
      return QueryExpression.create(pair.getKey()).gte(pair.getValue());
    case LESS_THAN:
      if (swapped) {
        return QueryExpression.create(pair.getKey()).gt(pair.getValue());
      }
      return QueryExpression.create(pair.getKey()).lt(pair.getValue());
    case LESS_THAN_OR_EQUAL:
      if (swapped) {
        return QueryExpression.create(pair.getKey()).gte(pair.getValue());
      }
      return QueryExpression.create(pair.getKey()).lte(pair.getValue());
    default:
      break;
  }
  throw new PredicateAnalyzerException(format("Unable to handle call: [%s]", call));
}
 
Example 16
Source File: RelOptUtil.java    From Bats with Apache License 2.0 4 votes vote down vote up
/**
 * Helper method for
 * {@link #splitJoinCondition(RexBuilder, int, RexNode, List, List, List, List)} and
 * {@link #splitJoinCondition(List, List, RexNode, List, List, List, List)}.
 *
 * <p>If the given expr <code>call</code> is an expanded version of
 * IS NOT DISTINCT FROM function call, collapse it and return a
 * IS NOT DISTINCT FROM function call.
 *
 * <p>For example: {@code t1.key IS NOT DISTINCT FROM t2.key}
 * can rewritten in expanded form as
 * {@code t1.key = t2.key OR (t1.key IS NULL AND t2.key IS NULL)}.
 *
 * @param call       Function expression to try collapsing.
 * @param rexBuilder {@link RexBuilder} instance to create new {@link RexCall} instances.
 * @return If the given function is an expanded IS NOT DISTINCT FROM function call,
 *         return a IS NOT DISTINCT FROM function call. Otherwise return the input
 *         function call as it is.
 */
private static RexCall collapseExpandedIsNotDistinctFromExpr(final RexCall call, final RexBuilder rexBuilder) {
    if (call.getKind() != SqlKind.OR || call.getOperands().size() != 2) {
        return call;
    }

    final RexNode op0 = call.getOperands().get(0);
    final RexNode op1 = call.getOperands().get(1);

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

    RexCall opEqCall = (RexCall) op0;
    RexCall opNullEqCall = (RexCall) op1;

    if (opEqCall.getKind() == SqlKind.AND && opNullEqCall.getKind() == SqlKind.EQUALS) {
        RexCall temp = opEqCall;
        opEqCall = opNullEqCall;
        opNullEqCall = temp;
    }

    if (opNullEqCall.getKind() != SqlKind.AND || opNullEqCall.getOperands().size() != 2
            || opEqCall.getKind() != SqlKind.EQUALS) {
        return call;
    }

    final RexNode op10 = opNullEqCall.getOperands().get(0);
    final RexNode op11 = opNullEqCall.getOperands().get(1);
    if (op10.getKind() != SqlKind.IS_NULL || op11.getKind() != SqlKind.IS_NULL) {
        return call;
    }
    final RexNode isNullInput0 = ((RexCall) op10).getOperands().get(0);
    final RexNode isNullInput1 = ((RexCall) op11).getOperands().get(0);

    final String isNullInput0Digest = isNullInput0.toString();
    final String isNullInput1Digest = isNullInput1.toString();
    final String equalsInput0Digest = opEqCall.getOperands().get(0).toString();
    final String equalsInput1Digest = opEqCall.getOperands().get(1).toString();

    if ((isNullInput0Digest.equals(equalsInput0Digest) && isNullInput1Digest.equals(equalsInput1Digest))
            || (isNullInput1Digest.equals(equalsInput0Digest) && isNullInput0Digest.equals(equalsInput1Digest))) {
        return (RexCall) rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_DISTINCT_FROM,
                ImmutableList.of(isNullInput0, isNullInput1));
    }

    return call;
}
 
Example 17
Source File: RelOptUtil.java    From Bats 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 18
Source File: RexUtil.java    From Bats with Apache License 2.0 2 votes vote down vote up
/**
 * Returns whether an operator is associative. AND is associative,
 * which means that "(x AND y) and z" is equivalent to "x AND (y AND z)".
 * We might well flatten the tree, and write "AND(x, y, z)".
 */
private static boolean isAssociative(SqlOperator op) {
    return op.getKind() == SqlKind.AND || op.getKind() == SqlKind.OR;
}
 
Example 19
Source File: RexUtil.java    From calcite with Apache License 2.0 2 votes vote down vote up
/**
 * Returns whether an operator is associative. AND is associative,
 * which means that "(x AND y) and z" is equivalent to "x AND (y AND z)".
 * We might well flatten the tree, and write "AND(x, y, z)".
 */
private static boolean isAssociative(SqlOperator op) {
  return op.getKind() == SqlKind.AND
      || op.getKind() == SqlKind.OR;
}