Class SqlOperator

  • Direct Known Subclasses:
    SqlBinaryOperator, SqlCaseOperator, SqlFunction, SqlJoin.SqlJoinOperator, SqlMatchRecognize.SqlMatchRecognizeOperator, SqlPostfixOperator, SqlPrefixOperator, SqlSelectOperator, SqlSpecialOperator, SqlWindow.SqlWindowOperator

    public abstract class SqlOperator
    extends java.lang.Object
    A SqlOperator is a type of node in a SQL parse tree (it is NOT a node in a SQL parse tree). It includes functions, operators such as '=', and syntactic constructs such as 'case' statements. Operators may represent query-level expressions (e.g. SqlSelectOperator or row-level expressions (e.g. SqlBetweenOperator.

    Operators have formal operands, meaning ordered (and optionally named) placeholders for the values they operate on. For example, the division operator takes two operands; the first is the numerator and the second is the denominator. In the context of subclass SqlFunction, formal operands are referred to as parameters.

    When an operator is instantiated via a SqlCall, it is supplied with actual operands. For example, in the expression 3 / 5, the literal expression 3 is the actual operand corresponding to the numerator, and 5 is the actual operand corresponding to the denominator. In the context of SqlFunction, actual operands are referred to as arguments

    In many cases, the formal/actual distinction is clear from context, in which case we drop these qualifiers.

    • Field Detail

      • NL

        public static final java.lang.String NL
      • MDX_PRECEDENCE

        public static final int MDX_PRECEDENCE
        Maximum precedence.
        See Also:
        Constant Field Values
      • name

        private final java.lang.String name
        The name of the operator/function. Ex. "OVERLAY" or "TRIM"
      • kind

        public final SqlKind kind
        See SqlKind. It's possible to have a name that doesn't match the kind
      • leftPrec

        private final int leftPrec
        The precedence with which this operator binds to the expression to the left. This is less than the right precedence if the operator is left-associative.
      • rightPrec

        private final int rightPrec
        The precedence with which this operator binds to the expression to the right. This is more than the left precedence if the operator is left-associative.
      • returnTypeInference

        private final SqlReturnTypeInference returnTypeInference
        used to infer the return type of a call to this operator
      • operandTypeInference

        private final SqlOperandTypeInference operandTypeInference
        used to infer types of unknown operands
      • operandTypeChecker

        private final SqlOperandTypeChecker operandTypeChecker
        used to validate operand types
    • Method Detail

      • leftPrec

        protected static int leftPrec​(int prec,
                                      boolean leftAssoc)
      • rightPrec

        protected static int rightPrec​(int prec,
                                       boolean leftAssoc)
      • getOperandCountRange

        public SqlOperandCountRange getOperandCountRange()
        Returns a constraint on the number of operands expected by this operator. Subclasses may override this method; when they don't, the range is derived from the SqlOperandTypeChecker associated with this operator.
        Returns:
        acceptable range
      • getName

        public java.lang.String getName()
      • getNameAsId

        public SqlIdentifier getNameAsId()
        Returns the fully-qualified name of this operator.
      • getKind

        public SqlKind getKind()
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • getLeftPrec

        public int getLeftPrec()
      • getRightPrec

        public int getRightPrec()
      • getSyntax

        public abstract SqlSyntax getSyntax()
        Returns the syntactic type of this operator, never null.
      • createCall

        public SqlCall createCall​(SqlLiteral functionQualifier,
                                  SqlParserPos pos,
                                  SqlNode... operands)
        Creates a call to this operand with an array of operands.

        The position of the resulting call is the union of the pos and the positions of all of the operands.

        Parameters:
        functionQualifier - function qualifier (e.g. "DISTINCT"), may be
        pos - parser position of the identifier of the call
        operands - array of operands
      • createCall

        public final SqlCall createCall​(SqlParserPos pos,
                                        SqlNode... operands)
        Creates a call to this operand with an array of operands.

        The position of the resulting call is the union of the pos and the positions of all of the operands.

        Parameters:
        pos - Parser position
        operands - List of arguments
        Returns:
        call to this operator
      • createCall

        public final SqlCall createCall​(SqlNodeList nodeList)
        Creates a call to this operand with a list of operands contained in a SqlNodeList.

        The position of the resulting call inferred from the SqlNodeList.

        Parameters:
        nodeList - List of arguments
        Returns:
        call to this operator
      • createCall

        public final SqlCall createCall​(SqlParserPos pos,
                                        java.util.List<? extends SqlNode> operandList)
        Creates a call to this operand with a list of operands.

        The position of the resulting call is the union of the pos and the positions of all of the operands.

      • rewriteCall

        public SqlNode rewriteCall​(SqlValidator validator,
                                   SqlCall call)
        Rewrites a call to this operator. Some operators are implemented as trivial rewrites (e.g. NULLIF becomes CASE). However, we don't do this at createCall time because we want to preserve the original SQL syntax as much as possible; instead, we do this before the call is validated (so the trivial operator doesn't need its own implementation of type derivation methods). The default implementation is to just return the original call without any rewrite.
        Parameters:
        validator - Validator
        call - Call to be rewritten
        Returns:
        rewritten call
      • unparseListClause

        protected void unparseListClause​(SqlWriter writer,
                                         SqlNode clause)
      • equals

        public boolean equals​(java.lang.Object obj)
        Overrides:
        equals in class java.lang.Object
      • isName

        public boolean isName​(java.lang.String testName)
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class java.lang.Object
      • validateOperands

        public final RelDataType validateOperands​(SqlValidator validator,
                                                  SqlValidatorScope scope,
                                                  SqlCall call)
        Validates the operands of a call, inferring the return type in the process.
        Parameters:
        validator - active validator
        scope - validation scope
        call - call to be validated
        Returns:
        inferred type
      • preValidateCall

        protected void preValidateCall​(SqlValidator validator,
                                       SqlValidatorScope scope,
                                       SqlCall call)
        Receives notification that validation of a call to this operator is beginning. Subclasses can supply custom behavior; default implementation does nothing.
        Parameters:
        validator - invoking validator
        scope - validation scope
        call - the call being validated
      • inferReturnType

        public RelDataType inferReturnType​(SqlOperatorBinding opBinding)
        Infers the return type of an invocation of this operator; only called after the number and types of operands have already been validated. Subclasses must either override this method or supply an instance of SqlReturnTypeInference to the constructor.
        Parameters:
        opBinding - description of invocation (not necessarily a SqlCall)
        Returns:
        inferred return type
      • constructArgNameList

        protected java.util.List<java.lang.String> constructArgNameList​(SqlCall call)
      • constructOperandList

        protected java.util.List<SqlNode> constructOperandList​(SqlValidator validator,
                                                               SqlCall call,
                                                               java.util.List<java.lang.String> argNames)
      • needsSpace

        boolean needsSpace()
        Returns whether this operator should be surrounded by space when unparsed.
        Returns:
        whether this operator should be surrounded by space
      • adjustType

        protected RelDataType adjustType​(SqlValidator validator,
                                         SqlCall call,
                                         RelDataType type)
        Validates and determines coercibility and resulting collation name of binary operator if needed.
      • checkOperandTypes

        public boolean checkOperandTypes​(SqlCallBinding callBinding,
                                         boolean throwOnFailure)
        Checks that the operand values in a SqlCall to this operator are valid. Subclasses must either override this method or supply an instance of SqlOperandTypeChecker to the constructor.
        Parameters:
        callBinding - description of call
        throwOnFailure - whether to throw an exception if check fails (otherwise returns false in that case)
        Returns:
        whether check succeeded
      • getSignatureTemplate

        public java.lang.String getSignatureTemplate​(int operandsCount)
        Returns a template describing how the operator signature is to be built. E.g for the binary + operator the template looks like "{1} {0} {2}" {0} is the operator, subsequent numbers are operands.
        Parameters:
        operandsCount - is used with functions that can take a variable number of operands
        Returns:
        signature template, or null to indicate that a default template will suffice
      • getAllowedSignatures

        public final java.lang.String getAllowedSignatures()
        Returns a string describing the expected operand types of a call, e.g. "SUBSTR(VARCHAR, INTEGER, INTEGER)".
      • getAllowedSignatures

        public java.lang.String getAllowedSignatures​(java.lang.String opNameToUse)
        Returns a string describing the expected operand types of a call, e.g. "SUBSTRING(VARCHAR, INTEGER, INTEGER)" where the name (SUBSTRING in this example) can be replaced by a specified name.
      • isAggregator

        public boolean isAggregator()
        Returns whether this operator is an aggregate function. By default, subclass type is used (an instance of SqlAggFunction is assumed to be an aggregator; anything else is not).

        Per SQL:2011, there are aggregate functions and window functions. Every aggregate function (e.g. SUM) is also a window function. There are window functions that are not aggregate functions, e.g. RANK, NTILE, LEAD, FIRST_VALUE.

        Collectively, aggregate and window functions are called analytic functions. Despite its name, this method returns true for every analytic function.

        Returns:
        whether this operator is an analytic function (aggregate function or window function)
        See Also:
        requiresOrder()
      • requiresOver

        public boolean requiresOver()
        Returns whether this is a window function that requires an OVER clause.

        For example, returns true for RANK, DENSE_RANK and other ranking functions; returns false for SUM, COUNT, MIN, MAX, AVG (they can be used as non-window aggregate functions).

        If requiresOver returns true, then isAggregator() must also return true.

        See Also:
        allowsFraming(), requiresOrder()
      • requiresOrder

        public boolean requiresOrder()
        Returns whether this is a window function that requires ordering.

        Per SQL:2011, 2, 6.10: "If <ntile function>, <lead or lag function>, RANK or DENSE_RANK is specified, then the window ordering clause shall be present."

        See Also:
        isAggregator()
      • allowsFraming

        public boolean allowsFraming()
        Returns whether this is a window function that allows framing (i.e. a ROWS or RANGE clause in the window specification).
      • isGroup

        public boolean isGroup()
        Returns whether this is a group function.

        Group functions can only appear in the GROUP BY clause.

        Examples are HOP, TUMBLE, SESSION.

        Group functions have auxiliary functions, e.g. HOP_START, but these are not group functions.

      • isGroupAuxiliary

        public boolean isGroupAuxiliary()
        Returns whether this is an group auxiliary function.

        Examples are HOP_START and HOP_END (both auxiliary to HOP).

        See Also:
        isGroup()
      • acceptCall

        public <R> R acceptCall​(SqlVisitor<R> visitor,
                                SqlCall call)
        Accepts a SqlVisitor, visiting each operand of a call. Returns null.
        Parameters:
        visitor - Visitor
        call - Call to visit
      • acceptCall

        public <R> void acceptCall​(SqlVisitor<R> visitor,
                                   SqlCall call,
                                   boolean onlyExpressions,
                                   SqlBasicVisitor.ArgHandler<R> argHandler)
        Accepts a SqlVisitor, directing an SqlBasicVisitor.ArgHandler to visit an operand of a call.

        The argument handler allows fine control about how the operands are visited, and how the results are combined.

        Parameters:
        visitor - Visitor
        call - Call to visit
        onlyExpressions - If true, ignores operands which are not expressions. For example, in the call to the AS operator
        argHandler - Called for each operand
      • getReturnTypeInference

        public SqlReturnTypeInference getReturnTypeInference()
        Returns:
        the return type inference strategy for this operator, or null if return type inference is implemented by a subclass override
      • getMonotonicity

        public SqlMonotonicity getMonotonicity​(SqlOperatorBinding call)
        Returns whether a call to this operator is monotonic.

        Default implementation returns SqlMonotonicity.NOT_MONOTONIC.

        Parameters:
        call - Call to this operator with particular arguments and information about the monotonicity of the arguments
      • isDeterministic

        public boolean isDeterministic()
        Returns:
        true iff a call to this operator is guaranteed to always return the same result given the same operands; true is assumed by default
      • isDynamicFunction

        public boolean isDynamicFunction()
        Returns:
        true iff it is unsafe to cache query plans referencing this operator; false is assumed by default
      • requiresDecimalExpansion

        public boolean requiresDecimalExpansion()
        Method to check if call requires expansion when it has decimal operands. The default implementation is to return true.
      • argumentMustBeScalar

        public boolean argumentMustBeScalar​(int ordinal)
        Returns whether the ordinalth argument to this operator must be scalar (as opposed to a query).

        If true (the default), the validator will attempt to convert the argument into a scalar sub-query, which must have one column and return at most one row.

        Operators such as SELECT and EXISTS override this method.