Skip to content

Commit 38c567b

Browse files
committed
feat: parse MySQL resource group statements
CREATE RESOURCE GROUP and ALTER RESOURCE GROUP were read as UnsupportedStatement, SET RESOURCE GROUP and DROP RESOURCE GROUP ... FORCE failed, and DROP RESOURCE GROUP rg was a Drop of type RESOURCE named GROUP. Add CreateResourceGroup and AlterResourceGroup, which share the name, the VCPU list (VcpuRange), the thread priority and the ENABLE or DISABLE state through ResourceGroupDefinition, and SetResourceGroup with its thread IDs. DROP RESOURCE GROUP is a Drop with the object type RESOURCE_GROUP and the existing force flag. The statements are read with the MySQL dialect or none and follow MySQL's grammar: the option order, the optional = or :=, the optional commas, a signed THREAD_PRIORITY, and FORCE after ALTER and DROP. RESOURCE, VCPU and THREAD_PRIORITY stay usable as names; no token is added. Wire the statements into the deparser, visitors, table finder, feature analysis and validation, with new createResourceGroup, alterResourceGroup and setResourceGroup features. Signed-off-by: minleejae <mmj9808@gmail.com>
1 parent e27929f commit 38c567b

22 files changed

Lines changed: 1499 additions & 4 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ and missing syntax gets added on demand — [open an issue](https://github.com/J
151151
| **MySQL table maintenance** | `ANALYZE` · `CHECK` · `CHECKSUM` · `OPTIMIZE` · `REPAIR TABLE` |
152152
| **PostgreSQL maintenance** | `VACUUM` · `ANALYZE` · `CLUSTER` · `CHECKPOINT` |
153153
| **MySQL locks** | `LOCK TABLES` · `UNLOCK TABLES` · `LOCK INSTANCE FOR BACKUP` · `UNLOCK INSTANCE` |
154+
| **MySQL resource groups** | `CREATE`/`ALTER`/`DROP RESOURCE GROUP` · `SET RESOURCE GROUP` |
154155
| **PostgreSQL session statements** | `DISCARD` · `LISTEN` · `UNLISTEN` · `SHOW`/`RESET TIME ZONE`/`TRANSACTION ISOLATION LEVEL`/`SESSION AUTHORIZATION` · `COPY` options from before 9.0 |
155156
| **MySQL account management** | `CREATE`/`ALTER`/`RENAME USER` · `CREATE ROLE` · `SET ROLE` · `SET DEFAULT ROLE` · `SET PASSWORD` |
156157
| **Tablespaces** | MySQL and PostgreSQL `CREATE TABLESPACE` · `ALTER TABLESPACE` |

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@
6060
import net.sf.jsqlparser.statement.merge.Merge;
6161
import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement;
6262
import net.sf.jsqlparser.statement.reindex.Reindex;
63+
import net.sf.jsqlparser.statement.resourcegroup.AlterResourceGroup;
64+
import net.sf.jsqlparser.statement.resourcegroup.CreateResourceGroup;
65+
import net.sf.jsqlparser.statement.resourcegroup.SetResourceGroup;
6366
import net.sf.jsqlparser.statement.role.ReassignOwned;
6467
import net.sf.jsqlparser.statement.select.Fetch;
6568
import net.sf.jsqlparser.statement.select.First;
@@ -796,6 +799,24 @@ public enum Feature {
796799
* @see BackupLockStatement
797800
*/
798801
backupLock,
802+
/**
803+
* MySQL "CREATE RESOURCE GROUP" statement is allowed
804+
*
805+
* @see CreateResourceGroup
806+
*/
807+
createResourceGroup,
808+
/**
809+
* MySQL "ALTER RESOURCE GROUP" statement is allowed
810+
*
811+
* @see AlterResourceGroup
812+
*/
813+
alterResourceGroup,
814+
/**
815+
* MySQL "SET RESOURCE GROUP" statement is allowed
816+
*
817+
* @see SetResourceGroup
818+
*/
819+
setResourceGroup,
799820
/**
800821
* SQL "COMMENT ON" statement is allowed
801822
*

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@
111111
import net.sf.jsqlparser.statement.oracle.OracleNullStatement;
112112
import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement;
113113
import net.sf.jsqlparser.statement.reindex.Reindex;
114+
import net.sf.jsqlparser.statement.resourcegroup.AlterResourceGroup;
115+
import net.sf.jsqlparser.statement.resourcegroup.CreateResourceGroup;
116+
import net.sf.jsqlparser.statement.resourcegroup.SetResourceGroup;
114117
import net.sf.jsqlparser.statement.securitylabel.SecurityLabel;
115118
import net.sf.jsqlparser.statement.role.AlterRole;
116119
import net.sf.jsqlparser.statement.role.CreateRole;
@@ -928,6 +931,21 @@ public <S> Void visit(XaStatement statement, S context) {
928931
: transactionOnly();
929932
}
930933

934+
@Override
935+
public <S> Void visit(CreateResourceGroup statement, S context) {
936+
return schemaOnly();
937+
}
938+
939+
@Override
940+
public <S> Void visit(AlterResourceGroup statement, S context) {
941+
return schemaOnly();
942+
}
943+
944+
@Override
945+
public <S> Void visit(SetResourceGroup statement, S context) {
946+
return sessionOnly();
947+
}
948+
931949
@Override
932950
public <S> Void visit(Commit commit, S context) {
933951
return transactionOnly();

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@
100100
import net.sf.jsqlparser.statement.merge.Merge;
101101
import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement;
102102
import net.sf.jsqlparser.statement.reindex.Reindex;
103+
import net.sf.jsqlparser.statement.resourcegroup.AlterResourceGroup;
104+
import net.sf.jsqlparser.statement.resourcegroup.CreateResourceGroup;
105+
import net.sf.jsqlparser.statement.resourcegroup.SetResourceGroup;
103106
import net.sf.jsqlparser.statement.securitylabel.SecurityLabel;
104107
import net.sf.jsqlparser.statement.select.Select;
105108
import net.sf.jsqlparser.statement.show.ShowCreateStatement;
@@ -197,6 +200,30 @@ default void visit(XaStatement statement) {
197200
visit(statement, null);
198201
}
199202

203+
default <S> T visit(CreateResourceGroup statement, S context) {
204+
return null;
205+
}
206+
207+
default void visit(CreateResourceGroup statement) {
208+
visit(statement, null);
209+
}
210+
211+
default <S> T visit(AlterResourceGroup statement, S context) {
212+
return null;
213+
}
214+
215+
default void visit(AlterResourceGroup statement) {
216+
visit(statement, null);
217+
}
218+
219+
default <S> T visit(SetResourceGroup statement, S context) {
220+
return null;
221+
}
222+
223+
default void visit(SetResourceGroup statement) {
224+
visit(statement, null);
225+
}
226+
200227
<S> T visit(Commit commit, S context);
201228

202229
default void visit(Commit commit) {

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@
105105
import net.sf.jsqlparser.statement.merge.MergeOperationVisitorAdapter;
106106
import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement;
107107
import net.sf.jsqlparser.statement.reindex.Reindex;
108+
import net.sf.jsqlparser.statement.resourcegroup.AlterResourceGroup;
109+
import net.sf.jsqlparser.statement.resourcegroup.CreateResourceGroup;
110+
import net.sf.jsqlparser.statement.resourcegroup.SetResourceGroup;
108111
import net.sf.jsqlparser.statement.securitylabel.SecurityLabel;
109112
import net.sf.jsqlparser.statement.select.FromItem;
110113
import net.sf.jsqlparser.statement.select.FromItemVisitor;
@@ -262,6 +265,21 @@ public <S> T visit(XaStatement statement, S context) {
262265
return null;
263266
}
264267

268+
@Override
269+
public <S> T visit(CreateResourceGroup statement, S context) {
270+
return null;
271+
}
272+
273+
@Override
274+
public <S> T visit(AlterResourceGroup statement, S context) {
275+
return null;
276+
}
277+
278+
@Override
279+
public <S> T visit(SetResourceGroup statement, S context) {
280+
return null;
281+
}
282+
265283
@Override
266284
public <S> T visit(Commit commit, S context) {
267285

‎src/main/java/net/sf/jsqlparser/statement/drop/Drop.java‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
public class Drop extends ASTNodeAccessImpl implements Statement {
3636

3737
public enum ObjectType {
38-
DATABASE, EVENT, FUNCTION, INDEX, PROCEDURE, SCHEMA, SEQUENCE, SERVER, TABLE, TABLESPACE, TRIGGER, VIEW, FOREIGN_TABLE, FOREIGN_DATA_WRAPPER, AGGREGATE, DOMAIN, EVENT_TRIGGER, GROUP, OWNED, ROLE, ROUTINE, RULE, TYPE, USER, SYNONYM, ACCESS_METHOD, LANGUAGE, OPERATOR_CLASS, OPERATOR_FAMILY, TEXT_SEARCH_CONFIGURATION, TEXT_SEARCH_DICTIONARY, TEXT_SEARCH_PARSER, TEXT_SEARCH_TEMPLATE, CAST, OPERATOR, TRANSFORM, OTHER;
38+
DATABASE, EVENT, FUNCTION, INDEX, PROCEDURE, SCHEMA, SEQUENCE, SERVER, TABLE, TABLESPACE, TRIGGER, VIEW, FOREIGN_TABLE, FOREIGN_DATA_WRAPPER, AGGREGATE, DOMAIN, EVENT_TRIGGER, GROUP, OWNED, ROLE, ROUTINE, RULE, TYPE, USER, SYNONYM, ACCESS_METHOD, LANGUAGE, OPERATOR_CLASS, OPERATOR_FAMILY, TEXT_SEARCH_CONFIGURATION, TEXT_SEARCH_DICTIONARY, TEXT_SEARCH_PARSER, TEXT_SEARCH_TEMPLATE, CAST, OPERATOR, TRANSFORM, RESOURCE_GROUP, OTHER;
3939

4040
/** Targets are {@link RoutineReference}s, each with an optional argument signature. */
4141
public boolean hasRoutineTargets() {
@@ -432,7 +432,10 @@ public Drop withUndo(boolean undo) {
432432
return this;
433433
}
434434

435-
/** PostgreSQL DROP DATABASE ... WITH (FORCE), or Oracle DROP SYNONYM ... FORCE. */
435+
/**
436+
* PostgreSQL DROP DATABASE ... WITH (FORCE), or Oracle DROP SYNONYM ... FORCE and MySQL DROP
437+
* RESOURCE GROUP ... FORCE.
438+
*/
436439
public boolean isForce() {
437440
return force;
438441
}
@@ -634,7 +637,8 @@ public StringBuilder appendTo(StringBuilder builder, Consumer<Table> tablePrinte
634637
builder.append(" USING ").append(accessMethod);
635638
}
636639
if (force) {
637-
builder.append(objectType == ObjectType.SYNONYM ? " FORCE" : " WITH (FORCE)");
640+
builder.append(objectType == ObjectType.SYNONYM
641+
|| objectType == ObjectType.RESOURCE_GROUP ? " FORCE" : " WITH (FORCE)");
638642
}
639643
if (engine != null) {
640644
builder.append(engineUseEquals ? " ENGINE = " : " ENGINE ").append(engine);
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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.resourcegroup;
11+
12+
import java.util.Collection;
13+
import java.util.List;
14+
import net.sf.jsqlparser.statement.StatementVisitor;
15+
16+
/**
17+
* MySQL {@code ALTER RESOURCE GROUP group_name [VCPU [=] vcpu_spec [, vcpu_spec] ...]
18+
* [THREAD_PRIORITY [=] N] [ENABLE | DISABLE] [FORCE]}. MySQL's grammar takes FORCE without DISABLE
19+
* too.
20+
*
21+
* @see <a href="https://dev.mysql.com/doc/refman/8.4/en/alter-resource-group.html">MySQL ALTER
22+
* RESOURCE GROUP Statement</a>
23+
*/
24+
public class AlterResourceGroup extends ResourceGroupDefinition {
25+
private boolean force;
26+
27+
public AlterResourceGroup() {
28+
// the parser fills the statement in
29+
}
30+
31+
public AlterResourceGroup(String name) {
32+
super(name);
33+
}
34+
35+
/** Whether FORCE is written: the group is changed although threads are assigned to it. */
36+
public boolean isForce() {
37+
return force;
38+
}
39+
40+
public void setForce(boolean force) {
41+
this.force = force;
42+
}
43+
44+
public AlterResourceGroup withForce(boolean force) {
45+
setForce(force);
46+
return this;
47+
}
48+
49+
public AlterResourceGroup withVcpus(List<VcpuRange> vcpus) {
50+
setVcpus(vcpus);
51+
return this;
52+
}
53+
54+
public AlterResourceGroup addVcpuRanges(Collection<? extends VcpuRange> vcpus) {
55+
addVcpus(vcpus);
56+
return this;
57+
}
58+
59+
public AlterResourceGroup withThreadPriority(Integer threadPriority) {
60+
setThreadPriority(threadPriority);
61+
return this;
62+
}
63+
64+
public AlterResourceGroup withState(State state) {
65+
setState(state);
66+
return this;
67+
}
68+
69+
@Override
70+
public StringBuilder appendTo(StringBuilder builder) {
71+
appendOptionsTo(builder.append("ALTER RESOURCE GROUP ").append(getName()));
72+
return force ? builder.append(" FORCE") : builder;
73+
}
74+
75+
@Override
76+
public <T, S> T accept(StatementVisitor<T> statementVisitor, S context) {
77+
return statementVisitor.visit(this, context);
78+
}
79+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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.resourcegroup;
11+
12+
import java.util.Collection;
13+
import java.util.List;
14+
import java.util.Objects;
15+
import net.sf.jsqlparser.statement.StatementVisitor;
16+
17+
/**
18+
* MySQL {@code CREATE RESOURCE GROUP group_name TYPE [=] {SYSTEM | USER} [VCPU [=] vcpu_spec [,
19+
* vcpu_spec] ...] [THREAD_PRIORITY [=] N] [ENABLE | DISABLE]}.
20+
*
21+
* @see <a href="https://dev.mysql.com/doc/refman/8.4/en/create-resource-group.html">MySQL CREATE
22+
* RESOURCE GROUP Statement</a>
23+
*/
24+
public class CreateResourceGroup extends ResourceGroupDefinition {
25+
/** Whether the group takes system threads or user threads. */
26+
public enum Type {
27+
SYSTEM, USER
28+
}
29+
30+
private Type type;
31+
private OptionAssignment typeAssignment = OptionAssignment.EQUALS;
32+
33+
public CreateResourceGroup() {
34+
// the parser fills the statement in
35+
}
36+
37+
public CreateResourceGroup(String name, Type type) {
38+
super(name);
39+
setType(type);
40+
}
41+
42+
public Type getType() {
43+
return type;
44+
}
45+
46+
public final void setType(Type type) {
47+
this.type = Objects.requireNonNull(type, "type");
48+
}
49+
50+
public OptionAssignment getTypeAssignment() {
51+
return typeAssignment;
52+
}
53+
54+
public void setTypeAssignment(OptionAssignment typeAssignment) {
55+
this.typeAssignment = Objects.requireNonNull(typeAssignment, "typeAssignment");
56+
}
57+
58+
public CreateResourceGroup withTypeAssignment(OptionAssignment typeAssignment) {
59+
setTypeAssignment(typeAssignment);
60+
return this;
61+
}
62+
63+
public CreateResourceGroup withVcpus(List<VcpuRange> vcpus) {
64+
setVcpus(vcpus);
65+
return this;
66+
}
67+
68+
public CreateResourceGroup addVcpuRanges(Collection<? extends VcpuRange> vcpus) {
69+
addVcpus(vcpus);
70+
return this;
71+
}
72+
73+
public CreateResourceGroup withThreadPriority(Integer threadPriority) {
74+
setThreadPriority(threadPriority);
75+
return this;
76+
}
77+
78+
public CreateResourceGroup withState(State state) {
79+
setState(state);
80+
return this;
81+
}
82+
83+
@Override
84+
public StringBuilder appendTo(StringBuilder builder) {
85+
builder.append("CREATE RESOURCE GROUP ").append(getName()).append(' ');
86+
typeAssignment.appendTo(builder, "TYPE").append(type);
87+
return appendOptionsTo(builder);
88+
}
89+
90+
@Override
91+
public <T, S> T accept(StatementVisitor<T> statementVisitor, S context) {
92+
return statementVisitor.visit(this, context);
93+
}
94+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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.resourcegroup;
11+
12+
/**
13+
* How a MySQL resource group option is joined to its value: {@code TYPE USER}, {@code TYPE = USER}
14+
* or {@code TYPE := USER}. MySQL reads the three alike.
15+
*/
16+
public enum OptionAssignment {
17+
NONE(""), EQUALS("="), COLON_EQUALS(":=");
18+
19+
private final String symbol;
20+
21+
OptionAssignment(String symbol) {
22+
this.symbol = symbol;
23+
}
24+
25+
/** The symbol as written, empty for {@link #NONE}. */
26+
public String getSymbol() {
27+
return symbol;
28+
}
29+
30+
/** Appends the option name, the symbol if there is one, and a space before the value. */
31+
StringBuilder appendTo(StringBuilder builder, String option) {
32+
builder.append(option).append(' ');
33+
return this == NONE ? builder : builder.append(symbol).append(' ');
34+
}
35+
}

0 commit comments

Comments
 (0)