Skip to content

fix insert default values statements not parsing #2050

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public class ParserKeywordsUtils {
{"CREATE", RESTRICTED_ALIAS},
{"CROSS", RESTRICTED_SQL2016},
{"CURRENT", RESTRICTED_JSQLPARSER},
{"DEFAULT", RESTRICTED_ALIAS},
{"DISTINCT", RESTRICTED_SQL2016},
{"DOUBLE", RESTRICTED_ALIAS},
{"ELSE", RESTRICTED_JSQLPARSER},
Expand Down
19 changes: 18 additions & 1 deletion src/main/java/net/sf/jsqlparser/statement/insert/Insert.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class Insert implements Statement {
private OracleHint oracleHint = null;
private ExpressionList<Column> columns;
private Select select;
private boolean onlyDefaultValues = false;
private List<UpdateSet> duplicateUpdateSets = null;
private InsertModifierPriority modifierPriority = null;
private boolean modifierIgnore = false;
Expand Down Expand Up @@ -162,7 +163,6 @@ public void setModifierIgnore(boolean modifierIgnore) {
this.modifierIgnore = modifierIgnore;
}


@Deprecated
public boolean isUseSet() {
return setUpdateSets != null && !setUpdateSets.isEmpty();
Expand All @@ -176,6 +176,19 @@ public void setWithItemsList(List<WithItem> withItemsList) {
this.withItemsList = withItemsList;
}

public boolean isOnlyDefaultValues() {
return onlyDefaultValues;
}

public void setOnlyDefaultValues(boolean onlyDefaultValues) {
this.onlyDefaultValues = onlyDefaultValues;
}

public Insert withOnlyDefaultValues(boolean onlyDefaultValues) {
this.setOnlyDefaultValues(onlyDefaultValues);
return this;
}

public InsertConflictTarget getConflictTarget() {
return conflictTarget;
}
Expand Down Expand Up @@ -230,6 +243,10 @@ public String toString() {
sql.append("INTO ");
sql.append(table).append(" ");

if (onlyDefaultValues) {
sql.append("DEFAULT VALUES");
}

if (columns != null) {
sql.append("(");
for (int i = 0; i < columns.size(); i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ public void deParse(Insert insert) {
buffer.append("INTO ");

buffer.append(insert.getTable().toString());

if (insert.isOnlyDefaultValues()) {
buffer.append(" DEFAULT VALUES");
}

if (insert.getColumns() != null) {
buffer.append(" (");
for (Iterator<Column> iter = insert.getColumns().iterator(); iter.hasNext();) {
Expand Down
6 changes: 4 additions & 2 deletions src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -1602,6 +1602,8 @@ Insert Insert( List<WithItem> with ):
[ outputClause = OutputClause() { insert.setOutputClause(outputClause); } ]

(
<K_DEFAULT> <K_VALUES> { insert.setOnlyDefaultValues(true); }
|
(
<K_SET> updateSets = UpdateSets() { insert.withSetUpdateSets(updateSets); }
)
Expand Down Expand Up @@ -1959,7 +1961,7 @@ String RelObjectNameWithoutValue() :
{ Token tk = null; }
{
( tk=<DATA_TYPE> | tk=<S_IDENTIFIER> | tk=<S_QUOTED_IDENTIFIER> | tk=<K_DATE_LITERAL> | tk=<K_DATETIMELITERAL> | tk=<K_STRING_FUNCTION_NAME> | tk=<K_ISOLATION> | tk=<K_TIME_KEY_EXPR> | tk=<K_TEXT_LITERAL>
| tk="ACTION" | tk="ACTIVE" | tk="ADD" | tk="ADVANCE" | tk="ADVISE" | tk="AGAINST" | tk="ALGORITHM" | tk="ALTER" | tk="ANALYZE" | tk="APPLY" | tk="APPROXIMATE" | tk="ARCHIVE" | tk="ARRAY" | tk="ASC" | tk="AT" | tk="AUTHORIZATION" | tk="AUTO" | tk="BASE64" | tk="BEGIN" | tk="BERNOULLI" | tk="BINARY" | tk="BIT" | tk="BLOCK" | tk="BROWSE" | tk="BUFFERS" | tk="BY" | tk="BYTE" | tk="BYTES" | tk="CACHE" | tk="CALL" | tk="CASCADE" | tk="CASE" | tk="CAST" | tk="CHANGE" | tk="CHANGES" | tk="CHAR" | tk="CHARACTER" | tk="CHECKPOINT" | tk="CLOSE" | tk="COLLATE" | tk="COLUMN" | tk="COLUMNS" | tk="COMMENT" | tk="COMMIT" | tk="CONCURRENTLY" | tk="CONFLICT" | tk="CONSTRAINTS" | tk="CONVERT" | tk="COSTS" | tk="CS" | tk="CYCLE" | tk="DATA" | tk="DATABASE" | tk="DATETIME" | tk="DBA_RECYCLEBIN" | tk="DDL" | tk="DECLARE" | tk="DEFAULT" | tk="DEFERRABLE" | tk="DELAYED" | tk="DELETE" | tk="DESC" | tk="DESCRIBE" | tk="DISABLE" | tk="DISCONNECT" | tk="DIV" | tk="DML" | tk="DO" | tk="DOMAIN" | tk="DROP" | tk="DUMP" | tk="DUPLICATE" | tk="ELEMENTS" | tk="EMIT" | tk="ENABLE" | tk="END" | tk="ESCAPE" | tk="EXCLUDE" | tk="EXEC" | tk="EXECUTE" | tk="EXPLAIN" | tk="EXPLICIT" | tk="EXTENDED" | tk="EXTRACT" | tk="FALSE" | tk="FILTER" | tk="FIRST" | tk="FLUSH" | tk="FN" | tk="FOLLOWING" | tk="FORMAT" | tk="FULLTEXT" | tk="FUNCTION" | tk="GRANT" | tk="GROUP_CONCAT" | tk="GUARD" | tk="HASH" | tk="HIGH_PRIORITY" | tk="HISTORY" | tk="HOPPING" | tk="INCLUDE" | tk="INCLUDE_NULL_VALUES" | tk="INCREMENT" | tk="INDEX" | tk="INSERT" | tk="INTERLEAVE" | tk="INTERPRET" | tk="INVALIDATE" | tk="ISNULL" | tk="JSON" | tk="JSON_ARRAY" | tk="JSON_ARRAYAGG" | tk="JSON_OBJECT" | tk="JSON_OBJECTAGG" | tk="KEEP" | tk="KEY" | tk="KEYS" | tk="LAST" | tk="LEADING" | tk="LINK" | tk="LOCAL" | tk="LOCKED" | tk="LOG" | tk="LONGTEXT" | tk="LOOP" | tk="LOW_PRIORITY" | tk="MATCH" | tk="MATCHED" | tk="MATERIALIZED" | tk="MAX" | tk="MAXVALUE" | tk="MEDIUMTEXT" | tk="MEMBER" | tk="MERGE" | tk="MIN" | tk="MINVALUE" | tk="MODIFY" | tk="MOVEMENT" | tk="NEXT" | tk="NO" | tk="NOCACHE" | tk="NOKEEP" | tk="NOLOCK" | tk="NOMAXVALUE" | tk="NOMINVALUE" | tk="NOORDER" | tk="NOTHING" | tk="NOTNULL" | tk="NOVALIDATE" | tk="NOWAIT" | tk="NULLS" | tk="OF" | tk="OFF" | tk="OPEN" | tk="OVER" | tk="OVERLAPS" | tk="PARALLEL" | tk="PARENT" | tk="PARTITION" | tk="PATH" | tk="PERCENT" | tk="PLACING" | tk="PRECEDING" | tk="PRIMARY" | tk="PRIOR" | tk="PURGE" | tk="QUERY" | tk="QUICK" | tk="QUIESCE" | tk="RANGE" | tk="RAW" | tk="READ" | tk="RECURSIVE" | tk="RECYCLEBIN" | tk="REFERENCES" | tk="REFRESH" | tk="REGEXP" | tk="REGISTER" | tk="REMOTE" | tk="RENAME" | tk="REPEATABLE" | tk="REPLACE" | tk="RESET" | tk="RESPECT" | tk="RESTART" | tk="RESTRICT" | tk="RESTRICTED" | tk="RESUMABLE" | tk="RESUME" | tk="RETURN" | tk="RLIKE" | tk="ROLLBACK" | tk="ROLLUP" | tk="ROOT" | tk="ROW" | tk="ROWS" | tk="RR" | tk="RS" | tk="SAFE_CAST" | tk="SAVEPOINT" | tk="SCHEMA" | tk="SECURE" | tk="SEED" | tk="SEPARATOR" | tk="SEQUENCE" | tk="SESSION" | tk="SETS" | tk="SHARE" | tk="SHOW" | tk="SHUTDOWN" | tk="SIBLINGS" | tk="SIGNED" | tk="SIMILAR" | tk="SIZE" | tk="SKIP" | tk="STORED" | tk="STRING" | tk="STRUCT" | tk="SUSPEND" | tk="SWITCH" | tk="SYNONYM" | tk="SYSTEM" | tk="TABLE" | tk="TABLESPACE" | tk="TEMP" | tk="TEMPORARY" | tk="TEXT" | tk="THEN" | tk="TIMEOUT" | tk="TIMESTAMPTZ" | tk="TIMEZONE" | tk="TINYTEXT" | tk="TO" | tk="TRIGGER" | tk="TRUE" | tk="TRUNCATE" | tk="TRY_CAST" | tk="TUMBLING" | tk="TYPE" | tk="UNLOGGED" | tk="UNQIESCE" | tk="UNSIGNED" | tk="UPDATE" | tk="UPSERT" | tk="UR" | tk="USER" | tk="VALIDATE" | tk="VERBOSE" | tk="VIEW" | tk="VOLATILE" | tk="WAIT" | tk="WITHIN" | tk="WITHOUT" | tk="WITHOUT_ARRAY_WRAPPER" | tk="WORK" | tk="XML" | tk="XMLAGG" | tk="XMLDATA" | tk="XMLSCHEMA" | tk="XMLTEXT" | tk="XSINIL" | tk="YAML" | tk="YES" | tk="ZONE" )
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only change here is that tk="DEFAULT" has been removed, added to line 1978

| tk="ACTION" | tk="ACTIVE" | tk="ADD" | tk="ADVANCE" | tk="ADVISE" | tk="AGAINST" | tk="ALGORITHM" | tk="ALTER" | tk="ANALYZE" | tk="APPLY" | tk="APPROXIMATE" | tk="ARCHIVE" | tk="ARRAY" | tk="ASC" | tk="AT" | tk="AUTHORIZATION" | tk="AUTO" | tk="BASE64" | tk="BEGIN" | tk="BERNOULLI" | tk="BINARY" | tk="BIT" | tk="BLOCK" | tk="BROWSE" | tk="BUFFERS" | tk="BY" | tk="BYTE" | tk="BYTES" | tk="CACHE" | tk="CALL" | tk="CASCADE" | tk="CASE" | tk="CAST" | tk="CHANGE" | tk="CHANGES" | tk="CHAR" | tk="CHARACTER" | tk="CHECKPOINT" | tk="CLOSE" | tk="COLLATE" | tk="COLUMN" | tk="COLUMNS" | tk="COMMENT" | tk="COMMIT" | tk="CONCURRENTLY" | tk="CONFLICT" | tk="CONSTRAINTS" | tk="CONVERT" | tk="COSTS" | tk="CS" | tk="CYCLE" | tk="DATA" | tk="DATABASE" | tk="DATETIME" | tk="DBA_RECYCLEBIN" | tk="DDL" | tk="DECLARE" | tk="DEFERRABLE" | tk="DELAYED" | tk="DELETE" | tk="DESC" | tk="DESCRIBE" | tk="DISABLE" | tk="DISCONNECT" | tk="DIV" | tk="DML" | tk="DO" | tk="DOMAIN" | tk="DROP" | tk="DUMP" | tk="DUPLICATE" | tk="ELEMENTS" | tk="EMIT" | tk="ENABLE" | tk="END" | tk="ESCAPE" | tk="EXCLUDE" | tk="EXEC" | tk="EXECUTE" | tk="EXPLAIN" | tk="EXPLICIT" | tk="EXTENDED" | tk="EXTRACT" | tk="FALSE" | tk="FILTER" | tk="FIRST" | tk="FLUSH" | tk="FN" | tk="FOLLOWING" | tk="FORMAT" | tk="FULLTEXT" | tk="FUNCTION" | tk="GRANT" | tk="GROUP_CONCAT" | tk="GUARD" | tk="HASH" | tk="HIGH_PRIORITY" | tk="HISTORY" | tk="HOPPING" | tk="INCLUDE" | tk="INCLUDE_NULL_VALUES" | tk="INCREMENT" | tk="INDEX" | tk="INSERT" | tk="INTERLEAVE" | tk="INTERPRET" | tk="INVALIDATE" | tk="ISNULL" | tk="JSON" | tk="JSON_ARRAY" | tk="JSON_ARRAYAGG" | tk="JSON_OBJECT" | tk="JSON_OBJECTAGG" | tk="KEEP" | tk="KEY" | tk="KEYS" | tk="LAST" | tk="LEADING" | tk="LINK" | tk="LOCAL" | tk="LOCKED" | tk="LOG" | tk="LONGTEXT" | tk="LOOP" | tk="LOW_PRIORITY" | tk="MATCH" | tk="MATCHED" | tk="MATERIALIZED" | tk="MAX" | tk="MAXVALUE" | tk="MEDIUMTEXT" | tk="MEMBER" | tk="MERGE" | tk="MIN" | tk="MINVALUE" | tk="MODIFY" | tk="MOVEMENT" | tk="NEXT" | tk="NO" | tk="NOCACHE" | tk="NOKEEP" | tk="NOLOCK" | tk="NOMAXVALUE" | tk="NOMINVALUE" | tk="NOORDER" | tk="NOTHING" | tk="NOTNULL" | tk="NOVALIDATE" | tk="NOWAIT" | tk="NULLS" | tk="OF" | tk="OFF" | tk="OPEN" | tk="OVER" | tk="OVERLAPS" | tk="PARALLEL" | tk="PARENT" | tk="PARTITION" | tk="PATH" | tk="PERCENT" | tk="PLACING" | tk="PRECEDING" | tk="PRIMARY" | tk="PRIOR" | tk="PURGE" | tk="QUERY" | tk="QUICK" | tk="QUIESCE" | tk="RANGE" | tk="RAW" | tk="READ" | tk="RECURSIVE" | tk="RECYCLEBIN" | tk="REFERENCES" | tk="REFRESH" | tk="REGEXP" | tk="REGISTER" | tk="REMOTE" | tk="RENAME" | tk="REPEATABLE" | tk="REPLACE" | tk="RESET" | tk="RESPECT" | tk="RESTART" | tk="RESTRICT" | tk="RESTRICTED" | tk="RESUMABLE" | tk="RESUME" | tk="RETURN" | tk="RLIKE" | tk="ROLLBACK" | tk="ROLLUP" | tk="ROOT" | tk="ROW" | tk="ROWS" | tk="RR" | tk="RS" | tk="SAFE_CAST" | tk="SAVEPOINT" | tk="SCHEMA" | tk="SECURE" | tk="SEED" | tk="SEPARATOR" | tk="SEQUENCE" | tk="SESSION" | tk="SETS" | tk="SHARE" | tk="SHOW" | tk="SHUTDOWN" | tk="SIBLINGS" | tk="SIGNED" | tk="SIMILAR" | tk="SIZE" | tk="SKIP" | tk="STORED" | tk="STRING" | tk="STRUCT" | tk="SUSPEND" | tk="SWITCH" | tk="SYNONYM" | tk="SYSTEM" | tk="TABLE" | tk="TABLESPACE" | tk="TEMP" | tk="TEMPORARY" | tk="TEXT" | tk="THEN" | tk="TIMEOUT" | tk="TIMESTAMPTZ" | tk="TIMEZONE" | tk="TINYTEXT" | tk="TO" | tk="TRIGGER" | tk="TRUE" | tk="TRUNCATE" | tk="TRY_CAST" | tk="TUMBLING" | tk="TYPE" | tk="UNLOGGED" | tk="UNQIESCE" | tk="UNSIGNED" | tk="UPDATE" | tk="UPSERT" | tk="UR" | tk="USER" | tk="VALIDATE" | tk="VERBOSE" | tk="VIEW" | tk="VOLATILE" | tk="WAIT" | tk="WITHIN" | tk="WITHOUT" | tk="WITHOUT_ARRAY_WRAPPER" | tk="WORK" | tk="XML" | tk="XMLAGG" | tk="XMLDATA" | tk="XMLSCHEMA" | tk="XMLTEXT" | tk="XSINIL" | tk="YAML" | tk="YES" | tk="ZONE" )
{ return tk.image; }
}

Expand All @@ -1973,7 +1975,7 @@ String RelObjectName() :
(result = RelObjectNameWithoutValue()
| tk=<K_GROUP> | tk=<K_INTERVAL> | tk=<K_ON> | tk=<K_START> | tk=<K_TOP> | tk=<K_VALUE>
| tk=<K_VALUES> | tk=<K_CREATE> | tk=<K_TABLES> | tk=<K_CONNECT> | tk=<K_IGNORE >
| tk=<K_QUALIFY>
| tk=<K_QUALIFY> | tk=<K_DEFAULT>
)

{ return tk!=null ? tk.image : result; }
Expand Down
4 changes: 3 additions & 1 deletion src/site/sphinx/keywords.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ The following Keywords are **restricted** in JSQLParser-|JSQLPARSER_VERSION| and
+----------------------+-------------+-----------+
| CURRENT | Yes | Yes |
+----------------------+-------------+-----------+
| DISTINCT | Yes | Yes |
| DEFAULT | Yes | |
+----------------------+-------------+-----------+
| DISTINCT | Yes | Yes |
+----------------------+-------------+-----------+
| DOUBLE | Yes | |
+----------------------+-------------+-----------+
Expand Down
52 changes: 52 additions & 0 deletions src/test/java/net/sf/jsqlparser/statement/insert/InsertTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package net.sf.jsqlparser.statement.insert;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.DoubleValue;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.JdbcParameter;
Expand Down Expand Up @@ -590,4 +591,55 @@ void testMultiColumnConflictTargetIssue955() throws JSQLParserException {
+ "on conflict(xxx0, xxx1) do update set xxx1=?, update_time=?";
assertSqlCanBeParsedAndDeparsed(sqlStr, true);
}

@Test
public void testDefaultValues() throws JSQLParserException {
String statement = "INSERT INTO mytable DEFAULT VALUES";
//assertSqlCanBeParsedAndDeparsed(statement);
Insert insert = (Insert) parserManager.parse(new StringReader(statement));
assertEquals("mytable", insert.getTable().getFullyQualifiedName());
assertEquals("INSERT INTO MYTABLE DEFAULT VALUES", insert.toString().toUpperCase());
assertTrue(insert.isOnlyDefaultValues());
assertDeparse(new Insert()
.withTable(new Table("mytable"))
.withOnlyDefaultValues(true), statement);
}

@Test
public void testDefaultValuesWithAlias() throws JSQLParserException {
String statement = "INSERT INTO mytable x DEFAULT VALUES";
assertSqlCanBeParsedAndDeparsed(statement);
Insert insert = (Insert) parserManager.parse(new StringReader(statement));
assertEquals("mytable", insert.getTable().getFullyQualifiedName());
assertEquals("INSERT INTO MYTABLE X DEFAULT VALUES", insert.toString().toUpperCase());
assertEquals("x", insert.getTable().getAlias().getName());
assertTrue(insert.isOnlyDefaultValues());
assertDeparse(new Insert()
.withTable(new Table("mytable")
.withAlias(new Alias("x").withUseAs(false)))
.withOnlyDefaultValues(true), statement);
}

@Test
public void testDefaultValuesWithAliasAndAs() throws JSQLParserException {
String statement = "INSERT INTO mytable AS x DEFAULT VALUES";
assertSqlCanBeParsedAndDeparsed(statement);
Insert insert = (Insert) parserManager.parse(new StringReader(statement));
assertEquals("mytable", insert.getTable().getFullyQualifiedName());
assertEquals("INSERT INTO MYTABLE AS X DEFAULT VALUES", insert.toString().toUpperCase());
assertEquals("x", insert.getTable().getAlias().getName());
assertTrue(insert.isOnlyDefaultValues());
assertDeparse(new Insert()
.withTable(new Table("mytable")
.withAlias(new Alias("x").withUseAs(true)))
.withOnlyDefaultValues(true), statement);
}

@Test
public void throwsParseWhenDefaultKeyowrdUsedAsAlias() {
String statement = "INSERT INTO mytable default DEFAULT VALUES";
assertThrows(JSQLParserException.class,
() -> parserManager.parse(new StringReader(statement)));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static net.sf.jsqlparser.test.TestUtils.assertDeparse;
import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -104,4 +105,12 @@ public void testTruncateOnlyAndCascadeDeparse() throws JSQLParserException {
.withCascade(true)
.withOnly(true), statement);
}

@Test
public void throwsParseWhenOnlyUsedWithMultipleTables() {
String statement = "TRUNCATE TABLE ONLY foo, bar";
assertThrows(JSQLParserException.class,
() -> parserManager.parse(new StringReader(statement)));
}

}
Loading