Skip to content

Commit

Permalink
sql/opt/exec: perform implicit SELECT FOR UPDATE on UPDATE with index…
Browse files Browse the repository at this point in the history
… join

Fixes cockroachdb#45511.

This commit enables implicit row-level locking on UPDATEs with an index-join
in its initial row scan. To support this, two new patterns were needed in
`Builder.shouldApplyImplicitLockingToUpdateInput`:

```
(Update
    $input:(IndexJoin
        $input:(Scan $scanPrivate:*)
        $indexJoinPrivate:*
    )
    $checks:*
    $mutationPrivate:*
)

AND

(Update
    $input:(Project
        $input:(IndexJoin
            $input:(Scan $scanPrivate:*)
            $indexJoinPrivate:*
        )
        $projections:*
        $passthrough:*
    )
    $checks:*
    $mutationPrivate:*
)
```

These extra patterns are pushing the limits of this form of pattern matching,
but this is ok for the next release. If/when we want to make any more general,
we should strongly consider Andy's proposal to fold the patten matching and
analysis into the explorer rather than execbuilder.
  • Loading branch information
nvanbenschoten committed Mar 6, 2020
1 parent cdc5681 commit 8c000de
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 33 deletions.
39 changes: 10 additions & 29 deletions pkg/sql/opt/exec/execbuilder/mutation.go
Original file line number Diff line number Diff line change
Expand Up @@ -802,38 +802,19 @@ func (b *Builder) shouldApplyImplicitLockingToUpdateInput(upd *memo.UpdateExpr)
return false
}

// Try to match the pattern:
// Try to match the Update's input expression against the pattern:
//
// (Update
// $input:(Scan $scanPrivate:*)
// $checks:*
// $mutationPrivate:*
// )
// [Project] [IndexJoin] Scan
//
// Or
//
// (Update
// $input:(Project
// (Scan $scanPrivate:*)
// $projections:*
// $passthrough:*
// )
// $checks:*
// $mutationPrivate:*
// )
//
_, ok := upd.Input.(*memo.ScanExpr)
if !ok {
proj, ok := upd.Input.(*memo.ProjectExpr)
if !ok {
return false
}
_, ok = proj.Input.(*memo.ScanExpr)
if !ok {
return false
}
input := upd.Input
if proj, ok := input.(*memo.ProjectExpr); ok {
input = proj.Input
}
return true
if idxJoin, ok := input.(*memo.IndexJoinExpr); ok {
input = idxJoin.Input
}
_, ok := input.(*memo.ScanExpr)
return ok
}

// tryApplyImplicitLockingToUpsertInput determines whether or not the builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -601,5 +601,3 @@ message LIKE 'Del /Table/61/2/%' OR
message LIKE 'CPut /Table/61/2/%'
----
CPut /Table/61/2/5/1/0 -> /BYTES/0x330a1308 (replacing raw_bytes:"\000\000\000\000\0033\006\023\010" timestamp:<> , if exists)


91 changes: 89 additions & 2 deletions pkg/sql/opt/exec/execbuilder/testdata/update
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ count · ·
· locking strength for update

query TTT
EXPLAIN UPDATE kv SET v=k WHERE k > 1 AND k < 10;
EXPLAIN UPDATE kv SET v = k WHERE k > 1 AND k < 10
----
· distributed false
· vectorized false
Expand Down Expand Up @@ -481,6 +481,55 @@ count · ·
· spans ALL
· locking strength for update

statement ok
CREATE TABLE kv3 (
k INT PRIMARY KEY,
v INT,
meta INT,
INDEX (v),
FAMILY (k, v, meta)
)

query TTT
EXPLAIN UPDATE kv3 SET k = 3 WHERE v = 10
----
· distributed false
· vectorized false
count · ·
└── update · ·
│ table kv3
│ set k
│ strategy updater
│ auto commit ·
└── render · ·
└── index-join · ·
│ table kv3@primary
│ key columns k
└── scan · ·
· table kv3@kv3_v_idx
· spans /10-/11
· locking strength for update

query TTT
EXPLAIN UPDATE kv3 SET k = v WHERE v > 1 AND v < 10
----
· distributed false
· vectorized false
count · ·
└── update · ·
│ table kv3
│ set k
│ strategy updater
│ auto commit ·
└── render · ·
└── index-join · ·
│ table kv3@primary
│ key columns k
└── scan · ·
· table kv3@kv3_v_idx
· spans /2-/10
· locking strength for update

statement ok
SET enable_implicit_select_for_update = false

Expand All @@ -501,7 +550,7 @@ count · ·
· spans /3-/3/#

query TTT
EXPLAIN UPDATE kv SET v=k WHERE k > 1 AND k < 10;
EXPLAIN UPDATE kv SET v = k WHERE k > 1 AND k < 10
----
· distributed false
· vectorized false
Expand Down Expand Up @@ -571,6 +620,44 @@ count · ·
· spans -/2/#
· limit 1

query TTT
EXPLAIN UPDATE kv3 SET k = 3 WHERE v = 10
----
· distributed false
· vectorized false
count · ·
└── update · ·
│ table kv3
│ set k
│ strategy updater
│ auto commit ·
└── render · ·
└── index-join · ·
│ table kv3@primary
│ key columns k
└── scan · ·
· table kv3@kv3_v_idx
· spans /10-/11

query TTT
EXPLAIN UPDATE kv3 SET k = v WHERE v > 1 AND v < 10
----
· distributed false
· vectorized false
count · ·
└── update · ·
│ table kv3
│ set k
│ strategy updater
│ auto commit ·
└── render · ·
└── index-join · ·
│ table kv3@primary
│ key columns k
└── scan · ·
· table kv3@kv3_v_idx
· spans /2-/10

# Update single column family.
query TTT
SELECT tree, field, description FROM [
Expand Down

0 comments on commit 8c000de

Please sign in to comment.