Skip to content

Commit 03a8d4a

Browse files
committed
opt: show locking durability in EXPLAIN (OPT) output
Because the "guaranteed-durable locking not yet implemented" error condition is checked in execbuilder, it prevents not only execution but also `EXPLAIN` of queries using guaranteed-durable locking. Thankfully `EXPLAIN (OPT)` bypasses execbuilder, and hence still works, so use this for now to verify that we are enabling durable locking for `SELECT FOR UPDATE` under read committed isolation. (Note that we have not yet fixed the `SELECT FOR UPDATE` plans to use more precise locking, that will come in a later PR.) Informs: cockroachdb#100194 Release note: None
1 parent 6a3e43d commit 03a8d4a

File tree

3 files changed

+133
-1
lines changed

3 files changed

+133
-1
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# LogicTest: local
2+
3+
statement ok
4+
CREATE TABLE supermarket (
5+
person STRING PRIMARY KEY,
6+
aisle INT NOT NULL,
7+
starts_with STRING GENERATED ALWAYS AS (left(person, 1)) STORED,
8+
ends_with STRING GENERATED ALWAYS AS (right(person, 3)) STORED,
9+
INDEX (starts_with),
10+
INDEX (ends_with)
11+
)
12+
13+
statement ok
14+
INSERT INTO supermarket (person, aisle)
15+
VALUES ('abbie', 1), ('gideon', 2), ('matilda', 3), ('michael', 4)
16+
17+
statement ok
18+
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED
19+
20+
query T
21+
EXPLAIN (OPT) SELECT aisle FROM supermarket WHERE person = 'matilda' FOR UPDATE
22+
----
23+
project
24+
└── scan supermarket
25+
├── constraint: /1: [/'matilda' - /'matilda']
26+
└── locking: for-update,durability-guaranteed
27+
28+
query T
29+
EXPLAIN (OPT)
30+
UPDATE supermarket
31+
SET aisle = (SELECT aisle FROM supermarket WHERE person = 'matilda' FOR UPDATE)
32+
WHERE person = 'michael'
33+
----
34+
update supermarket
35+
└── project
36+
├── scan supermarket
37+
│ └── constraint: /7: [/'michael' - /'michael']
38+
└── projections
39+
└── subquery
40+
└── project
41+
└── scan supermarket
42+
├── constraint: /13: [/'matilda' - /'matilda']
43+
└── locking: for-update,durability-guaranteed
44+
45+
query T
46+
EXPLAIN (OPT)
47+
WITH s AS
48+
(SELECT aisle FROM supermarket WHERE person = 'matilda' FOR UPDATE)
49+
SELECT aisle + 1 FROM s
50+
----
51+
with &1 (s)
52+
├── project
53+
│ └── scan supermarket
54+
│ ├── constraint: /1: [/'matilda' - /'matilda']
55+
│ └── locking: for-update,durability-guaranteed
56+
└── project
57+
├── with-scan &1 (s)
58+
└── projections
59+
└── aisle + 1
60+
61+
query T
62+
EXPLAIN (OPT)
63+
WITH names AS MATERIALIZED
64+
(SELECT 'matilda' AS person)
65+
SELECT aisle
66+
FROM names
67+
NATURAL INNER LOOKUP JOIN supermarket
68+
FOR UPDATE
69+
----
70+
with &1 (names)
71+
├── materialized
72+
├── values
73+
│ └── ('matilda',)
74+
└── project
75+
└── inner-join (lookup supermarket)
76+
├── flags: force lookup join (into right side)
77+
├── lookup columns are key
78+
├── locking: for-update,durability-guaranteed
79+
├── with-scan &1 (names)
80+
└── filters (true)
81+
82+
query T
83+
EXPLAIN (OPT)
84+
SELECT aisle
85+
FROM supermarket@supermarket_starts_with_idx
86+
WHERE starts_with = 'm'
87+
FOR UPDATE
88+
----
89+
project
90+
└── index-join supermarket
91+
├── locking: for-update,durability-guaranteed
92+
└── scan supermarket@supermarket_starts_with_idx
93+
├── constraint: /3/1: [/'m' - /'m']
94+
├── flags: force-index=supermarket_starts_with_idx
95+
└── locking: for-update,durability-guaranteed
96+
97+
query T
98+
EXPLAIN (OPT)
99+
SELECT aisle
100+
FROM supermarket@{FORCE_ZIGZAG}
101+
WHERE starts_with = 'm' AND ends_with = 'lda'
102+
FOR UPDATE
103+
----
104+
project
105+
└── inner-join (lookup supermarket)
106+
├── lookup columns are key
107+
├── locking: for-update,durability-guaranteed
108+
├── inner-join (zigzag supermarket@supermarket_starts_with_idx supermarket@supermarket_ends_with_idx)
109+
│ ├── left locking: for-update,durability-guaranteed
110+
│ ├── right locking: for-update,durability-guaranteed
111+
│ └── filters
112+
│ ├── starts_with = 'm'
113+
│ └── ends_with = 'lda'
114+
└── filters (true)
115+
116+
statement ok
117+
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE

pkg/sql/opt/exec/execbuilder/tests/local/generated_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/opt/memo/expr_format.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,15 @@ func (f *ExprFmtCtx) formatLockingWithPrefix(
15561556
default:
15571557
panic(errors.AssertionFailedf("unexpected wait policy"))
15581558
}
1559-
tp.Childf("%slocking: %s%s", labelPrefix, strength, wait)
1559+
durability := ""
1560+
switch locking.Durability {
1561+
case tree.LockDurabilityBestEffort:
1562+
case tree.LockDurabilityGuaranteed:
1563+
durability = ",durability-guaranteed"
1564+
default:
1565+
panic(errors.AssertionFailedf("unexpected durability"))
1566+
}
1567+
tp.Childf("%slocking: %s%s%s", labelPrefix, strength, wait, durability)
15601568
}
15611569

15621570
// formatDependencies adds a new treeprinter child for schema dependencies.

0 commit comments

Comments
 (0)