org.eigenbase.sql
Class SqlOperator

java.lang.Object
  extended by org.eigenbase.sql.SqlOperator
Direct Known Subclasses:
SqlBinaryOperator, SqlCaseOperator, SqlFunction, SqlJoinOperator, SqlPostfixOperator, SqlPrefixOperator, SqlSelectOperator, SqlSpecialOperator, SqlWindowOperator

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 Summary
private  SqlKind kind
          See SqlKind.
private  int leftPrec
          The precedence with which this operator binds to the expression to the left.
protected static int MaxPrec
          Maximum precedence.
private  String name
          The name of the operator/function.
static String NL
           
private  SqlOperandTypeChecker operandTypeChecker
          used to validate operand types
private  SqlOperandTypeInference operandTypeInference
          used to infer types of unknown operands
private  SqlReturnTypeInference returnTypeInference
          used to infer the return type of a call to this operator
private  int rightPrec
          The precedence with which this operator binds to the expression to the right.
 
Constructor Summary
protected SqlOperator(String name, SqlKind kind, int prec, boolean leftAssoc, SqlReturnTypeInference returnTypeInference, SqlOperandTypeInference operandTypeInference, SqlOperandTypeChecker operandTypeChecker)
          Creates an operator specifying left/right associativity.
protected SqlOperator(String name, SqlKind kind, int leftPrecedence, int rightPrecedence, SqlReturnTypeInference returnTypeInference, SqlOperandTypeInference operandTypeInference, SqlOperandTypeChecker operandTypeChecker)
          Creates an operator.
 
Method Summary
<R> R
acceptCall(SqlVisitor<R> visitor, SqlCall call)
          Accepts a SqlVisitor, visiting each operand of a call.
<R> void
acceptCall(SqlVisitor<R> visitor, SqlCall call, boolean onlyExpressions, SqlBasicVisitor.ArgHandler<R> argHandler)
          Accepts a SqlVisitor, directing an SqlBasicVisitor.ArgHandler to visit operand of a call.
protected  RelDataType adjustType(SqlValidator validator, SqlCall call, RelDataType type)
          Validates and determines coercibility and resulting collation name of binary operator if needed.
 boolean argumentMustBeScalar(int ordinal)
          Returns whether the ordinalth argument to this operator must be scalar (as opposed to a query).
protected  void checkOperandCount(SqlValidator validator, SqlOperandTypeChecker argType, SqlCall call)
           
 boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure)
          Checks that the operand values in a SqlCall to this operator are valid.
 SqlCall createCall(SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands)
          Creates a call to this operand with an array of operands.
 SqlCall createCall(SqlNodeList nodeList)
          Creates a call to this operand with a list of operands contained in a SqlNodeList.
 SqlCall createCall(SqlParserPos pos, List<? extends SqlNode> operandList)
          Creates a call to this operand with a list of operands.
 SqlCall createCall(SqlParserPos pos, SqlNode... operands)
          Creates a call to this operand with an array of operands.
 RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call)
          Derives the type of a call to this operator.
 boolean equals(Object obj)
           
 String getAllowedSignatures()
          Returns a string describing the expected operand types of a call, e.g.
 String getAllowedSignatures(String opNameToUse)
          Returns a string describing the expected operand types of a call, e.g.
 SqlKind getKind()
           
 int getLeftPrec()
           
 SqlMonotonicity getMonotonicity(SqlCall call, SqlValidatorScope scope)
          Returns whether this operator is monotonic.
 String getName()
           
 SqlOperandCountRange getOperandCountRange()
          Returns a constraint on the number of operands expected by this operator.
 SqlOperandTypeChecker getOperandTypeChecker()
           
 SqlOperandTypeInference getOperandTypeInference()
           
 SqlReturnTypeInference getReturnTypeInference()
           
 int getRightPrec()
           
 String getSignatureTemplate(int operandsCount)
          Returns a template describing how the operator signature is to be built.
abstract  SqlSyntax getSyntax()
          Returns the syntactic type of this operator.
 int hashCode()
           
 RelDataType inferReturnType(RelDataTypeFactory typeFactory, RelDataType[] operandTypes)
          Infers the type of a call to this operator with a given set of operand types.
 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.
 boolean isAggregator()
          Returns whether this operator is an aggregate function.
 boolean isDeterministic()
           
 boolean isDynamicFunction()
           
 boolean isName(String testName)
           
protected static int leftPrec(int prec, boolean leftAssoc)
           
protected  void preValidateCall(SqlValidator validator, SqlValidatorScope scope, SqlCall call)
          Receives notification that validation of a call to this operator is beginning.
 boolean requiresDecimalExpansion()
          Method to check if call requires expansion when it has decimal operands.
 SqlNode rewriteCall(SqlValidator validator, SqlCall call)
          Rewrites a call to this operator.
protected static int rightPrec(int prec, boolean leftAssoc)
           
 String toString()
           
 void unparse(SqlWriter writer, SqlNode[] operands, 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.
protected  void unparseListClause(SqlWriter writer, SqlNode clause)
           
protected  void unparseListClause(SqlWriter writer, SqlNode clause, SqlKind sepKind)
           
 void validateCall(SqlCall call, SqlValidator validator, SqlValidatorScope scope, SqlValidatorScope operandScope)
          Validates a call to this operator.
 RelDataType validateOperands(SqlValidator validator, SqlValidatorScope scope, SqlCall call)
          Validates the operands of a call, inferring the return type in the process.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

NL

public static final String NL

MaxPrec

protected static final int MaxPrec
Maximum precedence.

See Also:
Constant Field Values

name

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


kind

private 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

Constructor Detail

SqlOperator

protected SqlOperator(String name,
                      SqlKind kind,
                      int leftPrecedence,
                      int rightPrecedence,
                      SqlReturnTypeInference returnTypeInference,
                      SqlOperandTypeInference operandTypeInference,
                      SqlOperandTypeChecker operandTypeChecker)
Creates an operator.

"Precondition:"
kind != null

SqlOperator

protected SqlOperator(String name,
                      SqlKind kind,
                      int prec,
                      boolean leftAssoc,
                      SqlReturnTypeInference returnTypeInference,
                      SqlOperandTypeInference operandTypeInference,
                      SqlOperandTypeChecker operandTypeChecker)
Creates an operator specifying left/right associativity.

Method Detail

leftPrec

protected static int leftPrec(int prec,
                              boolean leftAssoc)

rightPrec

protected static int rightPrec(int prec,
                               boolean leftAssoc)

getOperandTypeChecker

public 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()

getKind

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.

"Postcondition:"
return != 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,
                                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 -
call - to be rewritten
Returns:
rewritten call

unparse

public void unparse(SqlWriter writer,
                    SqlNode[] operands,
                    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.eigenbase.sql.SqlWriter, org.eigenbase.sql.SqlOperator, org.eigenbase.sql.SqlNode[], int, int).


unparseListClause

protected void unparseListClause(SqlWriter writer,
                                 SqlNode clause)

unparseListClause

protected void unparseListClause(SqlWriter writer,
                                 SqlNode clause,
                                 SqlKind sepKind)

equals

public boolean equals(Object obj)
Overrides:
equals in class Object

isName

public boolean isName(String testName)

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.eigenbase.sql.validate.SqlValidator, org.eigenbase.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:
SqlNode.validateExpr(SqlValidator, SqlValidatorScope), deriveType(SqlValidator, SqlValidatorScope, SqlCall)

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.eigenbase.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

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,
                                         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,
                                 SqlOperandTypeChecker argType,
                                 SqlCall call)

getSignatureTemplate

public 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 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 specifed name.


getOperandTypeInference

public SqlOperandTypeInference getOperandTypeInference()

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).

Returns:
whether this operator is an aggregator

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 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(SqlCall call,
                                       SqlValidatorScope scope)
Returns whether this operator is monotonic.

Default implementation returns SqlMonotonicity.NotMonotonic.

Parameters:
call - Call to this operator
scope - Scope in which the call occurs

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 subquery, which must have one column and return at most one row.

Operators such as SELECT and EXISTS override this method.