diff --git a/pkg/sql/opt/exec/execbuilder/mutation.go b/pkg/sql/opt/exec/execbuilder/mutation.go index 30b793512626..3caa984fb615 100644 --- a/pkg/sql/opt/exec/execbuilder/mutation.go +++ b/pkg/sql/opt/exec/execbuilder/mutation.go @@ -142,6 +142,11 @@ func (b *Builder) tryBuildFastPathInsert(ins *memo.InsertExpr) (_ execPlan, ok b if !b.allowInsertFastPath { return execPlan{}, false, nil } + // If there are unique checks required, there must be the same number of fast + // path unique checks. + if len(ins.UniqueChecks) != len(ins.FastPathUniqueChecks) { + return execPlan{}, false, nil + } insInput := ins.Input values, ok := insInput.(*memo.ValuesExpr) diff --git a/pkg/sql/opt/optbuilder/mutation_builder_unique.go b/pkg/sql/opt/optbuilder/mutation_builder_unique.go index 2bee6db104eb..ee33299b3742 100644 --- a/pkg/sql/opt/optbuilder/mutation_builder_unique.go +++ b/pkg/sql/opt/optbuilder/mutation_builder_unique.go @@ -44,6 +44,7 @@ func (mb *mutationBuilder) buildUniqueChecksForInsert() { h := &mb.uniqueCheckHelper + buildFastPathCheck := true for i, n := 0, mb.tab.UniqueCount(); i < n; i++ { // If this constraint is already enforced by an index, we don't need to plan // a check. @@ -58,9 +59,16 @@ func (mb *mutationBuilder) buildUniqueChecksForInsert() { continue } if h.init(mb, i) { - uniqueChecksItem, fastPathUniqueChecksItem := h.buildInsertionCheck(true /* buildFastPathCheck */) + uniqueChecksItem, fastPathUniqueChecksItem := h.buildInsertionCheck(buildFastPathCheck) + if fastPathUniqueChecksItem == nil { + // If we can't build one fast path check, don't build any of them into + // the expression tree. + buildFastPathCheck = false + mb.fastPathUniqueChecks = nil + } else { + mb.fastPathUniqueChecks = append(mb.fastPathUniqueChecks, *fastPathUniqueChecksItem) + } mb.uniqueChecks = append(mb.uniqueChecks, uniqueChecksItem) - mb.fastPathUniqueChecks = append(mb.fastPathUniqueChecks, fastPathUniqueChecksItem) } } telemetry.Inc(sqltelemetry.UniqueChecksUseCounter) @@ -416,10 +424,12 @@ func (h *uniqueCheckHelper) buildFiltersForFastPathCheck( // buildInsertionCheck creates a unique check for rows which are added to a // table. The input to the insertion check will be produced from the input to // the mutation operator. If buildFastPathCheck is true, a fast-path unique -// check for the insert is also built. +// check for the insert is also built. A `UniqueChecksItem` can always be built, +// but if it is not possible to build a `FastPathUniqueChecksItem`, the second +// return value is nil. func (h *uniqueCheckHelper) buildInsertionCheck( buildFastPathCheck bool, -) (memo.UniqueChecksItem, memo.FastPathUniqueChecksItem) { +) (memo.UniqueChecksItem, *memo.FastPathUniqueChecksItem) { f := h.mb.b.factory // Build a self semi-join, with the new values on the left and the @@ -538,6 +548,14 @@ func (h *uniqueCheckHelper) buildInsertionCheck( // violation error. project := f.ConstructProject(semiJoin, nil /* projections */, keyCols.ToSet()) + uniqueChecks := f.ConstructUniqueChecksItem(project, &memo.UniqueChecksItemPrivate{ + Table: h.mb.tabID, + CheckOrdinal: h.uniqueOrdinal, + KeyCols: keyCols, + }) + if !buildFastPathCheck { + return uniqueChecks, nil + } // Build a SelectExpr which can be optimized in the explore phase and used // to build information needed to perform the fast path uniqueness check. // The goal is for the Select to be rewritten into a constrained scan on @@ -556,24 +574,16 @@ func (h *uniqueCheckHelper) buildInsertionCheck( newFilters := f.CustomFuncs().RemapScanColsInFilter(scanFilters, &scanExpr.ScanPrivate, newScanPrivate) uniqueFastPathCheck = f.ConstructSelect(newScanExpr, newFilters) } else { - uniqueFastPathCheck = f.CustomFuncs().ConstructEmptyValues(opt.ColSet{}) + // Don't build a fast-path check if we failed to create a new ScanExpr. + return uniqueChecks, nil } } else if buildFastPathCheck { - // Things blow up if a RelExpr is nil, so construct a minimal dummy relation - // that will not be used. - uniqueFastPathCheck = f.CustomFuncs().ConstructEmptyValues(opt.ColSet{}) - } - - uniqueChecks := f.ConstructUniqueChecksItem(project, &memo.UniqueChecksItemPrivate{ - Table: h.mb.tabID, - CheckOrdinal: h.uniqueOrdinal, - KeyCols: keyCols, - }) - if !buildFastPathCheck { - return uniqueChecks, memo.FastPathUniqueChecksItem{} + // Don't build a fast-path check if we failed to build a ScanExpr with + // filters on all unique check columns. + return uniqueChecks, nil } fastPathChecks := f.ConstructFastPathUniqueChecksItem(uniqueFastPathCheck, &memo.FastPathUniqueChecksItemPrivate{ReferencedTableID: h.mb.tabID, CheckOrdinal: h.uniqueOrdinal}) - return uniqueChecks, fastPathChecks + return uniqueChecks, &fastPathChecks } // buildTableScan builds a Scan of the table. The ordinals of the columns diff --git a/pkg/sql/opt/optbuilder/testdata/unique-checks-insert b/pkg/sql/opt/optbuilder/testdata/unique-checks-insert index 7e2e08f46202..8b0d7d77d7cd 100644 --- a/pkg/sql/opt/optbuilder/testdata/unique-checks-insert +++ b/pkg/sql/opt/optbuilder/testdata/unique-checks-insert @@ -26,51 +26,46 @@ insert uniq │ ├── columns: column1:8!null column2:9!null column3:10!null column4:11!null column5:12!null │ ├── (1, 1, 1, 1, 1) │ └── (2, 2, 2, 2, 2) - ├── unique-checks - │ ├── unique-checks-item: uniq(w) - │ │ └── project - │ │ ├── columns: w:22!null - │ │ └── semi-join (hash) - │ │ ├── columns: k:20!null v:21!null w:22!null x:23!null y:24!null - │ │ ├── with-scan &1 - │ │ │ ├── columns: k:20!null v:21!null w:22!null x:23!null y:24!null - │ │ │ └── mapping: - │ │ │ ├── column1:8 => k:20 - │ │ │ ├── column2:9 => v:21 - │ │ │ ├── column3:10 => w:22 - │ │ │ ├── column4:11 => x:23 - │ │ │ └── column5:12 => y:24 - │ │ ├── scan uniq - │ │ │ ├── columns: uniq.k:13!null uniq.v:14 uniq.w:15 uniq.x:16 uniq.y:17 - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── w:22 = uniq.w:15 - │ │ └── k:20 != uniq.k:13 - │ └── unique-checks-item: uniq(x,y) - │ └── project - │ ├── columns: x:35!null y:36!null - │ └── semi-join (hash) - │ ├── columns: k:32!null v:33!null w:34!null x:35!null y:36!null - │ ├── with-scan &1 - │ │ ├── columns: k:32!null v:33!null w:34!null x:35!null y:36!null - │ │ └── mapping: - │ │ ├── column1:8 => k:32 - │ │ ├── column2:9 => v:33 - │ │ ├── column3:10 => w:34 - │ │ ├── column4:11 => x:35 - │ │ └── column5:12 => y:36 - │ ├── scan uniq - │ │ ├── columns: uniq.k:25!null uniq.v:26 uniq.w:27 uniq.x:28 uniq.y:29 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── x:35 = uniq.x:28 - │ ├── y:36 = uniq.y:29 - │ └── k:32 != uniq.k:25 - └── fast-path-unique-checks - ├── fast-path-unique-checks-item: uniq(w) - │ └── values - └── fast-path-unique-checks-item: uniq(x,y) - └── values + └── unique-checks + ├── unique-checks-item: uniq(w) + │ └── project + │ ├── columns: w:22!null + │ └── semi-join (hash) + │ ├── columns: k:20!null v:21!null w:22!null x:23!null y:24!null + │ ├── with-scan &1 + │ │ ├── columns: k:20!null v:21!null w:22!null x:23!null y:24!null + │ │ └── mapping: + │ │ ├── column1:8 => k:20 + │ │ ├── column2:9 => v:21 + │ │ ├── column3:10 => w:22 + │ │ ├── column4:11 => x:23 + │ │ └── column5:12 => y:24 + │ ├── scan uniq + │ │ ├── columns: uniq.k:13!null uniq.v:14 uniq.w:15 uniq.x:16 uniq.y:17 + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── w:22 = uniq.w:15 + │ └── k:20 != uniq.k:13 + └── unique-checks-item: uniq(x,y) + └── project + ├── columns: x:35!null y:36!null + └── semi-join (hash) + ├── columns: k:32!null v:33!null w:34!null x:35!null y:36!null + ├── with-scan &1 + │ ├── columns: k:32!null v:33!null w:34!null x:35!null y:36!null + │ └── mapping: + │ ├── column1:8 => k:32 + │ ├── column2:9 => v:33 + │ ├── column3:10 => w:34 + │ ├── column4:11 => x:35 + │ └── column5:12 => y:36 + ├── scan uniq + │ ├── columns: uniq.k:25!null uniq.v:26 uniq.w:27 uniq.x:28 uniq.y:29 + │ └── flags: disabled not visible index feature + └── filters + ├── x:35 = uniq.x:28 + ├── y:36 = uniq.y:29 + └── k:32 != uniq.k:25 # Some of the inserted values have nulls. build @@ -90,51 +85,46 @@ insert uniq │ ├── (1, 1, 1, 1, 1) │ ├── (2, 2, 2, 2, 2) │ └── (3, NULL::INT8, NULL::INT8, NULL::INT8, 3) - ├── unique-checks - │ ├── unique-checks-item: uniq(w) - │ │ └── project - │ │ ├── columns: w:22 - │ │ └── semi-join (hash) - │ │ ├── columns: k:20!null v:21 w:22 x:23 y:24!null - │ │ ├── with-scan &1 - │ │ │ ├── columns: k:20!null v:21 w:22 x:23 y:24!null - │ │ │ └── mapping: - │ │ │ ├── column1:8 => k:20 - │ │ │ ├── column2:9 => v:21 - │ │ │ ├── column3:10 => w:22 - │ │ │ ├── column4:11 => x:23 - │ │ │ └── column5:12 => y:24 - │ │ ├── scan uniq - │ │ │ ├── columns: uniq.k:13!null uniq.v:14 uniq.w:15 uniq.x:16 uniq.y:17 - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── w:22 = uniq.w:15 - │ │ └── k:20 != uniq.k:13 - │ └── unique-checks-item: uniq(x,y) - │ └── project - │ ├── columns: x:35 y:36!null - │ └── semi-join (hash) - │ ├── columns: k:32!null v:33 w:34 x:35 y:36!null - │ ├── with-scan &1 - │ │ ├── columns: k:32!null v:33 w:34 x:35 y:36!null - │ │ └── mapping: - │ │ ├── column1:8 => k:32 - │ │ ├── column2:9 => v:33 - │ │ ├── column3:10 => w:34 - │ │ ├── column4:11 => x:35 - │ │ └── column5:12 => y:36 - │ ├── scan uniq - │ │ ├── columns: uniq.k:25!null uniq.v:26 uniq.w:27 uniq.x:28 uniq.y:29 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── x:35 = uniq.x:28 - │ ├── y:36 = uniq.y:29 - │ └── k:32 != uniq.k:25 - └── fast-path-unique-checks - ├── fast-path-unique-checks-item: uniq(w) - │ └── values - └── fast-path-unique-checks-item: uniq(x,y) - └── values + └── unique-checks + ├── unique-checks-item: uniq(w) + │ └── project + │ ├── columns: w:22 + │ └── semi-join (hash) + │ ├── columns: k:20!null v:21 w:22 x:23 y:24!null + │ ├── with-scan &1 + │ │ ├── columns: k:20!null v:21 w:22 x:23 y:24!null + │ │ └── mapping: + │ │ ├── column1:8 => k:20 + │ │ ├── column2:9 => v:21 + │ │ ├── column3:10 => w:22 + │ │ ├── column4:11 => x:23 + │ │ └── column5:12 => y:24 + │ ├── scan uniq + │ │ ├── columns: uniq.k:13!null uniq.v:14 uniq.w:15 uniq.x:16 uniq.y:17 + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── w:22 = uniq.w:15 + │ └── k:20 != uniq.k:13 + └── unique-checks-item: uniq(x,y) + └── project + ├── columns: x:35 y:36!null + └── semi-join (hash) + ├── columns: k:32!null v:33 w:34 x:35 y:36!null + ├── with-scan &1 + │ ├── columns: k:32!null v:33 w:34 x:35 y:36!null + │ └── mapping: + │ ├── column1:8 => k:32 + │ ├── column2:9 => v:33 + │ ├── column3:10 => w:34 + │ ├── column4:11 => x:35 + │ └── column5:12 => y:36 + ├── scan uniq + │ ├── columns: uniq.k:25!null uniq.v:26 uniq.w:27 uniq.x:28 uniq.y:29 + │ └── flags: disabled not visible index feature + └── filters + ├── x:35 = uniq.x:28 + ├── y:36 = uniq.y:29 + └── k:32 != uniq.k:25 # No need to plan checks for w since it's always null. # NOTE: We use the norm directive here so that assignment casts are eliminated @@ -155,28 +145,25 @@ insert uniq │ ├── columns: column1:8!null column2:9!null column3:10 column4:11!null column5:12!null │ ├── (1, 1, NULL, 1, 1) │ └── (2, 2, NULL, 2, 2) - ├── unique-checks - │ └── unique-checks-item: uniq(x,y) - │ └── project - │ ├── columns: x:23!null y:24!null - │ └── semi-join (hash) - │ ├── columns: k:20!null x:23!null y:24!null - │ ├── with-scan &1 - │ │ ├── columns: k:20!null x:23!null y:24!null - │ │ └── mapping: - │ │ ├── column1:8 => k:20 - │ │ ├── column4:11 => x:23 - │ │ └── column5:12 => y:24 - │ ├── scan uniq - │ │ ├── columns: uniq.k:13!null uniq.x:16 uniq.y:17 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── x:23 = uniq.x:16 - │ ├── y:24 = uniq.y:17 - │ └── k:20 != uniq.k:13 - └── fast-path-unique-checks - └── fast-path-unique-checks-item: uniq(x,y) - └── values + └── unique-checks + └── unique-checks-item: uniq(x,y) + └── project + ├── columns: x:23!null y:24!null + └── semi-join (hash) + ├── columns: k:20!null x:23!null y:24!null + ├── with-scan &1 + │ ├── columns: k:20!null x:23!null y:24!null + │ └── mapping: + │ ├── column1:8 => k:20 + │ ├── column4:11 => x:23 + │ └── column5:12 => y:24 + ├── scan uniq + │ ├── columns: uniq.k:13!null uniq.x:16 uniq.y:17 + │ └── flags: disabled not visible index feature + └── filters + ├── x:23 = uniq.x:16 + ├── y:24 = uniq.y:17 + └── k:20 != uniq.k:13 # No need to plan checks for x,y since x is always null. # NOTE: We use the norm directive here so that assignment casts are eliminated @@ -197,26 +184,23 @@ insert uniq │ ├── columns: column1:8!null column2:9!null column3:10 column4:11 column5:12!null │ ├── (1, 1, 1, NULL, 1) │ └── (2, 2, NULL, NULL, 2) - ├── unique-checks - │ └── unique-checks-item: uniq(w) - │ └── project - │ ├── columns: w:22 - │ └── semi-join (hash) - │ ├── columns: k:20!null w:22 - │ ├── with-scan &1 - │ │ ├── columns: k:20!null w:22 - │ │ └── mapping: - │ │ ├── column1:8 => k:20 - │ │ └── column3:10 => w:22 - │ ├── scan uniq - │ │ ├── columns: uniq.k:13!null uniq.w:15 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── w:22 = uniq.w:15 - │ └── k:20 != uniq.k:13 - └── fast-path-unique-checks - └── fast-path-unique-checks-item: uniq(w) - └── values + └── unique-checks + └── unique-checks-item: uniq(w) + └── project + ├── columns: w:22 + └── semi-join (hash) + ├── columns: k:20!null w:22 + ├── with-scan &1 + │ ├── columns: k:20!null w:22 + │ └── mapping: + │ ├── column1:8 => k:20 + │ └── column3:10 => w:22 + ├── scan uniq + │ ├── columns: uniq.k:13!null uniq.w:15 + │ └── flags: disabled not visible index feature + └── filters + ├── w:22 = uniq.w:15 + └── k:20 != uniq.k:13 # No need to plan checks for x,y since y is always null. # NOTE: We use the norm directive here so that assignment casts are eliminated @@ -237,26 +221,23 @@ insert uniq │ ├── columns: column1:8!null column2:9!null column3:10!null column4:11!null column5:12 │ ├── (1, 1, 1, 1, NULL) │ └── (2, 2, 2, 2, NULL) - ├── unique-checks - │ └── unique-checks-item: uniq(w) - │ └── project - │ ├── columns: w:22!null - │ └── semi-join (hash) - │ ├── columns: k:20!null w:22!null - │ ├── with-scan &1 - │ │ ├── columns: k:20!null w:22!null - │ │ └── mapping: - │ │ ├── column1:8 => k:20 - │ │ └── column3:10 => w:22 - │ ├── scan uniq - │ │ ├── columns: uniq.k:13!null uniq.w:15 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── w:22 = uniq.w:15 - │ └── k:20 != uniq.k:13 - └── fast-path-unique-checks - └── fast-path-unique-checks-item: uniq(w) - └── values + └── unique-checks + └── unique-checks-item: uniq(w) + └── project + ├── columns: w:22!null + └── semi-join (hash) + ├── columns: k:20!null w:22!null + ├── with-scan &1 + │ ├── columns: k:20!null w:22!null + │ └── mapping: + │ ├── column1:8 => k:20 + │ └── column3:10 => w:22 + ├── scan uniq + │ ├── columns: uniq.k:13!null uniq.w:15 + │ └── flags: disabled not visible index feature + └── filters + ├── w:22 = uniq.w:15 + └── k:20 != uniq.k:13 # No need to plan any checks, since w, x and y are always null. # NOTE: We use the norm directive here so that assignment casts are eliminated @@ -472,30 +453,27 @@ insert uniq │ │ └── column4:11 │ └── first-agg [as=column5:12] │ └── column5:12 - ├── unique-checks - │ └── unique-checks-item: uniq(x,y) - │ └── project - │ ├── columns: x:30!null y:31!null - │ └── semi-join (hash) - │ ├── columns: k:27!null v:28!null w:29!null x:30!null y:31!null - │ ├── with-scan &1 - │ │ ├── columns: k:27!null v:28!null w:29!null x:30!null y:31!null - │ │ └── mapping: - │ │ ├── column1:8 => k:27 - │ │ ├── column2:9 => v:28 - │ │ ├── column3:10 => w:29 - │ │ ├── column4:11 => x:30 - │ │ └── column5:12 => y:31 - │ ├── scan uniq - │ │ ├── columns: uniq.k:20!null uniq.v:21 uniq.w:22 uniq.x:23 uniq.y:24 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── x:30 = uniq.x:23 - │ ├── y:31 = uniq.y:24 - │ └── k:27 != uniq.k:20 - └── fast-path-unique-checks - └── fast-path-unique-checks-item: uniq(x,y) - └── values + └── unique-checks + └── unique-checks-item: uniq(x,y) + └── project + ├── columns: x:30!null y:31!null + └── semi-join (hash) + ├── columns: k:27!null v:28!null w:29!null x:30!null y:31!null + ├── with-scan &1 + │ ├── columns: k:27!null v:28!null w:29!null x:30!null y:31!null + │ └── mapping: + │ ├── column1:8 => k:27 + │ ├── column2:9 => v:28 + │ ├── column3:10 => w:29 + │ ├── column4:11 => x:30 + │ └── column5:12 => y:31 + ├── scan uniq + │ ├── columns: uniq.k:20!null uniq.v:21 uniq.w:22 uniq.x:23 uniq.y:24 + │ └── flags: disabled not visible index feature + └── filters + ├── x:30 = uniq.x:23 + ├── y:31 = uniq.y:24 + └── k:27 != uniq.k:20 # On conflict clause references unique without index constraint explicitly. build @@ -580,51 +558,46 @@ insert uniq │ ├── columns: other.k:8 other.v:9 other.w:10!null other.x:11 other.y:12 │ └── scan other │ └── columns: other.k:8 other.v:9 other.w:10!null other.x:11 other.y:12 rowid:13!null other.crdb_internal_mvcc_timestamp:14 other.tableoid:15 - ├── unique-checks - │ ├── unique-checks-item: uniq(w) - │ │ └── project - │ │ ├── columns: w:25!null - │ │ └── semi-join (hash) - │ │ ├── columns: k:23 v:24 w:25!null x:26 y:27 - │ │ ├── with-scan &1 - │ │ │ ├── columns: k:23 v:24 w:25!null x:26 y:27 - │ │ │ └── mapping: - │ │ │ ├── other.k:8 => k:23 - │ │ │ ├── other.v:9 => v:24 - │ │ │ ├── other.w:10 => w:25 - │ │ │ ├── other.x:11 => x:26 - │ │ │ └── other.y:12 => y:27 - │ │ ├── scan uniq - │ │ │ ├── columns: uniq.k:16!null uniq.v:17 uniq.w:18 uniq.x:19 uniq.y:20 - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── w:25 = uniq.w:18 - │ │ └── k:23 != uniq.k:16 - │ └── unique-checks-item: uniq(x,y) - │ └── project - │ ├── columns: x:38 y:39 - │ └── semi-join (hash) - │ ├── columns: k:35 v:36 w:37!null x:38 y:39 - │ ├── with-scan &1 - │ │ ├── columns: k:35 v:36 w:37!null x:38 y:39 - │ │ └── mapping: - │ │ ├── other.k:8 => k:35 - │ │ ├── other.v:9 => v:36 - │ │ ├── other.w:10 => w:37 - │ │ ├── other.x:11 => x:38 - │ │ └── other.y:12 => y:39 - │ ├── scan uniq - │ │ ├── columns: uniq.k:28!null uniq.v:29 uniq.w:30 uniq.x:31 uniq.y:32 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── x:38 = uniq.x:31 - │ ├── y:39 = uniq.y:32 - │ └── k:35 != uniq.k:28 - └── fast-path-unique-checks - ├── fast-path-unique-checks-item: uniq(w) - │ └── values - └── fast-path-unique-checks-item: uniq(x,y) - └── values + └── unique-checks + ├── unique-checks-item: uniq(w) + │ └── project + │ ├── columns: w:25!null + │ └── semi-join (hash) + │ ├── columns: k:23 v:24 w:25!null x:26 y:27 + │ ├── with-scan &1 + │ │ ├── columns: k:23 v:24 w:25!null x:26 y:27 + │ │ └── mapping: + │ │ ├── other.k:8 => k:23 + │ │ ├── other.v:9 => v:24 + │ │ ├── other.w:10 => w:25 + │ │ ├── other.x:11 => x:26 + │ │ └── other.y:12 => y:27 + │ ├── scan uniq + │ │ ├── columns: uniq.k:16!null uniq.v:17 uniq.w:18 uniq.x:19 uniq.y:20 + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── w:25 = uniq.w:18 + │ └── k:23 != uniq.k:16 + └── unique-checks-item: uniq(x,y) + └── project + ├── columns: x:38 y:39 + └── semi-join (hash) + ├── columns: k:35 v:36 w:37!null x:38 y:39 + ├── with-scan &1 + │ ├── columns: k:35 v:36 w:37!null x:38 y:39 + │ └── mapping: + │ ├── other.k:8 => k:35 + │ ├── other.v:9 => v:36 + │ ├── other.w:10 => w:37 + │ ├── other.x:11 => x:38 + │ └── other.y:12 => y:39 + ├── scan uniq + │ ├── columns: uniq.k:28!null uniq.v:29 uniq.w:30 uniq.x:31 uniq.y:32 + │ └── flags: disabled not visible index feature + └── filters + ├── x:38 = uniq.x:31 + ├── y:39 = uniq.y:32 + └── k:35 != uniq.k:28 exec-ddl CREATE TABLE uniq_overlaps_pk ( @@ -658,70 +631,63 @@ insert uniq_overlaps_pk │ ├── columns: column1:7!null column2:8!null column3:9!null column4:10!null │ ├── (1, 1, 1, 1) │ └── (2, 2, 2, 2) - ├── unique-checks - │ ├── unique-checks-item: uniq_overlaps_pk(b,c) - │ │ └── project - │ │ ├── columns: b:18!null c:19!null - │ │ └── semi-join (hash) - │ │ ├── columns: a:17!null b:18!null c:19!null d:20!null - │ │ ├── with-scan &1 - │ │ │ ├── columns: a:17!null b:18!null c:19!null d:20!null - │ │ │ └── mapping: - │ │ │ ├── column1:7 => a:17 - │ │ │ ├── column2:8 => b:18 - │ │ │ ├── column3:9 => c:19 - │ │ │ └── column4:10 => d:20 - │ │ ├── scan uniq_overlaps_pk - │ │ │ ├── columns: uniq_overlaps_pk.a:11!null uniq_overlaps_pk.b:12!null uniq_overlaps_pk.c:13 uniq_overlaps_pk.d:14 - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── b:18 = uniq_overlaps_pk.b:12 - │ │ ├── c:19 = uniq_overlaps_pk.c:13 - │ │ └── a:17 != uniq_overlaps_pk.a:11 - │ ├── unique-checks-item: uniq_overlaps_pk(a) - │ │ └── project - │ │ ├── columns: a:27!null - │ │ └── semi-join (hash) - │ │ ├── columns: a:27!null b:28!null c:29!null d:30!null - │ │ ├── with-scan &1 - │ │ │ ├── columns: a:27!null b:28!null c:29!null d:30!null - │ │ │ └── mapping: - │ │ │ ├── column1:7 => a:27 - │ │ │ ├── column2:8 => b:28 - │ │ │ ├── column3:9 => c:29 - │ │ │ └── column4:10 => d:30 - │ │ ├── scan uniq_overlaps_pk - │ │ │ ├── columns: uniq_overlaps_pk.a:21!null uniq_overlaps_pk.b:22!null uniq_overlaps_pk.c:23 uniq_overlaps_pk.d:24 - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── a:27 = uniq_overlaps_pk.a:21 - │ │ └── b:28 != uniq_overlaps_pk.b:22 - │ └── unique-checks-item: uniq_overlaps_pk(c,d) - │ └── project - │ ├── columns: c:39!null d:40!null - │ └── semi-join (hash) - │ ├── columns: a:37!null b:38!null c:39!null d:40!null - │ ├── with-scan &1 - │ │ ├── columns: a:37!null b:38!null c:39!null d:40!null - │ │ └── mapping: - │ │ ├── column1:7 => a:37 - │ │ ├── column2:8 => b:38 - │ │ ├── column3:9 => c:39 - │ │ └── column4:10 => d:40 - │ ├── scan uniq_overlaps_pk - │ │ ├── columns: uniq_overlaps_pk.a:31!null uniq_overlaps_pk.b:32!null uniq_overlaps_pk.c:33 uniq_overlaps_pk.d:34 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── c:39 = uniq_overlaps_pk.c:33 - │ ├── d:40 = uniq_overlaps_pk.d:34 - │ └── (a:37 != uniq_overlaps_pk.a:31) OR (b:38 != uniq_overlaps_pk.b:32) - └── fast-path-unique-checks - ├── fast-path-unique-checks-item: uniq_overlaps_pk(b,c) - │ └── values - ├── fast-path-unique-checks-item: uniq_overlaps_pk(a) - │ └── values - └── fast-path-unique-checks-item: uniq_overlaps_pk(c,d) - └── values + └── unique-checks + ├── unique-checks-item: uniq_overlaps_pk(b,c) + │ └── project + │ ├── columns: b:18!null c:19!null + │ └── semi-join (hash) + │ ├── columns: a:17!null b:18!null c:19!null d:20!null + │ ├── with-scan &1 + │ │ ├── columns: a:17!null b:18!null c:19!null d:20!null + │ │ └── mapping: + │ │ ├── column1:7 => a:17 + │ │ ├── column2:8 => b:18 + │ │ ├── column3:9 => c:19 + │ │ └── column4:10 => d:20 + │ ├── scan uniq_overlaps_pk + │ │ ├── columns: uniq_overlaps_pk.a:11!null uniq_overlaps_pk.b:12!null uniq_overlaps_pk.c:13 uniq_overlaps_pk.d:14 + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── b:18 = uniq_overlaps_pk.b:12 + │ ├── c:19 = uniq_overlaps_pk.c:13 + │ └── a:17 != uniq_overlaps_pk.a:11 + ├── unique-checks-item: uniq_overlaps_pk(a) + │ └── project + │ ├── columns: a:27!null + │ └── semi-join (hash) + │ ├── columns: a:27!null b:28!null c:29!null d:30!null + │ ├── with-scan &1 + │ │ ├── columns: a:27!null b:28!null c:29!null d:30!null + │ │ └── mapping: + │ │ ├── column1:7 => a:27 + │ │ ├── column2:8 => b:28 + │ │ ├── column3:9 => c:29 + │ │ └── column4:10 => d:30 + │ ├── scan uniq_overlaps_pk + │ │ ├── columns: uniq_overlaps_pk.a:21!null uniq_overlaps_pk.b:22!null uniq_overlaps_pk.c:23 uniq_overlaps_pk.d:24 + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── a:27 = uniq_overlaps_pk.a:21 + │ └── b:28 != uniq_overlaps_pk.b:22 + └── unique-checks-item: uniq_overlaps_pk(c,d) + └── project + ├── columns: c:39!null d:40!null + └── semi-join (hash) + ├── columns: a:37!null b:38!null c:39!null d:40!null + ├── with-scan &1 + │ ├── columns: a:37!null b:38!null c:39!null d:40!null + │ └── mapping: + │ ├── column1:7 => a:37 + │ ├── column2:8 => b:38 + │ ├── column3:9 => c:39 + │ └── column4:10 => d:40 + ├── scan uniq_overlaps_pk + │ ├── columns: uniq_overlaps_pk.a:31!null uniq_overlaps_pk.b:32!null uniq_overlaps_pk.c:33 uniq_overlaps_pk.d:34 + │ └── flags: disabled not visible index feature + └── filters + ├── c:39 = uniq_overlaps_pk.c:33 + ├── d:40 = uniq_overlaps_pk.d:34 + └── (a:37 != uniq_overlaps_pk.a:31) OR (b:38 != uniq_overlaps_pk.b:32) # Insert with non-constant input. # Add inequality filters for the primary key columns that are not part of each @@ -741,70 +707,63 @@ insert uniq_overlaps_pk │ ├── columns: k:7 v:8 x:10 y:11 │ └── scan other │ └── columns: k:7 v:8 w:9!null x:10 y:11 rowid:12!null other.crdb_internal_mvcc_timestamp:13 other.tableoid:14 - ├── unique-checks - │ ├── unique-checks-item: uniq_overlaps_pk(b,c) - │ │ └── project - │ │ ├── columns: b:22 c:23 - │ │ └── semi-join (hash) - │ │ ├── columns: a:21 b:22 c:23 d:24 - │ │ ├── with-scan &1 - │ │ │ ├── columns: a:21 b:22 c:23 d:24 - │ │ │ └── mapping: - │ │ │ ├── k:7 => a:21 - │ │ │ ├── v:8 => b:22 - │ │ │ ├── x:10 => c:23 - │ │ │ └── y:11 => d:24 - │ │ ├── scan uniq_overlaps_pk - │ │ │ ├── columns: uniq_overlaps_pk.a:15!null uniq_overlaps_pk.b:16!null uniq_overlaps_pk.c:17 uniq_overlaps_pk.d:18 - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── b:22 = uniq_overlaps_pk.b:16 - │ │ ├── c:23 = uniq_overlaps_pk.c:17 - │ │ └── a:21 != uniq_overlaps_pk.a:15 - │ ├── unique-checks-item: uniq_overlaps_pk(a) - │ │ └── project - │ │ ├── columns: a:31 - │ │ └── semi-join (hash) - │ │ ├── columns: a:31 b:32 c:33 d:34 - │ │ ├── with-scan &1 - │ │ │ ├── columns: a:31 b:32 c:33 d:34 - │ │ │ └── mapping: - │ │ │ ├── k:7 => a:31 - │ │ │ ├── v:8 => b:32 - │ │ │ ├── x:10 => c:33 - │ │ │ └── y:11 => d:34 - │ │ ├── scan uniq_overlaps_pk - │ │ │ ├── columns: uniq_overlaps_pk.a:25!null uniq_overlaps_pk.b:26!null uniq_overlaps_pk.c:27 uniq_overlaps_pk.d:28 - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── a:31 = uniq_overlaps_pk.a:25 - │ │ └── b:32 != uniq_overlaps_pk.b:26 - │ └── unique-checks-item: uniq_overlaps_pk(c,d) - │ └── project - │ ├── columns: c:43 d:44 - │ └── semi-join (hash) - │ ├── columns: a:41 b:42 c:43 d:44 - │ ├── with-scan &1 - │ │ ├── columns: a:41 b:42 c:43 d:44 - │ │ └── mapping: - │ │ ├── k:7 => a:41 - │ │ ├── v:8 => b:42 - │ │ ├── x:10 => c:43 - │ │ └── y:11 => d:44 - │ ├── scan uniq_overlaps_pk - │ │ ├── columns: uniq_overlaps_pk.a:35!null uniq_overlaps_pk.b:36!null uniq_overlaps_pk.c:37 uniq_overlaps_pk.d:38 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── c:43 = uniq_overlaps_pk.c:37 - │ ├── d:44 = uniq_overlaps_pk.d:38 - │ └── (a:41 != uniq_overlaps_pk.a:35) OR (b:42 != uniq_overlaps_pk.b:36) - └── fast-path-unique-checks - ├── fast-path-unique-checks-item: uniq_overlaps_pk(b,c) - │ └── values - ├── fast-path-unique-checks-item: uniq_overlaps_pk(a) - │ └── values - └── fast-path-unique-checks-item: uniq_overlaps_pk(c,d) - └── values + └── unique-checks + ├── unique-checks-item: uniq_overlaps_pk(b,c) + │ └── project + │ ├── columns: b:22 c:23 + │ └── semi-join (hash) + │ ├── columns: a:21 b:22 c:23 d:24 + │ ├── with-scan &1 + │ │ ├── columns: a:21 b:22 c:23 d:24 + │ │ └── mapping: + │ │ ├── k:7 => a:21 + │ │ ├── v:8 => b:22 + │ │ ├── x:10 => c:23 + │ │ └── y:11 => d:24 + │ ├── scan uniq_overlaps_pk + │ │ ├── columns: uniq_overlaps_pk.a:15!null uniq_overlaps_pk.b:16!null uniq_overlaps_pk.c:17 uniq_overlaps_pk.d:18 + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── b:22 = uniq_overlaps_pk.b:16 + │ ├── c:23 = uniq_overlaps_pk.c:17 + │ └── a:21 != uniq_overlaps_pk.a:15 + ├── unique-checks-item: uniq_overlaps_pk(a) + │ └── project + │ ├── columns: a:31 + │ └── semi-join (hash) + │ ├── columns: a:31 b:32 c:33 d:34 + │ ├── with-scan &1 + │ │ ├── columns: a:31 b:32 c:33 d:34 + │ │ └── mapping: + │ │ ├── k:7 => a:31 + │ │ ├── v:8 => b:32 + │ │ ├── x:10 => c:33 + │ │ └── y:11 => d:34 + │ ├── scan uniq_overlaps_pk + │ │ ├── columns: uniq_overlaps_pk.a:25!null uniq_overlaps_pk.b:26!null uniq_overlaps_pk.c:27 uniq_overlaps_pk.d:28 + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── a:31 = uniq_overlaps_pk.a:25 + │ └── b:32 != uniq_overlaps_pk.b:26 + └── unique-checks-item: uniq_overlaps_pk(c,d) + └── project + ├── columns: c:43 d:44 + └── semi-join (hash) + ├── columns: a:41 b:42 c:43 d:44 + ├── with-scan &1 + │ ├── columns: a:41 b:42 c:43 d:44 + │ └── mapping: + │ ├── k:7 => a:41 + │ ├── v:8 => b:42 + │ ├── x:10 => c:43 + │ └── y:11 => d:44 + ├── scan uniq_overlaps_pk + │ ├── columns: uniq_overlaps_pk.a:35!null uniq_overlaps_pk.b:36!null uniq_overlaps_pk.c:37 uniq_overlaps_pk.d:38 + │ └── flags: disabled not visible index feature + └── filters + ├── c:43 = uniq_overlaps_pk.c:37 + ├── d:44 = uniq_overlaps_pk.d:38 + └── (a:41 != uniq_overlaps_pk.a:35) OR (b:42 != uniq_overlaps_pk.b:36) exec-ddl CREATE TABLE uniq_hidden_pk ( @@ -840,74 +799,67 @@ insert uniq_hidden_pk │ │ └── (2, 2, 2, 2) │ └── projections │ └── unique_rowid() [as=rowid_default:12] - ├── unique-checks - │ ├── unique-checks-item: uniq_hidden_pk(b,c) - │ │ └── project - │ │ ├── columns: b:21!null c:22!null - │ │ └── semi-join (hash) - │ │ ├── columns: a:20!null b:21!null c:22!null d:23!null rowid:24 - │ │ ├── with-scan &1 - │ │ │ ├── columns: a:20!null b:21!null c:22!null d:23!null rowid:24 - │ │ │ └── mapping: - │ │ │ ├── column1:8 => a:20 - │ │ │ ├── column2:9 => b:21 - │ │ │ ├── column3:10 => c:22 - │ │ │ ├── column4:11 => d:23 - │ │ │ └── rowid_default:12 => rowid:24 - │ │ ├── scan uniq_hidden_pk - │ │ │ ├── columns: uniq_hidden_pk.a:13 uniq_hidden_pk.b:14 uniq_hidden_pk.c:15 uniq_hidden_pk.d:16 uniq_hidden_pk.rowid:17!null - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── b:21 = uniq_hidden_pk.b:14 - │ │ ├── c:22 = uniq_hidden_pk.c:15 - │ │ └── rowid:24 != uniq_hidden_pk.rowid:17 - │ ├── unique-checks-item: uniq_hidden_pk(a,b,d) - │ │ └── project - │ │ ├── columns: a:32!null b:33!null d:35!null - │ │ └── semi-join (hash) - │ │ ├── columns: a:32!null b:33!null c:34!null d:35!null rowid:36 - │ │ ├── with-scan &1 - │ │ │ ├── columns: a:32!null b:33!null c:34!null d:35!null rowid:36 - │ │ │ └── mapping: - │ │ │ ├── column1:8 => a:32 - │ │ │ ├── column2:9 => b:33 - │ │ │ ├── column3:10 => c:34 - │ │ │ ├── column4:11 => d:35 - │ │ │ └── rowid_default:12 => rowid:36 - │ │ ├── scan uniq_hidden_pk - │ │ │ ├── columns: uniq_hidden_pk.a:25 uniq_hidden_pk.b:26 uniq_hidden_pk.c:27 uniq_hidden_pk.d:28 uniq_hidden_pk.rowid:29!null - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── a:32 = uniq_hidden_pk.a:25 - │ │ ├── b:33 = uniq_hidden_pk.b:26 - │ │ ├── d:35 = uniq_hidden_pk.d:28 - │ │ └── rowid:36 != uniq_hidden_pk.rowid:29 - │ └── unique-checks-item: uniq_hidden_pk(a) - │ └── project - │ ├── columns: a:44!null - │ └── semi-join (hash) - │ ├── columns: a:44!null b:45!null c:46!null d:47!null rowid:48 - │ ├── with-scan &1 - │ │ ├── columns: a:44!null b:45!null c:46!null d:47!null rowid:48 - │ │ └── mapping: - │ │ ├── column1:8 => a:44 - │ │ ├── column2:9 => b:45 - │ │ ├── column3:10 => c:46 - │ │ ├── column4:11 => d:47 - │ │ └── rowid_default:12 => rowid:48 - │ ├── scan uniq_hidden_pk - │ │ ├── columns: uniq_hidden_pk.a:37 uniq_hidden_pk.b:38 uniq_hidden_pk.c:39 uniq_hidden_pk.d:40 uniq_hidden_pk.rowid:41!null - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── a:44 = uniq_hidden_pk.a:37 - │ └── rowid:48 != uniq_hidden_pk.rowid:41 - └── fast-path-unique-checks - ├── fast-path-unique-checks-item: uniq_hidden_pk(b,c) - │ └── values - ├── fast-path-unique-checks-item: uniq_hidden_pk(a,b,d) - │ └── values - └── fast-path-unique-checks-item: uniq_hidden_pk(a) - └── values + └── unique-checks + ├── unique-checks-item: uniq_hidden_pk(b,c) + │ └── project + │ ├── columns: b:21!null c:22!null + │ └── semi-join (hash) + │ ├── columns: a:20!null b:21!null c:22!null d:23!null rowid:24 + │ ├── with-scan &1 + │ │ ├── columns: a:20!null b:21!null c:22!null d:23!null rowid:24 + │ │ └── mapping: + │ │ ├── column1:8 => a:20 + │ │ ├── column2:9 => b:21 + │ │ ├── column3:10 => c:22 + │ │ ├── column4:11 => d:23 + │ │ └── rowid_default:12 => rowid:24 + │ ├── scan uniq_hidden_pk + │ │ ├── columns: uniq_hidden_pk.a:13 uniq_hidden_pk.b:14 uniq_hidden_pk.c:15 uniq_hidden_pk.d:16 uniq_hidden_pk.rowid:17!null + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── b:21 = uniq_hidden_pk.b:14 + │ ├── c:22 = uniq_hidden_pk.c:15 + │ └── rowid:24 != uniq_hidden_pk.rowid:17 + ├── unique-checks-item: uniq_hidden_pk(a,b,d) + │ └── project + │ ├── columns: a:32!null b:33!null d:35!null + │ └── semi-join (hash) + │ ├── columns: a:32!null b:33!null c:34!null d:35!null rowid:36 + │ ├── with-scan &1 + │ │ ├── columns: a:32!null b:33!null c:34!null d:35!null rowid:36 + │ │ └── mapping: + │ │ ├── column1:8 => a:32 + │ │ ├── column2:9 => b:33 + │ │ ├── column3:10 => c:34 + │ │ ├── column4:11 => d:35 + │ │ └── rowid_default:12 => rowid:36 + │ ├── scan uniq_hidden_pk + │ │ ├── columns: uniq_hidden_pk.a:25 uniq_hidden_pk.b:26 uniq_hidden_pk.c:27 uniq_hidden_pk.d:28 uniq_hidden_pk.rowid:29!null + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── a:32 = uniq_hidden_pk.a:25 + │ ├── b:33 = uniq_hidden_pk.b:26 + │ ├── d:35 = uniq_hidden_pk.d:28 + │ └── rowid:36 != uniq_hidden_pk.rowid:29 + └── unique-checks-item: uniq_hidden_pk(a) + └── project + ├── columns: a:44!null + └── semi-join (hash) + ├── columns: a:44!null b:45!null c:46!null d:47!null rowid:48 + ├── with-scan &1 + │ ├── columns: a:44!null b:45!null c:46!null d:47!null rowid:48 + │ └── mapping: + │ ├── column1:8 => a:44 + │ ├── column2:9 => b:45 + │ ├── column3:10 => c:46 + │ ├── column4:11 => d:47 + │ └── rowid_default:12 => rowid:48 + ├── scan uniq_hidden_pk + │ ├── columns: uniq_hidden_pk.a:37 uniq_hidden_pk.b:38 uniq_hidden_pk.c:39 uniq_hidden_pk.d:40 uniq_hidden_pk.rowid:41!null + │ └── flags: disabled not visible index feature + └── filters + ├── a:44 = uniq_hidden_pk.a:37 + └── rowid:48 != uniq_hidden_pk.rowid:41 # Insert with non-constant input. # Add inequality filters for the hidden primary key column. @@ -931,74 +883,67 @@ insert uniq_hidden_pk │ │ └── columns: k:8 v:9 w:10!null x:11 y:12 other.rowid:13!null other.crdb_internal_mvcc_timestamp:14 other.tableoid:15 │ └── projections │ └── unique_rowid() [as=rowid_default:16] - ├── unique-checks - │ ├── unique-checks-item: uniq_hidden_pk(b,c) - │ │ └── project - │ │ ├── columns: b:25 c:26 - │ │ └── semi-join (hash) - │ │ ├── columns: a:24 b:25 c:26 d:27 rowid:28 - │ │ ├── with-scan &1 - │ │ │ ├── columns: a:24 b:25 c:26 d:27 rowid:28 - │ │ │ └── mapping: - │ │ │ ├── k:8 => a:24 - │ │ │ ├── v:9 => b:25 - │ │ │ ├── x:11 => c:26 - │ │ │ ├── y:12 => d:27 - │ │ │ └── rowid_default:16 => rowid:28 - │ │ ├── scan uniq_hidden_pk - │ │ │ ├── columns: uniq_hidden_pk.a:17 uniq_hidden_pk.b:18 uniq_hidden_pk.c:19 uniq_hidden_pk.d:20 uniq_hidden_pk.rowid:21!null - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── b:25 = uniq_hidden_pk.b:18 - │ │ ├── c:26 = uniq_hidden_pk.c:19 - │ │ └── rowid:28 != uniq_hidden_pk.rowid:21 - │ ├── unique-checks-item: uniq_hidden_pk(a,b,d) - │ │ └── project - │ │ ├── columns: a:36 b:37 d:39 - │ │ └── semi-join (hash) - │ │ ├── columns: a:36 b:37 c:38 d:39 rowid:40 - │ │ ├── with-scan &1 - │ │ │ ├── columns: a:36 b:37 c:38 d:39 rowid:40 - │ │ │ └── mapping: - │ │ │ ├── k:8 => a:36 - │ │ │ ├── v:9 => b:37 - │ │ │ ├── x:11 => c:38 - │ │ │ ├── y:12 => d:39 - │ │ │ └── rowid_default:16 => rowid:40 - │ │ ├── scan uniq_hidden_pk - │ │ │ ├── columns: uniq_hidden_pk.a:29 uniq_hidden_pk.b:30 uniq_hidden_pk.c:31 uniq_hidden_pk.d:32 uniq_hidden_pk.rowid:33!null - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── a:36 = uniq_hidden_pk.a:29 - │ │ ├── b:37 = uniq_hidden_pk.b:30 - │ │ ├── d:39 = uniq_hidden_pk.d:32 - │ │ └── rowid:40 != uniq_hidden_pk.rowid:33 - │ └── unique-checks-item: uniq_hidden_pk(a) - │ └── project - │ ├── columns: a:48 - │ └── semi-join (hash) - │ ├── columns: a:48 b:49 c:50 d:51 rowid:52 - │ ├── with-scan &1 - │ │ ├── columns: a:48 b:49 c:50 d:51 rowid:52 - │ │ └── mapping: - │ │ ├── k:8 => a:48 - │ │ ├── v:9 => b:49 - │ │ ├── x:11 => c:50 - │ │ ├── y:12 => d:51 - │ │ └── rowid_default:16 => rowid:52 - │ ├── scan uniq_hidden_pk - │ │ ├── columns: uniq_hidden_pk.a:41 uniq_hidden_pk.b:42 uniq_hidden_pk.c:43 uniq_hidden_pk.d:44 uniq_hidden_pk.rowid:45!null - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── a:48 = uniq_hidden_pk.a:41 - │ └── rowid:52 != uniq_hidden_pk.rowid:45 - └── fast-path-unique-checks - ├── fast-path-unique-checks-item: uniq_hidden_pk(b,c) - │ └── values - ├── fast-path-unique-checks-item: uniq_hidden_pk(a,b,d) - │ └── values - └── fast-path-unique-checks-item: uniq_hidden_pk(a) - └── values + └── unique-checks + ├── unique-checks-item: uniq_hidden_pk(b,c) + │ └── project + │ ├── columns: b:25 c:26 + │ └── semi-join (hash) + │ ├── columns: a:24 b:25 c:26 d:27 rowid:28 + │ ├── with-scan &1 + │ │ ├── columns: a:24 b:25 c:26 d:27 rowid:28 + │ │ └── mapping: + │ │ ├── k:8 => a:24 + │ │ ├── v:9 => b:25 + │ │ ├── x:11 => c:26 + │ │ ├── y:12 => d:27 + │ │ └── rowid_default:16 => rowid:28 + │ ├── scan uniq_hidden_pk + │ │ ├── columns: uniq_hidden_pk.a:17 uniq_hidden_pk.b:18 uniq_hidden_pk.c:19 uniq_hidden_pk.d:20 uniq_hidden_pk.rowid:21!null + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── b:25 = uniq_hidden_pk.b:18 + │ ├── c:26 = uniq_hidden_pk.c:19 + │ └── rowid:28 != uniq_hidden_pk.rowid:21 + ├── unique-checks-item: uniq_hidden_pk(a,b,d) + │ └── project + │ ├── columns: a:36 b:37 d:39 + │ └── semi-join (hash) + │ ├── columns: a:36 b:37 c:38 d:39 rowid:40 + │ ├── with-scan &1 + │ │ ├── columns: a:36 b:37 c:38 d:39 rowid:40 + │ │ └── mapping: + │ │ ├── k:8 => a:36 + │ │ ├── v:9 => b:37 + │ │ ├── x:11 => c:38 + │ │ ├── y:12 => d:39 + │ │ └── rowid_default:16 => rowid:40 + │ ├── scan uniq_hidden_pk + │ │ ├── columns: uniq_hidden_pk.a:29 uniq_hidden_pk.b:30 uniq_hidden_pk.c:31 uniq_hidden_pk.d:32 uniq_hidden_pk.rowid:33!null + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── a:36 = uniq_hidden_pk.a:29 + │ ├── b:37 = uniq_hidden_pk.b:30 + │ ├── d:39 = uniq_hidden_pk.d:32 + │ └── rowid:40 != uniq_hidden_pk.rowid:33 + └── unique-checks-item: uniq_hidden_pk(a) + └── project + ├── columns: a:48 + └── semi-join (hash) + ├── columns: a:48 b:49 c:50 d:51 rowid:52 + ├── with-scan &1 + │ ├── columns: a:48 b:49 c:50 d:51 rowid:52 + │ └── mapping: + │ ├── k:8 => a:48 + │ ├── v:9 => b:49 + │ ├── x:11 => c:50 + │ ├── y:12 => d:51 + │ └── rowid_default:16 => rowid:52 + ├── scan uniq_hidden_pk + │ ├── columns: uniq_hidden_pk.a:41 uniq_hidden_pk.b:42 uniq_hidden_pk.c:43 uniq_hidden_pk.d:44 uniq_hidden_pk.rowid:45!null + │ └── flags: disabled not visible index feature + └── filters + ├── a:48 = uniq_hidden_pk.a:41 + └── rowid:52 != uniq_hidden_pk.rowid:45 exec-ddl CREATE TABLE uniq_partial ( @@ -1024,29 +969,26 @@ insert uniq_partial │ ├── columns: column1:6!null column2:7!null column3:8!null │ ├── (1, 1, 1) │ └── (2, 2, 2) - ├── unique-checks - │ └── unique-checks-item: uniq_partial(a) - │ └── project - │ ├── columns: a:15!null - │ └── semi-join (hash) - │ ├── columns: k:14!null a:15!null b:16!null - │ ├── with-scan &1 - │ │ ├── columns: k:14!null a:15!null b:16!null - │ │ └── mapping: - │ │ ├── column1:6 => k:14 - │ │ ├── column2:7 => a:15 - │ │ └── column3:8 => b:16 - │ ├── scan uniq_partial - │ │ ├── columns: uniq_partial.k:9!null uniq_partial.a:10 uniq_partial.b:11 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── a:15 = uniq_partial.a:10 - │ ├── b:16 > 0 - │ ├── uniq_partial.b:11 > 0 - │ └── k:14 != uniq_partial.k:9 - └── fast-path-unique-checks - └── fast-path-unique-checks-item: uniq_partial(a) - └── values + └── unique-checks + └── unique-checks-item: uniq_partial(a) + └── project + ├── columns: a:15!null + └── semi-join (hash) + ├── columns: k:14!null a:15!null b:16!null + ├── with-scan &1 + │ ├── columns: k:14!null a:15!null b:16!null + │ └── mapping: + │ ├── column1:6 => k:14 + │ ├── column2:7 => a:15 + │ └── column3:8 => b:16 + ├── scan uniq_partial + │ ├── columns: uniq_partial.k:9!null uniq_partial.a:10 uniq_partial.b:11 + │ └── flags: disabled not visible index feature + └── filters + ├── a:15 = uniq_partial.a:10 + ├── b:16 > 0 + ├── uniq_partial.b:11 > 0 + └── k:14 != uniq_partial.k:9 # Some of the inserted values have nulls. build @@ -1064,29 +1006,26 @@ insert uniq_partial │ ├── (1, 1, 1) │ ├── (2, 2, 2) │ └── (3, NULL::INT8, 3) - ├── unique-checks - │ └── unique-checks-item: uniq_partial(a) - │ └── project - │ ├── columns: a:15 - │ └── semi-join (hash) - │ ├── columns: k:14!null a:15 b:16!null - │ ├── with-scan &1 - │ │ ├── columns: k:14!null a:15 b:16!null - │ │ └── mapping: - │ │ ├── column1:6 => k:14 - │ │ ├── column2:7 => a:15 - │ │ └── column3:8 => b:16 - │ ├── scan uniq_partial - │ │ ├── columns: uniq_partial.k:9!null uniq_partial.a:10 uniq_partial.b:11 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── a:15 = uniq_partial.a:10 - │ ├── b:16 > 0 - │ ├── uniq_partial.b:11 > 0 - │ └── k:14 != uniq_partial.k:9 - └── fast-path-unique-checks - └── fast-path-unique-checks-item: uniq_partial(a) - └── values + └── unique-checks + └── unique-checks-item: uniq_partial(a) + └── project + ├── columns: a:15 + └── semi-join (hash) + ├── columns: k:14!null a:15 b:16!null + ├── with-scan &1 + │ ├── columns: k:14!null a:15 b:16!null + │ └── mapping: + │ ├── column1:6 => k:14 + │ ├── column2:7 => a:15 + │ └── column3:8 => b:16 + ├── scan uniq_partial + │ ├── columns: uniq_partial.k:9!null uniq_partial.a:10 uniq_partial.b:11 + │ └── flags: disabled not visible index feature + └── filters + ├── a:15 = uniq_partial.a:10 + ├── b:16 > 0 + ├── uniq_partial.b:11 > 0 + └── k:14 != uniq_partial.k:9 # No need to plan checks for a since it's always null. # NOTE: We use the norm directive here so that assignment casts are eliminated @@ -1234,29 +1173,26 @@ insert uniq_partial │ ├── columns: other.k:6 v:7 w:8!null │ └── scan other │ └── columns: other.k:6 v:7 w:8!null x:9 y:10 rowid:11!null other.crdb_internal_mvcc_timestamp:12 other.tableoid:13 - ├── unique-checks - │ └── unique-checks-item: uniq_partial(a) - │ └── project - │ ├── columns: a:20 - │ └── semi-join (hash) - │ ├── columns: k:19 a:20 b:21!null - │ ├── with-scan &1 - │ │ ├── columns: k:19 a:20 b:21!null - │ │ └── mapping: - │ │ ├── other.k:6 => k:19 - │ │ ├── v:7 => a:20 - │ │ └── w:8 => b:21 - │ ├── scan uniq_partial - │ │ ├── columns: uniq_partial.k:14!null uniq_partial.a:15 uniq_partial.b:16 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── a:20 = uniq_partial.a:15 - │ ├── b:21 > 0 - │ ├── uniq_partial.b:16 > 0 - │ └── k:19 != uniq_partial.k:14 - └── fast-path-unique-checks - └── fast-path-unique-checks-item: uniq_partial(a) - └── values + └── unique-checks + └── unique-checks-item: uniq_partial(a) + └── project + ├── columns: a:20 + └── semi-join (hash) + ├── columns: k:19 a:20 b:21!null + ├── with-scan &1 + │ ├── columns: k:19 a:20 b:21!null + │ └── mapping: + │ ├── other.k:6 => k:19 + │ ├── v:7 => a:20 + │ └── w:8 => b:21 + ├── scan uniq_partial + │ ├── columns: uniq_partial.k:14!null uniq_partial.a:15 uniq_partial.b:16 + │ └── flags: disabled not visible index feature + └── filters + ├── a:20 = uniq_partial.a:15 + ├── b:21 > 0 + ├── uniq_partial.b:16 > 0 + └── k:19 != uniq_partial.k:14 exec-ddl CREATE TABLE uniq_partial_overlaps_pk ( @@ -1291,75 +1227,68 @@ insert uniq_partial_overlaps_pk │ ├── columns: column1:7!null column2:8!null column3:9!null column4:10!null │ ├── (1, 1, 1, 1) │ └── (2, 2, 2, 2) - ├── unique-checks - │ ├── unique-checks-item: uniq_partial_overlaps_pk(c) - │ │ └── project - │ │ ├── columns: c:19!null - │ │ └── semi-join (hash) - │ │ ├── columns: a:17!null b:18!null c:19!null d:20!null - │ │ ├── with-scan &1 - │ │ │ ├── columns: a:17!null b:18!null c:19!null d:20!null - │ │ │ └── mapping: - │ │ │ ├── column1:7 => a:17 - │ │ │ ├── column2:8 => b:18 - │ │ │ ├── column3:9 => c:19 - │ │ │ └── column4:10 => d:20 - │ │ ├── scan uniq_partial_overlaps_pk - │ │ │ ├── columns: uniq_partial_overlaps_pk.a:11!null uniq_partial_overlaps_pk.b:12!null uniq_partial_overlaps_pk.c:13 uniq_partial_overlaps_pk.d:14 - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── c:19 = uniq_partial_overlaps_pk.c:13 - │ │ ├── d:20 > 0 - │ │ ├── uniq_partial_overlaps_pk.d:14 > 0 - │ │ └── (a:17 != uniq_partial_overlaps_pk.a:11) OR (b:18 != uniq_partial_overlaps_pk.b:12) - │ ├── unique-checks-item: uniq_partial_overlaps_pk(a) - │ │ └── project - │ │ ├── columns: a:27!null - │ │ └── semi-join (hash) - │ │ ├── columns: a:27!null b:28!null c:29!null d:30!null - │ │ ├── with-scan &1 - │ │ │ ├── columns: a:27!null b:28!null c:29!null d:30!null - │ │ │ └── mapping: - │ │ │ ├── column1:7 => a:27 - │ │ │ ├── column2:8 => b:28 - │ │ │ ├── column3:9 => c:29 - │ │ │ └── column4:10 => d:30 - │ │ ├── scan uniq_partial_overlaps_pk - │ │ │ ├── columns: uniq_partial_overlaps_pk.a:21!null uniq_partial_overlaps_pk.b:22!null uniq_partial_overlaps_pk.c:23 uniq_partial_overlaps_pk.d:24 - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── a:27 = uniq_partial_overlaps_pk.a:21 - │ │ ├── d:30 > 0 - │ │ ├── uniq_partial_overlaps_pk.d:24 > 0 - │ │ └── b:28 != uniq_partial_overlaps_pk.b:22 - │ └── unique-checks-item: uniq_partial_overlaps_pk(b,c) - │ └── project - │ ├── columns: b:38!null c:39!null - │ └── semi-join (hash) - │ ├── columns: a:37!null b:38!null c:39!null d:40!null - │ ├── with-scan &1 - │ │ ├── columns: a:37!null b:38!null c:39!null d:40!null - │ │ └── mapping: - │ │ ├── column1:7 => a:37 - │ │ ├── column2:8 => b:38 - │ │ ├── column3:9 => c:39 - │ │ └── column4:10 => d:40 - │ ├── scan uniq_partial_overlaps_pk - │ │ ├── columns: uniq_partial_overlaps_pk.a:31!null uniq_partial_overlaps_pk.b:32!null uniq_partial_overlaps_pk.c:33 uniq_partial_overlaps_pk.d:34 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── b:38 = uniq_partial_overlaps_pk.b:32 - │ ├── c:39 = uniq_partial_overlaps_pk.c:33 - │ ├── d:40 > 0 - │ ├── uniq_partial_overlaps_pk.d:34 > 0 - │ └── a:37 != uniq_partial_overlaps_pk.a:31 - └── fast-path-unique-checks - ├── fast-path-unique-checks-item: uniq_partial_overlaps_pk(c) - │ └── values - ├── fast-path-unique-checks-item: uniq_partial_overlaps_pk(a) - │ └── values - └── fast-path-unique-checks-item: uniq_partial_overlaps_pk(b,c) - └── values + └── unique-checks + ├── unique-checks-item: uniq_partial_overlaps_pk(c) + │ └── project + │ ├── columns: c:19!null + │ └── semi-join (hash) + │ ├── columns: a:17!null b:18!null c:19!null d:20!null + │ ├── with-scan &1 + │ │ ├── columns: a:17!null b:18!null c:19!null d:20!null + │ │ └── mapping: + │ │ ├── column1:7 => a:17 + │ │ ├── column2:8 => b:18 + │ │ ├── column3:9 => c:19 + │ │ └── column4:10 => d:20 + │ ├── scan uniq_partial_overlaps_pk + │ │ ├── columns: uniq_partial_overlaps_pk.a:11!null uniq_partial_overlaps_pk.b:12!null uniq_partial_overlaps_pk.c:13 uniq_partial_overlaps_pk.d:14 + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── c:19 = uniq_partial_overlaps_pk.c:13 + │ ├── d:20 > 0 + │ ├── uniq_partial_overlaps_pk.d:14 > 0 + │ └── (a:17 != uniq_partial_overlaps_pk.a:11) OR (b:18 != uniq_partial_overlaps_pk.b:12) + ├── unique-checks-item: uniq_partial_overlaps_pk(a) + │ └── project + │ ├── columns: a:27!null + │ └── semi-join (hash) + │ ├── columns: a:27!null b:28!null c:29!null d:30!null + │ ├── with-scan &1 + │ │ ├── columns: a:27!null b:28!null c:29!null d:30!null + │ │ └── mapping: + │ │ ├── column1:7 => a:27 + │ │ ├── column2:8 => b:28 + │ │ ├── column3:9 => c:29 + │ │ └── column4:10 => d:30 + │ ├── scan uniq_partial_overlaps_pk + │ │ ├── columns: uniq_partial_overlaps_pk.a:21!null uniq_partial_overlaps_pk.b:22!null uniq_partial_overlaps_pk.c:23 uniq_partial_overlaps_pk.d:24 + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── a:27 = uniq_partial_overlaps_pk.a:21 + │ ├── d:30 > 0 + │ ├── uniq_partial_overlaps_pk.d:24 > 0 + │ └── b:28 != uniq_partial_overlaps_pk.b:22 + └── unique-checks-item: uniq_partial_overlaps_pk(b,c) + └── project + ├── columns: b:38!null c:39!null + └── semi-join (hash) + ├── columns: a:37!null b:38!null c:39!null d:40!null + ├── with-scan &1 + │ ├── columns: a:37!null b:38!null c:39!null d:40!null + │ └── mapping: + │ ├── column1:7 => a:37 + │ ├── column2:8 => b:38 + │ ├── column3:9 => c:39 + │ └── column4:10 => d:40 + ├── scan uniq_partial_overlaps_pk + │ ├── columns: uniq_partial_overlaps_pk.a:31!null uniq_partial_overlaps_pk.b:32!null uniq_partial_overlaps_pk.c:33 uniq_partial_overlaps_pk.d:34 + │ └── flags: disabled not visible index feature + └── filters + ├── b:38 = uniq_partial_overlaps_pk.b:32 + ├── c:39 = uniq_partial_overlaps_pk.c:33 + ├── d:40 > 0 + ├── uniq_partial_overlaps_pk.d:34 > 0 + └── a:37 != uniq_partial_overlaps_pk.a:31 # Insert with non-constant input. # Do not build uniqueness checks when the primary key columns are a subset of @@ -1379,75 +1308,68 @@ insert uniq_partial_overlaps_pk │ ├── columns: k:7 v:8 x:10 y:11 │ └── scan other │ └── columns: k:7 v:8 w:9!null x:10 y:11 rowid:12!null other.crdb_internal_mvcc_timestamp:13 other.tableoid:14 - ├── unique-checks - │ ├── unique-checks-item: uniq_partial_overlaps_pk(c) - │ │ └── project - │ │ ├── columns: c:23 - │ │ └── semi-join (hash) - │ │ ├── columns: a:21 b:22 c:23 d:24 - │ │ ├── with-scan &1 - │ │ │ ├── columns: a:21 b:22 c:23 d:24 - │ │ │ └── mapping: - │ │ │ ├── k:7 => a:21 - │ │ │ ├── v:8 => b:22 - │ │ │ ├── x:10 => c:23 - │ │ │ └── y:11 => d:24 - │ │ ├── scan uniq_partial_overlaps_pk - │ │ │ ├── columns: uniq_partial_overlaps_pk.a:15!null uniq_partial_overlaps_pk.b:16!null uniq_partial_overlaps_pk.c:17 uniq_partial_overlaps_pk.d:18 - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── c:23 = uniq_partial_overlaps_pk.c:17 - │ │ ├── d:24 > 0 - │ │ ├── uniq_partial_overlaps_pk.d:18 > 0 - │ │ └── (a:21 != uniq_partial_overlaps_pk.a:15) OR (b:22 != uniq_partial_overlaps_pk.b:16) - │ ├── unique-checks-item: uniq_partial_overlaps_pk(a) - │ │ └── project - │ │ ├── columns: a:31 - │ │ └── semi-join (hash) - │ │ ├── columns: a:31 b:32 c:33 d:34 - │ │ ├── with-scan &1 - │ │ │ ├── columns: a:31 b:32 c:33 d:34 - │ │ │ └── mapping: - │ │ │ ├── k:7 => a:31 - │ │ │ ├── v:8 => b:32 - │ │ │ ├── x:10 => c:33 - │ │ │ └── y:11 => d:34 - │ │ ├── scan uniq_partial_overlaps_pk - │ │ │ ├── columns: uniq_partial_overlaps_pk.a:25!null uniq_partial_overlaps_pk.b:26!null uniq_partial_overlaps_pk.c:27 uniq_partial_overlaps_pk.d:28 - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── a:31 = uniq_partial_overlaps_pk.a:25 - │ │ ├── d:34 > 0 - │ │ ├── uniq_partial_overlaps_pk.d:28 > 0 - │ │ └── b:32 != uniq_partial_overlaps_pk.b:26 - │ └── unique-checks-item: uniq_partial_overlaps_pk(b,c) - │ └── project - │ ├── columns: b:42 c:43 - │ └── semi-join (hash) - │ ├── columns: a:41 b:42 c:43 d:44 - │ ├── with-scan &1 - │ │ ├── columns: a:41 b:42 c:43 d:44 - │ │ └── mapping: - │ │ ├── k:7 => a:41 - │ │ ├── v:8 => b:42 - │ │ ├── x:10 => c:43 - │ │ └── y:11 => d:44 - │ ├── scan uniq_partial_overlaps_pk - │ │ ├── columns: uniq_partial_overlaps_pk.a:35!null uniq_partial_overlaps_pk.b:36!null uniq_partial_overlaps_pk.c:37 uniq_partial_overlaps_pk.d:38 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── b:42 = uniq_partial_overlaps_pk.b:36 - │ ├── c:43 = uniq_partial_overlaps_pk.c:37 - │ ├── d:44 > 0 - │ ├── uniq_partial_overlaps_pk.d:38 > 0 - │ └── a:41 != uniq_partial_overlaps_pk.a:35 - └── fast-path-unique-checks - ├── fast-path-unique-checks-item: uniq_partial_overlaps_pk(c) - │ └── values - ├── fast-path-unique-checks-item: uniq_partial_overlaps_pk(a) - │ └── values - └── fast-path-unique-checks-item: uniq_partial_overlaps_pk(b,c) - └── values + └── unique-checks + ├── unique-checks-item: uniq_partial_overlaps_pk(c) + │ └── project + │ ├── columns: c:23 + │ └── semi-join (hash) + │ ├── columns: a:21 b:22 c:23 d:24 + │ ├── with-scan &1 + │ │ ├── columns: a:21 b:22 c:23 d:24 + │ │ └── mapping: + │ │ ├── k:7 => a:21 + │ │ ├── v:8 => b:22 + │ │ ├── x:10 => c:23 + │ │ └── y:11 => d:24 + │ ├── scan uniq_partial_overlaps_pk + │ │ ├── columns: uniq_partial_overlaps_pk.a:15!null uniq_partial_overlaps_pk.b:16!null uniq_partial_overlaps_pk.c:17 uniq_partial_overlaps_pk.d:18 + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── c:23 = uniq_partial_overlaps_pk.c:17 + │ ├── d:24 > 0 + │ ├── uniq_partial_overlaps_pk.d:18 > 0 + │ └── (a:21 != uniq_partial_overlaps_pk.a:15) OR (b:22 != uniq_partial_overlaps_pk.b:16) + ├── unique-checks-item: uniq_partial_overlaps_pk(a) + │ └── project + │ ├── columns: a:31 + │ └── semi-join (hash) + │ ├── columns: a:31 b:32 c:33 d:34 + │ ├── with-scan &1 + │ │ ├── columns: a:31 b:32 c:33 d:34 + │ │ └── mapping: + │ │ ├── k:7 => a:31 + │ │ ├── v:8 => b:32 + │ │ ├── x:10 => c:33 + │ │ └── y:11 => d:34 + │ ├── scan uniq_partial_overlaps_pk + │ │ ├── columns: uniq_partial_overlaps_pk.a:25!null uniq_partial_overlaps_pk.b:26!null uniq_partial_overlaps_pk.c:27 uniq_partial_overlaps_pk.d:28 + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── a:31 = uniq_partial_overlaps_pk.a:25 + │ ├── d:34 > 0 + │ ├── uniq_partial_overlaps_pk.d:28 > 0 + │ └── b:32 != uniq_partial_overlaps_pk.b:26 + └── unique-checks-item: uniq_partial_overlaps_pk(b,c) + └── project + ├── columns: b:42 c:43 + └── semi-join (hash) + ├── columns: a:41 b:42 c:43 d:44 + ├── with-scan &1 + │ ├── columns: a:41 b:42 c:43 d:44 + │ └── mapping: + │ ├── k:7 => a:41 + │ ├── v:8 => b:42 + │ ├── x:10 => c:43 + │ └── y:11 => d:44 + ├── scan uniq_partial_overlaps_pk + │ ├── columns: uniq_partial_overlaps_pk.a:35!null uniq_partial_overlaps_pk.b:36!null uniq_partial_overlaps_pk.c:37 uniq_partial_overlaps_pk.d:38 + │ └── flags: disabled not visible index feature + └── filters + ├── b:42 = uniq_partial_overlaps_pk.b:36 + ├── c:43 = uniq_partial_overlaps_pk.c:37 + ├── d:44 > 0 + ├── uniq_partial_overlaps_pk.d:38 > 0 + └── a:41 != uniq_partial_overlaps_pk.a:35 exec-ddl CREATE TABLE uniq_partial_hidden_pk ( @@ -1480,30 +1402,27 @@ insert uniq_partial_hidden_pk │ └── projections │ ├── NULL::INT8 [as=c_default:9] │ └── unique_rowid() [as=rowid_default:10] - ├── unique-checks - │ └── unique-checks-item: uniq_partial_hidden_pk(b) - │ └── project - │ ├── columns: b:18!null - │ └── semi-join (hash) - │ ├── columns: a:17!null b:18!null c:19 rowid:20 - │ ├── with-scan &1 - │ │ ├── columns: a:17!null b:18!null c:19 rowid:20 - │ │ └── mapping: - │ │ ├── column1:7 => a:17 - │ │ ├── column2:8 => b:18 - │ │ ├── c_default:9 => c:19 - │ │ └── rowid_default:10 => rowid:20 - │ ├── scan uniq_partial_hidden_pk - │ │ ├── columns: uniq_partial_hidden_pk.a:11 uniq_partial_hidden_pk.b:12 uniq_partial_hidden_pk.c:13 uniq_partial_hidden_pk.rowid:14!null - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── b:18 = uniq_partial_hidden_pk.b:12 - │ ├── c:19 > 0 - │ ├── uniq_partial_hidden_pk.c:13 > 0 - │ └── rowid:20 != uniq_partial_hidden_pk.rowid:14 - └── fast-path-unique-checks - └── fast-path-unique-checks-item: uniq_partial_hidden_pk(b) - └── values + └── unique-checks + └── unique-checks-item: uniq_partial_hidden_pk(b) + └── project + ├── columns: b:18!null + └── semi-join (hash) + ├── columns: a:17!null b:18!null c:19 rowid:20 + ├── with-scan &1 + │ ├── columns: a:17!null b:18!null c:19 rowid:20 + │ └── mapping: + │ ├── column1:7 => a:17 + │ ├── column2:8 => b:18 + │ ├── c_default:9 => c:19 + │ └── rowid_default:10 => rowid:20 + ├── scan uniq_partial_hidden_pk + │ ├── columns: uniq_partial_hidden_pk.a:11 uniq_partial_hidden_pk.b:12 uniq_partial_hidden_pk.c:13 uniq_partial_hidden_pk.rowid:14!null + │ └── flags: disabled not visible index feature + └── filters + ├── b:18 = uniq_partial_hidden_pk.b:12 + ├── c:19 > 0 + ├── uniq_partial_hidden_pk.c:13 > 0 + └── rowid:20 != uniq_partial_hidden_pk.rowid:14 # Add inequality filters for the hidden primary key column. build @@ -1526,30 +1445,27 @@ insert uniq_partial_hidden_pk │ └── projections │ ├── NULL::INT8 [as=c_default:15] │ └── unique_rowid() [as=rowid_default:16] - ├── unique-checks - │ └── unique-checks-item: uniq_partial_hidden_pk(b) - │ └── project - │ ├── columns: b:24 - │ └── semi-join (hash) - │ ├── columns: a:23 b:24 c:25 rowid:26 - │ ├── with-scan &1 - │ │ ├── columns: a:23 b:24 c:25 rowid:26 - │ │ └── mapping: - │ │ ├── k:7 => a:23 - │ │ ├── v:8 => b:24 - │ │ ├── c_default:15 => c:25 - │ │ └── rowid_default:16 => rowid:26 - │ ├── scan uniq_partial_hidden_pk - │ │ ├── columns: uniq_partial_hidden_pk.a:17 uniq_partial_hidden_pk.b:18 uniq_partial_hidden_pk.c:19 uniq_partial_hidden_pk.rowid:20!null - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── b:24 = uniq_partial_hidden_pk.b:18 - │ ├── c:25 > 0 - │ ├── uniq_partial_hidden_pk.c:19 > 0 - │ └── rowid:26 != uniq_partial_hidden_pk.rowid:20 - └── fast-path-unique-checks - └── fast-path-unique-checks-item: uniq_partial_hidden_pk(b) - └── values + └── unique-checks + └── unique-checks-item: uniq_partial_hidden_pk(b) + └── project + ├── columns: b:24 + └── semi-join (hash) + ├── columns: a:23 b:24 c:25 rowid:26 + ├── with-scan &1 + │ ├── columns: a:23 b:24 c:25 rowid:26 + │ └── mapping: + │ ├── k:7 => a:23 + │ ├── v:8 => b:24 + │ ├── c_default:15 => c:25 + │ └── rowid_default:16 => rowid:26 + ├── scan uniq_partial_hidden_pk + │ ├── columns: uniq_partial_hidden_pk.a:17 uniq_partial_hidden_pk.b:18 uniq_partial_hidden_pk.c:19 uniq_partial_hidden_pk.rowid:20!null + │ └── flags: disabled not visible index feature + └── filters + ├── b:24 = uniq_partial_hidden_pk.b:18 + ├── c:25 > 0 + ├── uniq_partial_hidden_pk.c:19 > 0 + └── rowid:26 != uniq_partial_hidden_pk.rowid:20 exec-ddl CREATE TABLE uniq_partial_constraint_and_index ( @@ -1602,13 +1518,10 @@ insert uniq_partial_constraint_and_index │ │ └── filters (true) │ └── projections │ └── true [as=partial_index_put1:15] - ├── unique-checks - │ └── unique-checks-item: uniq_partial_constraint_and_index(a) - │ └── values - │ └── columns: a:22!null - └── fast-path-unique-checks - └── fast-path-unique-checks-item: uniq_partial_constraint_and_index(a) + └── unique-checks + └── unique-checks-item: uniq_partial_constraint_and_index(a) └── values + └── columns: a:22!null exec-ddl CREATE TABLE uniq_constraint_and_partial_index ( @@ -1791,44 +1704,41 @@ insert uniq_computed_pk │ └── projections │ ├── CASE WHEN column1:10 < 0 THEN 'foo' ELSE 'bar' END [as=c_i_expr_comp:13] │ └── column3:12::STRING [as=c_d_expr_comp:14] - ├── unique-checks - │ └── unique-checks-item: uniq_computed_pk(d) - │ └── project - │ ├── columns: d:44!null - │ └── semi-join (hash) - │ ├── columns: i:42!null s:43!null d:44!null c_i_expr:45!null c_s:46!null c_d:47!null c_d_expr:48!null - │ ├── with-scan &1 - │ │ ├── columns: i:42!null s:43!null d:44!null c_i_expr:45!null c_s:46!null c_d:47!null c_d_expr:48!null - │ │ └── mapping: - │ │ ├── column1:10 => i:42 - │ │ ├── column2:11 => s:43 - │ │ ├── column3:12 => d:44 - │ │ ├── c_i_expr_comp:13 => c_i_expr:45 - │ │ ├── column2:11 => c_s:46 - │ │ ├── column3:12 => c_d:47 - │ │ └── c_d_expr_comp:14 => c_d_expr:48 - │ ├── project - │ │ ├── columns: uniq_computed_pk.c_s:37 uniq_computed_pk.i:33!null uniq_computed_pk.s:34 uniq_computed_pk.d:35 uniq_computed_pk.c_i_expr:36!null uniq_computed_pk.c_d:38 uniq_computed_pk.c_d_expr:39 - │ │ ├── scan uniq_computed_pk - │ │ │ ├── columns: uniq_computed_pk.i:33!null uniq_computed_pk.s:34 uniq_computed_pk.d:35 uniq_computed_pk.c_i_expr:36!null uniq_computed_pk.c_d:38 uniq_computed_pk.c_d_expr:39 - │ │ │ ├── computed column expressions - │ │ │ │ ├── uniq_computed_pk.c_i_expr:36 - │ │ │ │ │ └── CASE WHEN uniq_computed_pk.i:33 < 0 THEN 'foo' ELSE 'bar' END - │ │ │ │ ├── uniq_computed_pk.c_s:37 - │ │ │ │ │ └── uniq_computed_pk.s:34 - │ │ │ │ ├── uniq_computed_pk.c_d:38 - │ │ │ │ │ └── uniq_computed_pk.d:35 - │ │ │ │ └── uniq_computed_pk.c_d_expr:39 - │ │ │ │ └── uniq_computed_pk.d:35::STRING - │ │ │ └── flags: disabled not visible index feature - │ │ └── projections - │ │ └── uniq_computed_pk.s:34 [as=uniq_computed_pk.c_s:37] - │ └── filters - │ ├── d:44 = uniq_computed_pk.d:35 - │ └── (i:42 != uniq_computed_pk.i:33) OR (c_i_expr:45 != uniq_computed_pk.c_i_expr:36) - └── fast-path-unique-checks - └── fast-path-unique-checks-item: uniq_computed_pk(d) - └── values + └── unique-checks + └── unique-checks-item: uniq_computed_pk(d) + └── project + ├── columns: d:44!null + └── semi-join (hash) + ├── columns: i:42!null s:43!null d:44!null c_i_expr:45!null c_s:46!null c_d:47!null c_d_expr:48!null + ├── with-scan &1 + │ ├── columns: i:42!null s:43!null d:44!null c_i_expr:45!null c_s:46!null c_d:47!null c_d_expr:48!null + │ └── mapping: + │ ├── column1:10 => i:42 + │ ├── column2:11 => s:43 + │ ├── column3:12 => d:44 + │ ├── c_i_expr_comp:13 => c_i_expr:45 + │ ├── column2:11 => c_s:46 + │ ├── column3:12 => c_d:47 + │ └── c_d_expr_comp:14 => c_d_expr:48 + ├── project + │ ├── columns: uniq_computed_pk.c_s:37 uniq_computed_pk.i:33!null uniq_computed_pk.s:34 uniq_computed_pk.d:35 uniq_computed_pk.c_i_expr:36!null uniq_computed_pk.c_d:38 uniq_computed_pk.c_d_expr:39 + │ ├── scan uniq_computed_pk + │ │ ├── columns: uniq_computed_pk.i:33!null uniq_computed_pk.s:34 uniq_computed_pk.d:35 uniq_computed_pk.c_i_expr:36!null uniq_computed_pk.c_d:38 uniq_computed_pk.c_d_expr:39 + │ │ ├── computed column expressions + │ │ │ ├── uniq_computed_pk.c_i_expr:36 + │ │ │ │ └── CASE WHEN uniq_computed_pk.i:33 < 0 THEN 'foo' ELSE 'bar' END + │ │ │ ├── uniq_computed_pk.c_s:37 + │ │ │ │ └── uniq_computed_pk.s:34 + │ │ │ ├── uniq_computed_pk.c_d:38 + │ │ │ │ └── uniq_computed_pk.d:35 + │ │ │ └── uniq_computed_pk.c_d_expr:39 + │ │ │ └── uniq_computed_pk.d:35::STRING + │ │ └── flags: disabled not visible index feature + │ └── projections + │ └── uniq_computed_pk.s:34 [as=uniq_computed_pk.c_s:37] + └── filters + ├── d:44 = uniq_computed_pk.d:35 + └── (i:42 != uniq_computed_pk.i:33) OR (c_i_expr:45 != uniq_computed_pk.c_i_expr:36) exec-ddl CREATE TABLE uniq_default ( @@ -1920,31 +1830,28 @@ insert t │ │ └── column2:8 IN ('east', 'west') [as=check1:11] │ └── projections │ └── column1:7 != 1 [as=partial_index_put1:12] - ├── unique-checks - │ └── unique-checks-item: t(a) - │ └── project - │ ├── columns: a:21!null - │ └── semi-join (hash) - │ ├── columns: k:19!null r:20!null a:21!null b:22!null - │ ├── values - │ │ ├── columns: k:19!null r:20!null a:21!null b:22!null - │ │ └── (1, 'east', 10, 100) - │ ├── scan t - │ │ ├── columns: t.k:13!null t.r:14!null t.a:15 t.b:16 - │ │ ├── check constraint expressions - │ │ │ └── t.r:14 IN ('east', 'west') - │ │ ├── partial index predicates - │ │ │ └── t_r_a_idx: filters - │ │ │ └── t.k:13 != 1 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── a:21 = t.a:15 - │ ├── k:19 != 1 - │ ├── t.k:13 != 1 - │ └── k:19 != t.k:13 - └── fast-path-unique-checks - └── fast-path-unique-checks-item: t(a) - └── values + └── unique-checks + └── unique-checks-item: t(a) + └── project + ├── columns: a:21!null + └── semi-join (hash) + ├── columns: k:19!null r:20!null a:21!null b:22!null + ├── values + │ ├── columns: k:19!null r:20!null a:21!null b:22!null + │ └── (1, 'east', 10, 100) + ├── scan t + │ ├── columns: t.k:13!null t.r:14!null t.a:15 t.b:16 + │ ├── check constraint expressions + │ │ └── t.r:14 IN ('east', 'west') + │ ├── partial index predicates + │ │ └── t_r_a_idx: filters + │ │ └── t.k:13 != 1 + │ └── flags: disabled not visible index feature + └── filters + ├── a:21 = t.a:15 + ├── k:19 != 1 + ├── t.k:13 != 1 + └── k:19 != t.k:13 exec-ddl DROP TABLE t @@ -2070,69 +1977,53 @@ insert t │ │ └── column1:7 % 9 [as=b_comp:10] │ └── projections │ └── column2:8 IN ('east', 'west') [as=check1:11] - ├── unique-checks - │ ├── unique-checks-item: t(a) - │ │ └── project - │ │ ├── columns: a:20!null - │ │ └── semi-join (hash) - │ │ ├── columns: k:18!null r:19!null a:20!null b:21!null - │ │ ├── with-scan &1 - │ │ │ ├── columns: k:18!null r:19!null a:20!null b:21!null - │ │ │ └── mapping: - │ │ │ ├── column1:7 => k:18 - │ │ │ ├── column2:8 => r:19 - │ │ │ ├── column3:9 => a:20 - │ │ │ └── b_comp:10 => b:21 - │ │ ├── scan t - │ │ │ ├── columns: t.k:12!null t.r:13!null t.a:14 t.b:15 - │ │ │ ├── check constraint expressions - │ │ │ │ └── t.r:13 IN ('east', 'west') - │ │ │ ├── computed column expressions - │ │ │ │ └── t.b:15 - │ │ │ │ └── t.k:12 % 9 - │ │ │ └── flags: disabled not visible index feature - │ │ └── filters - │ │ ├── a:20 = t.a:14 - │ │ └── k:18 != t.k:12 - │ └── unique-checks-item: t(b) - │ └── project - │ ├── columns: b:37!null - │ └── semi-join (hash) - │ ├── columns: k:34!null r:35!null a:36!null b:37!null - │ ├── with-scan &1 - │ │ ├── columns: k:34!null r:35!null a:36!null b:37!null - │ │ └── mapping: - │ │ ├── column1:7 => k:34 - │ │ ├── column2:8 => r:35 - │ │ ├── column3:9 => a:36 - │ │ └── b_comp:10 => b:37 - │ ├── scan t - │ │ ├── columns: t.k:28!null t.r:29!null t.a:30 t.b:31 - │ │ ├── check constraint expressions - │ │ │ └── t.r:29 IN ('east', 'west') - │ │ ├── computed column expressions - │ │ │ └── t.b:31 - │ │ │ └── t.k:28 % 9 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ ├── b:37 = t.b:31 - │ └── k:34 != t.k:28 - └── fast-path-unique-checks - ├── fast-path-unique-checks-item: t(a) - │ └── select - │ ├── columns: t.k:22!null t.r:23!null t.a:24!null t.b:25 - │ ├── scan t - │ │ ├── columns: t.k:22!null t.r:23!null t.a:24 t.b:25 - │ │ ├── check constraint expressions - │ │ │ └── t.r:23 IN ('east', 'west') - │ │ ├── computed column expressions - │ │ │ └── t.b:25 - │ │ │ └── t.k:22 % 9 - │ │ └── flags: disabled not visible index feature - │ └── filters - │ └── t.a:24 = 10 - └── fast-path-unique-checks-item: t(b) - └── values + └── unique-checks + ├── unique-checks-item: t(a) + │ └── project + │ ├── columns: a:20!null + │ └── semi-join (hash) + │ ├── columns: k:18!null r:19!null a:20!null b:21!null + │ ├── with-scan &1 + │ │ ├── columns: k:18!null r:19!null a:20!null b:21!null + │ │ └── mapping: + │ │ ├── column1:7 => k:18 + │ │ ├── column2:8 => r:19 + │ │ ├── column3:9 => a:20 + │ │ └── b_comp:10 => b:21 + │ ├── scan t + │ │ ├── columns: t.k:12!null t.r:13!null t.a:14 t.b:15 + │ │ ├── check constraint expressions + │ │ │ └── t.r:13 IN ('east', 'west') + │ │ ├── computed column expressions + │ │ │ └── t.b:15 + │ │ │ └── t.k:12 % 9 + │ │ └── flags: disabled not visible index feature + │ └── filters + │ ├── a:20 = t.a:14 + │ └── k:18 != t.k:12 + └── unique-checks-item: t(b) + └── project + ├── columns: b:37!null + └── semi-join (hash) + ├── columns: k:34!null r:35!null a:36!null b:37!null + ├── with-scan &1 + │ ├── columns: k:34!null r:35!null a:36!null b:37!null + │ └── mapping: + │ ├── column1:7 => k:34 + │ ├── column2:8 => r:35 + │ ├── column3:9 => a:36 + │ └── b_comp:10 => b:37 + ├── scan t + │ ├── columns: t.k:28!null t.r:29!null t.a:30 t.b:31 + │ ├── check constraint expressions + │ │ └── t.r:29 IN ('east', 'west') + │ ├── computed column expressions + │ │ └── t.b:31 + │ │ └── t.k:28 % 9 + │ └── flags: disabled not visible index feature + └── filters + ├── b:37 = t.b:31 + └── k:34 != t.k:28 exec-ddl DROP TABLE t diff --git a/pkg/sql/opt/xform/coster.go b/pkg/sql/opt/xform/coster.go index 83d618920ed9..1380b67a738c 100644 --- a/pkg/sql/opt/xform/coster.go +++ b/pkg/sql/opt/xform/coster.go @@ -595,7 +595,7 @@ func (c *coster) ComputeCost(candidate memo.RelExpr, required *physical.Required case opt.InsertOp: insertExpr, _ := candidate.(*memo.InsertExpr) - if len(insertExpr.UniqueChecks) != 0 { + if len(insertExpr.FastPathUniqueChecks) != 0 { if len(insertExpr.FastPathUniqueChecks[0].DatumsFromConstraint) != 0 { // Make the cost of insert fast path slightly cheaper than non-fast path // so that the optimizer will pick it. All of the costed operations diff --git a/pkg/sql/opt/xform/testdata/rules/insert b/pkg/sql/opt/xform/testdata/rules/insert index b677009dd3d7..195ac2a6d4fc 100644 --- a/pkg/sql/opt/xform/testdata/rules/insert +++ b/pkg/sql/opt/xform/testdata/rules/insert @@ -36,18 +36,13 @@ insert t │ ├── key: () │ ├── fd: ()-->(7-12) │ └── (1, 'east', 10, 100, true, false) - ├── unique-checks - │ └── unique-checks-item: t(a) - │ └── values - │ ├── columns: a:21!null - │ ├── cardinality: [0 - 0] - │ ├── key: () - │ └── fd: ()-->(21) - └── fast-path-unique-checks - └── fast-path-unique-checks-item: t(a) + └── unique-checks + └── unique-checks-item: t(a) └── values + ├── columns: a:21!null ├── cardinality: [0 - 0] - └── key: () + ├── key: () + └── fd: ()-->(21) exec-ddl DROP TABLE t