Skip to content

Commit a02fcf3

Browse files
committed
feat: parse PostgreSQL event triggers, REINDEX, SECURITY LABEL and schema elements
Add typed CreateEventTrigger, AlterEventTrigger, Reindex and SecurityLabel statements. Event triggers reuse the CREATE TRIGGER routine invocation and the shared trigger and rule enable states; SECURITY LABEL addresses routines through RoutineReference. REINDEX becomes a non-reserved keyword. CREATE SCHEMA parses PostgreSQL schema elements (CREATE TABLE, VIEW, INDEX, SEQUENCE, TRIGGER and GRANT), keeps their names as written and renders them, together with the PATH clause, in toString() and StatementDeParser. Signed-off-by: minleejae <mmj9808@gmail.com>
1 parent 6c5fc6c commit a02fcf3

22 files changed

Lines changed: 2000 additions & 25 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ and missing syntax gets added on demand — [open an issue](https://github.com/J
148148
| **MySQL account management** | `CREATE`/`ALTER`/`RENAME USER` · `CREATE ROLE` · `SET ROLE` · `SET DEFAULT ROLE` · `SET PASSWORD` |
149149
| **PostgreSQL RLS** | `CREATE POLICY` · `ALTER TABLE … ENABLE`/`DISABLE`/`FORCE`/`NO FORCE ROW LEVEL SECURITY` |
150150
| **Routine changes** | `ALTER FUNCTION` · `ALTER PROCEDURE` · `ALTER ROUTINE` · PostgreSQL `ALTER TRIGGER` |
151+
| **PostgreSQL administration** | `CREATE`/`ALTER EVENT TRIGGER` · `REINDEX` · `SECURITY LABEL` |
151152
| **Informix constraints** | `ALTER TABLE … ADD CONSTRAINT` with trailing constraint names for primary, unique, foreign and check constraints; enable with `parser.withDialect(Dialect.INFORMIX)` |
152153
| **Salesforce SOQL** | `INCLUDES` · `EXCLUDES` |
153154

‎src/main/java/net/sf/jsqlparser/parser/feature/Feature.java‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import net.sf.jsqlparser.statement.TableMaintenanceStatement;
3030
import net.sf.jsqlparser.statement.UseStatement;
3131
import net.sf.jsqlparser.statement.alter.Alter;
32+
import net.sf.jsqlparser.statement.alter.AlterEventTrigger;
3233
import net.sf.jsqlparser.statement.alter.sequence.AlterSequence;
3334
import net.sf.jsqlparser.statement.analyze.Analyze;
3435
import net.sf.jsqlparser.statement.comment.Comment;
@@ -40,6 +41,7 @@
4041
import net.sf.jsqlparser.statement.create.sequence.CreateSequence;
4142
import net.sf.jsqlparser.statement.create.synonym.CreateSynonym;
4243
import net.sf.jsqlparser.statement.create.table.CreateTable;
44+
import net.sf.jsqlparser.statement.create.trigger.CreateEventTrigger;
4345
import net.sf.jsqlparser.statement.create.view.AlterView;
4446
import net.sf.jsqlparser.statement.create.view.CreateView;
4547
import net.sf.jsqlparser.statement.delete.Delete;
@@ -48,6 +50,7 @@
4850
import net.sf.jsqlparser.statement.grant.Grant;
4951
import net.sf.jsqlparser.statement.merge.Merge;
5052
import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement;
53+
import net.sf.jsqlparser.statement.reindex.Reindex;
5154
import net.sf.jsqlparser.statement.role.ReassignOwned;
5255
import net.sf.jsqlparser.statement.select.Fetch;
5356
import net.sf.jsqlparser.statement.select.First;
@@ -61,6 +64,7 @@
6164
import net.sf.jsqlparser.statement.select.TableFunction;
6265
import net.sf.jsqlparser.statement.select.Top;
6366
import net.sf.jsqlparser.statement.select.UnPivot;
67+
import net.sf.jsqlparser.statement.securitylabel.SecurityLabel;
6468
import net.sf.jsqlparser.statement.show.*;
6569
import net.sf.jsqlparser.statement.truncate.Truncate;
6670
import net.sf.jsqlparser.statement.update.Update;
@@ -620,6 +624,26 @@ public enum Feature {
620624
* SQL "CREATE TRIGGER" statement is allowed
621625
*/
622626
createTrigger,
627+
/**
628+
* PostgreSQL "CREATE EVENT TRIGGER" and "ALTER EVENT TRIGGER" statements are allowed
629+
*
630+
* @see CreateEventTrigger
631+
* @see AlterEventTrigger
632+
*/
633+
createEventTrigger, alterEventTrigger,
634+
/**
635+
* PostgreSQL "REINDEX" statement is allowed; "REINDEX … CONCURRENTLY" additionally requires
636+
* {@link #reindexConcurrently}
637+
*
638+
* @see Reindex
639+
*/
640+
reindex, reindexConcurrently,
641+
/**
642+
* PostgreSQL "SECURITY LABEL" statement is allowed
643+
*
644+
* @see SecurityLabel
645+
*/
646+
securityLabel,
623647
/**
624648
* SQL "COMMIT" statement is allowed
625649
*

‎src/main/java/net/sf/jsqlparser/statement/StatementFeatureVisitor.java‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import net.sf.jsqlparser.statement.alter.AlterSession;
3939
import net.sf.jsqlparser.statement.alter.AlterStatistics;
4040
import net.sf.jsqlparser.statement.alter.AlterSubscription;
41+
import net.sf.jsqlparser.statement.alter.AlterEventTrigger;
4142
import net.sf.jsqlparser.statement.alter.AlterSystemStatement;
4243
import net.sf.jsqlparser.statement.alter.AlterTablespaceMove;
4344
import net.sf.jsqlparser.statement.alter.AlterTextSearchConfiguration;
@@ -72,6 +73,7 @@
7273
import net.sf.jsqlparser.statement.create.synonym.CreateSynonym;
7374
import net.sf.jsqlparser.statement.create.table.CreateTable;
7475
import net.sf.jsqlparser.statement.create.textsearch.CreateTextSearchConfiguration;
76+
import net.sf.jsqlparser.statement.create.trigger.CreateEventTrigger;
7577
import net.sf.jsqlparser.statement.create.trigger.CreateTrigger;
7678
import net.sf.jsqlparser.statement.create.type.CreateType;
7779
import net.sf.jsqlparser.statement.create.user.CreateUser;
@@ -97,6 +99,8 @@
9799
import net.sf.jsqlparser.statement.oracle.OracleBlock;
98100
import net.sf.jsqlparser.statement.oracle.OracleNullStatement;
99101
import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement;
102+
import net.sf.jsqlparser.statement.reindex.Reindex;
103+
import net.sf.jsqlparser.statement.securitylabel.SecurityLabel;
100104
import net.sf.jsqlparser.statement.role.AlterRole;
101105
import net.sf.jsqlparser.statement.role.CreateRole;
102106
import net.sf.jsqlparser.statement.role.ReassignOwned;
@@ -1080,6 +1084,29 @@ public <S> Void visit(CreateTrigger statement, S context) {
10801084
return schemaOnly();
10811085
}
10821086

1087+
@Override
1088+
public <S> Void visit(CreateEventTrigger statement, S context) {
1089+
return schemaOnly();
1090+
}
1091+
1092+
@Override
1093+
public <S> Void visit(AlterEventTrigger statement, S context) {
1094+
return schemaOnly();
1095+
}
1096+
1097+
@Override
1098+
public <S> Void visit(Reindex statement, S context) {
1099+
analysis.claimTopLevel();
1100+
// rebuilds index storage from the indexed rows
1101+
analysis.certain(StmtFeature.MODIFIES_SCHEMA, StmtFeature.READS_DATA);
1102+
return null;
1103+
}
1104+
1105+
@Override
1106+
public <S> Void visit(SecurityLabel statement, S context) {
1107+
return schemaOnly();
1108+
}
1109+
10831110
@Override
10841111
public <S> Void visit(CreateType statement, S context) {
10851112
analysis.claimTopLevel();

‎src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555

5656
import net.sf.jsqlparser.statement.alter.Alter;
5757
import net.sf.jsqlparser.statement.alter.AlterSession;
58+
import net.sf.jsqlparser.statement.alter.AlterEventTrigger;
5859
import net.sf.jsqlparser.statement.alter.AlterSystemStatement;
5960
import net.sf.jsqlparser.statement.alter.RenameTableStatement;
6061
import net.sf.jsqlparser.statement.alter.AlterUser;
@@ -71,6 +72,7 @@
7172
import net.sf.jsqlparser.statement.create.sequence.CreateSequence;
7273
import net.sf.jsqlparser.statement.create.synonym.CreateSynonym;
7374
import net.sf.jsqlparser.statement.create.table.CreateTable;
75+
import net.sf.jsqlparser.statement.create.trigger.CreateEventTrigger;
7476
import net.sf.jsqlparser.statement.create.trigger.CreateTrigger;
7577
import net.sf.jsqlparser.statement.create.user.CreateUser;
7678
import net.sf.jsqlparser.statement.create.view.AlterView;
@@ -88,6 +90,8 @@
8890
import net.sf.jsqlparser.statement.lock.LockStatement;
8991
import net.sf.jsqlparser.statement.merge.Merge;
9092
import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement;
93+
import net.sf.jsqlparser.statement.reindex.Reindex;
94+
import net.sf.jsqlparser.statement.securitylabel.SecurityLabel;
9195
import net.sf.jsqlparser.statement.select.Select;
9296
import net.sf.jsqlparser.statement.show.ShowIndexStatement;
9397
import net.sf.jsqlparser.statement.show.ShowTablesStatement;
@@ -276,6 +280,38 @@ default void visit(CreateTrigger createTrigger) {
276280
this.visit(createTrigger, null);
277281
}
278282

283+
default <S> T visit(CreateEventTrigger statement, S context) {
284+
return null;
285+
}
286+
287+
default void visit(CreateEventTrigger statement) {
288+
this.visit(statement, null);
289+
}
290+
291+
default <S> T visit(AlterEventTrigger statement, S context) {
292+
return null;
293+
}
294+
295+
default void visit(AlterEventTrigger statement) {
296+
this.visit(statement, null);
297+
}
298+
299+
default <S> T visit(Reindex statement, S context) {
300+
return null;
301+
}
302+
303+
default void visit(Reindex statement) {
304+
this.visit(statement, null);
305+
}
306+
307+
default <S> T visit(SecurityLabel statement, S context) {
308+
return null;
309+
}
310+
311+
default void visit(SecurityLabel statement) {
312+
this.visit(statement, null);
313+
}
314+
279315
<S> T visit(CreateView createView, S context);
280316

281317
default void visit(CreateView createView) {

‎src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import net.sf.jsqlparser.statement.alter.Alter;
5858
import net.sf.jsqlparser.statement.alter.AlterExpression;
5959
import net.sf.jsqlparser.statement.alter.AlterSession;
60+
import net.sf.jsqlparser.statement.alter.AlterEventTrigger;
6061
import net.sf.jsqlparser.statement.alter.AlterSystemStatement;
6162
import net.sf.jsqlparser.statement.alter.RenameTableStatement;
6263
import net.sf.jsqlparser.statement.alter.AlterUser;
@@ -73,6 +74,7 @@
7374
import net.sf.jsqlparser.statement.create.sequence.CreateSequence;
7475
import net.sf.jsqlparser.statement.create.synonym.CreateSynonym;
7576
import net.sf.jsqlparser.statement.create.table.CreateTable;
77+
import net.sf.jsqlparser.statement.create.trigger.CreateEventTrigger;
7678
import net.sf.jsqlparser.statement.create.trigger.CreateTrigger;
7779
import net.sf.jsqlparser.statement.create.user.CreateUser;
7880
import net.sf.jsqlparser.statement.create.view.AlterView;
@@ -93,6 +95,8 @@
9395
import net.sf.jsqlparser.statement.merge.MergeOperationVisitor;
9496
import net.sf.jsqlparser.statement.merge.MergeOperationVisitorAdapter;
9597
import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement;
98+
import net.sf.jsqlparser.statement.reindex.Reindex;
99+
import net.sf.jsqlparser.statement.securitylabel.SecurityLabel;
96100
import net.sf.jsqlparser.statement.select.FromItemVisitor;
97101
import net.sf.jsqlparser.statement.select.FromItemVisitorAdapter;
98102
import net.sf.jsqlparser.statement.select.PivotVisitor;
@@ -393,6 +397,7 @@ public <S> T visit(CreateIndex createIndex, S context) {
393397

394398
@Override
395399
public <S> T visit(CreateSchema createSchema, S context) {
400+
createSchema.getStatements().forEach(element -> element.accept(this, context));
396401
return null;
397402
}
398403

@@ -457,6 +462,32 @@ public <S> T visit(CreateTrigger createTrigger, S context) {
457462
return null;
458463
}
459464

465+
@Override
466+
public <S> T visit(CreateEventTrigger statement, S context) {
467+
statement.visitExpressions(expression -> expression.accept(expressionVisitor, context));
468+
return null;
469+
}
470+
471+
@Override
472+
public <S> T visit(AlterEventTrigger statement, S context) {
473+
return null;
474+
}
475+
476+
@Override
477+
public <S> T visit(Reindex statement, S context) {
478+
if (statement.getTable() != null) {
479+
statement.getTable().accept(fromItemVisitor, context);
480+
}
481+
return null;
482+
}
483+
484+
@Override
485+
public <S> T visit(SecurityLabel statement, S context) {
486+
statement.visitRelations(table -> table.accept(fromItemVisitor, context));
487+
expressionVisitor.visitExpression(statement.getLabel(), context);
488+
return null;
489+
}
490+
460491
@Override
461492
public <S> T visit(CreateView createView, S context) {
462493
createView.getView().accept(fromItemVisitor, context);
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2026 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.statement.alter;
11+
12+
import net.sf.jsqlparser.statement.Statement;
13+
import net.sf.jsqlparser.statement.StatementVisitor;
14+
15+
/**
16+
* A PostgreSQL {@code ALTER EVENT TRIGGER} statement. The enable states are shared with the trigger
17+
* and rule actions of {@link RelationAlterAction}. Each non-null setter selects its action and
18+
* discards the values of the other actions.
19+
*/
20+
public class AlterEventTrigger implements Statement {
21+
public enum Action {
22+
STATE, OWNER, RENAME
23+
}
24+
25+
private String name;
26+
private Action action;
27+
private RelationAlterAction.EnableState enableState;
28+
private String owner;
29+
private String newName;
30+
31+
@Override
32+
public <T, S> T accept(StatementVisitor<T> statementVisitor, S context) {
33+
return statementVisitor.visit(this, context);
34+
}
35+
36+
public String getName() {
37+
return name;
38+
}
39+
40+
public void setName(String name) {
41+
this.name = name;
42+
}
43+
44+
public Action getAction() {
45+
return action;
46+
}
47+
48+
/** {@code ENABLE}, {@code ENABLE REPLICA}, {@code ENABLE ALWAYS} or {@code DISABLE}. */
49+
public RelationAlterAction.EnableState getEnableState() {
50+
return enableState;
51+
}
52+
53+
public void setEnableState(RelationAlterAction.EnableState enableState) {
54+
if (enableState != null) {
55+
select(Action.STATE);
56+
}
57+
this.enableState = enableState;
58+
}
59+
60+
public String getOwner() {
61+
return owner;
62+
}
63+
64+
public void setOwner(String owner) {
65+
if (owner != null) {
66+
select(Action.OWNER);
67+
}
68+
this.owner = owner;
69+
}
70+
71+
public String getNewName() {
72+
return newName;
73+
}
74+
75+
public void setNewName(String newName) {
76+
if (newName != null) {
77+
select(Action.RENAME);
78+
}
79+
this.newName = newName;
80+
}
81+
82+
private void select(Action action) {
83+
this.action = action;
84+
enableState = null;
85+
owner = null;
86+
newName = null;
87+
}
88+
89+
public StringBuilder appendTo(StringBuilder sql) {
90+
sql.append("ALTER EVENT TRIGGER ").append(name);
91+
switch (action) {
92+
case STATE:
93+
sql.append(' ').append(enableState.name().replace('_', ' '));
94+
break;
95+
case OWNER:
96+
sql.append(" OWNER TO ").append(owner);
97+
break;
98+
case RENAME:
99+
sql.append(" RENAME TO ").append(newName);
100+
break;
101+
default:
102+
throw new IllegalStateException("Unknown event trigger action: " + action);
103+
}
104+
return sql;
105+
}
106+
107+
@Override
108+
public String toString() {
109+
return appendTo(new StringBuilder()).toString();
110+
}
111+
112+
public AlterEventTrigger withName(String name) {
113+
setName(name);
114+
return this;
115+
}
116+
117+
public AlterEventTrigger withEnableState(RelationAlterAction.EnableState enableState) {
118+
setEnableState(enableState);
119+
return this;
120+
}
121+
122+
public AlterEventTrigger withOwner(String owner) {
123+
setOwner(owner);
124+
return this;
125+
}
126+
127+
public AlterEventTrigger withNewName(String newName) {
128+
setNewName(newName);
129+
return this;
130+
}
131+
}

0 commit comments

Comments
 (0)