diff --git a/pkg/sql/logictest/testdata/logic_test/select_for_update_read_committed b/pkg/sql/logictest/testdata/logic_test/select_for_update_read_committed index 01eefc71685e..23e2d106605d 100644 --- a/pkg/sql/logictest/testdata/logic_test/select_for_update_read_committed +++ b/pkg/sql/logictest/testdata/logic_test/select_for_update_read_committed @@ -36,7 +36,7 @@ COMMIT statement ok BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED -query error pgcode 0A000 cannot execute SELECT FOR UPDATE statements under ReadCommitted isolation +query error pgcode 0A000 guaranteed-durable locking not yet implemented SELECT aisle FROM supermarket WHERE person = 'matilda' FOR UPDATE statement ok @@ -49,7 +49,7 @@ SET CLUSTER SETTING sql.txn.snapshot_isolation.enabled = true statement ok BEGIN TRANSACTION ISOLATION LEVEL SNAPSHOT -query error pgcode 0A000 cannot execute SELECT FOR UPDATE statements under Snapshot isolation +query error pgcode 0A000 guaranteed-durable locking not yet implemented SELECT aisle FROM supermarket WHERE person = 'matilda' FOR UPDATE statement ok @@ -65,7 +65,7 @@ BEGIN TRANSACTION statement ok SET TRANSACTION ISOLATION LEVEL READ COMMITTED; -query error pgcode 0A000 cannot execute SELECT FOR UPDATE statements under ReadCommitted isolation +query error pgcode 0A000 guaranteed-durable locking not yet implemented UPDATE supermarket SET aisle = (SELECT aisle FROM supermarket WHERE person = 'matilda' FOR UPDATE) WHERE person = 'michael' @@ -80,7 +80,7 @@ BEGIN TRANSACTION statement ok SET TRANSACTION ISOLATION LEVEL READ COMMITTED; -query error pgcode 0A000 cannot execute SELECT FOR UPDATE statements under ReadCommitted isolation +query error pgcode 0A000 guaranteed-durable locking not yet implemented WITH s AS (SELECT aisle FROM supermarket WHERE person = 'matilda' FOR UPDATE) SELECT aisle + 1 FROM s @@ -98,7 +98,7 @@ CREATE FUNCTION wrangle (name STRING) RETURNS INT LANGUAGE SQL AS $$ $$ # But calling that function should fail. -query error pgcode 0A000 cannot execute SELECT FOR UPDATE statements under ReadCommitted isolation +query error pgcode 0A000 guaranteed-durable locking not yet implemented INSERT INTO supermarket (person, aisle) VALUES ('grandma', wrangle('matilda')) statement ok @@ -109,14 +109,14 @@ statement ok PREPARE psa AS SELECT aisle FROM supermarket WHERE person = $1::STRING FOR UPDATE # But execution should fail. -query error pgcode 0A000 cannot execute SELECT FOR UPDATE statements under ReadCommitted isolation +query error pgcode 0A000 guaranteed-durable locking not yet implemented EXECUTE psa('matilda') statement ok DEALLOCATE psa # SELECT FOR UPDATE using a lookup join should also fail. -query error pgcode 0A000 cannot execute SELECT FOR UPDATE statements under ReadCommitted isolation +query error pgcode 0A000 guaranteed-durable locking not yet implemented WITH names AS MATERIALIZED (SELECT 'matilda' AS person) SELECT aisle @@ -125,14 +125,14 @@ SELECT aisle FOR UPDATE # SELECT FOR UPDATE using an index join should also fail. -query error pgcode 0A000 cannot execute SELECT FOR UPDATE statements under ReadCommitted isolation +query error pgcode 0A000 guaranteed-durable locking not yet implemented SELECT aisle FROM supermarket@supermarket_starts_with_idx WHERE starts_with = 'm' FOR UPDATE # SELECT FOR UPDATE using a zigzag join should also fail. -query error pgcode 0A000 cannot execute SELECT FOR UPDATE statements under ReadCommitted isolation +query error pgcode 0A000 guaranteed-durable locking not yet implemented SELECT aisle FROM supermarket@{FORCE_ZIGZAG} WHERE starts_with = 'm' AND ends_with = 'lda' diff --git a/pkg/sql/opt/exec/execbuilder/BUILD.bazel b/pkg/sql/opt/exec/execbuilder/BUILD.bazel index db02fb7c28d3..665f7e242e50 100644 --- a/pkg/sql/opt/exec/execbuilder/BUILD.bazel +++ b/pkg/sql/opt/exec/execbuilder/BUILD.bazel @@ -14,7 +14,6 @@ go_library( importpath = "github.com/cockroachdb/cockroach/pkg/sql/opt/exec/execbuilder", visibility = ["//visibility:public"], deps = [ - "//pkg/kv/kvserver/concurrency/isolation", "//pkg/server/telemetry", "//pkg/sql/catalog/colinfo", "//pkg/sql/catalog/descpb", diff --git a/pkg/sql/opt/exec/execbuilder/relational.go b/pkg/sql/opt/exec/execbuilder/relational.go index 00788aae7fb5..a090360b4a0c 100644 --- a/pkg/sql/opt/exec/execbuilder/relational.go +++ b/pkg/sql/opt/exec/execbuilder/relational.go @@ -17,7 +17,6 @@ import ( "math" "strings" - "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/isolation" "github.com/cockroachdb/cockroach/pkg/server/telemetry" "github.com/cockroachdb/cockroach/pkg/sql/catalog/colinfo" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" @@ -2896,11 +2895,9 @@ func (b *Builder) buildLocking(locking opt.Locking) (opt.Locking, error) { "cannot execute %s in a read-only transaction", locking.Strength.String(), ) } - if locking.Durability == tree.LockDurabilityGuaranteed && - b.evalCtx.TxnIsoLevel != isolation.Serializable { + if locking.Durability == tree.LockDurabilityGuaranteed { return opt.Locking{}, unimplemented.NewWithIssuef( - 100144, "cannot execute SELECT FOR UPDATE statements under %s isolation", - b.evalCtx.TxnIsoLevel, + 100193, "guaranteed-durable locking not yet implemented", ) } b.ContainsNonDefaultKeyLocking = true diff --git a/pkg/sql/opt/exec/execbuilder/testdata/select_for_update b/pkg/sql/opt/exec/execbuilder/testdata/select_for_update index c45ce69a9304..e36bae6c8e19 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/select_for_update +++ b/pkg/sql/opt/exec/execbuilder/testdata/select_for_update @@ -28,7 +28,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR NO KEY UPDATE @@ -42,7 +41,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for no key update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR SHARE @@ -56,7 +54,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for share - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR KEY SHARE @@ -70,7 +67,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for key share - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR KEY SHARE FOR SHARE @@ -84,7 +80,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for share - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR KEY SHARE FOR SHARE FOR NO KEY UPDATE @@ -98,7 +93,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for no key update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR KEY SHARE FOR SHARE FOR NO KEY UPDATE FOR UPDATE @@ -112,7 +106,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR UPDATE OF t @@ -126,7 +119,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query error pgcode 42P01 relation "t2" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM t FOR UPDATE OF t2 @@ -147,7 +139,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR UPDATE @@ -161,7 +152,6 @@ vectorized: true table: t@t_pkey spans: /1/0 locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR NO KEY UPDATE @@ -175,7 +165,6 @@ vectorized: true table: t@t_pkey spans: /1/0 locking strength: for no key update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR SHARE @@ -189,7 +178,6 @@ vectorized: true table: t@t_pkey spans: /1/0 locking strength: for share - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR KEY SHARE @@ -203,7 +191,6 @@ vectorized: true table: t@t_pkey spans: /1/0 locking strength: for key share - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR KEY SHARE FOR SHARE @@ -217,7 +204,6 @@ vectorized: true table: t@t_pkey spans: /1/0 locking strength: for share - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR KEY SHARE FOR SHARE FOR NO KEY UPDATE @@ -231,7 +217,6 @@ vectorized: true table: t@t_pkey spans: /1/0 locking strength: for no key update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR KEY SHARE FOR SHARE FOR NO KEY UPDATE FOR UPDATE @@ -245,7 +230,6 @@ vectorized: true table: t@t_pkey spans: /1/0 locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR UPDATE OF t @@ -259,7 +243,6 @@ vectorized: true table: t@t_pkey spans: /1/0 locking strength: for update - locking durability: guaranteed query error pgcode 42P01 relation "t2" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR UPDATE OF t2 @@ -280,7 +263,6 @@ vectorized: true table: t@t_pkey spans: /1/0 locking strength: for update - locking durability: guaranteed # ------------------------------------------------------------------------------ # Tests with table aliases. @@ -298,7 +280,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query error pgcode 42P01 relation "t" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM t AS t2 FOR UPDATE OF t @@ -315,7 +296,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM [$t_id AS t] FOR UPDATE @@ -329,7 +309,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM [$t_id AS t] FOR UPDATE OF t @@ -343,7 +322,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query error pgcode 42P01 relation "t2" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM [$t_id AS t] FOR UPDATE OF t2 @@ -364,7 +342,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM v FOR UPDATE OF v @@ -378,7 +355,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query error pgcode 42P01 relation "v2" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM v FOR UPDATE OF v2 @@ -405,7 +381,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query error pgcode 42P01 relation "v" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM v AS v2 FOR UPDATE OF v @@ -422,7 +397,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed # ------------------------------------------------------------------------------ # Tests with subqueries. @@ -444,7 +418,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM (SELECT a FROM t FOR UPDATE) @@ -458,7 +431,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM (SELECT a FROM t FOR NO KEY UPDATE) FOR KEY SHARE @@ -472,7 +444,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for no key update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM (SELECT a FROM t FOR KEY SHARE) FOR NO KEY UPDATE @@ -486,7 +457,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for no key update - locking durability: guaranteed query error pgcode 42P01 relation "t" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM (SELECT a FROM t) FOR UPDATE OF t @@ -503,7 +473,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM (SELECT a FROM t) AS r FOR UPDATE @@ -517,7 +486,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM (SELECT a FROM t FOR UPDATE) AS r @@ -531,7 +499,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query error pgcode 42P01 relation "t" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM (SELECT a FROM t) AS r FOR UPDATE OF t @@ -548,7 +515,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT (SELECT a FROM t) FOR UPDATE @@ -608,7 +574,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query error pgcode 42P01 relation "t" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT (SELECT a FROM t) FOR UPDATE OF t @@ -642,7 +607,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT (SELECT a FROM t) AS r FOR UPDATE @@ -702,7 +666,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query error pgcode 42P01 relation "t" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT (SELECT a FROM t) AS r FOR UPDATE OF t @@ -736,7 +699,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a IN (SELECT a FROM t) FOR UPDATE @@ -750,7 +712,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a IN (SELECT a FROM t FOR UPDATE) @@ -776,7 +737,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a IN (SELECT a FROM t FOR UPDATE OF t) @@ -806,7 +766,6 @@ vectorized: true │ equality: (b) = (a) │ equality cols are key │ locking strength: for update - │ locking durability: guaranteed │ └── • distinct │ columns: (b) @@ -846,7 +805,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a IN (SELECT b FROM t) FOR UPDATE OF t @@ -864,7 +822,6 @@ vectorized: true │ equality: (b) = (a) │ equality cols are key │ locking strength: for update - │ locking durability: guaranteed │ └── • distinct │ columns: (b) @@ -904,7 +861,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed # ------------------------------------------------------------------------------ # Tests with common-table expressions. @@ -978,7 +934,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) WITH cte AS (SELECT a FROM t FOR UPDATE) SELECT * FROM cte @@ -1009,7 +964,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed # Verify that the unused CTE doesn't get eliminated. # TODO(radu): we should at least not buffer the rows in this case. @@ -1044,7 +998,6 @@ vectorized: true table: t@t_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed # ------------------------------------------------------------------------------ # Tests with joins. @@ -1074,7 +1027,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1083,7 +1035,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t JOIN u USING (a) FOR UPDATE OF t @@ -1109,7 +1060,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1149,7 +1099,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t JOIN u USING (a) FOR UPDATE OF t, u @@ -1175,7 +1124,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1184,7 +1132,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t JOIN u USING (a) FOR UPDATE OF t FOR SHARE OF u @@ -1210,7 +1157,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1219,7 +1165,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for share - locking durability: guaranteed query error pgcode 42P01 relation "t2" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM t JOIN u USING (a) FOR UPDATE OF t2 FOR SHARE OF u2 @@ -1248,7 +1193,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1257,7 +1201,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for share - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t JOIN u USING (a) FOR KEY SHARE FOR UPDATE @@ -1283,7 +1226,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1292,7 +1234,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t JOIN u USING (a) FOR KEY SHARE FOR NO KEY UPDATE OF t @@ -1318,7 +1259,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for no key update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1327,7 +1267,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for key share - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t JOIN u USING (a) FOR SHARE FOR NO KEY UPDATE OF t FOR UPDATE OF u @@ -1353,7 +1292,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for no key update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1362,7 +1300,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed # ------------------------------------------------------------------------------ # Tests with joins of aliased tables and aliased joins. @@ -1392,7 +1329,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1401,7 +1337,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query error pgcode 42P01 relation "t" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM t AS t2 JOIN u AS u2 USING (a) FOR UPDATE OF t @@ -1436,7 +1371,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1476,7 +1410,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t AS t2 JOIN u AS u2 USING (a) FOR UPDATE OF t2, u2 @@ -1502,7 +1435,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1511,7 +1443,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed # Postgres doesn't support applying locking clauses to joins. The following # queries all return the error: "FOR UPDATE cannot be applied to a join". @@ -1541,7 +1472,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1550,7 +1480,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query error pgcode 42P01 relation "t" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM (t JOIN u AS u2 USING (a)) j FOR UPDATE OF t @@ -1585,7 +1514,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1594,7 +1522,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed # ------------------------------------------------------------------------------ # Tests with lateral joins. @@ -1616,7 +1543,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update -│ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1624,7 +1550,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t, u FOR UPDATE OF t @@ -1642,7 +1567,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update -│ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1666,7 +1590,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for share -│ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1674,7 +1597,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t, LATERAL (SELECT * FROM u) sub FOR UPDATE @@ -1692,7 +1614,6 @@ vectorized: true │ table: t@t_pkey │ spans: FULL SCAN │ locking strength: for update -│ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1700,7 +1621,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed query error pgcode 42P01 relation "u" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM t, LATERAL (SELECT * FROM u) sub FOR UPDATE OF u @@ -1727,7 +1647,6 @@ vectorized: true table: u@u_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed # ------------------------------------------------------------------------------ # Tests with index joins. @@ -1753,7 +1672,6 @@ vectorized: true │ table: indexed@indexed_pkey │ key columns: a │ locking strength: for update -│ locking durability: guaranteed │ └── • scan columns: (a, b) @@ -1761,7 +1679,6 @@ vectorized: true table: indexed@b_idx spans: /2-/3 locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM indexed WHERE b BETWEEN 2 AND 10 FOR UPDATE @@ -1775,7 +1692,6 @@ vectorized: true │ table: indexed@indexed_pkey │ key columns: a │ locking strength: for update -│ locking durability: guaranteed │ └── • scan columns: (a, b) @@ -1783,7 +1699,6 @@ vectorized: true table: indexed@b_idx spans: /2-/11 locking strength: for update - locking durability: guaranteed # ------------------------------------------------------------------------------ # Tests with lookup joins. @@ -1805,7 +1720,6 @@ vectorized: true │ equality: (b) = (a) │ equality cols are key │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b) @@ -1813,7 +1727,6 @@ vectorized: true table: t@t_pkey spans: /2/0 locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT c FROM t JOIN u ON t.b = u.a WHERE t.a BETWEEN 2 AND 10 FOR UPDATE @@ -1831,7 +1744,6 @@ vectorized: true │ equality: (b) = (a) │ equality cols are key │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b) @@ -1840,7 +1752,6 @@ vectorized: true spans: /2-/11 parallel locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t JOIN indexed ON t.b = indexed.b WHERE t.a = 2 FOR UPDATE @@ -1855,7 +1766,6 @@ vectorized: true │ equality: (a) = (a) │ equality cols are key │ locking strength: for update -│ locking durability: guaranteed │ └── • lookup join (inner) │ columns: (a, b, a, b) @@ -1863,7 +1773,6 @@ vectorized: true │ table: indexed@b_idx │ equality: (b) = (b) │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b) @@ -1871,7 +1780,6 @@ vectorized: true table: t@t_pkey spans: /2/0 locking strength: for update - locking durability: guaranteed # ------------------------------------------------------------------------------ # Tests with inverted filters and joins. @@ -1898,7 +1806,6 @@ vectorized: true │ equality: (a) = (a) │ equality cols are key │ locking strength: for update -│ locking durability: guaranteed │ └── • project │ columns: (a) @@ -1910,12 +1817,10 @@ vectorized: true left columns: (a, b_inverted_key) left fixed values: 1 column left locking strength: for update - left locking durability: guaranteed right table: inverted@b_inv right columns: (a, b_inverted_key) right fixed values: 1 column right locking strength: for update - right locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM inverted WHERE b <@ '{1, 2}' FOR UPDATE @@ -1934,7 +1839,6 @@ vectorized: true │ table: inverted@inverted_pkey │ key columns: a │ locking strength: for update - │ locking durability: guaranteed │ └── • project │ columns: (a) @@ -1951,7 +1855,6 @@ vectorized: true table: inverted@b_inv spans: /[]-/"D" /1-/3 locking strength: for update - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM inverted@b_inv AS i1, inverted AS i2 WHERE i1.b @> i2.b FOR UPDATE @@ -1970,7 +1873,6 @@ vectorized: true │ equality cols are key │ pred: b @> b │ locking strength: for update - │ locking durability: guaranteed │ └── • project │ columns: (a, b, c, a) @@ -1981,7 +1883,6 @@ vectorized: true │ table: inverted@b_inv │ inverted expr: b_inverted_key @> b │ locking strength: for update - │ locking durability: guaranteed │ └── • scan columns: (a, b, c) @@ -1989,7 +1890,6 @@ vectorized: true table: inverted@inverted_pkey spans: FULL SCAN locking strength: for update - locking durability: guaranteed # ------------------------------------------------------------------------------ # Tests with zigzag joins. @@ -2023,12 +1923,10 @@ vectorized: true left columns: (a, b) left fixed values: 1 column left locking strength: for update - left locking durability: guaranteed right table: zigzag@c_idx right columns: (a, c) right fixed values: 1 column right locking strength: for update - right locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * from zigzag where d @> '{"a": {"b": "c"}, "f": "g"}' FOR UPDATE @@ -2043,7 +1941,6 @@ vectorized: true │ equality: (a) = (a) │ equality cols are key │ locking strength: for update -│ locking durability: guaranteed │ └── • project │ columns: (a) @@ -2055,12 +1952,10 @@ vectorized: true left columns: (a, d_inverted_key) left fixed values: 1 column left locking strength: for update - left locking durability: guaranteed right table: zigzag@d_idx right columns: (a, d_inverted_key) right fixed values: 1 column right locking strength: for update - right locking durability: guaranteed # ------------------------------------------------------------------------------ # Tests with the NOWAIT lock wait policy. @@ -2079,7 +1974,6 @@ vectorized: true spans: FULL SCAN locking strength: for update locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR NO KEY UPDATE NOWAIT @@ -2094,7 +1988,6 @@ vectorized: true spans: FULL SCAN locking strength: for no key update locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR SHARE NOWAIT @@ -2109,7 +2002,6 @@ vectorized: true spans: FULL SCAN locking strength: for share locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR KEY SHARE NOWAIT @@ -2124,7 +2016,6 @@ vectorized: true spans: FULL SCAN locking strength: for key share locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR KEY SHARE FOR SHARE NOWAIT @@ -2139,7 +2030,6 @@ vectorized: true spans: FULL SCAN locking strength: for share locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR KEY SHARE FOR SHARE NOWAIT FOR NO KEY UPDATE @@ -2154,7 +2044,6 @@ vectorized: true spans: FULL SCAN locking strength: for no key update locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR KEY SHARE FOR SHARE NOWAIT FOR NO KEY UPDATE FOR UPDATE NOWAIT @@ -2169,7 +2058,6 @@ vectorized: true spans: FULL SCAN locking strength: for update locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR UPDATE OF t NOWAIT @@ -2184,7 +2072,6 @@ vectorized: true spans: FULL SCAN locking strength: for update locking wait policy: nowait - locking durability: guaranteed query error pgcode 42P01 relation "t2" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM t FOR UPDATE OF t2 NOWAIT @@ -2206,7 +2093,6 @@ vectorized: true spans: FULL SCAN locking strength: for update locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR UPDATE NOWAIT @@ -2221,7 +2107,6 @@ vectorized: true spans: /1/0 locking strength: for update locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR NO KEY UPDATE NOWAIT @@ -2236,7 +2121,6 @@ vectorized: true spans: /1/0 locking strength: for no key update locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR SHARE NOWAIT @@ -2251,7 +2135,6 @@ vectorized: true spans: /1/0 locking strength: for share locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR KEY SHARE NOWAIT @@ -2266,7 +2149,6 @@ vectorized: true spans: /1/0 locking strength: for key share locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR KEY SHARE FOR SHARE NOWAIT @@ -2281,7 +2163,6 @@ vectorized: true spans: /1/0 locking strength: for share locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR KEY SHARE FOR SHARE FOR NO KEY UPDATE NOWAIT @@ -2296,7 +2177,6 @@ vectorized: true spans: /1/0 locking strength: for no key update locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR KEY SHARE FOR SHARE FOR NO KEY UPDATE FOR UPDATE NOWAIT @@ -2311,7 +2191,6 @@ vectorized: true spans: /1/0 locking strength: for update locking wait policy: nowait - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR UPDATE OF t NOWAIT @@ -2326,7 +2205,6 @@ vectorized: true spans: /1/0 locking strength: for update locking wait policy: nowait - locking durability: guaranteed query error pgcode 42P01 relation "t2" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR UPDATE OF t2 NOWAIT @@ -2348,7 +2226,6 @@ vectorized: true spans: /1/0 locking strength: for update locking wait policy: nowait - locking durability: guaranteed # ------------------------------------------------------------------------------ # Tests with the SKIP LOCKED lock wait policy. @@ -2367,7 +2244,6 @@ vectorized: true spans: FULL SCAN locking strength: for update locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR NO KEY UPDATE SKIP LOCKED @@ -2382,7 +2258,6 @@ vectorized: true spans: FULL SCAN locking strength: for no key update locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR SHARE SKIP LOCKED @@ -2397,7 +2272,6 @@ vectorized: true spans: FULL SCAN locking strength: for share locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR KEY SHARE SKIP LOCKED @@ -2412,7 +2286,6 @@ vectorized: true spans: FULL SCAN locking strength: for key share locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR KEY SHARE FOR SHARE SKIP LOCKED @@ -2427,7 +2300,6 @@ vectorized: true spans: FULL SCAN locking strength: for share locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR KEY SHARE FOR SHARE SKIP LOCKED FOR NO KEY UPDATE @@ -2442,7 +2314,6 @@ vectorized: true spans: FULL SCAN locking strength: for no key update locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR KEY SHARE FOR SHARE SKIP LOCKED FOR NO KEY UPDATE FOR UPDATE SKIP LOCKED @@ -2457,7 +2328,6 @@ vectorized: true spans: FULL SCAN locking strength: for update locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t FOR UPDATE OF t SKIP LOCKED @@ -2472,7 +2342,6 @@ vectorized: true spans: FULL SCAN locking strength: for update locking wait policy: skip locked - locking durability: guaranteed query error pgcode 42P01 relation "t2" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM t FOR UPDATE OF t2 SKIP LOCKED @@ -2494,7 +2363,6 @@ vectorized: true spans: FULL SCAN locking strength: for update locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR UPDATE SKIP LOCKED @@ -2509,7 +2377,6 @@ vectorized: true spans: /1/0 locking strength: for update locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR NO KEY UPDATE SKIP LOCKED @@ -2524,7 +2391,6 @@ vectorized: true spans: /1/0 locking strength: for no key update locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR SHARE SKIP LOCKED @@ -2539,7 +2405,6 @@ vectorized: true spans: /1/0 locking strength: for share locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR KEY SHARE SKIP LOCKED @@ -2554,7 +2419,6 @@ vectorized: true spans: /1/0 locking strength: for key share locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR KEY SHARE FOR SHARE SKIP LOCKED @@ -2569,7 +2433,6 @@ vectorized: true spans: /1/0 locking strength: for share locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR KEY SHARE FOR SHARE FOR NO KEY UPDATE SKIP LOCKED @@ -2584,7 +2447,6 @@ vectorized: true spans: /1/0 locking strength: for no key update locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR KEY SHARE FOR SHARE FOR NO KEY UPDATE FOR UPDATE SKIP LOCKED @@ -2599,7 +2461,6 @@ vectorized: true spans: /1/0 locking strength: for update locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR UPDATE OF t SKIP LOCKED @@ -2614,7 +2475,6 @@ vectorized: true spans: /1/0 locking strength: for update locking wait policy: skip locked - locking durability: guaranteed query error pgcode 42P01 relation "t2" in FOR UPDATE clause not found in FROM clause EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 1 FOR UPDATE OF t2 SKIP LOCKED @@ -2636,7 +2496,6 @@ vectorized: true spans: /1/0 locking strength: for update locking wait policy: skip locked - locking durability: guaranteed # Tests with a secondary index. @@ -2653,7 +2512,6 @@ vectorized: true spans: /2-/3 locking strength: for update locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM u WHERE b = 2 FOR UPDATE SKIP LOCKED @@ -2668,7 +2526,6 @@ vectorized: true │ key columns: a │ locking strength: for update │ locking wait policy: skip locked -│ locking durability: guaranteed │ └── • scan columns: (a, b) @@ -2677,7 +2534,6 @@ vectorized: true spans: /2-/3 locking strength: for update locking wait policy: skip locked - locking durability: guaranteed query T EXPLAIN (VERBOSE) SELECT * FROM u WHERE b = 2 LIMIT 1 FOR UPDATE SKIP LOCKED @@ -2696,7 +2552,6 @@ vectorized: true │ key columns: a │ locking strength: for update │ locking wait policy: skip locked - │ locking durability: guaranteed │ └── • scan columns: (a, b) @@ -2705,4 +2560,3 @@ vectorized: true spans: /2-/3 locking strength: for update locking wait policy: skip locked - locking durability: guaranteed diff --git a/pkg/sql/opt/exec/explain/testdata/gists b/pkg/sql/opt/exec/explain/testdata/gists index ba1623aff862..441bda114816 100644 --- a/pkg/sql/opt/exec/explain/testdata/gists +++ b/pkg/sql/opt/exec/explain/testdata/gists @@ -524,7 +524,6 @@ explain(shape): table: abc@abc_b_idx spans: FULL SCAN locking strength: for update - locking durability: guaranteed explain(gist): • root │ diff --git a/pkg/sql/opt/memo/BUILD.bazel b/pkg/sql/opt/memo/BUILD.bazel index ccfbde53a019..cf8bba5bc476 100644 --- a/pkg/sql/opt/memo/BUILD.bazel +++ b/pkg/sql/opt/memo/BUILD.bazel @@ -25,6 +25,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/geo/geoindex", + "//pkg/kv/kvserver/concurrency/isolation", "//pkg/sql/catalog/colinfo", "//pkg/sql/catalog/tabledesc", "//pkg/sql/inverted", @@ -78,6 +79,7 @@ go_test( ], embed = [":memo"], deps = [ + "//pkg/kv/kvserver/concurrency/isolation", "//pkg/settings/cluster", "//pkg/sql/inverted", "//pkg/sql/opt", diff --git a/pkg/sql/opt/memo/memo.go b/pkg/sql/opt/memo/memo.go index 9cd060dae529..ec55b6bed9c5 100644 --- a/pkg/sql/opt/memo/memo.go +++ b/pkg/sql/opt/memo/memo.go @@ -14,6 +14,7 @@ package memo import ( "context" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/isolation" "github.com/cockroachdb/cockroach/pkg/sql/opt" "github.com/cockroachdb/cockroach/pkg/sql/opt/cat" "github.com/cockroachdb/cockroach/pkg/sql/opt/props" @@ -168,6 +169,11 @@ type Memo struct { hoistUncorrelatedEqualitySubqueries bool useImprovedComputedColumnFiltersDerivation bool + // txnIsoLevel is the isolation level under which the plan was created. This + // affects the planning of some locking operations, so it must be included in + // memo staleness calculation. + txnIsoLevel isolation.Level + // curRank is the highest currently in-use scalar expression rank. curRank opt.ScalarRank @@ -228,6 +234,7 @@ func (m *Memo) Init(ctx context.Context, evalCtx *eval.Context) { alwaysUseHistograms: evalCtx.SessionData().OptimizerAlwaysUseHistograms, hoistUncorrelatedEqualitySubqueries: evalCtx.SessionData().OptimizerHoistUncorrelatedEqualitySubqueries, useImprovedComputedColumnFiltersDerivation: evalCtx.SessionData().OptimizerUseImprovedComputedColumnFiltersDerivation, + txnIsoLevel: evalCtx.TxnIsoLevel, } m.metadata.Init() m.logPropsBuilder.init(ctx, evalCtx, m) @@ -372,7 +379,8 @@ func (m *Memo) IsStale( m.useImprovedSplitDisjunctionForJoins != evalCtx.SessionData().OptimizerUseImprovedSplitDisjunctionForJoins || m.alwaysUseHistograms != evalCtx.SessionData().OptimizerAlwaysUseHistograms || m.hoistUncorrelatedEqualitySubqueries != evalCtx.SessionData().OptimizerHoistUncorrelatedEqualitySubqueries || - m.useImprovedComputedColumnFiltersDerivation != evalCtx.SessionData().OptimizerUseImprovedComputedColumnFiltersDerivation { + m.useImprovedComputedColumnFiltersDerivation != evalCtx.SessionData().OptimizerUseImprovedComputedColumnFiltersDerivation || + m.txnIsoLevel != evalCtx.TxnIsoLevel { return true, nil } diff --git a/pkg/sql/opt/memo/memo_test.go b/pkg/sql/opt/memo/memo_test.go index 61ea58ca5b41..cc33780a2b36 100644 --- a/pkg/sql/opt/memo/memo_test.go +++ b/pkg/sql/opt/memo/memo_test.go @@ -15,6 +15,7 @@ import ( "fmt" "testing" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/isolation" "github.com/cockroachdb/cockroach/pkg/settings/cluster" "github.com/cockroachdb/cockroach/pkg/sql/opt/memo" "github.com/cockroachdb/cockroach/pkg/sql/opt/norm" @@ -373,6 +374,12 @@ func TestMemoIsStale(t *testing.T) { evalCtx.SessionData().OptimizerUseImprovedComputedColumnFiltersDerivation = false notStale() + // Stale txn isolation level. + evalCtx.TxnIsoLevel = isolation.ReadCommitted + stale() + evalCtx.TxnIsoLevel = isolation.Serializable + notStale() + // User no longer has access to view. catalog.View(tree.NewTableNameWithSchema("t", catconstants.PublicSchemaName, "abcview")).Revoked = true _, err = o.Memo().IsStale(ctx, &evalCtx, catalog) diff --git a/pkg/sql/opt/optbuilder/BUILD.bazel b/pkg/sql/opt/optbuilder/BUILD.bazel index 91c7fb303964..1db73e94064f 100644 --- a/pkg/sql/opt/optbuilder/BUILD.bazel +++ b/pkg/sql/opt/optbuilder/BUILD.bazel @@ -49,6 +49,7 @@ go_library( importpath = "github.com/cockroachdb/cockroach/pkg/sql/opt/optbuilder", visibility = ["//visibility:public"], deps = [ + "//pkg/kv/kvserver/concurrency/isolation", "//pkg/server/telemetry", "//pkg/settings", "//pkg/sql/catalog/catpb", diff --git a/pkg/sql/opt/optbuilder/locking.go b/pkg/sql/opt/optbuilder/locking.go index bc3eacb20fd1..8c56336a03b7 100644 --- a/pkg/sql/opt/optbuilder/locking.go +++ b/pkg/sql/opt/optbuilder/locking.go @@ -78,12 +78,6 @@ func (lm lockingSpec) get() opt.Locking { return opt.Locking{ Strength: spec.Strength, WaitPolicy: spec.WaitPolicy, - // We use fully-durable locks for all SELECT FOR UPDATE statements, - // regardless of locking strength and wait policy. Unlike mutation - // statements, SELECT FOR UPDATE statements do not lay down intents, so we - // cannot rely on the durability of intents to guarantee exclusion until - // commit as we do for mutation statements. - Durability: tree.LockDurabilityGuaranteed, } } return opt.Locking{} diff --git a/pkg/sql/opt/optbuilder/select.go b/pkg/sql/opt/optbuilder/select.go index 48249eb4940a..9ad853c3269a 100644 --- a/pkg/sql/opt/optbuilder/select.go +++ b/pkg/sql/opt/optbuilder/select.go @@ -14,6 +14,7 @@ import ( "context" "fmt" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/isolation" "github.com/cockroachdb/cockroach/pkg/server/telemetry" "github.com/cockroachdb/cockroach/pkg/sql/catalog/catpb" "github.com/cockroachdb/cockroach/pkg/sql/catalog/colinfo" @@ -690,6 +691,18 @@ func (b *Builder) buildScan( } if locking.isSet() { private.Locking = locking.get() + if b.evalCtx.TxnIsoLevel != isolation.Serializable { + // Under weaker isolation levels we use fully-durable locks for SELECT FOR + // UPDATE statements, SELECT FOR SHARE statements, and all other locked + // scans (e.g. FK checks), regardless of locking strength and wait + // policy. Unlike mutation statements, SELECT FOR UPDATE statements do not + // lay down intents, so we cannot rely on the durability of intents to + // guarantee exclusion until commit as we do for mutation statements. And + // unlike serializable isolation, weaker isolation levels do not perform + // read refreshing, so we cannot rely on read refreshing to guarantee + // exclusion. + private.Locking.Durability = tree.LockDurabilityGuaranteed + } if private.Locking.WaitPolicy == tree.LockWaitSkipLocked && tab.FamilyCount() > 1 { // TODO(rytaft): We may be able to support this if enough columns are // pruned that only a single family is scanned. diff --git a/pkg/sql/sem/tree/select.go b/pkg/sql/sem/tree/select.go index afc03320be2a..2ea127bcc232 100644 --- a/pkg/sql/sem/tree/select.go +++ b/pkg/sql/sem/tree/select.go @@ -1210,14 +1210,14 @@ const ( // on the leaseholder of the locked row. Best-effort locks do not propagate // via Raft to other nodes, and are therefore much faster to acquire than // guaranteed-durable locks. For this reason we prefer to use best-effort - // locks when possible (i.e. when locking is used as an optimization rather - // than as a guarantor of exclusion). + // locks when possible (i.e. whenever locking is used as an optimization + // rather than as a guarantor of exclusion). LockDurabilityBestEffort LockingDurability = iota // LockDurabilityGuaranteed guarantees that if the transaction commits, the // lock was held until commit, even in the face of lease transfers, range // splits, range merges, node failures, memory limits, etc. Guaranteed-durable - // locks *must* be used when correctness depends on locking. + // locks *must* be used whenever correctness depends on locking. LockDurabilityGuaranteed )