public class SqlCaseOperator extends SqlOperator
COALESCEexpression. All of these forms are normalized at parse time to a to a simple
CASEstatement like this:
CASE WHEN <when expression_0> THEN <then expression_0> WHEN <when expression_1> THEN <then expression_1> ... WHEN <when expression_N> THEN <then expression_N> ELSE <else expression> END
The switched form of the
CASE statement is normalized to the
simple form by inserting calls to the
= operator. For
CASE x + y WHEN 1 THEN 'fee' WHEN 2 THEN 'fie' ELSE 'foe' END
CASE WHEN Equals(x + y, 1) THEN 'fee' WHEN Equals(x + y, 2) THEN 'fie' ELSE 'foe' END
REVIEW jhyde 2004/3/19 Does
Equals handle NULL semantics
COALESCE(x, y, z) becomes
CASE WHEN x IS NOT NULL THEN x WHEN y IS NOT NULL THEN y ELSE z END
NULLIF(x, -1) becomes
CASE WHEN x = -1 THEN NULL ELSE x END
Note that some of these normalizations cause expressions to be duplicated. This may make it more difficult to write optimizer rules (because the rules will have to deduce that expressions are equivalent). It also requires that some part of the planning process (probably the generator of the calculator program) does common sub-expression elimination.
REVIEW jhyde 2004/3/19. Expanding expressions at parse time has some other
drawbacks. It is more difficult to give meaningful validation errors: given
COALESCE(DATE '2004-03-18', 3.5), do we issue a type-checking
error against a
CASE operator? Second, I'd like to use the
SqlNode object model to generate SQL to send to 3rd-party databases,
but there's now no way to represent a call to COALESCE or NULLIF. All in all,
it would be better to have operators for COALESCE, NULLIF, and both simple
and switched forms of CASE, then translate to simple CASE when building the
The arguments are physically represented as follows:
|Modifier and Type||Field||Description|
|Modifier and Type||Method||Description|
Checks that the operand values in a
Creates a call to this operand with an array of operands.
Derives the type of a call to this operator.
Returns a constraint on the number of operands expected by this operator.
Returns the syntactic type of this operator, never null.
Infers the return type of an invocation of this operator; only called after the number and types of operands have already been validated.
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.
Validates a call to this operator.
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
acceptCall, acceptCall, adjustType, allowsFraming, argumentMustBeScalar, checkOperandCount, constructArgNameList, constructArgTypeList, constructOperandList, createCall, createCall, createCall, equals, getAllowedSignatures, getAllowedSignatures, getKind, getLeftPrec, getMonotonicity, getMonotonicity, getName, getNameAsId, getOperandTypeChecker, getOperandTypeInference, getReturnTypeInference, getRightPrec, getSignatureTemplate, hashCode, inferReturnType, isAggregator, isDeterministic, isDynamicFunction, isGroup, isGroupAuxiliary, isName, leftPrec, preValidateCall, requiresDecimalExpansion, requiresOrder, requiresOver, rewriteCall, rightPrec, toString, unparseListClause, unparseListClause, validateOperands, validRexOperands
public static final SqlCaseOperator INSTANCE
public void validateCall(SqlCall call, SqlValidator validator, SqlValidatorScope scope, SqlValidatorScope operandScope)
This method should not perform type-derivation or perform validation
related related to types. That is done later, by
SqlOperator.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
but note that some sub-classes of
SqlCall never call this method.
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
SqlOperator.deriveType(SqlValidator, SqlValidatorScope, SqlCall)
public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call)
This method is an intrinsic part of the validation process so, unlike
SqlOperator.inferReturnType(org.apache.calcite.sql.SqlOperatorBinding), specific operators would not typically override
public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure)
SqlCallto this operator are valid. Subclasses must either override this method or supply an instance of
SqlOperandTypeCheckerto the constructor.
public RelDataType inferReturnType(SqlOperatorBinding opBinding)
SqlReturnTypeInferenceto the constructor.
public SqlOperandCountRange getOperandCountRange()
SqlOperandTypeCheckerassociated with this operator.
public SqlSyntax getSyntax()
public SqlCall createCall(SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands)
The position of the resulting call is the union of the
pos and the positions of all of the operands.
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).
Copyright © 2012–2017 The Apache Software Foundation. All rights reserved.