Details
-
Bug
-
Status: Closed
-
Minor
-
Resolution: Fixed
-
None
Description
Following my email on Calcite's dev mailing list, julianhyde told me to open an issue as there is likely a bug in Babel's parser regarding IF statements.
You can find the email with this title: Error parsing DATE("2021-01-01") for BigQuery using Calcite
The symptoms are the following:
- If I use SqlParserImpl.FACTORY, most statements work but DATE(string) fails, likely because it's a reserved keyword, as Julian pointed out in the mail thread. Statements such as IF(cond, then, else) work, as well as other dialect-specific functions such as CURRENT_DATETIME() [Bigquery].
- If I use SqlBabelParserImpl.FACTORY, it will work for parsing DATE(string), it also works for dialect-specific functions, but it doesn't work for IF(cond, then, else).
Here is a table to sum it up:
Test | Normal parser | Babel |
---|---|---|
1+(2*4) as foo | SUCCESS | SUCCESS |
CURRENT_DATE() | SUCCESS | SUCCESS |
CURRENT_DATETIME() | SUCCESS | SUCCESS |
DATE_FROM_UNIX(123456) | SUCCESS | SUCCESS |
IF(TRUE, 1, 2) | SUCCESS | FAILURE |
DATE("2021-01-01") | FAILURE | SUCCESS |
Here is the code I use to check:
package test.Test; import org.apache.calcite.config.Lex; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.parser.SqlParseException; import org.apache.calcite.sql.parser.SqlParser; import org.apache.calcite.sql.parser.babel.SqlBabelParserImpl; import org.apache.calcite.sql.parser.impl.SqlParserImpl; import org.apache.calcite.sql.validate.SqlConformanceEnum; import org.apache.calcite.tools.FrameworkConfig; import org.apache.calcite.tools.Frameworks; import org.apache.calcite.tools.Planner; import java.util.HashMap; import java.util.Map; public class Test { public static void main(String[] args) { SqlParser.Config sqlParserConfigBabel = SqlParser.config().DEFAULT .withLex(Lex.BIG_QUERY) .withConformance(SqlConformanceEnum.BIG_QUERY) .withParserFactory(SqlBabelParserImpl.FACTORY); SqlParser.Config sqlParserConfigNotBabel = SqlParser.config().DEFAULT .withLex(Lex.BIG_QUERY) .withConformance(SqlConformanceEnum.BIG_QUERY) .withParserFactory(SqlParserImpl.FACTORY); Map<String, SqlParser.Config> parserConfigs = new HashMap<String, SqlParser.Config>(); parserConfigs.put("With babel", sqlParserConfigBabel); parserConfigs.put("Without babel", sqlParserConfigNotBabel); String[] testSqlFragments = { "1+(2*4) as foo", "CURRENT_DATE()", "CURRENT_DATETIME()", "DATE_FROM_UNIX(123456)", "IF(TRUE, 1, 2)", "DATE('2021-01-01')", }; for (String sqlFragment : testSqlFragments) { String query = "SELECT " + sqlFragment; System.out.println("Trying to parse : " + query); for (var config : parserConfigs.entrySet()) { System.out.print(config.getKey() + " : "); try { FrameworkConfig frameworkConfig = Frameworks.newConfigBuilder() .parserConfig(config.getValue()) .build(); Planner planner = Frameworks.getPlanner(frameworkConfig); SqlNode node = planner.parse(query); System.out.println("SUCCESS"); } catch (SqlParseException e) { System.out.println("ERROR"); } } } } }
And here is the output of that code:
Trying to parse : SELECT 1+(2*4) as foo Without babel : SUCCESS With babel : SUCCESS Trying to parse : SELECT CURRENT_DATE() Without babel : SUCCESS With babel : SUCCESS Trying to parse : SELECT CURRENT_DATETIME() Without babel : SUCCESS With babel : SUCCESS Trying to parse : SELECT DATE_FROM_UNIX(123456) Without babel : SUCCESS With babel : SUCCESS Trying to parse : SELECT IF(TRUE, 1, 2) Without babel : SUCCESS With babel : ERROR Trying to parse : SELECT DATE('2021-01-01') Without babel : ERROR With babel : SUCCESS Process finished with exit code 0
Please tell me if I can be of any help on this issue, or if it's too deep into the project and a newcomer can't solve this.
Have a great day
Attachments
Issue Links
- links to