Interface SqlValidator

All Known Subinterfaces:
SqlValidatorWithHints
All Known Implementing Classes:
CalciteSqlValidator, ContextSqlValidator, SqlAdvisorValidator, SqlValidatorImpl

@Enclosing public interface SqlValidator
Validates the parse tree of a SQL statement, and provides semantic information about the parse tree.

To create an instance of the default validator implementation, call SqlValidatorUtil.newValidator(org.apache.calcite.sql.SqlOperatorTable, org.apache.calcite.sql.validate.SqlValidatorCatalogReader, org.apache.calcite.rel.type.RelDataTypeFactory, org.apache.calcite.sql.validate.SqlValidator.Config).

Visitor pattern

The validator interface is an instance of the visitor pattern. Implementations of the SqlNode.validate(org.apache.calcite.sql.validate.SqlValidator, org.apache.calcite.sql.validate.SqlValidatorScope) method call the validateXxx method appropriate to the kind of node:

The SqlNode.validateExpr(SqlValidator, SqlValidatorScope) method is as SqlNode.validate(SqlValidator, SqlValidatorScope) but is called when the node is known to be a scalar expression.

Scopes and namespaces

In order to resolve names to objects, the validator builds a map of the structure of the query. This map consists of two types of objects. A SqlValidatorScope describes the tables and columns accessible at a particular point in the query; and a SqlValidatorNamespace is a description of a data source used in a query.

There are different kinds of namespace for different parts of the query. for example IdentifierNamespace for table names, SelectNamespace for SELECT queries, SetopNamespace for UNION, EXCEPT and INTERSECT. A validator is allowed to wrap namespaces in other objects which implement SqlValidatorNamespace, so don't try to cast your namespace or use instanceof; use SqlValidatorNamespace.unwrap(Class) and SqlValidatorNamespace.isWrapperFor(Class) instead.

The validator builds the map by making a quick scan over the query when the root SqlNode is first provided. Thereafter, it supplies the correct scope or namespace object when it calls validation methods.

The methods getSelectScope(org.apache.calcite.sql.SqlSelect), getFromScope(org.apache.calcite.sql.SqlSelect), getWhereScope(org.apache.calcite.sql.SqlSelect), getGroupScope(org.apache.calcite.sql.SqlSelect), getHavingScope(org.apache.calcite.sql.SqlSelect), getOrderScope(org.apache.calcite.sql.SqlSelect) and getJoinScope(org.apache.calcite.sql.SqlNode) get the correct scope to resolve names in a particular clause of a SQL statement.

  • Method Details

    • getCatalogReader

      @Pure SqlValidatorCatalogReader getCatalogReader()
      Returns the catalog reader used by this validator.
      Returns:
      catalog reader
    • getOperatorTable

      @Pure SqlOperatorTable getOperatorTable()
      Returns the operator table used by this validator.
      Returns:
      operator table
    • validate

      SqlNode validate(SqlNode topNode)
      Validates an expression tree. You can call this method multiple times, but not reentrantly.
      Parameters:
      topNode - top of expression tree to be validated
      Returns:
      validated tree (possibly rewritten)
    • validateParameterizedExpression

      SqlNode validateParameterizedExpression(SqlNode topNode, Map<String,RelDataType> nameToTypeMap)
      Validates an expression tree. You can call this method multiple times, but not reentrantly.
      Parameters:
      topNode - top of expression tree to be validated
      nameToTypeMap - map of simple name to RelDataType; used to resolve SqlIdentifier references
      Returns:
      validated tree (possibly rewritten)
    • validateQuery

      void validateQuery(SqlNode node, SqlValidatorScope scope, RelDataType targetRowType)
      Checks that a query is valid.

      Valid queries include:

      • SELECT statement,
      • set operation (UNION, INTERSECT, EXCEPT)
      • identifier (e.g. representing use of a table in a FROM clause)
      • query aliased with the AS operator
      Parameters:
      node - Query node
      scope - Scope in which the query occurs
      targetRowType - Desired row type, must not be null, may be the data type 'unknown'.
      Throws:
      RuntimeException - if the query is not valid
    • getValidatedNodeType

      RelDataType getValidatedNodeType(SqlNode node)
      Returns the type assigned to a node by validation.
      Parameters:
      node - the node of interest
      Returns:
      validated type, never null
    • getValidatedNodeTypeIfKnown

      @Nullable RelDataType getValidatedNodeTypeIfKnown(SqlNode node)
      Returns the type assigned to a node by validation, or null if unknown. This allows for queries against nodes such as aliases, which have no type of their own. If you want to assert that the node of interest must have a type, use getValidatedNodeType(org.apache.calcite.sql.SqlNode) instead.
      Parameters:
      node - the node of interest
      Returns:
      validated type, or null if unknown or not applicable
    • getValidatedOperandTypes

      @Nullable List<RelDataType> getValidatedOperandTypes(SqlCall call)
      Returns the types of a call's operands.

      Returns null if the call has not been validated, or if the operands' types do not differ from their types as expressions.

      This method is most useful when some of the operands are of type ANY, or if they need to be coerced to be consistent with other operands, or with the needs of the function.

      Parameters:
      call - Call
      Returns:
      List of operands' types, or null if not known or 'obvious'
    • validateIdentifier

      void validateIdentifier(SqlIdentifier id, SqlValidatorScope scope)
      Resolves an identifier to a fully-qualified name.
      Parameters:
      id - Identifier
      scope - Naming scope
    • validateLiteral

      void validateLiteral(SqlLiteral literal)
      Validates a literal.
      Parameters:
      literal - Literal
    • validateIntervalQualifier

      void validateIntervalQualifier(SqlIntervalQualifier qualifier)
      Parameters:
      qualifier - Interval qualifier
    • validateInsert

      void validateInsert(SqlInsert insert)
      Validates an INSERT statement.
      Parameters:
      insert - INSERT statement
    • validateUpdate

      void validateUpdate(SqlUpdate update)
      Validates an UPDATE statement.
      Parameters:
      update - UPDATE statement
    • validateDelete

      void validateDelete(SqlDelete delete)
      Validates a DELETE statement.
      Parameters:
      delete - DELETE statement
    • validateMerge

      void validateMerge(SqlMerge merge)
      Validates a MERGE statement.
      Parameters:
      merge - MERGE statement
    • validateDataType

      void validateDataType(SqlDataTypeSpec dataType)
      Validates a data type expression.
      Parameters:
      dataType - Data type
    • validateDynamicParam

      void validateDynamicParam(SqlDynamicParam dynamicParam)
      Validates a dynamic parameter.
      Parameters:
      dynamicParam - Dynamic parameter
    • validateWindow

      void validateWindow(SqlNode windowOrId, SqlValidatorScope scope, @Nullable SqlCall call)
      Validates the right-hand side of an OVER expression. It might be either an identifier referencing a window, or an inline window specification.
      Parameters:
      windowOrId - SqlNode that can be either SqlWindow with all the components of a window spec or a SqlIdentifier with the name of a window spec.
      scope - Naming scope
      call - the SqlNode if a function call if the window is attached to one.
    • validateMatchRecognize

      void validateMatchRecognize(SqlCall pattern)
      Validates a MATCH_RECOGNIZE clause.
      Parameters:
      pattern - MATCH_RECOGNIZE clause
    • validateLambda

      void validateLambda(SqlLambda lambdaExpr)
      Validates a lambda expression. lambda expression will be validated twice during the validation process. The first time is validate lambda expression namespace, the second time is when validating higher order function operands type check.
      Parameters:
      lambdaExpr - Lambda expression
    • validateCall

      void validateCall(SqlCall call, SqlValidatorScope scope)
      Validates a call to an operator.
      Parameters:
      call - Operator call
      scope - Naming scope
    • validateAggregateParams

      void validateAggregateParams(SqlCall aggCall, @Nullable SqlNode filter, @Nullable SqlNodeList distinctList, @Nullable SqlNodeList orderList, SqlValidatorScope scope)
      Validates parameters for aggregate function.
      Parameters:
      aggCall - Call to aggregate function
      filter - Filter (FILTER (WHERE) clause), or null
      distinctList - Distinct specification (WITHIN DISTINCT clause), or null
      orderList - Ordering specification (WITHIN GROUP clause), or null
      scope - Syntactic scope
    • makeNullaryCall

      @Nullable SqlCall makeNullaryCall(SqlIdentifier id)
      If an identifier is a legitimate call to a function that has no arguments and requires no parentheses (for example "CURRENT_USER"), returns a call to that function, otherwise returns null.
    • deriveType

      RelDataType deriveType(SqlValidatorScope scope, SqlNode operand)
      Derives the type of a node in a given scope. If the type has already been inferred, returns the previous type.
      Parameters:
      scope - Syntactic scope
      operand - Parse tree node
      Returns:
      Type of the SqlNode. Should never return NULL
    • newValidationError

      CalciteContextException newValidationError(SqlNode node, org.apache.calcite.runtime.Resources.ExInst<SqlValidatorException> e)
      Adds "line x, column y" context to a validator exception.

      Note that the input exception is checked (it derives from Exception) and the output exception is unchecked (it derives from RuntimeException). This is intentional -- it should remind code authors to provide context for their validation errors.

      Parameters:
      node - The place where the exception occurred, not null
      e - The validation error
      Returns:
      Exception containing positional information, never null
    • isAggregate

      boolean isAggregate(SqlSelect select)
      Returns whether a SELECT statement is an aggregation. Criteria are: (1) contains GROUP BY, or (2) contains HAVING, or (3) SELECT or ORDER BY clause contains aggregate functions. (Windowed aggregate functions, such as SUM(x) OVER w, don't count.)
      Parameters:
      select - SELECT statement
      Returns:
      whether SELECT statement is an aggregation
    • isAggregate

      @Deprecated boolean isAggregate(SqlNode selectNode)
      Deprecated.
      Returns whether a select list expression is an aggregate function.
      Parameters:
      selectNode - Expression in SELECT clause
      Returns:
      whether expression is an aggregate function
    • resolveWindow

      SqlWindow resolveWindow(SqlNode windowOrRef, SqlValidatorScope scope)
      Converts a window specification or window name into a fully-resolved window specification. For example, in SELECT sum(x) OVER (PARTITION BY x ORDER BY y), sum(y) OVER w1, sum(z) OVER (w ORDER BY y) FROM t WINDOW w AS (PARTITION BY x) all aggregations have the same resolved window specification (PARTITION BY x ORDER BY y).
      Parameters:
      windowOrRef - Either the name of a window (a SqlIdentifier) or a window specification (a SqlWindow).
      scope - Scope in which to resolve window names
      Returns:
      A window
      Throws:
      RuntimeException - Validation exception if window does not exist
    • resolveWindow

      @Deprecated default SqlWindow resolveWindow(SqlNode windowOrRef, SqlValidatorScope scope, boolean populateBounds)
      Deprecated.
      Use resolveWindow(SqlNode, SqlValidatorScope), which does not have the deprecated populateBounds parameter.
      Converts a window specification or window name into a fully-resolved window specification.
      Parameters:
      populateBounds - Whether to populate bounds. Doing so may alter the definition of the window. It is recommended that populate bounds when translating to physical algebra, but not when validating.
    • getNamespace

      @Nullable SqlValidatorNamespace getNamespace(SqlNode node)
      Finds the namespace corresponding to a given node.

      For example, in the query SELECT * FROM (SELECT * FROM t), t1 AS alias, the both items in the FROM clause have a corresponding namespace.

      Parameters:
      node - Parse tree node
      Returns:
      namespace of node
    • deriveAlias

      @Nullable String deriveAlias(SqlNode node, int ordinal)
      Derives an alias for an expression. If no alias can be derived, returns null if ordinal is less than zero, otherwise generates an alias EXPR$ordinal.
      Parameters:
      node - Expression
      ordinal - Ordinal of expression
      Returns:
      derived alias, or null if no alias can be derived and ordinal is less than zero
    • expandStar

      SqlNodeList expandStar(SqlNodeList selectList, SqlSelect query, boolean includeSystemVars)
      Returns a list of expressions, with every occurrence of "*" or "TABLE.*" expanded.
      Parameters:
      selectList - Select clause to be expanded
      query - Query
      includeSystemVars - Whether to include system variables
      Returns:
      expanded select clause
    • getWhereScope

      SqlValidatorScope getWhereScope(SqlSelect select)
      Returns the scope that expressions in the WHERE and GROUP BY clause of this query should use. This scope consists of the tables in the FROM clause, and the enclosing scope.
      Parameters:
      select - Query
      Returns:
      naming scope of WHERE clause
    • getTypeFactory

      @Pure RelDataTypeFactory getTypeFactory()
      Returns the type factory used by this validator.
      Returns:
      type factory
    • setValidatedNodeType

      @API(status=INTERNAL, since="1.24") void setValidatedNodeType(SqlNode node, RelDataType type)
      Saves the type of a SqlNode, now that it has been validated.

      This method is only for internal use. The validator should drive the type-derivation process, and store nodes' types when they have been derived.

      Parameters:
      node - A SQL parse tree node, never null
      type - Its type; must not be null
    • removeValidatedNodeType

      void removeValidatedNodeType(SqlNode node)
      Removes a node from the set of validated nodes.
      Parameters:
      node - node to be removed
    • getUnknownType

      RelDataType getUnknownType()
      Returns an object representing the "unknown" type.
      Returns:
      unknown type
    • getSelectScope

      SqlValidatorScope getSelectScope(SqlSelect select)
      Returns the appropriate scope for validating a particular clause of a SELECT statement.

      Consider

      SELECT *
       FROM foo
       WHERE EXISTS (
          SELECT deptno AS x
          FROM emp
             JOIN dept ON emp.deptno = dept.deptno
          WHERE emp.deptno = 5
          GROUP BY deptno
          ORDER BY x)

      What objects can be seen in each part of the sub-query?

      Parameters:
      select - SELECT statement
      Returns:
      naming scope for SELECT statement
    • getRawSelectScope

      @Nullable SelectScope getRawSelectScope(SqlSelect select)
      Returns the scope for resolving the SELECT, GROUP BY and HAVING clauses. Always a SelectScope; if this is an aggregation query, the AggregatingScope is stripped away.
      Parameters:
      select - SELECT statement
      Returns:
      naming scope for SELECT statement, sans any aggregating scope
    • getFromScope

      SqlValidatorScope getFromScope(SqlSelect select)
      Returns a scope containing the objects visible from the FROM clause of a query.
      Parameters:
      select - SELECT statement
      Returns:
      naming scope for FROM clause
    • getJoinScope

      SqlValidatorScope getJoinScope(SqlNode node)
      Returns a scope containing the objects visible from the ON and USING sections of a JOIN clause.
      Parameters:
      node - The item in the FROM clause which contains the ON or USING expression
      Returns:
      naming scope for JOIN clause
      See Also:
    • getGroupScope

      SqlValidatorScope getGroupScope(SqlSelect select)
      Returns a scope containing the objects visible from the GROUP BY clause of a query.
      Parameters:
      select - SELECT statement
      Returns:
      naming scope for GROUP BY clause
    • getHavingScope

      SqlValidatorScope getHavingScope(SqlSelect select)
      Returns a scope containing the objects visible from the HAVING clause of a query.
      Parameters:
      select - SELECT statement
      Returns:
      naming scope for HAVING clause
    • getOrderScope

      SqlValidatorScope getOrderScope(SqlSelect select)
      Returns the scope that expressions in the SELECT and HAVING clause of this query should use. This scope consists of the FROM clause and the enclosing scope. If the query is aggregating, only columns in the GROUP BY clause may be used.
      Parameters:
      select - SELECT statement
      Returns:
      naming scope for ORDER BY clause
    • getMatchRecognizeScope

      SqlValidatorScope getMatchRecognizeScope(SqlMatchRecognize node)
      Returns a scope match recognize clause.
      Parameters:
      node - Match recognize
      Returns:
      naming scope for Match recognize clause
    • getLambdaScope

      SqlValidatorScope getLambdaScope(SqlLambda node)
      Returns the lambda expression scope.
      Parameters:
      node - Lambda expression
      Returns:
      naming scope for lambda expression
    • getEmptyScope

      SqlValidatorScope getEmptyScope()
      Returns a scope that cannot see anything.
    • declareCursor

      void declareCursor(SqlSelect select, SqlValidatorScope scope)
      Declares a SELECT expression as a cursor.
      Parameters:
      select - select expression associated with the cursor
      scope - scope of the parent query associated with the cursor
    • pushFunctionCall

      void pushFunctionCall()
      Pushes a new instance of a function call on to a function call stack.
    • popFunctionCall

      void popFunctionCall()
      Removes the topmost entry from the function call stack.
    • getParentCursor

      @Nullable String getParentCursor(String columnListParamName)
      Retrieves the name of the parent cursor referenced by a column list parameter.
      Parameters:
      columnListParamName - name of the column list parameter
      Returns:
      name of the parent cursor
    • deriveConstructorType

      RelDataType deriveConstructorType(SqlValidatorScope scope, SqlCall call, SqlFunction unresolvedConstructor, @Nullable SqlFunction resolvedConstructor, List<RelDataType> argTypes)
      Derives the type of a constructor.
      Parameters:
      scope - Scope
      call - Call
      unresolvedConstructor - TODO
      resolvedConstructor - TODO
      argTypes - Types of arguments
      Returns:
      Resolved type of constructor
    • handleUnresolvedFunction

      CalciteException handleUnresolvedFunction(SqlCall call, SqlOperator unresolvedFunction, List<RelDataType> argTypes, @Nullable List<String> argNames)
      Handles a call to a function which cannot be resolved. Returns an appropriately descriptive error, which caller must throw.
      Parameters:
      call - Call
      unresolvedFunction - Overloaded function which is the target of the call
      argTypes - Types of arguments
      argNames - Names of arguments, or null if call by position
    • expandOrderExpr

      SqlNode expandOrderExpr(SqlSelect select, SqlNode orderExpr)
      Expands an expression in the ORDER BY clause into an expression with the same semantics as expressions in the SELECT clause.

      This is made necessary by a couple of dialect 'features':

      • ordinal expressions: In "SELECT x, y FROM t ORDER BY 2", the expression "2" is shorthand for the 2nd item in the select clause, namely "y".
      • alias references: In "SELECT x AS a, y FROM t ORDER BY a", the expression "a" is shorthand for the item in the select clause whose alias is "a"
      Parameters:
      select - Select statement which contains ORDER BY
      orderExpr - Expression in the ORDER BY clause.
      Returns:
      Expression translated into SELECT clause semantics
    • expand

      SqlNode expand(SqlNode expr, SqlValidatorScope scope)
      Expands an expression.
      Parameters:
      expr - Expression
      scope - Scope
      Returns:
      Expanded expression
    • resolveLiteral

      SqlLiteral resolveLiteral(SqlLiteral literal)
      Resolves a literal.

      Usually returns the literal unchanged, but if the literal is of type SqlTypeName.UNKNOWN looks up its type and converts to the appropriate literal subclass.

    • isSystemField

      boolean isSystemField(RelDataTypeField field)
      Returns whether a field is a system field. Such fields may have particular properties such as sortedness and nullability.

      In the default implementation, always returns false.

      Parameters:
      field - Field
      Returns:
      whether field is a system field
    • getFieldOrigins

      List<@Nullable List<String>> getFieldOrigins(SqlNode sqlQuery)
      Returns a description of how each field in the row type maps to a catalog, schema, table and column in the schema.

      The returned list is never null, and has one element for each field in the row type. Each element is a list of four elements (catalog, schema, table, column), or may be null if the column is an expression.

      Parameters:
      sqlQuery - Query
      Returns:
      Description of how each field in the row type maps to a schema object
    • getParameterRowType

      RelDataType getParameterRowType(SqlNode sqlQuery)
      Returns a record type that contains the name and type of each parameter. Returns a record type with no fields if there are no parameters.
      Parameters:
      sqlQuery - Query
      Returns:
      Record type
    • getOverScope

      SqlValidatorScope getOverScope(SqlNode node)
      Returns the scope of an OVER or VALUES node.
      Parameters:
      node - Node
      Returns:
      Scope
    • validateModality

      boolean validateModality(SqlSelect select, SqlModality modality, boolean fail)
      Validates that a query is capable of producing a return of given modality (relational or streaming).
      Parameters:
      select - Query
      modality - Modality (streaming or relational)
      fail - Whether to throw a user error if does not support required modality
      Returns:
      whether query supports the given modality
    • validateWith

      void validateWith(SqlWith with, SqlValidatorScope scope)
    • validateWithItem

      void validateWithItem(SqlWithItem withItem)
    • validateSequenceValue

      void validateSequenceValue(SqlValidatorScope scope, SqlIdentifier id)
    • getWithScope

      SqlValidatorScope getWithScope(SqlNode withItem)
    • getTypeCoercion

      TypeCoercion getTypeCoercion()
      Get the type coercion instance.
    • getTypeMappingRule

      default SqlTypeMappingRule getTypeMappingRule()
      Returns the type mapping rule.
    • config

      Returns the config of the validator.
    • transform

      @API(status=INTERNAL, since="1.23") SqlValidator transform(UnaryOperator<SqlValidator.Config> transform)
      Returns this SqlValidator, with the same state, applying a transform to the config.

      This is mainly used for tests, otherwise constructs a SqlValidator.Config directly through the constructor.

    • getTimeFrameSet

      TimeFrameSet getTimeFrameSet()
      Returns the set of allowed time frames.
    • validateTimeFrame

      TimeFrame validateTimeFrame(SqlIntervalQualifier intervalQualifier)
      Validates a time frame.

      A time frame is either a built-in time frame based on a time unit such as TimeUnitRange.HOUR, or is a custom time frame represented by a name in SqlIntervalQualifier.timeFrameName. A custom time frame is validated against getTimeFrameSet().

      Returns a time frame, or throws.