diff --git a/src/main/java/net/sf/jsqlparser/parser/feature/Feature.java b/src/main/java/net/sf/jsqlparser/parser/feature/Feature.java
index b59191844..956d636b5 100644
--- a/src/main/java/net/sf/jsqlparser/parser/feature/Feature.java
+++ b/src/main/java/net/sf/jsqlparser/parser/feature/Feature.java
@@ -306,6 +306,11 @@ public enum Feature {
*/
values,
+ /**
+ * SQL "TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]]“
+ */
+ tableStatement,
+
/**
* SQL "UPDATE" statement is allowed
*
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitor.java b/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitor.java
index 1d3643f50..04a6b9d9e 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitor.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitor.java
@@ -22,4 +22,6 @@ public interface SelectVisitor {
void visit(Values aThis);
void visit(LateralSubSelect lateralSubSelect);
+
+ void visit(TableStatement tableStatement);
}
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitorAdapter.java b/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitorAdapter.java
index 91c6f32c2..a349a9005 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitorAdapter.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitorAdapter.java
@@ -41,4 +41,9 @@ public void visit(Values aThis) {
public void visit(LateralSubSelect lateralSubSelect) {
}
+
+ @Override
+ public void visit(TableStatement tableStatement) {
+
+ }
}
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/TableStatement.java b/src/main/java/net/sf/jsqlparser/statement/select/TableStatement.java
new file mode 100644
index 000000000..b665b16a6
--- /dev/null
+++ b/src/main/java/net/sf/jsqlparser/statement/select/TableStatement.java
@@ -0,0 +1,59 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2019 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+package net.sf.jsqlparser.statement.select;
+
+import net.sf.jsqlparser.schema.Table;
+
+/**
+ * @see `TABLE table_name [ORDER
+ * BY column_name] [LIMIT number [OFFSET number]]` Union not currently supported
+ *
+ * @author jxnu-liguobin
+ */
+public class TableStatement extends Select {
+
+ private Table table;
+
+ public Table getTable() {
+ return table;
+ }
+
+ public void setTable(Table table) {
+ this.table = table;
+ }
+
+ @Override
+ public StringBuilder appendSelectBodyTo(StringBuilder builder) {
+ builder.append("TABLE ").append(table.getName());
+ return builder;
+ }
+
+ @SuppressWarnings({"PMD.CyclomaticComplexity"})
+ @Override
+ public StringBuilder appendTo(StringBuilder builder) {
+
+ appendSelectBodyTo(builder);
+
+ builder.append(orderByToString(false, orderByElements));
+
+ if (limit != null) {
+ builder.append(limit);
+ }
+ if (offset != null) {
+ builder.append(offset);
+ }
+ return builder;
+ }
+
+ @Override
+ public void accept(SelectVisitor selectVisitor) {
+ selectVisitor.visit(this);
+ }
+}
diff --git a/src/main/java/net/sf/jsqlparser/util/AddAliasesVisitor.java b/src/main/java/net/sf/jsqlparser/util/AddAliasesVisitor.java
index 3303c091f..58ca4326f 100644
--- a/src/main/java/net/sf/jsqlparser/util/AddAliasesVisitor.java
+++ b/src/main/java/net/sf/jsqlparser/util/AddAliasesVisitor.java
@@ -9,6 +9,8 @@
*/
package net.sf.jsqlparser.util;
+import java.util.LinkedList;
+import java.util.List;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.statement.select.LateralSubSelect;
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
@@ -18,12 +20,10 @@
import net.sf.jsqlparser.statement.select.SelectItemVisitor;
import net.sf.jsqlparser.statement.select.SelectVisitor;
import net.sf.jsqlparser.statement.select.SetOperationList;
+import net.sf.jsqlparser.statement.select.TableStatement;
import net.sf.jsqlparser.statement.select.Values;
import net.sf.jsqlparser.statement.select.WithItem;
-import java.util.LinkedList;
-import java.util.List;
-
/**
* Add aliases to every column and expression selected by a select - statement. Existing aliases are
* recognized and preserved. This class standard uses a prefix of A and a counter to generate new
@@ -112,4 +112,9 @@ public void visit(Values aThis) {
public void visit(LateralSubSelect lateralSubSelect) {
lateralSubSelect.getSelect().accept(this);
}
+
+ @Override
+ public void visit(TableStatement tableStatement) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
}
diff --git a/src/main/java/net/sf/jsqlparser/util/ConnectExpressionsVisitor.java b/src/main/java/net/sf/jsqlparser/util/ConnectExpressionsVisitor.java
index 479bc3c3e..46b746f0a 100644
--- a/src/main/java/net/sf/jsqlparser/util/ConnectExpressionsVisitor.java
+++ b/src/main/java/net/sf/jsqlparser/util/ConnectExpressionsVisitor.java
@@ -9,6 +9,8 @@
*/
package net.sf.jsqlparser.util;
+import java.util.LinkedList;
+import java.util.List;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.BinaryExpression;
import net.sf.jsqlparser.statement.select.LateralSubSelect;
@@ -19,12 +21,10 @@
import net.sf.jsqlparser.statement.select.SelectItemVisitor;
import net.sf.jsqlparser.statement.select.SelectVisitor;
import net.sf.jsqlparser.statement.select.SetOperationList;
+import net.sf.jsqlparser.statement.select.TableStatement;
import net.sf.jsqlparser.statement.select.Values;
import net.sf.jsqlparser.statement.select.WithItem;
-import java.util.LinkedList;
-import java.util.List;
-
/**
* Connect all selected expressions with a binary expression. Out of select a,b from table one gets
* select a || b as expr from table. The type of binary expression is set by overwriting this class
@@ -103,4 +103,8 @@ public void visit(Values aThis) {
throw new UnsupportedOperationException("Not supported yet.");
}
+ @Override
+ public void visit(TableStatement tableStatement) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
}
diff --git a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
index 44f0859a5..b3b697e4d 100644
--- a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
+++ b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
@@ -167,6 +167,7 @@
import net.sf.jsqlparser.statement.select.SelectVisitor;
import net.sf.jsqlparser.statement.select.SetOperationList;
import net.sf.jsqlparser.statement.select.TableFunction;
+import net.sf.jsqlparser.statement.select.TableStatement;
import net.sf.jsqlparser.statement.select.Values;
import net.sf.jsqlparser.statement.select.WithItem;
import net.sf.jsqlparser.statement.show.ShowIndexStatement;
@@ -691,6 +692,11 @@ public void visit(LateralSubSelect lateralSubSelect) {
lateralSubSelect.getSelect().accept((SelectVisitor) this);
}
+ @Override
+ public void visit(TableStatement tableStatement) {
+ tableStatement.getTable().accept(this);
+ }
+
/**
* Initializes table names collector. Important is the usage of Column instances to find table
* names. This is only allowed for expression parsing, where a better place for tablenames could
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java
index 75aac7a9e..7c4c0e1fb 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java
@@ -9,6 +9,10 @@
*/
package net.sf.jsqlparser.util.deparser;
+import static java.util.stream.Collectors.joining;
+
+import java.util.Iterator;
+import java.util.List;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitor;
@@ -40,16 +44,12 @@
import net.sf.jsqlparser.statement.select.SetOperationList;
import net.sf.jsqlparser.statement.select.Skip;
import net.sf.jsqlparser.statement.select.TableFunction;
+import net.sf.jsqlparser.statement.select.TableStatement;
import net.sf.jsqlparser.statement.select.Top;
import net.sf.jsqlparser.statement.select.UnPivot;
import net.sf.jsqlparser.statement.select.Values;
import net.sf.jsqlparser.statement.select.WithItem;
-import java.util.Iterator;
-import java.util.List;
-
-import static java.util.stream.Collectors.joining;
-
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
public class SelectDeParser extends AbstractDeParser implements SelectVisitor,
SelectItemVisitor, FromItemVisitor, PivotVisitor {
@@ -589,6 +589,11 @@ public void visit(LateralSubSelect lateralSubSelect) {
visit((ParenthesedSelect) lateralSubSelect);
}
+ @Override
+ public void visit(TableStatement tableStatement) {
+ new TableStatementDeParser(expressionVisitor, buffer).deParse(tableStatement);
+ }
+
@Override
public void visit(TableFunction tableFunction) {
buffer.append(tableFunction.toString());
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/TableStatementDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/TableStatementDeParser.java
new file mode 100644
index 000000000..962849c6e
--- /dev/null
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/TableStatementDeParser.java
@@ -0,0 +1,98 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2019 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+package net.sf.jsqlparser.util.deparser;
+
+import net.sf.jsqlparser.expression.ExpressionVisitor;
+import net.sf.jsqlparser.statement.select.LateralSubSelect;
+import net.sf.jsqlparser.statement.select.Offset;
+import net.sf.jsqlparser.statement.select.ParenthesedSelect;
+import net.sf.jsqlparser.statement.select.PlainSelect;
+import net.sf.jsqlparser.statement.select.SelectVisitor;
+import net.sf.jsqlparser.statement.select.SetOperationList;
+import net.sf.jsqlparser.statement.select.TableStatement;
+import net.sf.jsqlparser.statement.select.Values;
+import net.sf.jsqlparser.statement.select.WithItem;
+
+/**
+ * @author jxnu-liguobin
+ */
+public class TableStatementDeParser extends AbstractDeParser
+ implements SelectVisitor {
+
+ private final ExpressionVisitor expressionVisitor;
+
+ public TableStatementDeParser(ExpressionVisitor expressionVisitor, StringBuilder buffer) {
+ super(buffer);
+ this.expressionVisitor = expressionVisitor;
+ }
+
+ @Override
+ public void deParse(TableStatement tableStatement) {
+ tableStatement.accept(this);
+ }
+
+ public void visit(Offset offset) {
+ buffer.append(" OFFSET ");
+ offset.getOffset().accept(expressionVisitor);
+ if (offset.getOffsetParam() != null) {
+ buffer.append(" ").append(offset.getOffsetParam());
+ }
+
+ }
+
+ @Override
+ public void visit(ParenthesedSelect parenthesedSelect) {
+
+ }
+
+ @Override
+ public void visit(PlainSelect plainSelect) {
+
+ }
+
+ @Override
+ public void visit(SetOperationList setOpList) {
+
+ }
+
+ @Override
+ public void visit(WithItem withItem) {
+
+ }
+
+ @Override
+ public void visit(Values aThis) {
+
+ }
+
+ @Override
+ public void visit(LateralSubSelect lateralSubSelect) {
+
+ }
+
+ @Override
+ public void visit(TableStatement tableStatement) {
+ buffer.append("TABLE ");
+ buffer.append(tableStatement.getTable());
+ if (tableStatement.getOrderByElements() != null) {
+ new OrderByDeParser(expressionVisitor, buffer)
+ .deParse(tableStatement.getOrderByElements());
+ }
+
+ if (tableStatement.getLimit() != null) {
+ new LimitDeparser(expressionVisitor, buffer).deParse(tableStatement.getLimit());
+ }
+ if (tableStatement.getOffset() != null) {
+ visit(tableStatement.getOffset());
+ }
+
+ // TODO UNION
+ }
+}
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/FeaturesAllowed.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/FeaturesAllowed.java
index 04c9a1277..3ada0ec28 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/feature/FeaturesAllowed.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/FeaturesAllowed.java
@@ -38,13 +38,14 @@ public class FeaturesAllowed implements FeatureSetValidation, ModifyableFeatureS
Feature.jdbcParameter,
Feature.jdbcNamedParameter).unmodifyable();
- public static final FeaturesAllowed EXPRESSIONS = new FeaturesAllowed("EXPRESSIONS", Feature.exprLike,
- Feature.exprSimilarTo);
+ public static final FeaturesAllowed EXPRESSIONS =
+ new FeaturesAllowed("EXPRESSIONS", Feature.exprLike,
+ Feature.exprSimilarTo);
/**
* all {@link Feature}' within SQL SELECT without modification features like
- * {@link Feature#selectInto}, but jdbc-features like
- * {@link Feature#jdbcParameter} and {@link Feature#jdbcNamedParameter}
+ * {@link Feature#selectInto}, but jdbc-features like {@link Feature#jdbcParameter} and
+ * {@link Feature#jdbcNamedParameter}
*/
public static final FeaturesAllowed SELECT = new FeaturesAllowed("SELECT",
// select features
@@ -86,22 +87,25 @@ public class FeaturesAllowed implements FeatureSetValidation, ModifyableFeatureS
Feature.distinctOn,
Feature.orderBy,
Feature.orderByNullOrdering,
+ Feature.tableStatement,
Feature.function).unmodifyable();
/**
- * all {@link Feature}' for SQL INSERT including {@link #SELECT} and
- * {@link Feature#selectInto}
+ * all {@link Feature}' for SQL INSERT including {@link #SELECT} and {@link Feature#selectInto}
*/
- public static final FeaturesAllowed INSERT = new FeaturesAllowed("INSERT", Feature.insert, Feature.insertFromSelect,
- Feature.insertModifierIgnore, Feature.insertModifierPriority, Feature.insertReturningAll,
- Feature.insertReturningExpressionList, Feature.insertUseSet,
- Feature.insertValues, Feature.selectInto).add(SELECT).unmodifyable();
+ public static final FeaturesAllowed INSERT =
+ new FeaturesAllowed("INSERT", Feature.insert, Feature.insertFromSelect,
+ Feature.insertModifierIgnore, Feature.insertModifierPriority,
+ Feature.insertReturningAll,
+ Feature.insertReturningExpressionList, Feature.insertUseSet,
+ Feature.insertValues, Feature.selectInto).add(SELECT).unmodifyable();
/**
* all {@link Feature}' for SQL UPDATE including {@link #SELECT}
*/
- public static final FeaturesAllowed UPDATE = new FeaturesAllowed("UPDATE", Feature.update, Feature.updateJoins,
+ public static final FeaturesAllowed UPDATE = new FeaturesAllowed("UPDATE", Feature.update,
+ Feature.updateJoins,
Feature.updateFrom, Feature.updateLimit, Feature.updateOrderBy, Feature.updateReturning,
Feature.updateUseSelect)
.add(SELECT).unmodifyable();
@@ -109,55 +113,66 @@ public class FeaturesAllowed implements FeatureSetValidation, ModifyableFeatureS
/**
* all {@link Feature}' for SQL UPDATE including {@link #SELECT}
*/
- public static final FeaturesAllowed DELETE = new FeaturesAllowed("DELETE", Feature.delete, Feature.deleteJoin,
- Feature.deleteLimit, Feature.deleteOrderBy, Feature.deleteTables, Feature.deleteReturningExpressionList,
- Feature.truncate)
- .add(SELECT).unmodifyable();
+ public static final FeaturesAllowed DELETE =
+ new FeaturesAllowed("DELETE", Feature.delete, Feature.deleteJoin,
+ Feature.deleteLimit, Feature.deleteOrderBy, Feature.deleteTables,
+ Feature.deleteReturningExpressionList,
+ Feature.truncate)
+ .add(SELECT).unmodifyable();
/**
* all {@link Feature}' for SQL MERGE other similar commands
*/
- public static final FeaturesAllowed MERGE = new FeaturesAllowed("MERGE", Feature.merge, Feature.upsert,
- Feature.insertUseDuplicateKeyUpdate).unmodifyable();
+ public static final FeaturesAllowed MERGE =
+ new FeaturesAllowed("MERGE", Feature.merge, Feature.upsert,
+ Feature.insertUseDuplicateKeyUpdate).unmodifyable();
/**
* all DML {@link Feature}'s
*/
- public static final FeaturesAllowed DML = new FeaturesAllowed("DML").add(SELECT, INSERT, UPDATE, DELETE, MERGE)
- .unmodifyable();
+ public static final FeaturesAllowed DML =
+ new FeaturesAllowed("DML").add(SELECT, INSERT, UPDATE, DELETE, MERGE)
+ .unmodifyable();
- public static final FeaturesAllowed EXECUTE = new FeaturesAllowed("EXECUTE", Feature.execute).unmodifyable();
+ public static final FeaturesAllowed EXECUTE =
+ new FeaturesAllowed("EXECUTE", Feature.execute).unmodifyable();
/**
* all "CREATE" {@link Feature}'s
*/
public static final FeaturesAllowed CREATE = new FeaturesAllowed("CREATE", Feature.createIndex,
- Feature.createSchema, Feature.createSequence, Feature.createTable, Feature.createTableUnlogged,
+ Feature.createSchema, Feature.createSequence, Feature.createTable,
+ Feature.createTableUnlogged,
Feature.createTableCreateOptionStrings, Feature.createTableTableOptionStrings,
- Feature.createTableIfNotExists, Feature.createTableRowMovement, Feature.createTableFromSelect,
+ Feature.createTableIfNotExists, Feature.createTableRowMovement,
+ Feature.createTableFromSelect,
Feature.createTrigger,
Feature.createView).unmodifyable();
/**
* all "ALTER" {@link Feature}'s
*/
- public static final FeaturesAllowed ALTER = new FeaturesAllowed("ALTER", Feature.alterTable, Feature.alterSequence,
- Feature.alterView, Feature.alterIndex)
- .unmodifyable();
+ public static final FeaturesAllowed ALTER =
+ new FeaturesAllowed("ALTER", Feature.alterTable, Feature.alterSequence,
+ Feature.alterView, Feature.alterIndex)
+ .unmodifyable();
/**
* all "DROP" {@link Feature}'s
*/
- public static final FeaturesAllowed DROP = new FeaturesAllowed("DROP", Feature.drop, Feature.dropTable,
- Feature.dropIndex, Feature.dropView, Feature.dropSchema, Feature.dropSequence, Feature.dropTableIfExists,
- Feature.dropIndexIfExists, Feature.dropViewIfExists, Feature.dropSchemaIfExists,
- Feature.dropSequenceIfExists)
- .unmodifyable();
+ public static final FeaturesAllowed DROP =
+ new FeaturesAllowed("DROP", Feature.drop, Feature.dropTable,
+ Feature.dropIndex, Feature.dropView, Feature.dropSchema, Feature.dropSequence,
+ Feature.dropTableIfExists,
+ Feature.dropIndexIfExists, Feature.dropViewIfExists, Feature.dropSchemaIfExists,
+ Feature.dropSequenceIfExists)
+ .unmodifyable();
/**
* all DDL {@link Feature}'s
*/
- public static final FeaturesAllowed DDL = new FeaturesAllowed("DDL").add(CREATE, ALTER, DROP).unmodifyable();
+ public static final FeaturesAllowed DDL =
+ new FeaturesAllowed("DDL").add(CREATE, ALTER, DROP).unmodifyable();
private Set names = new LinkedHashSet<>();
private Set features = new HashSet<>();
@@ -278,7 +293,8 @@ public ValidationException getMessage(Feature feature) {
@Override
public String getName() {
- return names.isEmpty() ? FeatureSetValidation.super.getName() : names.stream().collect(Collectors.joining(SEPERATOR));
+ return names.isEmpty() ? FeatureSetValidation.super.getName()
+ : names.stream().collect(Collectors.joining(SEPERATOR));
}
@@ -289,7 +305,8 @@ public Set getFeatures() {
private List collectNames(FeatureSetValidation fs) {
String name = fs.getName();
- return Stream.of(name.split(SEPERATOR_REGEX)).map(String::trim).collect(Collectors.toList());
+ return Stream.of(name.split(SEPERATOR_REGEX)).map(String::trim)
+ .collect(Collectors.toList());
}
}
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/MySqlVersion.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/MySqlVersion.java
index d631344d8..3486261ed 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/feature/MySqlVersion.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/MySqlVersion.java
@@ -60,6 +60,7 @@ public enum MySqlVersion implements Version {
Feature.insert,
Feature.insertValues,
Feature.values,
+ Feature.tableStatement,
Feature.insertFromSelect, Feature.insertUseSet, Feature.insertModifierPriority,
Feature.insertModifierIgnore, Feature.insertUseDuplicateKeyUpdate,
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java
index 88166c1b5..3cba4a988 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java
@@ -9,6 +9,7 @@
*/
package net.sf.jsqlparser.util.validation.validator;
+import java.util.List;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.MySQLIndexHint;
import net.sf.jsqlparser.expression.SQLServerHints;
@@ -33,6 +34,7 @@
import net.sf.jsqlparser.statement.select.SelectVisitor;
import net.sf.jsqlparser.statement.select.SetOperationList;
import net.sf.jsqlparser.statement.select.TableFunction;
+import net.sf.jsqlparser.statement.select.TableStatement;
import net.sf.jsqlparser.statement.select.UnPivot;
import net.sf.jsqlparser.statement.select.UnionOp;
import net.sf.jsqlparser.statement.select.Values;
@@ -41,8 +43,6 @@
import net.sf.jsqlparser.util.validation.ValidationUtil;
import net.sf.jsqlparser.util.validation.metadata.NamedObject;
-import java.util.List;
-
/**
* @author gitmotte
*/
@@ -306,6 +306,11 @@ public void visit(LateralSubSelect lateralSubSelect) {
validateOptional(lateralSubSelect.getSelect(), e -> e.accept(this));
}
+ @Override
+ public void visit(TableStatement tableStatement) {
+ getValidator(TableStatementValidator.class).validate(tableStatement);
+ }
+
@Override
public void visit(TableFunction tableFunction) {
validateFeature(Feature.tableFunction);
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/TableStatementValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/TableStatementValidator.java
new file mode 100644
index 000000000..4b954126e
--- /dev/null
+++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/TableStatementValidator.java
@@ -0,0 +1,27 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2019 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+package net.sf.jsqlparser.util.validation.validator;
+
+import net.sf.jsqlparser.parser.feature.Feature;
+import net.sf.jsqlparser.statement.select.TableStatement;
+import net.sf.jsqlparser.util.validation.ValidationCapability;
+
+/**
+ * @author jxnu-liguobin
+ */
+public class TableStatementValidator extends AbstractValidator {
+
+ @Override
+ public void validate(TableStatement statement) {
+ for (ValidationCapability c : getCapabilities()) {
+ validateFeature(c, Feature.tableStatement);
+ }
+ }
+}
diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
index 6e6cce16b..547324944 100644
--- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
+++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
@@ -676,6 +676,8 @@ Statement SingleStatement() :
|
stm = Select()
|
+ stm = TableStatement()
+ |
LOOKAHEAD(3) stm = Upsert()
|
LOOKAHEAD(2) stm = Alter()
@@ -2002,6 +2004,24 @@ Select Select() #Select:
}
}
+TableStatement TableStatement():
+{
+ Table table = null;
+ List orderByElements = null;
+ Limit limit = null;
+ Offset offset = null;
+ TableStatement tableStatement = new TableStatement();
+}{
+
+ table = Table()
+ { tableStatement.setTable(table); }
+ [ LOOKAHEAD( ) orderByElements = OrderByElements() { tableStatement.setOrderByElements(orderByElements); } ]
+ [ LOOKAHEAD() limit=LimitWithOffset() { tableStatement.setLimit(limit);} ]
+ [ LOOKAHEAD() offset = Offset() { tableStatement.setOffset(offset);} ]
+ { return tableStatement; }
+ /* Support operationList */
+}
+
ParenthesedSelect ParenthesedSelect() #ParenthesedSelect:
{
ParenthesedSelect parenthesedSelect = new ParenthesedSelect();
diff --git a/src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java b/src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java
index 0b78f60d0..f5010099e 100644
--- a/src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java
+++ b/src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java
@@ -9,6 +9,12 @@
*/
package net.sf.jsqlparser.parser;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
import java.io.ByteArrayInputStream;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
@@ -19,7 +25,6 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
-
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
@@ -29,15 +34,9 @@
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.Statements;
-
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
import net.sf.jsqlparser.statement.UnsupportedStatement;
import net.sf.jsqlparser.statement.select.PlainSelect;
+import net.sf.jsqlparser.statement.select.TableStatement;
import net.sf.jsqlparser.test.MemoryLeakVerifier;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
@@ -336,6 +335,13 @@ public void testCondExpressionIssue1482() throws JSQLParserException {
assertEquals("test_table_enum.f1_enum IN ('TEST2'::test.test_enum)", expr.toString());
}
+ @Test
+ public void testTableStatementIssue1836() throws JSQLParserException {
+ TableStatement expr = (TableStatement) CCJSqlParserUtil
+ .parse("TABLE columns ORDER BY column_name LIMIT 10 OFFSET 10");
+ assertEquals("TABLE columns ORDER BY column_name LIMIT 10 OFFSET 10", expr.toString());
+ }
+
@Test
public void testCondExpressionIssue1482_2() throws JSQLParserException {
Expression expr = CCJSqlParserUtil.parseCondExpression(
diff --git a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java
index f4a0b77f6..5fb760b93 100644
--- a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java
+++ b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java
@@ -9,6 +9,28 @@
*/
package net.sf.jsqlparser.statement.select;
+import static net.sf.jsqlparser.test.TestUtils.assertDeparse;
+import static net.sf.jsqlparser.test.TestUtils.assertExpressionCanBeDeparsedAs;
+import static net.sf.jsqlparser.test.TestUtils.assertExpressionCanBeParsedAndDeparsed;
+import static net.sf.jsqlparser.test.TestUtils.assertOracleHintExists;
+import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;
+import static net.sf.jsqlparser.test.TestUtils.assertStatementCanBeDeparsedAs;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.AllValue;
@@ -56,29 +78,6 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
-import java.io.IOException;
-import java.io.StringReader;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-
-import static net.sf.jsqlparser.test.TestUtils.assertDeparse;
-import static net.sf.jsqlparser.test.TestUtils.assertExpressionCanBeDeparsedAs;
-import static net.sf.jsqlparser.test.TestUtils.assertExpressionCanBeParsedAndDeparsed;
-import static net.sf.jsqlparser.test.TestUtils.assertOracleHintExists;
-import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;
-import static net.sf.jsqlparser.test.TestUtils.assertStatementCanBeDeparsedAs;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertInstanceOf;
-import static org.junit.jupiter.api.Assertions.assertNotEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
-
@Execution(ExecutionMode.CONCURRENT)
public class SelectTest {
@@ -4615,6 +4614,20 @@ public void testMultiColumnAliasIssue849_2() throws JSQLParserException {
"SELECT * FROM crosstab('select rowid, attribute, value from ct where attribute = ''att2'' or attribute = ''att3'' order by 1,2') AS ct(row_name text, category_1 text, category_2 text, category_3 text)");
}
+ @Test
+ public void testTableStatementIssue1836() throws JSQLParserException {
+ assertSqlCanBeParsedAndDeparsed(
+ "TABLE columns ORDER BY column_name LIMIT 10 OFFSET 10");
+ assertSqlCanBeParsedAndDeparsed(
+ "TABLE columns ORDER BY column_name LIMIT 10");
+ assertSqlCanBeParsedAndDeparsed(
+ "TABLE columns ORDER BY column_name");
+ assertSqlCanBeParsedAndDeparsed(
+ "TABLE columns LIMIT 10 OFFSET 10");
+ assertSqlCanBeParsedAndDeparsed(
+ "TABLE columns LIMIT 10");
+ }
+
@Test
public void testLimitClauseDroppedIssue845() throws JSQLParserException {
assertEquals("SELECT * FROM employee ORDER BY emp_id LIMIT 10 OFFSET 2", CCJSqlParserUtil
diff --git a/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java b/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java
index e0f2d0b97..4248ef494 100644
--- a/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java
+++ b/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java
@@ -9,6 +9,13 @@
*/
package net.sf.jsqlparser.util.deparser;
+import static org.mockito.BDDMockito.then;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
@@ -26,6 +33,7 @@
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.SelectVisitor;
+import net.sf.jsqlparser.statement.select.TableStatement;
import net.sf.jsqlparser.statement.select.WithItem;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.update.UpdateSet;
@@ -37,14 +45,6 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.mockito.BDDMockito.then;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-
@ExtendWith(MockitoExtension.class)
public class StatementDeParserTest {
@@ -56,8 +56,12 @@ public class StatementDeParserTest {
private StatementDeParser statementDeParser;
+ private TableStatementDeParser tableStatementDeParser;
+
@BeforeEach
public void setUp() {
+ tableStatementDeParser =
+ new TableStatementDeParser(expressionDeParser, new StringBuilder());
statementDeParser =
new StatementDeParser(expressionDeParser, selectDeParser, new StringBuilder());
}
@@ -326,6 +330,13 @@ public void testIssue1500AllColumns() throws JSQLParserException {
selectBody.accept(new SelectDeParser());
}
+ @Test
+ public void testIssue1836() throws JSQLParserException {
+ String sqlStr = "TABLE columns ORDER BY column_name LIMIT 10 OFFSET 10;";
+ TableStatement tableStatement = (TableStatement) CCJSqlParserUtil.parse(sqlStr);
+ tableStatement.accept(tableStatementDeParser);
+ }
+
@Test
public void testIssue1500AllTableColumns() throws JSQLParserException {
String sqlStr = "select count(a.*) from some_table a";
diff --git a/src/test/java/net/sf/jsqlparser/util/validation/validator/TableStatementValidatorTest.java b/src/test/java/net/sf/jsqlparser/util/validation/validator/TableStatementValidatorTest.java
new file mode 100644
index 000000000..c71b8448e
--- /dev/null
+++ b/src/test/java/net/sf/jsqlparser/util/validation/validator/TableStatementValidatorTest.java
@@ -0,0 +1,38 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2020 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+package net.sf.jsqlparser.util.validation.validator;
+
+import java.util.Arrays;
+import net.sf.jsqlparser.JSQLParserException;
+import net.sf.jsqlparser.parser.feature.Feature;
+import net.sf.jsqlparser.util.validation.ValidationTestAsserts;
+import net.sf.jsqlparser.util.validation.feature.FeaturesAllowed;
+import net.sf.jsqlparser.util.validation.feature.MySqlVersion;
+import net.sf.jsqlparser.util.validation.feature.PostgresqlVersion;
+import org.junit.jupiter.api.Test;
+
+public class TableStatementValidatorTest extends ValidationTestAsserts {
+
+ @Test
+ public void testValidationSelectAllowed() throws JSQLParserException {
+ String sql = "TABLE columns ORDER BY column_name LIMIT 10 OFFSET 10";
+ validateNoErrors(sql, 1, MySqlVersion.V8_0);
+ }
+
+ @Test
+ public void testValidationSelectNotAllowed() throws JSQLParserException {
+ String sql = "TABLE columns ORDER BY column_name LIMIT 10 OFFSET 10";
+ validateNotAllowed(sql, 1, 1, FeaturesAllowed.DDL, Feature.select, Feature.tableStatement);
+
+ validateNotSupported(sql, 1, 1, Arrays.asList(
+ PostgresqlVersion.V14), Feature.tableStatement);
+ }
+
+}