From 58fc796ac54d6c7558447450d1d85c3af0b43f3a Mon Sep 17 00:00:00 2001 From: Knut Wannheden Date: Thu, 29 Oct 2026 02:19:31 +0100 Subject: [PATCH 1/7] fix: give arithmetic expressions an AST node prattArithRest builds operator expressions in plain Java, outside any production, so JJTree never opened a node for them and `CURRENT_DATE - 7` or `a || b` had no source range. Each expression the loop builds is now linked to a node from the token its operand chain starts at to the last token consumed. The node stays out of the tree, so the operands' nodes keep their place. --- .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 26 ++++++++++++++++--- .../statement/select/SelectASTTest.java | 22 ++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index f2bf3b59cb..d7a4c9a6c8 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -301,6 +301,18 @@ public class CCJSqlParser extends AbstractJSqlParser { } } + /** + * Links an expression the operator loop builds, which no production opens a node for, to a node + * spanning its tokens from {@code first} to the last one consumed. The node is left out of the + * tree, so the operands' nodes keep their place in it. + */ + private void linkAST(ASTNodeAccess access, Token first) { + Node node = new Node(this, JJTEXPRESSION); + node.jjtSetFirstToken(first); + node.jjtSetLastToken(getToken(0)); + linkAST(access, node); + } + public Node getASTRoot() { return jjtree.rootNode(); } @@ -1002,7 +1014,7 @@ public class CCJSqlParser extends AbstractJSqlParser { return kind == K_RETURNING || kind == K_ABSENT && getToken(2).kind == K_ON; } - protected Expression prattArithRest(Expression left, int minPrec) throws ParseException { + protected Expression prattArithRest(Expression left, Token first, int minPrec) throws ParseException { while (!interrupted) { Token t = getToken(1); int op = t.kind; @@ -1051,13 +1063,16 @@ public class CCJSqlParser extends AbstractJSqlParser { if (op == OP_PIPE && getToken(2).kind == OP_PIPE) { jj_consume_token(OP_PIPE, getToken(1).image); jj_consume_token(OP_PIPE, getToken(1).image); - Expression right = prattArithRest(PrimaryExpression(), prec + 1); + Token rightFirst = getToken(1); + Expression right = prattArithRest(PrimaryExpression(), rightFirst, prec + 1); Concat r = new Concat(); r.setLeftExpression(left); r.setRightExpression(right); left = r; + linkAST(left, first); continue; } jj_consume_token(op, getToken(1).image); - Expression right = prattArithRest(PrimaryExpression(), prec + 1); + Token rightFirst = getToken(1); + Expression right = prattArithRest(PrimaryExpression(), rightFirst, prec + 1); if (jsonAccess) { JsonExpression access = left instanceof JsonExpression @@ -1087,6 +1102,7 @@ public class CCJSqlParser extends AbstractJSqlParser { else if ("&".equals(img)) { BitwiseAnd r = new BitwiseAnd(); r.setLeftExpression(left); r.setRightExpression(right); left = r; } else if ("<->".equals(img) || "<#>".equals(img)) { GeometryDistance r = new GeometryDistance(img); r.setLeftExpression(left); r.setRightExpression(right); left = r; } } + linkAST(left, first); } return left; } @@ -12944,16 +12960,18 @@ Expression SimpleExpression(): Expression retval = null; UserVariable user = null; Token operation = null; + Token first; } { [ LOOKAHEAD( 5, { getToken(1).kind == S_AT_IDENTIFIER } ) user = UserVariable() ( operation = "=" | operation = ":=" ) ] + { first = getToken(1); } retval=PrimaryExpression() // PostgreSQL path operators bind below arithmetic and above comparisons. // MySQL also gives | and & their own tiers below <<, >>, so the loop's // entry floor drops to 2 there instead of the shared bitwise level 4. { int arithFloor = Dialect.MYSQL.name().equals(getAsString(Feature.dialect)) ? 2 : 4; - retval = prattArithRest(retval, arithFloor); + retval = prattArithRest(retval, first, arithFloor); } { if (user != null) { diff --git a/src/test/java/net/sf/jsqlparser/statement/select/SelectASTTest.java b/src/test/java/net/sf/jsqlparser/statement/select/SelectASTTest.java index 5fd6a79301..f46c1a2384 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/SelectASTTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/SelectASTTest.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.List; import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.expression.BinaryExpression; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.parser.ASTNodeAccess; @@ -203,6 +204,27 @@ public void testBinaryConditionNodeStartsAtItsLeftOperand() throws JSQLParserExc } } + @Test + public void testOperatorExpressionNodeSpansItsOperands() throws JSQLParserException { + String sql = "SELECT a - 1 - 2, 1 + 2 * 3, a | | b FROM t WHERE d > CURRENT_DATE - 7"; + PlainSelect select = (PlainSelect) CCJSqlParserUtil.parse(sql); + BinaryExpression chain = (BinaryExpression) select.getSelectItem(0).getExpression(); + BinaryExpression precedence = (BinaryExpression) select.getSelectItem(1).getExpression(); + + assertEquals("a - 1 - 2", source(sql, chain)); + assertEquals("a - 1", source(sql, chain.getLeftExpression())); + assertEquals("2 * 3", source(sql, precedence.getRightExpression())); + assertEquals("a | | b", source(sql, select.getSelectItem(2).getExpression())); + assertEquals("CURRENT_DATE - 7", + source(sql, ((BinaryExpression) select.getWhere()).getRightExpression())); + } + + private static String source(String sql, Expression expression) { + Node node = expression.getASTNode(); + return sql.substring(node.jjtGetFirstToken().absoluteBegin - 1, + node.jjtGetLastToken().absoluteEnd - 1); + } + @Test public void testSelectASTExtractWithCommentsIssue1580() throws JSQLParserException { String sql = From 287ee1806f01254b556c25320db12aed8e08d9d1 Mon Sep 17 00:00:00 2001 From: Knut Wannheden Date: Thu, 29 Oct 2026 03:52:16 +0100 Subject: [PATCH 2/7] refactor: let every statement class carry an AST node The statement classes that implemented Statement alone now extend ASTNodeAccessImpl, as Select and Import already did, so a parsed statement can hold the node that records its source range. Nothing links them yet. --- .../java/net/sf/jsqlparser/statement/AssertStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/AttachStatement.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/Block.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/Commit.java | 4 +++- .../java/net/sf/jsqlparser/statement/ConnectStatement.java | 4 +++- src/main/java/net/sf/jsqlparser/statement/CopyStatement.java | 3 ++- .../sf/jsqlparser/statement/CreateFunctionalStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/DeallocateStatement.java | 4 +++- .../java/net/sf/jsqlparser/statement/DeclareStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/DescribeStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/DetachStatement.java | 4 +++- .../java/net/sf/jsqlparser/statement/DisconnectStatement.java | 4 +++- src/main/java/net/sf/jsqlparser/statement/DoStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/ExplainStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/ExtensionStatement.java | 4 +++- .../java/net/sf/jsqlparser/statement/IfElseStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/PragmaStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/PrepareStatement.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/PurgeStatement.java | 3 ++- .../sf/jsqlparser/statement/ReleaseSavepointStatement.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/ResetStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/RollbackStatement.java | 4 +++- .../java/net/sf/jsqlparser/statement/SavepointStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/SessionStatement.java | 3 ++- .../net/sf/jsqlparser/statement/SetDefaultRoleStatement.java | 3 ++- .../sf/jsqlparser/statement/SetIdentityInsertStatement.java | 3 ++- .../net/sf/jsqlparser/statement/SetPasswordStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/SetRoleStatement.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/SetStatement.java | 3 ++- .../net/sf/jsqlparser/statement/ShowColumnsStatement.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/ShowStatement.java | 4 +++- .../java/net/sf/jsqlparser/statement/StartTransaction.java | 3 ++- .../sf/jsqlparser/statement/TableMaintenanceStatement.java | 3 ++- .../net/sf/jsqlparser/statement/UnsupportedStatement.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/UseStatement.java | 4 +++- src/main/java/net/sf/jsqlparser/statement/alter/Alter.java | 3 ++- .../net/sf/jsqlparser/statement/alter/AlterCollation.java | 3 ++- .../java/net/sf/jsqlparser/statement/alter/AlterDomain.java | 3 ++- .../net/sf/jsqlparser/statement/alter/AlterEventTrigger.java | 3 ++- .../net/sf/jsqlparser/statement/alter/AlterExtension.java | 3 ++- .../java/net/sf/jsqlparser/statement/alter/AlterPolicy.java | 3 ++- .../net/sf/jsqlparser/statement/alter/AlterPublication.java | 3 ++- .../java/net/sf/jsqlparser/statement/alter/AlterRelation.java | 3 ++- .../java/net/sf/jsqlparser/statement/alter/AlterRoutine.java | 3 ++- .../java/net/sf/jsqlparser/statement/alter/AlterSession.java | 3 ++- .../net/sf/jsqlparser/statement/alter/AlterStatistics.java | 3 ++- .../net/sf/jsqlparser/statement/alter/AlterSubscription.java | 3 ++- .../sf/jsqlparser/statement/alter/AlterSystemStatement.java | 3 ++- .../net/sf/jsqlparser/statement/alter/AlterTablespace.java | 3 ++- .../sf/jsqlparser/statement/alter/AlterTablespaceMove.java | 3 ++- .../statement/alter/AlterTextSearchConfiguration.java | 3 ++- .../java/net/sf/jsqlparser/statement/alter/AlterTrigger.java | 3 ++- .../java/net/sf/jsqlparser/statement/alter/AlterType.java | 3 ++- .../java/net/sf/jsqlparser/statement/alter/AlterUser.java | 3 ++- .../sf/jsqlparser/statement/alter/RenameTableStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/alter/RenameUser.java | 3 ++- .../sf/jsqlparser/statement/alter/database/AlterDatabase.java | 3 ++- .../net/sf/jsqlparser/statement/alter/schema/AlterSchema.java | 3 ++- .../sf/jsqlparser/statement/alter/sequence/AlterSequence.java | 3 ++- .../java/net/sf/jsqlparser/statement/analyze/Analyze.java | 3 ++- .../java/net/sf/jsqlparser/statement/comment/Comment.java | 3 ++- .../statement/create/accessmethod/CreateAccessMethod.java | 3 ++- .../statement/create/collation/CreateCollation.java | 3 ++- .../jsqlparser/statement/create/database/CreateDatabase.java | 3 ++- .../sf/jsqlparser/statement/create/domain/CreateDomain.java | 3 ++- .../sf/jsqlparser/statement/create/event/EventStatement.java | 3 ++- .../statement/create/extension/CreateExtension.java | 3 ++- .../statement/create/extension/CreateExtensionRepository.java | 3 ++- .../net/sf/jsqlparser/statement/create/index/CreateIndex.java | 3 ++- .../net/sf/jsqlparser/statement/create/macro/CreateMacro.java | 3 ++- .../sf/jsqlparser/statement/create/policy/CreatePolicy.java | 3 ++- .../statement/create/publication/CreatePublication.java | 3 ++- .../net/sf/jsqlparser/statement/create/rule/CreateRule.java | 3 ++- .../sf/jsqlparser/statement/create/schema/CreateSchema.java | 3 ++- .../jsqlparser/statement/create/sequence/CreateSequence.java | 3 ++- .../statement/create/statistics/CreateStatistics.java | 3 ++- .../statement/create/subscription/CreateSubscription.java | 3 ++- .../sf/jsqlparser/statement/create/synonym/CreateSynonym.java | 3 ++- .../net/sf/jsqlparser/statement/create/table/CreateTable.java | 3 ++- .../statement/create/tablespace/CreateTablespace.java | 3 ++- .../create/textsearch/CreateTextSearchConfiguration.java | 3 ++- .../statement/create/trigger/CreateEventTrigger.java | 3 ++- .../sf/jsqlparser/statement/create/trigger/CreateTrigger.java | 3 ++- .../net/sf/jsqlparser/statement/create/type/CreateType.java | 3 ++- .../net/sf/jsqlparser/statement/create/user/CreateUser.java | 3 ++- .../net/sf/jsqlparser/statement/create/view/AlterView.java | 3 ++- .../net/sf/jsqlparser/statement/create/view/CreateView.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/delete/Delete.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/drop/Drop.java | 3 ++- .../java/net/sf/jsqlparser/statement/drop/DropPolicy.java | 3 ++- .../java/net/sf/jsqlparser/statement/execute/Execute.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/export/Export.java | 3 ++- .../sf/jsqlparser/statement/export/ExportDataStatement.java | 3 ++- .../sf/jsqlparser/statement/foreign/ForeignDataStatement.java | 3 ++- .../sf/jsqlparser/statement/grant/AlterDefaultPrivileges.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/grant/Grant.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/grant/Revoke.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/insert/Insert.java | 3 ++- .../java/net/sf/jsqlparser/statement/insert/InsertBulk.java | 3 ++- .../net/sf/jsqlparser/statement/load/LoadDataStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/lock/LockStatement.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/merge/Merge.java | 3 ++- .../net/sf/jsqlparser/statement/notify/NotifyStatement.java | 3 ++- .../net/sf/jsqlparser/statement/oracle/OracleAssignment.java | 3 ++- .../sf/jsqlparser/statement/oracle/OracleNullStatement.java | 3 ++- .../statement/refresh/RefreshMaterializedViewStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/reindex/Reindex.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/role/AlterRole.java | 3 ++- .../java/net/sf/jsqlparser/statement/role/CreateRole.java | 3 ++- .../java/net/sf/jsqlparser/statement/role/ReassignOwned.java | 3 ++- .../sf/jsqlparser/statement/securitylabel/SecurityLabel.java | 3 ++- .../net/sf/jsqlparser/statement/show/ShowCreateStatement.java | 3 ++- .../net/sf/jsqlparser/statement/show/ShowIndexStatement.java | 3 ++- .../jsqlparser/statement/show/ShowTableStatusStatement.java | 3 ++- .../net/sf/jsqlparser/statement/show/ShowTablesStatement.java | 3 ++- .../java/net/sf/jsqlparser/statement/truncate/Truncate.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/update/Update.java | 3 ++- src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java | 3 ++- 118 files changed, 245 insertions(+), 118 deletions(-) diff --git a/src/main/java/net/sf/jsqlparser/statement/AssertStatement.java b/src/main/java/net/sf/jsqlparser/statement/AssertStatement.java index 1e5a742982..58a294bb5f 100644 --- a/src/main/java/net/sf/jsqlparser/statement/AssertStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/AssertStatement.java @@ -11,6 +11,7 @@ import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.StringValue; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; import java.util.function.Consumer; @@ -22,7 +23,7 @@ * "https://cloud.google.com/bigquery/docs/reference/standard-sql/debugging-statements">Debugging * statements */ -public class AssertStatement implements Statement { +public class AssertStatement extends ASTNodeAccessImpl implements Statement { private Expression expression; private StringValue description; diff --git a/src/main/java/net/sf/jsqlparser/statement/AttachStatement.java b/src/main/java/net/sf/jsqlparser/statement/AttachStatement.java index 7ad71dd546..84726280d1 100644 --- a/src/main/java/net/sf/jsqlparser/statement/AttachStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/AttachStatement.java @@ -9,6 +9,7 @@ */ package net.sf.jsqlparser.statement; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; import net.sf.jsqlparser.statement.select.PlainSelect; import java.util.List; @@ -19,7 +20,7 @@ * * @see ATTACH */ -public class AttachStatement implements Statement { +public class AttachStatement extends ASTNodeAccessImpl implements Statement { private String databasePath; private String alias; private boolean usingDatabaseKeyword; diff --git a/src/main/java/net/sf/jsqlparser/statement/Block.java b/src/main/java/net/sf/jsqlparser/statement/Block.java index f609e58262..a4e822f01b 100644 --- a/src/main/java/net/sf/jsqlparser/statement/Block.java +++ b/src/main/java/net/sf/jsqlparser/statement/Block.java @@ -10,8 +10,9 @@ package net.sf.jsqlparser.statement; import java.util.function.Consumer; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; -public class Block implements Statement { +public class Block extends ASTNodeAccessImpl implements Statement { private boolean hasSemicolonAfterEnd = false; private Statements statements; diff --git a/src/main/java/net/sf/jsqlparser/statement/Commit.java b/src/main/java/net/sf/jsqlparser/statement/Commit.java index 20df0a111c..37205308fc 100644 --- a/src/main/java/net/sf/jsqlparser/statement/Commit.java +++ b/src/main/java/net/sf/jsqlparser/statement/Commit.java @@ -9,7 +9,9 @@ */ package net.sf.jsqlparser.statement; -public class Commit implements Statement { +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; + +public class Commit extends ASTNodeAccessImpl implements Statement { private TransactionKeyword keyword; private TransactionChain chain; diff --git a/src/main/java/net/sf/jsqlparser/statement/ConnectStatement.java b/src/main/java/net/sf/jsqlparser/statement/ConnectStatement.java index a5ae350c64..829410b280 100644 --- a/src/main/java/net/sf/jsqlparser/statement/ConnectStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/ConnectStatement.java @@ -9,11 +9,13 @@ */ package net.sf.jsqlparser.statement; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; + /** * DuckDB's {@code CONNECT target [AS alias]}, which routes the session's queries to a remote * database. */ -public class ConnectStatement implements Statement { +public class ConnectStatement extends ASTNodeAccessImpl implements Statement { private String target; private String alias; diff --git a/src/main/java/net/sf/jsqlparser/statement/CopyStatement.java b/src/main/java/net/sf/jsqlparser/statement/CopyStatement.java index 0e05b58636..2697677dbb 100644 --- a/src/main/java/net/sf/jsqlparser/statement/CopyStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/CopyStatement.java @@ -10,6 +10,7 @@ package net.sf.jsqlparser.statement; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.select.PlainSelect; @@ -25,7 +26,7 @@ * * @see COPY */ -public class CopyStatement implements Statement { +public class CopyStatement extends ASTNodeAccessImpl implements Statement { private Table table; private ExpressionList columns; private Select select; diff --git a/src/main/java/net/sf/jsqlparser/statement/CreateFunctionalStatement.java b/src/main/java/net/sf/jsqlparser/statement/CreateFunctionalStatement.java index d3f75a1278..b1978dc4a6 100644 --- a/src/main/java/net/sf/jsqlparser/statement/CreateFunctionalStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/CreateFunctionalStatement.java @@ -15,13 +15,14 @@ import java.util.List; import java.util.Optional; import java.util.function.Consumer; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; import net.sf.jsqlparser.statement.create.function.FunctionReturnType; import net.sf.jsqlparser.statement.create.table.TableElement; /** * A base for the declaration of function like statements */ -public abstract class CreateFunctionalStatement implements Statement { +public abstract class CreateFunctionalStatement extends ASTNodeAccessImpl implements Statement { private String kind; private boolean orReplace = false; diff --git a/src/main/java/net/sf/jsqlparser/statement/DeallocateStatement.java b/src/main/java/net/sf/jsqlparser/statement/DeallocateStatement.java index 25d375e38b..58b0fe34cd 100644 --- a/src/main/java/net/sf/jsqlparser/statement/DeallocateStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/DeallocateStatement.java @@ -9,10 +9,12 @@ */ package net.sf.jsqlparser.statement; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; + /** * {@code DEALLOCATE [PREPARE] name}, which drops a statement prepared by {@link PrepareStatement}. */ -public class DeallocateStatement implements Statement { +public class DeallocateStatement extends ASTNodeAccessImpl implements Statement { private String name; private boolean usingPrepareKeyword; diff --git a/src/main/java/net/sf/jsqlparser/statement/DeclareStatement.java b/src/main/java/net/sf/jsqlparser/statement/DeclareStatement.java index 27537bc5ff..c189280b54 100644 --- a/src/main/java/net/sf/jsqlparser/statement/DeclareStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/DeclareStatement.java @@ -18,10 +18,11 @@ import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.UserVariable; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; import net.sf.jsqlparser.statement.create.table.ColDataType; import net.sf.jsqlparser.statement.create.table.ColumnDefinition; -public final class DeclareStatement implements Statement { +public final class DeclareStatement extends ASTNodeAccessImpl implements Statement { private UserVariable userVariable = null; private DeclareType declareType = DeclareType.TYPE; diff --git a/src/main/java/net/sf/jsqlparser/statement/DescribeStatement.java b/src/main/java/net/sf/jsqlparser/statement/DescribeStatement.java index 054b648436..2efedba2d1 100644 --- a/src/main/java/net/sf/jsqlparser/statement/DescribeStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/DescribeStatement.java @@ -9,10 +9,11 @@ */ package net.sf.jsqlparser.statement; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.select.Select; -public class DescribeStatement implements Statement { +public class DescribeStatement extends ASTNodeAccessImpl implements Statement { private Table table; private Select select; diff --git a/src/main/java/net/sf/jsqlparser/statement/DetachStatement.java b/src/main/java/net/sf/jsqlparser/statement/DetachStatement.java index 80fe5780a9..d8bd25f810 100644 --- a/src/main/java/net/sf/jsqlparser/statement/DetachStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/DetachStatement.java @@ -9,12 +9,14 @@ */ package net.sf.jsqlparser.statement; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; + /** * DuckDB's {@code DETACH [DATABASE] [IF EXISTS] name}, the counterpart of {@link AttachStatement}. * * @see DETACH */ -public class DetachStatement implements Statement { +public class DetachStatement extends ASTNodeAccessImpl implements Statement { private String databaseName; private boolean usingDatabaseKeyword; private boolean ifExists; diff --git a/src/main/java/net/sf/jsqlparser/statement/DisconnectStatement.java b/src/main/java/net/sf/jsqlparser/statement/DisconnectStatement.java index fdbe6f4e71..1231963f67 100644 --- a/src/main/java/net/sf/jsqlparser/statement/DisconnectStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/DisconnectStatement.java @@ -9,10 +9,12 @@ */ package net.sf.jsqlparser.statement; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; + /** * DuckDB's {@code DISCONNECT [name]}, the counterpart of {@link ConnectStatement}. */ -public class DisconnectStatement implements Statement { +public class DisconnectStatement extends ASTNodeAccessImpl implements Statement { private String name; public DisconnectStatement() {} diff --git a/src/main/java/net/sf/jsqlparser/statement/DoStatement.java b/src/main/java/net/sf/jsqlparser/statement/DoStatement.java index c595ea1a32..4f21c91f6a 100644 --- a/src/main/java/net/sf/jsqlparser/statement/DoStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/DoStatement.java @@ -11,9 +11,10 @@ import java.util.function.Consumer; import net.sf.jsqlparser.expression.StringValue; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; /** A PostgreSQL anonymous routine. The language-specific body remains a string literal. */ -public class DoStatement implements Statement { +public class DoStatement extends ASTNodeAccessImpl implements Statement { private StringValue code; private String language; private boolean languageBeforeCode; diff --git a/src/main/java/net/sf/jsqlparser/statement/ExplainStatement.java b/src/main/java/net/sf/jsqlparser/statement/ExplainStatement.java index 5442ce4c5e..22db6859f9 100644 --- a/src/main/java/net/sf/jsqlparser/statement/ExplainStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/ExplainStatement.java @@ -14,12 +14,13 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; import net.sf.jsqlparser.schema.Table; /** * An {@code EXPLAIN} statement */ -public class ExplainStatement implements Statement { +public class ExplainStatement extends ASTNodeAccessImpl implements Statement { private String keyword; private Statement statement; private List