diff --git a/driver/escaping/escape_sequences.cpp b/driver/escaping/escape_sequences.cpp index af7a8818c..1bc19d7e0 100644 --- a/driver/escaping/escape_sequences.cpp +++ b/driver/escaping/escape_sequences.cpp @@ -120,15 +120,18 @@ string processIdentOrFunction(const StringView seq, Lexer & lex) { lex.SetEmitSpaces(true); } else if (token.type == Token::LPARENT) { result += processParentheses(seq, lex); - } else if (token.type == Token::IDENT && lex.LookAhead(1).type == Token::LPARENT) { // CAST( ... ) + } else if (function_map_strip_params.find(token.type) != function_map_strip_params.end()) { + result += function_map_strip_params.at(token.type); + } else if ( // any of the remaining recognized FUNCTION( ... ), or any IDENT( ... ), including CAST( ... ) + (token.type == Token::IDENT || function_map.find(token.type) != function_map.end()) && + lex.LookAhead(1).type == Token::LPARENT + ) { result += token.literal.to_string(); // func name lex.Consume(); result += processParentheses(seq, lex); } else if (token.type == Token::NUMBER || token.type == Token::IDENT || token.type == Token::STRING) { result += token.literal.to_string(); lex.Consume(); - } else if (function_map_strip_params.find(token.type) != function_map_strip_params.end()) { - result += function_map_strip_params.at(token.type); } else { return ""; } @@ -267,6 +270,14 @@ string processFunction(const StringView seq, Lexer & lex) { lex.Consume(); return "( toRelativeDayNum(" + param + ") - toRelativeDayNum(toStartOfYear(" + param + ")) + 1 )"; */ + } else if (function_map_strip_params.find(fn.type) != function_map_strip_params.end()) { + string result = function_map_strip_params.at(fn.type); + + if (lex.Peek().type == Token::LPARENT) { + processParentheses(seq, lex); // ignore anything inside ( ) + } + + return result; } else if (function_map.find(fn.type) != function_map.end()) { string result = function_map.at(fn.type); auto func = result; @@ -294,15 +305,6 @@ string processFunction(const StringView seq, Lexer & lex) { } lex.SetEmitSpaces(false); - return result; - - } else if (function_map_strip_params.find(fn.type) != function_map_strip_params.end()) { - string result = function_map_strip_params.at(fn.type); - - if (lex.Peek().type == Token::LPARENT) { - processParentheses(seq, lex); // ignore anything inside ( ) - } - return result; } diff --git a/driver/escaping/function_declare.h b/driver/escaping/function_declare.h index 9d3f6a153..3174e2a80 100644 --- a/driver/escaping/function_declare.h +++ b/driver/escaping/function_declare.h @@ -43,8 +43,9 @@ DECLARE2(LOWER, "lowerUTF8"), // LEFT substring(s, 0, length) DECLARE2(LENGTH, "lengthUTF8"), - //DECLARE2(LOCATE, "position"), // special - // LTRIM + DECLARE2(LOCATE, "" /* "position" */), // special handling + DECLARE2(CONVERT, ""), // special handling + DECLARE2(LTRIM, ""), // special handling DECLARE2(OCTET_LENGTH, "length"), // POSITION // REPEAT @@ -59,10 +60,11 @@ // Date + DECLARE2(CURRENT_TIMESTAMP, ""), // special handling DECLARE2(CURDATE, "today"), DECLARE2(CURRENT_DATE, "today"), DECLARE2(DAYOFMONTH, "toDayOfMonth"), - // DECLARE2(DAYOFWEEK, " toDayOfWeek"), // special handling + DECLARE2(DAYOFWEEK, "" /* "toDayOfWeek" */), // special handling DECLARE2(DAYOFYEAR, " toDayOfYear"), // Supported by ClickHouse since 18.13.0 DECLARE2(EXTRACT, "EXTRACT"), // Do not touch extract inside {fn ... } DECLARE2(HOUR, "toHour"), @@ -70,6 +72,7 @@ DECLARE2(MONTH, "toMonth"), DECLARE2(NOW, "now"), DECLARE2(SECOND, "toSecond"), + DECLARE2(TIMESTAMPADD, ""), // special handling DECLARE2(TIMESTAMPDIFF, "dateDiff"), DECLARE2(WEEK, "toISOWeek"), DECLARE2(SQL_TSI_QUARTER, "toQuarter"), diff --git a/driver/escaping/lexer_declare.h b/driver/escaping/lexer_declare.h index 708d712f9..08d5c8f87 100644 --- a/driver/escaping/lexer_declare.h +++ b/driver/escaping/lexer_declare.h @@ -1,14 +1,6 @@ // clang-format off - DECLARE(DAYOFWEEK), - DECLARE(TIMESTAMPADD), - DECLARE(CONVERT), - DECLARE(LOCATE), - DECLARE(LTRIM), - - DECLARE(CURRENT_TIMESTAMP), - //DECLARE(SQL_TSI_FRAC_SECOND), DECLARE(SQL_TSI_SECOND), DECLARE(SQL_TSI_MINUTE), diff --git a/driver/test/escape_sequences_ut.cpp b/driver/test/escape_sequences_ut.cpp index 09d9137a9..6cdc9f9a4 100644 --- a/driver/test/escape_sequences_ut.cpp +++ b/driver/test/escape_sequences_ut.cpp @@ -143,6 +143,10 @@ TEST(EscapeSequencesCase, ParseTimestampadd6) { "toDayOfWeek(CAST(`publishers_report`.`install_date` AS DATE)) + 1)), 7))))"); } +TEST(EscapeSequencesCase, ParseTimestampadd7) { + ASSERT_EQ(replaceEscapeSequences("SELECT {fn TIMESTAMPADD(SQL_TSI_HOUR,EXTRACT(HOUR FROM `abc`.`xyz`),CAST(`klm`.`nop` AS DATE))}"), + "SELECT addHours(CAST(`klm`.`nop` AS DATE), EXTRACT(HOUR FROM `abc`.`xyz`))"); +} TEST(EscapeSequencesCase, ParseCurrentTimestamp1) { ASSERT_EQ(replaceEscapeSequences("SELECT {fn CURRENT_TIMESTAMP}"), "SELECT now()");