Skip to content
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

sql: disallow multiple modification subqueries of same table #12456

Open
cockroach-teamcity opened this issue Nov 23, 2021 · 0 comments
Open

Comments

@cockroach-teamcity
Copy link
Member

cockroach-teamcity commented Nov 23, 2021

Exalate commented:

cockroachdb/cockroach#71595 --- Release note (sql change): Statements containing multiple INSERT ON CONFLICT, UPSERT, UPDATE, or DELETE subqueries can cause data corruption if they modify the same row multiple times. For example, the following SELECT 1 statement will cause corruption of table t: sql CREATE TABLE t (i INT, j INT, PRIMARY KEY (i), INDEX (j)); INSERT INTO t VALUES (0, 0); WITH cte1 AS (UPDATE t SET j = 1 WHERE i = 0 RETURNING *), cte2 AS (UPDATE t SET j = 2 WHERE i = 0 RETURNING *) SELECT 1; Until this is fixed, this change disallows statements with multiple subqueries which modify the same table. Applications can work around this by rewriting problematic statements. For example, the query above can be rewritten as an explicit multi-statement transaction: sql BEGIN; UPDATE t SET j = 1 WHERE i = 0; UPDATE t SET j = 2 WHERE i = 0; SELECT 1; COMMIT; or, if it doesn't matter which update "wins", as multiple non-mutating CTEs on an UPDATE statement: sql WITH cte1 AS (SELECT 1), cte2 AS (SELECT 2) UPDATE t SET j = x.j FROM (SELECT * FROM cte1 UNION ALL SELECT * FROM cte2) AS x (j) WHERE i = 0 RETURNING 1; which in this case could be written more simply as: sql UPDATE t SET j = x.j FROM (VALUES (1), (2)) AS x (j) WHERE i = 0 RETURNING 1; (Note that in these last two rewrites the first update will win, rather than the last.) None of these rewrites suffer from the corruption problem. To override this change and allow these statements in spite of the risk of corruption, applications can: sql SET CLUSTER SETTING sql.multiple_modifications_of_table.enabled = true But be warned that with this enabled there is nothing to prevent this type of corruption from occuring if the same row is modified multiple times by a single statment. To check for corruption, use the EXPERIMENTAL SCRUB command: sql EXPERIMENTAL SCRUB TABLE t WITH OPTIONS INDEX ALL;

Jira Issue: DOC-1871

@exalate-issue-sync exalate-issue-sync bot assigned ghost Dec 2, 2021
@exalate-issue-sync exalate-issue-sync bot changed the title release-21.2: sql: disallow multiple modification subqueries of same table sql: disallow multiple modification subqueries of same table Apr 1, 2022
@exalate-issue-sync exalate-issue-sync bot unassigned ghost Jul 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants