Skip to content

Commit f629584

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 f6ac257 commit f629584

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
@@ -146,6 +146,7 @@ and missing syntax gets added on demand — [open an issue](https://github.com/J
146146
| **PostgreSQL ownership** | `DROP OWNED` · `REASSIGN OWNED` |
147147
| **MySQL table maintenance** | `ANALYZE` · `CHECK` · `OPTIMIZE` · `REPAIR TABLE` |
148148
| **PostgreSQL RLS** | `CREATE POLICY` · `ALTER TABLE … ENABLE`/`DISABLE`/`FORCE`/`NO FORCE ROW LEVEL SECURITY` |
149+
| **PostgreSQL administration** | `CREATE`/`ALTER EVENT TRIGGER` · `REINDEX` · `SECURITY LABEL` |
149150
| **Informix constraints** | `ALTER TABLE … ADD CONSTRAINT` with trailing constraint names for primary, unique, foreign and check constraints; enable with `parser.withDialect(Dialect.INFORMIX)` |
150151
| **Salesforce SOQL** | `INCLUDES` · `EXCLUDES` |
151152

‎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
@@ -36,6 +36,7 @@
3636
import net.sf.jsqlparser.statement.alter.AlterSession;
3737
import net.sf.jsqlparser.statement.alter.AlterStatistics;
3838
import net.sf.jsqlparser.statement.alter.AlterSubscription;
39+
import net.sf.jsqlparser.statement.alter.AlterEventTrigger;
3940
import net.sf.jsqlparser.statement.alter.AlterSystemStatement;
4041
import net.sf.jsqlparser.statement.alter.AlterTablespaceMove;
4142
import net.sf.jsqlparser.statement.alter.AlterTextSearchConfiguration;
@@ -68,6 +69,7 @@
6869
import net.sf.jsqlparser.statement.create.synonym.CreateSynonym;
6970
import net.sf.jsqlparser.statement.create.table.CreateTable;
7071
import net.sf.jsqlparser.statement.create.textsearch.CreateTextSearchConfiguration;
72+
import net.sf.jsqlparser.statement.create.trigger.CreateEventTrigger;
7173
import net.sf.jsqlparser.statement.create.trigger.CreateTrigger;
7274
import net.sf.jsqlparser.statement.create.type.CreateType;
7375
import net.sf.jsqlparser.statement.create.user.CreateUser;
@@ -93,6 +95,8 @@
9395
import net.sf.jsqlparser.statement.oracle.OracleBlock;
9496
import net.sf.jsqlparser.statement.oracle.OracleNullStatement;
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.role.AlterRole;
97101
import net.sf.jsqlparser.statement.role.CreateRole;
98102
import net.sf.jsqlparser.statement.role.ReassignOwned;
@@ -1071,6 +1075,29 @@ public <S> Void visit(CreateTrigger statement, S context) {
10711075
return schemaOnly();
10721076
}
10731077

1078+
@Override
1079+
public <S> Void visit(CreateEventTrigger statement, S context) {
1080+
return schemaOnly();
1081+
}
1082+
1083+
@Override
1084+
public <S> Void visit(AlterEventTrigger statement, S context) {
1085+
return schemaOnly();
1086+
}
1087+
1088+
@Override
1089+
public <S> Void visit(Reindex statement, S context) {
1090+
analysis.claimTopLevel();
1091+
// rebuilds index storage from the indexed rows
1092+
analysis.certain(StmtFeature.MODIFIES_SCHEMA, StmtFeature.READS_DATA);
1093+
return null;
1094+
}
1095+
1096+
@Override
1097+
public <S> Void visit(SecurityLabel statement, S context) {
1098+
return schemaOnly();
1099+
}
1100+
10741101
@Override
10751102
public <S> Void visit(CreateType statement, S context) {
10761103
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
@@ -53,6 +53,7 @@
5353

5454
import net.sf.jsqlparser.statement.alter.Alter;
5555
import net.sf.jsqlparser.statement.alter.AlterSession;
56+
import net.sf.jsqlparser.statement.alter.AlterEventTrigger;
5657
import net.sf.jsqlparser.statement.alter.AlterSystemStatement;
5758
import net.sf.jsqlparser.statement.alter.RenameTableStatement;
5859
import net.sf.jsqlparser.statement.alter.sequence.AlterSequence;
@@ -67,6 +68,7 @@
6768
import net.sf.jsqlparser.statement.create.sequence.CreateSequence;
6869
import net.sf.jsqlparser.statement.create.synonym.CreateSynonym;
6970
import net.sf.jsqlparser.statement.create.table.CreateTable;
71+
import net.sf.jsqlparser.statement.create.trigger.CreateEventTrigger;
7072
import net.sf.jsqlparser.statement.create.trigger.CreateTrigger;
7173
import net.sf.jsqlparser.statement.create.user.CreateUser;
7274
import net.sf.jsqlparser.statement.create.view.AlterView;
@@ -84,6 +86,8 @@
8486
import net.sf.jsqlparser.statement.lock.LockStatement;
8587
import net.sf.jsqlparser.statement.merge.Merge;
8688
import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement;
89+
import net.sf.jsqlparser.statement.reindex.Reindex;
90+
import net.sf.jsqlparser.statement.securitylabel.SecurityLabel;
8791
import net.sf.jsqlparser.statement.select.Select;
8892
import net.sf.jsqlparser.statement.show.ShowIndexStatement;
8993
import net.sf.jsqlparser.statement.show.ShowTablesStatement;
@@ -232,6 +236,38 @@ default void visit(CreateTrigger createTrigger) {
232236
this.visit(createTrigger, null);
233237
}
234238

239+
default <S> T visit(CreateEventTrigger statement, S context) {
240+
return null;
241+
}
242+
243+
default void visit(CreateEventTrigger statement) {
244+
this.visit(statement, null);
245+
}
246+
247+
default <S> T visit(AlterEventTrigger statement, S context) {
248+
return null;
249+
}
250+
251+
default void visit(AlterEventTrigger statement) {
252+
this.visit(statement, null);
253+
}
254+
255+
default <S> T visit(Reindex statement, S context) {
256+
return null;
257+
}
258+
259+
default void visit(Reindex statement) {
260+
this.visit(statement, null);
261+
}
262+
263+
default <S> T visit(SecurityLabel statement, S context) {
264+
return null;
265+
}
266+
267+
default void visit(SecurityLabel statement) {
268+
this.visit(statement, null);
269+
}
270+
235271
<S> T visit(CreateView createView, S context);
236272

237273
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
@@ -55,6 +55,7 @@
5555
import net.sf.jsqlparser.statement.alter.Alter;
5656
import net.sf.jsqlparser.statement.alter.AlterExpression;
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.sequence.AlterSequence;
@@ -69,6 +70,7 @@
6970
import net.sf.jsqlparser.statement.create.sequence.CreateSequence;
7071
import net.sf.jsqlparser.statement.create.synonym.CreateSynonym;
7172
import net.sf.jsqlparser.statement.create.table.CreateTable;
73+
import net.sf.jsqlparser.statement.create.trigger.CreateEventTrigger;
7274
import net.sf.jsqlparser.statement.create.trigger.CreateTrigger;
7375
import net.sf.jsqlparser.statement.create.user.CreateUser;
7476
import net.sf.jsqlparser.statement.create.view.AlterView;
@@ -89,6 +91,8 @@
8991
import net.sf.jsqlparser.statement.merge.MergeOperationVisitor;
9092
import net.sf.jsqlparser.statement.merge.MergeOperationVisitorAdapter;
9193
import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement;
94+
import net.sf.jsqlparser.statement.reindex.Reindex;
95+
import net.sf.jsqlparser.statement.securitylabel.SecurityLabel;
9296
import net.sf.jsqlparser.statement.select.FromItemVisitor;
9397
import net.sf.jsqlparser.statement.select.FromItemVisitorAdapter;
9498
import net.sf.jsqlparser.statement.select.PivotVisitor;
@@ -389,6 +393,7 @@ public <S> T visit(CreateIndex createIndex, S context) {
389393

390394
@Override
391395
public <S> T visit(CreateSchema createSchema, S context) {
396+
createSchema.getStatements().forEach(element -> element.accept(this, context));
392397
return null;
393398
}
394399

@@ -428,6 +433,32 @@ public <S> T visit(CreateTrigger createTrigger, S context) {
428433
return null;
429434
}
430435

436+
@Override
437+
public <S> T visit(CreateEventTrigger statement, S context) {
438+
statement.visitExpressions(expression -> expression.accept(expressionVisitor, context));
439+
return null;
440+
}
441+
442+
@Override
443+
public <S> T visit(AlterEventTrigger statement, S context) {
444+
return null;
445+
}
446+
447+
@Override
448+
public <S> T visit(Reindex statement, S context) {
449+
if (statement.getTable() != null) {
450+
statement.getTable().accept(fromItemVisitor, context);
451+
}
452+
return null;
453+
}
454+
455+
@Override
456+
public <S> T visit(SecurityLabel statement, S context) {
457+
statement.visitRelations(table -> table.accept(fromItemVisitor, context));
458+
expressionVisitor.visitExpression(statement.getLabel(), context);
459+
return null;
460+
}
461+
431462
@Override
432463
public <S> T visit(CreateView createView, S context) {
433464
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)