From e31c4937dac6e9c46d56c79da94347d48f636c99 Mon Sep 17 00:00:00 2001 From: Jules Ivanic Date: Tue, 13 Oct 2026 10:23:49 +1100 Subject: [PATCH] Allow `ERRORS` as an unquoted identifier `ERRORS` was declared in the reserved keyword block when the Exasol IMPORT/EXPORT error clauses were added (#2256), so 5.4 rejects queries using it as a name, e.g. `SELECT errors FROM t` or a `WITH errors AS (...)` CTE, which DuckDB, PostgreSQL and most databases accept. Its only uses, `ERRORS INTO ...` and `REJECT LIMIT n ERRORS`, are behind lookaheads, so it moves to the non-reserved keywords next to `ERROR`. The Exasol IMPORT/EXPORT tests still pass. --- .../jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt | 2 +- src/site/sphinx/keywords.rst | 2 -- .../java/net/sf/jsqlparser/statement/KeywordsTest.java | 10 ++++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 50d98ed835..6bbe251c53 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -2535,6 +2535,7 @@ String NonReservedWord() : | tk= | tk= | tk= + | tk= | tk= | tk= | tk= @@ -2866,7 +2867,6 @@ TOKEN: /* Reserved SQL Keywords and structural tokens */ | | | -| | | /* Salesforce SOQL */ | diff --git a/src/site/sphinx/keywords.rst b/src/site/sphinx/keywords.rst index a9058fbaad..ed27b60603 100644 --- a/src/site/sphinx/keywords.rst +++ b/src/site/sphinx/keywords.rst @@ -47,8 +47,6 @@ The following Keywords are **reserved** in JSQLParser-|JSQLPARSER_VERSION| and m +---------------------------+ | ELSE | +---------------------------+ -| ERRORS | -+---------------------------+ | EXCEPT | +---------------------------+ | EXCLUDES | diff --git a/src/test/java/net/sf/jsqlparser/statement/KeywordsTest.java b/src/test/java/net/sf/jsqlparser/statement/KeywordsTest.java index 9e2c14ce7e..c349e92c94 100644 --- a/src/test/java/net/sf/jsqlparser/statement/KeywordsTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/KeywordsTest.java @@ -62,4 +62,14 @@ public void testGroupsAsIdentifier() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("SELECT a groups FROM mytable", true); assertSqlCanBeParsedAndDeparsed("CREATE TABLE mytable (groups INT)", true); } + + // ERRORS introduces Exasol's IMPORT/EXPORT error clauses but is an ordinary name elsewhere, + // e.g. a DuckDB column holding the errors of an upstream step. + @Test + public void testErrorsAsIdentifier() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("SELECT errors FROM mytable", true); + assertSqlCanBeParsedAndDeparsed("SELECT t.errors AS errors FROM mytable t", true); + assertSqlCanBeParsedAndDeparsed("WITH errors AS (SELECT 1) SELECT * FROM errors", true); + assertSqlCanBeParsedAndDeparsed("CREATE TABLE mytable (errors VARCHAR)", true); + } }