From 1ae0420135e0dc3ea2ddaf36203271b6720b5945 Mon Sep 17 00:00:00 2001 From: lingo-xp <36907211+lingo-xp@users.noreply.github.com> Date: Mon, 2 Dec 2024 15:58:04 +0800 Subject: [PATCH] Fix parse interval issue, cannot parse 'cast(xxx as xx) year' correctly. (#6261) * Fix parse interval issue, cannot parse 'cast(xxx as xx) year' correctly. * lint. * Improve. --- .../dialect/hive/parser/HiveExprParser.java | 17 ++++++---- .../druid/sql/parser/SQLExprParser.java | 32 ------------------- .../test/resources/bvt/parser/impala/0.txt | 16 ++++++++++ 3 files changed, 27 insertions(+), 38 deletions(-) diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveExprParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveExprParser.java index 3321311e20..44626753d2 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveExprParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/hive/parser/HiveExprParser.java @@ -231,11 +231,6 @@ public SQLExpr primaryRest(SQLExpr expr) { lexer.nextToken(); Number num = ((SQLNumericLiteralExpr) expr).getNumber(); expr = new SQLDecimalExpr(num.toString()); - } else if (lexer.token() == Token.IDENTIFIER) { // hortonworks - SQLIntervalUnit unit = parseIntervalUnit(); - if (unit != null) { - expr = new SQLIntervalExpr(expr, unit); - } } break; default: @@ -376,13 +371,23 @@ protected SQLExpr parseInterval() { SQLIntervalExpr intervalExpr = new SQLIntervalExpr(); intervalExpr.setValue(value); - SQLIntervalUnit intervalUnit = SQLIntervalUnit.valueOf(unit.toUpperCase()); + SQLIntervalUnit intervalUnit = SQLIntervalUnit.of(unit.toUpperCase()); if (intervalUnit == SQLIntervalUnit.YEAR && lexer.token() == Token.TO) { lexer.nextToken(); acceptIdentifier("MONTH"); intervalUnit = SQLIntervalUnit.YEAR_TO_MONTH; } + if (intervalUnit == SQLIntervalUnit.YEAR && lexer.nextIf(Token.TO)) { + acceptIdentifier(FnvHash.Constants.MONTH); + intervalUnit = SQLIntervalUnit.YEAR_TO_MONTH; + } else if (intervalUnit == SQLIntervalUnit.DAY && lexer.nextIf(Token.TO)) { + acceptIdentifier(FnvHash.Constants.SECOND); + intervalUnit = SQLIntervalUnit.DAY_HOUR; + } else if (intervalUnit == SQLIntervalUnit.HOUR && lexer.nextIf(Token.TO)) { + acceptIdentifier(FnvHash.Constants.SECOND); + intervalUnit = SQLIntervalUnit.HOUR_SECOND; + } intervalExpr.setUnit(intervalUnit); return intervalExpr; diff --git a/core/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/core/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index c176ef5e39..4925562e70 100644 --- a/core/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -376,38 +376,6 @@ public int parseIntValue() { } } - public SQLIntervalUnit parseIntervalUnit() { - if (lexer.token() == Token.IDENTIFIER) { - SQLIntervalUnit unit = SQLIntervalUnit.of(lexer.stringVal()); - if (unit != null) { - lexer.nextToken(); - } - - if (unit == SQLIntervalUnit.YEAR && lexer.nextIf(Token.TO)) { - if (lexer.nextIfIdentifier(FnvHash.Constants.MONTH)) { - unit = SQLIntervalUnit.YEAR_TO_MONTH; - } else { - throw new ParserException("parse interval unit error, " + lexer.info()); - } - } else if (unit == SQLIntervalUnit.DAY && lexer.nextIf(Token.TO)) { - if (lexer.nextIfIdentifier(FnvHash.Constants.SECOND)) { - unit = SQLIntervalUnit.DAY_HOUR; - } else { - throw new ParserException("parse interval unit error, " + lexer.info()); - } - } else if (unit == SQLIntervalUnit.HOUR && lexer.nextIf(Token.TO)) { - if (lexer.nextIfIdentifier(FnvHash.Constants.SECOND)) { - unit = SQLIntervalUnit.HOUR_SECOND; - } else { - throw new ParserException("parse interval unit error, " + lexer.info()); - } - } - - return unit; - } - return null; - } - public void parseAssignItems(List items, SQLObject parent, boolean variant) { for (; ; ) { SQLAssignItem item = parseAssignItem(variant, parent); diff --git a/core/src/test/resources/bvt/parser/impala/0.txt b/core/src/test/resources/bvt/parser/impala/0.txt index 529955c5c0..95bfacde0a 100644 --- a/core/src/test/resources/bvt/parser/impala/0.txt +++ b/core/src/test/resources/bvt/parser/impala/0.txt @@ -1,3 +1,19 @@ +select cast(concat('20', strleft(m_brd_season_name, 2)) as int) year + , strright(m_brd_season_name, 2) qtr + , m_brd_season_name + , product_no + , managing_provice_no + from dwd_kudu.t15_imp_key_pro + WHERE + m_brd_season_name > '23' + group by m_brd_season_name, product_no, managing_provice_no +-------------------- +SELECT CAST(concat('20', strleft(m_brd_season_name, 2)) AS int) AS year, strright(m_brd_season_name, 2) AS qtr, m_brd_season_name + , product_no, managing_provice_no +FROM dwd_kudu.t15_imp_key_pro +WHERE m_brd_season_name > '23' +GROUP BY m_brd_season_name, product_no, managing_provice_no +------------------------------------------------------------------------------------------------------------------------ SELECT a AS A FROM B AS b LEFT JOIN /* +shuffle */ ( select c from D d join E e on d.id=e.id where e.id = 'test' group by 1,2 ) f on b.id=f.id WHERE 1=1 GROUP BY a HAVING 1=1 limit 2000000 -------------------- SELECT a AS A