Skip to content

Commit f44ef8f

Browse files
authored
feat: parse MySQL SHOW FULL COLUMNS, SHOW TABLE STATUS and SHOW CREATE statements (#2824)
MySQL tools read table and column definitions and comments with SHOW FULL COLUMNS, SHOW TABLE STATUS and SHOW CREATE. Only plain SHOW COLUMNS FROM t was typed; the other forms became UnsupportedStatement, and LIKE, WHERE or a qualified table after SHOW COLUMNS failed to parse. Extend ShowColumnsStatement with EXTENDED, FULL, the FIELDS spelling, FROM/IN, a Table name, the trailing database and LIKE/WHERE, keeping getTableName() and setTableName(String). Add ShowTableStatusStatement and ShowCreateStatement for TABLE, VIEW, PROCEDURE, FUNCTION, TRIGGER, EVENT, DATABASE/SCHEMA [IF NOT EXISTS] and USER, whose account reuses MySqlAccountNamePart and accepts CURRENT_USER[()]. A typed SHOW form is chosen only when it covers the whole statement, so other dialects' SHOW variants still fall back to UnsupportedStatement. Wire the statements into the deparser, table finder, validation (showTableStatus, showCreate) and feature analysis. Signed-off-by: minleejae <mmj9808@gmail.com>
1 parent c4137c2 commit f44ef8f

27 files changed

Lines changed: 1535 additions & 18 deletions

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ and missing syntax gets added on demand — [open an issue](https://github.com/J
149149
| **Tablespaces** | MySQL and PostgreSQL `CREATE TABLESPACE` · `ALTER TABLESPACE` |
150150
| **PostgreSQL RLS** | `CREATE POLICY` · `ALTER TABLE … ENABLE`/`DISABLE`/`FORCE`/`NO FORCE ROW LEVEL SECURITY` |
151151
| **Routine changes** | `ALTER FUNCTION` · `ALTER PROCEDURE` · `ALTER ROUTINE` · PostgreSQL `ALTER TRIGGER` |
152+
| **MySQL metadata statements** | `SHOW [FULL] COLUMNS`/`FIELDS` · `SHOW TABLE STATUS` · `SHOW CREATE TABLE`/`VIEW`/`PROCEDURE`/`FUNCTION`/`TRIGGER`/`EVENT`/`DATABASE`/`USER` |
152153
| **Informix constraints** | `ALTER TABLE … ADD CONSTRAINT` with trailing constraint names for primary, unique, foreign and check constraints; enable with `parser.withDialect(Dialect.INFORMIX)` |
153154
| **Salesforce SOQL** | `INCLUDES` · `EXCLUDES` |
154155

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,18 @@ public enum Feature {
736736
* @see ShowIndexStatement
737737
*/
738738
showIndex,
739+
/**
740+
* MySQL/MariaDB "SHOW TABLE STATUS" statement is allowed
741+
*
742+
* @see ShowTableStatusStatement
743+
*/
744+
showTableStatus,
745+
/**
746+
* MySQL/MariaDB "SHOW CREATE" statement is allowed
747+
*
748+
* @see ShowCreateStatement
749+
*/
750+
showCreate,
739751
/**
740752
* @see UseStatement
741753
*/

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

Lines changed: 169 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,148 @@
99
*/
1010
package net.sf.jsqlparser.statement;
1111

12+
import net.sf.jsqlparser.expression.Expression;
13+
import net.sf.jsqlparser.schema.Table;
14+
import net.sf.jsqlparser.statement.show.ShowTablesStatement.SelectionMode;
15+
16+
/**
17+
* A MySQL {@code SHOW [EXTENDED] [FULL] {COLUMNS | FIELDS} {FROM | IN} table [{FROM | IN} db]
18+
* [LIKE 'pattern' | WHERE expr]} statement.
19+
*
20+
* @see <a href="https://dev.mysql.com/doc/refman/8.4/en/show-columns.html">MySQL SHOW COLUMNS</a>
21+
*/
1222
public class ShowColumnsStatement implements Statement {
1323

14-
private String tableName;
24+
private boolean extended;
25+
private boolean full;
26+
private boolean fieldsKeyword;
27+
private SelectionMode tableSelectionMode = SelectionMode.FROM;
28+
private Table table;
29+
private SelectionMode dbSelectionMode = SelectionMode.FROM;
30+
private String dbName;
31+
private Expression likeExpression;
32+
private Expression whereCondition;
1533

1634
public ShowColumnsStatement() {
1735
// empty constructor
1836
}
1937

2038
public ShowColumnsStatement(String tableName) {
21-
this.tableName = tableName;
39+
setTableName(tableName);
40+
}
41+
42+
public ShowColumnsStatement(Table table) {
43+
this.table = table;
44+
}
45+
46+
public boolean isExtended() {
47+
return extended;
48+
}
49+
50+
public void setExtended(boolean extended) {
51+
this.extended = extended;
52+
}
53+
54+
public boolean isFull() {
55+
return full;
56+
}
57+
58+
public void setFull(boolean full) {
59+
this.full = full;
60+
}
61+
62+
/** Whether the statement is spelled with {@code FIELDS} instead of {@code COLUMNS}. */
63+
public boolean isFieldsKeyword() {
64+
return fieldsKeyword;
65+
}
66+
67+
public void setFieldsKeyword(boolean fieldsKeyword) {
68+
this.fieldsKeyword = fieldsKeyword;
69+
}
70+
71+
/** The keyword before the table name, {@code FROM} unless {@code IN} was written. */
72+
public SelectionMode getTableSelectionMode() {
73+
return tableSelectionMode;
74+
}
75+
76+
public void setTableSelectionMode(SelectionMode tableSelectionMode) {
77+
this.tableSelectionMode = tableSelectionMode;
78+
}
79+
80+
public Table getTable() {
81+
return table;
2282
}
2383

84+
public void setTable(Table table) {
85+
this.table = table;
86+
}
87+
88+
/** The table name as written, including any qualifier; derived from {@link #getTable()}. */
2489
public String getTableName() {
25-
return tableName;
90+
return table == null ? null : table.getFullyQualifiedName();
2691
}
2792

2893
public void setTableName(String tableName) {
29-
this.tableName = tableName;
94+
this.table = tableName == null ? null : new Table(tableName);
95+
}
96+
97+
/** The keyword before the database name, {@code FROM} unless {@code IN} was written. */
98+
public SelectionMode getDbSelectionMode() {
99+
return dbSelectionMode;
100+
}
101+
102+
public void setDbSelectionMode(SelectionMode dbSelectionMode) {
103+
this.dbSelectionMode = dbSelectionMode;
104+
}
105+
106+
/** The database of the trailing {@code FROM db} or {@code IN db} clause, or null. */
107+
public String getDbName() {
108+
return dbName;
109+
}
110+
111+
public void setDbName(String dbName) {
112+
this.dbName = dbName;
113+
}
114+
115+
public Expression getLikeExpression() {
116+
return likeExpression;
117+
}
118+
119+
public void setLikeExpression(Expression likeExpression) {
120+
this.likeExpression = likeExpression;
121+
}
122+
123+
public Expression getWhereCondition() {
124+
return whereCondition;
125+
}
126+
127+
public void setWhereCondition(Expression whereCondition) {
128+
this.whereCondition = whereCondition;
30129
}
31130

32131
@Override
33132
public String toString() {
34-
return "SHOW COLUMNS FROM " + tableName;
133+
StringBuilder builder = new StringBuilder("SHOW");
134+
if (extended) {
135+
builder.append(" EXTENDED");
136+
}
137+
if (full) {
138+
builder.append(" FULL");
139+
}
140+
builder.append(fieldsKeyword ? " FIELDS " : " COLUMNS ")
141+
.append(tableSelectionMode == null ? SelectionMode.FROM : tableSelectionMode)
142+
.append(' ').append(table);
143+
if (dbName != null) {
144+
builder.append(' ')
145+
.append(dbSelectionMode == null ? SelectionMode.FROM : dbSelectionMode)
146+
.append(' ').append(dbName);
147+
}
148+
if (likeExpression != null) {
149+
builder.append(" LIKE ").append(likeExpression);
150+
} else if (whereCondition != null) {
151+
builder.append(" WHERE ").append(whereCondition);
152+
}
153+
return builder.toString();
35154
}
36155

37156
@Override
@@ -43,4 +162,49 @@ public ShowColumnsStatement withTableName(String tableName) {
43162
this.setTableName(tableName);
44163
return this;
45164
}
165+
166+
public ShowColumnsStatement withTable(Table table) {
167+
this.setTable(table);
168+
return this;
169+
}
170+
171+
public ShowColumnsStatement withExtended(boolean extended) {
172+
this.setExtended(extended);
173+
return this;
174+
}
175+
176+
public ShowColumnsStatement withFull(boolean full) {
177+
this.setFull(full);
178+
return this;
179+
}
180+
181+
public ShowColumnsStatement withFieldsKeyword(boolean fieldsKeyword) {
182+
this.setFieldsKeyword(fieldsKeyword);
183+
return this;
184+
}
185+
186+
public ShowColumnsStatement withTableSelectionMode(SelectionMode tableSelectionMode) {
187+
this.setTableSelectionMode(tableSelectionMode);
188+
return this;
189+
}
190+
191+
public ShowColumnsStatement withDbSelectionMode(SelectionMode dbSelectionMode) {
192+
this.setDbSelectionMode(dbSelectionMode);
193+
return this;
194+
}
195+
196+
public ShowColumnsStatement withDbName(String dbName) {
197+
this.setDbName(dbName);
198+
return this;
199+
}
200+
201+
public ShowColumnsStatement withLikeExpression(Expression likeExpression) {
202+
this.setLikeExpression(likeExpression);
203+
return this;
204+
}
205+
206+
public ShowColumnsStatement withWhereCondition(Expression whereCondition) {
207+
this.setWhereCondition(whereCondition);
208+
return this;
209+
}
46210
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@
116116
import net.sf.jsqlparser.statement.select.SelectVisitorAdapter;
117117
import net.sf.jsqlparser.statement.select.TableStatement;
118118
import net.sf.jsqlparser.statement.select.WithItem;
119+
import net.sf.jsqlparser.statement.show.ShowCreateStatement;
119120
import net.sf.jsqlparser.statement.show.ShowIndexStatement;
121+
import net.sf.jsqlparser.statement.show.ShowTableStatusStatement;
120122
import net.sf.jsqlparser.statement.show.ShowTablesStatement;
121123
import net.sf.jsqlparser.statement.truncate.Truncate;
122124
import net.sf.jsqlparser.statement.update.Update;
@@ -940,6 +942,16 @@ public <S> Void visit(ShowTablesStatement showTables, S context) {
940942
return metadataOnly();
941943
}
942944

945+
@Override
946+
public <S> Void visit(ShowTableStatusStatement showTableStatus, S context) {
947+
return metadataOnly();
948+
}
949+
950+
@Override
951+
public <S> Void visit(ShowCreateStatement showCreate, S context) {
952+
return metadataOnly();
953+
}
954+
943955
@Override
944956
public <S> Void visit(DescribeStatement describe, S context) {
945957
return metadataOnly();

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@
9191
import net.sf.jsqlparser.statement.merge.Merge;
9292
import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement;
9393
import net.sf.jsqlparser.statement.select.Select;
94+
import net.sf.jsqlparser.statement.show.ShowCreateStatement;
9495
import net.sf.jsqlparser.statement.show.ShowIndexStatement;
96+
import net.sf.jsqlparser.statement.show.ShowTableStatusStatement;
9597
import net.sf.jsqlparser.statement.show.ShowTablesStatement;
9698
import net.sf.jsqlparser.statement.truncate.Truncate;
9799
import net.sf.jsqlparser.statement.update.ParenthesedUpdate;
@@ -366,6 +368,22 @@ default void visit(ShowTablesStatement showTables) {
366368
this.visit(showTables, null);
367369
}
368370

371+
default <S> T visit(ShowTableStatusStatement showTableStatus, S context) {
372+
return null;
373+
}
374+
375+
default void visit(ShowTableStatusStatement showTableStatus) {
376+
this.visit(showTableStatus, null);
377+
}
378+
379+
default <S> T visit(ShowCreateStatement showCreate, S context) {
380+
return null;
381+
}
382+
383+
default void visit(ShowCreateStatement showCreate) {
384+
this.visit(showCreate, null);
385+
}
386+
369387
<S> T visit(Merge merge, S context);
370388

371389
default void visit(Merge merge) {

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@
105105
import net.sf.jsqlparser.statement.select.SelectVisitor;
106106
import net.sf.jsqlparser.statement.select.SelectVisitorAdapter;
107107
import net.sf.jsqlparser.statement.select.WithItem;
108+
import net.sf.jsqlparser.statement.show.ShowCreateStatement;
108109
import net.sf.jsqlparser.statement.show.ShowIndexStatement;
110+
import net.sf.jsqlparser.statement.show.ShowTableStatusStatement;
109111
import net.sf.jsqlparser.statement.show.ShowTablesStatement;
110112
import net.sf.jsqlparser.statement.truncate.Truncate;
111113
import net.sf.jsqlparser.statement.update.ParenthesedUpdate;
@@ -604,6 +606,16 @@ public <S> T visit(ShowTablesStatement showTables, S context) {
604606
return null;
605607
}
606608

609+
@Override
610+
public <S> T visit(ShowTableStatusStatement showTableStatus, S context) {
611+
return null;
612+
}
613+
614+
@Override
615+
public <S> T visit(ShowCreateStatement showCreate, S context) {
616+
return null;
617+
}
618+
607619
@Override
608620
public <S> T visit(DeclareStatement declareStatement, S context) {
609621
return null;

0 commit comments

Comments
 (0)