Skip to content

Commit 589893e

Browse files
feat: parse INSERT OR ABORT, FAIL, IGNORE and ROLLBACK (SQLite)
UpsertType and the deparsers already had these values, but the grammar only accepted INSERT OR REPLACE. Part of #2852
1 parent 90ac3a7 commit 589893e

2 files changed

Lines changed: 38 additions & 1 deletion

File tree

‎src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7952,7 +7952,22 @@ Upsert Upsert():
79527952
<K_REPLACE> { upsert.setUpsertType(UpsertType.REPLACE); }
79537953
|
79547954
(
7955-
<K_INSERT> <K_OR> <K_REPLACE> { upsert.setUpsertType(UpsertType.INSERT_OR_REPLACE); }
7955+
<K_INSERT> <K_OR>
7956+
(
7957+
<K_REPLACE> { upsert.setUpsertType(UpsertType.INSERT_OR_REPLACE); }
7958+
|
7959+
<K_IGNORE> { upsert.setUpsertType(UpsertType.INSERT_OR_IGNORE); }
7960+
|
7961+
<K_ROLLBACK> { upsert.setUpsertType(UpsertType.INSERT_OR_ROLLBACK); }
7962+
|
7963+
// SQLite conflict resolution algorithms that are not keywords of the parser
7964+
tk=<S_IDENTIFIER> {
7965+
requireDdlSyntax("ABORT".equalsIgnoreCase(tk.image) || "FAIL".equalsIgnoreCase(tk.image),
7966+
"Expected ABORT, FAIL, IGNORE, REPLACE or ROLLBACK");
7967+
upsert.setUpsertType("ABORT".equalsIgnoreCase(tk.image)
7968+
? UpsertType.INSERT_OR_ABORT : UpsertType.INSERT_OR_FAIL);
7969+
}
7970+
)
79567971
)
79577972
)
79587973
[ LOOKAHEAD(2) <K_INTO> { upsert.setUsingInto(true); } ]

‎src/test/java/net/sf/jsqlparser/statement/select/SQLiteTest.java‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,35 @@
1010
package net.sf.jsqlparser.statement.select;
1111

1212
import net.sf.jsqlparser.JSQLParserException;
13+
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
1314
import net.sf.jsqlparser.test.TestUtils;
1415
import org.junit.jupiter.api.Test;
16+
import org.junit.jupiter.params.ParameterizedTest;
17+
import org.junit.jupiter.params.provider.ValueSource;
18+
19+
import java.util.Locale;
20+
21+
import static org.junit.jupiter.api.Assertions.assertThrows;
1522

1623
public class SQLiteTest {
1724
@Test
1825
void testInsertOrReplaceUpsert() throws JSQLParserException {
1926
String sqlString = "INSERT OR REPLACE INTO kjobLocks VALUES (?, ?, ?)";
2027
TestUtils.assertSqlCanBeParsedAndDeparsed(sqlString, true);
2128
}
29+
30+
@ParameterizedTest
31+
@ValueSource(strings = {"ABORT", "FAIL", "IGNORE", "REPLACE", "ROLLBACK"})
32+
void testInsertOrConflictAlgorithm(String algorithm) throws JSQLParserException {
33+
TestUtils.assertSqlCanBeParsedAndDeparsed(
34+
"INSERT OR " + algorithm + " INTO t (a, b) VALUES (1, 2)", true);
35+
TestUtils.assertSqlCanBeParsedAndDeparsed(
36+
"insert or " + algorithm.toLowerCase(Locale.ROOT) + " into t select * from s", true);
37+
}
38+
39+
@Test
40+
void testInsertOrUnknownAlgorithm() {
41+
assertThrows(JSQLParserException.class,
42+
() -> CCJSqlParserUtil.parse("INSERT OR NOTHING INTO t VALUES (1)"));
43+
}
2244
}

0 commit comments

Comments
 (0)