Class SqlOperator

java.lang.Object
org.apache.calcite.sql.SqlOperator
Direct Known Subclasses:
SqlBinaryOperator, SqlCaseOperator, SqlDescriptorOperator, SqlFunction, SqlJoin.SqlJoinOperator, SqlMatchRecognize.SqlMatchRecognizeOperator, SqlPostfixOperator, SqlPrefixOperator, SqlSelectOperator, SqlSnapshot.SqlSnapshotOperator, SqlSpecialOperator

public abstract class SqlOperator extends 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 Details

    • NL

      public static final String NL
    • MDX_PRECEDENCE

      public static final int MDX_PRECEDENCE
      Maximum precedence.
      See Also:
    • kind

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

  • Method Details

    • leftPrec

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

      protected static int rightPrec(int prec, boolean leftAssoc)
    • getOperandTypeChecker

      public @Nullable SqlOperandTypeChecker getOperandTypeChecker()
    • 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 String getName()
    • getNameAsId

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

      @Pure public SqlKind getKind()
    • toString

      public String toString()
      Overrides:
      toString in class 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 final SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, Iterable<? extends @Nullable SqlNode> operands)
      Creates a call to this operator 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.

      Parameters:
      functionQualifier - Function qualifier (e.g. "DISTINCT"), or null
      pos - Parser position of the identifier of the call
      operands - List of operands
    • createCall

      public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, @Nullable SqlNode... operands)
      Creates a call to this operator 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"), or null
      pos - Parser position of the identifier of the call
      operands - Array of operands
    • createCall

      @Deprecated public static SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNodeList operands)
      Deprecated.
      Not supported. Choose between createCall(SqlLiteral, SqlParserPos, SqlNode...) and createCall(SqlParserPos, List). The ambiguity arises because SqlNodeList extends SqlNode and also implements List<SqlNode>.
    • createCall

      public final SqlCall createCall(SqlParserPos pos, @Nullable SqlNode... operands)
      Creates a call to this operator 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 operator with a list of operands contained in a SqlNodeList.

      The position of the resulting call is inferred from the SqlNodeList.

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

      public final SqlCall createCall(SqlParserPos pos, List<? extends @Nullable SqlNode> operandList)
      Creates a call to this operator 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.

    • createCall

      @Deprecated public SqlCall createCall(SqlParserPos pos, SqlNodeList operands)
      Deprecated.
      Not supported. Choose between createCall(SqlParserPos, SqlNode...) and createCall(SqlParserPos, List). The ambiguity arises because SqlNodeList extends SqlNode and also implements List<SqlNode>.
    • 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
    • unparse

      public void unparse(SqlWriter writer, SqlCall call, int leftPrec, int rightPrec)
      Writes a SQL representation of a call to this operator to a writer, including parentheses if the operators on either side are of greater precedence.

      The default implementation of this method delegates to SqlSyntax.unparse(org.apache.calcite.sql.SqlWriter, org.apache.calcite.sql.SqlOperator, org.apache.calcite.sql.SqlCall, int, int).

    • unparseListClause

      @Deprecated protected void unparseListClause(SqlWriter writer, SqlNode clause)
      Deprecated.
    • unparseListClause

      @Deprecated protected void unparseListClause(SqlWriter writer, SqlNode clause, @Nullable SqlKind sepKind)
      Deprecated.
    • equals

      public boolean equals(@Nullable Object obj)
      Overrides:
      equals in class Object
    • isName

      public boolean isName(String testName, boolean caseSensitive)
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • validateCall

      public void validateCall(SqlCall call, SqlValidator validator, SqlValidatorScope scope, SqlValidatorScope operandScope)
      Validates a call to this operator.

      This method should not perform type-derivation or perform validation related related to types. That is done later, by deriveType(SqlValidator, SqlValidatorScope, SqlCall). This method should focus on structural validation.

      A typical implementation of this method first validates the operands, then performs some operator-specific logic. The default implementation just validates the operands.

      This method is the default implementation of SqlCall.validate(org.apache.calcite.sql.validate.SqlValidator, org.apache.calcite.sql.validate.SqlValidatorScope); but note that some sub-classes of SqlCall never call this method.

      Parameters:
      call - the call to this operator
      validator - the active validator
      scope - validator scope
      operandScope - validator scope in which to validate operands to this call; usually equal to scope, but not always because some operators introduce new scopes
      See Also:
    • 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
    • deriveType

      public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call)
      Derives the type of a call to this operator.

      This method is an intrinsic part of the validation process so, unlike inferReturnType(org.apache.calcite.sql.SqlOperatorBinding), specific operators would not typically override this method.

      Parameters:
      validator - Validator
      scope - Scope of validation
      call - Call to this operator
      Returns:
      Type of call
    • constructArgNameList

      protected @Nullable List<String> constructArgNameList(SqlCall call)
    • constructOperandList

      protected List<SqlNode> constructOperandList(SqlValidator validator, SqlCall call, @Nullable List<String> argNames)
    • constructArgTypeList

      protected List<RelDataType> constructArgTypeList(SqlValidator validator, SqlValidatorScope scope, SqlCall call, List<SqlNode> args, boolean convertRowArgToColumnList)
    • deriveOperandType

      protected RelDataType deriveOperandType(SqlValidator validator, SqlValidatorScope scope, int i, SqlNode operand)
    • adjustType

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

      public final RelDataType inferReturnType(RelDataTypeFactory typeFactory, List<RelDataType> operandTypes)
      Infers the type of a call to this operator with a given set of operand types. Shorthand for inferReturnType(SqlOperatorBinding).
    • 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
    • checkOperandCount

      protected void checkOperandCount(SqlValidator validator, @Nullable SqlOperandTypeChecker argType, SqlCall call)
    • validRexOperands

      public boolean validRexOperands(int count, Litmus litmus)
      Returns whether the given operands are valid. If not valid and fail, throws an assertion error.

      Similar to checkOperandCount(org.apache.calcite.sql.validate.SqlValidator, org.apache.calcite.sql.type.SqlOperandTypeChecker, org.apache.calcite.sql.SqlCall), but some operators may have different valid operands in SqlNode and RexNode formats (some examples are CAST and AND), and this method throws internal errors, not user errors.

    • getSignatureTemplate

      public @Nullable 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 String getAllowedSignatures()
      Returns a string describing the expected operand types of a call, e.g. "SUBSTR(VARCHAR, INTEGER, INTEGER)".
    • getAllowedSignatures

      public String getAllowedSignatures(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.
    • getOperandTypeInference

      public @Nullable SqlOperandTypeInference getOperandTypeInference()
    • isAggregator

      @Pure 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:
    • 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:
    • 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:
    • 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:
    • acceptCall

      public <R> @Nullable 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 @Nullable SqlReturnTypeInference getReturnTypeInference()
      Returns the return type inference strategy for this operator, or null if return type inference is implemented by a subclass override.
    • not

      public @Nullable SqlOperator not()
      Returns the operator that is the logical inverse of this operator.

      For example, SqlStdOperatorTable.LIKE.not() returns SqlStdOperatorTable.NOT_LIKE, and vice versa.

      By default, returns null, which means there is no inverse operator.

      See Also:
    • reverse

      public @Nullable SqlOperator reverse()
      Returns the operator that has the same effect as this operator if its arguments are reversed.

      For example, SqlStdOperatorTable.GREATER_THAN.reverse() returns SqlStdOperatorTable.LESS_THAN, and vice versa, because a > b is equivalent to b < a.

      SqlStdOperatorTable.EQUALS.reverse() returns itself.

      By default, returns null, which means there is no inverse operator.

      See Also:
    • getStrongPolicyInference

      @Pure public @Nullable Supplier<Strong.Policy> getStrongPolicyInference()
      Returns the Strong.Policy strategy for this operator, or null if there is no particular strategy, in which case this policy will be deducted from the operator's SqlKind.
      See Also:
    • getMonotonicity

      @Deprecated public SqlMonotonicity getMonotonicity(SqlCall call, SqlValidatorScope scope)
      Returns whether this operator is monotonic.

      Default implementation returns SqlMonotonicity.NOT_MONOTONIC.

      Parameters:
      call - Call to this operator
      scope - Scope in which the call occurs
    • 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 whether a call to this operator is guaranteed to always return the same result given the same operands; true is assumed by default.
    • isSymmetrical

      public boolean isSymmetrical()
      Returns whether a call to this operator is not sensitive to the operands input order. An operator is symmetrical if the call returns the same result when the operands are shuffled.

      By default, returns true for SqlKind.SYMMETRICAL.

    • isDynamicFunction

      public boolean isDynamicFunction()
      Returns whether 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.