IMPALA-3916: Reserve SQL:2016 reserved words This patch reserves SQL:2016 reserved words, excluding: 1. Impala builtin function names. 2. Time unit words(year, month, etc.). 3. An exception list based on a discussion.
Some test cases are modified to avoid these words. A impalad and catalogd startup option reserved_words_version is added. The words are reserved if the option is set to "3.0.0". Change-Id: If1b295e6a77e840cf1b794c2eb73e1b9d2b8ddd6 Reviewed-on: http://gerrit.cloudera.org:8080/9096 Reviewed-by: Alex Behm <alex.b...@cloudera.com> Reviewed-by: Philip Zeyliger <phi...@cloudera.com> Tested-by: Impala Public Jenkins Project: http://git-wip-us.apache.org/repos/asf/impala/repo Commit: http://git-wip-us.apache.org/repos/asf/impala/commit/f0b3d9d1 Tree: http://git-wip-us.apache.org/repos/asf/impala/tree/f0b3d9d1 Diff: http://git-wip-us.apache.org/repos/asf/impala/diff/f0b3d9d1 Branch: refs/heads/master Commit: f0b3d9d122f2c6eb4137bf93e3512a489ff8fab0 Parents: 4bd7cc8 Author: Tianyi Wang <tw...@cloudera.com> Authored: Tue Jan 16 18:00:02 2018 -0800 Committer: Impala Public Jenkins <impala-public-jenk...@gerrit.cloudera.org> Committed: Fri Feb 2 01:13:08 2018 +0000 ---------------------------------------------------------------------- be/src/common/global-flags.cc | 7 +- be/src/common/init.cc | 9 +- be/src/util/backend-gflag-util.cc | 11 +- common/thrift/BackendGflags.thrift | 7 + fe/src/main/cup/sql-parser.cup | 56 +- .../org/apache/impala/analysis/ToSqlUtils.java | 7 +- .../org/apache/impala/catalog/BuiltinsDb.java | 4 +- .../java/org/apache/impala/catalog/Catalog.java | 10 +- .../impala/catalog/CatalogServiceCatalog.java | 11 +- .../main/java/org/apache/impala/catalog/Db.java | 18 +- .../apache/impala/catalog/ImpaladCatalog.java | 14 +- .../apache/impala/service/BackendConfig.java | 12 +- fe/src/main/jflex/sql-scanner.flex | 577 +++++++++++-------- .../apache/impala/analysis/AnalyzeDDLTest.java | 13 +- .../impala/analysis/AnalyzeStmtsTest.java | 6 +- .../org/apache/impala/analysis/ToSqlTest.java | 14 +- .../org/apache/impala/catalog/CatalogTest.java | 12 +- .../apache/impala/common/FrontendTestBase.java | 2 +- .../impala/planner/StatsExtrapolationTest.java | 24 +- .../org/apache/impala/service/JdbcTest.java | 8 +- .../queries/QueryTest/empty-build-joins.test | 84 +-- .../queries/QueryTest/exprs.test | 16 +- .../queries/QueryTest/partition-col-types.test | 2 +- .../queries/QueryTest/single-node-nlj.test | 24 +- .../queries/QueryTest/spilling-large-rows.test | 16 +- .../queries/QueryTest/values.test | 6 +- .../test_reserved_words_version.py | 38 ++ .../custom_cluster/test_stats_extrapolation.py | 2 +- tests/query_test/test_sort.py | 6 +- 29 files changed, 572 insertions(+), 444 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/be/src/common/global-flags.cc ---------------------------------------------------------------------- diff --git a/be/src/common/global-flags.cc b/be/src/common/global-flags.cc index d9d99c8..2d832da 100644 --- a/be/src/common/global-flags.cc +++ b/be/src/common/global-flags.cc @@ -182,10 +182,15 @@ DEFINE_int32(max_log_files, 10, "Maximum number of log files to retain per sever "retained."); // The read size is the preferred size of the reads issued to HDFS or the local FS. -// There is a trade off of latency and throughout, trying to keep disks busy but +// There is a trade off of latency and throughput, trying to keep disks busy but // not introduce seeks. The literature seems to agree that with 8 MB reads, random // io and sequential io perform similarly. DEFINE_int32(read_size, 8 * 1024 * 1024, "(Advanced) The preferred I/O request size in " "bytes to issue to HDFS or the local filesystem. Increasing the read size will " "increase memory requirements. Decreasing the read size may decrease I/O " "throughput."); + +DEFINE_string(reserved_words_version, "3.0.0", "Reserved words compatibility version. " + "Reserved words cannot be used as identifiers in SQL. This flag determines the impala" + " version from which the reserved word list is taken. The value must be one of " + "[\"2.11.0\", \"3.0.0\"]."); http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/be/src/common/init.cc ---------------------------------------------------------------------- diff --git a/be/src/common/init.cc b/be/src/common/init.cc index abbe416..41d4549 100644 --- a/be/src/common/init.cc +++ b/be/src/common/init.cc @@ -63,9 +63,10 @@ DECLARE_string(heap_profile_dir); DECLARE_string(hostname); // TODO: rename this to be more generic when we have a good CM release to do so. DECLARE_int32(logbufsecs); +DECLARE_int32(max_log_files); DECLARE_int32(max_minidumps); DECLARE_string(redaction_rules_file); -DECLARE_int32(max_log_files); +DECLARE_string(reserved_words_version); DEFINE_int32(max_audit_event_log_files, 0, "Maximum number of audit event log files " "to retain. The most recent audit event log files are retained. If set to 0, " @@ -199,6 +200,12 @@ void impala::InitCommonRuntime(int argc, char** argv, bool init_jvm, CLEAN_EXIT_WITH_ERROR(Substitute("read_size can not be lower than $0", READ_SIZE_MIN_VALUE)); } + if (FLAGS_reserved_words_version != "2.11.0" && FLAGS_reserved_words_version != "3.0.0") + { + CLEAN_EXIT_WITH_ERROR(Substitute("Invalid flag reserved_words_version. The value must" + " be one of [\"2.11.0\", \"3.0.0\"], while the provided value is $0.", + FLAGS_reserved_words_version)); + } impala::InitGoogleLoggingSafe(argv[0]); // Breakpad needs flags and logging to initialize. ABORT_IF_ERROR(RegisterMinidump(argv[0])); http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/be/src/util/backend-gflag-util.cc ---------------------------------------------------------------------- diff --git a/be/src/util/backend-gflag-util.cc b/be/src/util/backend-gflag-util.cc index 91095e1..f7f49ac 100644 --- a/be/src/util/backend-gflag-util.cc +++ b/be/src/util/backend-gflag-util.cc @@ -16,13 +16,12 @@ // under the License. #include "common/global-flags.h" -#include "util/backend-gflag-util.h" #include "gen-cpp/BackendGflags_types.h" #include "rpc/jni-thrift-util.h" +#include "util/backend-gflag-util.h" #include "util/logging-support.h" -#include <gflags/gflags.h> // Configs for the Frontend and the Catalog. DECLARE_bool(load_catalog_in_background); @@ -46,6 +45,7 @@ DECLARE_string(authorization_policy_provider_class); DECLARE_string(authorized_proxy_user_config); DECLARE_string(authorized_proxy_user_config_delimiter); DECLARE_string(kudu_master_hosts); +DECLARE_string(reserved_words_version); DECLARE_string(sentry_config); namespace impala { @@ -78,6 +78,13 @@ Status GetThriftBackendGflags(JNIEnv* jni_env, jbyteArray* cfg_bytes) { cfg.__set_local_library_path(FLAGS_local_library_dir); cfg.__set_kudu_operation_timeout_ms(FLAGS_kudu_operation_timeout_ms); cfg.__set_sentry_catalog_polling_frequency_s(FLAGS_sentry_catalog_polling_frequency_s); + if (FLAGS_reserved_words_version == "2.11.0") { + cfg.__set_reserved_words_version(TReservedWordsVersion::IMPALA_2_11); + } else { + DCHECK_EQ(FLAGS_reserved_words_version, "3.0.0"); + cfg.__set_reserved_words_version(TReservedWordsVersion::IMPALA_3_0); + } + RETURN_IF_ERROR(SerializeThriftMsg(jni_env, &cfg, cfg_bytes)); return Status::OK(); } http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/common/thrift/BackendGflags.thrift ---------------------------------------------------------------------- diff --git a/common/thrift/BackendGflags.thrift b/common/thrift/BackendGflags.thrift index baae9ba..36c4a7e 100644 --- a/common/thrift/BackendGflags.thrift +++ b/common/thrift/BackendGflags.thrift @@ -18,6 +18,11 @@ namespace cpp impala namespace java org.apache.impala.thrift +enum TReservedWordsVersion { + IMPALA_2_11 + IMPALA_3_0 +} + // Used to pass gflags from backend to frontend, JniCatalog and JniFrontend // Attributes without comments correspond to gflags struct TBackendGflags { @@ -62,4 +67,6 @@ struct TBackendGflags { 20: required i32 max_hdfs_partitions_parallel_load 21: required i32 max_nonhdfs_partitions_parallel_load + + 22: required TReservedWordsVersion reserved_words_version } http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/main/cup/sql-parser.cup ---------------------------------------------------------------------- diff --git a/fe/src/main/cup/sql-parser.cup b/fe/src/main/cup/sql-parser.cup index dc0199b..38183f8 100644 --- a/fe/src/main/cup/sql-parser.cup +++ b/fe/src/main/cup/sql-parser.cup @@ -215,6 +215,9 @@ parser code {: SqlScanner.tokenIdMap.get(Integer.valueOf(errorToken_.sym)); if (lastToken != null) { result.append(lastToken); + } else if (SqlScanner.isReserved((String)errorToken_.value)) { + result.append("A reserved word cannot be used as an identifier: ") + .append((String)errorToken_.value); } else { result.append("Unknown last token with id: " + errorToken_.sym); } @@ -244,7 +247,7 @@ parser code {: :}; // List of keywords. Please keep them sorted alphabetically. -// ALL KEYWORDS ALSO NEED TO BE ADDED TO THE ident_or_keyword PRODUCTION. +// ALL KEYWORDS ALSO NEED TO BE ADDED TO THE word PRODUCTION. terminal KW_ADD, KW_AGGREGATE, KW_ALL, KW_ALTER, KW_ANALYTIC, KW_AND, KW_ANTI, KW_API_VERSION, KW_ARRAY, KW_AS, KW_ASC, KW_AVRO, KW_BETWEEN, KW_BIGINT, KW_BINARY, KW_BLOCKSIZE, @@ -270,8 +273,10 @@ terminal KW_SHOW, KW_SMALLINT, KW_SORT, KW_STORED, KW_STRAIGHT_JOIN, KW_STRING, KW_STRUCT, KW_SYMBOL, KW_TABLE, KW_TABLES, KW_TABLESAMPLE, KW_TBLPROPERTIES, KW_TERMINATED, KW_TEXTFILE, KW_THEN, KW_TIMESTAMP, KW_TINYINT, KW_TRUNCATE, KW_STATS, KW_TO, KW_TRUE, - KW_UNBOUNDED, KW_UNCACHED, KW_UNION, KW_UPDATE, KW_UPDATE_FN, KW_UPSERT, KW_USE, - KW_USING, KW_VALUES, KW_VARCHAR, KW_VIEW, KW_WHEN, KW_WHERE, KW_WITH; + KW_UNBOUNDED, KW_UNCACHED, KW_UNION, KW_UNKNOWN, KW_UPDATE, KW_UPDATE_FN, KW_UPSERT, + KW_USE, KW_USING, KW_VALUES, KW_VARCHAR, KW_VIEW, KW_WHEN, KW_WHERE, KW_WITH; + +terminal UNUSED_RESERVED_WORD; terminal COLON, SEMICOLON, COMMA, DOT, DOTDOTDOT, STAR, LPAREN, RPAREN, LBRACKET, RBRACKET, DIVIDE, MOD, ADD, SUBTRACT; @@ -292,7 +297,11 @@ terminal String UNEXPECTED_CHAR; // IMPALA-3726 introduced the DEFAULT keyword which could break existing applications // that use the identifier "KEYWORD" as database, column or table names. To avoid that, // the ident_or_default non-terminal is introduced and should be used instead of IDENT. -nonterminal String ident_or_keyword, ident_or_default; +nonterminal String ident_or_default; +// A word is an arbitrary token composed of digits and at least one letter. Reserved +// words cannot be used as identifiers but they are words and can be used in query +// options, column attributes, etc. +nonterminal String word; nonterminal StatementBase stmt; // Single select statement. nonterminal SelectStmt select_stmt; @@ -494,7 +503,6 @@ nonterminal Boolean server_ident; nonterminal Boolean source_ident; nonterminal Boolean sources_ident; nonterminal Boolean uri_ident; -nonterminal Boolean unknown_ident; // For Create/Drop/Show function ddl nonterminal FunctionArgs function_def_args; @@ -1633,13 +1641,13 @@ nullability_val ::= ; encoding_val ::= - KW_ENCODING ident_or_default:encoding_ident - {: RESULT = encoding_ident; :} + KW_ENCODING word:value + {: RESULT = value; :} ; compression_val ::= - KW_COMPRESSION ident_or_default:compression_ident - {: RESULT = compression_ident; :} + KW_COMPRESSION word:value + {: RESULT = value; :} ; default_val ::= @@ -1740,16 +1748,6 @@ option_ident ::= :} ; -unknown_ident ::= - IDENT:ident - {: - if (!ident.toUpperCase().equals("UNKNOWN")) { - parser.parseError("identifier", SqlParserSymbols.IDENT, "UNKNOWN"); - } - RESULT = true; - :} - ; - view_column_defs ::= LPAREN view_column_def_list:view_col_defs RPAREN {: RESULT = view_col_defs; :} @@ -2361,14 +2359,16 @@ select_clause ::= ; set_stmt ::= - KW_SET ident_or_default:key EQUAL literal:l + KW_SET ident_or_default:key EQUAL numeric_literal:l {: RESULT = new SetStmt(key, l.getStringValue(), false); :} + | KW_SET ident_or_default:key EQUAL STRING_LITERAL:l + {: RESULT = new SetStmt(key, l, false); :} | KW_SET ident_or_default:key EQUAL SUBTRACT numeric_literal:l {: l.swapSign(); RESULT = new SetStmt(key, l.getStringValue(), false); :} - | KW_SET ident_or_default:key EQUAL ident_or_default:ident - {: RESULT = new SetStmt(key, ident, false); :} + | KW_SET ident_or_default:key EQUAL word:value + {: RESULT = new SetStmt(key, value, false); :} | KW_SET KW_ALL {: RESULT = new SetStmt(null, null, true); :} | KW_SET @@ -3106,9 +3106,9 @@ bool_test_expr ::= {: RESULT = new FunctionCallExpr("isfalse", Lists.newArrayList(e)); :} | expr:e KW_IS KW_NOT KW_FALSE {: RESULT = new FunctionCallExpr("isnotfalse", Lists.newArrayList(e)); :} - | expr:e KW_IS unknown_ident + | expr:e KW_IS KW_UNKNOWN {: RESULT = new IsNullPredicate(e, false); :} - | expr:e KW_IS KW_NOT unknown_ident + | expr:e KW_IS KW_NOT KW_UNKNOWN {: RESULT = new IsNullPredicate(e, true); :} ; @@ -3203,7 +3203,7 @@ type ::= // that we can parse type strings from the Hive Metastore which // may have unquoted identifiers corresponding to keywords. struct_field_def ::= - ident_or_keyword:name COLON type:t opt_comment_val:comment + word:name COLON type:t opt_comment_val:comment {: RESULT = new StructField(name, t, comment); :} ; @@ -3228,7 +3228,7 @@ ident_or_default ::= {: RESULT = name.toString(); :} ; -ident_or_keyword ::= +word ::= IDENT:r {: RESULT = r.toString(); :} | KW_ADD:r @@ -3579,6 +3579,8 @@ ident_or_keyword ::= {: RESULT = r.toString(); :} | KW_UNION:r {: RESULT = r.toString(); :} + | KW_UNKNOWN:r + {: RESULT = r.toString(); :} | KW_UPDATE:r {: RESULT = r.toString(); :} | KW_UPDATE_FN:r @@ -3601,4 +3603,6 @@ ident_or_keyword ::= {: RESULT = r.toString(); :} | KW_WITH:r {: RESULT = r.toString(); :} + | UNUSED_RESERVED_WORD:r + {: RESULT = r.toString(); :} ; http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/main/java/org/apache/impala/analysis/ToSqlUtils.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/analysis/ToSqlUtils.java b/fe/src/main/java/org/apache/impala/analysis/ToSqlUtils.java index facebfd..1940cde 100644 --- a/fe/src/main/java/org/apache/impala/analysis/ToSqlUtils.java +++ b/fe/src/main/java/org/apache/impala/analysis/ToSqlUtils.java @@ -39,7 +39,6 @@ import org.apache.commons.lang.StringEscapeUtils; import org.apache.hadoop.hive.common.StatsSetupConst; import org.apache.hadoop.hive.metastore.TableType; import org.apache.hadoop.hive.ql.parse.HiveLexer; - import org.apache.impala.catalog.CatalogException; import org.apache.impala.catalog.Column; import org.apache.impala.catalog.Function; @@ -123,15 +122,15 @@ public class ToSqlUtils { } catch (Exception e) { // Ignore exception and just quote the identifier to be safe. } - boolean isImpalaKeyword = SqlScanner.isKeyword(ident.toUpperCase()); + boolean isImpalaReserved = SqlScanner.isReserved(ident.toUpperCase()); // Impala's scanner recognizes the ".123" portion of "db.123_tbl" as a decimal, // so while the quoting is not necessary for the given identifier itself, the quotes // are needed if this identifier will be preceded by a ".". boolean startsWithNumber = false; - if (!hiveNeedsQuotes && !isImpalaKeyword) { + if (!hiveNeedsQuotes && !isImpalaReserved) { startsWithNumber = Character.isDigit(ident.charAt(0)); } - if (hiveNeedsQuotes || isImpalaKeyword || startsWithNumber) return "`" + ident + "`"; + if (hiveNeedsQuotes || isImpalaReserved || startsWithNumber) return "`" + ident + "`"; return ident; } http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java b/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java index f8a6b89..a95435e 100644 --- a/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java +++ b/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java @@ -56,8 +56,8 @@ public class BuiltinsDb extends Db { // Size in bytes of RankState used for rank() and dense_rank(). private static final int RANK_INTERMEDIATE_SIZE = 16; - public BuiltinsDb(String name, Catalog catalog) { - super(name, catalog, createMetastoreDb(name)); + public BuiltinsDb(String name) { + super(name, createMetastoreDb(name)); setIsSystemDb(true); initBuiltins(); } http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/main/java/org/apache/impala/catalog/Catalog.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/catalog/Catalog.java b/fe/src/main/java/org/apache/impala/catalog/Catalog.java index 4548c2b..6136835 100644 --- a/fe/src/main/java/org/apache/impala/catalog/Catalog.java +++ b/fe/src/main/java/org/apache/impala/catalog/Catalog.java @@ -17,10 +17,6 @@ package org.apache.impala.catalog; -import com.google.common.base.Joiner; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; - import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -36,7 +32,9 @@ import org.apache.impala.thrift.TTable; import org.apache.impala.thrift.TTableName; import org.apache.impala.util.PatternMatcher; -import org.apache.log4j.Logger; +import com.google.common.base.Joiner; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; /** * Thread safe interface for reading and updating metadata stored in the Hive MetaStore. @@ -89,7 +87,7 @@ public abstract class Catalog { public Catalog() { dataSources_ = new CatalogObjectCache<DataSource>(); - builtinsDb_ = new BuiltinsDb(BUILTINS_DB, this); + builtinsDb_ = new BuiltinsDb(BUILTINS_DB); addDb(builtinsDb_); } http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/main/java/org/apache/impala/catalog/CatalogServiceCatalog.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/catalog/CatalogServiceCatalog.java b/fe/src/main/java/org/apache/impala/catalog/CatalogServiceCatalog.java index 8f75a16..7bc2a91 100644 --- a/fe/src/main/java/org/apache/impala/catalog/CatalogServiceCatalog.java +++ b/fe/src/main/java/org/apache/impala/catalog/CatalogServiceCatalog.java @@ -25,15 +25,14 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.commons.codec.binary.Base64; import org.apache.hadoop.fs.Path; @@ -49,7 +48,6 @@ import org.apache.hadoop.hive.metastore.api.UnknownDBException; import org.apache.hadoop.hive.ql.exec.FunctionUtils; import org.apache.impala.authorization.SentryConfig; import org.apache.impala.catalog.MetaStoreClientPool.MetaStoreClient; -import org.apache.impala.catalog.TopicUpdateLog.Entry; import org.apache.impala.common.FileSystemUtil; import org.apache.impala.common.ImpalaException; import org.apache.impala.common.ImpalaRuntimeException; @@ -79,7 +77,6 @@ import org.apache.thrift.protocol.TCompactProtocol; import com.codahale.metrics.Timer; import com.google.common.base.Joiner; import com.google.common.base.Preconditions; -import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -943,7 +940,7 @@ public class CatalogServiceCatalog extends Catalog { // Contains native functions in it's params map. org.apache.hadoop.hive.metastore.api.Database msDb = msClient.getHiveClient().getDatabase(dbName); - tmpDb = new Db(dbName, this, null); + tmpDb = new Db(dbName, null); // Load native UDFs into the temporary db. loadFunctionsFromDbParams(tmpDb, msDb); // Load Java UDFs from HMS into the temporary db. @@ -1004,7 +1001,7 @@ public class CatalogServiceCatalog extends Catalog { } org.apache.hadoop.hive.metastore.api.Database msDb = msClient.getHiveClient().getDatabase(dbName); - Db newDb = new Db(dbName, this, msDb); + Db newDb = new Db(dbName, msDb); // existingDb is usually null when the Catalog loads for the first time. // In that case we needn't restore any transient functions. if (existingDb != null) { @@ -1144,7 +1141,7 @@ public class CatalogServiceCatalog extends Catalog { * new Db object. Used by CREATE DATABASE statements. */ public Db addDb(String dbName, org.apache.hadoop.hive.metastore.api.Database msDb) { - Db newDb = new Db(dbName, this, msDb); + Db newDb = new Db(dbName, msDb); versionLock_.writeLock().lock(); try { newDb.setCatalogVersion(incrementAndGetCatalogVersion()); http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/main/java/org/apache/impala/catalog/Db.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/catalog/Db.java b/fe/src/main/java/org/apache/impala/catalog/Db.java index f1c9c8e..d59a28f 100644 --- a/fe/src/main/java/org/apache/impala/catalog/Db.java +++ b/fe/src/main/java/org/apache/impala/catalog/Db.java @@ -24,23 +24,20 @@ import java.util.List; import java.util.Map; import org.apache.commons.codec.binary.Base64; -import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.TException; import org.apache.thrift.TSerializer; +import org.apache.thrift.protocol.TCompactProtocol; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import org.apache.impala.catalog.Function; import org.apache.impala.common.ImpalaException; import org.apache.impala.common.ImpalaRuntimeException; -import org.apache.impala.common.JniUtil; import org.apache.impala.thrift.TCatalogObject; import org.apache.impala.thrift.TCatalogObjectType; import org.apache.impala.thrift.TDatabase; -import org.apache.impala.thrift.TFunction; import org.apache.impala.thrift.TFunctionBinaryType; import org.apache.impala.thrift.TFunctionCategory; import org.apache.impala.util.PatternMatcher; + import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -62,7 +59,6 @@ import com.google.common.collect.Maps; */ public class Db extends CatalogObjectImpl { private static final Logger LOG = LoggerFactory.getLogger(Db.class); - private final Catalog parentCatalog_; private final TDatabase thriftDb_; public static final String FUNCTION_INDEX_PREFIX = "impala_registered_function_"; @@ -87,10 +83,8 @@ public class Db extends CatalogObjectImpl { // (e.g. can't drop it, can't add tables to it, etc). private boolean isSystemDb_ = false; - public Db(String name, Catalog catalog, - org.apache.hadoop.hive.metastore.api.Database msDb) { + public Db(String name, org.apache.hadoop.hive.metastore.api.Database msDb) { thriftDb_ = new TDatabase(name.toLowerCase()); - parentCatalog_ = catalog; thriftDb_.setMetastore_db(msDb); tableCache_ = new CatalogObjectCache<Table>(); functions_ = new HashMap<String, List<Function>>(); @@ -101,8 +95,8 @@ public class Db extends CatalogObjectImpl { /** * Creates a Db object with no tables based on the given TDatabase thrift struct. */ - public static Db fromTDatabase(TDatabase db, Catalog parentCatalog) { - return new Db(db.getDb_name(), parentCatalog, db.getMetastore_db()); + public static Db fromTDatabase(TDatabase db) { + return new Db(db.getDb_name(), db.getMetastore_db()); } /** @@ -416,7 +410,7 @@ public class Db extends CatalogObjectImpl { * This is not thread safe so a higher level lock must be taken while iterating * over the returned functions. */ - protected HashMap<String, List<Function>> getAllFunctions() { + public HashMap<String, List<Function>> getAllFunctions() { return functions_; } http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/main/java/org/apache/impala/catalog/ImpaladCatalog.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/catalog/ImpaladCatalog.java b/fe/src/main/java/org/apache/impala/catalog/ImpaladCatalog.java index 0e2e8b9..4bb6b65 100644 --- a/fe/src/main/java/org/apache/impala/catalog/ImpaladCatalog.java +++ b/fe/src/main/java/org/apache/impala/catalog/ImpaladCatalog.java @@ -17,20 +17,13 @@ package org.apache.impala.catalog; -import com.google.common.base.Preconditions; - import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hive.metastore.api.MetaException; import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; -import org.apache.log4j.Logger; -import org.apache.thrift.TException; - import org.apache.impala.catalog.MetaStoreClientPool.MetaStoreClient; import org.apache.impala.common.ImpalaException; -import org.apache.impala.util.PatternMatcher; import org.apache.impala.thrift.TCatalogObject; import org.apache.impala.thrift.TCatalogObjectType; import org.apache.impala.thrift.TDataSource; @@ -42,6 +35,11 @@ import org.apache.impala.thrift.TTable; import org.apache.impala.thrift.TUniqueId; import org.apache.impala.thrift.TUpdateCatalogCacheRequest; import org.apache.impala.thrift.TUpdateCatalogCacheResponse; +import org.apache.impala.util.PatternMatcher; +import org.apache.log4j.Logger; +import org.apache.thrift.TException; + +import com.google.common.base.Preconditions; /** * Thread safe Catalog for an Impalad. The Impalad catalog can be updated either via @@ -374,7 +372,7 @@ public class ImpaladCatalog extends Catalog { Db existingDb = getDb(thriftDb.getDb_name()); if (existingDb == null || existingDb.getCatalogVersion() < catalogVersion) { - Db newDb = Db.fromTDatabase(thriftDb, this); + Db newDb = Db.fromTDatabase(thriftDb); newDb.setCatalogVersion(catalogVersion); addDb(newDb); if (existingDb != null) { http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/main/java/org/apache/impala/service/BackendConfig.java ---------------------------------------------------------------------- diff --git a/fe/src/main/java/org/apache/impala/service/BackendConfig.java b/fe/src/main/java/org/apache/impala/service/BackendConfig.java index af05ad6..659e717 100644 --- a/fe/src/main/java/org/apache/impala/service/BackendConfig.java +++ b/fe/src/main/java/org/apache/impala/service/BackendConfig.java @@ -17,14 +17,17 @@ package org.apache.impala.service; -import com.google.common.base.Preconditions; -import com.google.common.base.Strings; +import static org.apache.hadoop.fs.CommonConfigurationKeysPublic + .HADOOP_SECURITY_AUTH_TO_LOCAL; import org.apache.hadoop.conf.Configuration; -import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTH_TO_LOCAL; import org.apache.hadoop.security.authentication.util.KerberosName; +import org.apache.impala.analysis.SqlScanner; import org.apache.impala.thrift.TBackendGflags; +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; + /** * This class is meant to provide the FE with impalad backend configuration parameters, * including command line arguments. @@ -41,9 +44,11 @@ public class BackendConfig { public static void create(TBackendGflags cfg) { Preconditions.checkNotNull(cfg); INSTANCE = new BackendConfig(cfg); + SqlScanner.init(cfg.getReserved_words_version()); initAuthToLocal(); } + public TBackendGflags getBackendCfg() { return backendCfg_; } public long getReadSize() { return backendCfg_.read_size; } public boolean getComputeLineage() { return !Strings.isNullOrEmpty(backendCfg_.lineage_event_log_dir); @@ -71,6 +76,7 @@ public class BackendConfig { public int maxNonHdfsPartsParallelLoad() { return backendCfg_.max_nonhdfs_partitions_parallel_load; } + // Inits the auth_to_local configuration in the static KerberosName class. private static void initAuthToLocal() { // If auth_to_local is enabled, we read the configuration hadoop.security.auth_to_local http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/main/jflex/sql-scanner.flex ---------------------------------------------------------------------- diff --git a/fe/src/main/jflex/sql-scanner.flex b/fe/src/main/jflex/sql-scanner.flex index ee8355d..c4ed217 100644 --- a/fe/src/main/jflex/sql-scanner.flex +++ b/fe/src/main/jflex/sql-scanner.flex @@ -20,15 +20,19 @@ package org.apache.impala.analysis; import java_cup.runtime.Symbol; import java.lang.Integer; import java.math.BigDecimal; -import java.math.BigInteger; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Set; import java.util.Iterator; -import java.util.List; -import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import org.apache.impala.analysis.SqlParserSymbols; +import org.apache.impala.catalog.BuiltinsDb; +import static org.apache.impala.catalog.Catalog.BUILTINS_DB; +import org.apache.impala.service.BackendConfig; +import org.apache.impala.thrift.TReservedWordsVersion; %% @@ -49,253 +53,328 @@ import org.apache.impala.analysis.SqlParserSymbols; // uses "and" as a display name and not "&&". // Please keep the puts sorted alphabetically by keyword (where the order // does not affect the desired error reporting) - public static final Map<String, Integer> keywordMap = - new LinkedHashMap<String, Integer>(); - static { - keywordMap.put("&&", new Integer(SqlParserSymbols.KW_AND)); - keywordMap.put("add", new Integer(SqlParserSymbols.KW_ADD)); - keywordMap.put("aggregate", new Integer(SqlParserSymbols.KW_AGGREGATE)); - keywordMap.put("all", new Integer(SqlParserSymbols.KW_ALL)); - keywordMap.put("alter", new Integer(SqlParserSymbols.KW_ALTER)); - keywordMap.put("analytic", new Integer(SqlParserSymbols.KW_ANALYTIC)); - keywordMap.put("and", new Integer(SqlParserSymbols.KW_AND)); - keywordMap.put("anti", new Integer(SqlParserSymbols.KW_ANTI)); - keywordMap.put("api_version", new Integer(SqlParserSymbols.KW_API_VERSION)); - keywordMap.put("array", new Integer(SqlParserSymbols.KW_ARRAY)); - keywordMap.put("as", new Integer(SqlParserSymbols.KW_AS)); - keywordMap.put("asc", new Integer(SqlParserSymbols.KW_ASC)); - keywordMap.put("avro", new Integer(SqlParserSymbols.KW_AVRO)); - keywordMap.put("between", new Integer(SqlParserSymbols.KW_BETWEEN)); - keywordMap.put("bigint", new Integer(SqlParserSymbols.KW_BIGINT)); - keywordMap.put("binary", new Integer(SqlParserSymbols.KW_BINARY)); - keywordMap.put("block_size", new Integer(SqlParserSymbols.KW_BLOCKSIZE)); - keywordMap.put("boolean", new Integer(SqlParserSymbols.KW_BOOLEAN)); - keywordMap.put("by", new Integer(SqlParserSymbols.KW_BY)); - keywordMap.put("cached", new Integer(SqlParserSymbols.KW_CACHED)); - keywordMap.put("case", new Integer(SqlParserSymbols.KW_CASE)); - keywordMap.put("cascade", new Integer(SqlParserSymbols.KW_CASCADE)); - keywordMap.put("cast", new Integer(SqlParserSymbols.KW_CAST)); - keywordMap.put("change", new Integer(SqlParserSymbols.KW_CHANGE)); - keywordMap.put("char", new Integer(SqlParserSymbols.KW_CHAR)); - keywordMap.put("class", new Integer(SqlParserSymbols.KW_CLASS)); - keywordMap.put("close_fn", new Integer(SqlParserSymbols.KW_CLOSE_FN)); - keywordMap.put("column", new Integer(SqlParserSymbols.KW_COLUMN)); - keywordMap.put("columns", new Integer(SqlParserSymbols.KW_COLUMNS)); - keywordMap.put("comment", new Integer(SqlParserSymbols.KW_COMMENT)); - keywordMap.put("compression", new Integer(SqlParserSymbols.KW_COMPRESSION)); - keywordMap.put("compute", new Integer(SqlParserSymbols.KW_COMPUTE)); - keywordMap.put("create", new Integer(SqlParserSymbols.KW_CREATE)); - keywordMap.put("cross", new Integer(SqlParserSymbols.KW_CROSS)); - keywordMap.put("current", new Integer(SqlParserSymbols.KW_CURRENT)); - keywordMap.put("data", new Integer(SqlParserSymbols.KW_DATA)); - keywordMap.put("database", new Integer(SqlParserSymbols.KW_DATABASE)); - keywordMap.put("databases", new Integer(SqlParserSymbols.KW_DATABASES)); - keywordMap.put("date", new Integer(SqlParserSymbols.KW_DATE)); - keywordMap.put("datetime", new Integer(SqlParserSymbols.KW_DATETIME)); - keywordMap.put("decimal", new Integer(SqlParserSymbols.KW_DECIMAL)); - keywordMap.put("default", new Integer(SqlParserSymbols.KW_DEFAULT)); - keywordMap.put("delete", new Integer(SqlParserSymbols.KW_DELETE)); - keywordMap.put("delimited", new Integer(SqlParserSymbols.KW_DELIMITED)); - keywordMap.put("desc", new Integer(SqlParserSymbols.KW_DESC)); - keywordMap.put("describe", new Integer(SqlParserSymbols.KW_DESCRIBE)); - keywordMap.put("distinct", new Integer(SqlParserSymbols.KW_DISTINCT)); - keywordMap.put("div", new Integer(SqlParserSymbols.KW_DIV)); - keywordMap.put("double", new Integer(SqlParserSymbols.KW_DOUBLE)); - keywordMap.put("drop", new Integer(SqlParserSymbols.KW_DROP)); - keywordMap.put("else", new Integer(SqlParserSymbols.KW_ELSE)); - keywordMap.put("encoding", new Integer(SqlParserSymbols.KW_ENCODING)); - keywordMap.put("end", new Integer(SqlParserSymbols.KW_END)); - keywordMap.put("escaped", new Integer(SqlParserSymbols.KW_ESCAPED)); - keywordMap.put("exists", new Integer(SqlParserSymbols.KW_EXISTS)); - keywordMap.put("explain", new Integer(SqlParserSymbols.KW_EXPLAIN)); - keywordMap.put("extended", new Integer(SqlParserSymbols.KW_EXTENDED)); - keywordMap.put("external", new Integer(SqlParserSymbols.KW_EXTERNAL)); - keywordMap.put("false", new Integer(SqlParserSymbols.KW_FALSE)); - keywordMap.put("fields", new Integer(SqlParserSymbols.KW_FIELDS)); - keywordMap.put("fileformat", new Integer(SqlParserSymbols.KW_FILEFORMAT)); - keywordMap.put("files", new Integer(SqlParserSymbols.KW_FILES)); - keywordMap.put("finalize_fn", new Integer(SqlParserSymbols.KW_FINALIZE_FN)); - keywordMap.put("first", new Integer(SqlParserSymbols.KW_FIRST)); - keywordMap.put("float", new Integer(SqlParserSymbols.KW_FLOAT)); - keywordMap.put("following", new Integer(SqlParserSymbols.KW_FOLLOWING)); - keywordMap.put("for", new Integer(SqlParserSymbols.KW_FOR)); - keywordMap.put("format", new Integer(SqlParserSymbols.KW_FORMAT)); - keywordMap.put("formatted", new Integer(SqlParserSymbols.KW_FORMATTED)); - keywordMap.put("from", new Integer(SqlParserSymbols.KW_FROM)); - keywordMap.put("full", new Integer(SqlParserSymbols.KW_FULL)); - keywordMap.put("function", new Integer(SqlParserSymbols.KW_FUNCTION)); - keywordMap.put("functions", new Integer(SqlParserSymbols.KW_FUNCTIONS)); - keywordMap.put("grant", new Integer(SqlParserSymbols.KW_GRANT)); - keywordMap.put("group", new Integer(SqlParserSymbols.KW_GROUP)); - keywordMap.put("hash", new Integer(SqlParserSymbols.KW_HASH)); - keywordMap.put("having", new Integer(SqlParserSymbols.KW_HAVING)); - keywordMap.put("if", new Integer(SqlParserSymbols.KW_IF)); - keywordMap.put("ilike", new Integer(SqlParserSymbols.KW_ILIKE)); - keywordMap.put("ignore", new Integer(SqlParserSymbols.KW_IGNORE)); - keywordMap.put("in", new Integer(SqlParserSymbols.KW_IN)); - keywordMap.put("incremental", new Integer(SqlParserSymbols.KW_INCREMENTAL)); - keywordMap.put("init_fn", new Integer(SqlParserSymbols.KW_INIT_FN)); - keywordMap.put("inner", new Integer(SqlParserSymbols.KW_INNER)); - keywordMap.put("inpath", new Integer(SqlParserSymbols.KW_INPATH)); - keywordMap.put("insert", new Integer(SqlParserSymbols.KW_INSERT)); - keywordMap.put("int", new Integer(SqlParserSymbols.KW_INT)); - keywordMap.put("integer", new Integer(SqlParserSymbols.KW_INT)); - keywordMap.put("intermediate", new Integer(SqlParserSymbols.KW_INTERMEDIATE)); - keywordMap.put("interval", new Integer(SqlParserSymbols.KW_INTERVAL)); - keywordMap.put("into", new Integer(SqlParserSymbols.KW_INTO)); - keywordMap.put("invalidate", new Integer(SqlParserSymbols.KW_INVALIDATE)); - keywordMap.put("iregexp", new Integer(SqlParserSymbols.KW_IREGEXP)); - keywordMap.put("is", new Integer(SqlParserSymbols.KW_IS)); - keywordMap.put("join", new Integer(SqlParserSymbols.KW_JOIN)); - keywordMap.put("kudu", new Integer(SqlParserSymbols.KW_KUDU)); - keywordMap.put("last", new Integer(SqlParserSymbols.KW_LAST)); - keywordMap.put("left", new Integer(SqlParserSymbols.KW_LEFT)); - keywordMap.put("like", new Integer(SqlParserSymbols.KW_LIKE)); - keywordMap.put("limit", new Integer(SqlParserSymbols.KW_LIMIT)); - keywordMap.put("lines", new Integer(SqlParserSymbols.KW_LINES)); - keywordMap.put("load", new Integer(SqlParserSymbols.KW_LOAD)); - keywordMap.put("location", new Integer(SqlParserSymbols.KW_LOCATION)); - keywordMap.put("map", new Integer(SqlParserSymbols.KW_MAP)); - keywordMap.put("merge_fn", new Integer(SqlParserSymbols.KW_MERGE_FN)); - keywordMap.put("metadata", new Integer(SqlParserSymbols.KW_METADATA)); - keywordMap.put("not", new Integer(SqlParserSymbols.KW_NOT)); - keywordMap.put("null", new Integer(SqlParserSymbols.KW_NULL)); - keywordMap.put("nulls", new Integer(SqlParserSymbols.KW_NULLS)); - keywordMap.put("offset", new Integer(SqlParserSymbols.KW_OFFSET)); - keywordMap.put("on", new Integer(SqlParserSymbols.KW_ON)); - keywordMap.put("||", new Integer(SqlParserSymbols.KW_OR)); - keywordMap.put("or", new Integer(SqlParserSymbols.KW_OR)); - keywordMap.put("order", new Integer(SqlParserSymbols.KW_ORDER)); - keywordMap.put("outer", new Integer(SqlParserSymbols.KW_OUTER)); - keywordMap.put("over", new Integer(SqlParserSymbols.KW_OVER)); - keywordMap.put("overwrite", new Integer(SqlParserSymbols.KW_OVERWRITE)); - keywordMap.put("parquet", new Integer(SqlParserSymbols.KW_PARQUET)); - keywordMap.put("parquetfile", new Integer(SqlParserSymbols.KW_PARQUETFILE)); - keywordMap.put("partition", new Integer(SqlParserSymbols.KW_PARTITION)); - keywordMap.put("partitioned", new Integer(SqlParserSymbols.KW_PARTITIONED)); - keywordMap.put("partitions", new Integer(SqlParserSymbols.KW_PARTITIONS)); - keywordMap.put("preceding", new Integer(SqlParserSymbols.KW_PRECEDING)); - keywordMap.put("prepare_fn", new Integer(SqlParserSymbols.KW_PREPARE_FN)); - keywordMap.put("primary", new Integer(SqlParserSymbols.KW_PRIMARY)); - keywordMap.put("produced", new Integer(SqlParserSymbols.KW_PRODUCED)); - keywordMap.put("purge", new Integer(SqlParserSymbols.KW_PURGE)); - keywordMap.put("range", new Integer(SqlParserSymbols.KW_RANGE)); - keywordMap.put("rcfile", new Integer(SqlParserSymbols.KW_RCFILE)); - keywordMap.put("real", new Integer(SqlParserSymbols.KW_DOUBLE)); - keywordMap.put("recover", new Integer(SqlParserSymbols.KW_RECOVER)); - keywordMap.put("refresh", new Integer(SqlParserSymbols.KW_REFRESH)); - keywordMap.put("regexp", new Integer(SqlParserSymbols.KW_REGEXP)); - keywordMap.put("rename", new Integer(SqlParserSymbols.KW_RENAME)); - keywordMap.put("repeatable", new Integer(SqlParserSymbols.KW_REPEATABLE)); - keywordMap.put("replace", new Integer(SqlParserSymbols.KW_REPLACE)); - keywordMap.put("replication", new Integer(SqlParserSymbols.KW_REPLICATION)); - keywordMap.put("restrict", new Integer(SqlParserSymbols.KW_RESTRICT)); - keywordMap.put("returns", new Integer(SqlParserSymbols.KW_RETURNS)); - keywordMap.put("revoke", new Integer(SqlParserSymbols.KW_REVOKE)); - keywordMap.put("right", new Integer(SqlParserSymbols.KW_RIGHT)); - keywordMap.put("rlike", new Integer(SqlParserSymbols.KW_RLIKE)); - keywordMap.put("role", new Integer(SqlParserSymbols.KW_ROLE)); - keywordMap.put("roles", new Integer(SqlParserSymbols.KW_ROLES)); - keywordMap.put("row", new Integer(SqlParserSymbols.KW_ROW)); - keywordMap.put("rows", new Integer(SqlParserSymbols.KW_ROWS)); - keywordMap.put("schema", new Integer(SqlParserSymbols.KW_SCHEMA)); - keywordMap.put("schemas", new Integer(SqlParserSymbols.KW_SCHEMAS)); - keywordMap.put("select", new Integer(SqlParserSymbols.KW_SELECT)); - keywordMap.put("semi", new Integer(SqlParserSymbols.KW_SEMI)); - keywordMap.put("sequencefile", new Integer(SqlParserSymbols.KW_SEQUENCEFILE)); - keywordMap.put("serdeproperties", new Integer(SqlParserSymbols.KW_SERDEPROPERTIES)); - keywordMap.put("serialize_fn", new Integer(SqlParserSymbols.KW_SERIALIZE_FN)); - keywordMap.put("set", new Integer(SqlParserSymbols.KW_SET)); - keywordMap.put("show", new Integer(SqlParserSymbols.KW_SHOW)); - keywordMap.put("smallint", new Integer(SqlParserSymbols.KW_SMALLINT)); - keywordMap.put("sort", new Integer(SqlParserSymbols.KW_SORT)); - keywordMap.put("stats", new Integer(SqlParserSymbols.KW_STATS)); - keywordMap.put("stored", new Integer(SqlParserSymbols.KW_STORED)); - keywordMap.put("straight_join", new Integer(SqlParserSymbols.KW_STRAIGHT_JOIN)); - keywordMap.put("string", new Integer(SqlParserSymbols.KW_STRING)); - keywordMap.put("struct", new Integer(SqlParserSymbols.KW_STRUCT)); - keywordMap.put("symbol", new Integer(SqlParserSymbols.KW_SYMBOL)); - keywordMap.put("table", new Integer(SqlParserSymbols.KW_TABLE)); - keywordMap.put("tables", new Integer(SqlParserSymbols.KW_TABLES)); - keywordMap.put("tablesample", new Integer(SqlParserSymbols.KW_TABLESAMPLE)); - keywordMap.put("tblproperties", new Integer(SqlParserSymbols.KW_TBLPROPERTIES)); - keywordMap.put("terminated", new Integer(SqlParserSymbols.KW_TERMINATED)); - keywordMap.put("textfile", new Integer(SqlParserSymbols.KW_TEXTFILE)); - keywordMap.put("then", new Integer(SqlParserSymbols.KW_THEN)); - keywordMap.put("timestamp", new Integer(SqlParserSymbols.KW_TIMESTAMP)); - keywordMap.put("tinyint", new Integer(SqlParserSymbols.KW_TINYINT)); - keywordMap.put("to", new Integer(SqlParserSymbols.KW_TO)); - keywordMap.put("true", new Integer(SqlParserSymbols.KW_TRUE)); - keywordMap.put("truncate", new Integer(SqlParserSymbols.KW_TRUNCATE)); - keywordMap.put("unbounded", new Integer(SqlParserSymbols.KW_UNBOUNDED)); - keywordMap.put("uncached", new Integer(SqlParserSymbols.KW_UNCACHED)); - keywordMap.put("union", new Integer(SqlParserSymbols.KW_UNION)); - keywordMap.put("update", new Integer(SqlParserSymbols.KW_UPDATE)); - keywordMap.put("update_fn", new Integer(SqlParserSymbols.KW_UPDATE_FN)); - keywordMap.put("upsert", new Integer(SqlParserSymbols.KW_UPSERT)); - keywordMap.put("use", new Integer(SqlParserSymbols.KW_USE)); - keywordMap.put("using", new Integer(SqlParserSymbols.KW_USING)); - keywordMap.put("values", new Integer(SqlParserSymbols.KW_VALUES)); - keywordMap.put("varchar", new Integer(SqlParserSymbols.KW_VARCHAR)); - keywordMap.put("view", new Integer(SqlParserSymbols.KW_VIEW)); - keywordMap.put("when", new Integer(SqlParserSymbols.KW_WHEN)); - keywordMap.put("where", new Integer(SqlParserSymbols.KW_WHERE)); - keywordMap.put("with", new Integer(SqlParserSymbols.KW_WITH)); - } - + static Map<String, Integer> keywordMap; + // Reserved words are words that cannot be used as identifiers. It is a superset of + // keywords. + static Set<String> reservedWords; // map from token id to token description - public static final Map<Integer, String> tokenIdMap = - new HashMap<Integer, String>(); - static { - Iterator<Map.Entry<String, Integer>> it = keywordMap.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry<String, Integer> pairs = (Map.Entry<String, Integer>) it.next(); - tokenIdMap.put(pairs.getValue(), pairs.getKey().toUpperCase()); + static HashMap<Integer, String> tokenIdMap; + + public static void init(TReservedWordsVersion reservedWordsVersion) { + // initilize keywords + keywordMap = new LinkedHashMap<>(); + keywordMap.put("&&", SqlParserSymbols.KW_AND); + keywordMap.put("add", SqlParserSymbols.KW_ADD); + keywordMap.put("aggregate", SqlParserSymbols.KW_AGGREGATE); + keywordMap.put("all", SqlParserSymbols.KW_ALL); + keywordMap.put("alter", SqlParserSymbols.KW_ALTER); + keywordMap.put("analytic", SqlParserSymbols.KW_ANALYTIC); + keywordMap.put("and", SqlParserSymbols.KW_AND); + keywordMap.put("anti", SqlParserSymbols.KW_ANTI); + keywordMap.put("api_version", SqlParserSymbols.KW_API_VERSION); + keywordMap.put("array", SqlParserSymbols.KW_ARRAY); + keywordMap.put("as", SqlParserSymbols.KW_AS); + keywordMap.put("asc", SqlParserSymbols.KW_ASC); + keywordMap.put("avro", SqlParserSymbols.KW_AVRO); + keywordMap.put("between", SqlParserSymbols.KW_BETWEEN); + keywordMap.put("bigint", SqlParserSymbols.KW_BIGINT); + keywordMap.put("binary", SqlParserSymbols.KW_BINARY); + keywordMap.put("block_size", SqlParserSymbols.KW_BLOCKSIZE); + keywordMap.put("boolean", SqlParserSymbols.KW_BOOLEAN); + keywordMap.put("by", SqlParserSymbols.KW_BY); + keywordMap.put("cached", SqlParserSymbols.KW_CACHED); + keywordMap.put("case", SqlParserSymbols.KW_CASE); + keywordMap.put("cascade", SqlParserSymbols.KW_CASCADE); + keywordMap.put("cast", SqlParserSymbols.KW_CAST); + keywordMap.put("change", SqlParserSymbols.KW_CHANGE); + keywordMap.put("char", SqlParserSymbols.KW_CHAR); + keywordMap.put("class", SqlParserSymbols.KW_CLASS); + keywordMap.put("close_fn", SqlParserSymbols.KW_CLOSE_FN); + keywordMap.put("column", SqlParserSymbols.KW_COLUMN); + keywordMap.put("columns", SqlParserSymbols.KW_COLUMNS); + keywordMap.put("comment", SqlParserSymbols.KW_COMMENT); + keywordMap.put("compression", SqlParserSymbols.KW_COMPRESSION); + keywordMap.put("compute", SqlParserSymbols.KW_COMPUTE); + keywordMap.put("create", SqlParserSymbols.KW_CREATE); + keywordMap.put("cross", SqlParserSymbols.KW_CROSS); + keywordMap.put("current", SqlParserSymbols.KW_CURRENT); + keywordMap.put("data", SqlParserSymbols.KW_DATA); + keywordMap.put("database", SqlParserSymbols.KW_DATABASE); + keywordMap.put("databases", SqlParserSymbols.KW_DATABASES); + keywordMap.put("date", SqlParserSymbols.KW_DATE); + keywordMap.put("datetime", SqlParserSymbols.KW_DATETIME); + keywordMap.put("decimal", SqlParserSymbols.KW_DECIMAL); + keywordMap.put("default", SqlParserSymbols.KW_DEFAULT); + keywordMap.put("delete", SqlParserSymbols.KW_DELETE); + keywordMap.put("delimited", SqlParserSymbols.KW_DELIMITED); + keywordMap.put("desc", SqlParserSymbols.KW_DESC); + keywordMap.put("describe", SqlParserSymbols.KW_DESCRIBE); + keywordMap.put("distinct", SqlParserSymbols.KW_DISTINCT); + keywordMap.put("div", SqlParserSymbols.KW_DIV); + keywordMap.put("double", SqlParserSymbols.KW_DOUBLE); + keywordMap.put("drop", SqlParserSymbols.KW_DROP); + keywordMap.put("else", SqlParserSymbols.KW_ELSE); + keywordMap.put("encoding", SqlParserSymbols.KW_ENCODING); + keywordMap.put("end", SqlParserSymbols.KW_END); + keywordMap.put("escaped", SqlParserSymbols.KW_ESCAPED); + keywordMap.put("exists", SqlParserSymbols.KW_EXISTS); + keywordMap.put("explain", SqlParserSymbols.KW_EXPLAIN); + keywordMap.put("extended", SqlParserSymbols.KW_EXTENDED); + keywordMap.put("external", SqlParserSymbols.KW_EXTERNAL); + keywordMap.put("false", SqlParserSymbols.KW_FALSE); + keywordMap.put("fields", SqlParserSymbols.KW_FIELDS); + keywordMap.put("fileformat", SqlParserSymbols.KW_FILEFORMAT); + keywordMap.put("files", SqlParserSymbols.KW_FILES); + keywordMap.put("finalize_fn", SqlParserSymbols.KW_FINALIZE_FN); + keywordMap.put("first", SqlParserSymbols.KW_FIRST); + keywordMap.put("float", SqlParserSymbols.KW_FLOAT); + keywordMap.put("following", SqlParserSymbols.KW_FOLLOWING); + keywordMap.put("for", SqlParserSymbols.KW_FOR); + keywordMap.put("format", SqlParserSymbols.KW_FORMAT); + keywordMap.put("formatted", SqlParserSymbols.KW_FORMATTED); + keywordMap.put("from", SqlParserSymbols.KW_FROM); + keywordMap.put("full", SqlParserSymbols.KW_FULL); + keywordMap.put("function", SqlParserSymbols.KW_FUNCTION); + keywordMap.put("functions", SqlParserSymbols.KW_FUNCTIONS); + keywordMap.put("grant", SqlParserSymbols.KW_GRANT); + keywordMap.put("group", SqlParserSymbols.KW_GROUP); + keywordMap.put("hash", SqlParserSymbols.KW_HASH); + keywordMap.put("having", SqlParserSymbols.KW_HAVING); + keywordMap.put("if", SqlParserSymbols.KW_IF); + keywordMap.put("ilike", SqlParserSymbols.KW_ILIKE); + keywordMap.put("ignore", SqlParserSymbols.KW_IGNORE); + keywordMap.put("in", SqlParserSymbols.KW_IN); + keywordMap.put("incremental", SqlParserSymbols.KW_INCREMENTAL); + keywordMap.put("init_fn", SqlParserSymbols.KW_INIT_FN); + keywordMap.put("inner", SqlParserSymbols.KW_INNER); + keywordMap.put("inpath", SqlParserSymbols.KW_INPATH); + keywordMap.put("insert", SqlParserSymbols.KW_INSERT); + keywordMap.put("int", SqlParserSymbols.KW_INT); + keywordMap.put("integer", SqlParserSymbols.KW_INT); + keywordMap.put("intermediate", SqlParserSymbols.KW_INTERMEDIATE); + keywordMap.put("interval", SqlParserSymbols.KW_INTERVAL); + keywordMap.put("into", SqlParserSymbols.KW_INTO); + keywordMap.put("invalidate", SqlParserSymbols.KW_INVALIDATE); + keywordMap.put("iregexp", SqlParserSymbols.KW_IREGEXP); + keywordMap.put("is", SqlParserSymbols.KW_IS); + keywordMap.put("join", SqlParserSymbols.KW_JOIN); + keywordMap.put("kudu", SqlParserSymbols.KW_KUDU); + keywordMap.put("last", SqlParserSymbols.KW_LAST); + keywordMap.put("left", SqlParserSymbols.KW_LEFT); + keywordMap.put("like", SqlParserSymbols.KW_LIKE); + keywordMap.put("limit", SqlParserSymbols.KW_LIMIT); + keywordMap.put("lines", SqlParserSymbols.KW_LINES); + keywordMap.put("load", SqlParserSymbols.KW_LOAD); + keywordMap.put("location", SqlParserSymbols.KW_LOCATION); + keywordMap.put("map", SqlParserSymbols.KW_MAP); + keywordMap.put("merge_fn", SqlParserSymbols.KW_MERGE_FN); + keywordMap.put("metadata", SqlParserSymbols.KW_METADATA); + keywordMap.put("not", SqlParserSymbols.KW_NOT); + keywordMap.put("null", SqlParserSymbols.KW_NULL); + keywordMap.put("nulls", SqlParserSymbols.KW_NULLS); + keywordMap.put("offset", SqlParserSymbols.KW_OFFSET); + keywordMap.put("on", SqlParserSymbols.KW_ON); + keywordMap.put("||", SqlParserSymbols.KW_OR); + keywordMap.put("or", SqlParserSymbols.KW_OR); + keywordMap.put("order", SqlParserSymbols.KW_ORDER); + keywordMap.put("outer", SqlParserSymbols.KW_OUTER); + keywordMap.put("over", SqlParserSymbols.KW_OVER); + keywordMap.put("overwrite", SqlParserSymbols.KW_OVERWRITE); + keywordMap.put("parquet", SqlParserSymbols.KW_PARQUET); + keywordMap.put("parquetfile", SqlParserSymbols.KW_PARQUETFILE); + keywordMap.put("partition", SqlParserSymbols.KW_PARTITION); + keywordMap.put("partitioned", SqlParserSymbols.KW_PARTITIONED); + keywordMap.put("partitions", SqlParserSymbols.KW_PARTITIONS); + keywordMap.put("preceding", SqlParserSymbols.KW_PRECEDING); + keywordMap.put("prepare_fn", SqlParserSymbols.KW_PREPARE_FN); + keywordMap.put("primary", SqlParserSymbols.KW_PRIMARY); + keywordMap.put("produced", SqlParserSymbols.KW_PRODUCED); + keywordMap.put("purge", SqlParserSymbols.KW_PURGE); + keywordMap.put("range", SqlParserSymbols.KW_RANGE); + keywordMap.put("rcfile", SqlParserSymbols.KW_RCFILE); + keywordMap.put("real", SqlParserSymbols.KW_DOUBLE); + keywordMap.put("recover", SqlParserSymbols.KW_RECOVER); + keywordMap.put("refresh", SqlParserSymbols.KW_REFRESH); + keywordMap.put("regexp", SqlParserSymbols.KW_REGEXP); + keywordMap.put("rename", SqlParserSymbols.KW_RENAME); + keywordMap.put("repeatable", SqlParserSymbols.KW_REPEATABLE); + keywordMap.put("replace", SqlParserSymbols.KW_REPLACE); + keywordMap.put("replication", SqlParserSymbols.KW_REPLICATION); + keywordMap.put("restrict", SqlParserSymbols.KW_RESTRICT); + keywordMap.put("returns", SqlParserSymbols.KW_RETURNS); + keywordMap.put("revoke", SqlParserSymbols.KW_REVOKE); + keywordMap.put("right", SqlParserSymbols.KW_RIGHT); + keywordMap.put("rlike", SqlParserSymbols.KW_RLIKE); + keywordMap.put("role", SqlParserSymbols.KW_ROLE); + keywordMap.put("roles", SqlParserSymbols.KW_ROLES); + keywordMap.put("row", SqlParserSymbols.KW_ROW); + keywordMap.put("rows", SqlParserSymbols.KW_ROWS); + keywordMap.put("schema", SqlParserSymbols.KW_SCHEMA); + keywordMap.put("schemas", SqlParserSymbols.KW_SCHEMAS); + keywordMap.put("select", SqlParserSymbols.KW_SELECT); + keywordMap.put("semi", SqlParserSymbols.KW_SEMI); + keywordMap.put("sequencefile", SqlParserSymbols.KW_SEQUENCEFILE); + keywordMap.put("serdeproperties", SqlParserSymbols.KW_SERDEPROPERTIES); + keywordMap.put("serialize_fn", SqlParserSymbols.KW_SERIALIZE_FN); + keywordMap.put("set", SqlParserSymbols.KW_SET); + keywordMap.put("show", SqlParserSymbols.KW_SHOW); + keywordMap.put("smallint", SqlParserSymbols.KW_SMALLINT); + keywordMap.put("sort", SqlParserSymbols.KW_SORT); + keywordMap.put("stats", SqlParserSymbols.KW_STATS); + keywordMap.put("stored", SqlParserSymbols.KW_STORED); + keywordMap.put("straight_join", SqlParserSymbols.KW_STRAIGHT_JOIN); + keywordMap.put("string", SqlParserSymbols.KW_STRING); + keywordMap.put("struct", SqlParserSymbols.KW_STRUCT); + keywordMap.put("symbol", SqlParserSymbols.KW_SYMBOL); + keywordMap.put("table", SqlParserSymbols.KW_TABLE); + keywordMap.put("tables", SqlParserSymbols.KW_TABLES); + keywordMap.put("tablesample", SqlParserSymbols.KW_TABLESAMPLE); + keywordMap.put("tblproperties", SqlParserSymbols.KW_TBLPROPERTIES); + keywordMap.put("terminated", SqlParserSymbols.KW_TERMINATED); + keywordMap.put("textfile", SqlParserSymbols.KW_TEXTFILE); + keywordMap.put("then", SqlParserSymbols.KW_THEN); + keywordMap.put("timestamp", SqlParserSymbols.KW_TIMESTAMP); + keywordMap.put("tinyint", SqlParserSymbols.KW_TINYINT); + keywordMap.put("to", SqlParserSymbols.KW_TO); + keywordMap.put("true", SqlParserSymbols.KW_TRUE); + keywordMap.put("truncate", SqlParserSymbols.KW_TRUNCATE); + keywordMap.put("unbounded", SqlParserSymbols.KW_UNBOUNDED); + keywordMap.put("uncached", SqlParserSymbols.KW_UNCACHED); + keywordMap.put("union", SqlParserSymbols.KW_UNION); + keywordMap.put("unknown", SqlParserSymbols.KW_UNKNOWN); + keywordMap.put("update", SqlParserSymbols.KW_UPDATE); + keywordMap.put("update_fn", SqlParserSymbols.KW_UPDATE_FN); + keywordMap.put("upsert", SqlParserSymbols.KW_UPSERT); + keywordMap.put("use", SqlParserSymbols.KW_USE); + keywordMap.put("using", SqlParserSymbols.KW_USING); + keywordMap.put("values", SqlParserSymbols.KW_VALUES); + keywordMap.put("varchar", SqlParserSymbols.KW_VARCHAR); + keywordMap.put("view", SqlParserSymbols.KW_VIEW); + keywordMap.put("when", SqlParserSymbols.KW_WHEN); + keywordMap.put("where", SqlParserSymbols.KW_WHERE); + keywordMap.put("with", SqlParserSymbols.KW_WITH); + + // Initilize tokenIdMap for error reporting + tokenIdMap = new HashMap<>(); + for (Map.Entry<String, Integer> entry : keywordMap.entrySet()) { + tokenIdMap.put(entry.getValue(), entry.getKey().toUpperCase()); } - // add non-keyword tokens - tokenIdMap.put(new Integer(SqlParserSymbols.IDENT), "IDENTIFIER"); - tokenIdMap.put(new Integer(SqlParserSymbols.COLON), ":"); - tokenIdMap.put(new Integer(SqlParserSymbols.SEMICOLON), ";"); - tokenIdMap.put(new Integer(SqlParserSymbols.COMMA), "COMMA"); - tokenIdMap.put(new Integer(SqlParserSymbols.BITNOT), "~"); - tokenIdMap.put(new Integer(SqlParserSymbols.LPAREN), "("); - tokenIdMap.put(new Integer(SqlParserSymbols.RPAREN), ")"); - tokenIdMap.put(new Integer(SqlParserSymbols.LBRACKET), "["); - tokenIdMap.put(new Integer(SqlParserSymbols.RBRACKET), "]"); - tokenIdMap.put(new Integer(SqlParserSymbols.DECIMAL_LITERAL), "DECIMAL LITERAL"); - tokenIdMap.put(new Integer(SqlParserSymbols.INTEGER_LITERAL), "INTEGER LITERAL"); - tokenIdMap.put(new Integer(SqlParserSymbols.NOT), "!"); - tokenIdMap.put(new Integer(SqlParserSymbols.LESSTHAN), "<"); - tokenIdMap.put(new Integer(SqlParserSymbols.GREATERTHAN), ">"); - tokenIdMap.put(new Integer(SqlParserSymbols.UNMATCHED_STRING_LITERAL), - "UNMATCHED STRING LITERAL"); - tokenIdMap.put(new Integer(SqlParserSymbols.MOD), "%"); - tokenIdMap.put(new Integer(SqlParserSymbols.ADD), "+"); - tokenIdMap.put(new Integer(SqlParserSymbols.DIVIDE), "/"); - tokenIdMap.put(new Integer(SqlParserSymbols.EQUAL), "="); - tokenIdMap.put(new Integer(SqlParserSymbols.STAR), "*"); - tokenIdMap.put(new Integer(SqlParserSymbols.BITOR), "|"); - tokenIdMap.put(new Integer(SqlParserSymbols.DOT), "."); - tokenIdMap.put(new Integer(SqlParserSymbols.DOTDOTDOT), "..."); - tokenIdMap.put(new Integer(SqlParserSymbols.STRING_LITERAL), "STRING LITERAL"); - tokenIdMap.put(new Integer(SqlParserSymbols.EOF), "EOF"); - tokenIdMap.put(new Integer(SqlParserSymbols.SUBTRACT), "-"); - tokenIdMap.put(new Integer(SqlParserSymbols.BITAND), "&"); - tokenIdMap.put(new Integer(SqlParserSymbols.UNEXPECTED_CHAR), "Unexpected character"); - tokenIdMap.put(new Integer(SqlParserSymbols.BITXOR), "^"); - tokenIdMap.put(new Integer(SqlParserSymbols.NUMERIC_OVERFLOW), "NUMERIC OVERFLOW"); - tokenIdMap.put(new Integer(SqlParserSymbols.EMPTY_IDENT), "EMPTY IDENTIFIER"); + tokenIdMap.put(SqlParserSymbols.IDENT, "IDENTIFIER"); + tokenIdMap.put(SqlParserSymbols.COLON, ":"); + tokenIdMap.put(SqlParserSymbols.SEMICOLON, ";"); + tokenIdMap.put(SqlParserSymbols.COMMA, "COMMA"); + tokenIdMap.put(SqlParserSymbols.BITNOT, "~"); + tokenIdMap.put(SqlParserSymbols.LPAREN, "("); + tokenIdMap.put(SqlParserSymbols.RPAREN, ")"); + tokenIdMap.put(SqlParserSymbols.LBRACKET, "["); + tokenIdMap.put(SqlParserSymbols.RBRACKET, "]"); + tokenIdMap.put(SqlParserSymbols.DECIMAL_LITERAL, "DECIMAL LITERAL"); + tokenIdMap.put(SqlParserSymbols.INTEGER_LITERAL, "INTEGER LITERAL"); + tokenIdMap.put(SqlParserSymbols.NOT, "!"); + tokenIdMap.put(SqlParserSymbols.LESSTHAN, "<"); + tokenIdMap.put(SqlParserSymbols.GREATERTHAN, ">"); + tokenIdMap.put(SqlParserSymbols.UNMATCHED_STRING_LITERAL, "UNMATCHED STRING LITERAL"); + tokenIdMap.put(SqlParserSymbols.MOD, "%"); + tokenIdMap.put(SqlParserSymbols.ADD, "+"); + tokenIdMap.put(SqlParserSymbols.DIVIDE, "/"); + tokenIdMap.put(SqlParserSymbols.EQUAL, "="); + tokenIdMap.put(SqlParserSymbols.STAR, "*"); + tokenIdMap.put(SqlParserSymbols.BITOR, "|"); + tokenIdMap.put(SqlParserSymbols.DOT, "."); + tokenIdMap.put(SqlParserSymbols.DOTDOTDOT, "..."); + tokenIdMap.put(SqlParserSymbols.STRING_LITERAL, "STRING LITERAL"); + tokenIdMap.put(SqlParserSymbols.EOF, "EOF"); + tokenIdMap.put(SqlParserSymbols.SUBTRACT, "-"); + tokenIdMap.put(SqlParserSymbols.BITAND, "&"); + tokenIdMap.put(SqlParserSymbols.UNEXPECTED_CHAR, "Unexpected character"); + tokenIdMap.put(SqlParserSymbols.BITXOR, "^"); + tokenIdMap.put(SqlParserSymbols.NUMERIC_OVERFLOW, "NUMERIC OVERFLOW"); + tokenIdMap.put(SqlParserSymbols.EMPTY_IDENT, "EMPTY IDENTIFIER"); + + // Initilize reservedWords. For impala 2.11, reserved words = keywords. + if (reservedWordsVersion == TReservedWordsVersion.IMPALA_2_11) { + reservedWords = keywordMap.keySet(); + return; + } + // For impala 3.0, reserved words = keywords + sql16ReservedWords - builtinFunctions + // - whitelist + // unused reserved words = reserved words - keywords. These words are reserved for + // forward compatibility purposes. + reservedWords = new HashSet<>(keywordMap.keySet()); + // Add SQL:2016 reserved words + reservedWords.addAll(Arrays.asList(new String[] { + "abs", "acos", "allocate", "any", "are", "array_agg", "array_max_cardinality", + "asensitive", "asin", "asymmetric", "at", "atan", "atomic", "authorization", + "avg", "begin", "begin_frame", "begin_partition", "blob", "both", "call", + "called", "cardinality", "cascaded", "ceil", "ceiling", "char_length", + "character", "character_length", "check", "classifier", "clob", "close", + "coalesce", "collate", "collect", "commit", "condition", "connect", "constraint", + "contains", "convert", "copy", "corr", "corresponding", "cos", "cosh", "count", + "covar_pop", "covar_samp", "cube", "cume_dist", "current_catalog", "current_date", + "current_default_transform_group", "current_path", "current_path", "current_role", + "current_role", "current_row", "current_schema", "current_time", + "current_timestamp", "current_transform_group_for_type", "current_user", "cursor", + "cycle", "day", "deallocate", "dec", "decfloat", "declare", "define", + "dense_rank", "deref", "deterministic", "disconnect", "dynamic", "each", + "element", "empty", "end-exec", "end_frame", "end_partition", "equals", "escape", + "every", "except", "exec", "execute", "exp", "extract", "fetch", "filter", + "first_value", "floor", "foreign", "frame_row", "free", "fusion", "get", "global", + "grouping", "groups", "hold", "hour", "identity", "indicator", "initial", "inout", + "insensitive", "integer", "intersect", "intersection", "json_array", + "json_arrayagg", "json_exists", "json_object", "json_objectagg", "json_query", + "json_table", "json_table_primitive", "json_value", "lag", "language", "large", + "last_value", "lateral", "lead", "leading", "like_regex", "listagg", "ln", + "local", "localtime", "localtimestamp", "log", "log10 ", "lower", "match", + "match_number", "match_recognize", "matches", "max", "member", "merge", "method", + "min", "minute", "mod", "modifies", "module", "month", "multiset", "national", + "natural", "nchar", "nclob", "new", "no", "none", "normalize", "nth_value", + "ntile", "nullif", "numeric", "occurrences_regex", "octet_length", "of", "old", + "omit", "one", "only", "open", "out", "overlaps", "overlay", "parameter", + "pattern", "per", "percent", "percent_rank", "percentile_cont", "percentile_disc", + "period", "portion", "position", "position_regex", "power", "precedes", + "precision", "prepare", "procedure", "ptf", "rank", "reads", "real", "recursive", + "ref", "references", "referencing", "regr_avgx", "regr_avgy", "regr_count", + "regr_intercept", "regr_r2", "regr_slope", "regr_sxx", "regr_sxy", "regr_syy", + "release", "result", "return", "rollback", "rollup", "row_number", "running", + "savepoint", "scope", "scroll", "search", "second", "seek", "sensitive", + "session_user", "similar", "sin", "sinh", "skip", "some", "specific", + "specifictype", "sql", "sqlexception", "sqlstate", "sqlwarning", "sqrt", "start", + "static", "stddev_pop", "stddev_samp", "submultiset", "subset", "substring", + "substring_regex", "succeeds", "sum", "symmetric", "system", "system_time", + "system_user", "tan", "tanh", "time", "timezone_hour", "timezone_minute", + "trailing", "translate", "translate_regex", "translation", "treat", "trigger", + "trim", "trim_array", "uescape", "unique", "unknown", "unnest", "update ", + "upper", "user", "value", "value_of", "var_pop", "var_samp", "varbinary", + "varying", "versioning", "whenever", "width_bucket", "window", "within", + "without", "year"})); + // Remove impala builtin function names + reservedWords.removeAll(new BuiltinsDb(BUILTINS_DB).getAllFunctions().keySet()); + // Remove whitelist words. These words might be heavily used in production, and + // impala is unlikely to implement SQL features around these words in the near future. + reservedWords.removeAll(Arrays.asList(new String[] { + // time units + "year", "month", "day", "hour", "minute", "second", + "begin", "call", "check", "classifier", "close", "identity", "language", + "localtime", "member", "module", "new", "nullif", "old", "open", "parameter", + "period", "result", "return", "sql", "start", "system", "time", "user", "value" + })); } - public static boolean isKeyword(Integer tokenId) { - String token = tokenIdMap.get(tokenId); - if (token == null) return false; - return keywordMap.containsKey(token.toLowerCase()); + static { + // Default-initilize the static members for FE tests. Outside of FE tests, init() is + // called again in BackendConfig.create() once the backend configuration is passed to + // the FE, overwriting this initilization. + init(TReservedWordsVersion.IMPALA_3_0); } - public static boolean isKeyword(String ident) { - return keywordMap.containsKey(ident.toLowerCase()); + static boolean isReserved(String token) { + return reservedWords.contains(token.toLowerCase()); + } + + static boolean isKeyword(Integer tokenId) { + String token = tokenIdMap.get(tokenId); + return token != null && keywordMap.containsKey(token.toLowerCase()); } private Symbol newToken(int id, Object value) { @@ -384,23 +463,19 @@ EndOfLineComment = "--" !({HintContent}|{ContainsLineTerminator}) {LineTerminato // The rules for IntegerLiteral and DecimalLiteral are the same, but it is useful // to distinguish them, e.g., so the Parser can use integer literals without analysis. {IntegerLiteral} { - BigDecimal val = null; try { - val = new BigDecimal(yytext()); + return newToken(SqlParserSymbols.INTEGER_LITERAL, new BigDecimal(yytext())); } catch (NumberFormatException e) { return newToken(SqlParserSymbols.NUMERIC_OVERFLOW, yytext()); } - return newToken(SqlParserSymbols.INTEGER_LITERAL, val); } {DecimalLiteral} { - BigDecimal val = null; try { - val = new BigDecimal(yytext()); + return newToken(SqlParserSymbols.DECIMAL_LITERAL, new BigDecimal(yytext())); } catch (NumberFormatException e) { return newToken(SqlParserSymbols.NUMERIC_OVERFLOW, yytext()); } - return newToken(SqlParserSymbols.DECIMAL_LITERAL, val); } {QuotedIdentifier} { @@ -416,7 +491,9 @@ EndOfLineComment = "--" !({HintContent}|{ContainsLineTerminator}) {LineTerminato String text = yytext(); Integer kw_id = keywordMap.get(text.toLowerCase()); if (kw_id != null) { - return newToken(kw_id.intValue(), text); + return newToken(kw_id, text); + } else if (isReserved(text)) { + return newToken(SqlParserSymbols.UNUSED_RESERVED_WORD, text); } else { return newToken(SqlParserSymbols.IDENT, text); } http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java ---------------------------------------------------------------------- diff --git a/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java b/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java index 4124493..1c02306 100644 --- a/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java +++ b/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java @@ -1276,12 +1276,10 @@ public class AnalyzeDDLTest extends FrontendTestBase { // Test tablesample clause with extrapolation enabled/disabled. Replace/restore the // static backend config for this test to control stats extrapolation. - BackendConfig origInstance = BackendConfig.INSTANCE; + TBackendGflags gflags = BackendConfig.INSTANCE.getBackendCfg(); + boolean origEnableStatsExtrapolation = gflags.isEnable_stats_extrapolation(); try { - TBackendGflags testGflags = new TBackendGflags(); - testGflags.setEnable_stats_extrapolation(true); - BackendConfig.create(testGflags); - + gflags.setEnable_stats_extrapolation(true); // Test different COMPUTE_STATS_MIN_SAMPLE_BYTES. TQueryOptions queryOpts = new TQueryOptions(); @@ -1346,13 +1344,12 @@ public class AnalyzeDDLTest extends FrontendTestBase { "compute stats functional.alltypes_datasource tablesample system (3)", "TABLESAMPLE is only supported on HDFS tables."); - testGflags.setEnable_stats_extrapolation(false); - BackendConfig.create(testGflags); + gflags.setEnable_stats_extrapolation(false); AnalysisError("compute stats functional.alltypes tablesample system (10)", "COMPUTE STATS TABLESAMPLE requires --enable_stats_extrapolation=true. " + "Stats extrapolation is currently disabled."); } finally { - BackendConfig.INSTANCE = origInstance; + gflags.setEnable_stats_extrapolation(origEnableStatsExtrapolation); } } http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/test/java/org/apache/impala/analysis/AnalyzeStmtsTest.java ---------------------------------------------------------------------- diff --git a/fe/src/test/java/org/apache/impala/analysis/AnalyzeStmtsTest.java b/fe/src/test/java/org/apache/impala/analysis/AnalyzeStmtsTest.java index d3311ba..65639b2 100644 --- a/fe/src/test/java/org/apache/impala/analysis/AnalyzeStmtsTest.java +++ b/fe/src/test/java/org/apache/impala/analysis/AnalyzeStmtsTest.java @@ -1048,11 +1048,11 @@ public class AnalyzeStmtsTest extends AnalyzerTest { AnalysisError("select sum(id) over(order by id) from functional.alltypes having 1", "HAVING clause must not contain analytic expressions: " + "sum(id) OVER (ORDER BY id ASC)"); - AnalyzesOk("with w_test as (select '1' as one, 2 as two, '3' as three) " + - "select one as one, substring(cast(two as string), 1, 1) as two, " + + AnalyzesOk("with w_test as (select '1' as `one`, 2 as two, '3' as three) " + + "select `one` as `one`, substring(cast(two as string), 1, 1) as two, " + "three as three, count(1) as cnt " + "from w_test " + - "group by one, substring(cast(two as string), 1, 1), three"); + "group by `one`, substring(cast(two as string), 1, 1), three"); // Constant exprs should not be interpreted as ordinals AnalyzesOk("select int_col, count(*) from functional.alltypes group by 1, 1 * 2"); AnalyzesOk("select int_col, bigint_col from functional.alltypes order by 1 + 4"); http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/test/java/org/apache/impala/analysis/ToSqlTest.java ---------------------------------------------------------------------- diff --git a/fe/src/test/java/org/apache/impala/analysis/ToSqlTest.java b/fe/src/test/java/org/apache/impala/analysis/ToSqlTest.java index 2b9da03..41124f5 100644 --- a/fe/src/test/java/org/apache/impala/analysis/ToSqlTest.java +++ b/fe/src/test/java/org/apache/impala/analysis/ToSqlTest.java @@ -19,13 +19,13 @@ package org.apache.impala.analysis; import static org.junit.Assert.fail; -import org.junit.Ignore; -import org.junit.Test; - import org.apache.impala.authorization.AuthorizationConfig; import org.apache.impala.common.AnalysisException; import org.apache.impala.common.FrontendTestBase; import org.apache.impala.testutil.TestUtils; +import org.junit.Ignore; +import org.junit.Test; + import com.google.common.base.Preconditions; // TODO: Expand this test, in particular, because view creation relies @@ -584,9 +584,9 @@ public class ToSqlTest extends FrontendTestBase { // Table hint testToSql(String.format( - "select * from functional.alltypes at %sschedule_random_replica%s", prefix, + "select * from functional.alltypes atp %sschedule_random_replica%s", prefix, suffix), - "SELECT * FROM functional.alltypes at\n-- +schedule_random_replica\n"); + "SELECT * FROM functional.alltypes atp\n-- +schedule_random_replica\n"); testToSql(String.format( "select * from functional.alltypes %sschedule_random_replica%s", prefix, suffix), @@ -597,9 +597,9 @@ public class ToSqlTest extends FrontendTestBase { "SELECT * FROM functional.alltypes\n-- +schedule_random_replica," + "schedule_disk_local\n"); testToSql(String.format( - "select c1 from (select at.tinyint_col as c1 from functional.alltypes at " + + "select c1 from (select atp.tinyint_col as c1 from functional.alltypes atp " + "%sschedule_random_replica%s) s1", prefix, suffix), - "SELECT c1 FROM (SELECT at.tinyint_col c1 FROM functional.alltypes at\n-- +" + + "SELECT c1 FROM (SELECT atp.tinyint_col c1 FROM functional.alltypes atp\n-- +" + "schedule_random_replica\n) s1"); // Select-list hint. The legacy-style hint has no prefix and suffix. http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/test/java/org/apache/impala/catalog/CatalogTest.java ---------------------------------------------------------------------- diff --git a/fe/src/test/java/org/apache/impala/catalog/CatalogTest.java b/fe/src/test/java/org/apache/impala/catalog/CatalogTest.java index e6b71cd..9486a7f 100644 --- a/fe/src/test/java/org/apache/impala/catalog/CatalogTest.java +++ b/fe/src/test/java/org/apache/impala/catalog/CatalogTest.java @@ -24,8 +24,8 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.ArrayList; -import java.util.HashMap; import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; @@ -33,15 +33,14 @@ import java.util.Set; import org.apache.commons.codec.binary.Base64; import org.apache.hadoop.hive.metastore.TableType; import org.apache.hadoop.hive.metastore.api.ColumnStatisticsData; -import org.junit.Test; - import org.apache.impala.analysis.FunctionName; -import org.apache.impala.analysis.HdfsUri; import org.apache.impala.analysis.LiteralExpr; import org.apache.impala.analysis.NumericLiteral; import org.apache.impala.catalog.MetaStoreClientPool.MetaStoreClient; import org.apache.impala.testutil.CatalogServiceTestCatalog; import org.apache.impala.thrift.TFunctionBinaryType; +import org.junit.Test; + import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -623,9 +622,8 @@ public class CatalogTest { dbParams.put(badFnKey, badFnVal); Db db = catalog_.getDb(dbName); assertEquals(db, null); - db = new Db(dbName, catalog_, - new org.apache.hadoop.hive.metastore.api.Database(dbName, - "", "", dbParams)); + db = new Db(dbName, + new org.apache.hadoop.hive.metastore.api.Database(dbName, "", "", dbParams)); catalog_.addDb(db); db = catalog_.getDb(dbName); assertTrue(db != null); http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/test/java/org/apache/impala/common/FrontendTestBase.java ---------------------------------------------------------------------- diff --git a/fe/src/test/java/org/apache/impala/common/FrontendTestBase.java b/fe/src/test/java/org/apache/impala/common/FrontendTestBase.java index 49b1f6b..c087f5a 100644 --- a/fe/src/test/java/org/apache/impala/common/FrontendTestBase.java +++ b/fe/src/test/java/org/apache/impala/common/FrontendTestBase.java @@ -153,7 +153,7 @@ public class FrontendTestBase { protected Db addTestDb(String dbName, String comment) { Db db = catalog_.getDb(dbName); Preconditions.checkState(db == null, "Test db must not already exist."); - db = new Db(dbName, catalog_, new org.apache.hadoop.hive.metastore.api.Database( + db = new Db(dbName, new org.apache.hadoop.hive.metastore.api.Database( dbName, comment, "", Collections.<String, String>emptyMap())); catalog_.addDb(db); testDbs_.add(db); http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/test/java/org/apache/impala/planner/StatsExtrapolationTest.java ---------------------------------------------------------------------- diff --git a/fe/src/test/java/org/apache/impala/planner/StatsExtrapolationTest.java b/fe/src/test/java/org/apache/impala/planner/StatsExtrapolationTest.java index 92b2f93..bee6a32 100644 --- a/fe/src/test/java/org/apache/impala/planner/StatsExtrapolationTest.java +++ b/fe/src/test/java/org/apache/impala/planner/StatsExtrapolationTest.java @@ -79,13 +79,11 @@ public class StatsExtrapolationTest extends FrontendTestBase { addTestDb("extrap_stats", null); Table tbl = addTestTable("create table extrap_stats.t (i int)"); - // Replace/restore the static backend config for this test. - BackendConfig origInstance = BackendConfig.INSTANCE; + // Modify/restore the backend config for this test. + TBackendGflags gflags = BackendConfig.INSTANCE.getBackendCfg(); + boolean origEnableStatsExtrapolation = gflags.isEnable_stats_extrapolation(); try { - // Create a fake config with extrapolation enabled. - TBackendGflags testGflags = new TBackendGflags(); - testGflags.setEnable_stats_extrapolation(true); - BackendConfig.create(testGflags); + gflags.setEnable_stats_extrapolation(true); // Both stats are set to a meaningful value. runTest(tbl, 100L, 1000L, 0, 0); @@ -131,7 +129,7 @@ public class StatsExtrapolationTest extends FrontendTestBase { runTest(tbl, 100L, 1000L, -1, -1); runTest(tbl, 100L, 1000L, Long.MIN_VALUE, -1); } finally { - BackendConfig.INSTANCE = origInstance; + gflags.setEnable_stats_extrapolation(origEnableStatsExtrapolation); } } @@ -140,13 +138,11 @@ public class StatsExtrapolationTest extends FrontendTestBase { addTestDb("extrap_stats", null); Table tbl = addTestTable("create table extrap_stats.t (i int)"); - // Replace/restore the static backend config for this test. - BackendConfig origInstance = BackendConfig.INSTANCE; + // Modify/restore the backend config for this test. + TBackendGflags gflags = BackendConfig.INSTANCE.getBackendCfg(); + boolean origEnableStatsExtrapolation = gflags.isEnable_stats_extrapolation(); try { - // Create a fake config with extrapolation disabled. - TBackendGflags testGflags = new TBackendGflags(); - testGflags.setEnable_stats_extrapolation(false); - BackendConfig.create(testGflags); + gflags.setEnable_stats_extrapolation(false); // Always expect -1 even with legitimate stats. runTest(tbl, 100L, 1000L, 0, -1); @@ -155,7 +151,7 @@ public class StatsExtrapolationTest extends FrontendTestBase { runTest(tbl, 100L, 1000L, Long.MAX_VALUE, -1); runTest(tbl, 100L, 1000L, -100, -1); } finally { - BackendConfig.INSTANCE = origInstance; + gflags.setEnable_stats_extrapolation(origEnableStatsExtrapolation); } } } http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/fe/src/test/java/org/apache/impala/service/JdbcTest.java ---------------------------------------------------------------------- diff --git a/fe/src/test/java/org/apache/impala/service/JdbcTest.java b/fe/src/test/java/org/apache/impala/service/JdbcTest.java index 1a907f8..28b032b 100644 --- a/fe/src/test/java/org/apache/impala/service/JdbcTest.java +++ b/fe/src/test/java/org/apache/impala/service/JdbcTest.java @@ -36,15 +36,15 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; import org.apache.impala.analysis.CreateTableStmt; import org.apache.impala.analysis.SqlParser; import org.apache.impala.analysis.SqlScanner; import org.apache.impala.testutil.ImpalaJdbcClient; import org.apache.impala.util.Metrics; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; import com.google.common.collect.Lists; http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/testdata/workloads/functional-query/queries/QueryTest/empty-build-joins.test ---------------------------------------------------------------------- diff --git a/testdata/workloads/functional-query/queries/QueryTest/empty-build-joins.test b/testdata/workloads/functional-query/queries/QueryTest/empty-build-joins.test index 3aa9994..19f5ea6 100644 --- a/testdata/workloads/functional-query/queries/QueryTest/empty-build-joins.test +++ b/testdata/workloads/functional-query/queries/QueryTest/empty-build-joins.test @@ -1,9 +1,9 @@ ==== ---- QUERY # Inner equi-join - executes with hash join. -select straight_join at.id -from alltypes at - inner join functional.alltypestiny att on at.id = att.id +select straight_join atp.id +from alltypes atp + inner join functional.alltypestiny att on atp.id = att.id where att.int_col = 999 ---- RESULTS ---- TYPES @@ -11,9 +11,9 @@ INT ==== ---- QUERY # Right equi-join - executes with hash join. -select straight_join at.id -from alltypes at - right join functional.alltypestiny att on at.id = att.id +select straight_join atp.id +from alltypes atp + right join functional.alltypestiny att on atp.id = att.id where att.int_col = 999 ---- RESULTS ---- TYPES @@ -21,11 +21,11 @@ INT ==== ---- QUERY # Left equi-join - executes with hash join. -select straight_join at.id -from alltypes at +select straight_join atp.id +from alltypes atp left join ( - select * from functional.alltypestiny where int_col = 999) att on at.id = att.id -order by at.id desc + select * from functional.alltypestiny where int_col = 999) att on atp.id = att.id +order by atp.id desc limit 5 ---- RESULTS 7299 @@ -38,11 +38,11 @@ INT ==== ---- QUERY # Full outer equi-join - executes with hash join. -select straight_join at.id -from alltypes at +select straight_join atp.id +from alltypes atp full outer join ( - select * from functional.alltypestiny where int_col = 999) att on at.id = att.id -order by at.id desc + select * from functional.alltypestiny where int_col = 999) att on atp.id = att.id +order by atp.id desc limit 5 ---- RESULTS 7299 @@ -55,8 +55,8 @@ INT ==== ---- QUERY # Left semi equi-join - executes with hash join. -select straight_join at.id -from alltypes at +select straight_join atp.id +from alltypes atp where id in ( select id from functional.alltypestiny where id = 999) @@ -66,17 +66,17 @@ INT ==== ---- QUERY # Right semi equi-join - executes with hash join. -select straight_join at.id +select straight_join atp.id from (select * from functional.alltypestiny att where int_col = 999) att - right semi join alltypes at on at.id = att.id + right semi join alltypes atp on atp.id = att.id ---- RESULTS ---- TYPES INT ==== ---- QUERY # Left NAAJ equi-join - executes with hash join. -select straight_join at.id -from alltypes at +select straight_join atp.id +from alltypes atp where id not in ( select id from functional.alltypestiny where id = 999) @@ -93,11 +93,11 @@ INT ==== ---- QUERY # Left anti equi-join - executes with hash join. -select straight_join at.id -from alltypes at +select straight_join atp.id +from alltypes atp where not exists ( select id from functional.alltypestiny att - where id = 999 and att.id = at.id) + where id = 999 and att.id = atp.id) order by id desc limit 5 ---- RESULTS @@ -111,10 +111,10 @@ INT ==== ---- QUERY # Right anti equi-join - executes with hash join. -select straight_join at.id +select straight_join atp.id from (select * from functional.alltypestiny att where int_col = 999) att - right anti join alltypes at on at.id = att.id -order by at.id desc + right anti join alltypes atp on atp.id = att.id +order by atp.id desc limit 5 ---- RESULTS 7299 @@ -127,9 +127,9 @@ INT ==== ---- QUERY # Inner non-equi-join - executes with nested loop join. -select straight_join at.id -from alltypes at - inner join functional.alltypestiny att on at.id < att.id +select straight_join atp.id +from alltypes atp + inner join functional.alltypestiny att on atp.id < att.id where att.int_col = 999 ---- RESULTS ---- TYPES @@ -137,8 +137,8 @@ INT ==== ---- QUERY # Cross join - executes with nested loop join. -select straight_join at.id -from alltypes at, functional.alltypestiny att +select straight_join atp.id +from alltypes atp, functional.alltypestiny att where att.int_col = 999 ---- RESULTS ---- TYPES @@ -146,11 +146,11 @@ INT ==== ---- QUERY # Left non-equi-join - executes with nested loop join. -select straight_join at.id -from alltypes at +select straight_join atp.id +from alltypes atp left join ( - select * from functional.alltypestiny where int_col = 999) att on at.id < att.id -order by at.id desc + select * from functional.alltypestiny where int_col = 999) att on atp.id < att.id +order by atp.id desc limit 5 ---- RESULTS 7299 @@ -163,11 +163,11 @@ INT ==== ---- QUERY # Left semi non-equi-join - executes with nested loop join. -select straight_join at.id -from alltypes at +select straight_join atp.id +from alltypes atp left semi join ( - select * from functional.alltypestiny att where int_col = 999) att on at.id < att.id -order by at.id desc + select * from functional.alltypestiny att where int_col = 999) att on atp.id < att.id +order by atp.id desc limit 5 ---- RESULTS ---- TYPES @@ -175,10 +175,10 @@ INT ==== ---- QUERY # Left anti non-equi-join - executes with nested loop join. -select straight_join at.id -from alltypes at left anti join ( +select straight_join atp.id +from alltypes atp left anti join ( select * from functional.alltypestiny att - where id = 999) att on at.id < att.id + where id = 999) att on atp.id < att.id order by id desc limit 5 ---- RESULTS http://git-wip-us.apache.org/repos/asf/impala/blob/f0b3d9d1/testdata/workloads/functional-query/queries/QueryTest/exprs.test ---------------------------------------------------------------------- diff --git a/testdata/workloads/functional-query/queries/QueryTest/exprs.test b/testdata/workloads/functional-query/queries/QueryTest/exprs.test index 71759f3..67494a6 100644 --- a/testdata/workloads/functional-query/queries/QueryTest/exprs.test +++ b/testdata/workloads/functional-query/queries/QueryTest/exprs.test @@ -2355,8 +2355,8 @@ select dayofyear(trunc('2014-11-11', string_col)) from functional.alltypestiny l Invalid Truncate Unit: 0 ==== ---- QUERY -select regexp_match_count(tmp.str, tmp.pattern) from (values -('aaa' as str, 'a' as pattern), +select regexp_match_count(tmp.str, tmp.`pattern`) from (values +('aaa' as str, 'a' as `pattern`), ('aaa', 'aa'), ('aaaa', 'aa'), ('', ''), @@ -2401,8 +2401,8 @@ select regexp_match_count(tmp.str, tmp.pattern) from (values int ==== ---- QUERY -select regexp_match_count(tmp.str, tmp.pattern, tmp.start_pos, tmp.params) from (values -('aaa' as str, 'A' as pattern, 1 as start_pos, 'i' as params), +select regexp_match_count(tmp.str, tmp.`pattern`, tmp.start_pos, tmp.params) from (values +('aaa' as str, 'A' as `pattern`, 1 as start_pos, 'i' as params), ('aaa', 'A', 1, 'c'), ('this\nis\nnewline', '.*', 1, ''), ('this\nis\nnewline', '.*', 1, 'n'), @@ -2435,16 +2435,16 @@ select regexp_match_count(tmp.str, tmp.pattern, tmp.start_pos, tmp.params) from int ==== ---- QUERY -select regexp_match_count(tmp.str, tmp.pattern, tmp.start_pos, tmp.params) from (values -('a' as str, 'a' as pattern, -1 as start_pos, '' as params), +select regexp_match_count(tmp.str, tmp.`pattern`, tmp.start_pos, tmp.params) from (values +('a' as str, 'a' as `pattern`, -1 as start_pos, '' as params), ('foobar', 'foobar', 1, 'i'), ('iPhone\niPad\niPod', '^I.*$', 1, 'imn')) as tmp ---- CATCH Illegal starting position -1 ==== ---- QUERY -select regexp_match_count(tmp.str, tmp.pattern, tmp.start_pos, tmp.params) from (values -('a' as str, 'a' as pattern, 1 as start_pos, 'xyz' as params), +select regexp_match_count(tmp.str, tmp.`pattern`, tmp.start_pos, tmp.params) from (values +('a' as str, 'a' as `pattern`, 1 as start_pos, 'xyz' as params), ('foobar', 'foobar', 1, 'i'), ('iPhone\niPad\niPod', '^I.*$', 1, 'imn')) as tmp ---- CATCH