Search in sources :

Example 11 with SqlFunction

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlFunction in project druid by druid-io.

the class ExpressionsTest method testTruncate.

@Test
public void testTruncate() {
    final SqlFunction truncateFunction = new TruncateOperatorConversion().calciteOperator();
    testHelper.testExpression(truncateFunction, testHelper.makeInputRef("a"), DruidExpression.ofExpression(ColumnType.LONG, (args) -> "(cast(cast(" + args.get(0).getExpression() + " * 1,'long'),'double') / 1)", ImmutableList.of(DruidExpression.ofColumn(ColumnType.LONG, "a"))), 10.0);
    testHelper.testExpression(truncateFunction, testHelper.makeInputRef("x"), DruidExpression.ofExpression(ColumnType.FLOAT, (args) -> "(cast(cast(" + args.get(0).getExpression() + " * 1,'long'),'double') / 1)", ImmutableList.of(DruidExpression.ofColumn(ColumnType.FLOAT, "x"))), 2.0);
    testHelper.testExpression(truncateFunction, testHelper.makeInputRef("y"), DruidExpression.ofExpression(ColumnType.LONG, (args) -> "(cast(cast(" + args.get(0).getExpression() + " * 1,'long'),'double') / 1)", ImmutableList.of(DruidExpression.ofColumn(ColumnType.LONG, "y"))), 3.0);
    testHelper.testExpression(truncateFunction, testHelper.makeInputRef("z"), DruidExpression.ofExpression(ColumnType.FLOAT, (args) -> "(cast(cast(" + args.get(0).getExpression() + " * 1,'long'),'double') / 1)", ImmutableList.of(DruidExpression.ofColumn(ColumnType.FLOAT, "z"))), -2.0);
    testHelper.testExpressionString(truncateFunction, ImmutableList.of(testHelper.makeInputRef("x"), testHelper.makeLiteral(1)), DruidExpression.ofExpression(ColumnType.FLOAT, (args) -> "(cast(cast(" + args.get(0).getExpression() + " * 10.0,'long'),'double') / 10.0)", ImmutableList.of(DruidExpression.ofColumn(ColumnType.FLOAT, "x"), DruidExpression.ofLiteral(ColumnType.LONG, DruidExpression.numberLiteral(1)))), 2.2);
    testHelper.testExpressionString(truncateFunction, ImmutableList.of(testHelper.makeInputRef("z"), testHelper.makeLiteral(1)), DruidExpression.ofExpression(ColumnType.FLOAT, (args) -> "(cast(cast(" + args.get(0).getExpression() + " * 10.0,'long'),'double') / 10.0)", ImmutableList.of(DruidExpression.ofColumn(ColumnType.FLOAT, "z"), DruidExpression.ofLiteral(ColumnType.LONG, DruidExpression.numberLiteral(1)))), -2.2);
    testHelper.testExpressionString(truncateFunction, ImmutableList.of(testHelper.makeInputRef("b"), testHelper.makeLiteral(-1)), DruidExpression.ofExpression(ColumnType.LONG, (args) -> "(cast(cast(" + args.get(0).getExpression() + " * 0.1,'long'),'double') / 0.1)", ImmutableList.of(DruidExpression.ofColumn(ColumnType.LONG, "b"), DruidExpression.ofLiteral(ColumnType.LONG, DruidExpression.numberLiteral(-1)))), 20.0);
    testHelper.testExpressionString(truncateFunction, ImmutableList.of(testHelper.makeInputRef("z"), testHelper.makeLiteral(-1)), DruidExpression.ofExpression(ColumnType.FLOAT, (args) -> "(cast(cast(" + args.get(0).getExpression() + " * 0.1,'long'),'double') / 0.1)", ImmutableList.of(DruidExpression.ofColumn(ColumnType.FLOAT, "z"), DruidExpression.ofLiteral(ColumnType.LONG, DruidExpression.numberLiteral(-1)))), 0.0);
}
Also used : RPadOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.RPadOperatorConversion) SqlTrimFunction(org.apache.calcite.sql.fun.SqlTrimFunction) TimeUnit(org.apache.calcite.avatica.util.TimeUnit) ReverseOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.ReverseOperatorConversion) BigDecimal(java.math.BigDecimal) SearchQueryDimFilter(org.apache.druid.query.filter.SearchQueryDimFilter) TimeParseOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.TimeParseOperatorConversion) Map(java.util.Map) LeftOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.LeftOperatorConversion) RoundOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.RoundOperatorConversion) IAE(org.apache.druid.java.util.common.IAE) ContainsOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.ContainsOperatorConversion) TimeFloorOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.TimeFloorOperatorConversion) StringFormatOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.StringFormatOperatorConversion) DateTimes(org.apache.druid.java.util.common.DateTimes) RegexDimFilter(org.apache.druid.query.filter.RegexDimFilter) ImmutableMap(com.google.common.collect.ImmutableMap) RegexpExtractOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.RegexpExtractOperatorConversion) TestExprMacroTable(org.apache.druid.query.expression.TestExprMacroTable) RegexDimExtractionFn(org.apache.druid.query.extraction.RegexDimExtractionFn) TimeCeilOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.TimeCeilOperatorConversion) SqlStdOperatorTable(org.apache.calcite.sql.fun.SqlStdOperatorTable) TruncateOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.TruncateOperatorConversion) RegexpLikeOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.RegexpLikeOperatorConversion) RightOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.RightOperatorConversion) DateTruncOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.DateTruncOperatorConversion) RepeatOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.RepeatOperatorConversion) TimeUnitRange(org.apache.calcite.avatica.util.TimeUnitRange) ImmutableList(com.google.common.collect.ImmutableList) TimeExtractOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.TimeExtractOperatorConversion) ExpressionVirtualColumn(org.apache.druid.segment.virtual.ExpressionVirtualColumn) HumanReadableFormatOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.HumanReadableFormatOperatorConversion) Before(org.junit.Before) TimeShiftOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.TimeShiftOperatorConversion) SqlIntervalQualifier(org.apache.calcite.sql.SqlIntervalQualifier) SqlParserPos(org.apache.calcite.sql.parser.SqlParserPos) Period(org.joda.time.Period) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) TimeFormatOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.TimeFormatOperatorConversion) LPadOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.LPadOperatorConversion) Test(org.junit.Test) StrposOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.StrposOperatorConversion) SqlFunction(org.apache.calcite.sql.SqlFunction) NullHandling(org.apache.druid.common.config.NullHandling) RowSignature(org.apache.druid.segment.column.RowSignature) ParseLongOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.ParseLongOperatorConversion) ColumnType(org.apache.druid.segment.column.ColumnType) ContainsSearchQuerySpec(org.apache.druid.query.search.ContainsSearchQuerySpec) Collections(java.util.Collections) TruncateOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.TruncateOperatorConversion) SqlFunction(org.apache.calcite.sql.SqlFunction) Test(org.junit.Test)

Example 12 with SqlFunction

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlFunction in project druid by druid-io.

the class ExpressionsTest method testRoundWithInvalidSecondArgument.

@Test
public void testRoundWithInvalidSecondArgument() {
    final SqlFunction roundFunction = new RoundOperatorConversion().calciteOperator();
    expectException(IAE.class, "The second argument to the function[round] should be integer type but got the type: STRING");
    testHelper.testExpressionString(roundFunction, ImmutableList.of(testHelper.makeInputRef("x"), testHelper.makeLiteral("foo")), DruidExpression.ofExpression(ColumnType.FLOAT, DruidExpression.functionCall("round"), ImmutableList.of(DruidExpression.ofColumn(ColumnType.FLOAT, "x"), DruidExpression.ofStringLiteral("foo"))), "IAE Exception");
}
Also used : RoundOperatorConversion(org.apache.druid.sql.calcite.expression.builtin.RoundOperatorConversion) SqlFunction(org.apache.calcite.sql.SqlFunction) Test(org.junit.Test)

Example 13 with SqlFunction

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlFunction in project hazelcast by hazelcast.

the class NamedOperandCheckerProgram method check.

public boolean check(HazelcastCallBinding callBinding, boolean throwOnFailure) {
    boolean res = true;
    SqlCall call = callBinding.getCall();
    SqlFunction operator = (SqlFunction) call.getOperator();
    for (int i = 0; i < call.operandCount(); i++) {
        SqlNode operand = call.operand(i);
        assert operand.getKind() == SqlKind.ARGUMENT_ASSIGNMENT;
        SqlIdentifier id = ((SqlCall) operand).operand(1);
        OperandChecker checker = findOperandChecker(id, operator);
        res &= checker.check(callBinding, false, i);
    }
    if (!res && throwOnFailure) {
        throw callBinding.newValidationSignatureError();
    }
    return res;
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlFunction(org.apache.calcite.sql.SqlFunction) SqlNode(org.apache.calcite.sql.SqlNode)

Example 14 with SqlFunction

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlFunction in project hive by apache.

the class HiveSubQueryRemoveRule method rewriteInExists.

private RexNode rewriteInExists(RexSubQuery e, Set<CorrelationId> variablesSet, RelOptUtil.Logic logic, RelBuilder builder, int offset, boolean isCorrScalarAgg) {
    // Most general case, where the left and right keys might have nulls, and
    // caller requires 3-valued logic return.
    // 
    // select e.deptno, e.deptno in (select deptno from emp)
    // 
    // becomes
    // 
    // select e.deptno,
    // case
    // when ct.c = 0 then false
    // when dt.i is not null then true
    // when e.deptno is null then null
    // when ct.ck < ct.c then null
    // else false
    // end
    // from e
    // left join (
    // (select count(*) as c, count(deptno) as ck from emp) as ct
    // cross join (select distinct deptno, true as i from emp)) as dt
    // on e.deptno = dt.deptno
    // 
    // If keys are not null we can remove "ct" and simplify to
    // 
    // select e.deptno,
    // case
    // when dt.i is not null then true
    // else false
    // end
    // from e
    // left join (select distinct deptno, true as i from emp) as dt
    // on e.deptno = dt.deptno
    // 
    // We could further simplify to
    // 
    // select e.deptno,
    // dt.i is not null
    // from e
    // left join (select distinct deptno, true as i from emp) as dt
    // on e.deptno = dt.deptno
    // 
    // but have not yet.
    // 
    // If the logic is TRUE we can just kill the record if the condition
    // evaluates to FALSE or UNKNOWN. Thus the query simplifies to an inner
    // join:
    // 
    // select e.deptno,
    // true
    // from e
    // inner join (select distinct deptno from emp) as dt
    // on e.deptno = dt.deptno
    // 
    final List<RexNode> fields = new ArrayList<>();
    if (e.getKind() == SqlKind.IN) {
        builder.push(e.rel);
        fields.addAll(builder.fields());
        // will produce wrong results (because we further rewrite such queries into JOIN)
        if (isCorrScalarAgg) {
            // returns single row/column
            builder.aggregate(builder.groupKey(), builder.count(false, "cnt_in"));
            if (!variablesSet.isEmpty()) {
                builder.join(JoinRelType.LEFT, builder.literal(true), variablesSet);
            } else {
                builder.join(JoinRelType.INNER, builder.literal(true), variablesSet);
            }
            SqlFunction inCountCheck = new SqlFunction("sq_count_check", SqlKind.OTHER_FUNCTION, ReturnTypes.BOOLEAN, InferTypes.RETURN_TYPE, OperandTypes.NUMERIC, SqlFunctionCategory.USER_DEFINED_FUNCTION);
            // we create FILTER (sq_count_check(count())) instead of PROJECT
            // because RelFieldTrimmer ends up getting rid of Project
            // since it is not used further up the tree.
            // sq_count_check returns true when subquery returns single row, else it fails
            builder.filter(// true here indicates that sq_count_check is for IN/NOT IN subqueries
            builder.call(inCountCheck, builder.field("cnt_in"), builder.literal(true)));
            offset = offset + 1;
            builder.push(e.rel);
        }
    } else if (e.getKind() == SqlKind.EXISTS && !variablesSet.isEmpty()) {
        // Query has 'exists' and correlation:
        // select * from web_sales ws1
        // where exists (select 1 from web_sales ws2 where ws1.ws_order_number = ws2.ws_order_number limit 1);
        // 
        // HiveRelDecorrelator will replace LogicalCorrelate with a SemiJoin. Hence the right hand side won't be
        // evaluated for every row coming from left and SortLimit cuts the right result set incorrectly. (HIVE-24199)
        builder.push(e.rel.accept(new HiveSortLimitRemover()));
    } else {
        // Query may has exists but no correlation
        // select * from web_sales ws1
        // where exists (select 1 from web_sales ws2 where ws2.ws_order_number = 2 limit 1);
        builder.push(e.rel);
    }
    boolean isCandidateForAntiJoin = false;
    // First, the cross join
    switch(logic) {
        case TRUE_FALSE_UNKNOWN:
        case UNKNOWN_AS_TRUE:
            // null keys we do not need to generate count(*), count(c)
            if (e.getKind() == SqlKind.EXISTS) {
                logic = RelOptUtil.Logic.TRUE_FALSE;
                if (conf.getBoolVar(HiveConf.ConfVars.HIVE_CONVERT_ANTI_JOIN)) {
                    // TODO : As of now anti join is first converted to left outer join
                    // and then converted to anti join.
                    // logic = RelOptUtil.Logic.FALSE;
                    isCandidateForAntiJoin = true;
                }
                break;
            }
            builder.aggregate(builder.groupKey(), builder.count(false, "c"), builder.aggregateCall(SqlStdOperatorTable.COUNT, false, null, "ck", builder.fields()));
            builder.as("ct");
            if (!variablesSet.isEmpty()) {
                // builder.join(JoinRelType.INNER, builder.literal(true), variablesSet);
                builder.join(JoinRelType.LEFT, builder.literal(true), variablesSet);
            } else {
                builder.join(JoinRelType.INNER, builder.literal(true), variablesSet);
            }
            offset += 2;
            builder.push(e.rel);
            break;
    }
    // Now the left join
    String trueLiteral = "literalTrue";
    switch(logic) {
        case TRUE:
        case FALSE:
            if (fields.isEmpty()) {
                if (logic == RelOptUtil.Logic.TRUE) {
                    builder.project(builder.alias(builder.literal(true), trueLiteral));
                } else {
                    builder.project(builder.alias(builder.literal(false), "literalFalse"));
                }
                if (!variablesSet.isEmpty() && (e.getKind() == SqlKind.EXISTS || e.getKind() == SqlKind.IN)) {
                    // since this is rewritting into semijoin
                    break;
                } else {
                    builder.aggregate(builder.groupKey(0));
                }
            } else {
                if (!variablesSet.isEmpty() && (e.getKind() == SqlKind.EXISTS || e.getKind() == SqlKind.IN)) {
                    // since this is rewritting into semijoin
                    break;
                } else {
                    builder.aggregate(builder.groupKey(fields));
                }
            }
            break;
        default:
            fields.add(builder.alias(builder.literal(true), trueLiteral));
            builder.project(fields);
            // later during semi/anti join processing at genMapGroupByForSemijoin.
            if (!isCandidateForAntiJoin || variablesSet.isEmpty()) {
                builder.distinct();
            }
    }
    builder.as("dt");
    final List<RexNode> conditions = new ArrayList<>();
    for (Pair<RexNode, RexNode> pair : Pair.zip(e.getOperands(), builder.fields())) {
        conditions.add(builder.equals(pair.left, RexUtil.shift(pair.right, offset)));
    }
    switch(logic) {
        case TRUE:
            builder.join(JoinRelType.SEMI, builder.and(conditions), variablesSet);
            return builder.literal(true);
        case FALSE:
            builder.join(JoinRelType.ANTI, builder.and(conditions), variablesSet);
            return builder.literal(false);
    }
    builder.join(JoinRelType.LEFT, builder.and(conditions), variablesSet);
    final List<RexNode> keyIsNulls = new ArrayList<>();
    for (RexNode operand : e.getOperands()) {
        if (operand.getType().isNullable()) {
            keyIsNulls.add(builder.isNull(operand));
        }
    }
    final ImmutableList.Builder<RexNode> operands = ImmutableList.builder();
    switch(logic) {
        case TRUE_FALSE_UNKNOWN:
        case UNKNOWN_AS_TRUE:
            operands.add(builder.equals(builder.field("ct", "c"), builder.literal(0)), builder.literal(false));
            // now that we are using LEFT OUTER JOIN to join inner count, count(*)
            // with outer table, we wouldn't be able to tell if count is zero
            // for inner table since inner join with correlated values will get rid
            // of all values where join cond is not true (i.e where actual inner table
            // will produce zero result). To  handle this case we need to check both
            // count is zero or count is null
            operands.add((builder.isNull(builder.field("ct", "c"))), builder.literal(false));
            break;
    }
    operands.add(builder.isNotNull(builder.field("dt", trueLiteral)), builder.literal(true));
    if (!keyIsNulls.isEmpty()) {
        // Calcite creates null literal with Null type here but
        // because HIVE doesn't support null type it is appropriately typed boolean
        operands.add(builder.or(keyIsNulls), e.rel.getCluster().getRexBuilder().makeNullLiteral(SqlTypeName.BOOLEAN));
    // we are creating filter here so should not be returning NULL.
    // Not sure why Calcite return NULL
    }
    RexNode b = builder.literal(true);
    switch(logic) {
        case TRUE_FALSE_UNKNOWN:
            b = e.rel.getCluster().getRexBuilder().makeNullLiteral(SqlTypeName.BOOLEAN);
        // fall through
        case UNKNOWN_AS_TRUE:
            operands.add(builder.call(SqlStdOperatorTable.LESS_THAN, builder.field("ct", "ck"), builder.field("ct", "c")), b);
            break;
    }
    operands.add(builder.literal(false));
    return builder.call(SqlStdOperatorTable.CASE, operands.build());
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) ArrayList(java.util.ArrayList) RexNode(org.apache.calcite.rex.RexNode) SqlFunction(org.apache.calcite.sql.SqlFunction)

Example 15 with SqlFunction

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlFunction in project drill by axbaretto.

the class PreProcessLogicalRel method visit.

@Override
public RelNode visit(LogicalProject project) {
    final List<RexNode> projExpr = Lists.newArrayList();
    for (RexNode rexNode : project.getChildExps()) {
        projExpr.add(rexNode.accept(unwrappingExpressionVisitor));
    }
    project = project.copy(project.getTraitSet(), project.getInput(), projExpr, project.getRowType());
    List<RexNode> exprList = new ArrayList<>();
    boolean rewrite = false;
    for (RexNode rex : project.getChildExps()) {
        RexNode newExpr = rex;
        if (rex instanceof RexCall) {
            RexCall function = (RexCall) rex;
            String functionName = function.getOperator().getName();
            int nArgs = function.getOperands().size();
            // check if its a convert_from or convert_to function
            if (functionName.equalsIgnoreCase("convert_from") || functionName.equalsIgnoreCase("convert_to")) {
                String literal;
                if (nArgs == 2) {
                    if (function.getOperands().get(1) instanceof RexLiteral) {
                        try {
                            literal = ((NlsString) (((RexLiteral) function.getOperands().get(1)).getValue())).getValue();
                        } catch (final ClassCastException e) {
                            // Caused by user entering a value with a non-string literal
                            throw getConvertFunctionInvalidTypeException(function);
                        }
                    } else {
                        // caused by user entering a non-literal
                        throw getConvertFunctionInvalidTypeException(function);
                    }
                } else {
                    // Second operand is missing
                    throw UserException.parseError().message("'%s' expects a string literal as a second argument.", functionName).build(logger);
                }
                RexBuilder builder = new RexBuilder(factory);
                // construct the new function name based on the input argument
                String newFunctionName = functionName + literal;
                // Look up the new function name in the drill operator table
                List<SqlOperator> operatorList = table.getSqlOperator(newFunctionName);
                if (operatorList.size() == 0) {
                    // User typed in an invalid type name
                    throw getConvertFunctionException(functionName, literal);
                }
                SqlFunction newFunction = null;
                // Find the SqlFunction with the correct args
                for (SqlOperator op : operatorList) {
                    if (op.getOperandTypeChecker().getOperandCountRange().isValidCount(nArgs - 1)) {
                        newFunction = (SqlFunction) op;
                        break;
                    }
                }
                if (newFunction == null) {
                    // we are here because we found some dummy convert function. (See DummyConvertFrom and DummyConvertTo)
                    throw getConvertFunctionException(functionName, literal);
                }
                // create the new expression to be used in the rewritten project
                newExpr = builder.makeCall(newFunction, function.getOperands().subList(0, 1));
                rewrite = true;
            }
        }
        exprList.add(newExpr);
    }
    if (rewrite == true) {
        LogicalProject newProject = project.copy(project.getTraitSet(), project.getInput(0), exprList, project.getRowType());
        return visitChild(newProject, 0, project.getInput());
    }
    return visitChild(project, 0, project.getInput());
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) SqlOperator(org.apache.calcite.sql.SqlOperator) ArrayList(java.util.ArrayList) NlsString(org.apache.calcite.util.NlsString) RexCall(org.apache.calcite.rex.RexCall) RexBuilder(org.apache.calcite.rex.RexBuilder) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexNode(org.apache.calcite.rex.RexNode) SqlFunction(org.apache.calcite.sql.SqlFunction)

Aggregations

SqlFunction (org.apache.calcite.sql.SqlFunction)30 SqlOperator (org.apache.calcite.sql.SqlOperator)13 ArrayList (java.util.ArrayList)7 RexNode (org.apache.calcite.rex.RexNode)6 RoundOperatorConversion (org.apache.druid.sql.calcite.expression.builtin.RoundOperatorConversion)6 Test (org.junit.Test)6 SqlCall (org.apache.calcite.sql.SqlCall)5 ImmutableList (com.google.common.collect.ImmutableList)4 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)4 BigDecimal (java.math.BigDecimal)3 RexCall (org.apache.calcite.rex.RexCall)3 RexLiteral (org.apache.calcite.rex.RexLiteral)3 SqlNode (org.apache.calcite.sql.SqlNode)3 List (java.util.List)2 TimeUnitRange (org.apache.calcite.avatica.util.TimeUnitRange)2 LogicalProject (org.apache.calcite.rel.logical.LogicalProject)2 RelDataType (org.apache.calcite.rel.type.RelDataType)2 RexBuilder (org.apache.calcite.rex.RexBuilder)2 SqlAggFunction (org.apache.calcite.sql.SqlAggFunction)2 SqlBasicCall (org.apache.calcite.sql.SqlBasicCall)2