All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.org.apache.calcite.sql.parser.SqlAbstractParserImpl Maven / Gradle / Ivy

There is a newer version: 5.4.0
Show newest version
/*
 * 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 com.hazelcast.com.liance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.com.hazelcast.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 com.hazelcast.org.apache.calcite.sql.parser;

import com.hazelcast.org.apache.calcite.avatica.util.Casing;
import com.hazelcast.org.apache.calcite.runtime.CalciteContextException;
import com.hazelcast.org.apache.calcite.sql.SqlCall;
import com.hazelcast.org.apache.calcite.sql.SqlFunctionCategory;
import com.hazelcast.org.apache.calcite.sql.SqlIdentifier;
import com.hazelcast.org.apache.calcite.sql.SqlLiteral;
import com.hazelcast.org.apache.calcite.sql.SqlNode;
import com.hazelcast.org.apache.calcite.sql.SqlNodeList;
import com.hazelcast.org.apache.calcite.sql.SqlOperator;
import com.hazelcast.org.apache.calcite.sql.SqlUnresolvedFunction;
import com.hazelcast.org.apache.calcite.sql.validate.SqlConformance;
import com.hazelcast.org.apache.calcite.util.Glossary;

import com.hazelcast.com.google.com.hazelcast.com.on.collect.ImmutableList;
import com.hazelcast.com.google.com.hazelcast.com.on.collect.ImmutableSet;
import com.hazelcast.com.google.com.hazelcast.com.on.collect.Iterables;

import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * Abstract base for parsers generated from CommonParser.jj.
 */
public abstract class SqlAbstractParserImpl {
  //~ Static fields/initializers ---------------------------------------------

  private static final ImmutableSet SQL_92_RESERVED_WORD_SET =
      ImmutableSet.of(
          "ABSOLUTE",
          "ACTION",
          "ADD",
          "ALL",
          "ALLOCATE",
          "ALTER",
          "AND",
          "ANY",
          "ARE",
          "AS",
          "ASC",
          "ASSERTION",
          "AT",
          "AUTHORIZATION",
          "AVG",
          "BEGIN",
          "BETWEEN",
          "BIT",
          "BIT_LENGTH",
          "BOTH",
          "BY",
          "CASCADE",
          "CASCADED",
          "CASE",
          "CAST",
          "CATALOG",
          "CHAR",
          "CHARACTER",
          "CHARACTER_LENGTH",
          "CHAR_LENGTH",
          "CHECK",
          "CLOSE",
          "COALESCE",
          "COLLATE",
          "COLLATION",
          "COLUMN",
          "COMMIT",
          "CONNECT",
          "CONNECTION",
          "CONSTRAINT",
          "CONSTRAINTS",
          "CONTINUE",
          "CONVERT",
          "CORRESPONDING",
          "COUNT",
          "CREATE",
          "CROSS",
          "CURRENT",
          "CURRENT_DATE",
          "CURRENT_TIME",
          "CURRENT_TIMESTAMP",
          "CURRENT_USER",
          "CURSOR",
          "DATE",
          "DAY",
          "DEALLOCATE",
          "DEC",
          "DECIMAL",
          "DECLARE",
          "DEFAULT",
          "DEFERRABLE",
          "DEFERRED",
          "DELETE",
          "DESC",
          "DESCRIBE",
          "DESCRIPTOR",
          "DIAGNOSTICS",
          "DISCONNECT",
          "DISTINCT",
          "DOMAIN",
          "DOUBLE",
          "DROP",
          "ELSE",
          "END",
          "END-EXEC",
          "ESCAPE",
          "EXCEPT",
          "EXCEPTION",
          "EXEC",
          "EXECUTE",
          "EXISTS",
          "EXTERNAL",
          "EXTRACT",
          "FALSE",
          "FETCH",
          "FIRST",
          "FLOAT",
          "FOR",
          "FOREIGN",
          "FOUND",
          "FROM",
          "FULL",
          "GET",
          "GLOBAL",
          "GO",
          "GOTO",
          "GRANT",
          "GROUP",
          "HAVING",
          "HOUR",
          "IDENTITY",
          "IMMEDIATE",
          "IN",
          "INDICATOR",
          "INITIALLY",
          "INNER",
          "INADD",
          "INSENSITIVE",
          "INSERT",
          "INT",
          "INTEGER",
          "INTERSECT",
          "INTERVAL",
          "INTO",
          "IS",
          "ISOLATION",
          "JOIN",
          "KEY",
          "LANGUAGE",
          "LAST",
          "LEADING",
          "LEFT",
          "LEVEL",
          "LIKE",
          "LOCAL",
          "LOWER",
          "MATCH",
          "MAX",
          "MIN",
          "MINUTE",
          "MODULE",
          "MONTH",
          "NAMES",
          "NATIONAL",
          "NATURAL",
          "NCHAR",
          "NEXT",
          "NO",
          "NOT",
          "NULL",
          "NULLIF",
          "NUMERIC",
          "OCTET_LENGTH",
          "OF",
          "ON",
          "ONLY",
          "OPEN",
          "OPTION",
          "OR",
          "ORDER",
          "OUTER",
          "OUTADD",
          "OVERLAPS",
          "PAD",
          "PARTIAL",
          "POSITION",
          "PRECISION",
          "PREPARE",
          "PRESERVE",
          "PRIMARY",
          "PRIOR",
          "PRIVILEGES",
          "PROCEDURE",
          "PUBLIC",
          "READ",
          "REAL",
          "REFERENCES",
          "RELATIVE",
          "RESTRICT",
          "REVOKE",
          "RIGHT",
          "ROLLBACK",
          "ROWS",
          "SCHEMA",
          "SCROLL",
          "SECOND",
          "SECTION",
          "SELECT",
          "SESSION",
          "SESSION_USER",
          "SET",
          "SIZE",
          "SMALLINT",
          "SOME",
          "SPACE",
          "SQL",
          "SQLCODE",
          "SQLERROR",
          "SQLSTATE",
          "SUBSTRING",
          "SUM",
          "SYSTEM_USER",
          "TABLE",
          "TEMPORARY",
          "THEN",
          "TIME",
          "TIMESTAMP",
          "TIMEZONE_HOUR",
          "TIMEZONE_MINUTE",
          "TO",
          "TRAILING",
          "TRANSACTION",
          "TRANSLATE",
          "TRANSLATION",
          "TRIM",
          "TRUE",
          "UNION",
          "UNIQUE",
          "UNKNOWN",
          "UPDATE",
          "UPPER",
          "USAGE",
          "USER",
          "USING",
          "VALUE",
          "VALUES",
          "VARCHAR",
          "VARYING",
          "VIEW",
          "WHEN",
          "WHENEVER",
          "WHERE",
          "WITH",
          "WORK",
          "WRITE",
          "YEAR",
          "ZONE");

  //~ Enums ------------------------------------------------------------------

  /**
   * Type-safe enum for context of acceptable expressions.
   */
  protected enum ExprContext {
    /**
     * Accept any kind of expression in this context.
     */
    ACCEPT_ALL,

    /**
     * Accept any kind of expression in this context, with the exception of
     * CURSOR constructors.
     */
    ACCEPT_NONCURSOR,

    /**
     * Accept only query expressions in this context.
     */
    ACCEPT_QUERY,

    /**
     * Accept only non-query expressions in this context.
     */
    ACCEPT_NON_QUERY,

    /**
     * Accept only parenthesized queries or non-query expressions in this
     * context.
     */
    ACCEPT_SUB_QUERY,

    /**
     * Accept only CURSOR constructors, parenthesized queries, or non-query
     * expressions in this context.
     */
    ACCEPT_CURSOR;

    @Deprecated // to be removed before 2.0
    public static final ExprContext ACCEPT_SUBQUERY = ACCEPT_SUB_QUERY;

    @Deprecated // to be removed before 2.0
    public static final ExprContext ACCEPT_NONQUERY = ACCEPT_NON_QUERY;
  }

  //~ Instance fields --------------------------------------------------------

  protected int nDynamicParams;

  protected String originalSql;

  protected final List warnings = new ArrayList<>();

  //~ Methods ----------------------------------------------------------------

  /**
   * Returns immutable set of all reserved words defined by SQL-92.
   *
   * @see Glossary#SQL92 SQL-92 Section 5.2
   */
  public static Set getSql92ReservedWords() {
    return SQL_92_RESERVED_WORD_SET;
  }

  /**
   * Creates a call.
   *
   * @param funName           Name of function
   * @param pos               Position in source code
   * @param funcType          Type of function
   * @param functionQualifier Qualifier
   * @param operands          Operands to call
   * @return Call
   */
  protected SqlCall createCall(
      SqlIdentifier funName,
      SqlParserPos pos,
      SqlFunctionCategory funcType,
      SqlLiteral functionQualifier,
      Iterable operands) {
    return createCall(funName, pos, funcType, functionQualifier,
        Iterables.toArray(operands, SqlNode.class));
  }

  /**
   * Creates a call.
   *
   * @param funName           Name of function
   * @param pos               Position in source code
   * @param funcType          Type of function
   * @param functionQualifier Qualifier
   * @param operands          Operands to call
   * @return Call
   */
  protected SqlCall createCall(
      SqlIdentifier funName,
      SqlParserPos pos,
      SqlFunctionCategory funcType,
      SqlLiteral functionQualifier,
      SqlNode[] operands) {
    // Create a placeholder function.  Later, during
    // validation, it will be resolved into a real function reference.
    SqlOperator fun = new SqlUnresolvedFunction(funName, null, null, null, null,
        funcType);

    return fun.createCall(functionQualifier, pos, operands);
  }

  /**
   * Returns metadata about this parser: keywords, etc.
   */
  public abstract Metadata getMetadata();

  /**
   * Removes or transforms misleading information from a parse exception or
   * error, and converts to {@link SqlParseException}.
   *
   * @param ex dirty excn
   * @return clean excn
   */
  public abstract SqlParseException normalizeException(Throwable ex);

  protected abstract SqlParserPos getPos() throws Exception;

  /**
   * Reinitializes parser with new input.
   *
   * @param reader provides new input
   */
  // CHECKSTYLE: IGNORE 1
  public abstract void ReInit(Reader reader);

  /**
   * Parses a SQL expression ending with EOF and constructs a
   * parse tree.
   *
   * @return constructed parse tree.
   */
  public abstract SqlNode parseSqlExpressionEof() throws Exception;

  /**
   * Parses a SQL statement ending with EOF and constructs a
   * parse tree.
   *
   * @return constructed parse tree.
   */
  public abstract SqlNode parseSqlStmtEof() throws Exception;

  /**
   * Parses a list of SQL statements separated by semicolon and constructs a
   * parse tree. The semicolon is required between statements, but is
   * optional at the end.
   *
   * @return constructed list of SQL statements.
   */
  public abstract SqlNodeList parseSqlStmtList() throws Exception;

  /**
   * Sets the tab stop size.
   *
   * @param tabSize Tab stop size
   */
  public abstract void setTabSize(int tabSize);

  /**
   * Sets the casing policy for quoted identifiers.
   *
   * @param quotedCasing Casing to set.
   */
  public abstract void setQuotedCasing(Casing quotedCasing);

  /**
   * Sets the casing policy for unquoted identifiers.
   *
   * @param unquotedCasing Casing to set.
   */
  public abstract void setUnquotedCasing(Casing unquotedCasing);

  /**
   * Sets the maximum length for sql identifier.
   */
  public abstract void setIdentifierMaxLength(int identifierMaxLength);

  /**
   * Sets the SQL language conformance level.
   */
  public abstract void setConformance(SqlConformance conformance);

  /**
   * Sets the SQL text that is being parsed.
   */
  public void setOriginalSql(String originalSql) {
    this.originalSql = originalSql;
  }

  /**
   * Returns the SQL text.
   */
  public String getOriginalSql() {
    return originalSql;
  }

  /**
   * Change parser state.
   *
   * @param stateName new state.
   */
  public abstract void switchTo(String stateName);

  //~ Inner Interfaces -------------------------------------------------------

  /**
   * Metadata about the parser. For example:
   *
   * 
    *
  • "KEY" is a keyword: it is meaningful in certain contexts, such as * "CREATE FOREIGN KEY", but can be used as an identifier, as in * "CREATE TABLE t (key INTEGER)". *
  • "SELECT" is a reserved word. It can not be used as an identifier. *
  • "CURRENT_USER" is the name of a context variable. It cannot be used * as an identifier. *
  • "ABS" is the name of a reserved function. It cannot be used as an * identifier. *
  • "DOMAIN" is a reserved word as specified by the SQL:92 standard. *
*/ public interface Metadata { /** * Returns true if token is a keyword but not a reserved word. For * example, "KEY". */ boolean isNonReservedKeyword(String token); /** * Returns whether token is the name of a context variable such as * "CURRENT_USER". */ boolean isContextVariableName(String token); /** * Returns whether token is a reserved function name such as * "CURRENT_USER". */ boolean isReservedFunctionName(String token); /** * Returns whether token is a keyword. (That is, a non-reserved keyword, * a context variable, or a reserved function name.) */ boolean isKeyword(String token); /** * Returns whether token is a reserved word. */ boolean isReservedWord(String token); /** * Returns whether token is a reserved word as specified by the SQL:92 * standard. */ boolean isSql92ReservedWord(String token); /** * Returns com.hazelcast.com.a-separated list of JDBC keywords. */ String getJdbcKeywords(); /** * Returns a list of all tokens in alphabetical order. */ List getTokens(); } //~ Inner Classes ---------------------------------------------------------- /** * Default implementation of the {@link Metadata} interface. */ public static class MetadataImpl implements Metadata { private final Set reservedFunctionNames = new HashSet<>(); private final Set contextVariableNames = new HashSet<>(); private final Set nonReservedKeyWordSet = new HashSet<>(); /** * Set of all tokens. */ private final SortedSet tokenSet = new TreeSet<>(); /** * Immutable list of all tokens, in alphabetical order. */ private final List tokenList; private final Set reservedWords = new HashSet<>(); private final String sql92ReservedWords; /** * Creates a MetadataImpl. * * @param sqlParser Parser */ public MetadataImpl(SqlAbstractParserImpl sqlParser) { initList(sqlParser, reservedFunctionNames, "ReservedFunctionName"); initList(sqlParser, contextVariableNames, "ContextVariable"); initList(sqlParser, nonReservedKeyWordSet, "NonReservedKeyWord"); tokenList = ImmutableList.copyOf(tokenSet); sql92ReservedWords = constructSql92ReservedWordList(); Set reservedWordSet = new TreeSet<>(); reservedWordSet.addAll(tokenSet); reservedWordSet.removeAll(nonReservedKeyWordSet); reservedWords.addAll(reservedWordSet); } /** * Initializes lists of keywords. */ private void initList( SqlAbstractParserImpl parserImpl, Set keywords, String name) { parserImpl.ReInit(new StringReader("1")); try { Object o = virtualCall(parserImpl, name); throw new AssertionError("expected call to fail, got " + o); } catch (SqlParseException parseException) { // First time through, build the list of all tokens. final String[] tokenImages = parseException.getTokenImages(); if (tokenSet.isEmpty()) { for (String token : tokenImages) { String tokenVal = SqlParserUtil.getTokenVal(token); if (tokenVal != null) { tokenSet.add(tokenVal); } } } // Add the tokens which would have been expected in this // syntactic context to the list we're building. final int[][] expectedTokenSequences = parseException.getExpectedTokenSequences(); for (final int[] tokens : expectedTokenSequences) { assert tokens.length == 1; final int tokenId = tokens[0]; String token = tokenImages[tokenId]; String tokenVal = SqlParserUtil.getTokenVal(token); if (tokenVal != null) { keywords.add(tokenVal); } } } catch (Throwable e) { throw new RuntimeException("While building token lists", e); } } /** * Uses reflection to invoke a method on this parser. The method must be * public and have no parameters. * * @param parserImpl Parser * @param name Name of method. For example "ReservedFunctionName". * @return Result of calling method */ private Object virtualCall( SqlAbstractParserImpl parserImpl, String name) throws Throwable { Class clazz = parserImpl.getClass(); try { final Method method = clazz.getMethod(name, (Class[]) null); return method.invoke(parserImpl, (Object[]) null); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); throw parserImpl.normalizeException(cause); } } /** * Builds a com.hazelcast.com.a-separated list of JDBC reserved words. */ private String constructSql92ReservedWordList() { StringBuilder sb = new StringBuilder(); TreeSet jdbcReservedSet = new TreeSet<>(); jdbcReservedSet.addAll(tokenSet); jdbcReservedSet.removeAll(SQL_92_RESERVED_WORD_SET); jdbcReservedSet.removeAll(nonReservedKeyWordSet); int j = 0; for (String jdbcReserved : jdbcReservedSet) { if (j++ > 0) { sb.append(","); } sb.append(jdbcReserved); } return sb.toString(); } public List getTokens() { return tokenList; } public boolean isSql92ReservedWord(String token) { return SQL_92_RESERVED_WORD_SET.contains(token); } public String getJdbcKeywords() { return sql92ReservedWords; } public boolean isKeyword(String token) { return isNonReservedKeyword(token) || isReservedFunctionName(token) || isContextVariableName(token) || isReservedWord(token); } public boolean isNonReservedKeyword(String token) { return nonReservedKeyWordSet.contains(token); } public boolean isReservedFunctionName(String token) { return reservedFunctionNames.contains(token); } public boolean isContextVariableName(String token) { return contextVariableNames.contains(token); } public boolean isReservedWord(String token) { return reservedWords.contains(token); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy