Skip to content

Commit 796ede8

Browse files
committed
opt: handle locking in the vector search rule
This commit updates `GenerateVectorSearch` so that the lookup-join has the same locking clause as the originally matched scan. This ensures that any locking/nowait behavior is preserved, and makes the rule's behavior match those for other index types more closely. Epic: CRDB-42943 Release note: None
1 parent 5cb0795 commit 796ede8

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

pkg/sql/opt/xform/limit_funcs.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ func (c *CustomFuncs) TryGenerateVectorSearch(
503503
KeyCols: lookupCols,
504504
Cols: sp.Cols,
505505
LookupColsAreTableKey: true,
506+
Locking: sp.Locking,
506507
}
507508
vectorSearch = c.e.f.ConstructLookupJoin(vectorSearch, nil /* on */, lookupPrivate)
508509

pkg/sql/opt/xform/testdata/rules/limit

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3654,6 +3654,118 @@ top-k
36543654
└── projections
36553655
└── vec1:9 <-> $1 [as=column15:15, outer=(9), immutable]
36563656

3657+
# Locking should transfer from the scan to the lookup-join.
3658+
opt expect=GenerateVectorSearch
3659+
SELECT * FROM index_tab ORDER BY vec1 <-> '[3,1,2]' LIMIT 5 FOR UPDATE;
3660+
----
3661+
top-k
3662+
├── columns: id:1!null val:2 region:3 latitude:4 longitude:5 data1:6!null data2:7!null geom:8 vec1:9 vec2:10 vec3:11 [hidden: column15:15]
3663+
├── internal-ordering: +15
3664+
├── k: 5
3665+
├── cardinality: [0 - 5]
3666+
├── volatile
3667+
├── key: (1)
3668+
├── fd: (1)-->(2-11), (9)-->(15)
3669+
├── ordering: +15
3670+
└── project
3671+
├── columns: column15:15 id:1!null val:2 region:3 latitude:4 longitude:5 data1:6!null data2:7!null geom:8 vec1:9 vec2:10 vec3:11
3672+
├── volatile
3673+
├── key: (1)
3674+
├── fd: (1)-->(2-11), (9)-->(15)
3675+
├── inner-join (lookup index_tab)
3676+
│ ├── columns: id:1!null val:2 region:3 latitude:4 longitude:5 data1:6!null data2:7!null geom:8 vec1:9 vec2:10 vec3:11
3677+
│ ├── key columns: [1] = [1]
3678+
│ ├── lookup columns are key
3679+
│ ├── locking: for-update
3680+
│ ├── volatile
3681+
│ ├── key: (1)
3682+
│ ├── fd: (1)-->(2-11)
3683+
│ ├── vector-search index_tab@index_tab_vec1_idx,vector
3684+
│ │ ├── columns: id:1!null
3685+
│ │ ├── target nearest neighbors: 5
3686+
│ │ ├── key: (1)
3687+
│ │ └── '[3,1,2]'
3688+
│ └── filters (true)
3689+
└── projections
3690+
└── vec1:9 <-> '[3,1,2]' [as=column15:15, outer=(9), immutable]
3691+
3692+
opt expect=GenerateVectorSearch
3693+
SELECT * FROM index_tab ORDER BY vec1 <-> '[3,1,2]' LIMIT 5 FOR SHARE SKIP LOCKED;
3694+
----
3695+
top-k
3696+
├── columns: id:1!null val:2 region:3 latitude:4 longitude:5 data1:6!null data2:7!null geom:8 vec1:9 vec2:10 vec3:11 [hidden: column15:15]
3697+
├── internal-ordering: +15
3698+
├── k: 5
3699+
├── cardinality: [0 - 5]
3700+
├── volatile
3701+
├── key: (1)
3702+
├── fd: (1)-->(2-11), (9)-->(15)
3703+
├── ordering: +15
3704+
└── project
3705+
├── columns: column15:15 id:1!null val:2 region:3 latitude:4 longitude:5 data1:6!null data2:7!null geom:8 vec1:9 vec2:10 vec3:11
3706+
├── volatile
3707+
├── key: (1)
3708+
├── fd: (1)-->(2-11), (9)-->(15)
3709+
├── inner-join (lookup index_tab)
3710+
│ ├── columns: id:1!null val:2 region:3 latitude:4 longitude:5 data1:6!null data2:7!null geom:8 vec1:9 vec2:10 vec3:11
3711+
│ ├── key columns: [1] = [1]
3712+
│ ├── lookup columns are key
3713+
│ ├── locking: for-share,skip-locked
3714+
│ ├── volatile
3715+
│ ├── key: (1)
3716+
│ ├── fd: (1)-->(2-11)
3717+
│ ├── vector-search index_tab@index_tab_vec1_idx,vector
3718+
│ │ ├── columns: id:1!null
3719+
│ │ ├── target nearest neighbors: 5
3720+
│ │ ├── key: (1)
3721+
│ │ └── '[3,1,2]'
3722+
│ └── filters (true)
3723+
└── projections
3724+
└── vec1:9 <-> '[3,1,2]' [as=column15:15, outer=(9), immutable]
3725+
3726+
# The lock operator handles locking, so the lookup-join is non-locking.
3727+
opt expect=GenerateVectorSearch set=optimizer_use_lock_op_for_serializable=true
3728+
SELECT * FROM index_tab ORDER BY vec1 <-> '[3,1,2]' LIMIT 5 FOR SHARE;
3729+
----
3730+
lock index_tab
3731+
├── columns: id:1!null val:2 region:3 latitude:4 longitude:5 data1:6!null data2:7!null geom:8 vec1:9 vec2:10 vec3:11 [hidden: column15:15]
3732+
├── key columns: id:1
3733+
├── lock columns: (16-26)
3734+
├── locking: for-share
3735+
├── cardinality: [0 - 5]
3736+
├── volatile
3737+
├── key: (1)
3738+
├── fd: (1)-->(2-11), (9)-->(15)
3739+
├── ordering: +15
3740+
└── top-k
3741+
├── columns: id:1!null val:2 region:3 latitude:4 longitude:5 data1:6!null data2:7!null geom:8 vec1:9 vec2:10 vec3:11 column15:15
3742+
├── internal-ordering: +15
3743+
├── k: 5
3744+
├── cardinality: [0 - 5]
3745+
├── immutable
3746+
├── key: (1)
3747+
├── fd: (1)-->(2-11), (9)-->(15)
3748+
├── ordering: +15
3749+
└── project
3750+
├── columns: column15:15 id:1!null val:2 region:3 latitude:4 longitude:5 data1:6!null data2:7!null geom:8 vec1:9 vec2:10 vec3:11
3751+
├── immutable
3752+
├── key: (1)
3753+
├── fd: (1)-->(2-11), (9)-->(15)
3754+
├── inner-join (lookup index_tab)
3755+
│ ├── columns: id:1!null val:2 region:3 latitude:4 longitude:5 data1:6!null data2:7!null geom:8 vec1:9 vec2:10 vec3:11
3756+
│ ├── key columns: [1] = [1]
3757+
│ ├── lookup columns are key
3758+
│ ├── key: (1)
3759+
│ ├── fd: (1)-->(2-11)
3760+
│ ├── vector-search index_tab@index_tab_vec1_idx,vector
3761+
│ │ ├── columns: id:1!null
3762+
│ │ ├── target nearest neighbors: 5
3763+
│ │ ├── key: (1)
3764+
│ │ └── '[3,1,2]'
3765+
│ └── filters (true)
3766+
└── projections
3767+
└── vec1:9 <-> '[3,1,2]' [as=column15:15, outer=(9), immutable]
3768+
36573769
# The index can be forced.
36583770
opt expect=GenerateVectorSearch
36593771
SELECT * FROM index_tab@index_tab_vec2_idx ORDER BY vec2 <-> '[3,1,2]' LIMIT 500;

0 commit comments

Comments
 (0)