diff --git a/src/sqlfluff/dialects/dialect_vertica.py b/src/sqlfluff/dialects/dialect_vertica.py index 219f42f5685..35ef154a752 100644 --- a/src/sqlfluff/dialects/dialect_vertica.py +++ b/src/sqlfluff/dialects/dialect_vertica.py @@ -519,10 +519,11 @@ ) ), ParameterNameSegment=RegexParser( - #need to cover cases where non-ascii word is parameter like ALTER TABLE some_table TO utf8_identifier_eg_Verkäufer; + # need to cover cases where non-ascii word is parameter + # like ```ALTER TABLE some_table TO utf8_identifier_eg_Verkäufer;``` r"[\p{L}_][\p{L}\p{N}$_]*", - sqlfluff.core.parser.CodeSegment, - type="parameter" + CodeSegment, + type="parameter", ), ) diff --git a/test/fixtures/dialects/vertica/select.sql b/test/fixtures/dialects/vertica/select.sql index 6a367e7d929..9d08d54b5b8 100644 --- a/test/fixtures/dialects/vertica/select.sql +++ b/test/fixtures/dialects/vertica/select.sql @@ -84,3 +84,48 @@ SELECT DISTINCT customer_name FROM customer_dimension WHERE customer_region = 'East' AND customer_name ILIKE 'Amer%'; + +/* https://docs.vertica.com/24.3.x/en/sql-reference/language-elements/identifiers/ +* Unquoted SQL identifiers must begin with one of the following: +* * Non-Unicode letters: A–Z or a-z +* -- /actually Vertica accepts also non-ASCII UTF-8 Unicode +* characters here, which is not well documented/ +* * Underscore (_) +* Subsequent characters in an identifier can be any combination of +* the following: +* * Non-Unicode letters: A–Z or a-z +* * Underscore (_) +* * Digits(0–9) +* * Unicode letters (letters with diacriticals or not in the Latin +* alphabet), unsupported for model names +* * Dollar sign ($), unsupported for model names +* +* Vertica accepts **non-ASCII UTF-8 Unicode characters** for table +* names, column names, and other identifiers, +* extending the cases where upper/lower case distinctions are +* ignored (case-folded) to all alphabets, +* including Latin, Cyrillic, and Greek. +*/ +-- unqouted identifiers +SELECT * FROM public.sales; + +SELECT * FROM public.sales1; +SELECT * FROM public.sales_; +SELECT * FROM public.s$ales$; +SELECT * FROM public._sales; +SELECT * FROM public._1234sales; + +SELECT * FROM public1.sales; +SELECT * FROM public_.sales; +SELECT * FROM p$ublic$.sales; +SELECT * FROM _public.sales; +SELECT * FROM _1234public.sales; + +SELECT * FROM public1.sales1; +SELECT * FROM public1_.sales1_; +SELECT * FROM p$ublic1_$.s$ales1_$; + + +-- quoted identifiers +SELECT * FROM "12public"."12344gr"; +SELECT * FROM "_1234public"."_1234sales"; diff --git a/test/fixtures/dialects/vertica/select.yml b/test/fixtures/dialects/vertica/select.yml index 32bb73a8989..d5f9027887a 100644 --- a/test/fixtures/dialects/vertica/select.yml +++ b/test/fixtures/dialects/vertica/select.yml @@ -3,7 +3,7 @@ # computed by SQLFluff when running the tests. Please run # `python test/generate_parse_fixture_yml.py` to generate them after adding or # altering SQL files. -_hash: 296aff357834f41b502939251b9c5574cbfe4c2e96ad50e6d2ca5f83dc0d21b0 +_hash: 81dff6951792526333c0948e979cdfd183bbd58721afe5f4c607b3f816f1ada0 file: - statement: select_statement: @@ -724,3 +724,291 @@ file: - keyword: ILIKE - quoted_literal: "'Amer%'" - statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: public + - dot: . + - naked_identifier: sales +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: public + - dot: . + - naked_identifier: sales1 +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: public + - dot: . + - naked_identifier: sales_ +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: public + - dot: . + - naked_identifier: s$ales$ +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: public + - dot: . + - naked_identifier: _sales +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: public + - dot: . + - naked_identifier: _1234sales +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: public1 + - dot: . + - naked_identifier: sales +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: public_ + - dot: . + - naked_identifier: sales +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: p$ublic$ + - dot: . + - naked_identifier: sales +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: _public + - dot: . + - naked_identifier: sales +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: _1234public + - dot: . + - naked_identifier: sales +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: public1 + - dot: . + - naked_identifier: sales1 +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: public1_ + - dot: . + - naked_identifier: sales1_ +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: p$ublic1_$ + - dot: . + - naked_identifier: s$ales1_$ +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - quoted_identifier: '"12public"' + - dot: . + - quoted_identifier: '"12344gr"' +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - quoted_identifier: '"_1234public"' + - dot: . + - quoted_identifier: '"_1234sales"' +- statement_terminator: ; diff --git a/test/fixtures/dialects/vertica/utf8.sql b/test/fixtures/dialects/vertica/utf8.sql index 586bb443639..9c9c5af5f5b 100644 --- a/test/fixtures/dialects/vertica/utf8.sql +++ b/test/fixtures/dialects/vertica/utf8.sql @@ -162,9 +162,9 @@ ALTER TABLE public.заказы_магазина ADD COLUMN ожиддаемая ALTER TABLE t33 OWNER TO Alice; ---! ALTER TABLE επιμελητεία OWNER TO διαχειριστής; +ALTER TABLE επιμελητεία OWNER TO διαχειριστής; ---! ALTER TABLE заказы OWNER TO алиса; +ALTER TABLE заказы OWNER TO алиса; -- ARRAY block SELECT (ARRAY['مسؤل', 'διαχειριστής', 'логистика', 'd', 'e'])[1]; @@ -189,21 +189,29 @@ COMMENT ON SCHEMA public IS 'Όλοι οι χρήστες έχουν πρόσβ COMMENT ON SCHEMA public IS 'Все пользователи могут получить доступ к этой схеме'; -- COPY block --- COPY INTO test_parquet --- FROM 'https://myaccount.blob.core.windows.net/myblobcontainer/folder1/*.parquet' --- WITH ( --- FILE_FORMAT = myFileFormat, --- CREDENTIAL=(IDENTITY= 'Shared Access Signature', SECRET='') --- ); - --- COPY INTO продажи.продажи_на_сегодня --- FROM 'https://myaccount.blob.core.windows.net/myblobcontainer/folder0/*.txt' --- WITH ( --- FILE_TYPE = 'CSV', --- CREDENTIAL = (IDENTITY = 'Managed Identity'), --- FIELDQUOTE = '"', --- FIELDTERMINATOR=',' --- ); +COPY public.customer_dimension ( + customer_since FORMAT 'YYYY' +) + FROM STDIN + DELIMITER ',' + NULL AS 'null' + ENCLOSED BY '"'; + +COPY παραγγελίες.παραγγελίες_ανά_ημέρα ( + πελάτη_αφού FORMAT 'YYYY' +) + FROM STDIN + DELIMITER ',' + NULL AS 'null' + ENCLOSED BY '"'; + +COPY заказы.заказы_на_день ( + клиент_с_даты FORMAT 'YYYY' +) + FROM STDIN + DELIMITER ',' + NULL AS 'null' + ENCLOSED BY '"'; -- CREATE PROJECTION block CREATE PROJECTION public.employee_dimension_super @@ -222,6 +230,29 @@ CREATE PROJECTION продажи.продажи_на_по_клиенту SEGMENTED BY hash(клиент) ALL NODES; -- CREATE SCHEMA block --- CREATE SCHEMA IF NOT EXISTS foo COMMENT 'test schema' MANAGEDLOCATION 'hdfs://path'; --- CREATE SCHEMA IF NOT EXISTS εμπορικός COMMENT 'test schema' MANAGEDLOCATION 'hdfs://path'; --- CREATE SCHEMA IF NOT EXISTS продажи COMMENT 'test schema' MANAGEDLOCATION 'hdfs://path'; +CREATE SCHEMA s3 DEFAULT INCLUDE SCHEMA PRIVILEGES; +CREATE SCHEMA εμπορικός DEFAULT INCLUDE SCHEMA PRIVILEGES; +CREATE SCHEMA продажи DEFAULT INCLUDE SCHEMA PRIVILEGES; + +-- unqouted identifiers +SELECT * FROM логистика.εμπορικός; + +SELECT * FROM логистика.εμπορικός1; +SELECT * FROM логистика.εμπορικός_; +SELECT * FROM логистика.s$ales$; +SELECT * FROM логистика._εμπορικός; +SELECT * FROM логистика._1234εμπορικός; + +SELECT * FROM логистика1.εμπορικός; +SELECT * FROM логистика_.εμπορικός; +SELECT * FROM p$ublic$.εμπορικός; +SELECT * FROM _логистика.εμπορικός; +SELECT * FROM _1234логистика.εμπορικός; + +SELECT * FROM логистика1.εμπορικός1; +SELECT * FROM логистика1_.εμπορικός1_; +SELECT * FROM p$ublic1_$.s$ales1_$; + +-- quoted identifiers +SELECT * FROM "12логистика"."12344εμπορικός"; +SELECT * FROM "_1234логистика"."_1234εμπορικός"; diff --git a/test/fixtures/dialects/vertica/utf8.yml b/test/fixtures/dialects/vertica/utf8.yml index a703ce2116a..4ce34ddc564 100644 --- a/test/fixtures/dialects/vertica/utf8.yml +++ b/test/fixtures/dialects/vertica/utf8.yml @@ -3,7 +3,7 @@ # computed by SQLFluff when running the tests. Please run # `python test/generate_parse_fixture_yml.py` to generate them after adding or # altering SQL files. -_hash: 52066abd17c4dc07c3f07a7839d42ca031e02419c8f372e4fa53305f4a470b0f +_hash: d48b7901afbfc3cd29d9c20e9c16ac2e5b173a4c3f6e0e0109f52ffb026a3235 file: - statement: select_statement: @@ -2007,6 +2007,28 @@ file: - keyword: TO - parameter: Alice - statement_terminator: ; +- statement: + alter_table_statement: + - keyword: ALTER + - keyword: TABLE + - table_reference: + naked_identifier: επιμελητεία + - alter_table_action_segment: + - keyword: OWNER + - keyword: TO + - parameter: διαχειριστής +- statement_terminator: ; +- statement: + alter_table_statement: + - keyword: ALTER + - keyword: TABLE + - table_reference: + naked_identifier: заказы + - alter_table_action_segment: + - keyword: OWNER + - keyword: TO + - parameter: алиса +- statement_terminator: ; - statement: select_statement: select_clause: @@ -2181,6 +2203,93 @@ file: - keyword: IS - quoted_literal: "'Все пользователи могут получить доступ к этой схеме'" - statement_terminator: ; +- statement: + copy_statement: + - keyword: COPY + - table_reference: + - naked_identifier: public + - dot: . + - naked_identifier: customer_dimension + - bracketed: + start_bracket: ( + copy_column_options: + column_reference: + naked_identifier: customer_since + copy_options_for_columns: + keyword: FORMAT + quoted_literal: "'YYYY'" + end_bracket: ) + - keyword: FROM + - keyword: STDIN + - copy_options: + copy_options_for_columns: + - keyword: DELIMITER + - quoted_literal: "','" + - keyword: 'NULL' + - keyword: AS + - quoted_literal: "'null'" + - keyword: ENCLOSED + - keyword: BY + - quoted_literal: "'\"'" +- statement_terminator: ; +- statement: + copy_statement: + - keyword: COPY + - table_reference: + - naked_identifier: παραγγελίες + - dot: . + - naked_identifier: παραγγελίες_ανά_ημέρα + - bracketed: + start_bracket: ( + copy_column_options: + column_reference: + naked_identifier: πελάτη_αφού + copy_options_for_columns: + keyword: FORMAT + quoted_literal: "'YYYY'" + end_bracket: ) + - keyword: FROM + - keyword: STDIN + - copy_options: + copy_options_for_columns: + - keyword: DELIMITER + - quoted_literal: "','" + - keyword: 'NULL' + - keyword: AS + - quoted_literal: "'null'" + - keyword: ENCLOSED + - keyword: BY + - quoted_literal: "'\"'" +- statement_terminator: ; +- statement: + copy_statement: + - keyword: COPY + - table_reference: + - naked_identifier: заказы + - dot: . + - naked_identifier: заказы_на_день + - bracketed: + start_bracket: ( + copy_column_options: + column_reference: + naked_identifier: клиент_с_даты + copy_options_for_columns: + keyword: FORMAT + quoted_literal: "'YYYY'" + end_bracket: ) + - keyword: FROM + - keyword: STDIN + - copy_options: + copy_options_for_columns: + - keyword: DELIMITER + - quoted_literal: "','" + - keyword: 'NULL' + - keyword: AS + - quoted_literal: "'null'" + - keyword: ENCLOSED + - keyword: BY + - quoted_literal: "'\"'" +- statement_terminator: ; - statement: create_projection_statement: - keyword: CREATE @@ -2319,3 +2428,327 @@ file: - keyword: ALL - keyword: NODES - statement_terminator: ; +- statement: + create_schema_statement: + - keyword: CREATE + - keyword: SCHEMA + - schema_reference: + naked_identifier: s3 + - keyword: DEFAULT + - schema_privileges_segment: + - keyword: INCLUDE + - keyword: SCHEMA + - keyword: PRIVILEGES +- statement_terminator: ; +- statement: + create_schema_statement: + - keyword: CREATE + - keyword: SCHEMA + - schema_reference: + naked_identifier: εμπορικός + - keyword: DEFAULT + - schema_privileges_segment: + - keyword: INCLUDE + - keyword: SCHEMA + - keyword: PRIVILEGES +- statement_terminator: ; +- statement: + create_schema_statement: + - keyword: CREATE + - keyword: SCHEMA + - schema_reference: + naked_identifier: продажи + - keyword: DEFAULT + - schema_privileges_segment: + - keyword: INCLUDE + - keyword: SCHEMA + - keyword: PRIVILEGES +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: логистика + - dot: . + - naked_identifier: εμπορικός +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: логистика + - dot: . + - naked_identifier: εμπορικός1 +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: логистика + - dot: . + - naked_identifier: εμπορικός_ +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: логистика + - dot: . + - naked_identifier: s$ales$ +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: логистика + - dot: . + - naked_identifier: _εμπορικός +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: логистика + - dot: . + - naked_identifier: _1234εμπορικός +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: логистика1 + - dot: . + - naked_identifier: εμπορικός +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: логистика_ + - dot: . + - naked_identifier: εμπορικός +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: p$ublic$ + - dot: . + - naked_identifier: εμπορικός +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: _логистика + - dot: . + - naked_identifier: εμπορικός +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: _1234логистика + - dot: . + - naked_identifier: εμπορικός +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: логистика1 + - dot: . + - naked_identifier: εμπορικός1 +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: логистика1_ + - dot: . + - naked_identifier: εμπορικός1_ +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - naked_identifier: p$ublic1_$ + - dot: . + - naked_identifier: s$ales1_$ +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - quoted_identifier: '"12логистика"' + - dot: . + - quoted_identifier: '"12344εμπορικός"' +- statement_terminator: ; +- statement: + select_statement: + select_clause: + keyword: SELECT + select_clause_element: + wildcard_expression: + wildcard_identifier: + star: '*' + from_clause: + keyword: FROM + from_expression: + from_expression_element: + table_expression: + table_reference: + - quoted_identifier: '"_1234логистика"' + - dot: . + - quoted_identifier: '"_1234εμπορικός"' +- statement_terminator: ;