org.apache.calcite.sql.fun.SqlCase Java Examples

The following examples show how to use org.apache.calcite.sql.fun.SqlCase. 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: StandardConvertletTable.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Converts a CASE expression.
 */
public RexNode convertCase(
    SqlRexContext cx,
    SqlCase call) {
  SqlNodeList whenList = call.getWhenOperands();
  SqlNodeList thenList = call.getThenOperands();
  assert whenList.size() == thenList.size();

  RexBuilder rexBuilder = cx.getRexBuilder();
  final List<RexNode> exprList = new ArrayList<>();
  for (int i = 0; i < whenList.size(); i++) {
    if (SqlUtil.isNullLiteral(whenList.get(i), false)) {
      exprList.add(rexBuilder.constantNull());
    } else {
      exprList.add(cx.convertExpression(whenList.get(i)));
    }
    if (SqlUtil.isNullLiteral(thenList.get(i), false)) {
      exprList.add(rexBuilder.constantNull());
    } else {
      exprList.add(cx.convertExpression(thenList.get(i)));
    }
  }
  if (SqlUtil.isNullLiteral(call.getElseOperand(), false)) {
    exprList.add(rexBuilder.constantNull());
  } else {
    exprList.add(cx.convertExpression(call.getElseOperand()));
  }

  RelDataType type =
      rexBuilder.deriveReturnType(call.getOperator(), exprList);
  for (int i : elseArgs(exprList.size())) {
    exprList.set(i,
        rexBuilder.ensureType(type, exprList.get(i), false));
  }
  return rexBuilder.makeCall(type, SqlStdOperatorTable.CASE, exprList);
}
 
Example #2
Source File: HsqldbSqlDialect.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override public SqlNode rewriteSingleValueExpr(SqlNode aggCall) {
  final SqlNode operand = ((SqlBasicCall) aggCall).operand(0);
  final SqlLiteral nullLiteral = SqlLiteral.createNull(SqlParserPos.ZERO);
  final SqlNode unionOperand = SqlStdOperatorTable.VALUES.createCall(SqlParserPos.ZERO,
      SqlLiteral.createApproxNumeric("0", SqlParserPos.ZERO));
  // For hsqldb, generate
  //   CASE COUNT(*)
  //   WHEN 0 THEN NULL
  //   WHEN 1 THEN MIN(<result>)
  //   ELSE (VALUES 1 UNION ALL VALUES 1)
  //   END
  final SqlNode caseExpr =
      new SqlCase(SqlParserPos.ZERO,
          SqlStdOperatorTable.COUNT.createCall(SqlParserPos.ZERO, operand),
          SqlNodeList.of(
              SqlLiteral.createExactNumeric("0", SqlParserPos.ZERO),
              SqlLiteral.createExactNumeric("1", SqlParserPos.ZERO)),
          SqlNodeList.of(
              nullLiteral,
              SqlStdOperatorTable.MIN.createCall(SqlParserPos.ZERO, operand)),
          SqlStdOperatorTable.SCALAR_QUERY.createCall(SqlParserPos.ZERO,
              SqlStdOperatorTable.UNION_ALL
                  .createCall(SqlParserPos.ZERO, unionOperand, unionOperand)));

  LOGGER.debug("SINGLE_VALUE rewritten into [{}]", caseExpr);

  return caseExpr;
}
 
Example #3
Source File: MysqlSqlDialect.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override public SqlNode rewriteSingleValueExpr(SqlNode aggCall) {
  final SqlNode operand = ((SqlBasicCall) aggCall).operand(0);
  final SqlLiteral nullLiteral = SqlLiteral.createNull(SqlParserPos.ZERO);
  final SqlNode unionOperand = new SqlSelect(SqlParserPos.ZERO, SqlNodeList.EMPTY,
      SqlNodeList.of(nullLiteral), null, null, null, null, SqlNodeList.EMPTY, null, null, null);
  // For MySQL, generate
  //   CASE COUNT(*)
  //   WHEN 0 THEN NULL
  //   WHEN 1 THEN <result>
  //   ELSE (SELECT NULL UNION ALL SELECT NULL)
  //   END
  final SqlNode caseExpr =
      new SqlCase(SqlParserPos.ZERO,
          SqlStdOperatorTable.COUNT.createCall(SqlParserPos.ZERO, operand),
          SqlNodeList.of(
              SqlLiteral.createExactNumeric("0", SqlParserPos.ZERO),
              SqlLiteral.createExactNumeric("1", SqlParserPos.ZERO)),
          SqlNodeList.of(
              nullLiteral,
              operand),
          SqlStdOperatorTable.SCALAR_QUERY.createCall(SqlParserPos.ZERO,
              SqlStdOperatorTable.UNION_ALL
                  .createCall(SqlParserPos.ZERO, unionOperand, unionOperand)));

  LOGGER.debug("SINGLE_VALUE rewritten into [{}]", caseExpr);

  return caseExpr;
}
 
Example #4
Source File: TypeCoercionImpl.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * CASE and COALESCE type coercion, collect all the branches types including then
 * operands and else operands to find a common type, then cast the operands to the common type
 * when needed.
 */
public boolean caseWhenCoercion(SqlCallBinding callBinding) {
  // For sql statement like:
  // `case when ... then (a, b, c) when ... then (d, e, f) else (g, h, i)`
  // an exception throws when entering this method.
  SqlCase caseCall = (SqlCase) callBinding.getCall();
  SqlNodeList thenList = caseCall.getThenOperands();
  List<RelDataType> argTypes = new ArrayList<RelDataType>();
  for (SqlNode node : thenList) {
    argTypes.add(
        validator.deriveType(
            callBinding.getScope(), node));
  }
  SqlNode elseOp = caseCall.getElseOperand();
  RelDataType elseOpType = validator.deriveType(
      callBinding.getScope(), caseCall.getElseOperand());
  argTypes.add(elseOpType);
  // Entering this method means we have already got a wider type, recompute it here
  // just to make the interface more clear.
  RelDataType widerType = getWiderTypeFor(argTypes, true);
  if (null != widerType) {
    boolean coerced = false;
    for (int i = 0; i < thenList.size(); i++) {
      coerced = coerceColumnType(callBinding.getScope(), thenList, i, widerType) || coerced;
    }
    if (needToCast(callBinding.getScope(), elseOp, widerType)) {
      coerced = coerceOperandType(callBinding.getScope(), caseCall, 3, widerType)
          || coerced;
    }
    return coerced;
  }
  return false;
}
 
Example #5
Source File: HsqldbSqlDialect.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public SqlNode rewriteSingleValueExpr(SqlNode aggCall) {
  final SqlNode operand = ((SqlBasicCall) aggCall).operand(0);
  final SqlLiteral nullLiteral = SqlLiteral.createNull(SqlParserPos.ZERO);
  final SqlNode unionOperand = SqlStdOperatorTable.VALUES.createCall(SqlParserPos.ZERO,
      SqlLiteral.createApproxNumeric("0", SqlParserPos.ZERO));
  // For hsqldb, generate
  //   CASE COUNT(*)
  //   WHEN 0 THEN NULL
  //   WHEN 1 THEN MIN(<result>)
  //   ELSE (VALUES 1 UNION ALL VALUES 1)
  //   END
  final SqlNode caseExpr =
      new SqlCase(SqlParserPos.ZERO,
          SqlStdOperatorTable.COUNT.createCall(SqlParserPos.ZERO, operand),
          SqlNodeList.of(
              SqlLiteral.createExactNumeric("0", SqlParserPos.ZERO),
              SqlLiteral.createExactNumeric("1", SqlParserPos.ZERO)),
          SqlNodeList.of(
              nullLiteral,
              SqlStdOperatorTable.MIN.createCall(SqlParserPos.ZERO, operand)),
          SqlStdOperatorTable.SCALAR_QUERY.createCall(SqlParserPos.ZERO,
              SqlStdOperatorTable.UNION_ALL
                  .createCall(SqlParserPos.ZERO, unionOperand, unionOperand)));

  LOGGER.debug("SINGLE_VALUE rewritten into [{}]", caseExpr);

  return caseExpr;
}
 
Example #6
Source File: MysqlSqlDialect.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public SqlNode rewriteSingleValueExpr(SqlNode aggCall) {
  final SqlNode operand = ((SqlBasicCall) aggCall).operand(0);
  final SqlLiteral nullLiteral = SqlLiteral.createNull(SqlParserPos.ZERO);
  final SqlNode unionOperand = new SqlSelect(SqlParserPos.ZERO, SqlNodeList.EMPTY,
      SqlNodeList.of(nullLiteral), null, null, null, null,
      SqlNodeList.EMPTY, null, null, null, SqlNodeList.EMPTY);
  // For MySQL, generate
  //   CASE COUNT(*)
  //   WHEN 0 THEN NULL
  //   WHEN 1 THEN <result>
  //   ELSE (SELECT NULL UNION ALL SELECT NULL)
  //   END
  final SqlNode caseExpr =
      new SqlCase(SqlParserPos.ZERO,
          SqlStdOperatorTable.COUNT.createCall(SqlParserPos.ZERO, operand),
          SqlNodeList.of(
              SqlLiteral.createExactNumeric("0", SqlParserPos.ZERO),
              SqlLiteral.createExactNumeric("1", SqlParserPos.ZERO)),
          SqlNodeList.of(
              nullLiteral,
              operand),
          SqlStdOperatorTable.SCALAR_QUERY.createCall(SqlParserPos.ZERO,
              SqlStdOperatorTable.UNION_ALL
                  .createCall(SqlParserPos.ZERO, unionOperand, unionOperand)));

  LOGGER.debug("SINGLE_VALUE rewritten into [{}]", caseExpr);

  return caseExpr;
}
 
Example #7
Source File: StandardConvertletTable.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Converts a CASE expression.
 */
public RexNode convertCase(
    SqlRexContext cx,
    SqlCase call) {
  SqlNodeList whenList = call.getWhenOperands();
  SqlNodeList thenList = call.getThenOperands();
  assert whenList.size() == thenList.size();

  RexBuilder rexBuilder = cx.getRexBuilder();
  final List<RexNode> exprList = new ArrayList<>();
  final RelDataTypeFactory typeFactory = rexBuilder.getTypeFactory();
  final RexLiteral unknownLiteral = rexBuilder.makeNullLiteral(
      typeFactory.createSqlType(SqlTypeName.BOOLEAN));
  final RexLiteral nullLiteral = rexBuilder.makeNullLiteral(
      typeFactory.createSqlType(SqlTypeName.NULL));
  for (int i = 0; i < whenList.size(); i++) {
    if (SqlUtil.isNullLiteral(whenList.get(i), false)) {
      exprList.add(unknownLiteral);
    } else {
      exprList.add(cx.convertExpression(whenList.get(i)));
    }
    if (SqlUtil.isNullLiteral(thenList.get(i), false)) {
      exprList.add(nullLiteral);
    } else {
      exprList.add(cx.convertExpression(thenList.get(i)));
    }
  }
  if (SqlUtil.isNullLiteral(call.getElseOperand(), false)) {
    exprList.add(nullLiteral);
  } else {
    exprList.add(cx.convertExpression(call.getElseOperand()));
  }

  RelDataType type =
      rexBuilder.deriveReturnType(call.getOperator(), exprList);
  for (int i : elseArgs(exprList.size())) {
    exprList.set(i,
        rexBuilder.ensureType(type, exprList.get(i), false));
  }
  return rexBuilder.makeCall(type, SqlStdOperatorTable.CASE, exprList);
}
 
Example #8
Source File: CalciteSqlParser.java    From incubator-pinot with Apache License 2.0 4 votes vote down vote up
private static Expression toExpression(SqlNode node) {
  LOGGER.debug("Current processing SqlNode: {}, node.getKind(): {}", node, node.getKind());
  switch (node.getKind()) {
    case IDENTIFIER:
      if (((SqlIdentifier) node).isStar()) {
        return RequestUtils.getIdentifierExpression("*");
      }
      if (((SqlIdentifier) node).isSimple()) {
        return RequestUtils.getIdentifierExpression(((SqlIdentifier) node).getSimple());
      }
      return RequestUtils.getIdentifierExpression(node.toString());
    case LITERAL:
      return RequestUtils.getLiteralExpression((SqlLiteral) node);
    case AS:
      SqlBasicCall asFuncSqlNode = (SqlBasicCall) node;
      final Expression asFuncExpr = RequestUtils.getFunctionExpression(SqlKind.AS.toString());
      asFuncExpr.getFunctionCall().addToOperands(toExpression(asFuncSqlNode.getOperands()[0]));
      SqlNode aliasSqlNode = asFuncSqlNode.getOperands()[1];
      String aliasName;
      switch (aliasSqlNode.getKind()) {
        case IDENTIFIER:
          aliasName = ((SqlIdentifier) aliasSqlNode).getSimple();
          break;
        case LITERAL:
          aliasName = ((SqlLiteral) aliasSqlNode).toValue();
          break;
        default:
          throw new SqlCompilationException("Unsupported Alias sql node - " + aliasSqlNode);
      }
      asFuncExpr.getFunctionCall().addToOperands(RequestUtils.getIdentifierExpression(aliasName));
      return asFuncExpr;
    case CASE:
      // CASE WHEN Statement is model as a function with variable length parameters.
      // Assume N is number of WHEN Statements, total number of parameters is (2 * N + 1).
      // - N: Convert each WHEN Statement into a function Expression;
      // - N: Convert each THEN Statement into an Expression;
      // - 1: Convert ELSE Statement into an Expression.
      SqlCase caseSqlNode = (SqlCase) node;
      SqlNodeList whenOperands = caseSqlNode.getWhenOperands();
      SqlNodeList thenOperands = caseSqlNode.getThenOperands();
      SqlNode elseOperand = caseSqlNode.getElseOperand();
      Expression caseFuncExpr = RequestUtils.getFunctionExpression(SqlKind.CASE.name());
      for (SqlNode whenSqlNode : whenOperands.getList()) {
        Expression whenExpression = toExpression(whenSqlNode);
        if (isAggregateExpression(whenExpression)) {
          throw new SqlCompilationException(
              "Aggregation functions inside WHEN Clause is not supported - " + whenSqlNode);
        }
        caseFuncExpr.getFunctionCall().addToOperands(whenExpression);
      }
      for (SqlNode thenSqlNode : thenOperands.getList()) {
        Expression thenExpression = toExpression(thenSqlNode);
        if (isAggregateExpression(thenExpression)) {
          throw new SqlCompilationException(
              "Aggregation functions inside THEN Clause is not supported - " + thenSqlNode);
        }
        caseFuncExpr.getFunctionCall().addToOperands(thenExpression);
      }
      Expression elseExpression = toExpression(elseOperand);
      if (isAggregateExpression(elseExpression)) {
        throw new SqlCompilationException(
            "Aggregation functions inside ELSE Clause is not supported - " + elseExpression);
      }
      caseFuncExpr.getFunctionCall().addToOperands(elseExpression);
      return caseFuncExpr;
    case OTHER:
      if (node instanceof SqlDataTypeSpec) {
        // This is to handle expression like: CAST(col AS INT)
        return RequestUtils.getLiteralExpression(((SqlDataTypeSpec) node).getTypeName().getSimple());
      } else {
        // Move on to process default logic.
      }
    default:
      return compileFunctionExpression((SqlBasicCall) node);
  }
}