blob: 2e5420c8e4c768f8c5a1a487de4cc0e5358fd2dd [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.calcite.sql.type;
import org.apache.calcite.sql.SqlCallBinding;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlOperandCountRange;
/**
* SqlSingleOperandTypeChecker is an extension of {@link SqlOperandTypeChecker}
* for implementations which are capable of checking the type of a single
* operand in isolation. This isn't meaningful for all type-checking rules (e.g.
* SameOperandTypeChecker requires two operands to have matching types, so
* checking one in isolation is meaningless).
*/
public interface SqlSingleOperandTypeChecker extends SqlOperandTypeChecker {
//~ Methods ----------------------------------------------------------------
/**
* Checks the type of a single operand against a particular ordinal position
* within a formal operator signature. Note that the actual ordinal position
* of the operand being checked may be <em>different</em> from the position
* of the formal operand.
*
* <p>For example, when validating the actual call
*
* <blockquote>
* <pre>C(X, Y, Z)</pre>
* </blockquote>
*
* <p>the strategy for validating the operand Z might involve checking its
* type against the formal signature OP(W). In this case,
* <code>iFormalOperand</code> would be zero, even though the position of Z
* within call C is two.
*
* <p>Caution that we could not(shouldn't) implement implicit type coercion for this checker,
* implicit type coercion has side effect(modify the AST), if this single operand checker is
* subsumed in a composite rule(OR or AND), we can not make any side effect if we
* can not make sure that all the single operands type check are passed(with type coercion).
* But there is an exception: only if the call has just one operand, for this case,
* use {@link SqlOperandTypeChecker#checkOperandTypes} instead.
*
* @param callBinding description of the call being checked; this is only
* provided for context when throwing an exception; the
* implementation should <em>NOT</em> examine the
* operands of the call as part of the check
* @param operand the actual operand to be checked
* @param iFormalOperand the 0-based formal operand ordinal
* @param throwOnFailure whether to throw an exception if check fails
* (otherwise returns false in that case)
* @return whether check succeeded
*/
boolean checkSingleOperandType(
SqlCallBinding callBinding,
SqlNode operand,
int iFormalOperand,
boolean throwOnFailure);
@Override default boolean checkOperandTypes(SqlCallBinding callBinding,
boolean throwOnFailure) {
return checkSingleOperandType(callBinding, callBinding.operand(0), 0,
throwOnFailure);
}
@Override default SqlOperandCountRange getOperandCountRange() {
return SqlOperandCountRanges.of(1);
}
/** Composes this with another single-operand checker using AND. */
default SqlSingleOperandTypeChecker and(
SqlSingleOperandTypeChecker checker) {
return OperandTypes.and(this, checker);
}
/** Composes this with another single-operand checker using OR. */
default SqlSingleOperandTypeChecker or(
SqlSingleOperandTypeChecker checker) {
return OperandTypes.or(this, checker);
}
}