Skip to content

feat: parse UPDATE OR conflict algorithms in the SQLite dialect - #2885

Open
DylanMerigaud wants to merge 1 commit into
JSQLParser:masterfrom
DylanMerigaud:feat/sqlite-update-or
Open

DylanMerigaud wants to merge 1 commit into
JSQLParser:masterfrom
DylanMerigaud:feat/sqlite-update-or

Conversation

@DylanMerigaud

Copy link
Copy Markdown

Part of #2852 (the UPDATE OR part; WITHOUT ROWID and STRICT are not in this PR).

INSERT OR REPLACE already parsed, and #2853 added INSERT OR ABORT, FAIL, IGNORE and ROLLBACK. SQLite takes the same five conflict algorithms after UPDATE OR (lang_update), and the issue's table shows UPDATE OR IGNORE t SET a = 1 and UPDATE OR REPLACE t SET a = 1 stopping at Encountered: <K_UPDATE> / "UPDATE".

What changes:

  • New enum UpdateConflictAlgorithm (ABORT, FAIL, IGNORE, REPLACE, ROLLBACK), next to UpdateModifierPriority.
  • Update gets getConflictAlgorithm(), setConflictAlgorithm() and withConflictAlgorithm(). The value is null for an UPDATE without OR, so existing statements build the same object. Update.toString() and UpdateDeParser print OR <algorithm> right after UPDATE.
  • The Update production reads [ <K_OR> RelObjectName() ] after UPDATE, and AbstractJSqlParser.updateOrAlgorithm maps the word to the enum. This is the shape feat: parse INSERT OR ABORT, FAIL, IGNORE and ROLLBACK (SQLite) #2853 settled on for INSERT OR, which keeps the addition to CCJSqlParser to one optional (the constant-pool headroom of JaCoCo instrumentation of CCJSqlParser is approaching the constant-pool limit #2866).
  • UPDATE OR needs Dialect.SQLITE. Without it, or with a word that is not one of the five, the statement is a parse error.
  • usage.rst lists UPDATE OR in the SQLITE row of the dialect table.

Tests, all in SQLiteTest:

  • testUpdateOrConflictAlgorithm, one case per algorithm: parse and round trip through toString() and the deparser, in upper and lower case, and getConflictAlgorithm() returns that algorithm.
  • testUpdateOrConflictAlgorithmNeedsSqliteDialect, one case per algorithm: rejected without the dialect.
  • testUpdateOrUnknownAlgorithm: UPDATE OR NOTHING is rejected with the dialect.
  • testUpdateWithoutConflictAlgorithm: a plain UPDATE keeps getConflictAlgorithm() null.

The two rejection tests would also pass on a parser with no UPDATE OR support at all; a comment above each says so. They pin the dialect guard and the word check.

SQLite accepts ABORT, FAIL, IGNORE, REPLACE and ROLLBACK after
UPDATE OR. Update gets a conflictAlgorithm (UpdateConflictAlgorithm),
printed by toString() and UpdateDeParser. The grammar reads the word
with RelObjectName and AbstractJSqlParser.updateOrAlgorithm decides
it, as INSERT OR does. UPDATE OR needs Dialect.SQLITE.

Part of JSQLParser#2852

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant