Search in sources :

Example 41 with SqlFunction

use of org.apache.calcite.sql.SqlFunction in project calcite by apache.

the class SqlFloorFunction method unparseDatetimeFunction.

/**
 * Most dialects that natively support datetime floor will use this.
 * In those cases the call will look like TRUNC(datetime, 'year').
 *
 * @param writer SqlWriter
 * @param call SqlCall
 * @param funName Name of the sql function to call
 * @param datetimeFirst Specify the order of the datetime & timeUnit
 * arguments
 */
public static void unparseDatetimeFunction(SqlWriter writer, SqlCall call, String funName, Boolean datetimeFirst) {
    SqlFunction func = new SqlFunction(funName, SqlKind.OTHER_FUNCTION, ReturnTypes.ARG0_NULLABLE_VARYING, null, null, SqlFunctionCategory.STRING);
    SqlCall call1;
    if (datetimeFirst) {
        call1 = call;
    } else {
        // switch order of operands
        SqlNode op1 = call.operand(0);
        SqlNode op2 = call.operand(1);
        call1 = call.getOperator().createCall(call.getParserPosition(), op2, op1);
    }
    SqlUtil.unparseFunctionSyntax(func, writer, call1, false);
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) SqlFunction(org.apache.calcite.sql.SqlFunction) SqlNode(org.apache.calcite.sql.SqlNode)

Example 42 with SqlFunction

use of org.apache.calcite.sql.SqlFunction in project calcite by apache.

the class RelOptRulesTest method testMonotonicityUDF.

/**
 * Test case for
 * <a href="https://issues.apache.org/jira/browse/CALCITE-3151">[CALCITE-3151]
 * RexCall's Monotonicity is not considered in determining a Calc's
 * collation</a>.
 */
@Test
void testMonotonicityUDF() {
    final SqlFunction monotonicityFun = new SqlFunction("MONOFUN", SqlKind.OTHER_FUNCTION, ReturnTypes.BIGINT, null, OperandTypes.NILADIC, SqlFunctionCategory.USER_DEFINED_FUNCTION) {

        @Override
        public boolean isDeterministic() {
            return false;
        }

        @Override
        public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
            return SqlMonotonicity.INCREASING;
        }
    };
    // Build a tree equivalent to the SQL
    // SELECT sal, MONOFUN() AS n FROM emp
    final RelBuilder builder = RelBuilder.create(RelBuilderTest.config().build());
    final RelNode root = builder.scan("EMP").project(builder.field("SAL"), builder.alias(builder.call(monotonicityFun), "M")).build();
    HepProgram preProgram = new HepProgramBuilder().build();
    HepPlanner prePlanner = new HepPlanner(preProgram);
    prePlanner.setRoot(root);
    final RelNode relBefore = prePlanner.findBestExp();
    final RelCollation collationBefore = relBefore.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE);
    HepProgram hepProgram = new HepProgramBuilder().addRuleInstance(CoreRules.PROJECT_TO_CALC).build();
    HepPlanner hepPlanner = new HepPlanner(hepProgram);
    hepPlanner.setRoot(root);
    final RelNode relAfter = hepPlanner.findBestExp();
    final RelCollation collationAfter = relAfter.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE);
    assertEquals(collationBefore, collationAfter);
}
Also used : SqlOperatorBinding(org.apache.calcite.sql.SqlOperatorBinding) RelCollation(org.apache.calcite.rel.RelCollation) RelBuilder(org.apache.calcite.tools.RelBuilder) HepProgram(org.apache.calcite.plan.hep.HepProgram) RelNode(org.apache.calcite.rel.RelNode) HepProgramBuilder(org.apache.calcite.plan.hep.HepProgramBuilder) HepPlanner(org.apache.calcite.plan.hep.HepPlanner) SqlFunction(org.apache.calcite.sql.SqlFunction) Test(org.junit.jupiter.api.Test)

Example 43 with SqlFunction

use of org.apache.calcite.sql.SqlFunction in project calcite by apache.

the class RelJson method toJson.

private Object toJson(RexNode node) {
    final Map<String, @Nullable Object> map;
    switch(node.getKind()) {
        case FIELD_ACCESS:
            map = jsonBuilder().map();
            final RexFieldAccess fieldAccess = (RexFieldAccess) node;
            map.put("field", fieldAccess.getField().getName());
            map.put("expr", toJson(fieldAccess.getReferenceExpr()));
            return map;
        case LITERAL:
            final RexLiteral literal = (RexLiteral) node;
            final Object value = literal.getValue3();
            map = jsonBuilder().map();
            map.put("literal", RelEnumTypes.fromEnum(value));
            map.put("type", toJson(node.getType()));
            return map;
        case INPUT_REF:
            map = jsonBuilder().map();
            map.put("input", ((RexSlot) node).getIndex());
            map.put("name", ((RexSlot) node).getName());
            return map;
        case LOCAL_REF:
            map = jsonBuilder().map();
            map.put("input", ((RexSlot) node).getIndex());
            map.put("name", ((RexSlot) node).getName());
            map.put("type", toJson(node.getType()));
            return map;
        case CORREL_VARIABLE:
            map = jsonBuilder().map();
            map.put("correl", ((RexCorrelVariable) node).getName());
            map.put("type", toJson(node.getType()));
            return map;
        default:
            if (node instanceof RexCall) {
                final RexCall call = (RexCall) node;
                map = jsonBuilder().map();
                map.put("op", toJson(call.getOperator()));
                final List<@Nullable Object> list = jsonBuilder().list();
                for (RexNode operand : call.getOperands()) {
                    list.add(toJson(operand));
                }
                map.put("operands", list);
                switch(node.getKind()) {
                    case CAST:
                        map.put("type", toJson(node.getType()));
                        break;
                    default:
                        break;
                }
                if (call.getOperator() instanceof SqlFunction) {
                    if (((SqlFunction) call.getOperator()).getFunctionType().isUserDefined()) {
                        SqlOperator op = call.getOperator();
                        map.put("class", op.getClass().getName());
                        map.put("type", toJson(node.getType()));
                        map.put("deterministic", op.isDeterministic());
                        map.put("dynamic", op.isDynamicFunction());
                    }
                }
                if (call instanceof RexOver) {
                    RexOver over = (RexOver) call;
                    map.put("distinct", over.isDistinct());
                    map.put("type", toJson(node.getType()));
                    map.put("window", toJson(over.getWindow()));
                }
                return map;
            }
            throw new UnsupportedOperationException("unknown rex " + node);
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexOver(org.apache.calcite.rex.RexOver) RexLiteral(org.apache.calcite.rex.RexLiteral) SqlOperator(org.apache.calcite.sql.SqlOperator) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode) SqlFunction(org.apache.calcite.sql.SqlFunction)

Example 44 with SqlFunction

use of org.apache.calcite.sql.SqlFunction in project calcite by apache.

the class AggVisitor method visit.

@Override
public Void visit(SqlCall call) {
    final SqlOperator operator = call.getOperator();
    // If nested aggregates disallowed or found an aggregate at invalid level
    if (operator.isAggregator() && !(operator instanceof SqlAbstractGroupFunction) && !operator.requiresOver()) {
        if (delegate != null) {
            return operator.acceptCall(delegate, call);
        }
        if (aggregate) {
            return found(call);
        }
    }
    if (group && operator.isGroup()) {
        return found(call);
    }
    // User-defined function may not be resolved yet.
    if (operator instanceof SqlFunction) {
        final SqlFunction sqlFunction = (SqlFunction) operator;
        if (sqlFunction.getFunctionType().isUserDefinedNotSpecificFunction()) {
            final List<SqlOperator> list = new ArrayList<>();
            final SqlIdentifier identifier = sqlFunction.getSqlIdentifier();
            if (identifier != null) {
                opTab.lookupOperatorOverloads(identifier, sqlFunction.getFunctionType(), SqlSyntax.FUNCTION, list, nameMatcher);
                for (SqlOperator operator2 : list) {
                    if (operator2.isAggregator() && !operator2.requiresOver()) {
                        // level
                        if (aggregate) {
                            found(call);
                        }
                    }
                }
            }
        }
    }
    if (call.isA(SqlKind.QUERY)) {
        // don't traverse into queries
        return null;
    }
    if (call.getKind() == SqlKind.WITHIN_GROUP) {
        if (aggregate) {
            return found(call);
        }
    }
    if (call.getKind() == SqlKind.OVER) {
        if (over) {
            return found(call);
        } else {
            // an aggregate function over a window is not an aggregate!
            return null;
        }
    }
    return super.visit(call);
}
Also used : SqlOperator(org.apache.calcite.sql.SqlOperator) ArrayList(java.util.ArrayList) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlAbstractGroupFunction(org.apache.calcite.sql.fun.SqlAbstractGroupFunction) SqlFunction(org.apache.calcite.sql.SqlFunction)

Example 45 with SqlFunction

use of org.apache.calcite.sql.SqlFunction in project calcite by apache.

the class ReflectiveSqlOperatorTable method lookupOperatorOverloads.

// implement SqlOperatorTable
@Override
public void lookupOperatorOverloads(SqlIdentifier opName, @Nullable SqlFunctionCategory category, SqlSyntax syntax, List<SqlOperator> operatorList, SqlNameMatcher nameMatcher) {
    // NOTE jvs 3-Mar-2005:  ignore category until someone cares
    String simpleName;
    if (opName.names.size() > 1) {
        if (opName.names.get(opName.names.size() - 2).equals(IS_NAME)) {
            // per SQL99 Part 2 Section 10.4 Syntax Rule 7.b.ii.1
            simpleName = Util.last(opName.names);
        } else {
            return;
        }
    } else {
        simpleName = opName.getSimple();
    }
    final Collection<SqlOperator> list = lookUpOperators(simpleName, syntax, nameMatcher);
    if (list.isEmpty()) {
        return;
    }
    for (SqlOperator op : list) {
        if (op.getSyntax() == syntax) {
            operatorList.add(op);
        } else if (syntax == SqlSyntax.FUNCTION && op instanceof SqlFunction) {
            // this special case is needed for operators like CAST,
            // which are treated as functions but have special syntax
            operatorList.add(op);
        }
    }
    // Shouldn't it be covered by search above?
    switch(syntax) {
        case BINARY:
        case PREFIX:
        case POSTFIX:
            for (SqlOperator extra : lookUpOperators(simpleName, syntax, nameMatcher)) {
                // REVIEW: should only search operators added during this method?
                if (extra != null && !operatorList.contains(extra)) {
                    operatorList.add(extra);
                }
            }
            break;
        default:
            break;
    }
}
Also used : SqlOperator(org.apache.calcite.sql.SqlOperator) SqlFunction(org.apache.calcite.sql.SqlFunction)

Aggregations

SqlFunction (org.apache.calcite.sql.SqlFunction)57 SqlOperator (org.apache.calcite.sql.SqlOperator)26 ArrayList (java.util.ArrayList)13 RoundOperatorConversion (org.apache.druid.sql.calcite.expression.builtin.RoundOperatorConversion)12 Test (org.junit.Test)12 RexNode (org.apache.calcite.rex.RexNode)8 SqlCall (org.apache.calcite.sql.SqlCall)8 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)8 AssignableOperandTypeChecker (org.apache.calcite.sql.type.AssignableOperandTypeChecker)6 BitString (org.apache.calcite.util.BitString)6 ImmutableList (com.google.common.collect.ImmutableList)5 RelDataType (org.apache.calcite.rel.type.RelDataType)5 SqlBasicCall (org.apache.calcite.sql.SqlBasicCall)5 RexCall (org.apache.calcite.rex.RexCall)4 RexLiteral (org.apache.calcite.rex.RexLiteral)4 FunctionDefinition (org.apache.flink.table.functions.FunctionDefinition)4 ScalarFunctionDefinition (org.apache.flink.table.functions.ScalarFunctionDefinition)4 BigDecimal (java.math.BigDecimal)3 TimeUnitRange (org.apache.calcite.avatica.util.TimeUnitRange)3 SqlTypeName (org.apache.calcite.sql.type.SqlTypeName)3