/*
* 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.eigenbase.sql;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Set;
/**
* Enumerates the possible types of {@link SqlNode}.
*
* <p>The values are immutable, canonical constants, so you can use Kinds to
* find particular types of expressions quickly. To identity a call to a common
* operator such as '=', use {@link org.eigenbase.sql.SqlNode#isA}:</p>
*
* <blockquote>
* <pre>exp.{@link org.eigenbase.sql.SqlNode#isA isA}({@link #EQUALS})</pre>
* </blockquote>
*
* <p>Only commonly-used nodes have their own type; other nodes are of type
* {@link #OTHER}. Some of the values, such as {@link #SET_QUERY}, represent
* aggregates.</p>
*
* <p>To quickly choose between a number of options, use a switch statement:</p>
*
* <blockquote>
* <pre>switch (exp.getKind()) {
* case {@link #EQUALS}:
* ...;
* case {@link #NOT_EQUALS}:
* ...;
* default:
* throw new AssertionError("unexpected");
* }</pre>
* </blockquote>
*
* <p>Note that we do not even have to check that a {@code SqlNode} is a
* {@link SqlCall}.</p>
*
* <p>To identify a category of expressions, use {@code SqlNode.isA} with
* an aggregate SqlKind. The following expression will return <code>true</code>
* for calls to '=' and '>=', but <code>false</code> for the constant '5', or
* a call to '+':</p>
*
* <blockquote>
* <pre>exp.isA({@link #COMPARISON SqlKind.COMPARISON})</pre>
* </blockquote>
*
* <p>RexNode also has a {@code getKind} method; {@code SqlKind} values are
* preserved during translation from {@code SqlNode} to {@code RexNode}, where
* applicable.</p>
*
* <p>There is no water-tight definition of "common", but that's OK. There will
* always be operators that don't have their own kind, and for these we use the
* {@code SqlOperator}. But for really the common ones, e.g. the many places
* where we are looking for {@code AND}, {@code OR} and {@code EQUALS}, the enum
* helps.</p>
*
* <p>(If we were using Scala, {@link SqlOperator} would be a case
* class, and we wouldn't need {@code SqlKind}. But we're not.)</p>
*/
public enum SqlKind {
//~ Static fields/initializers ---------------------------------------------
// the basics
/**
* Expression not covered by any other {@link SqlKind} value.
*
* @see #OTHER_FUNCTION
*/
OTHER,
/**
* SELECT statement or sub-query.
*/
SELECT,
/**
* JOIN operator or compound FROM clause.
*
* <p>A FROM clause with more than one table is represented as if it were a
* join. For example, "FROM x, y, z" is represented as "JOIN(x, JOIN(x,
* y))".</p>
*/
JOIN,
/**
* Identifier
*/
IDENTIFIER,
/**
* A literal.
*/
LITERAL,
/**
* Function that is not a special function.
*
* @see #FUNCTION
*/
OTHER_FUNCTION,
/**
* EXPLAIN statement
*/
EXPLAIN,
/**
* INSERT statement
*/
INSERT,
/**
* DELETE statement
*/
DELETE,
/**
* UPDATE statement
*/
UPDATE,
/**
* "ALTER scope SET option = value" statement.
*/
SET_OPTION,
/**
* A dynamic parameter.
*/
DYNAMIC_PARAM,
/**
* ORDER BY clause.
*
* @see #DESCENDING
* @see #NULLS_FIRST
* @see #NULLS_LAST
*/
ORDER_BY,
/** WITH clause. */
WITH,
/** Item in WITH clause. */
WITH_ITEM,
/**
* Union
*/
UNION,
/**
* Except
*/
EXCEPT,
/**
* Intersect
*/
INTERSECT,
/**
* AS operator
*/
AS,
/**
* OVER operator
*/
OVER,
/**
* Window specification
*/
WINDOW,
/**
* MERGE statement
*/
MERGE,
/**
* TABLESAMPLE operator
*/
TABLESAMPLE,
// binary operators
/**
* The arithmetic multiplication operator, "*".
*/
TIMES,
/**
* The arithmetic division operator, "/".
*/
DIVIDE,
/**
* The arithmetic plus operator, "+".
*
* @see #PLUS_PREFIX
*/
PLUS,
/**
* The arithmetic minus operator, "-".
*
* @see #MINUS_PREFIX
*/
MINUS,
// comparison operators
/**
* The "IN" operator.
*/
IN,
/**
* The less-than operator, "<".
*/
LESS_THAN,
/**
* The greater-than operator, ">".
*/
GREATER_THAN,
/**
* The less-than-or-equal operator, "<=".
*/
LESS_THAN_OR_EQUAL,
/**
* The greater-than-or-equal operator, ">=".
*/
GREATER_THAN_OR_EQUAL,
/**
* The equals operator, "=".
*/
EQUALS,
/**
* The not-equals operator, "!=" or "<>".
*/
NOT_EQUALS,
/**
* The is-distinct-from operator.
*/
IS_DISTINCT_FROM,
/**
* The is-not-distinct-from operator.
*/
IS_NOT_DISTINCT_FROM,
/**
* The logical "OR" operator.
*/
OR,
/**
* The logical "AND" operator.
*/
AND,
// other infix
/**
* Dot
*/
DOT,
/**
* The "OVERLAPS" operator.
*/
OVERLAPS,
/**
* The "LIKE" operator.
*/
LIKE,
/**
* The "SIMILAR" operator.
*/
SIMILAR,
/**
* The "BETWEEN" operator.
*/
BETWEEN,
/**
* A "CASE" expression.
*/
CASE,
// prefix operators
/**
* The logical "NOT" operator.
*/
NOT,
/**
* The unary plus operator, as in "+1".
*
* @see #PLUS
*/
PLUS_PREFIX,
/**
* The unary minus operator, as in "-1".
*
* @see #MINUS
*/
MINUS_PREFIX,
/**
* The "EXISTS" operator.
*/
EXISTS,
/**
* The "VALUES" operator.
*/
VALUES,
/**
* Explicit table, e.g. <code>select * from (TABLE t)</code> or <code>TABLE
* t</code>. See also {@link #COLLECTION_TABLE}.
*/
EXPLICIT_TABLE,
/**
* Scalar query; that is, a subquery used in an expression context, and
* returning one row and one column.
*/
SCALAR_QUERY,
/**
* ProcedureCall
*/
PROCEDURE_CALL,
/**
* NewSpecification
*/
NEW_SPECIFICATION,
// postfix operators
/**
* DESC in ORDER BY. A parse tree, not a true expression.
*/
DESCENDING,
/**
* NULLS FIRST clause in ORDER BY. A parse tree, not a true expression.
*/
NULLS_FIRST,
/**
* NULLS LAST clause in ORDER BY. A parse tree, not a true expression.
*/
NULLS_LAST,
/**
* The "IS TRUE" operator.
*/
IS_TRUE,
/**
* The "IS FALSE" operator.
*/
IS_FALSE,
/**
* The "IS NOT TRUE" operator.
*/
IS_NOT_TRUE,
/**
* The "IS NOT FALSE" operator.
*/
IS_NOT_FALSE,
/**
* The "IS UNKNOWN" operator.
*/
IS_UNKNOWN,
/**
* The "IS NULL" operator.
*/
IS_NULL,
/**
* The "IS NOT NULL" operator.
*/
IS_NOT_NULL,
/**
* The "PRECEDING" qualifier of an interval end-point in a window
* specification.
*/
PRECEDING,
/**
* The "FOLLOWING" qualifier of an interval end-point in a window
* specification.
*/
FOLLOWING,
/**
* The field access operator, ".".
*
* <p>(Only used at the RexNode level; at
* SqlNode level, a field-access is part of an identifier.)</p>
*/
FIELD_ACCESS,
/**
* Reference to an input field.
*
* <p>(Only used at the RexNode level.)</p>
*/
INPUT_REF,
/**
* Reference to a sub-expression computed within the current relational
* operator.
*
* <p>(Only used at the RexNode level.)</p>
*/
LOCAL_REF,
/**
* Reference to correlation variable.
*
* <p>(Only used at the RexNode level.)</p>
*/
CORREL_VARIABLE,
// functions
/**
* The row-constructor function. May be explicit or implicit:
* {@code VALUES 1, ROW (2)}.
*/
ROW,
/**
* The non-standard constructor used to pass a
* COLUMN_LIST parameter to a user-defined transform.
*/
COLUMN_LIST,
/**
* The "CAST" operator.
*/
CAST,
/**
* The "TRIM" function.
*/
TRIM,
/**
* Call to a function using JDBC function syntax.
*/
JDBC_FN,
/**
* The MULTISET value constructor.
*/
MULTISET_VALUE_CONSTRUCTOR,
/**
* The MULTISET query constructor.
*/
MULTISET_QUERY_CONSTRUCTOR,
/**
* The "UNNEST" operator.
*/
UNNEST,
/**
* The "LATERAL" qualifier to relations in the FROM clause.
*/
LATERAL,
/**
* Table operator which converts user-defined transform into a relation, for
* example, <code>select * from TABLE(udx(x, y, z))</code>. See also the
* {@link #EXPLICIT_TABLE} prefix operator.
*/
COLLECTION_TABLE,
/**
* Array Value Constructor, e.g. {@code Array[1, 2, 3]}.
*/
ARRAY_VALUE_CONSTRUCTOR,
/**
* Array Query Constructor, e.g. {@code Array(select deptno from dept)}.
*/
ARRAY_QUERY_CONSTRUCTOR,
/**
* Map Value Constructor, e.g. {@code Map['washington', 1, 'obama', 44]}.
*/
MAP_VALUE_CONSTRUCTOR,
/**
* Map Query Constructor, e.g. {@code MAP (SELECT empno, deptno FROM emp)}.
*/
MAP_QUERY_CONSTRUCTOR,
/**
* CURSOR constructor, for example, <code>select * from
* TABLE(udx(CURSOR(select ...), x, y, z))</code>
*/
CURSOR,
// internal operators (evaluated in validator) 200-299
/**
* Literal chain operator (for composite string literals).
* An internal operator that does not appear in SQL syntax.
*/
LITERAL_CHAIN,
/**
* Escape operator (always part of LIKE or SIMILAR TO expression).
* An internal operator that does not appear in SQL syntax.
*/
ESCAPE,
/**
* The internal REINTERPRET operator (meaning a reinterpret cast).
* An internal operator that does not appear in SQL syntax.
*/
REINTERPRET;
//~ Static fields/initializers ---------------------------------------------
// Most of the static fields are categories, aggregating several kinds into
// a set.
/**
* Category consisting of set-query node types.
*
* <p>Consists of:
* {@link #EXCEPT},
* {@link #INTERSECT},
* {@link #UNION}.
*/
public static final EnumSet<SqlKind> SET_QUERY =
EnumSet.of(UNION, INTERSECT, EXCEPT);
/**
* Category consisting of all expression operators.
*
* <p>A node is an expression if it is NOT one of the following:
* {@link #AS},
* {@link #DESCENDING},
* {@link #SELECT},
* {@link #JOIN},
* {@link #OTHER_FUNCTION},
* {@link #CAST},
* {@link #TRIM},
* {@link #LITERAL_CHAIN},
* {@link #JDBC_FN},
* {@link #PRECEDING},
* {@link #FOLLOWING},
* {@link #ORDER_BY},
* {@link #COLLECTION_TABLE},
* {@link #TABLESAMPLE}.
*/
public static final Set<SqlKind> EXPRESSION =
EnumSet.complementOf(
EnumSet.of(
AS, DESCENDING, SELECT, JOIN, OTHER_FUNCTION, CAST, TRIM,
LITERAL_CHAIN, JDBC_FN, PRECEDING, FOLLOWING, ORDER_BY,
NULLS_FIRST, NULLS_LAST, COLLECTION_TABLE, TABLESAMPLE,
WITH, WITH_ITEM));
/**
* Category consisting of all DML operators.
*
* <p>Consists of:
* {@link #INSERT},
* {@link #UPDATE},
* {@link #DELETE},
* {@link #MERGE},
* {@link #PROCEDURE_CALL}.
*
* <p>NOTE jvs 1-June-2006: For now we treat procedure calls as DML;
* this makes it easy for JDBC clients to call execute or
* executeUpdate and not have to process dummy cursor results. If
* in the future we support procedures which return results sets,
* we'll need to refine this.
*/
public static final EnumSet<SqlKind> DML =
EnumSet.of(INSERT, DELETE, UPDATE, MERGE, PROCEDURE_CALL);
/**
* Category consisting of query node types.
*
* <p>Consists of:
* {@link #SELECT},
* {@link #EXCEPT},
* {@link #INTERSECT},
* {@link #UNION},
* {@link #VALUES},
* {@link #ORDER_BY},
* {@link #EXPLICIT_TABLE}.
*/
public static final EnumSet<SqlKind> QUERY =
EnumSet.of(SELECT, UNION, INTERSECT, EXCEPT, VALUES, WITH, ORDER_BY,
EXPLICIT_TABLE);
/**
* Category of all SQL statement types.
*
* <p>Consists of all types in {@link #QUERY} and {@link #DML}.
*/
public static final Set<SqlKind> TOP_LEVEL = plus(QUERY, DML);
/**
* Category consisting of regular and special functions.
*
* <p>Consists of regular functions {@link #OTHER_FUNCTION} and special
* functions {@link #ROW}, {@link #TRIM}, {@link #CAST}, {@link #JDBC_FN}.
*/
public static final Set<SqlKind> FUNCTION =
EnumSet.of(OTHER_FUNCTION, ROW, TRIM, CAST, JDBC_FN);
/**
* Category of comparison operators.
*
* <p>Consists of:
* {@link #IN},
* {@link #EQUALS},
* {@link #NOT_EQUALS},
* {@link #LESS_THAN},
* {@link #GREATER_THAN},
* {@link #LESS_THAN_OR_EQUAL},
* {@link #GREATER_THAN_OR_EQUAL}.
*/
public static final Set<SqlKind> COMPARISON =
EnumSet.of(
IN, EQUALS, NOT_EQUALS,
LESS_THAN, GREATER_THAN,
GREATER_THAN_OR_EQUAL, LESS_THAN_OR_EQUAL);
/**
* Returns whether this {@code SqlKind} belongs to a given category.
*
* <p>A category is a collection of kinds, not necessarily disjoint. For
* example, QUERY is { SELECT, UNION, INTERSECT, EXCEPT, VALUES, ORDER_BY,
* EXPLICIT_TABLE }.
*
* @param category Category
* @return Whether this kind belongs to the given category
*/
public final boolean belongsTo(Collection<SqlKind> category) {
return category.contains(this);
}
private static <E extends Enum<E>> EnumSet<E> plus(EnumSet<E> set0,
EnumSet<E> set1) {
EnumSet<E> set = set0.clone();
set.addAll(set1);
return set;
}
}
// End SqlKind.java