diff --git a/src/Parsers/isUnquotedIdentifier.cpp b/src/Parsers/isUnquotedIdentifier.cpp index 6f2442635ec..26cb3992a50 100644 --- a/src/Parsers/isUnquotedIdentifier.cpp +++ b/src/Parsers/isUnquotedIdentifier.cpp @@ -1,5 +1,6 @@ #include +#include #include namespace DB @@ -7,6 +8,18 @@ namespace DB bool isUnquotedIdentifier(const String & name) { + auto is_keyword = [&name](Keyword keyword) + { + auto s = toStringView(keyword); + if (name.size() != s.size()) + return false; + return strncasecmp(s.data(), name.data(), s.size()) == 0; + }; + + /// Special keywords are parsed as literals instead of identifiers. + if (is_keyword(Keyword::NULL_KEYWORD) || is_keyword(Keyword::TRUE_KEYWORD) || is_keyword(Keyword::FALSE_KEYWORD)) + return false; + Lexer lexer(name.data(), name.data() + name.size()); auto maybe_ident = lexer.nextToken(); diff --git a/src/Parsers/isUnquotedIdentifier.h b/src/Parsers/isUnquotedIdentifier.h index 839e5860ad3..9c9f9239eb3 100644 --- a/src/Parsers/isUnquotedIdentifier.h +++ b/src/Parsers/isUnquotedIdentifier.h @@ -5,6 +5,14 @@ namespace DB { +/// Checks if the input string @name is a valid unquoted identifier. +/// +/// Example Usage: +/// abc -> true (valid unquoted identifier) +/// 123 -> false (identifiers cannot start with digits) +/// `123` -> false (quoted identifiers are not considered) +/// `abc` -> false (quoted identifiers are not considered) +/// null -> false (reserved literal keyword) bool isUnquotedIdentifier(const String & name); } diff --git a/tests/queries/0_stateless/02890_named_tuple_functions.reference b/tests/queries/0_stateless/02890_named_tuple_functions.reference index f7a0c440b5a..6b36ff2c54c 100644 --- a/tests/queries/0_stateless/02890_named_tuple_functions.reference +++ b/tests/queries/0_stateless/02890_named_tuple_functions.reference @@ -7,3 +7,4 @@ Tuple(\n k UInt8,\n j Int32) Tuple(Int32, Int32, Int32, Int32) ['1','2','3','4'] (1,2,3) +Tuple(Nullable(Nothing)) Tuple(Bool) Tuple(Bool) diff --git a/tests/queries/0_stateless/02890_named_tuple_functions.sql b/tests/queries/0_stateless/02890_named_tuple_functions.sql index 8e0c9c2b10e..0033102bd53 100644 --- a/tests/queries/0_stateless/02890_named_tuple_functions.sql +++ b/tests/queries/0_stateless/02890_named_tuple_functions.sql @@ -28,4 +28,7 @@ create table tbl (x Tuple(a Int32, b Int32, c Int32)) engine MergeTree order by insert into tbl values (tuple(1, 2, 3)); -- without tuple it's interpreted differently inside values block. select * from tbl; -drop table tbl +drop table tbl; + +-- Avoid generating named tuple for special keywords +select toTypeName(tuple(null)), toTypeName(tuple(true)), toTypeName(tuple(false));