From cb03bccc0ef4de4161d7239fc9757c940d2b8157 Mon Sep 17 00:00:00 2001 From: Marcus Gartner Date: Tue, 21 Dec 2021 18:44:19 -0500 Subject: [PATCH] sql: add assignment cast for UPDATEs Fixes #70628 Release note: None --- pkg/sql/logictest/testdata/logic_test/cast | 258 ++++++- pkg/sql/logictest/testdata/logic_test/update | 15 +- pkg/sql/opt/exec/explain/testdata/gists_tpce | 2 +- pkg/sql/opt/optbuilder/fk_cascade.go | 4 +- pkg/sql/opt/optbuilder/insert.go | 5 +- pkg/sql/opt/optbuilder/mutation_builder.go | 63 +- pkg/sql/opt/optbuilder/scope.go | 16 + .../optbuilder/testdata/fk-on-update-cascade | 183 +++-- .../testdata/fk-on-update-set-default | 82 ++- .../opt/optbuilder/testdata/partial-indexes | 21 +- pkg/sql/opt/optbuilder/testdata/update | 636 +++++++++++++++++- .../optbuilder/testdata/update-col-cast-bug | 61 +- pkg/sql/opt/optbuilder/testdata/update_from | 49 +- pkg/sql/opt/optbuilder/testdata/upsert | 6 +- pkg/sql/opt/optbuilder/update.go | 54 +- pkg/sql/opt/optbuilder/util.go | 1 + pkg/sql/opt/xform/testdata/external/tpcc | 48 +- .../xform/testdata/external/tpcc-later-stats | 48 +- .../opt/xform/testdata/external/tpcc-no-stats | 48 +- pkg/sql/opt/xform/testdata/external/tpce | 441 ++++++------ .../opt/xform/testdata/external/tpce-no-stats | 433 ++++++------ .../xform/testdata/external/trading-mutation | 7 +- 22 files changed, 1801 insertions(+), 680 deletions(-) diff --git a/pkg/sql/logictest/testdata/logic_test/cast b/pkg/sql/logictest/testdata/logic_test/cast index e2fe7b0061e1..b48918ad5e34 100644 --- a/pkg/sql/logictest/testdata/logic_test/cast +++ b/pkg/sql/logictest/testdata/logic_test/cast @@ -45,10 +45,10 @@ EXECUTE insert_c('foo'::STRING) statement ok DELETE FROM assn_cast -statement +statement ok EXECUTE insert_c(' ') -statement +statement ok EXECUTE insert_c(' '::STRING) query T @@ -93,6 +93,8 @@ INSERT INTO assn_cast(qc) VALUES (123) RETURNING qc ---- { +# An integer to "char" cast converts the integer into the corresponding 7-bit +# ASCII character. Anything greater than 127 is out of range. statement error \"char\" out of range INSERT INTO assn_cast(qc) VALUES (1234) @@ -348,6 +350,258 @@ SELECT d, d_comp, d2, d2_comp FROM assn_cast_comp ---- 2 2.00 2.78 3 + +# Tests for assignment casts in UPDATEs. +subtest assignment_casts_update + +statement ok +DELETE FROM assn_cast + +statement ok +INSERT INTO assn_cast (c) VALUES (NULL) + +statement error value too long for type CHAR +UPDATE assn_cast SET c = 'abc' + +query T +UPDATE assn_cast SET c = 1 RETURNING c +---- +1 + +statement error value too long for type CHAR +UPDATE assn_cast SET c = 123 + +statement ok +UPDATE assn_cast SET c = NULL + +statement ok +PREPARE update_c AS UPDATE assn_cast SET c = $1 + +statement error value too long for type CHAR +EXECUTE update_c('foo') + +statement error value too long for type CHAR +EXECUTE update_c('foo'::STRING) + +statement ok +EXECUTE update_c(' ') + +query T +SELECT concat('"', c, '"') FROM assn_cast +---- +"" + +statement ok +EXECUTE update_c(' '::STRING) + +query T +SELECT concat('"', c, '"') FROM assn_cast +---- +"" + +statement ok +UPDATE assn_cast SET qc = 'a' + +query T +UPDATE assn_cast SET qc = 'abc' RETURNING qc +---- +a + +# An integer to "char" cast converts the integer into the corresponding 7-bit +# ASCII character. Anything greater than 127 is out of range. +statement error \"char\" out of range +UPDATE assn_cast SET qc = 1234 + +statement ok +PREPARE update_qc AS UPDATE assn_cast SET qc = $1 + +statement ok +EXECUTE update_qc('foo') + +query T +SELECT qc FROM assn_cast +---- +f + +statement ok +EXECUTE update_qc('foo'::STRING) + +query T +SELECT qc FROM assn_cast +---- +f + +statement ok +UPDATE assn_cast SET i = '1' + +statement ok +PREPARE update_i AS UPDATE assn_cast SET i = $1 + +statement ok +EXECUTE update_i('1') + +statement error value type string doesn't match type int of column \"i\" +UPDATE assn_cast SET i = '1'::STRING + +statement error integer out of range for type int2 +UPDATE assn_cast SET i2 = 999999999 + +statement ok +PREPARE update_i2 AS UPDATE assn_cast SET i2 = $1 + +statement error integer out of range for type int2 +EXECUTE update_i2(99999999) + +query F +UPDATE assn_cast SET d = 11.22 RETURNING d +---- +11 + +query F +UPDATE assn_cast SET d = 11.22::DECIMAL(10, 0) RETURNING d +---- +11 + +query F +UPDATE assn_cast SET d = 11.22::DECIMAL(10, 2) RETURNING d +---- +11 + +statement ok +PREPARE update_d AS UPDATE assn_cast SET d = $1 + +statement ok +EXECUTE update_d(123.45) + +query F +SELECT d FROM assn_cast +---- +123 + +statement ok +PREPARE update_d2 AS UPDATE assn_cast SET d = (SELECT * FROM (VALUES ($1::DECIMAL(10, 2)))) + +statement ok +EXECUTE update_d2(67.89) + +query F +SELECT d FROM assn_cast +---- +68 + +query T +UPDATE assn_cast SET a = ARRAY[] RETURNING a +---- +{} + +query T +UPDATE assn_cast SET a = ARRAY[NULL] RETURNING a +---- +{NULL} + +query T +UPDATE assn_cast SET a = ARRAY[1.1] RETURNING a +---- +{1} + +query T +UPDATE assn_cast SET a = ARRAY[2.88, NULL, 15] RETURNING a +---- +{3,NULL,15} + +query T +UPDATE assn_cast SET a = ARRAY[3.99, NULL, 16]::DECIMAL(10, 2)[] RETURNING a +---- +{4,NULL,16} + +query T +UPDATE assn_cast SET a = ARRAY[5.55, 6.66::DECIMAL(10, 2)] RETURNING a +---- +{6,7} + +statement ok +PREPARE update_a AS UPDATE assn_cast SET a = $1 + +statement ok +EXECUTE update_a(ARRAY[7.77, 8.88::DECIMAL(10, 2)]) + +query T +SELECT a FROM assn_cast +---- +{8,9} + +statement ok +PREPARE update_a2 AS UPDATE assn_cast SET a = ARRAY[$1] + +statement ok +EXECUTE update_a2(20.2) + +query T +SELECT a FROM assn_cast +---- +{20} + +statement ok +PREPARE update_a3 AS UPDATE assn_cast SET a = ARRAY[30.12, $1, 32.1] + +statement ok +EXECUTE update_a3(30.9) + +query T +SELECT a FROM assn_cast +---- +{30,31,32} + +statement error value type tuple{int, int} doesn't match type timestamp of column "t" +UPDATE assn_cast SET t = (SELECT (10, 11)) + +statement error value type decimal doesn't match type timestamp of column "t" +UPDATE assn_cast SET t = 3.2 + +statement error value type decimal doesn't match type timestamp of column "t" +UPDATE assn_cast SET (i, t) = (1, 3.2) + +# Tests for assignment casts in cascading UPDATEs. +subtest assignment_casts_update_cascade + +statement ok +CREATE TABLE assn_cast_p (p DECIMAL(10, 2) PRIMARY KEY); +INSERT INTO assn_cast_p VALUES (1.0); + +# Test ON UPDATE CASCADE. +statement ok +CREATE TABLE assn_cast_c (c INT PRIMARY KEY, p DECIMAL(10, 0) REFERENCES assn_cast_p(p) ON UPDATE CASCADE); +INSERT INTO assn_cast_c VALUES (1, 1.0); + +statement error update on table "assn_cast_c" violates foreign key constraint "assn_cast_c_p_fkey" +UPDATE assn_cast_p SET p = 1.2 + +statement ok +UPDATE assn_cast_p SET p = 2.0 + +query IF +SELECT * FROM assn_cast_c +---- +1 2 + +# Test ON UPDATE SET DEFAULT. +statement ok +DROP TABLE assn_cast_c; +CREATE TABLE assn_cast_c (c INT PRIMARY KEY, p DECIMAL(10, 0) DEFAULT 3.1 REFERENCES assn_cast_p(p) ON UPDATE SET DEFAULT); +INSERT INTO assn_cast_c VALUES (2, 2.0); + +statement error update on table "assn_cast_c" violates foreign key constraint "assn_cast_c_p_fkey" +UPDATE assn_cast_p SET p = 1.2 + +statement ok +UPDATE assn_cast_p SET p = 3.0 + +query IF +SELECT * FROM assn_cast_c +---- +2 3 + + # Regression tests. subtest regressions diff --git a/pkg/sql/logictest/testdata/logic_test/update b/pkg/sql/logictest/testdata/logic_test/update index f4b6b0f0eb2b..5191f8962807 100644 --- a/pkg/sql/logictest/testdata/logic_test/update +++ b/pkg/sql/logictest/testdata/logic_test/update @@ -7,15 +7,24 @@ CREATE TABLE kv ( statement error value type tuple{int, int} doesn't match type int of column "v" UPDATE kv SET v = (SELECT (10, 11)) -statement error value type decimal doesn't match type int of column "v" +statement ok UPDATE kv SET v = 3.2 -statement error value type decimal doesn't match type int of column "v" +statement ok UPDATE kv SET (k, v) = (3, 3.2) -statement error value type decimal doesn't match type int of column "v" +statement ok UPDATE kv SET (k, v) = (SELECT 3, 3.2) +statement error value type string doesn't match type int of column "v" +UPDATE kv SET v = '3.2'::STRING + +statement error value type string doesn't match type int of column "v" +UPDATE kv SET (k, v) = (3, '3.2'::STRING) + +statement error value type string doesn't match type int of column "v" +UPDATE kv SET (k, v) = (SELECT 3, '3.2'::STRING) + statement count 4 INSERT INTO kv VALUES (1, 2), (3, 4), (5, 6), (7, 8) diff --git a/pkg/sql/opt/exec/explain/testdata/gists_tpce b/pkg/sql/opt/exec/explain/testdata/gists_tpce index 0a7d10fb03ac..663e5aff49e8 100644 --- a/pkg/sql/opt/exec/explain/testdata/gists_tpce +++ b/pkg/sql/opt/exec/explain/testdata/gists_tpce @@ -361,7 +361,7 @@ explain(shape): │ └── • lookup join (anti) │ table: status_type@status_type_pkey - │ equality: (t_st_id_new) = (st_id) + │ equality: (column127) = (st_id) │ equality cols are key │ └── • scan buffer diff --git a/pkg/sql/opt/optbuilder/fk_cascade.go b/pkg/sql/opt/optbuilder/fk_cascade.go index 22df18aaea5c..f7ca08262bf9 100644 --- a/pkg/sql/opt/optbuilder/fk_cascade.go +++ b/pkg/sql/opt/optbuilder/fk_cascade.go @@ -458,7 +458,7 @@ func (cb *onDeleteSetBuilder) Build( updateExprs[i].Expr = tree.DefaultVal{} } } - mb.addUpdateCols(updateExprs) + mb.addUpdateCols(updateExprs, false /* isUpsert */) // TODO(radu): consider plumbing a flag to prevent building the FK check // against the parent we are cascading from. Need to investigate in which @@ -687,7 +687,7 @@ func (cb *onUpdateCascadeBuilder) Build( panic(errors.AssertionFailedf("unsupported action")) } } - mb.addUpdateCols(updateExprs) + mb.addUpdateCols(updateExprs, false /* isUpsert */) mb.buildUpdate(nil /* returning */) return mb.outScope.expr diff --git a/pkg/sql/opt/optbuilder/insert.go b/pkg/sql/opt/optbuilder/insert.go index bd20eb72d001..cf76ab00f77a 100644 --- a/pkg/sql/opt/optbuilder/insert.go +++ b/pkg/sql/opt/optbuilder/insert.go @@ -317,7 +317,7 @@ func (b *Builder) buildInsert(ins *tree.Insert, inScope *scope) (outScope *scope // Add additional columns for computed expressions that may depend on any // updated columns, as well as mutation columns with default values. - mb.addSynthesizedColsForUpdate() + mb.addSynthesizedColsForUpdate(true /* isUpsert */) } // Build the final upsert statement, including any returned expressions. @@ -334,7 +334,7 @@ func (b *Builder) buildInsert(ins *tree.Insert, inScope *scope) (outScope *scope mb.addTargetColsForUpdate(ins.OnConflict.Exprs) // Build each of the SET expressions. - mb.addUpdateCols(ins.OnConflict.Exprs) + mb.addUpdateCols(ins.OnConflict.Exprs, true /* isUpsert */) // Build the final upsert statement, including any returned expressions. mb.buildUpsert(returning) @@ -646,6 +646,7 @@ func (mb *mutationBuilder) buildInputForInsert( } if !isUpsert { + // Add assignment casts for insert columns. mb.addAssignmentCasts(mb.insertColIDs) } } diff --git a/pkg/sql/opt/optbuilder/mutation_builder.go b/pkg/sql/opt/optbuilder/mutation_builder.go index 94e7fef0fd69..def38fe00641 100644 --- a/pkg/sql/opt/optbuilder/mutation_builder.go +++ b/pkg/sql/opt/optbuilder/mutation_builder.go @@ -1402,30 +1402,7 @@ func checkDatumTypeFitsColumnType(col *cat.Column, typ *types.T) { // If there is no valid assignment cast from a column type in srcCols to its // corresponding target column type, then this function throws an error. func (mb *mutationBuilder) addAssignmentCasts(srcCols opt.OptionalColList) { - // If all source columns have types identical to their target column types, - // there are no assignment casts necessary. Do not create an empty - // projection. - castRequired := false - for ord, colID := range srcCols { - if colID == 0 { - // Column not mutated, so nothing to do. - continue - } - srcType := mb.md.ColumnMeta(colID).Type - targetType := mb.tab.Column(ord).DatumType() - if !srcType.Identical(targetType) { - castRequired = true - break - } - } - if !castRequired { - return - } - - projectionScope := mb.outScope.replace() - projectionScope.cols = make([]scopeColumn, 0, len(mb.outScope.cols)) - var uncastedCols opt.ColSet - + var projectionScope *scope for ord, colID := range srcCols { if colID == 0 { // Column not mutated, so nothing to do. @@ -1439,7 +1416,6 @@ func (mb *mutationBuilder) addAssignmentCasts(srcCols opt.OptionalColList) { // An assignment cast is not necessary if the source and target types // are identical. if srcType.Identical(targetType) { - uncastedCols.Add(colID) continue } @@ -1449,32 +1425,33 @@ func (mb *mutationBuilder) addAssignmentCasts(srcCols opt.OptionalColList) { panic(sqlerrors.NewInvalidAssignmentCastError(srcType, targetType, string(targetCol.ColName()))) } - // Create a new column which casts the input column to the correct - // type. + // Create the cast expression. variable := mb.b.factory.ConstructVariable(colID) cast := mb.b.factory.ConstructAssignmentCast(variable, targetType) - scopeCol := mb.b.synthesizeColumn( - projectionScope, - scopeColName(targetCol.ColName()).WithMetadataName(""), - targetType, - nil, /* expr */ - cast, - ) + + // Lazily create the new scope. + if projectionScope == nil { + projectionScope = mb.outScope.replace() + projectionScope.appendColumnsFromScope(mb.outScope) + } + + // Update the scope column to be casted. + // + // When building an UPDATE..FROM expression the projectionScope may have + // two columns with different names but the same ID. To get the correct + // column, we perform a lookup with the ID and the name. See #61520. + scopeCol := projectionScope.getColumnWithIDAndReferenceName(colID, targetCol.ColName()) + scopeCol.name = scopeCol.name.WithMetadataName("") + mb.b.populateSynthesizedColumn(scopeCol, cast) // Replace old source column with the new one. srcCols[ord] = scopeCol.id } - // Add uncasted columns to the projection scope so that they become - // passthrough columns. - for i := range mb.outScope.cols { - if uncastedCols.Contains(mb.outScope.cols[i].id) { - projectionScope.appendColumn(&mb.outScope.cols[i]) - } + if projectionScope != nil { + projectionScope.expr = mb.b.constructProject(mb.outScope.expr, projectionScope.cols) + mb.outScope = projectionScope } - - projectionScope.expr = mb.b.constructProject(mb.outScope.expr, projectionScope.cols) - mb.outScope = projectionScope } // partialIndexCount returns the number of public, write-only, and delete-only diff --git a/pkg/sql/opt/optbuilder/scope.go b/pkg/sql/opt/optbuilder/scope.go index 2fd89d6a8b71..dc6c03aa7ed3 100644 --- a/pkg/sql/opt/optbuilder/scope.go +++ b/pkg/sql/opt/optbuilder/scope.go @@ -317,6 +317,22 @@ func (s *scope) getColumn(col opt.ColumnID) *scopeColumn { return nil } +// getColumnWithIDAndReferenceName returns the scopeColumn with the given id and +// reference name (either in cols or extraCols). +func (s *scope) getColumnWithIDAndReferenceName(col opt.ColumnID, refName tree.Name) *scopeColumn { + for i := range s.cols { + if s.cols[i].id == col && s.cols[i].name.MatchesReferenceName(refName) { + return &s.cols[i] + } + } + for i := range s.extraCols { + if s.extraCols[i].id == col && s.cols[i].name.MatchesReferenceName(refName) { + return &s.extraCols[i] + } + } + return nil +} + // getColumnForTableOrdinal returns the column with a specific tableOrdinal // value, or nil if it doesn't exist. func (s *scope) getColumnForTableOrdinal(tabOrd int) *scopeColumn { diff --git a/pkg/sql/opt/optbuilder/testdata/fk-on-update-cascade b/pkg/sql/opt/optbuilder/testdata/fk-on-update-cascade index a9b80708af39..b0d2852e3693 100644 --- a/pkg/sql/opt/optbuilder/testdata/fk-on-update-cascade +++ b/pkg/sql/opt/optbuilder/testdata/fk-on-update-cascade @@ -731,6 +731,86 @@ root ├── c:50 = child_multi.c:52 └── q:51 = child_multi.q:54 +# Test a cascade to a child that requires an assignment cast because the +# referencing column type is not identical to the referenced column type. +exec-ddl +CREATE TABLE parent_assn_cast (p DECIMAL(10, 2) PRIMARY KEY) +---- + +exec-ddl +CREATE TABLE child_assn_cast ( + c INT PRIMARY KEY, + p DECIMAL(10, 0) REFERENCES parent_assn_cast(p) ON UPDATE CASCADE +) +---- + +build-cascades +UPDATE parent_assn_cast SET p = 1.45 WHERE p > 1 +---- +root + ├── update parent_assn_cast + │ ├── columns: + │ ├── fetch columns: p:4 + │ ├── update-mapping: + │ │ └── column8:8 => p:1 + │ ├── input binding: &1 + │ ├── cascades + │ │ └── child_assn_cast_p_fkey + │ └── project + │ ├── columns: column8:8!null p:4!null crdb_internal_mvcc_timestamp:5 tableoid:6 + │ ├── project + │ │ ├── columns: p_new:7!null p:4!null crdb_internal_mvcc_timestamp:5 tableoid:6 + │ │ ├── select + │ │ │ ├── columns: p:4!null crdb_internal_mvcc_timestamp:5 tableoid:6 + │ │ │ ├── scan parent_assn_cast + │ │ │ │ └── columns: p:4!null crdb_internal_mvcc_timestamp:5 tableoid:6 + │ │ │ └── filters + │ │ │ └── p:4 > 1 + │ │ └── projections + │ │ └── 1.45 [as=p_new:7] + │ └── projections + │ └── assignment-cast: DECIMAL(10,2) [as=column8:8] + │ └── p_new:7 + └── cascade + └── update child_assn_cast + ├── columns: + ├── fetch columns: c:13 child_assn_cast.p:14 + ├── update-mapping: + │ └── column19:19 => child_assn_cast.p:10 + ├── input binding: &2 + ├── project + │ ├── columns: column19:19!null c:13!null child_assn_cast.p:14!null p_old:17!null p_new:18!null + │ ├── inner-join (hash) + │ │ ├── columns: c:13!null child_assn_cast.p:14!null p_old:17!null p_new:18!null + │ │ ├── scan child_assn_cast + │ │ │ └── columns: c:13!null child_assn_cast.p:14 + │ │ ├── select + │ │ │ ├── columns: p_old:17!null p_new:18!null + │ │ │ ├── with-scan &1 + │ │ │ │ ├── columns: p_old:17!null p_new:18!null + │ │ │ │ └── mapping: + │ │ │ │ ├── parent_assn_cast.p:4 => p_old:17 + │ │ │ │ └── column8:8 => p_new:18 + │ │ │ └── filters + │ │ │ └── p_old:17 IS DISTINCT FROM p_new:18 + │ │ └── filters + │ │ └── child_assn_cast.p:14 = p_old:17 + │ └── projections + │ └── assignment-cast: DECIMAL(10) [as=column19:19] + │ └── p_new:18 + └── f-k-checks + └── f-k-checks-item: child_assn_cast(p) -> parent_assn_cast(p) + └── anti-join (hash) + ├── columns: p:20!null + ├── with-scan &2 + │ ├── columns: p:20!null + │ └── mapping: + │ └── column19:19 => p:20 + ├── scan parent_assn_cast + │ └── columns: parent_assn_cast.p:21!null + └── filters + └── p:20 = parent_assn_cast.p:21 + # Test a cascade to a child with a partial index. exec-ddl CREATE TABLE parent_partial (p INT PRIMARY KEY) @@ -1246,71 +1326,80 @@ root ├── columns: ├── fetch columns: t.public.child_diff_type.c:12(int) t.public.child_diff_type.p:13(int2) ├── update-mapping: - │ └── p_new:17 => t.public.child_diff_type.p:9 + │ └── column18:18 => t.public.child_diff_type.p:9 ├── input binding: &2 ├── cardinality: [0 - 0] ├── volatile, mutations ├── stats: [rows=0] - ├── inner-join (hash) - │ ├── columns: t.public.child_diff_type.c:12(int!null) t.public.child_diff_type.p:13(int2!null) p_old:16(int!null) p_new:17(int!null) - │ ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) - │ ├── stats: [rows=3.3, distinct(13)=0.333333333, null(13)=0, distinct(16)=0.333333333, null(16)=0, distinct(17)=0.333317413, null(17)=0] + ├── project + │ ├── columns: column18:18(int2!null) t.public.child_diff_type.c:12(int!null) t.public.child_diff_type.p:13(int2!null) p_old:16(int!null) p_new:17(int!null) + │ ├── immutable + │ ├── stats: [rows=3.3, distinct(18)=0.333317413, null(18)=0] │ ├── key: (12) - │ ├── fd: ()-->(13,16,17), (13)==(16), (16)==(13) - │ ├── prune: (12) - │ ├── scan t.public.child_diff_type - │ │ ├── columns: t.public.child_diff_type.c:12(int!null) t.public.child_diff_type.p:13(int2) - │ │ ├── stats: [rows=1000, distinct(12)=1000, null(12)=0, distinct(13)=100, null(13)=10] + │ ├── fd: ()-->(13,16-18), (13)==(16), (16)==(13) + │ ├── prune: (12,13,16-18) + │ ├── inner-join (hash) + │ │ ├── columns: t.public.child_diff_type.c:12(int!null) t.public.child_diff_type.p:13(int2!null) p_old:16(int!null) p_new:17(int!null) + │ │ ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-more) + │ │ ├── stats: [rows=3.3, distinct(13)=0.333333333, null(13)=0, distinct(16)=0.333333333, null(16)=0, distinct(17)=0.333317413, null(17)=0] │ │ ├── key: (12) - │ │ ├── fd: (12)-->(13) - │ │ ├── prune: (12,13) - │ │ └── unfiltered-cols: (12-15) - │ ├── select - │ │ ├── columns: p_old:16(int!null) p_new:17(int!null) - │ │ ├── cardinality: [0 - 1] - │ │ ├── stats: [rows=0.333333333, distinct(16)=0.333333333, null(16)=0, distinct(17)=0.333333333, null(17)=0] - │ │ ├── key: () - │ │ ├── fd: ()-->(16,17) - │ │ ├── with-scan &1 + │ │ ├── fd: ()-->(13,16,17), (13)==(16), (16)==(13) + │ │ ├── scan t.public.child_diff_type + │ │ │ ├── columns: t.public.child_diff_type.c:12(int!null) t.public.child_diff_type.p:13(int2) + │ │ │ ├── stats: [rows=1000, distinct(12)=1000, null(12)=0, distinct(13)=100, null(13)=10] + │ │ │ ├── key: (12) + │ │ │ ├── fd: (12)-->(13) + │ │ │ ├── prune: (12,13) + │ │ │ └── unfiltered-cols: (12-15) + │ │ ├── select │ │ │ ├── columns: p_old:16(int!null) p_new:17(int!null) - │ │ │ ├── mapping: - │ │ │ │ ├── t.public.parent_diff_type.p:4(int) => p_old:16(int) - │ │ │ │ └── p_new:7(int) => p_new:17(int) │ │ │ ├── cardinality: [0 - 1] - │ │ │ ├── stats: [rows=1, distinct(16)=1, null(16)=0, distinct(17)=1, null(17)=0] + │ │ │ ├── stats: [rows=0.333333333, distinct(16)=0.333333333, null(16)=0, distinct(17)=0.333333333, null(17)=0] │ │ │ ├── key: () │ │ │ ├── fd: ()-->(16,17) - │ │ │ └── prune: (16,17) + │ │ │ ├── with-scan &1 + │ │ │ │ ├── columns: p_old:16(int!null) p_new:17(int!null) + │ │ │ │ ├── mapping: + │ │ │ │ │ ├── t.public.parent_diff_type.p:4(int) => p_old:16(int) + │ │ │ │ │ └── p_new:7(int) => p_new:17(int) + │ │ │ │ ├── cardinality: [0 - 1] + │ │ │ │ ├── stats: [rows=1, distinct(16)=1, null(16)=0, distinct(17)=1, null(17)=0] + │ │ │ │ ├── key: () + │ │ │ │ ├── fd: ()-->(16,17) + │ │ │ │ └── prune: (16,17) + │ │ │ └── filters + │ │ │ └── is-not [type=bool, outer=(16,17)] + │ │ │ ├── variable: p_old:16 [type=int] + │ │ │ └── variable: p_new:17 [type=int] │ │ └── filters - │ │ └── is-not [type=bool, outer=(16,17)] - │ │ ├── variable: p_old:16 [type=int] - │ │ └── variable: p_new:17 [type=int] - │ └── filters - │ └── eq [type=bool, outer=(13,16), constraints=(/13: (/NULL - ]; /16: (/NULL - ]), fd=(13)==(16), (16)==(13)] - │ ├── variable: t.public.child_diff_type.p:13 [type=int2] - │ └── variable: p_old:16 [type=int] + │ │ └── eq [type=bool, outer=(13,16), constraints=(/13: (/NULL - ]; /16: (/NULL - ]), fd=(13)==(16), (16)==(13)] + │ │ ├── variable: t.public.child_diff_type.p:13 [type=int2] + │ │ └── variable: p_old:16 [type=int] + │ └── projections + │ └── assignment-cast: INT2 [as=column18:18, type=int2, outer=(17), immutable] + │ └── variable: p_new:17 [type=int] └── f-k-checks └── f-k-checks-item: child_diff_type(p) -> parent_diff_type(p) └── anti-join (hash) - ├── columns: p:18(int2!null) + ├── columns: p:19(int2!null) ├── stats: [rows=1e-10] - ├── fd: ()-->(18) + ├── fd: ()-->(19) ├── cte-uses - │ └── &2: count=1 used-columns=(17) + │ └── &2: count=1 used-columns=(18) ├── with-scan &2 - │ ├── columns: p:18(int2!null) + │ ├── columns: p:19(int2!null) │ ├── mapping: - │ │ └── p_new:17(int) => p:18(int2) - │ ├── stats: [rows=3.3, distinct(18)=0.333317413, null(18)=0] - │ ├── fd: ()-->(18) + │ │ └── column18:18(int2) => p:19(int2) + │ ├── stats: [rows=3.3, distinct(19)=0.333317413, null(19)=0] + │ ├── fd: ()-->(19) │ └── cte-uses - │ └── &2: count=1 used-columns=(17) + │ └── &2: count=1 used-columns=(18) ├── scan t.public.parent_diff_type - │ ├── columns: t.public.parent_diff_type.p:19(int!null) - │ ├── stats: [rows=1000, distinct(19)=1000, null(19)=0] - │ ├── key: (19) - │ └── prune: (19) + │ ├── columns: t.public.parent_diff_type.p:20(int!null) + │ ├── stats: [rows=1000, distinct(20)=1000, null(20)=0] + │ ├── key: (20) + │ └── prune: (20) └── filters - └── eq [type=bool, outer=(18,19), constraints=(/18: (/NULL - ]; /19: (/NULL - ]), fd=(18)==(19), (19)==(18)] - ├── variable: p:18 [type=int2] - └── variable: t.public.parent_diff_type.p:19 [type=int] + └── eq [type=bool, outer=(19,20), constraints=(/19: (/NULL - ]; /20: (/NULL - ]), fd=(19)==(20), (20)==(19)] + ├── variable: p:19 [type=int2] + └── variable: t.public.parent_diff_type.p:20 [type=int] diff --git a/pkg/sql/opt/optbuilder/testdata/fk-on-update-set-default b/pkg/sql/opt/optbuilder/testdata/fk-on-update-set-default index 81f70350d742..b9e305a080d6 100644 --- a/pkg/sql/opt/optbuilder/testdata/fk-on-update-set-default +++ b/pkg/sql/opt/optbuilder/testdata/fk-on-update-set-default @@ -84,7 +84,7 @@ CREATE TABLE child_multi ( p INT DEFAULT 0, q INT DEFAULT 1, UNIQUE (c, q), - CONSTRAINT fk FOREIGN KEY (p, q) REFERENCES parent_multi(p, q) ON UPDATE SET DEFAULT + CONSTRAINT fk FOREIGN KEY (p, q) REFERENCES parent_multi(p, q) ON UPDATE SET DEFAULT ) ---- @@ -763,6 +763,86 @@ root ├── c:57 = child_multi.c:59 └── q:58 = child_multi.q:61 +# Test a cascade to a child that requires an assignment cast because the +# referencing column's DEFAULT expression type is not identical to the +# referencing column type. +exec-ddl +CREATE TABLE parent_assn_cast (p INT PRIMARY KEY) +---- + +exec-ddl +CREATE TABLE child_assn_cast ( + c INT PRIMARY KEY, + p DECIMAL(10, 0) DEFAULT 1.45::DECIMAL(10, 2) REFERENCES parent_assn_cast(p) ON UPDATE SET DEFAULT +) +---- + +build-cascades +UPDATE parent_assn_cast SET p = 1 WHERE p > 1 +---- +root + ├── update parent_assn_cast + │ ├── columns: + │ ├── fetch columns: p:4 + │ ├── update-mapping: + │ │ └── p_new:7 => p:1 + │ ├── input binding: &1 + │ ├── cascades + │ │ └── child_assn_cast_p_fkey + │ └── project + │ ├── columns: p_new:7!null p:4!null crdb_internal_mvcc_timestamp:5 tableoid:6 + │ ├── select + │ │ ├── columns: p:4!null crdb_internal_mvcc_timestamp:5 tableoid:6 + │ │ ├── scan parent_assn_cast + │ │ │ └── columns: p:4!null crdb_internal_mvcc_timestamp:5 tableoid:6 + │ │ └── filters + │ │ └── p:4 > 1 + │ └── projections + │ └── 1 [as=p_new:7] + └── cascade + └── update child_assn_cast + ├── columns: + ├── fetch columns: c:12 child_assn_cast.p:13 + ├── update-mapping: + │ └── column19:19 => child_assn_cast.p:9 + ├── input binding: &2 + ├── project + │ ├── columns: column19:19!null c:12!null child_assn_cast.p:13!null p_old:16!null p_new:17!null + │ ├── project + │ │ ├── columns: p_new:18!null c:12!null child_assn_cast.p:13!null p_old:16!null p_new:17!null + │ │ ├── inner-join (cross) + │ │ │ ├── columns: c:12!null child_assn_cast.p:13!null p_old:16!null p_new:17!null + │ │ │ ├── scan child_assn_cast + │ │ │ │ └── columns: c:12!null child_assn_cast.p:13 + │ │ │ ├── select + │ │ │ │ ├── columns: p_old:16!null p_new:17!null + │ │ │ │ ├── with-scan &1 + │ │ │ │ │ ├── columns: p_old:16!null p_new:17!null + │ │ │ │ │ └── mapping: + │ │ │ │ │ ├── parent_assn_cast.p:4 => p_old:16 + │ │ │ │ │ └── p_new:7 => p_new:17 + │ │ │ │ └── filters + │ │ │ │ └── p_old:16 IS DISTINCT FROM p_new:17 + │ │ │ └── filters + │ │ │ └── child_assn_cast.p:13 = p_old:16 + │ │ └── projections + │ │ └── 1.45::DECIMAL(10,2) [as=p_new:18] + │ └── projections + │ └── assignment-cast: DECIMAL(10) [as=column19:19] + │ └── p_new:18 + └── f-k-checks + └── f-k-checks-item: child_assn_cast(p) -> parent_assn_cast(p) + └── anti-join (cross) + ├── columns: p:20!null + ├── with-scan &2 + │ ├── columns: p:20!null + │ └── mapping: + │ └── column19:19 => p:20 + ├── scan parent_assn_cast + │ └── columns: parent_assn_cast.p:21!null + └── filters + └── p:20 = parent_assn_cast.p:21 + # Test a cascade to a child with a partial index. exec-ddl CREATE TABLE parent_partial (p INT PRIMARY KEY) diff --git a/pkg/sql/opt/optbuilder/testdata/partial-indexes b/pkg/sql/opt/optbuilder/testdata/partial-indexes index fede520fa668..464b6bcb0eee 100644 --- a/pkg/sql/opt/optbuilder/testdata/partial-indexes +++ b/pkg/sql/opt/optbuilder/testdata/partial-indexes @@ -537,9 +537,9 @@ update comp ├── e_comp:17 = 'FOO' [as=partial_index_put2:20] └── e:12 = 'FOO' [as=partial_index_del2:21] -# Regression test for #61520. The new value for column a (project as b:8) should -# be in-scope when building the partial index PUT expression when the value in -# the FROM clause must be rounded. +# Regression test for #61520. The new value for column a should be in-scope when +# building the partial index PUT expression when the value in the FROM clause +# must be assignment casted. exec-ddl CREATE TABLE t61520 ( @@ -552,18 +552,18 @@ build UPDATE t61520 t SET a = v.b FROM (VALUES (1.0)) v(b) WHERE t.a = v.b RETURNING a, b ---- project - ├── columns: a:1 b:9 + ├── columns: a:1!null b:9 └── update t61520 [as=t] - ├── columns: a:1 rowid:2!null column1:9 + ├── columns: a:1!null rowid:2!null column1:9 ├── fetch columns: a:5 rowid:6 ├── update-mapping: - │ └── b:10 => a:1 + │ └── column10:10 => a:1 ├── partial index put columns: partial_index_put1:11 ├── partial index del columns: partial_index_del1:12 └── project - ├── columns: partial_index_put1:11 partial_index_del1:12!null a:5!null rowid:6!null crdb_internal_mvcc_timestamp:7 tableoid:8 column1:9!null b:10 + ├── columns: partial_index_put1:11!null partial_index_del1:12!null a:5!null rowid:6!null crdb_internal_mvcc_timestamp:7 tableoid:8 column1:9!null column10:10!null ├── project - │ ├── columns: b:10 a:5!null rowid:6!null crdb_internal_mvcc_timestamp:7 tableoid:8 column1:9!null + │ ├── columns: column10:10!null a:5!null rowid:6!null crdb_internal_mvcc_timestamp:7 tableoid:8 column1:9!null │ ├── select │ │ ├── columns: a:5!null rowid:6!null crdb_internal_mvcc_timestamp:7 tableoid:8 column1:9!null │ │ ├── inner-join (cross) @@ -580,9 +580,10 @@ project │ │ └── filters │ │ └── a:5 = column1:9 │ └── projections - │ └── crdb_internal.round_decimal_values(column1:9, 2) [as=b:10] + │ └── assignment-cast: DECIMAL(10,2) [as=column10:10] + │ └── column1:9 └── projections - ├── b:10 > 0 [as=partial_index_put1:11] + ├── column10:10 > 0 [as=partial_index_put1:11] └── a:5 > 0 [as=partial_index_del1:12] # -- UPSERT / INSERT ON CONFLICT tests -- diff --git a/pkg/sql/opt/optbuilder/testdata/update b/pkg/sql/opt/optbuilder/testdata/update index 507da7469c56..40b731d056c4 100644 --- a/pkg/sql/opt/optbuilder/testdata/update +++ b/pkg/sql/opt/optbuilder/testdata/update @@ -67,6 +67,26 @@ CREATE TABLE decimals ( ) ---- +exec-ddl +CREATE TABLE assn_cast ( + c CHAR, + qc "char", + i INT DEFAULT 10::INT2, + s STRING, + d DECIMAL(10, 0), + d_comp DECIMAL(10, 0) AS (d + 10.0) STORED +) +---- + +exec-ddl +CREATE TABLE assn_cast_on_update ( + i INT, + d DECIMAL(10, 1) ON UPDATE 1.23, + d2 DECIMAL(10, 1) ON UPDATE 1.23::DECIMAL(10, 2), + d_comp DECIMAL(10, 0) AS (d) STORED +) +---- + exec-ddl CREATE TABLE generated_as_identity ( a INT, @@ -504,7 +524,30 @@ error (42703): column "f" does not exist build UPDATE xyz SET x=1, y=1, z=1 ---- -error (42804): value type int doesn't match type string of column "x" +update xyz + ├── columns: + ├── fetch columns: x:6 y:7 z:8 + ├── update-mapping: + │ ├── column13:13 => x:1 + │ ├── x_new:11 => y:2 + │ └── z_new:12 => z:3 + └── project + ├── columns: column13:13!null x:6!null y:7 z:8 crdb_internal_mvcc_timestamp:9 tableoid:10 x_new:11!null z_new:12!null + ├── project + │ ├── columns: x_new:11!null z_new:12!null x:6!null y:7 z:8 crdb_internal_mvcc_timestamp:9 tableoid:10 + │ ├── scan xyz + │ │ └── columns: x:6!null y:7 z:8 crdb_internal_mvcc_timestamp:9 tableoid:10 + │ └── projections + │ ├── 1 [as=x_new:11] + │ └── 1.0 [as=z_new:12] + └── projections + └── assignment-cast: STRING [as=column13:13] + └── x_new:11 + +build +UPDATE xyz SET y='1'::TEXT +---- +error (42804): value type string doesn't match type int of column "y" # Try to use non-returning UPDATE as expression. build @@ -1236,9 +1279,9 @@ error (42601): multiple assignments to the same column "b" # Target type does not match subquery result. build -UPDATE xyz SET (x, y)=(SELECT a, b FROM abcde WHERE a>0) +UPDATE abcde SET (a, b)=(SELECT x, y FROM xyz WHERE y>0) ---- -error (42804): value type int doesn't match type string of column "x" +error (42804): value type string doesn't match type int of column "a" # ------------------------------------------------------------------------------ # Test CTEs. @@ -1614,28 +1657,288 @@ update checks └── abcde.a:13 > 0 [as=check2:23] # ------------------------------------------------------------------------------ -# Test decimal column truncation. +# Test assignment casts. # ------------------------------------------------------------------------------ +# Test standard update with decimal types that require assignment casts. build -UPDATE decimals SET a=1.1, b=ARRAY[0.95, NULL, 15] +UPDATE decimals SET a=1.1, b=ARRAY[0.95, NULL, 15::DECIMAL(10, 2)] ---- update decimals ├── columns: ├── fetch columns: a:7 b:8 c:9 d:10 ├── update-mapping: - │ ├── a_new:15 => a:1 - │ ├── b_new:16 => b:2 - │ └── d_comp:18 => d:4 + │ ├── column15:15 => a:1 + │ ├── column16:16 => b:2 + │ └── column18:18 => d:4 + ├── check columns: check1:19 check2:20 + └── project + ├── columns: check1:19 check2:20 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column15:15!null column16:16 column18:18 + ├── project + │ ├── columns: column18:18 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column15:15!null column16:16 + │ ├── project + │ │ ├── columns: d_comp:17 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column15:15!null column16:16 + │ │ ├── project + │ │ │ ├── columns: column15:15!null column16:16 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 + │ │ │ ├── project + │ │ │ │ ├── columns: a_new:13!null b_new:14 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 + │ │ │ │ ├── scan decimals + │ │ │ │ │ ├── columns: a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 + │ │ │ │ │ └── computed column expressions + │ │ │ │ │ └── d:10 + │ │ │ │ │ └── a:7::DECIMAL + c:9::DECIMAL + │ │ │ │ └── projections + │ │ │ │ ├── 1.1 [as=a_new:13] + │ │ │ │ └── ARRAY[0.95, NULL, 15::DECIMAL(10,2)] [as=b_new:14] + │ │ │ └── projections + │ │ │ ├── assignment-cast: DECIMAL(10) [as=column15:15] + │ │ │ │ └── a_new:13 + │ │ │ └── assignment-cast: DECIMAL(5,1)[] [as=column16:16] + │ │ │ └── b_new:14 + │ │ └── projections + │ │ └── column15:15::DECIMAL + c:9::DECIMAL [as=d_comp:17] + │ └── projections + │ └── assignment-cast: DECIMAL(10,1) [as=column18:18] + │ └── d_comp:17 + └── projections + ├── round(column15:15) = column15:15 [as=check1:19] + └── column16:16[0] > 1 [as=check2:20] + +# Test standard prepared update with decimal types that require assignment +# casts. +assign-placeholders-build query-args=(1.1, (ARRAY[0.95, NULL, 15::DECIMAL(10, 2)])) +UPDATE decimals SET a=$1, b=$2 +---- +update decimals + ├── columns: + ├── fetch columns: a:7 b:8 c:9 d:10 + ├── update-mapping: + │ ├── column15:15 => a:1 + │ ├── column16:16 => b:2 + │ └── column18:18 => d:4 + ├── check columns: check1:19 check2:20 + └── project + ├── columns: check1:19 check2:20 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column15:15!null column16:16!null column18:18 + ├── project + │ ├── columns: column18:18 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column15:15!null column16:16!null + │ ├── project + │ │ ├── columns: d_comp:17 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column15:15!null column16:16!null + │ │ ├── project + │ │ │ ├── columns: column15:15!null column16:16!null a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 + │ │ │ ├── project + │ │ │ │ ├── columns: a_new:13!null b_new:14!null a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 + │ │ │ │ ├── scan decimals + │ │ │ │ │ ├── columns: a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 + │ │ │ │ │ └── computed column expressions + │ │ │ │ │ └── d:10 + │ │ │ │ │ └── a:7::DECIMAL + c:9::DECIMAL + │ │ │ │ └── projections + │ │ │ │ ├── 1.1 [as=a_new:13] + │ │ │ │ └── ARRAY[0.95,NULL,15.00] [as=b_new:14] + │ │ │ └── projections + │ │ │ ├── assignment-cast: DECIMAL(10) [as=column15:15] + │ │ │ │ └── a_new:13 + │ │ │ └── assignment-cast: DECIMAL(5,1)[] [as=column16:16] + │ │ │ └── b_new:14 + │ │ └── projections + │ │ └── column15:15::DECIMAL + c:9::DECIMAL [as=d_comp:17] + │ └── projections + │ └── assignment-cast: DECIMAL(10,1) [as=column18:18] + │ └── d_comp:17 + └── projections + ├── round(column15:15) = column15:15 [as=check1:19] + └── column16:16[0] > 1 [as=check2:20] + +# Test standard update with some types that require assignment casts. +build +UPDATE assn_cast SET c=' ', qc='foo', i='1', s=2 +---- +update assn_cast + ├── columns: + ├── fetch columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16 + ├── update-mapping: + │ ├── column23:23 => c:1 + │ ├── column24:24 => qc:2 + │ ├── i_new:21 => i:3 + │ └── column25:25 => s:4 + └── project + ├── columns: d_comp_comp:26 c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 i_new:21!null column23:23!null column24:24!null column25:25!null + ├── project + │ ├── columns: column23:23!null column24:24!null column25:25!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 i_new:21!null + │ ├── project + │ │ ├── columns: c_new:19!null qc_new:20!null i_new:21!null s_new:22!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ ├── scan assn_cast + │ │ │ ├── columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ │ └── computed column expressions + │ │ │ └── d_comp:15 + │ │ │ └── d:14::DECIMAL + 10.0 + │ │ └── projections + │ │ ├── ' ' [as=c_new:19] + │ │ ├── 'foo' [as=qc_new:20] + │ │ ├── 1 [as=i_new:21] + │ │ └── 2 [as=s_new:22] + │ └── projections + │ ├── assignment-cast: CHAR [as=column23:23] + │ │ └── c_new:19 + │ ├── assignment-cast: "char" [as=column24:24] + │ │ └── qc_new:20 + │ └── assignment-cast: STRING [as=column25:25] + │ └── s_new:22 + └── projections + └── d:14::DECIMAL + 10.0 [as=d_comp_comp:26] + +# Test standard prepared update with some types that require assignment casts. +assign-placeholders-build query-args=(' ', 'foo', '1') +UPDATE assn_cast SET c=$1, qc=$2, i=$3 +---- +update assn_cast + ├── columns: + ├── fetch columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16 + ├── update-mapping: + │ ├── column22:22 => c:1 + │ ├── column23:23 => qc:2 + │ └── i_new:21 => i:3 + └── project + ├── columns: d_comp_comp:24 c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 i_new:21!null column22:22!null column23:23!null + ├── project + │ ├── columns: column22:22!null column23:23!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 i_new:21!null + │ ├── project + │ │ ├── columns: c_new:19!null qc_new:20!null i_new:21!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ ├── scan assn_cast + │ │ │ ├── columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ │ └── computed column expressions + │ │ │ └── d_comp:15 + │ │ │ └── d:14::DECIMAL + 10.0 + │ │ └── projections + │ │ ├── ' ' [as=c_new:19] + │ │ ├── 'foo' [as=qc_new:20] + │ │ └── 1 [as=i_new:21] + │ └── projections + │ ├── assignment-cast: CHAR [as=column22:22] + │ │ └── c_new:19 + │ └── assignment-cast: "char" [as=column23:23] + │ └── qc_new:20 + └── projections + └── d:14::DECIMAL + 10.0 [as=d_comp_comp:24] + +# Test update to DEFAULT that requires an assignment cast. +build +UPDATE assn_cast SET i=DEFAULT +---- +update assn_cast + ├── columns: + ├── fetch columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16 + ├── update-mapping: + │ └── column20:20 => i:3 + └── project + ├── columns: d_comp_comp:21 c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 column20:20!null + ├── project + │ ├── columns: column20:20!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ ├── project + │ │ ├── columns: i_new:19!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ ├── scan assn_cast + │ │ │ ├── columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ │ └── computed column expressions + │ │ │ └── d_comp:15 + │ │ │ └── d:14::DECIMAL + 10.0 + │ │ └── projections + │ │ └── 10::INT2 [as=i_new:19] + │ └── projections + │ └── assignment-cast: INT8 [as=column20:20] + │ └── i_new:19 + └── projections + └── d:14::DECIMAL + 10.0 [as=d_comp_comp:21] + +# Test update to a column that requires an assignment cast and a computed column +# that depends on the new value. +build +UPDATE assn_cast SET d=1.45::DECIMAL(10, 2) +---- +update assn_cast + ├── columns: + ├── fetch columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16 + ├── update-mapping: + │ ├── column20:20 => d:5 + │ └── column22:22 => d_comp:6 + └── project + ├── columns: column22:22!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 column20:20!null + ├── project + │ ├── columns: d_comp_comp:21!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 column20:20!null + │ ├── project + │ │ ├── columns: column20:20!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ ├── project + │ │ │ ├── columns: d_new:19!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ │ ├── scan assn_cast + │ │ │ │ ├── columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ │ │ └── computed column expressions + │ │ │ │ └── d_comp:15 + │ │ │ │ └── d:14::DECIMAL + 10.0 + │ │ │ └── projections + │ │ │ └── 1.45::DECIMAL(10,2) [as=d_new:19] + │ │ └── projections + │ │ └── assignment-cast: DECIMAL(10) [as=column20:20] + │ │ └── d_new:19 + │ └── projections + │ └── column20:20::DECIMAL + 10.0 [as=d_comp_comp:21] + └── projections + └── assignment-cast: DECIMAL(10) [as=column22:22] + └── d_comp_comp:21 + +# Test prepared update to a column that requires an assignment cast and a +# computed column that depends on the new value. +assign-placeholders-build query-args=(1.45::DECIMAL(10, 2)) +UPDATE assn_cast SET d=$1 +---- +update assn_cast + ├── columns: + ├── fetch columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16 + ├── update-mapping: + │ ├── column20:20 => d:5 + │ └── column22:22 => d_comp:6 + └── project + ├── columns: column22:22!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 column20:20!null + ├── project + │ ├── columns: d_comp_comp:21!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 column20:20!null + │ ├── project + │ │ ├── columns: column20:20!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ ├── project + │ │ │ ├── columns: d_new:19!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ │ ├── scan assn_cast + │ │ │ │ ├── columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ │ │ └── computed column expressions + │ │ │ │ └── d_comp:15 + │ │ │ │ └── d:14::DECIMAL + 10.0 + │ │ │ └── projections + │ │ │ └── 1.45 [as=d_new:19] + │ │ └── projections + │ │ └── assignment-cast: DECIMAL(10) [as=column20:20] + │ │ └── d_new:19 + │ └── projections + │ └── column20:20::DECIMAL + 10.0 [as=d_comp_comp:21] + └── projections + └── assignment-cast: DECIMAL(10) [as=column22:22] + └── d_comp_comp:21 + +# Test tuple-syntax update with assignment casts required. +build +UPDATE decimals SET (a, b) = (1.1, ARRAY[0.95, NULL, 15::DECIMAL(10, 2)]) +---- +update decimals + ├── columns: + ├── fetch columns: a:7 b:8 c:9 d:10 + ├── update-mapping: + │ ├── column15:15 => a:1 + │ ├── column16:16 => b:2 + │ └── column18:18 => d:4 ├── check columns: check1:19 check2:20 └── project - ├── columns: check1:19 check2:20 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 a_new:15 b_new:16 d_comp:18 + ├── columns: check1:19 check2:20 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column15:15!null column16:16 column18:18 ├── project - │ ├── columns: d_comp:18 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 a_new:15 b_new:16 + │ ├── columns: column18:18 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column15:15!null column16:16 │ ├── project - │ │ ├── columns: d_comp:17 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 a_new:15 b_new:16 + │ │ ├── columns: d_comp:17 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column15:15!null column16:16 │ │ ├── project - │ │ │ ├── columns: a_new:15 b_new:16 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 + │ │ │ ├── columns: column15:15!null column16:16 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 │ │ │ ├── project │ │ │ │ ├── columns: a_new:13!null b_new:14 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 │ │ │ │ ├── scan decimals @@ -1645,17 +1948,312 @@ update decimals │ │ │ │ │ └── a:7::DECIMAL + c:9::DECIMAL │ │ │ │ └── projections │ │ │ │ ├── 1.1 [as=a_new:13] - │ │ │ │ └── ARRAY[0.95,NULL,15] [as=b_new:14] + │ │ │ │ └── ARRAY[0.95, NULL, 15::DECIMAL(10,2)] [as=b_new:14] + │ │ │ └── projections + │ │ │ ├── assignment-cast: DECIMAL(10) [as=column15:15] + │ │ │ │ └── a_new:13 + │ │ │ └── assignment-cast: DECIMAL(5,1)[] [as=column16:16] + │ │ │ └── b_new:14 + │ │ └── projections + │ │ └── column15:15::DECIMAL + c:9::DECIMAL [as=d_comp:17] + │ └── projections + │ └── assignment-cast: DECIMAL(10,1) [as=column18:18] + │ └── d_comp:17 + └── projections + ├── round(column15:15) = column15:15 [as=check1:19] + └── column16:16[0] > 1 [as=check2:20] + +# Test tuple-syntax prepared update with assignment casts required. +assign-placeholders-build query-args=(1.1, (ARRAY[0.95, NULL, 15::DECIMAL(10, 2)])) +UPDATE decimals SET (a, b) = ($1, $2) +---- +update decimals + ├── columns: + ├── fetch columns: a:7 b:8 c:9 d:10 + ├── update-mapping: + │ ├── column15:15 => a:1 + │ ├── column16:16 => b:2 + │ └── column18:18 => d:4 + ├── check columns: check1:19 check2:20 + └── project + ├── columns: check1:19 check2:20 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column15:15!null column16:16!null column18:18 + ├── project + │ ├── columns: column18:18 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column15:15!null column16:16!null + │ ├── project + │ │ ├── columns: d_comp:17 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column15:15!null column16:16!null + │ │ ├── project + │ │ │ ├── columns: column15:15!null column16:16!null a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 + │ │ │ ├── project + │ │ │ │ ├── columns: a_new:13!null b_new:14!null a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 + │ │ │ │ ├── scan decimals + │ │ │ │ │ ├── columns: a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 + │ │ │ │ │ └── computed column expressions + │ │ │ │ │ └── d:10 + │ │ │ │ │ └── a:7::DECIMAL + c:9::DECIMAL + │ │ │ │ └── projections + │ │ │ │ ├── 1.1 [as=a_new:13] + │ │ │ │ └── ARRAY[0.95,NULL,15.00] [as=b_new:14] + │ │ │ └── projections + │ │ │ ├── assignment-cast: DECIMAL(10) [as=column15:15] + │ │ │ │ └── a_new:13 + │ │ │ └── assignment-cast: DECIMAL(5,1)[] [as=column16:16] + │ │ │ └── b_new:14 + │ │ └── projections + │ │ └── column15:15::DECIMAL + c:9::DECIMAL [as=d_comp:17] + │ └── projections + │ └── assignment-cast: DECIMAL(10,1) [as=column18:18] + │ └── d_comp:17 + └── projections + ├── round(column15:15) = column15:15 [as=check1:19] + └── column16:16[0] > 1 [as=check2:20] + +# Test tuple-syntax update with DEFAULT that requires assignment cast. +build +UPDATE assn_cast SET (c, i) = (' ', DEFAULT) +---- +update assn_cast + ├── columns: + ├── fetch columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16 + ├── update-mapping: + │ ├── column21:21 => c:1 + │ └── column22:22 => i:3 + └── project + ├── columns: d_comp_comp:23 c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 column21:21!null column22:22!null + ├── project + │ ├── columns: column21:21!null column22:22!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ ├── project + │ │ ├── columns: c_new:19!null i_new:20!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ ├── scan assn_cast + │ │ │ ├── columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ │ └── computed column expressions + │ │ │ └── d_comp:15 + │ │ │ └── d:14::DECIMAL + 10.0 + │ │ └── projections + │ │ ├── ' ' [as=c_new:19] + │ │ └── 10::INT2 [as=i_new:20] + │ └── projections + │ ├── assignment-cast: CHAR [as=column21:21] + │ │ └── c_new:19 + │ └── assignment-cast: INT8 [as=column22:22] + │ └── i_new:20 + └── projections + └── d:14::DECIMAL + 10.0 [as=d_comp_comp:23] + +# Test tuple-syntax prepared update with DEFAULT that requires assignment casts. +assign-placeholders-build query-args=(' ') +UPDATE assn_cast SET (c, i) = ($1, DEFAULT) +---- +update assn_cast + ├── columns: + ├── fetch columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16 + ├── update-mapping: + │ ├── column21:21 => c:1 + │ └── column22:22 => i:3 + └── project + ├── columns: d_comp_comp:23 c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 column21:21!null column22:22!null + ├── project + │ ├── columns: column21:21!null column22:22!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ ├── project + │ │ ├── columns: c_new:19!null i_new:20!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ ├── scan assn_cast + │ │ │ ├── columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 rowid:16!null crdb_internal_mvcc_timestamp:17 tableoid:18 + │ │ │ └── computed column expressions + │ │ │ └── d_comp:15 + │ │ │ └── d:14::DECIMAL + 10.0 + │ │ └── projections + │ │ ├── ' ' [as=c_new:19] + │ │ └── 10::INT2 [as=i_new:20] + │ └── projections + │ ├── assignment-cast: CHAR [as=column21:21] + │ │ └── c_new:19 + │ └── assignment-cast: INT8 [as=column22:22] + │ └── i_new:20 + └── projections + └── d:14::DECIMAL + 10.0 [as=d_comp_comp:23] + +# Test update with a subquery that requires an assignment cast. +build +UPDATE decimals SET (a)=(SELECT 1.45 AS n) +---- +update decimals + ├── columns: + ├── fetch columns: a:7 b:8 c:9 d:10 + ├── update-mapping: + │ ├── column14:14 => a:1 + │ └── column16:16 => d:4 + ├── check columns: check1:17 + └── project + ├── columns: check1:17 check2:18 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column14:14 column16:16 + ├── project + │ ├── columns: column16:16 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column14:14 + │ ├── project + │ │ ├── columns: d_comp:15 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 column14:14 + │ │ ├── project + │ │ │ ├── columns: column14:14 a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 + │ │ │ ├── left-join-apply + │ │ │ │ ├── columns: a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 n:13 + │ │ │ │ ├── scan decimals + │ │ │ │ │ ├── columns: a:7!null b:8 c:9 d:10 crdb_internal_mvcc_timestamp:11 tableoid:12 + │ │ │ │ │ └── computed column expressions + │ │ │ │ │ └── d:10 + │ │ │ │ │ └── a:7::DECIMAL + c:9::DECIMAL + │ │ │ │ ├── max1-row + │ │ │ │ │ ├── columns: n:13!null + │ │ │ │ │ └── project + │ │ │ │ │ ├── columns: n:13!null + │ │ │ │ │ ├── values + │ │ │ │ │ │ └── () + │ │ │ │ │ └── projections + │ │ │ │ │ └── 1.45 [as=n:13] + │ │ │ │ └── filters (true) + │ │ │ └── projections + │ │ │ └── assignment-cast: DECIMAL(10) [as=column14:14] + │ │ │ └── n:13 + │ │ └── projections + │ │ └── column14:14::DECIMAL + c:9::DECIMAL [as=d_comp:15] + │ └── projections + │ └── assignment-cast: DECIMAL(10,1) [as=column16:16] + │ └── d_comp:15 + └── projections + ├── round(column14:14) = column14:14 [as=check1:17] + └── b:8[0] > 1 [as=check2:18] + +# Test update with a multi-column subquery that requires assignment casts. +build +UPDATE decimals SET (a, c)=(SELECT u, u*10.0 FROM uv WHERE decimals.c = uv.u) +---- +update decimals + ├── columns: + ├── fetch columns: a:7 b:8 c:9 d:10 + ├── update-mapping: + │ ├── column19:19 => a:1 + │ ├── column20:20 => c:3 + │ └── column22:22 => d:4 + ├── check columns: check1:23 + └── project + ├── columns: check1:23 check2:24 a:7!null b:8 c:9 d:10 decimals.crdb_internal_mvcc_timestamp:11 decimals.tableoid:12 column19:19 column20:20 column22:22 + ├── project + │ ├── columns: column22:22 a:7!null b:8 c:9 d:10 decimals.crdb_internal_mvcc_timestamp:11 decimals.tableoid:12 column19:19 column20:20 + │ ├── project + │ │ ├── columns: d_comp:21 a:7!null b:8 c:9 d:10 decimals.crdb_internal_mvcc_timestamp:11 decimals.tableoid:12 column19:19 column20:20 + │ │ ├── project + │ │ │ ├── columns: column19:19 column20:20 a:7!null b:8 c:9 d:10 decimals.crdb_internal_mvcc_timestamp:11 decimals.tableoid:12 + │ │ │ ├── left-join-apply + │ │ │ │ ├── columns: a:7!null b:8 c:9 d:10 decimals.crdb_internal_mvcc_timestamp:11 decimals.tableoid:12 u:13 "?column?":18 + │ │ │ │ ├── scan decimals + │ │ │ │ │ ├── columns: a:7!null b:8 c:9 d:10 decimals.crdb_internal_mvcc_timestamp:11 decimals.tableoid:12 + │ │ │ │ │ └── computed column expressions + │ │ │ │ │ └── d:10 + │ │ │ │ │ └── a:7::DECIMAL + c:9::DECIMAL + │ │ │ │ ├── max1-row + │ │ │ │ │ ├── columns: u:13!null "?column?":18!null + │ │ │ │ │ └── project + │ │ │ │ │ ├── columns: "?column?":18!null u:13!null + │ │ │ │ │ ├── select + │ │ │ │ │ │ ├── columns: u:13!null v:14 rowid:15!null uv.crdb_internal_mvcc_timestamp:16 uv.tableoid:17 + │ │ │ │ │ │ ├── scan uv + │ │ │ │ │ │ │ └── columns: u:13 v:14 rowid:15!null uv.crdb_internal_mvcc_timestamp:16 uv.tableoid:17 + │ │ │ │ │ │ └── filters + │ │ │ │ │ │ └── c:9 = u:13 + │ │ │ │ │ └── projections + │ │ │ │ │ └── u:13 * 10.0 [as="?column?":18] + │ │ │ │ └── filters (true) + │ │ │ └── projections + │ │ │ ├── assignment-cast: DECIMAL(10) [as=column19:19] + │ │ │ │ └── u:13 + │ │ │ └── assignment-cast: DECIMAL(10,1) [as=column20:20] + │ │ │ └── "?column?":18 + │ │ └── projections + │ │ └── column19:19::DECIMAL + column20:20::DECIMAL [as=d_comp:21] + │ └── projections + │ └── assignment-cast: DECIMAL(10,1) [as=column22:22] + │ └── d_comp:21 + └── projections + ├── round(column19:19) = column19:19 [as=check1:23] + └── b:8[0] > 1 [as=check2:24] + +# Test combined standard and subquery update the requires assignment casts. +build +UPDATE assn_cast SET c=' ', (qc, i)=(SELECT 'foo', '1' FROM uv) +---- +update assn_cast + ├── columns: + ├── fetch columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 assn_cast.rowid:16 + ├── update-mapping: + │ ├── column27:27 => c:1 + │ ├── column28:28 => qc:2 + │ └── "?column?":25 => i:3 + └── project + ├── columns: d_comp_comp:29 c:10 qc:11 i:12 s:13 d:14 d_comp:15 assn_cast.rowid:16!null assn_cast.crdb_internal_mvcc_timestamp:17 assn_cast.tableoid:18 "?column?":25 column27:27!null column28:28 + ├── project + │ ├── columns: column27:27!null column28:28 c:10 qc:11 i:12 s:13 d:14 d_comp:15 assn_cast.rowid:16!null assn_cast.crdb_internal_mvcc_timestamp:17 assn_cast.tableoid:18 "?column?":25 + │ ├── project + │ │ ├── columns: c_new:26!null c:10 qc:11 i:12 s:13 d:14 d_comp:15 assn_cast.rowid:16!null assn_cast.crdb_internal_mvcc_timestamp:17 assn_cast.tableoid:18 "?column?":24 "?column?":25 + │ │ ├── left-join-apply + │ │ │ ├── columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 assn_cast.rowid:16!null assn_cast.crdb_internal_mvcc_timestamp:17 assn_cast.tableoid:18 "?column?":24 "?column?":25 + │ │ │ ├── scan assn_cast + │ │ │ │ ├── columns: c:10 qc:11 i:12 s:13 d:14 d_comp:15 assn_cast.rowid:16!null assn_cast.crdb_internal_mvcc_timestamp:17 assn_cast.tableoid:18 + │ │ │ │ └── computed column expressions + │ │ │ │ └── d_comp:15 + │ │ │ │ └── d:14::DECIMAL + 10.0 + │ │ │ ├── max1-row + │ │ │ │ ├── columns: "?column?":24!null "?column?":25!null + │ │ │ │ └── project + │ │ │ │ ├── columns: "?column?":24!null "?column?":25!null + │ │ │ │ ├── scan uv + │ │ │ │ │ └── columns: u:19 v:20 uv.rowid:21!null uv.crdb_internal_mvcc_timestamp:22 uv.tableoid:23 + │ │ │ │ └── projections + │ │ │ │ ├── 'foo' [as="?column?":24] + │ │ │ │ └── 1 [as="?column?":25] + │ │ │ └── filters (true) + │ │ └── projections + │ │ └── ' ' [as=c_new:26] + │ └── projections + │ ├── assignment-cast: CHAR [as=column27:27] + │ │ └── c_new:26 + │ └── assignment-cast: "char" [as=column28:28] + │ └── "?column?":24 + └── projections + └── d:14::DECIMAL + 10.0 [as=d_comp_comp:29] + +# Test ON UPDATE columns that require assignment casts. +build +UPDATE assn_cast_on_update SET i=1 +---- +update assn_cast_on_update + ├── columns: + ├── fetch columns: i:8 d:9 d2:10 d_comp:11 rowid:12 + ├── update-mapping: + │ ├── i_new:15 => i:1 + │ ├── column18:18 => d:2 + │ ├── column19:19 => d2:3 + │ └── column20:20 => d_comp:4 + └── project + ├── columns: column20:20!null i:8 d:9 d2:10 d_comp:11 rowid:12!null crdb_internal_mvcc_timestamp:13 tableoid:14 i_new:15!null column18:18!null column19:19!null + ├── project + │ ├── columns: column18:18!null column19:19!null i:8 d:9 d2:10 d_comp:11 rowid:12!null crdb_internal_mvcc_timestamp:13 tableoid:14 i_new:15!null + │ ├── project + │ │ ├── columns: d_on_update:16!null d2_on_update:17!null i:8 d:9 d2:10 d_comp:11 rowid:12!null crdb_internal_mvcc_timestamp:13 tableoid:14 i_new:15!null + │ │ ├── project + │ │ │ ├── columns: i_new:15!null i:8 d:9 d2:10 d_comp:11 rowid:12!null crdb_internal_mvcc_timestamp:13 tableoid:14 + │ │ │ ├── scan assn_cast_on_update + │ │ │ │ ├── columns: i:8 d:9 d2:10 d_comp:11 rowid:12!null crdb_internal_mvcc_timestamp:13 tableoid:14 + │ │ │ │ └── computed column expressions + │ │ │ │ └── d_comp:11 + │ │ │ │ └── d:9 │ │ │ └── projections - │ │ │ ├── crdb_internal.round_decimal_values(a_new:13, 0) [as=a_new:15] - │ │ │ └── crdb_internal.round_decimal_values(b_new:14, 1) [as=b_new:16] + │ │ │ └── 1 [as=i_new:15] │ │ └── projections - │ │ └── a_new:15 + c:9::DECIMAL [as=d_comp:17] + │ │ ├── 1.23 [as=d_on_update:16] + │ │ └── 1.23::DECIMAL(10,2) [as=d2_on_update:17] │ └── projections - │ └── crdb_internal.round_decimal_values(d_comp:17, 1) [as=d_comp:18] + │ ├── assignment-cast: DECIMAL(10,1) [as=column18:18] + │ │ └── d_on_update:16 + │ └── assignment-cast: DECIMAL(10,1) [as=column19:19] + │ └── d2_on_update:17 └── projections - ├── round(a_new:15) = a_new:15 [as=check1:19] - └── b_new:16[0] > 1 [as=check2:20] + └── assignment-cast: DECIMAL(10) [as=column20:20] + └── column18:18 # ------------------------------------------------------------------------------ # ON UPDATE tests. diff --git a/pkg/sql/opt/optbuilder/testdata/update-col-cast-bug b/pkg/sql/opt/optbuilder/testdata/update-col-cast-bug index 105ab55b9de1..41e2cba597a2 100644 --- a/pkg/sql/opt/optbuilder/testdata/update-col-cast-bug +++ b/pkg/sql/opt/optbuilder/testdata/update-col-cast-bug @@ -2,8 +2,6 @@ exec-ddl create table t (a int2, b int2, c int2 as (a + b) virtual) ---- -# TODO(mgartner): An assignment cast should be added so that the type of the -# insert column for c is int2, not int. build format=show-types update t set a = (with cte as (select 1:::int8) select t.c from cte limit 1) ---- @@ -19,36 +17,41 @@ with &1 (cte) ├── fetch columns: a:7(int2) b:8(int2) t.c:9(int2) rowid:10(int) ├── update-mapping: │ ├── a_new:16 => a:1 - │ └── c_comp:17 => t.c:3 + │ └── column18:18 => t.c:3 └── project - ├── columns: c_comp:17(int) a:7(int2) b:8(int2) t.c:9(int2) rowid:10(int!null) crdb_internal_mvcc_timestamp:11(decimal) tableoid:12(oid) a_new:16(int2) + ├── columns: column18:18(int2) a:7(int2) b:8(int2) t.c:9(int2) rowid:10(int!null) crdb_internal_mvcc_timestamp:11(decimal) tableoid:12(oid) a_new:16(int2) ├── project - │ ├── columns: a_new:16(int2) a:7(int2) b:8(int2) t.c:9(int2) rowid:10(int!null) crdb_internal_mvcc_timestamp:11(decimal) tableoid:12(oid) + │ ├── columns: c_comp:17(int) a:7(int2) b:8(int2) t.c:9(int2) rowid:10(int!null) crdb_internal_mvcc_timestamp:11(decimal) tableoid:12(oid) a_new:16(int2) │ ├── project - │ │ ├── columns: t.c:9(int2) a:7(int2) b:8(int2) rowid:10(int!null) crdb_internal_mvcc_timestamp:11(decimal) tableoid:12(oid) - │ │ ├── scan t - │ │ │ ├── columns: a:7(int2) b:8(int2) rowid:10(int!null) crdb_internal_mvcc_timestamp:11(decimal) tableoid:12(oid) - │ │ │ └── computed column expressions - │ │ │ └── t.c:9 - │ │ │ └── a:7::INT8 + b:8::INT8 [type=int] + │ │ ├── columns: a_new:16(int2) a:7(int2) b:8(int2) t.c:9(int2) rowid:10(int!null) crdb_internal_mvcc_timestamp:11(decimal) tableoid:12(oid) + │ │ ├── project + │ │ │ ├── columns: t.c:9(int2) a:7(int2) b:8(int2) rowid:10(int!null) crdb_internal_mvcc_timestamp:11(decimal) tableoid:12(oid) + │ │ │ ├── scan t + │ │ │ │ ├── columns: a:7(int2) b:8(int2) rowid:10(int!null) crdb_internal_mvcc_timestamp:11(decimal) tableoid:12(oid) + │ │ │ │ └── computed column expressions + │ │ │ │ └── t.c:9 + │ │ │ │ └── a:7::INT8 + b:8::INT8 [type=int] + │ │ │ └── projections + │ │ │ └── a:7::INT8 + b:8::INT8 [as=t.c:9, type=int] │ │ └── projections - │ │ └── a:7::INT8 + b:8::INT8 [as=t.c:9, type=int] + │ │ └── subquery [as=a_new:16, type=int2] + │ │ └── max1-row + │ │ ├── columns: c:15(int2) + │ │ └── limit + │ │ ├── columns: c:15(int2) + │ │ ├── project + │ │ │ ├── columns: c:15(int2) + │ │ │ ├── limit hint: 1.00 + │ │ │ ├── with-scan &1 (cte) + │ │ │ │ ├── columns: int8:14(int!null) + │ │ │ │ ├── mapping: + │ │ │ │ │ └── int8:13(int) => int8:14(int) + │ │ │ │ └── limit hint: 1.00 + │ │ │ └── projections + │ │ │ └── t.c:9 [as=c:15, type=int2] + │ │ └── 1 [type=int] │ └── projections - │ └── subquery [as=a_new:16, type=int2] - │ └── max1-row - │ ├── columns: c:15(int2) - │ └── limit - │ ├── columns: c:15(int2) - │ ├── project - │ │ ├── columns: c:15(int2) - │ │ ├── limit hint: 1.00 - │ │ ├── with-scan &1 (cte) - │ │ │ ├── columns: int8:14(int!null) - │ │ │ ├── mapping: - │ │ │ │ └── int8:13(int) => int8:14(int) - │ │ │ └── limit hint: 1.00 - │ │ └── projections - │ │ └── t.c:9 [as=c:15, type=int2] - │ └── 1 [type=int] + │ └── a_new:16::INT8 + b:8::INT8 [as=c_comp:17, type=int] └── projections - └── a_new:16::INT8 + b:8::INT8 [as=c_comp:17, type=int] + └── assignment-cast: INT2 [as=column18:18, type=int2] + └── c_comp:17 [type=int] diff --git a/pkg/sql/opt/optbuilder/testdata/update_from b/pkg/sql/opt/optbuilder/testdata/update_from index 05e4c0003412..43652b45fdb7 100644 --- a/pkg/sql/opt/optbuilder/testdata/update_from +++ b/pkg/sql/opt/optbuilder/testdata/update_from @@ -6,6 +6,10 @@ exec-ddl CREATE TABLE new_abc (a int, b int, c int) ---- +exec-ddl +CREATE TABLE dec (k INT PRIMARY KEY, d DECIMAL(10, 2)) +---- + # Test a self join. opt UPDATE abc SET b = other.b + 1, c = other.c + 1 FROM abc AS other WHERE abc.a = other.a @@ -357,10 +361,34 @@ update abc └── first-agg [as=ac.rowid:18] └── ac.rowid:18 +opt +UPDATE abc SET b = other.d FROM dec AS other WHERE abc.a = other.k +---- +update abc + ├── columns: + ├── fetch columns: a:6 b:7 c:8 + ├── update-mapping: + │ └── column15:15 => b:2 + └── project + ├── columns: column15:15 a:6!null b:7 c:8 k:11!null d:12 other.crdb_internal_mvcc_timestamp:13 other.tableoid:14 + ├── inner-join (merge) + │ ├── columns: a:6!null b:7 c:8 k:11!null d:12 other.crdb_internal_mvcc_timestamp:13 other.tableoid:14 + │ ├── left ordering: +6 + │ ├── right ordering: +11 + │ ├── scan abc + │ │ ├── columns: a:6!null b:7 c:8 + │ │ └── ordering: +6 + │ ├── scan dec [as=other] + │ │ ├── columns: k:11!null d:12 other.crdb_internal_mvcc_timestamp:13 other.tableoid:14 + │ │ └── ordering: +11 + │ └── filters (true) + └── projections + └── assignment-cast: INT8 [as=column15:15] + └── d:12 -# Regression test for #61520. The new value for column a (projected as b:8) -# should be in-scope when building the partial index PUT expression when the -# value in the FROM clause must be rounded. +# Regression test for #61520. The new value for column a should be in-scope when +# building the partial index PUT expression when the value in the FROM clause +# must be rounded. exec-ddl CREATE TABLE t61520 ( @@ -373,17 +401,17 @@ build UPDATE t61520 t SET a = v.b FROM (VALUES (1.0)) v(b) WHERE t.a = v.b RETURNING a, b ---- project - ├── columns: a:1 b:9 + ├── columns: a:1!null b:9 └── update t61520 [as=t] - ├── columns: a:1 rowid:2!null column1:9 + ├── columns: a:1!null rowid:2!null column1:9 ├── fetch columns: a:5 rowid:6 ├── update-mapping: - │ └── b:10 => a:1 + │ └── column10:10 => a:1 ├── check columns: check1:11 └── project - ├── columns: check1:11 a:5!null rowid:6!null crdb_internal_mvcc_timestamp:7 tableoid:8 column1:9!null b:10 + ├── columns: check1:11!null a:5!null rowid:6!null crdb_internal_mvcc_timestamp:7 tableoid:8 column1:9!null column10:10!null ├── project - │ ├── columns: b:10 a:5!null rowid:6!null crdb_internal_mvcc_timestamp:7 tableoid:8 column1:9!null + │ ├── columns: column10:10!null a:5!null rowid:6!null crdb_internal_mvcc_timestamp:7 tableoid:8 column1:9!null │ ├── select │ │ ├── columns: a:5!null rowid:6!null crdb_internal_mvcc_timestamp:7 tableoid:8 column1:9!null │ │ ├── inner-join (cross) @@ -397,6 +425,7 @@ project │ │ └── filters │ │ └── a:5 = column1:9 │ └── projections - │ └── crdb_internal.round_decimal_values(column1:9, 2) [as=b:10] + │ └── assignment-cast: DECIMAL(10,2) [as=column10:10] + │ └── column1:9 └── projections - └── b:10 > 0 [as=check1:11] + └── column10:10 > 0 [as=check1:11] diff --git a/pkg/sql/opt/optbuilder/testdata/upsert b/pkg/sql/opt/optbuilder/testdata/upsert index 8f445b54311e..592995c88ee0 100644 --- a/pkg/sql/opt/optbuilder/testdata/upsert +++ b/pkg/sql/opt/optbuilder/testdata/upsert @@ -1743,7 +1743,7 @@ upsert decimals │ │ │ │ │ │ │ ├── crdb_internal.round_decimal_values(column2:8, 1) [as=b:11] │ │ │ │ │ │ │ └── crdb_internal.round_decimal_values(c_default:9, 1) [as=c_default:12] │ │ │ │ │ │ └── projections - │ │ │ │ │ │ └── a:10 + c_default:12 [as=d_comp:13] + │ │ │ │ │ │ └── a:10::DECIMAL + c_default:12::DECIMAL [as=d_comp:13] │ │ │ │ │ └── projections │ │ │ │ │ └── crdb_internal.round_decimal_values(d_comp:13, 1) [as=d_comp:14] │ │ │ │ └── aggregations @@ -1815,7 +1815,7 @@ upsert decimals │ │ │ │ │ │ │ ├── crdb_internal.round_decimal_values(b_default:8, 1) [as=b_default:11] │ │ │ │ │ │ │ └── crdb_internal.round_decimal_values(c_default:9, 1) [as=c_default:12] │ │ │ │ │ │ └── projections - │ │ │ │ │ │ └── a:10 + c_default:12 [as=d_comp:13] + │ │ │ │ │ │ └── a:10::DECIMAL + c_default:12::DECIMAL [as=d_comp:13] │ │ │ │ │ └── projections │ │ │ │ │ └── crdb_internal.round_decimal_values(d_comp:13, 1) [as=d_comp:14] │ │ │ │ └── aggregations @@ -1895,7 +1895,7 @@ upsert decimals │ │ │ │ │ │ │ │ │ ├── crdb_internal.round_decimal_values(column2:8, 1) [as=b:11] │ │ │ │ │ │ │ │ │ └── crdb_internal.round_decimal_values(c_default:9, 1) [as=c_default:12] │ │ │ │ │ │ │ │ └── projections - │ │ │ │ │ │ │ │ └── a:10 + c_default:12 [as=d_comp:13] + │ │ │ │ │ │ │ │ └── a:10::DECIMAL + c_default:12::DECIMAL [as=d_comp:13] │ │ │ │ │ │ │ └── projections │ │ │ │ │ │ │ └── crdb_internal.round_decimal_values(d_comp:13, 1) [as=d_comp:14] │ │ │ │ │ │ └── aggregations diff --git a/pkg/sql/opt/optbuilder/update.go b/pkg/sql/opt/optbuilder/update.go index 27e83b45c586..66927222f36c 100644 --- a/pkg/sql/opt/optbuilder/update.go +++ b/pkg/sql/opt/optbuilder/update.go @@ -104,7 +104,7 @@ func (b *Builder) buildUpdate(upd *tree.Update, inScope *scope) (outScope *scope mb.addTargetColsForUpdate(upd.Exprs) // Build each of the SET expressions. - mb.addUpdateCols(upd.Exprs) + mb.addUpdateCols(upd.Exprs, false /* isUpsert */) // Build the final update statement, including any returned expressions. if resultsNeeded(upd.Returning) { @@ -180,7 +180,7 @@ func (mb *mutationBuilder) addTargetColsForUpdate(exprs tree.UpdateExprs) { // Multiple subqueries result in multiple left joins successively wrapping the // input. A final Project operator is built if any single-column or tuple SET // expressions are present. -func (mb *mutationBuilder) addUpdateCols(exprs tree.UpdateExprs) { +func (mb *mutationBuilder) addUpdateCols(exprs tree.UpdateExprs, isUpsert bool) { // SET expressions should reject aggregates, generators, etc. scalarProps := &mb.b.semaCtx.Properties defer scalarProps.Restore(*scalarProps) @@ -215,16 +215,17 @@ func (mb *mutationBuilder) addUpdateCols(exprs tree.UpdateExprs) { } // Add new column to the projections scope. - // TODO(mgartner): Perform an assignment cast if necessary. texpr := inScope.resolveType(expr, targetCol.DatumType()) targetColName := targetCol.ColName() colName := scopeColName(targetColName).WithMetadataName(string(targetColName) + "_new") scopeCol := projectionsScope.addColumn(colName, texpr) mb.b.buildScalar(texpr, inScope, projectionsScope, scopeCol, nil) - // Type check the input expression against the corresponding table - // column. - checkDatumTypeFitsColumnType(targetCol, scopeCol.typ) + if isUpsert { + // Type check the input expression against the corresponding table + // column. + checkDatumTypeFitsColumnType(targetCol, scopeCol.typ) + } // Add the column ID to the list of columns to update. mb.updateColIDs[ord] = scopeCol.id @@ -244,10 +245,12 @@ func (mb *mutationBuilder) addUpdateCols(exprs tree.UpdateExprs) { for i := range subqueryScope.cols { ord := mb.tabID.ColumnOrdinal(mb.targetColList[n]) targetCol := mb.tab.Column(ord) - subqueryScope.cols[i].name = scopeColName(mb.tab.Column(ord).ColName()) - // Type check the input expression against the corresponding table - // column. - checkDatumTypeFitsColumnType(targetCol, subqueryScope.cols[i].typ) + subqueryScope.cols[i].name = scopeColName(targetCol.ColName()) + if isUpsert { + // Type check the input expression against the corresponding table + // column. + checkDatumTypeFitsColumnType(targetCol, subqueryScope.cols[i].typ) + } // Add the column ID to the list of columns to update. mb.updateColIDs[ord] = subqueryScope.cols[i].id @@ -288,15 +291,20 @@ func (mb *mutationBuilder) addUpdateCols(exprs tree.UpdateExprs) { mb.b.constructProjectForScope(mb.outScope, projectionsScope) mb.outScope = projectionsScope + if !isUpsert { + // Add assignment casts for update columns. + mb.addAssignmentCasts(mb.updateColIDs) + } + // Add additional columns for computed expressions that may depend on the // updated columns. - mb.addSynthesizedColsForUpdate() + mb.addSynthesizedColsForUpdate(isUpsert) } // addSynthesizedColsForUpdate wraps an Update input expression with a Project // operator containing any computed columns that need to be updated. This // includes write-only mutation columns that are computed. -func (mb *mutationBuilder) addSynthesizedColsForUpdate() { +func (mb *mutationBuilder) addSynthesizedColsForUpdate(isUpsert bool) { // Allow mutation columns to be referenced by other computed mutation // columns (otherwise the scope will raise an error if a mutation column // is referenced). These do not need to be set back to true again because @@ -315,10 +323,15 @@ func (mb *mutationBuilder) addSynthesizedColsForUpdate() { true, /* applyOnUpdate */ ) - // Possibly round DECIMAL-related columns containing update values. Do - // this before evaluating computed expressions, since those may depend on - // the inserted columns. - mb.roundDecimalValues(mb.updateColIDs, false /* roundComputedCols */) + if isUpsert { + // Possibly round DECIMAL-related columns containing update values. Do + // this before evaluating computed expressions, since those may depend on + // the inserted columns. + mb.roundDecimalValues(mb.updateColIDs, false /* roundComputedCols */) + } else { + // Add assignment casts for default column values. + mb.addAssignmentCasts(mb.updateColIDs) + } // Disambiguate names so that references in the computed expression refer to // the correct columns. @@ -327,8 +340,13 @@ func (mb *mutationBuilder) addSynthesizedColsForUpdate() { // Add all computed columns in case their values have changed. mb.addSynthesizedComputedCols(mb.updateColIDs, true /* restrict */) - // Possibly round DECIMAL-related computed columns. - mb.roundDecimalValues(mb.updateColIDs, true /* roundComputedCols */) + if isUpsert { + // Possibly round DECIMAL-related computed columns. + mb.roundDecimalValues(mb.updateColIDs, true /* roundComputedCols */) + } else { + // Add assignment casts for computed column values. + mb.addAssignmentCasts(mb.updateColIDs) + } } // buildUpdate constructs an Update operator, possibly wrapped by a Project diff --git a/pkg/sql/opt/optbuilder/util.go b/pkg/sql/opt/optbuilder/util.go index c4317c5ad207..98b0d4b7fba1 100644 --- a/pkg/sql/opt/optbuilder/util.go +++ b/pkg/sql/opt/optbuilder/util.go @@ -215,6 +215,7 @@ func (b *Builder) synthesizeColumn( // populateSynthesizedColumn is similar to synthesizeColumn, but it fills in // the given existing column rather than allocating a new one. func (b *Builder) populateSynthesizedColumn(col *scopeColumn, scalar opt.ScalarExpr) { + col.typ = scalar.DataType() colID := b.factory.Metadata().AddColumn(col.name.MetadataName(), col.typ) col.id = colID col.scalar = scalar diff --git a/pkg/sql/opt/xform/testdata/external/tpcc b/pkg/sql/opt/xform/testdata/external/tpcc index ba9154045033..c1ace1e23f6f 100644 --- a/pkg/sql/opt/xform/testdata/external/tpcc +++ b/pkg/sql/opt/xform/testdata/external/tpcc @@ -438,13 +438,13 @@ project ├── columns: w_id:1!null w_name:2 w_street_1:3 w_street_2:4 w_city:5 w_state:6 w_zip:7 ├── fetch columns: w_id:12 w_name:13 w_street_1:14 w_street_2:15 w_city:16 w_state:17 w_zip:18 w_tax:19 w_ytd:20 ├── update-mapping: - │ └── w_ytd_new:24 => w_ytd:9 + │ └── column24:24 => w_ytd:9 ├── cardinality: [0 - 1] ├── volatile, mutations ├── key: () ├── fd: ()-->(1-7) └── project - ├── columns: w_ytd_new:24 w_id:12!null w_name:13 w_street_1:14 w_street_2:15 w_city:16 w_state:17 w_zip:18 w_tax:19 w_ytd:20 + ├── columns: column24:24 w_id:12!null w_name:13 w_street_1:14 w_street_2:15 w_city:16 w_state:17 w_zip:18 w_tax:19 w_ytd:20 ├── cardinality: [0 - 1] ├── immutable ├── key: () @@ -456,7 +456,8 @@ project │ ├── key: () │ └── fd: ()-->(12-20) └── projections - └── crdb_internal.round_decimal_values(w_ytd:20::DECIMAL + 3860.61, 2) [as=w_ytd_new:24, outer=(20), immutable] + └── assignment-cast: DECIMAL(12,2) [as=column24:24, outer=(20), immutable] + └── w_ytd:20::DECIMAL + 3860.61 opt format=hide-qual UPDATE district SET d_ytd = d_ytd + 3860.61 WHERE (d_w_id = 10) AND (d_id = 5) @@ -472,13 +473,13 @@ project ├── columns: d_id:1!null d_w_id:2!null d_name:3 d_street_1:4 d_street_2:5 d_city:6 d_state:7 d_zip:8 ├── fetch columns: d_id:14 d_w_id:15 d_name:16 d_street_1:17 d_street_2:18 d_city:19 d_state:20 d_zip:21 d_tax:22 d_ytd:23 d_next_o_id:24 ├── update-mapping: - │ └── d_ytd_new:28 => d_ytd:10 + │ └── column28:28 => d_ytd:10 ├── cardinality: [0 - 1] ├── volatile, mutations ├── key: () ├── fd: ()-->(1-8) └── project - ├── columns: d_ytd_new:28 d_id:14!null d_w_id:15!null d_name:16 d_street_1:17 d_street_2:18 d_city:19 d_state:20 d_zip:21 d_tax:22 d_ytd:23 d_next_o_id:24 + ├── columns: column28:28 d_id:14!null d_w_id:15!null d_name:16 d_street_1:17 d_street_2:18 d_city:19 d_state:20 d_zip:21 d_tax:22 d_ytd:23 d_next_o_id:24 ├── cardinality: [0 - 1] ├── immutable ├── key: () @@ -490,7 +491,8 @@ project │ ├── key: () │ └── fd: ()-->(14-24) └── projections - └── crdb_internal.round_decimal_values(d_ytd:23::DECIMAL + 3860.61, 2) [as=d_ytd_new:28, outer=(23), immutable] + └── assignment-cast: DECIMAL(12,2) [as=column28:28, outer=(23), immutable] + └── d_ytd:23::DECIMAL + 3860.61 opt format=hide-qual SELECT c_id @@ -552,29 +554,29 @@ RETURNING CASE c_credit WHEN 'BC' THEN "left"(c_data, 200) ELSE '' END ---- project - ├── columns: c_first:4 c_middle:5 c_last:6 c_street_1:7 c_street_2:8 c_city:9 c_state:10 c_zip:11 c_phone:12 c_since:13 c_credit:14 c_credit_lim:15 c_discount:16 c_balance:17 case:53 + ├── columns: c_first:4 c_middle:5 c_last:6 c_street_1:7 c_street_2:8 c_city:9 c_state:10 c_zip:11 c_phone:12 c_since:13 c_credit:14 c_credit_lim:15 c_discount:16 c_balance:17 case:54 ├── cardinality: [0 - 1] ├── volatile, mutations ├── key: () - ├── fd: ()-->(4-17,53) + ├── fd: ()-->(4-17,54) ├── update customer │ ├── columns: c_id:1!null c_d_id:2!null c_w_id:3!null c_first:4 c_middle:5 c_last:6 c_street_1:7 c_street_2:8 c_city:9 c_state:10 c_zip:11 c_phone:12 c_since:13 c_credit:14 c_credit_lim:15 c_discount:16 c_balance:17 c_data:21 │ ├── fetch columns: c_id:24 c_d_id:25 c_w_id:26 c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 │ ├── update-mapping: - │ │ ├── c_balance_new:51 => c_balance:17 - │ │ ├── c_ytd_payment_new:52 => c_ytd_payment:18 + │ │ ├── column51:51 => c_balance:17 + │ │ ├── column52:52 => c_ytd_payment:18 │ │ ├── c_payment_cnt_new:49 => c_payment_cnt:19 - │ │ └── c_data_new:50 => c_data:21 + │ │ └── column53:53 => c_data:21 │ ├── cardinality: [0 - 1] │ ├── volatile, mutations │ ├── key: () │ ├── fd: ()-->(1-17,21) │ └── project - │ ├── columns: c_balance_new:51 c_ytd_payment_new:52 c_payment_cnt_new:49 c_data_new:50 c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 + │ ├── columns: column51:51 column52:52 column53:53 c_payment_cnt_new:49 c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 │ ├── cardinality: [0 - 1] │ ├── immutable │ ├── key: () - │ ├── fd: ()-->(24-44,49-52) + │ ├── fd: ()-->(24-44,49,51-53) │ ├── scan customer │ │ ├── columns: c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 │ │ ├── constraint: /26/25/24: [/10/5/1343 - /10/5/1343] @@ -582,12 +584,15 @@ project │ │ ├── key: () │ │ └── fd: ()-->(24-44) │ └── projections - │ ├── crdb_internal.round_decimal_values(c_balance:40::DECIMAL - 3860.61, 2) [as=c_balance_new:51, outer=(40), immutable] - │ ├── crdb_internal.round_decimal_values(c_ytd_payment:41::DECIMAL + 3860.61, 2) [as=c_ytd_payment_new:52, outer=(41), immutable] - │ ├── c_payment_cnt:42 + 1 [as=c_payment_cnt_new:49, outer=(42), immutable] - │ └── CASE c_credit:37 WHEN 'BC' THEN left((((((c_id:24::STRING || c_d_id:25::STRING) || c_w_id:26::STRING) || '5') || '10') || '3860.61') || c_data:44::STRING, 500) ELSE c_data:44::STRING END [as=c_data_new:50, outer=(24-26,37,44), immutable] + │ ├── assignment-cast: DECIMAL(12,2) [as=column51:51, outer=(40), immutable] + │ │ └── c_balance:40::DECIMAL - 3860.61 + │ ├── assignment-cast: DECIMAL(12,2) [as=column52:52, outer=(41), immutable] + │ │ └── c_ytd_payment:41::DECIMAL + 3860.61 + │ ├── assignment-cast: VARCHAR(500) [as=column53:53, outer=(24-26,37,44), immutable] + │ │ └── CASE c_credit:37 WHEN 'BC' THEN left((((((c_id:24::STRING || c_d_id:25::STRING) || c_w_id:26::STRING) || '5') || '10') || '3860.61') || c_data:44::STRING, 500) ELSE c_data:44::STRING END + │ └── c_payment_cnt:42 + 1 [as=c_payment_cnt_new:49, outer=(42), immutable] └── projections - └── CASE c_credit:14 WHEN 'BC' THEN left(c_data:21, 200) ELSE '' END [as=case:53, outer=(14,21), immutable] + └── CASE c_credit:14 WHEN 'BC' THEN left(c_data:21, 200) ELSE '' END [as=case:54, outer=(14,21), immutable] opt format=hide-qual INSERT INTO history @@ -877,12 +882,12 @@ update customer ├── columns: ├── fetch columns: c_id:24 c_d_id:25 c_w_id:26 c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 ├── update-mapping: - │ ├── c_balance_new:49 => c_balance:17 + │ ├── column49:49 => c_balance:17 │ └── c_delivery_cnt_new:47 => c_delivery_cnt:20 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: c_balance_new:49 c_delivery_cnt_new:47 c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 + ├── columns: column49:49 c_delivery_cnt_new:47 c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 ├── cardinality: [0 - 10] ├── immutable ├── key: (24,25) @@ -904,7 +909,8 @@ update customer │ ├── key: (24,25) │ └── fd: ()-->(26), (24,25)-->(27-44) └── projections - ├── crdb_internal.round_decimal_values(c_balance:40::DECIMAL + CASE c_d_id:25 WHEN 6 THEN 57214.780000 WHEN 8 THEN 67755.430000 WHEN 1 THEN 51177.840000 WHEN 2 THEN 73840.700000 WHEN 4 THEN 45906.990000 WHEN 9 THEN 32523.760000 WHEN 10 THEN 20240.200000 WHEN 3 THEN 75299.790000 WHEN 5 THEN 56543.340000 WHEN 7 THEN 67157.940000 ELSE CAST(NULL AS DECIMAL) END, 2) [as=c_balance_new:49, outer=(25,40), immutable] + ├── assignment-cast: DECIMAL(12,2) [as=column49:49, outer=(25,40), immutable] + │ └── c_balance:40::DECIMAL + CASE c_d_id:25 WHEN 6 THEN 57214.780000 WHEN 8 THEN 67755.430000 WHEN 1 THEN 51177.840000 WHEN 2 THEN 73840.700000 WHEN 4 THEN 45906.990000 WHEN 9 THEN 32523.760000 WHEN 10 THEN 20240.200000 WHEN 3 THEN 75299.790000 WHEN 5 THEN 56543.340000 WHEN 7 THEN 67157.940000 ELSE CAST(NULL AS DECIMAL) END └── c_delivery_cnt:43 + 1 [as=c_delivery_cnt_new:47, outer=(43), immutable] opt format=hide-qual diff --git a/pkg/sql/opt/xform/testdata/external/tpcc-later-stats b/pkg/sql/opt/xform/testdata/external/tpcc-later-stats index b608b6b7d098..687a8adfdc4d 100644 --- a/pkg/sql/opt/xform/testdata/external/tpcc-later-stats +++ b/pkg/sql/opt/xform/testdata/external/tpcc-later-stats @@ -441,13 +441,13 @@ project ├── columns: w_id:1!null w_name:2 w_street_1:3 w_street_2:4 w_city:5 w_state:6 w_zip:7 ├── fetch columns: w_id:12 w_name:13 w_street_1:14 w_street_2:15 w_city:16 w_state:17 w_zip:18 w_tax:19 w_ytd:20 ├── update-mapping: - │ └── w_ytd_new:24 => w_ytd:9 + │ └── column24:24 => w_ytd:9 ├── cardinality: [0 - 1] ├── volatile, mutations ├── key: () ├── fd: ()-->(1-7) └── project - ├── columns: w_ytd_new:24 w_id:12!null w_name:13 w_street_1:14 w_street_2:15 w_city:16 w_state:17 w_zip:18 w_tax:19 w_ytd:20 + ├── columns: column24:24 w_id:12!null w_name:13 w_street_1:14 w_street_2:15 w_city:16 w_state:17 w_zip:18 w_tax:19 w_ytd:20 ├── cardinality: [0 - 1] ├── immutable ├── key: () @@ -459,7 +459,8 @@ project │ ├── key: () │ └── fd: ()-->(12-20) └── projections - └── crdb_internal.round_decimal_values(w_ytd:20::DECIMAL + 3860.61, 2) [as=w_ytd_new:24, outer=(20), immutable] + └── assignment-cast: DECIMAL(12,2) [as=column24:24, outer=(20), immutable] + └── w_ytd:20::DECIMAL + 3860.61 opt format=hide-qual UPDATE district SET d_ytd = d_ytd + 3860.61 WHERE (d_w_id = 10) AND (d_id = 5) @@ -475,13 +476,13 @@ project ├── columns: d_id:1!null d_w_id:2!null d_name:3 d_street_1:4 d_street_2:5 d_city:6 d_state:7 d_zip:8 ├── fetch columns: d_id:14 d_w_id:15 d_name:16 d_street_1:17 d_street_2:18 d_city:19 d_state:20 d_zip:21 d_tax:22 d_ytd:23 d_next_o_id:24 ├── update-mapping: - │ └── d_ytd_new:28 => d_ytd:10 + │ └── column28:28 => d_ytd:10 ├── cardinality: [0 - 1] ├── volatile, mutations ├── key: () ├── fd: ()-->(1-8) └── project - ├── columns: d_ytd_new:28 d_id:14!null d_w_id:15!null d_name:16 d_street_1:17 d_street_2:18 d_city:19 d_state:20 d_zip:21 d_tax:22 d_ytd:23 d_next_o_id:24 + ├── columns: column28:28 d_id:14!null d_w_id:15!null d_name:16 d_street_1:17 d_street_2:18 d_city:19 d_state:20 d_zip:21 d_tax:22 d_ytd:23 d_next_o_id:24 ├── cardinality: [0 - 1] ├── immutable ├── key: () @@ -493,7 +494,8 @@ project │ ├── key: () │ └── fd: ()-->(14-24) └── projections - └── crdb_internal.round_decimal_values(d_ytd:23::DECIMAL + 3860.61, 2) [as=d_ytd_new:28, outer=(23), immutable] + └── assignment-cast: DECIMAL(12,2) [as=column28:28, outer=(23), immutable] + └── d_ytd:23::DECIMAL + 3860.61 opt format=hide-qual SELECT c_id @@ -555,29 +557,29 @@ RETURNING CASE c_credit WHEN 'BC' THEN "left"(c_data, 200) ELSE '' END ---- project - ├── columns: c_first:4 c_middle:5 c_last:6 c_street_1:7 c_street_2:8 c_city:9 c_state:10 c_zip:11 c_phone:12 c_since:13 c_credit:14 c_credit_lim:15 c_discount:16 c_balance:17 case:53 + ├── columns: c_first:4 c_middle:5 c_last:6 c_street_1:7 c_street_2:8 c_city:9 c_state:10 c_zip:11 c_phone:12 c_since:13 c_credit:14 c_credit_lim:15 c_discount:16 c_balance:17 case:54 ├── cardinality: [0 - 1] ├── volatile, mutations ├── key: () - ├── fd: ()-->(4-17,53) + ├── fd: ()-->(4-17,54) ├── update customer │ ├── columns: c_id:1!null c_d_id:2!null c_w_id:3!null c_first:4 c_middle:5 c_last:6 c_street_1:7 c_street_2:8 c_city:9 c_state:10 c_zip:11 c_phone:12 c_since:13 c_credit:14 c_credit_lim:15 c_discount:16 c_balance:17 c_data:21 │ ├── fetch columns: c_id:24 c_d_id:25 c_w_id:26 c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 │ ├── update-mapping: - │ │ ├── c_balance_new:51 => c_balance:17 - │ │ ├── c_ytd_payment_new:52 => c_ytd_payment:18 + │ │ ├── column51:51 => c_balance:17 + │ │ ├── column52:52 => c_ytd_payment:18 │ │ ├── c_payment_cnt_new:49 => c_payment_cnt:19 - │ │ └── c_data_new:50 => c_data:21 + │ │ └── column53:53 => c_data:21 │ ├── cardinality: [0 - 1] │ ├── volatile, mutations │ ├── key: () │ ├── fd: ()-->(1-17,21) │ └── project - │ ├── columns: c_balance_new:51 c_ytd_payment_new:52 c_payment_cnt_new:49 c_data_new:50 c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 + │ ├── columns: column51:51 column52:52 column53:53 c_payment_cnt_new:49 c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 │ ├── cardinality: [0 - 1] │ ├── immutable │ ├── key: () - │ ├── fd: ()-->(24-44,49-52) + │ ├── fd: ()-->(24-44,49,51-53) │ ├── scan customer │ │ ├── columns: c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 │ │ ├── constraint: /26/25/24: [/10/5/1343 - /10/5/1343] @@ -585,12 +587,15 @@ project │ │ ├── key: () │ │ └── fd: ()-->(24-44) │ └── projections - │ ├── crdb_internal.round_decimal_values(c_balance:40::DECIMAL - 3860.61, 2) [as=c_balance_new:51, outer=(40), immutable] - │ ├── crdb_internal.round_decimal_values(c_ytd_payment:41::DECIMAL + 3860.61, 2) [as=c_ytd_payment_new:52, outer=(41), immutable] - │ ├── c_payment_cnt:42 + 1 [as=c_payment_cnt_new:49, outer=(42), immutable] - │ └── CASE c_credit:37 WHEN 'BC' THEN left((((((c_id:24::STRING || c_d_id:25::STRING) || c_w_id:26::STRING) || '5') || '10') || '3860.61') || c_data:44::STRING, 500) ELSE c_data:44::STRING END [as=c_data_new:50, outer=(24-26,37,44), immutable] + │ ├── assignment-cast: DECIMAL(12,2) [as=column51:51, outer=(40), immutable] + │ │ └── c_balance:40::DECIMAL - 3860.61 + │ ├── assignment-cast: DECIMAL(12,2) [as=column52:52, outer=(41), immutable] + │ │ └── c_ytd_payment:41::DECIMAL + 3860.61 + │ ├── assignment-cast: VARCHAR(500) [as=column53:53, outer=(24-26,37,44), immutable] + │ │ └── CASE c_credit:37 WHEN 'BC' THEN left((((((c_id:24::STRING || c_d_id:25::STRING) || c_w_id:26::STRING) || '5') || '10') || '3860.61') || c_data:44::STRING, 500) ELSE c_data:44::STRING END + │ └── c_payment_cnt:42 + 1 [as=c_payment_cnt_new:49, outer=(42), immutable] └── projections - └── CASE c_credit:14 WHEN 'BC' THEN left(c_data:21, 200) ELSE '' END [as=case:53, outer=(14,21), immutable] + └── CASE c_credit:14 WHEN 'BC' THEN left(c_data:21, 200) ELSE '' END [as=case:54, outer=(14,21), immutable] opt format=hide-qual INSERT INTO history @@ -880,12 +885,12 @@ update customer ├── columns: ├── fetch columns: c_id:24 c_d_id:25 c_w_id:26 c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 ├── update-mapping: - │ ├── c_balance_new:49 => c_balance:17 + │ ├── column49:49 => c_balance:17 │ └── c_delivery_cnt_new:47 => c_delivery_cnt:20 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: c_balance_new:49 c_delivery_cnt_new:47 c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 + ├── columns: column49:49 c_delivery_cnt_new:47 c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 ├── cardinality: [0 - 10] ├── immutable ├── key: (24,25) @@ -907,7 +912,8 @@ update customer │ ├── key: (24,25) │ └── fd: ()-->(26), (24,25)-->(27-44) └── projections - ├── crdb_internal.round_decimal_values(c_balance:40::DECIMAL + CASE c_d_id:25 WHEN 6 THEN 57214.780000 WHEN 8 THEN 67755.430000 WHEN 1 THEN 51177.840000 WHEN 2 THEN 73840.700000 WHEN 4 THEN 45906.990000 WHEN 9 THEN 32523.760000 WHEN 10 THEN 20240.200000 WHEN 3 THEN 75299.790000 WHEN 5 THEN 56543.340000 WHEN 7 THEN 67157.940000 ELSE CAST(NULL AS DECIMAL) END, 2) [as=c_balance_new:49, outer=(25,40), immutable] + ├── assignment-cast: DECIMAL(12,2) [as=column49:49, outer=(25,40), immutable] + │ └── c_balance:40::DECIMAL + CASE c_d_id:25 WHEN 6 THEN 57214.780000 WHEN 8 THEN 67755.430000 WHEN 1 THEN 51177.840000 WHEN 2 THEN 73840.700000 WHEN 4 THEN 45906.990000 WHEN 9 THEN 32523.760000 WHEN 10 THEN 20240.200000 WHEN 3 THEN 75299.790000 WHEN 5 THEN 56543.340000 WHEN 7 THEN 67157.940000 ELSE CAST(NULL AS DECIMAL) END └── c_delivery_cnt:43 + 1 [as=c_delivery_cnt_new:47, outer=(43), immutable] opt format=hide-qual diff --git a/pkg/sql/opt/xform/testdata/external/tpcc-no-stats b/pkg/sql/opt/xform/testdata/external/tpcc-no-stats index 86be9e049ced..1e9e5dd53d77 100644 --- a/pkg/sql/opt/xform/testdata/external/tpcc-no-stats +++ b/pkg/sql/opt/xform/testdata/external/tpcc-no-stats @@ -435,13 +435,13 @@ project ├── columns: w_id:1!null w_name:2 w_street_1:3 w_street_2:4 w_city:5 w_state:6 w_zip:7 ├── fetch columns: w_id:12 w_name:13 w_street_1:14 w_street_2:15 w_city:16 w_state:17 w_zip:18 w_tax:19 w_ytd:20 ├── update-mapping: - │ └── w_ytd_new:24 => w_ytd:9 + │ └── column24:24 => w_ytd:9 ├── cardinality: [0 - 1] ├── volatile, mutations ├── key: () ├── fd: ()-->(1-7) └── project - ├── columns: w_ytd_new:24 w_id:12!null w_name:13 w_street_1:14 w_street_2:15 w_city:16 w_state:17 w_zip:18 w_tax:19 w_ytd:20 + ├── columns: column24:24 w_id:12!null w_name:13 w_street_1:14 w_street_2:15 w_city:16 w_state:17 w_zip:18 w_tax:19 w_ytd:20 ├── cardinality: [0 - 1] ├── immutable ├── key: () @@ -453,7 +453,8 @@ project │ ├── key: () │ └── fd: ()-->(12-20) └── projections - └── crdb_internal.round_decimal_values(w_ytd:20::DECIMAL + 3860.61, 2) [as=w_ytd_new:24, outer=(20), immutable] + └── assignment-cast: DECIMAL(12,2) [as=column24:24, outer=(20), immutable] + └── w_ytd:20::DECIMAL + 3860.61 opt format=hide-qual UPDATE district SET d_ytd = d_ytd + 3860.61 WHERE (d_w_id = 10) AND (d_id = 5) @@ -469,13 +470,13 @@ project ├── columns: d_id:1!null d_w_id:2!null d_name:3 d_street_1:4 d_street_2:5 d_city:6 d_state:7 d_zip:8 ├── fetch columns: d_id:14 d_w_id:15 d_name:16 d_street_1:17 d_street_2:18 d_city:19 d_state:20 d_zip:21 d_tax:22 d_ytd:23 d_next_o_id:24 ├── update-mapping: - │ └── d_ytd_new:28 => d_ytd:10 + │ └── column28:28 => d_ytd:10 ├── cardinality: [0 - 1] ├── volatile, mutations ├── key: () ├── fd: ()-->(1-8) └── project - ├── columns: d_ytd_new:28 d_id:14!null d_w_id:15!null d_name:16 d_street_1:17 d_street_2:18 d_city:19 d_state:20 d_zip:21 d_tax:22 d_ytd:23 d_next_o_id:24 + ├── columns: column28:28 d_id:14!null d_w_id:15!null d_name:16 d_street_1:17 d_street_2:18 d_city:19 d_state:20 d_zip:21 d_tax:22 d_ytd:23 d_next_o_id:24 ├── cardinality: [0 - 1] ├── immutable ├── key: () @@ -487,7 +488,8 @@ project │ ├── key: () │ └── fd: ()-->(14-24) └── projections - └── crdb_internal.round_decimal_values(d_ytd:23::DECIMAL + 3860.61, 2) [as=d_ytd_new:28, outer=(23), immutable] + └── assignment-cast: DECIMAL(12,2) [as=column28:28, outer=(23), immutable] + └── d_ytd:23::DECIMAL + 3860.61 opt format=hide-qual SELECT c_id @@ -549,29 +551,29 @@ RETURNING CASE c_credit WHEN 'BC' THEN "left"(c_data, 200) ELSE '' END ---- project - ├── columns: c_first:4 c_middle:5 c_last:6 c_street_1:7 c_street_2:8 c_city:9 c_state:10 c_zip:11 c_phone:12 c_since:13 c_credit:14 c_credit_lim:15 c_discount:16 c_balance:17 case:53 + ├── columns: c_first:4 c_middle:5 c_last:6 c_street_1:7 c_street_2:8 c_city:9 c_state:10 c_zip:11 c_phone:12 c_since:13 c_credit:14 c_credit_lim:15 c_discount:16 c_balance:17 case:54 ├── cardinality: [0 - 1] ├── volatile, mutations ├── key: () - ├── fd: ()-->(4-17,53) + ├── fd: ()-->(4-17,54) ├── update customer │ ├── columns: c_id:1!null c_d_id:2!null c_w_id:3!null c_first:4 c_middle:5 c_last:6 c_street_1:7 c_street_2:8 c_city:9 c_state:10 c_zip:11 c_phone:12 c_since:13 c_credit:14 c_credit_lim:15 c_discount:16 c_balance:17 c_data:21 │ ├── fetch columns: c_id:24 c_d_id:25 c_w_id:26 c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 │ ├── update-mapping: - │ │ ├── c_balance_new:51 => c_balance:17 - │ │ ├── c_ytd_payment_new:52 => c_ytd_payment:18 + │ │ ├── column51:51 => c_balance:17 + │ │ ├── column52:52 => c_ytd_payment:18 │ │ ├── c_payment_cnt_new:49 => c_payment_cnt:19 - │ │ └── c_data_new:50 => c_data:21 + │ │ └── column53:53 => c_data:21 │ ├── cardinality: [0 - 1] │ ├── volatile, mutations │ ├── key: () │ ├── fd: ()-->(1-17,21) │ └── project - │ ├── columns: c_balance_new:51 c_ytd_payment_new:52 c_payment_cnt_new:49 c_data_new:50 c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 + │ ├── columns: column51:51 column52:52 column53:53 c_payment_cnt_new:49 c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 │ ├── cardinality: [0 - 1] │ ├── immutable │ ├── key: () - │ ├── fd: ()-->(24-44,49-52) + │ ├── fd: ()-->(24-44,49,51-53) │ ├── scan customer │ │ ├── columns: c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 │ │ ├── constraint: /26/25/24: [/10/5/1343 - /10/5/1343] @@ -579,12 +581,15 @@ project │ │ ├── key: () │ │ └── fd: ()-->(24-44) │ └── projections - │ ├── crdb_internal.round_decimal_values(c_balance:40::DECIMAL - 3860.61, 2) [as=c_balance_new:51, outer=(40), immutable] - │ ├── crdb_internal.round_decimal_values(c_ytd_payment:41::DECIMAL + 3860.61, 2) [as=c_ytd_payment_new:52, outer=(41), immutable] - │ ├── c_payment_cnt:42 + 1 [as=c_payment_cnt_new:49, outer=(42), immutable] - │ └── CASE c_credit:37 WHEN 'BC' THEN left((((((c_id:24::STRING || c_d_id:25::STRING) || c_w_id:26::STRING) || '5') || '10') || '3860.61') || c_data:44::STRING, 500) ELSE c_data:44::STRING END [as=c_data_new:50, outer=(24-26,37,44), immutable] + │ ├── assignment-cast: DECIMAL(12,2) [as=column51:51, outer=(40), immutable] + │ │ └── c_balance:40::DECIMAL - 3860.61 + │ ├── assignment-cast: DECIMAL(12,2) [as=column52:52, outer=(41), immutable] + │ │ └── c_ytd_payment:41::DECIMAL + 3860.61 + │ ├── assignment-cast: VARCHAR(500) [as=column53:53, outer=(24-26,37,44), immutable] + │ │ └── CASE c_credit:37 WHEN 'BC' THEN left((((((c_id:24::STRING || c_d_id:25::STRING) || c_w_id:26::STRING) || '5') || '10') || '3860.61') || c_data:44::STRING, 500) ELSE c_data:44::STRING END + │ └── c_payment_cnt:42 + 1 [as=c_payment_cnt_new:49, outer=(42), immutable] └── projections - └── CASE c_credit:14 WHEN 'BC' THEN left(c_data:21, 200) ELSE '' END [as=case:53, outer=(14,21), immutable] + └── CASE c_credit:14 WHEN 'BC' THEN left(c_data:21, 200) ELSE '' END [as=case:54, outer=(14,21), immutable] opt format=hide-qual INSERT INTO history @@ -879,12 +884,12 @@ update customer ├── columns: ├── fetch columns: c_id:24 c_d_id:25 c_w_id:26 c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 ├── update-mapping: - │ ├── c_balance_new:49 => c_balance:17 + │ ├── column49:49 => c_balance:17 │ └── c_delivery_cnt_new:47 => c_delivery_cnt:20 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: c_balance_new:49 c_delivery_cnt_new:47 c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 + ├── columns: column49:49 c_delivery_cnt_new:47 c_id:24!null c_d_id:25!null c_w_id:26!null c_first:27 c_middle:28 c_last:29 c_street_1:30 c_street_2:31 c_city:32 c_state:33 c_zip:34 c_phone:35 c_since:36 c_credit:37 c_credit_lim:38 c_discount:39 c_balance:40 c_ytd_payment:41 c_payment_cnt:42 c_delivery_cnt:43 c_data:44 ├── cardinality: [0 - 10] ├── immutable ├── key: (24,25) @@ -906,7 +911,8 @@ update customer │ ├── key: (24,25) │ └── fd: ()-->(26), (24,25)-->(27-44) └── projections - ├── crdb_internal.round_decimal_values(c_balance:40::DECIMAL + CASE c_d_id:25 WHEN 6 THEN 57214.780000 WHEN 8 THEN 67755.430000 WHEN 1 THEN 51177.840000 WHEN 2 THEN 73840.700000 WHEN 4 THEN 45906.990000 WHEN 9 THEN 32523.760000 WHEN 10 THEN 20240.200000 WHEN 3 THEN 75299.790000 WHEN 5 THEN 56543.340000 WHEN 7 THEN 67157.940000 ELSE CAST(NULL AS DECIMAL) END, 2) [as=c_balance_new:49, outer=(25,40), immutable] + ├── assignment-cast: DECIMAL(12,2) [as=column49:49, outer=(25,40), immutable] + │ └── c_balance:40::DECIMAL + CASE c_d_id:25 WHEN 6 THEN 57214.780000 WHEN 8 THEN 67755.430000 WHEN 1 THEN 51177.840000 WHEN 2 THEN 73840.700000 WHEN 4 THEN 45906.990000 WHEN 9 THEN 32523.760000 WHEN 10 THEN 20240.200000 WHEN 3 THEN 75299.790000 WHEN 5 THEN 56543.340000 WHEN 7 THEN 67157.940000 ELSE CAST(NULL AS DECIMAL) END └── c_delivery_cnt:43 + 1 [as=c_delivery_cnt_new:47, outer=(43), immutable] opt format=hide-qual diff --git a/pkg/sql/opt/xform/testdata/external/tpce b/pkg/sql/opt/xform/testdata/external/tpce index 5dc6758e7a4c..e13b7368e070 100644 --- a/pkg/sql/opt/xform/testdata/external/tpce +++ b/pkg/sql/opt/xform/testdata/external/tpce @@ -552,10 +552,10 @@ update_trade_submitted AS ( SELECT * FROM request_list; ---- with &2 (update_last_trade) - ├── columns: tr_t_id:138!null tr_bid_price:139!null tr_tt_id:140!null tr_qty:141!null + ├── columns: tr_t_id:139!null tr_bid_price:140!null tr_tt_id:141!null tr_qty:142!null ├── volatile, mutations - ├── key: (138) - ├── fd: (138)-->(139-141) + ├── key: (139) + ├── fd: (139)-->(140-142) ├── project │ ├── columns: "?column?":19 │ ├── cardinality: [0 - 1] @@ -567,14 +567,14 @@ with &2 (update_last_trade) │ │ ├── fetch columns: lt_s_symb:8 lt_dts:9 lt_price:10 lt_open_price:11 lt_vol:12 │ │ ├── update-mapping: │ │ │ ├── lt_dts_new:17 => lt_dts:2 - │ │ │ ├── lt_price_new:18 => lt_price:3 + │ │ │ ├── column18:18 => lt_price:3 │ │ │ └── lt_vol_new:15 => lt_vol:5 │ │ ├── cardinality: [0 - 1] │ │ ├── volatile, mutations │ │ ├── key: () │ │ ├── fd: ()-->(1) │ │ └── project - │ │ ├── columns: lt_price_new:18!null lt_vol_new:15!null lt_dts_new:17!null lt_s_symb:8!null lt_dts:9!null lt_price:10!null lt_open_price:11!null lt_vol:12!null + │ │ ├── columns: column18:18!null lt_vol_new:15!null lt_dts_new:17!null lt_s_symb:8!null lt_dts:9!null lt_price:10!null lt_open_price:11!null lt_vol:12!null │ │ ├── cardinality: [0 - 1] │ │ ├── immutable │ │ ├── key: () @@ -586,16 +586,16 @@ with &2 (update_last_trade) │ │ │ ├── key: () │ │ │ └── fd: ()-->(8-12) │ │ └── projections - │ │ ├── 1E+2 [as=lt_price_new:18] + │ │ ├── 100.00 [as=column18:18] │ │ ├── lt_vol:12 + 10 [as=lt_vol_new:15, outer=(12), immutable] │ │ └── '2020-06-15 22:27:42.148484' [as=lt_dts_new:17] │ └── projections │ └── NULL [as="?column?":19] └── with &3 (request_list) - ├── columns: tr_t_id:138!null tr_bid_price:139!null tr_tt_id:140!null tr_qty:141!null + ├── columns: tr_t_id:139!null tr_bid_price:140!null tr_tt_id:141!null tr_qty:142!null ├── volatile, mutations - ├── key: (138) - ├── fd: (138)-->(139-141) + ├── key: (139) + ├── fd: (139)-->(140-142) ├── project │ ├── columns: tr_bid_price:28!null trade_request.tr_t_id:20!null trade_request.tr_tt_id:21!null trade_request.tr_qty:23!null │ ├── immutable @@ -622,10 +622,10 @@ with &2 (update_last_trade) │ └── projections │ └── trade_request.tr_bid_price:24::FLOAT8 [as=tr_bid_price:28, outer=(24), immutable] └── with &4 (delete_trade_request) - ├── columns: tr_t_id:138!null tr_bid_price:139!null tr_tt_id:140!null tr_qty:141!null + ├── columns: tr_t_id:139!null tr_bid_price:140!null tr_tt_id:141!null tr_qty:142!null ├── volatile, mutations - ├── key: (138) - ├── fd: (138)-->(139-141) + ├── key: (139) + ├── fd: (139)-->(140-142) ├── project │ ├── columns: "?column?":50 │ ├── volatile, mutations @@ -661,10 +661,10 @@ with &2 (update_last_trade) │ └── projections │ └── NULL [as="?column?":50] └── with &6 (insert_trade_history) - ├── columns: tr_t_id:138!null tr_bid_price:139!null tr_tt_id:140!null tr_qty:141!null + ├── columns: tr_t_id:139!null tr_bid_price:140!null tr_tt_id:141!null tr_qty:142!null ├── volatile, mutations - ├── key: (138) - ├── fd: (138)-->(139-141) + ├── key: (139) + ├── fd: (139)-->(140-142) ├── project │ ├── columns: "?column?":86 │ ├── volatile, mutations @@ -719,27 +719,27 @@ with &2 (update_last_trade) │ └── projections │ └── NULL [as="?column?":86] └── with &8 (update_trade_submitted) - ├── columns: tr_t_id:138!null tr_bid_price:139!null tr_tt_id:140!null tr_qty:141!null + ├── columns: tr_t_id:139!null tr_bid_price:140!null tr_tt_id:141!null tr_qty:142!null ├── volatile, mutations - ├── key: (138) - ├── fd: (138)-->(139-141) + ├── key: (139) + ├── fd: (139)-->(140-142) ├── project - │ ├── columns: "?column?":137 + │ ├── columns: "?column?":138 │ ├── volatile, mutations - │ ├── fd: ()-->(137) + │ ├── fd: ()-->(138) │ ├── update trade │ │ ├── columns: t_id:87!null │ │ ├── fetch columns: t_id:104 t_dts:105 trade.t_st_id:106 t_tt_id:107 t_is_cash:108 t_s_symb:109 t_qty:110 t_bid_price:111 t_ca_id:112 t_exec_name:113 t_trade_price:114 t_chrg:115 t_comm:116 t_lifo:118 │ │ ├── update-mapping: │ │ │ ├── t_dts_new:126 => t_dts:88 - │ │ │ └── t_st_id_new:125 => trade.t_st_id:89 + │ │ │ └── column127:127 => trade.t_st_id:89 │ │ ├── input binding: &7 │ │ ├── volatile, mutations │ │ ├── key: (87) │ │ ├── project - │ │ │ ├── columns: t_st_id_new:125!null t_dts_new:126!null t_id:104!null t_dts:105!null trade.t_st_id:106!null t_tt_id:107!null t_is_cash:108!null t_s_symb:109!null t_qty:110!null t_bid_price:111!null t_ca_id:112!null t_exec_name:113!null t_trade_price:114 t_chrg:115!null t_comm:116!null t_lifo:118!null + │ │ │ ├── columns: column127:127!null t_dts_new:126!null t_id:104!null t_dts:105!null trade.t_st_id:106!null t_tt_id:107!null t_is_cash:108!null t_s_symb:109!null t_qty:110!null t_bid_price:111!null t_ca_id:112!null t_exec_name:113!null t_trade_price:114 t_chrg:115!null t_comm:116!null t_lifo:118!null │ │ │ ├── key: (104) - │ │ │ ├── fd: ()-->(125,126), (104)-->(105-116,118) + │ │ │ ├── fd: ()-->(126,127), (104)-->(105-116,118) │ │ │ ├── project │ │ │ │ ├── columns: t_id:104!null t_dts:105!null trade.t_st_id:106!null t_tt_id:107!null t_is_cash:108!null t_s_symb:109!null t_qty:110!null t_bid_price:111!null t_ca_id:112!null t_exec_name:113!null t_trade_price:114 t_chrg:115!null t_comm:116!null t_lifo:118!null │ │ │ │ ├── key: (104) @@ -757,32 +757,32 @@ with &2 (update_last_trade) │ │ │ │ │ └── key: (121) │ │ │ │ └── filters (true) │ │ │ └── projections - │ │ │ ├── 'SBMT' [as=t_st_id_new:125] + │ │ │ ├── 'SBMT' [as=column127:127] │ │ │ └── '2020-06-15 22:27:42.148484' [as=t_dts_new:126] │ │ └── f-k-checks │ │ └── f-k-checks-item: trade(t_st_id) -> status_type(st_id) │ │ └── anti-join (lookup status_type) - │ │ ├── columns: t_st_id:132!null - │ │ ├── key columns: [132] = [133] + │ │ ├── columns: t_st_id:133!null + │ │ ├── key columns: [133] = [134] │ │ ├── lookup columns are key - │ │ ├── fd: ()-->(132) + │ │ ├── fd: ()-->(133) │ │ ├── with-scan &7 - │ │ │ ├── columns: t_st_id:132!null + │ │ │ ├── columns: t_st_id:133!null │ │ │ ├── mapping: - │ │ │ │ └── t_st_id_new:125 => t_st_id:132 - │ │ │ └── fd: ()-->(132) + │ │ │ │ └── column127:127 => t_st_id:133 + │ │ │ └── fd: ()-->(133) │ │ └── filters (true) │ └── projections - │ └── NULL [as="?column?":137] + │ └── NULL [as="?column?":138] └── with-scan &3 (request_list) - ├── columns: tr_t_id:138!null tr_bid_price:139!null tr_tt_id:140!null tr_qty:141!null + ├── columns: tr_t_id:139!null tr_bid_price:140!null tr_tt_id:141!null tr_qty:142!null ├── mapping: - │ ├── trade_request.tr_t_id:20 => tr_t_id:138 - │ ├── tr_bid_price:28 => tr_bid_price:139 - │ ├── trade_request.tr_tt_id:21 => tr_tt_id:140 - │ └── trade_request.tr_qty:23 => tr_qty:141 - ├── key: (138) - └── fd: (138)-->(139-141) + │ ├── trade_request.tr_t_id:20 => tr_t_id:139 + │ ├── tr_bid_price:28 => tr_bid_price:140 + │ ├── trade_request.tr_tt_id:21 => tr_tt_id:141 + │ └── trade_request.tr_qty:23 => tr_qty:142 + ├── key: (139) + └── fd: (139)-->(140-142) # -------------------------------------------------- # T4 @@ -3654,15 +3654,15 @@ update holding_summary ├── columns: ├── fetch columns: hs_ca_id:6 hs_s_symb:7 hs_qty:8 ├── update-mapping: - │ └── hs_qty_new:11 => hs_qty:3 + │ └── column12:12 => hs_qty:3 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: hs_qty_new:11!null hs_ca_id:6!null hs_s_symb:7!null hs_qty:8!null + ├── columns: column12:12!null hs_ca_id:6!null hs_s_symb:7!null hs_qty:8!null ├── cardinality: [0 - 1] ├── immutable ├── key: () - ├── fd: ()-->(6-8,11) + ├── fd: ()-->(6-8,12) ├── scan holding_summary │ ├── columns: hs_ca_id:6!null hs_s_symb:7!null hs_qty:8!null │ ├── constraint: /6/7: [/0/'ROACH' - /0/'ROACH'] @@ -3670,7 +3670,8 @@ update holding_summary │ ├── key: () │ └── fd: ()-->(6-8) └── projections - └── hs_qty:8::INT8 + 10 [as=hs_qty_new:11, outer=(8), immutable] + └── assignment-cast: INT4 [as=column12:12, outer=(8), immutable] + └── hs_qty:8::INT8 + 10 # Q5 opt @@ -3784,15 +3785,15 @@ update holding ├── columns: ├── fetch columns: h_t_id:9 h_ca_id:10 h_s_symb:11 h_dts:12 h_price:13 h_qty:14 ├── update-mapping: - │ └── h_qty_new:17 => h_qty:6 + │ └── column18:18 => h_qty:6 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: h_qty_new:17!null h_t_id:9!null h_ca_id:10!null h_s_symb:11!null h_dts:12!null h_price:13!null h_qty:14!null + ├── columns: column18:18!null h_t_id:9!null h_ca_id:10!null h_s_symb:11!null h_dts:12!null h_price:13!null h_qty:14!null ├── cardinality: [0 - 1] ├── immutable ├── key: () - ├── fd: ()-->(9-14,17) + ├── fd: ()-->(9-14,18) ├── scan holding │ ├── columns: h_t_id:9!null h_ca_id:10!null h_s_symb:11!null h_dts:12!null h_price:13!null h_qty:14!null │ ├── constraint: /9: [/0 - /0] @@ -3800,7 +3801,8 @@ update holding │ ├── key: () │ └── fd: ()-->(9-14) └── projections - └── h_qty:14::INT8 + 10 [as=h_qty_new:17, outer=(14), immutable] + └── assignment-cast: INT4 [as=column18:18, outer=(14), immutable] + └── h_qty:14::INT8 + 10 # Q9 opt @@ -3942,20 +3944,20 @@ project │ ├── columns: t_id:1!null trade.t_tax:14!null │ ├── fetch columns: t_id:18 trade.t_tax:31 │ ├── update-mapping: - │ │ └── t_tax_new:46 => trade.t_tax:14 + │ │ └── column46:46 => trade.t_tax:14 │ ├── check columns: check5:51 │ ├── cardinality: [0 - 1] │ ├── volatile, mutations │ ├── key: () │ ├── fd: ()-->(1,14) │ └── project - │ ├── columns: check5:51 t_id:18!null trade.t_tax:31!null t_tax_new:46 + │ ├── columns: check5:51 t_id:18!null trade.t_tax:31!null column46:46 │ ├── cardinality: [0 - 1] │ ├── immutable │ ├── key: () │ ├── fd: ()-->(18,31,46,51) │ ├── project - │ │ ├── columns: t_tax_new:46 t_id:18!null trade.t_tax:31!null + │ │ ├── columns: column46:46 t_id:18!null trade.t_tax:31!null │ │ ├── cardinality: [0 - 1] │ │ ├── immutable │ │ ├── key: () @@ -3967,33 +3969,32 @@ project │ │ │ ├── key: () │ │ │ └── fd: ()-->(18,31) │ │ └── projections - │ │ └── function: crdb_internal.round_decimal_values [as=t_tax_new:46, immutable, subquery] - │ │ ├── mult - │ │ │ ├── subquery - │ │ │ │ └── scalar-group-by - │ │ │ │ ├── columns: sum:44 - │ │ │ │ ├── cardinality: [1 - 1] - │ │ │ │ ├── key: () - │ │ │ │ ├── fd: ()-->(44) - │ │ │ │ ├── inner-join (lookup taxrate) - │ │ │ │ │ ├── columns: tx_id:35!null tx_rate:37!null cx_tx_id:40!null cx_c_id:41!null - │ │ │ │ │ ├── key columns: [40] = [35] - │ │ │ │ │ ├── lookup columns are key - │ │ │ │ │ ├── key: (40) - │ │ │ │ │ ├── fd: ()-->(41), (35)-->(37), (35)==(40), (40)==(35) - │ │ │ │ │ ├── scan customer_taxrate@customer_taxrate_cx_c_id_idx - │ │ │ │ │ │ ├── columns: cx_tx_id:40!null cx_c_id:41!null - │ │ │ │ │ │ ├── constraint: /41/40: [/0 - /0] - │ │ │ │ │ │ ├── key: (40) - │ │ │ │ │ │ └── fd: ()-->(41) - │ │ │ │ │ └── filters (true) - │ │ │ │ └── aggregations - │ │ │ │ └── sum [as=sum:44, outer=(37)] - │ │ │ │ └── tx_rate:37 - │ │ │ └── 2E+1 - │ │ └── 2 + │ │ └── assignment-cast: DECIMAL(10,2) [as=column46:46, immutable, subquery] + │ │ └── mult + │ │ ├── subquery + │ │ │ └── scalar-group-by + │ │ │ ├── columns: sum:44 + │ │ │ ├── cardinality: [1 - 1] + │ │ │ ├── key: () + │ │ │ ├── fd: ()-->(44) + │ │ │ ├── inner-join (lookup taxrate) + │ │ │ │ ├── columns: tx_id:35!null tx_rate:37!null cx_tx_id:40!null cx_c_id:41!null + │ │ │ │ ├── key columns: [40] = [35] + │ │ │ │ ├── lookup columns are key + │ │ │ │ ├── key: (40) + │ │ │ │ ├── fd: ()-->(41), (35)-->(37), (35)==(40), (40)==(35) + │ │ │ │ ├── scan customer_taxrate@customer_taxrate_cx_c_id_idx + │ │ │ │ │ ├── columns: cx_tx_id:40!null cx_c_id:41!null + │ │ │ │ │ ├── constraint: /41/40: [/0 - /0] + │ │ │ │ │ ├── key: (40) + │ │ │ │ │ └── fd: ()-->(41) + │ │ │ │ └── filters (true) + │ │ │ └── aggregations + │ │ │ └── sum [as=sum:44, outer=(37)] + │ │ │ └── tx_rate:37 + │ │ └── 2E+1 │ └── projections - │ └── t_tax_new:46 >= 0 [as=check5:51, outer=(46), immutable] + │ └── column46:46 >= 0 [as=check5:51, outer=(46), immutable] └── projections └── trade.t_tax:14::FLOAT8 [as=t_tax:52, outer=(14), immutable] @@ -4157,36 +4158,36 @@ insert_trade_history AS ( SELECT 1 ---- with &2 (update_trade_commission) - ├── columns: "?column?":103!null + ├── columns: "?column?":104!null ├── cardinality: [1 - 1] ├── volatile, mutations ├── key: () - ├── fd: ()-->(103) + ├── fd: ()-->(104) ├── project - │ ├── columns: "?column?":51!null + │ ├── columns: "?column?":52!null │ ├── cardinality: [0 - 1] │ ├── volatile, mutations │ ├── key: () - │ ├── fd: ()-->(51) + │ ├── fd: ()-->(52) │ ├── update trade │ │ ├── columns: t_id:1!null │ │ ├── fetch columns: t_id:18 t_dts:19 trade.t_st_id:20 t_tt_id:21 t_is_cash:22 t_s_symb:23 t_qty:24 t_bid_price:25 t_ca_id:26 t_exec_name:27 t_trade_price:28 t_chrg:29 t_comm:30 t_lifo:32 │ │ ├── update-mapping: │ │ │ ├── t_dts_new:36 => t_dts:2 - │ │ │ ├── t_st_id_new:37 => trade.t_st_id:3 - │ │ │ ├── t_trade_price_new:39 => t_trade_price:11 - │ │ │ └── t_comm_new:40 => t_comm:13 - │ │ ├── check columns: check4:44 + │ │ │ ├── column39:39 => trade.t_st_id:3 + │ │ │ ├── column40:40 => t_trade_price:11 + │ │ │ └── column41:41 => t_comm:13 + │ │ ├── check columns: check4:45 │ │ ├── input binding: &1 │ │ ├── cardinality: [0 - 1] │ │ ├── volatile, mutations │ │ ├── key: () │ │ ├── fd: ()-->(1) │ │ ├── project - │ │ │ ├── columns: check4:44!null t_comm_new:40!null t_trade_price_new:39!null t_dts_new:36!null t_st_id_new:37!null t_id:18!null t_dts:19!null trade.t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null + │ │ │ ├── columns: check4:45!null column41:41!null column39:39!null column40:40!null t_dts_new:36!null t_id:18!null t_dts:19!null trade.t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null │ │ │ ├── cardinality: [0 - 1] │ │ │ ├── key: () - │ │ │ ├── fd: ()-->(18-30,32,36,37,39,40,44) + │ │ │ ├── fd: ()-->(18-30,32,36,39-41,45) │ │ │ ├── scan trade │ │ │ │ ├── columns: t_id:18!null t_dts:19!null trade.t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null │ │ │ │ ├── constraint: /18: [/0 - /0] @@ -4194,138 +4195,139 @@ with &2 (update_trade_commission) │ │ │ │ ├── key: () │ │ │ │ └── fd: ()-->(18-30,32) │ │ │ └── projections - │ │ │ ├── true [as=check4:44] - │ │ │ ├── 5E+1 [as=t_comm_new:40] - │ │ │ ├── 1E+2 [as=t_trade_price_new:39] - │ │ │ ├── '2020-06-15 22:27:42.148484' [as=t_dts_new:36] - │ │ │ └── 'ACTV' [as=t_st_id_new:37] + │ │ │ ├── true [as=check4:45] + │ │ │ ├── 50.00 [as=column41:41] + │ │ │ ├── 'ACTV' [as=column39:39] + │ │ │ ├── 100.00 [as=column40:40] + │ │ │ └── '2020-06-15 22:27:42.148484' [as=t_dts_new:36] │ │ └── f-k-checks │ │ └── f-k-checks-item: trade(t_st_id) -> status_type(st_id) │ │ └── anti-join (lookup status_type) - │ │ ├── columns: t_st_id:46!null - │ │ ├── key columns: [46] = [47] + │ │ ├── columns: t_st_id:47!null + │ │ ├── key columns: [47] = [48] │ │ ├── lookup columns are key │ │ ├── cardinality: [0 - 1] │ │ ├── key: () - │ │ ├── fd: ()-->(46) + │ │ ├── fd: ()-->(47) │ │ ├── with-scan &1 - │ │ │ ├── columns: t_st_id:46!null + │ │ │ ├── columns: t_st_id:47!null │ │ │ ├── mapping: - │ │ │ │ └── t_st_id_new:37 => t_st_id:46 + │ │ │ │ └── column39:39 => t_st_id:47 │ │ │ ├── cardinality: [0 - 1] │ │ │ ├── key: () - │ │ │ └── fd: ()-->(46) + │ │ │ └── fd: ()-->(47) │ │ └── filters (true) │ └── projections - │ └── 1 [as="?column?":51] + │ └── 1 [as="?column?":52] └── with &4 (update_broker_commission) - ├── columns: "?column?":103!null + ├── columns: "?column?":104!null ├── cardinality: [1 - 1] ├── volatile, mutations ├── key: () - ├── fd: ()-->(103) + ├── fd: ()-->(104) ├── project - │ ├── columns: "?column?":69!null + │ ├── columns: "?column?":70!null │ ├── cardinality: [0 - 1] │ ├── volatile, mutations │ ├── key: () - │ ├── fd: ()-->(69) + │ ├── fd: ()-->(70) │ ├── update broker - │ │ ├── columns: b_id:52!null - │ │ ├── fetch columns: b_id:59 b_num_trades:62 b_comm_total:63 + │ │ ├── columns: b_id:53!null + │ │ ├── fetch columns: b_id:60 b_num_trades:63 b_comm_total:64 │ │ ├── update-mapping: - │ │ │ ├── b_num_trades_new:67 => b_num_trades:55 - │ │ │ └── b_comm_total_new:68 => b_comm_total:56 + │ │ │ ├── b_num_trades_new:68 => b_num_trades:56 + │ │ │ └── column69:69 => b_comm_total:57 │ │ ├── cardinality: [0 - 1] │ │ ├── volatile, mutations │ │ ├── key: () - │ │ ├── fd: ()-->(52) + │ │ ├── fd: ()-->(53) │ │ └── project - │ │ ├── columns: b_comm_total_new:68 b_num_trades_new:67!null b_id:59!null b_num_trades:62!null b_comm_total:63!null + │ │ ├── columns: column69:69!null b_num_trades_new:68!null b_id:60!null b_num_trades:63!null b_comm_total:64!null │ │ ├── cardinality: [0 - 1] │ │ ├── immutable │ │ ├── key: () - │ │ ├── fd: ()-->(59,62,63,67,68) + │ │ ├── fd: ()-->(60,63,64,68,69) │ │ ├── scan broker - │ │ │ ├── columns: b_id:59!null b_num_trades:62!null b_comm_total:63!null - │ │ │ ├── constraint: /59: [/0 - /0] + │ │ │ ├── columns: b_id:60!null b_num_trades:63!null b_comm_total:64!null + │ │ │ ├── constraint: /60: [/0 - /0] │ │ │ ├── cardinality: [0 - 1] │ │ │ ├── key: () - │ │ │ └── fd: ()-->(59,62,63) + │ │ │ └── fd: ()-->(60,63,64) │ │ └── projections - │ │ ├── crdb_internal.round_decimal_values(b_comm_total:63::DECIMAL + 5E+1, 2) [as=b_comm_total_new:68, outer=(63), immutable] - │ │ └── b_num_trades:62 + 1 [as=b_num_trades_new:67, outer=(62), immutable] + │ │ ├── assignment-cast: DECIMAL(12,2) [as=column69:69, outer=(64), immutable] + │ │ │ └── b_comm_total:64::DECIMAL + 5E+1 + │ │ └── b_num_trades:63 + 1 [as=b_num_trades_new:68, outer=(63), immutable] │ └── projections - │ └── 1 [as="?column?":69] + │ └── 1 [as="?column?":70] └── with &6 (insert_trade_history) - ├── columns: "?column?":103!null + ├── columns: "?column?":104!null ├── cardinality: [1 - 1] ├── volatile, mutations ├── key: () - ├── fd: ()-->(103) + ├── fd: ()-->(104) ├── project - │ ├── columns: "?column?":102!null + │ ├── columns: "?column?":103!null │ ├── cardinality: [1 - 1] │ ├── volatile, mutations │ ├── key: () - │ ├── fd: ()-->(102) + │ ├── fd: ()-->(103) │ ├── insert trade_history - │ │ ├── columns: trade_history.th_t_id:70!null trade_history.th_st_id:72!null + │ │ ├── columns: trade_history.th_t_id:71!null trade_history.th_st_id:73!null │ │ ├── insert-mapping: - │ │ │ ├── column1:75 => trade_history.th_t_id:70 - │ │ │ ├── column2:76 => th_dts:71 - │ │ │ └── column78:78 => trade_history.th_st_id:72 + │ │ │ ├── column1:76 => trade_history.th_t_id:71 + │ │ │ ├── column2:77 => th_dts:72 + │ │ │ └── column79:79 => trade_history.th_st_id:73 │ │ ├── input binding: &5 │ │ ├── cardinality: [1 - 1] │ │ ├── volatile, mutations │ │ ├── key: () - │ │ ├── fd: ()-->(70,72) + │ │ ├── fd: ()-->(71,73) │ │ ├── values - │ │ │ ├── columns: column1:75!null column2:76!null column78:78!null + │ │ │ ├── columns: column1:76!null column2:77!null column79:79!null │ │ │ ├── cardinality: [1 - 1] │ │ │ ├── key: () - │ │ │ ├── fd: ()-->(75,76,78) + │ │ │ ├── fd: ()-->(76,77,79) │ │ │ └── (0, '2020-06-15 22:27:42.148484', 'ACTV') │ │ └── f-k-checks │ │ ├── f-k-checks-item: trade_history(th_t_id) -> trade(t_id) │ │ │ └── anti-join (lookup trade) - │ │ │ ├── columns: th_t_id:79!null - │ │ │ ├── key columns: [79] = [80] + │ │ │ ├── columns: th_t_id:80!null + │ │ │ ├── key columns: [80] = [81] │ │ │ ├── lookup columns are key │ │ │ ├── cardinality: [0 - 1] │ │ │ ├── key: () - │ │ │ ├── fd: ()-->(79) + │ │ │ ├── fd: ()-->(80) │ │ │ ├── with-scan &5 - │ │ │ │ ├── columns: th_t_id:79!null + │ │ │ │ ├── columns: th_t_id:80!null │ │ │ │ ├── mapping: - │ │ │ │ │ └── column1:75 => th_t_id:79 + │ │ │ │ │ └── column1:76 => th_t_id:80 │ │ │ │ ├── cardinality: [1 - 1] │ │ │ │ ├── key: () - │ │ │ │ └── fd: ()-->(79) + │ │ │ │ └── fd: ()-->(80) │ │ │ └── filters (true) │ │ └── f-k-checks-item: trade_history(th_st_id) -> status_type(st_id) │ │ └── anti-join (lookup status_type) - │ │ ├── columns: th_st_id:97!null - │ │ ├── key columns: [97] = [98] + │ │ ├── columns: th_st_id:98!null + │ │ ├── key columns: [98] = [99] │ │ ├── lookup columns are key │ │ ├── cardinality: [0 - 1] │ │ ├── key: () - │ │ ├── fd: ()-->(97) + │ │ ├── fd: ()-->(98) │ │ ├── with-scan &5 - │ │ │ ├── columns: th_st_id:97!null + │ │ │ ├── columns: th_st_id:98!null │ │ │ ├── mapping: - │ │ │ │ └── column78:78 => th_st_id:97 + │ │ │ │ └── column79:79 => th_st_id:98 │ │ │ ├── cardinality: [1 - 1] │ │ │ ├── key: () - │ │ │ └── fd: ()-->(97) + │ │ │ └── fd: ()-->(98) │ │ └── filters (true) │ └── projections - │ └── 1 [as="?column?":102] + │ └── 1 [as="?column?":103] └── values - ├── columns: "?column?":103!null + ├── columns: "?column?":104!null ├── cardinality: [1 - 1] ├── key: () - ├── fd: ()-->(103) + ├── fd: ()-->(104) └── (1,) @@ -4462,13 +4464,13 @@ with &2 (insert_settlement) │ ├── columns: ca_id:63!null customer_account.ca_bal:68!null │ ├── fetch columns: ca_id:71 ca_b_id:72 ca_c_id:73 ca_name:74 ca_tax_st:75 customer_account.ca_bal:76 │ ├── update-mapping: - │ │ └── ca_bal_new:80 => customer_account.ca_bal:68 + │ │ └── column80:80 => customer_account.ca_bal:68 │ ├── cardinality: [0 - 1] │ ├── volatile, mutations │ ├── key: () │ ├── fd: ()-->(63,68) │ └── project - │ ├── columns: ca_bal_new:80 ca_id:71!null ca_b_id:72!null ca_c_id:73!null ca_name:74 ca_tax_st:75!null customer_account.ca_bal:76!null + │ ├── columns: column80:80!null ca_id:71!null ca_b_id:72!null ca_c_id:73!null ca_name:74 ca_tax_st:75!null customer_account.ca_bal:76!null │ ├── cardinality: [0 - 1] │ ├── immutable │ ├── key: () @@ -4480,7 +4482,8 @@ with &2 (insert_settlement) │ │ ├── key: () │ │ └── fd: ()-->(71-76) │ └── projections - │ └── crdb_internal.round_decimal_values(customer_account.ca_bal:76::DECIMAL + 1E+2, 2) [as=ca_bal_new:80, outer=(76), immutable] + │ └── assignment-cast: DECIMAL(12,2) [as=column80:80, outer=(76), immutable] + │ └── customer_account.ca_bal:76::DECIMAL + 1E+2 └── projections └── customer_account.ca_bal:68::FLOAT8 [as=ca_bal:82, outer=(68), immutable] @@ -5051,15 +5054,15 @@ update trade ├── columns: ├── fetch columns: t_id:18 t_dts:19 t_st_id:20 t_tt_id:21 t_is_cash:22 t_s_symb:23 t_qty:24 t_bid_price:25 t_ca_id:26 t_exec_name:27 t_trade_price:28 t_chrg:29 t_comm:30 t_lifo:32 ├── update-mapping: - │ └── t_exec_name_new:35 => t_exec_name:10 + │ └── column36:36 => t_exec_name:10 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: t_exec_name_new:35 t_id:18!null t_dts:19!null t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null + ├── columns: column36:36 t_id:18!null t_dts:19!null t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null ├── cardinality: [0 - 4] ├── immutable ├── key: (18) - ├── fd: (18)-->(19-30,32), (27)-->(35) + ├── fd: (18)-->(19-30,32), (27)-->(36) ├── scan trade │ ├── columns: t_id:18!null t_dts:19!null t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null │ ├── constraint: /18: [/0 - /3] @@ -5067,7 +5070,8 @@ update trade │ ├── key: (18) │ └── fd: (18)-->(19-30,32) └── projections - └── CASE t_exec_name:27 LIKE '% X %' WHEN true THEN replace(t_exec_name:27, ' X ', ' ') ELSE replace(t_exec_name:27, ' ', ' X ') END [as=t_exec_name_new:35, outer=(27), immutable] + └── assignment-cast: VARCHAR(49) [as=column36:36, outer=(27), immutable] + └── CASE t_exec_name:27 LIKE '% X %' WHEN true THEN replace(t_exec_name:27, ' X ', ' ') ELSE replace(t_exec_name:27, ' ', ' X ') END # Q3 opt @@ -5236,14 +5240,15 @@ update settlement ├── columns: ├── fetch columns: se_t_id:7 se_cash_type:8 se_cash_due_date:9 se_amt:10 ├── update-mapping: - │ └── se_cash_type_new:15 => se_cash_type:2 + │ └── column16:16 => se_cash_type:2 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: se_cash_type_new:15!null se_t_id:7!null se_cash_type:8!null se_cash_due_date:9!null se_amt:10!null unnest:13!null unnest:14!null + ├── columns: column16:16!null se_t_id:7!null se_cash_type:8!null se_cash_due_date:9!null se_amt:10!null unnest:13!null unnest:14!null ├── cardinality: [0 - 4] + ├── immutable ├── key: (7) - ├── fd: (7)-->(8-10,13,14), (7)==(13), (13)==(7), (8,14)-->(15) + ├── fd: (7)-->(8-10,13,14), (7)==(13), (13)==(7), (8,14)-->(16) ├── distinct-on │ ├── columns: se_t_id:7!null se_cash_type:8!null se_cash_due_date:9!null se_amt:10!null unnest:13!null unnest:14!null │ ├── grouping columns: se_t_id:7!null @@ -5276,7 +5281,8 @@ update settlement │ └── first-agg [as=unnest:14, outer=(14)] │ └── unnest:14 └── projections - └── CASE unnest:14 WHEN true THEN CASE se_cash_type:8 = 'Cash Account' WHEN true THEN 'Cash' ELSE 'Cash Account' END ELSE CASE se_cash_type:8 = 'Margin Account' WHEN true THEN 'Margin' ELSE 'Margin Account' END END [as=se_cash_type_new:15, outer=(8,14)] + └── assignment-cast: VARCHAR(40) [as=column16:16, outer=(8,14), immutable] + └── CASE unnest:14 WHEN true THEN CASE se_cash_type:8 = 'Cash Account' WHEN true THEN 'Cash' ELSE 'Cash Account' END ELSE CASE se_cash_type:8 = 'Margin Account' WHEN true THEN 'Margin' ELSE 'Margin Account' END END # Q6 opt @@ -5496,15 +5502,15 @@ update cash_transaction ├── columns: ├── fetch columns: ct_t_id:7 ct_dts:8 ct_amt:9 ct_name:10 ├── update-mapping: - │ └── ct_name_new:17 => ct_name:4 + │ └── column18:18 => ct_name:4 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: ct_name_new:17 ct_t_id:7!null ct_dts:8!null ct_amt:9!null ct_name:10 unnest:13!null unnest:14!null unnest:15!null unnest:16!null + ├── columns: column18:18 ct_t_id:7!null ct_dts:8!null ct_amt:9!null ct_name:10 unnest:13!null unnest:14!null unnest:15!null unnest:16!null ├── cardinality: [0 - 4] ├── immutable ├── key: (7) - ├── fd: (7)-->(8-10,13-16), (7)==(13), (13)==(7), (10,14-16)-->(17) + ├── fd: (7)-->(8-10,13-16), (7)==(13), (13)==(7), (10,14-16)-->(18) ├── distinct-on │ ├── columns: ct_t_id:7!null ct_dts:8!null ct_amt:9!null ct_name:10 unnest:13!null unnest:14!null unnest:15!null unnest:16!null │ ├── grouping columns: ct_t_id:7!null @@ -5541,7 +5547,8 @@ update cash_transaction │ └── first-agg [as=unnest:16, outer=(16)] │ └── unnest:16 └── projections - └── concat_ws(' ', unnest:14, unnest:15::STRING, CASE ct_name:10 LIKE '% shares of %' WHEN true THEN 'Shares of' ELSE 'shares of' END, unnest:16) [as=ct_name_new:17, outer=(10,14-16), immutable] + └── assignment-cast: VARCHAR(100) [as=column18:18, outer=(10,14-16), immutable] + └── concat_ws(' ', unnest:14, unnest:15::STRING, CASE ct_name:10 LIKE '% shares of %' WHEN true THEN 'Shares of' ELSE 'shares of' END, unnest:16) # -------------------------------------------------- # T11 @@ -5583,14 +5590,14 @@ update account_permission ├── columns: ├── fetch columns: ap_ca_id:8 ap_acl:9 ap_tax_id:10 ap_l_name:11 ap_f_name:12 ├── update-mapping: - │ └── ap_acl_new:15 => ap_acl:2 + │ └── column16:16 => ap_acl:2 ├── cardinality: [0 - 0] ├── volatile, mutations └── values - ├── columns: ap_ca_id:8!null ap_acl:9!null ap_tax_id:10!null ap_l_name:11!null ap_f_name:12!null ap_acl_new:15!null + ├── columns: ap_ca_id:8!null ap_acl:9!null ap_tax_id:10!null ap_l_name:11!null ap_f_name:12!null column16:16!null ├── cardinality: [0 - 0] ├── key: () - └── fd: ()-->(8-12,15) + └── fd: ()-->(8-12,16) # Q3 opt @@ -5652,14 +5659,14 @@ update address ├── columns: ├── fetch columns: ad_id:8 ad_line1:9 ad_line2:10 ad_zc_code:11 ad_ctry:12 ├── update-mapping: - │ └── ad_line2_new:15 => ad_line2:3 + │ └── column16:16 => ad_line2:3 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: ad_line2_new:15!null ad_id:8!null ad_line1:9 ad_line2:10 ad_zc_code:11!null ad_ctry:12 + ├── columns: column16:16!null ad_id:8!null ad_line1:9 ad_line2:10 ad_zc_code:11!null ad_ctry:12 ├── cardinality: [0 - 1] ├── key: () - ├── fd: ()-->(8-12,15) + ├── fd: ()-->(8-12,16) ├── scan address │ ├── columns: ad_id:8!null ad_line1:9 ad_line2:10 ad_zc_code:11!null ad_ctry:12 │ ├── constraint: /8: [/0 - /0] @@ -5667,7 +5674,7 @@ update address │ ├── key: () │ └── fd: ()-->(8-12) └── projections - └── '' [as=ad_line2_new:15] + └── '' [as=column16:16] # Q6 opt @@ -5677,14 +5684,15 @@ update company ├── columns: ├── fetch columns: co_id:12 co_st_id:13 co_name:14 co_in_id:15 co_sp_rate:16 co_ceo:17 co_ad_id:18 co_desc:19 co_open_date:20 ├── update-mapping: - │ └── co_sp_rate_new:23 => co_sp_rate:5 + │ └── column24:24 => co_sp_rate:5 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: co_sp_rate_new:23!null co_id:12!null co_st_id:13!null co_name:14!null co_in_id:15!null co_sp_rate:16!null co_ceo:17!null co_ad_id:18!null co_desc:19!null co_open_date:20!null + ├── columns: column24:24!null co_id:12!null co_st_id:13!null co_name:14!null co_in_id:15!null co_sp_rate:16!null co_ceo:17!null co_ad_id:18!null co_desc:19!null co_open_date:20!null ├── cardinality: [0 - 1] + ├── immutable ├── key: () - ├── fd: ()-->(12-20,23) + ├── fd: ()-->(12-20,24) ├── scan company │ ├── columns: co_id:12!null co_st_id:13!null co_name:14!null co_in_id:15!null co_sp_rate:16!null co_ceo:17!null co_ad_id:18!null co_desc:19!null co_open_date:20!null │ ├── constraint: /12: [/0 - /0] @@ -5692,7 +5700,8 @@ update company │ ├── key: () │ └── fd: ()-->(12-20) └── projections - └── CASE co_sp_rate:16 != 'ABA' WHEN true THEN 'ABA' ELSE 'AAA' END [as=co_sp_rate_new:23, outer=(16)] + └── assignment-cast: VARCHAR(4) [as=column24:24, outer=(16), immutable] + └── CASE co_sp_rate:16 != 'ABA' WHEN true THEN 'ABA' ELSE 'AAA' END # Q7 opt @@ -5705,15 +5714,15 @@ update customer ├── columns: ├── fetch columns: c_id:27 c_tax_id:28 c_st_id:29 c_l_name:30 c_f_name:31 c_m_name:32 c_gndr:33 c_tier:34 c_dob:35 c_ad_id:36 c_ctry_1:37 c_area_1:38 c_local_1:39 c_ext_1:40 c_ctry_2:41 c_area_2:42 c_local_2:43 c_ext_2:44 c_ctry_3:45 c_area_3:46 c_local_3:47 c_ext_3:48 c_email_1:49 c_email_2:50 ├── update-mapping: - │ └── c_email_2_new:53 => c_email_2:24 + │ └── column54:54 => c_email_2:24 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: c_email_2_new:53 c_id:27!null c_tax_id:28!null c_st_id:29!null c_l_name:30!null c_f_name:31!null c_m_name:32 c_gndr:33 c_tier:34!null c_dob:35!null c_ad_id:36!null c_ctry_1:37 c_area_1:38 c_local_1:39 c_ext_1:40 c_ctry_2:41 c_area_2:42 c_local_2:43 c_ext_2:44 c_ctry_3:45 c_area_3:46 c_local_3:47 c_ext_3:48 c_email_1:49 c_email_2:50 + ├── columns: column54:54 c_id:27!null c_tax_id:28!null c_st_id:29!null c_l_name:30!null c_f_name:31!null c_m_name:32 c_gndr:33 c_tier:34!null c_dob:35!null c_ad_id:36!null c_ctry_1:37 c_area_1:38 c_local_1:39 c_ext_1:40 c_ctry_2:41 c_area_2:42 c_local_2:43 c_ext_2:44 c_ctry_3:45 c_area_3:46 c_local_3:47 c_ext_3:48 c_email_1:49 c_email_2:50 ├── cardinality: [0 - 1] ├── immutable ├── key: () - ├── fd: ()-->(27-50,53) + ├── fd: ()-->(27-50,54) ├── scan customer │ ├── columns: c_id:27!null c_tax_id:28!null c_st_id:29!null c_l_name:30!null c_f_name:31!null c_m_name:32 c_gndr:33 c_tier:34!null c_dob:35!null c_ad_id:36!null c_ctry_1:37 c_area_1:38 c_local_1:39 c_ext_1:40 c_ctry_2:41 c_area_2:42 c_local_2:43 c_ext_2:44 c_ctry_3:45 c_area_3:46 c_local_3:47 c_ext_3:48 c_email_1:49 c_email_2:50 │ ├── constraint: /27: [/0 - /0] @@ -5721,7 +5730,8 @@ update customer │ ├── key: () │ └── fd: ()-->(27-50) └── projections - └── left(c_email_2:50, strpos(c_email_2:50, '@')) || CASE c_email_2:50 LIKE '%@mindspring.com' WHEN true THEN 'earthlink.com' ELSE 'mindspring.com' END [as=c_email_2_new:53, outer=(50), immutable] + └── assignment-cast: VARCHAR(50) [as=column54:54, outer=(50), immutable] + └── left(c_email_2:50, strpos(c_email_2:50, '@')) || CASE c_email_2:50 LIKE '%@mindspring.com' WHEN true THEN 'earthlink.com' ELSE 'mindspring.com' END # Q8 opt @@ -5745,15 +5755,15 @@ update customer_taxrate ├── columns: ├── fetch columns: customer_taxrate.cx_tx_id:5 cx_c_id:6 ├── update-mapping: - │ └── cx_tx_id_new:9 => customer_taxrate.cx_tx_id:1 + │ └── column10:10 => customer_taxrate.cx_tx_id:1 ├── input binding: &1 ├── cardinality: [0 - 0] ├── volatile, mutations ├── project - │ ├── columns: cx_tx_id_new:9 customer_taxrate.cx_tx_id:5!null cx_c_id:6!null + │ ├── columns: column10:10 customer_taxrate.cx_tx_id:5!null cx_c_id:6!null │ ├── immutable │ ├── key: (5) - │ ├── fd: ()-->(6), (5)-->(9) + │ ├── fd: ()-->(6), (5)-->(10) │ ├── scan customer_taxrate@customer_taxrate_cx_c_id_idx │ │ ├── columns: customer_taxrate.cx_tx_id:5!null cx_c_id:6!null │ │ ├── constraint: /6/5 @@ -5762,17 +5772,18 @@ update customer_taxrate │ │ ├── key: (5) │ │ └── fd: ()-->(6) │ └── projections - │ └── CASE left(customer_taxrate.cx_tx_id:5, 2) = 'US' WHEN true THEN CASE customer_taxrate.cx_tx_id:5 = 'US5' WHEN true THEN 'US1' ELSE 'US' || (right(customer_taxrate.cx_tx_id:5, 1)::INT8 + 1)::STRING END ELSE CASE customer_taxrate.cx_tx_id:5 = 'CN4' WHEN true THEN 'CN1' ELSE 'CN' || (right(customer_taxrate.cx_tx_id:5, 1)::INT8 + 1)::STRING END END [as=cx_tx_id_new:9, outer=(5), immutable] + │ └── assignment-cast: VARCHAR(4) [as=column10:10, outer=(5), immutable] + │ └── CASE left(customer_taxrate.cx_tx_id:5, 2) = 'US' WHEN true THEN CASE customer_taxrate.cx_tx_id:5 = 'US5' WHEN true THEN 'US1' ELSE 'US' || (right(customer_taxrate.cx_tx_id:5, 1)::INT8 + 1)::STRING END ELSE CASE customer_taxrate.cx_tx_id:5 = 'CN4' WHEN true THEN 'CN1' ELSE 'CN' || (right(customer_taxrate.cx_tx_id:5, 1)::INT8 + 1)::STRING END END └── f-k-checks └── f-k-checks-item: customer_taxrate(cx_tx_id) -> taxrate(tx_id) └── anti-join (lookup taxrate) - ├── columns: cx_tx_id:10 - ├── key columns: [10] = [11] + ├── columns: cx_tx_id:11 + ├── key columns: [11] = [12] ├── lookup columns are key ├── with-scan &1 - │ ├── columns: cx_tx_id:10 + │ ├── columns: cx_tx_id:11 │ └── mapping: - │ └── cx_tx_id_new:9 => cx_tx_id:10 + │ └── column10:10 => cx_tx_id:11 └── filters (true) # Q9 @@ -5822,20 +5833,21 @@ update exchange ├── columns: ├── fetch columns: ex_id:10 ex_name:11 ex_num_symb:12 ex_open:13 ex_close:14 ex_desc:15 ex_ad_id:16 ├── update-mapping: - │ └── ex_desc_new:19 => ex_desc:6 + │ └── column20:20 => ex_desc:6 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: ex_desc_new:19 ex_id:10!null ex_name:11!null ex_num_symb:12!null ex_open:13!null ex_close:14!null ex_desc:15 ex_ad_id:16!null + ├── columns: column20:20 ex_id:10!null ex_name:11!null ex_num_symb:12!null ex_open:13!null ex_close:14!null ex_desc:15 ex_ad_id:16!null ├── immutable ├── key: (10) - ├── fd: (10)-->(11-16), (15)-->(19) + ├── fd: (10)-->(11-16), (15)-->(20) ├── scan exchange │ ├── columns: ex_id:10!null ex_name:11!null ex_num_symb:12!null ex_open:13!null ex_close:14!null ex_desc:15 ex_ad_id:16!null │ ├── key: (10) │ └── fd: (10)-->(11-16) └── projections - └── CASE ex_desc:15 NOT LIKE '%LAST UPDATED%' WHEN true THEN (ex_desc:15::STRING || ' LAST UPDATED ') || '2017-05-10 13:00:00' ELSE substring(ex_desc:15, 1, length(ex_desc:15) - 19) || '2017-05-10 13:00:00' END [as=ex_desc_new:19, outer=(15), immutable] + └── assignment-cast: VARCHAR(150) [as=column20:20, outer=(15), immutable] + └── CASE ex_desc:15 NOT LIKE '%LAST UPDATED%' WHEN true THEN (ex_desc:15::STRING || ' LAST UPDATED ') || '2017-05-10 13:00:00' ELSE substring(ex_desc:15, 1, length(ex_desc:15) - 19) || '2017-05-10 13:00:00' END # Q11 opt @@ -5948,15 +5960,15 @@ update taxrate ├── columns: ├── fetch columns: tx_id:6 tx_name:7 tx_rate:8 ├── update-mapping: - │ └── tx_name_new:11 => tx_name:2 + │ └── column12:12 => tx_name:2 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: tx_name_new:11 tx_id:6!null tx_name:7!null tx_rate:8!null + ├── columns: column12:12 tx_id:6!null tx_name:7!null tx_rate:8!null ├── cardinality: [0 - 1] ├── immutable ├── key: () - ├── fd: ()-->(6-8,11) + ├── fd: ()-->(6-8,12) ├── scan taxrate │ ├── columns: tx_id:6!null tx_name:7!null tx_rate:8!null │ ├── constraint: /6: [/'US1' - /'US1'] @@ -5964,7 +5976,8 @@ update taxrate │ ├── key: () │ └── fd: ()-->(6-8) └── projections - └── CASE tx_name:7 LIKE '% Tax %' WHEN true THEN replace(tx_name:7, ' Tax ', ' tax ') ELSE replace(tx_name:7, ' tax ', ' Tax ') END [as=tx_name_new:11, outer=(7), immutable] + └── assignment-cast: VARCHAR(50) [as=column12:12, outer=(7), immutable] + └── CASE tx_name:7 LIKE '% Tax %' WHEN true THEN replace(tx_name:7, ' Tax ', ' tax ') ELSE replace(tx_name:7, ' tax ', ' Tax ') END # Q15 opt @@ -6090,24 +6103,24 @@ update watch_item ├── columns: ├── fetch columns: wi_wl_id:5 watch_item.wi_s_symb:6 ├── update-mapping: - │ └── wi_s_symb_new:13 => watch_item.wi_s_symb:2 + │ └── column14:14 => watch_item.wi_s_symb:2 ├── input binding: &1 ├── cardinality: [0 - 0] ├── volatile, mutations ├── project - │ ├── columns: wi_s_symb_new:13!null wi_wl_id:5!null watch_item.wi_s_symb:6!null wl_id:9!null wl_c_id:10!null watch_list.crdb_internal_mvcc_timestamp:11 watch_list.tableoid:12 + │ ├── columns: column14:14!null wi_wl_id:5!null watch_item.wi_s_symb:6!null wl_id:9!null wl_c_id:10!null watch_list.crdb_internal_mvcc_timestamp:11 watch_list.tableoid:12 │ ├── key: (9) - │ ├── fd: ()-->(6,10,13), (9)-->(11,12), (5)==(9), (9)==(5) + │ ├── fd: ()-->(6,10,14), (9)-->(11,12), (5)==(9), (9)==(5) │ ├── inner-join (lookup watch_item) │ │ ├── columns: wi_wl_id:5!null watch_item.wi_s_symb:6!null wl_id:9!null wl_c_id:10!null watch_list.crdb_internal_mvcc_timestamp:11 watch_list.tableoid:12 - │ │ ├── key columns: [9 34] = [5 6] + │ │ ├── key columns: [9 35] = [5 6] │ │ ├── lookup columns are key │ │ ├── key: (9) │ │ ├── fd: ()-->(6,10), (9)-->(11,12), (5)==(9), (9)==(5) │ │ ├── project - │ │ │ ├── columns: "lookup_join_const_col_@6":34!null wl_id:9!null wl_c_id:10!null watch_list.crdb_internal_mvcc_timestamp:11 watch_list.tableoid:12 + │ │ │ ├── columns: "lookup_join_const_col_@6":35!null wl_id:9!null wl_c_id:10!null watch_list.crdb_internal_mvcc_timestamp:11 watch_list.tableoid:12 │ │ │ ├── key: (9) - │ │ │ ├── fd: ()-->(10,34), (9)-->(11,12) + │ │ │ ├── fd: ()-->(10,35), (9)-->(11,12) │ │ │ ├── index-join watch_list │ │ │ │ ├── columns: wl_id:9!null wl_c_id:10!null watch_list.crdb_internal_mvcc_timestamp:11 watch_list.tableoid:12 │ │ │ │ ├── key: (9) @@ -6118,22 +6131,22 @@ update watch_item │ │ │ │ ├── key: (9) │ │ │ │ └── fd: ()-->(10) │ │ │ └── projections - │ │ │ └── 'ROACH' [as="lookup_join_const_col_@6":34] + │ │ │ └── 'ROACH' [as="lookup_join_const_col_@6":35] │ │ └── filters (true) │ └── projections - │ └── 'ROACH' [as=wi_s_symb_new:13] + │ └── 'ROACH' [as=column14:14] └── f-k-checks └── f-k-checks-item: watch_item(wi_s_symb) -> security(s_symb) └── anti-join (lookup security) - ├── columns: wi_s_symb:14!null - ├── key columns: [14] = [15] + ├── columns: wi_s_symb:15!null + ├── key columns: [15] = [16] ├── lookup columns are key - ├── fd: ()-->(14) + ├── fd: ()-->(15) ├── with-scan &1 - │ ├── columns: wi_s_symb:14!null + │ ├── columns: wi_s_symb:15!null │ ├── mapping: - │ │ └── wi_s_symb_new:13 => wi_s_symb:14 - │ └── fd: ()-->(14) + │ │ └── column14:14 => wi_s_symb:15 + │ └── fd: ()-->(15) └── filters (true) # -------------------------------------------------- @@ -6215,15 +6228,15 @@ update trade ├── fetch columns: t_id:18 t_dts:19 trade.t_st_id:20 t_tt_id:21 t_is_cash:22 t_s_symb:23 t_qty:24 t_bid_price:25 t_ca_id:26 t_exec_name:27 t_trade_price:28 t_chrg:29 t_comm:30 t_lifo:32 ├── update-mapping: │ ├── t_dts_new:36 => t_dts:2 - │ └── t_st_id_new:35 => trade.t_st_id:3 + │ └── column37:37 => trade.t_st_id:3 ├── input binding: &1 ├── cardinality: [0 - 0] ├── volatile, mutations ├── project - │ ├── columns: t_st_id_new:35!null t_dts_new:36!null t_id:18!null t_dts:19!null trade.t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null + │ ├── columns: column37:37!null t_dts_new:36!null t_id:18!null t_dts:19!null trade.t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null │ ├── cardinality: [0 - 5] │ ├── key: (18) - │ ├── fd: ()-->(35,36), (18)-->(19-30,32) + │ ├── fd: ()-->(36,37), (18)-->(19-30,32) │ ├── scan trade │ │ ├── columns: t_id:18!null t_dts:19!null trade.t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null │ │ ├── constraint: /18: [/1 - /5] @@ -6231,26 +6244,26 @@ update trade │ │ ├── key: (18) │ │ └── fd: (18)-->(19-30,32) │ └── projections - │ ├── 'PNDG' [as=t_st_id_new:35] + │ ├── 'PNDG' [as=column37:37] │ └── '2020-06-15 22:27:42.148484' [as=t_dts_new:36] └── f-k-checks └── f-k-checks-item: trade(t_st_id) -> status_type(st_id) └── anti-join (merge) - ├── columns: t_st_id:42!null - ├── left ordering: +42 - ├── right ordering: +43 + ├── columns: t_st_id:43!null + ├── left ordering: +43 + ├── right ordering: +44 ├── cardinality: [0 - 5] - ├── fd: ()-->(42) + ├── fd: ()-->(43) ├── with-scan &1 - │ ├── columns: t_st_id:42!null + │ ├── columns: t_st_id:43!null │ ├── mapping: - │ │ └── t_st_id_new:35 => t_st_id:42 + │ │ └── column37:37 => t_st_id:43 │ ├── cardinality: [0 - 5] - │ └── fd: ()-->(42) + │ └── fd: ()-->(43) ├── scan status_type - │ ├── columns: st_id:43!null - │ ├── key: (43) - │ └── ordering: +43 + │ ├── columns: st_id:44!null + │ ├── key: (44) + │ └── ordering: +44 └── filters (true) # Q4 diff --git a/pkg/sql/opt/xform/testdata/external/tpce-no-stats b/pkg/sql/opt/xform/testdata/external/tpce-no-stats index 15c1ec4193de..aa6702e50c65 100644 --- a/pkg/sql/opt/xform/testdata/external/tpce-no-stats +++ b/pkg/sql/opt/xform/testdata/external/tpce-no-stats @@ -570,10 +570,10 @@ update_trade_submitted AS ( SELECT * FROM request_list; ---- with &2 (update_last_trade) - ├── columns: tr_t_id:138!null tr_bid_price:139!null tr_tt_id:140!null tr_qty:141!null + ├── columns: tr_t_id:139!null tr_bid_price:140!null tr_tt_id:141!null tr_qty:142!null ├── volatile, mutations - ├── key: (138) - ├── fd: (138)-->(139-141) + ├── key: (139) + ├── fd: (139)-->(140-142) ├── project │ ├── columns: "?column?":19 │ ├── cardinality: [0 - 1] @@ -585,14 +585,14 @@ with &2 (update_last_trade) │ │ ├── fetch columns: lt_s_symb:8 lt_dts:9 lt_price:10 lt_open_price:11 lt_vol:12 │ │ ├── update-mapping: │ │ │ ├── lt_dts_new:17 => lt_dts:2 - │ │ │ ├── lt_price_new:18 => lt_price:3 + │ │ │ ├── column18:18 => lt_price:3 │ │ │ └── lt_vol_new:15 => lt_vol:5 │ │ ├── cardinality: [0 - 1] │ │ ├── volatile, mutations │ │ ├── key: () │ │ ├── fd: ()-->(1) │ │ └── project - │ │ ├── columns: lt_price_new:18!null lt_vol_new:15!null lt_dts_new:17!null lt_s_symb:8!null lt_dts:9!null lt_price:10!null lt_open_price:11!null lt_vol:12!null + │ │ ├── columns: column18:18!null lt_vol_new:15!null lt_dts_new:17!null lt_s_symb:8!null lt_dts:9!null lt_price:10!null lt_open_price:11!null lt_vol:12!null │ │ ├── cardinality: [0 - 1] │ │ ├── immutable │ │ ├── key: () @@ -604,16 +604,16 @@ with &2 (update_last_trade) │ │ │ ├── key: () │ │ │ └── fd: ()-->(8-12) │ │ └── projections - │ │ ├── 1E+2 [as=lt_price_new:18] + │ │ ├── 100.00 [as=column18:18] │ │ ├── lt_vol:12 + 10 [as=lt_vol_new:15, outer=(12), immutable] │ │ └── '2020-06-15 22:27:42.148484' [as=lt_dts_new:17] │ └── projections │ └── NULL [as="?column?":19] └── with &3 (request_list) - ├── columns: tr_t_id:138!null tr_bid_price:139!null tr_tt_id:140!null tr_qty:141!null + ├── columns: tr_t_id:139!null tr_bid_price:140!null tr_tt_id:141!null tr_qty:142!null ├── volatile, mutations - ├── key: (138) - ├── fd: (138)-->(139-141) + ├── key: (139) + ├── fd: (139)-->(140-142) ├── project │ ├── columns: tr_bid_price:28!null trade_request.tr_t_id:20!null trade_request.tr_tt_id:21!null trade_request.tr_qty:23!null │ ├── immutable @@ -640,10 +640,10 @@ with &2 (update_last_trade) │ └── projections │ └── trade_request.tr_bid_price:24::FLOAT8 [as=tr_bid_price:28, outer=(24), immutable] └── with &4 (delete_trade_request) - ├── columns: tr_t_id:138!null tr_bid_price:139!null tr_tt_id:140!null tr_qty:141!null + ├── columns: tr_t_id:139!null tr_bid_price:140!null tr_tt_id:141!null tr_qty:142!null ├── volatile, mutations - ├── key: (138) - ├── fd: (138)-->(139-141) + ├── key: (139) + ├── fd: (139)-->(140-142) ├── project │ ├── columns: "?column?":50 │ ├── volatile, mutations @@ -679,10 +679,10 @@ with &2 (update_last_trade) │ └── projections │ └── NULL [as="?column?":50] └── with &6 (insert_trade_history) - ├── columns: tr_t_id:138!null tr_bid_price:139!null tr_tt_id:140!null tr_qty:141!null + ├── columns: tr_t_id:139!null tr_bid_price:140!null tr_tt_id:141!null tr_qty:142!null ├── volatile, mutations - ├── key: (138) - ├── fd: (138)-->(139-141) + ├── key: (139) + ├── fd: (139)-->(140-142) ├── project │ ├── columns: "?column?":86 │ ├── volatile, mutations @@ -737,27 +737,27 @@ with &2 (update_last_trade) │ └── projections │ └── NULL [as="?column?":86] └── with &8 (update_trade_submitted) - ├── columns: tr_t_id:138!null tr_bid_price:139!null tr_tt_id:140!null tr_qty:141!null + ├── columns: tr_t_id:139!null tr_bid_price:140!null tr_tt_id:141!null tr_qty:142!null ├── volatile, mutations - ├── key: (138) - ├── fd: (138)-->(139-141) + ├── key: (139) + ├── fd: (139)-->(140-142) ├── project - │ ├── columns: "?column?":137 + │ ├── columns: "?column?":138 │ ├── volatile, mutations - │ ├── fd: ()-->(137) + │ ├── fd: ()-->(138) │ ├── update trade │ │ ├── columns: t_id:87!null │ │ ├── fetch columns: t_id:104 t_dts:105 trade.t_st_id:106 t_tt_id:107 t_is_cash:108 t_s_symb:109 t_qty:110 t_bid_price:111 t_ca_id:112 t_exec_name:113 t_trade_price:114 t_chrg:115 t_comm:116 t_lifo:118 │ │ ├── update-mapping: │ │ │ ├── t_dts_new:126 => t_dts:88 - │ │ │ └── t_st_id_new:125 => trade.t_st_id:89 + │ │ │ └── column127:127 => trade.t_st_id:89 │ │ ├── input binding: &7 │ │ ├── volatile, mutations │ │ ├── key: (87) │ │ ├── project - │ │ │ ├── columns: t_st_id_new:125!null t_dts_new:126!null t_id:104!null t_dts:105!null trade.t_st_id:106!null t_tt_id:107!null t_is_cash:108!null t_s_symb:109!null t_qty:110!null t_bid_price:111!null t_ca_id:112!null t_exec_name:113!null t_trade_price:114 t_chrg:115!null t_comm:116!null t_lifo:118!null + │ │ │ ├── columns: column127:127!null t_dts_new:126!null t_id:104!null t_dts:105!null trade.t_st_id:106!null t_tt_id:107!null t_is_cash:108!null t_s_symb:109!null t_qty:110!null t_bid_price:111!null t_ca_id:112!null t_exec_name:113!null t_trade_price:114 t_chrg:115!null t_comm:116!null t_lifo:118!null │ │ │ ├── key: (104) - │ │ │ ├── fd: ()-->(125,126), (104)-->(105-116,118) + │ │ │ ├── fd: ()-->(126,127), (104)-->(105-116,118) │ │ │ ├── project │ │ │ │ ├── columns: t_id:104!null t_dts:105!null trade.t_st_id:106!null t_tt_id:107!null t_is_cash:108!null t_s_symb:109!null t_qty:110!null t_bid_price:111!null t_ca_id:112!null t_exec_name:113!null t_trade_price:114 t_chrg:115!null t_comm:116!null t_lifo:118!null │ │ │ │ ├── key: (104) @@ -775,32 +775,32 @@ with &2 (update_last_trade) │ │ │ │ │ └── key: (121) │ │ │ │ └── filters (true) │ │ │ └── projections - │ │ │ ├── 'SBMT' [as=t_st_id_new:125] + │ │ │ ├── 'SBMT' [as=column127:127] │ │ │ └── '2020-06-15 22:27:42.148484' [as=t_dts_new:126] │ │ └── f-k-checks │ │ └── f-k-checks-item: trade(t_st_id) -> status_type(st_id) │ │ └── anti-join (lookup status_type) - │ │ ├── columns: t_st_id:132!null - │ │ ├── key columns: [132] = [133] + │ │ ├── columns: t_st_id:133!null + │ │ ├── key columns: [133] = [134] │ │ ├── lookup columns are key - │ │ ├── fd: ()-->(132) + │ │ ├── fd: ()-->(133) │ │ ├── with-scan &7 - │ │ │ ├── columns: t_st_id:132!null + │ │ │ ├── columns: t_st_id:133!null │ │ │ ├── mapping: - │ │ │ │ └── t_st_id_new:125 => t_st_id:132 - │ │ │ └── fd: ()-->(132) + │ │ │ │ └── column127:127 => t_st_id:133 + │ │ │ └── fd: ()-->(133) │ │ └── filters (true) │ └── projections - │ └── NULL [as="?column?":137] + │ └── NULL [as="?column?":138] └── with-scan &3 (request_list) - ├── columns: tr_t_id:138!null tr_bid_price:139!null tr_tt_id:140!null tr_qty:141!null + ├── columns: tr_t_id:139!null tr_bid_price:140!null tr_tt_id:141!null tr_qty:142!null ├── mapping: - │ ├── trade_request.tr_t_id:20 => tr_t_id:138 - │ ├── tr_bid_price:28 => tr_bid_price:139 - │ ├── trade_request.tr_tt_id:21 => tr_tt_id:140 - │ └── trade_request.tr_qty:23 => tr_qty:141 - ├── key: (138) - └── fd: (138)-->(139-141) + │ ├── trade_request.tr_t_id:20 => tr_t_id:139 + │ ├── tr_bid_price:28 => tr_bid_price:140 + │ ├── trade_request.tr_tt_id:21 => tr_tt_id:141 + │ └── trade_request.tr_qty:23 => tr_qty:142 + ├── key: (139) + └── fd: (139)-->(140-142) # -------------------------------------------------- # T4 @@ -3685,15 +3685,15 @@ update holding_summary ├── columns: ├── fetch columns: hs_ca_id:6 hs_s_symb:7 hs_qty:8 ├── update-mapping: - │ └── hs_qty_new:11 => hs_qty:3 + │ └── column12:12 => hs_qty:3 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: hs_qty_new:11!null hs_ca_id:6!null hs_s_symb:7!null hs_qty:8!null + ├── columns: column12:12!null hs_ca_id:6!null hs_s_symb:7!null hs_qty:8!null ├── cardinality: [0 - 1] ├── immutable ├── key: () - ├── fd: ()-->(6-8,11) + ├── fd: ()-->(6-8,12) ├── scan holding_summary │ ├── columns: hs_ca_id:6!null hs_s_symb:7!null hs_qty:8!null │ ├── constraint: /6/7: [/0/'ROACH' - /0/'ROACH'] @@ -3701,7 +3701,8 @@ update holding_summary │ ├── key: () │ └── fd: ()-->(6-8) └── projections - └── hs_qty:8::INT8 + 10 [as=hs_qty_new:11, outer=(8), immutable] + └── assignment-cast: INT4 [as=column12:12, outer=(8), immutable] + └── hs_qty:8::INT8 + 10 # Q5 opt @@ -3815,15 +3816,15 @@ update holding ├── columns: ├── fetch columns: h_t_id:9 h_ca_id:10 h_s_symb:11 h_dts:12 h_price:13 h_qty:14 ├── update-mapping: - │ └── h_qty_new:17 => h_qty:6 + │ └── column18:18 => h_qty:6 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: h_qty_new:17!null h_t_id:9!null h_ca_id:10!null h_s_symb:11!null h_dts:12!null h_price:13!null h_qty:14!null + ├── columns: column18:18!null h_t_id:9!null h_ca_id:10!null h_s_symb:11!null h_dts:12!null h_price:13!null h_qty:14!null ├── cardinality: [0 - 1] ├── immutable ├── key: () - ├── fd: ()-->(9-14,17) + ├── fd: ()-->(9-14,18) ├── scan holding │ ├── columns: h_t_id:9!null h_ca_id:10!null h_s_symb:11!null h_dts:12!null h_price:13!null h_qty:14!null │ ├── constraint: /9: [/0 - /0] @@ -3831,7 +3832,8 @@ update holding │ ├── key: () │ └── fd: ()-->(9-14) └── projections - └── h_qty:14::INT8 + 10 [as=h_qty_new:17, outer=(14), immutable] + └── assignment-cast: INT4 [as=column18:18, outer=(14), immutable] + └── h_qty:14::INT8 + 10 # Q9 opt @@ -3973,20 +3975,20 @@ project │ ├── columns: t_id:1!null trade.t_tax:14!null │ ├── fetch columns: t_id:18 trade.t_tax:31 │ ├── update-mapping: - │ │ └── t_tax_new:46 => trade.t_tax:14 + │ │ └── column46:46 => trade.t_tax:14 │ ├── check columns: check5:51 │ ├── cardinality: [0 - 1] │ ├── volatile, mutations │ ├── key: () │ ├── fd: ()-->(1,14) │ └── project - │ ├── columns: check5:51 t_id:18!null trade.t_tax:31!null t_tax_new:46 + │ ├── columns: check5:51 t_id:18!null trade.t_tax:31!null column46:46 │ ├── cardinality: [0 - 1] │ ├── immutable │ ├── key: () │ ├── fd: ()-->(18,31,46,51) │ ├── project - │ │ ├── columns: t_tax_new:46 t_id:18!null trade.t_tax:31!null + │ │ ├── columns: column46:46 t_id:18!null trade.t_tax:31!null │ │ ├── cardinality: [0 - 1] │ │ ├── immutable │ │ ├── key: () @@ -3998,33 +4000,32 @@ project │ │ │ ├── key: () │ │ │ └── fd: ()-->(18,31) │ │ └── projections - │ │ └── function: crdb_internal.round_decimal_values [as=t_tax_new:46, immutable, subquery] - │ │ ├── mult - │ │ │ ├── subquery - │ │ │ │ └── scalar-group-by - │ │ │ │ ├── columns: sum:44 - │ │ │ │ ├── cardinality: [1 - 1] - │ │ │ │ ├── key: () - │ │ │ │ ├── fd: ()-->(44) - │ │ │ │ ├── inner-join (lookup taxrate) - │ │ │ │ │ ├── columns: tx_id:35!null tx_rate:37!null cx_tx_id:40!null cx_c_id:41!null - │ │ │ │ │ ├── key columns: [40] = [35] - │ │ │ │ │ ├── lookup columns are key - │ │ │ │ │ ├── key: (40) - │ │ │ │ │ ├── fd: ()-->(41), (35)-->(37), (35)==(40), (40)==(35) - │ │ │ │ │ ├── scan customer_taxrate@customer_taxrate_cx_c_id_idx - │ │ │ │ │ │ ├── columns: cx_tx_id:40!null cx_c_id:41!null - │ │ │ │ │ │ ├── constraint: /41/40: [/0 - /0] - │ │ │ │ │ │ ├── key: (40) - │ │ │ │ │ │ └── fd: ()-->(41) - │ │ │ │ │ └── filters (true) - │ │ │ │ └── aggregations - │ │ │ │ └── sum [as=sum:44, outer=(37)] - │ │ │ │ └── tx_rate:37 - │ │ │ └── 2E+1 - │ │ └── 2 + │ │ └── assignment-cast: DECIMAL(10,2) [as=column46:46, immutable, subquery] + │ │ └── mult + │ │ ├── subquery + │ │ │ └── scalar-group-by + │ │ │ ├── columns: sum:44 + │ │ │ ├── cardinality: [1 - 1] + │ │ │ ├── key: () + │ │ │ ├── fd: ()-->(44) + │ │ │ ├── inner-join (lookup taxrate) + │ │ │ │ ├── columns: tx_id:35!null tx_rate:37!null cx_tx_id:40!null cx_c_id:41!null + │ │ │ │ ├── key columns: [40] = [35] + │ │ │ │ ├── lookup columns are key + │ │ │ │ ├── key: (40) + │ │ │ │ ├── fd: ()-->(41), (35)-->(37), (35)==(40), (40)==(35) + │ │ │ │ ├── scan customer_taxrate@customer_taxrate_cx_c_id_idx + │ │ │ │ │ ├── columns: cx_tx_id:40!null cx_c_id:41!null + │ │ │ │ │ ├── constraint: /41/40: [/0 - /0] + │ │ │ │ │ ├── key: (40) + │ │ │ │ │ └── fd: ()-->(41) + │ │ │ │ └── filters (true) + │ │ │ └── aggregations + │ │ │ └── sum [as=sum:44, outer=(37)] + │ │ │ └── tx_rate:37 + │ │ └── 2E+1 │ └── projections - │ └── t_tax_new:46 >= 0 [as=check5:51, outer=(46), immutable] + │ └── column46:46 >= 0 [as=check5:51, outer=(46), immutable] └── projections └── trade.t_tax:14::FLOAT8 [as=t_tax:52, outer=(14), immutable] @@ -4186,36 +4187,36 @@ insert_trade_history AS ( SELECT 1 ---- with &2 (update_trade_commission) - ├── columns: "?column?":103!null + ├── columns: "?column?":104!null ├── cardinality: [1 - 1] ├── volatile, mutations ├── key: () - ├── fd: ()-->(103) + ├── fd: ()-->(104) ├── project - │ ├── columns: "?column?":51!null + │ ├── columns: "?column?":52!null │ ├── cardinality: [0 - 1] │ ├── volatile, mutations │ ├── key: () - │ ├── fd: ()-->(51) + │ ├── fd: ()-->(52) │ ├── update trade │ │ ├── columns: t_id:1!null │ │ ├── fetch columns: t_id:18 t_dts:19 trade.t_st_id:20 t_tt_id:21 t_is_cash:22 t_s_symb:23 t_qty:24 t_bid_price:25 t_ca_id:26 t_exec_name:27 t_trade_price:28 t_chrg:29 t_comm:30 t_lifo:32 │ │ ├── update-mapping: │ │ │ ├── t_dts_new:36 => t_dts:2 - │ │ │ ├── t_st_id_new:37 => trade.t_st_id:3 - │ │ │ ├── t_trade_price_new:39 => t_trade_price:11 - │ │ │ └── t_comm_new:40 => t_comm:13 - │ │ ├── check columns: check4:44 + │ │ │ ├── column39:39 => trade.t_st_id:3 + │ │ │ ├── column40:40 => t_trade_price:11 + │ │ │ └── column41:41 => t_comm:13 + │ │ ├── check columns: check4:45 │ │ ├── input binding: &1 │ │ ├── cardinality: [0 - 1] │ │ ├── volatile, mutations │ │ ├── key: () │ │ ├── fd: ()-->(1) │ │ ├── project - │ │ │ ├── columns: check4:44!null t_comm_new:40!null t_trade_price_new:39!null t_dts_new:36!null t_st_id_new:37!null t_id:18!null t_dts:19!null trade.t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null + │ │ │ ├── columns: check4:45!null column41:41!null column39:39!null column40:40!null t_dts_new:36!null t_id:18!null t_dts:19!null trade.t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null │ │ │ ├── cardinality: [0 - 1] │ │ │ ├── key: () - │ │ │ ├── fd: ()-->(18-30,32,36,37,39,40,44) + │ │ │ ├── fd: ()-->(18-30,32,36,39-41,45) │ │ │ ├── scan trade │ │ │ │ ├── columns: t_id:18!null t_dts:19!null trade.t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null │ │ │ │ ├── constraint: /18: [/0 - /0] @@ -4223,138 +4224,139 @@ with &2 (update_trade_commission) │ │ │ │ ├── key: () │ │ │ │ └── fd: ()-->(18-30,32) │ │ │ └── projections - │ │ │ ├── true [as=check4:44] - │ │ │ ├── 5E+1 [as=t_comm_new:40] - │ │ │ ├── 1E+2 [as=t_trade_price_new:39] - │ │ │ ├── '2020-06-15 22:27:42.148484' [as=t_dts_new:36] - │ │ │ └── 'ACTV' [as=t_st_id_new:37] + │ │ │ ├── true [as=check4:45] + │ │ │ ├── 50.00 [as=column41:41] + │ │ │ ├── 'ACTV' [as=column39:39] + │ │ │ ├── 100.00 [as=column40:40] + │ │ │ └── '2020-06-15 22:27:42.148484' [as=t_dts_new:36] │ │ └── f-k-checks │ │ └── f-k-checks-item: trade(t_st_id) -> status_type(st_id) │ │ └── anti-join (lookup status_type) - │ │ ├── columns: t_st_id:46!null - │ │ ├── key columns: [46] = [47] + │ │ ├── columns: t_st_id:47!null + │ │ ├── key columns: [47] = [48] │ │ ├── lookup columns are key │ │ ├── cardinality: [0 - 1] │ │ ├── key: () - │ │ ├── fd: ()-->(46) + │ │ ├── fd: ()-->(47) │ │ ├── with-scan &1 - │ │ │ ├── columns: t_st_id:46!null + │ │ │ ├── columns: t_st_id:47!null │ │ │ ├── mapping: - │ │ │ │ └── t_st_id_new:37 => t_st_id:46 + │ │ │ │ └── column39:39 => t_st_id:47 │ │ │ ├── cardinality: [0 - 1] │ │ │ ├── key: () - │ │ │ └── fd: ()-->(46) + │ │ │ └── fd: ()-->(47) │ │ └── filters (true) │ └── projections - │ └── 1 [as="?column?":51] + │ └── 1 [as="?column?":52] └── with &4 (update_broker_commission) - ├── columns: "?column?":103!null + ├── columns: "?column?":104!null ├── cardinality: [1 - 1] ├── volatile, mutations ├── key: () - ├── fd: ()-->(103) + ├── fd: ()-->(104) ├── project - │ ├── columns: "?column?":69!null + │ ├── columns: "?column?":70!null │ ├── cardinality: [0 - 1] │ ├── volatile, mutations │ ├── key: () - │ ├── fd: ()-->(69) + │ ├── fd: ()-->(70) │ ├── update broker - │ │ ├── columns: b_id:52!null - │ │ ├── fetch columns: b_id:59 b_num_trades:62 b_comm_total:63 + │ │ ├── columns: b_id:53!null + │ │ ├── fetch columns: b_id:60 b_num_trades:63 b_comm_total:64 │ │ ├── update-mapping: - │ │ │ ├── b_num_trades_new:67 => b_num_trades:55 - │ │ │ └── b_comm_total_new:68 => b_comm_total:56 + │ │ │ ├── b_num_trades_new:68 => b_num_trades:56 + │ │ │ └── column69:69 => b_comm_total:57 │ │ ├── cardinality: [0 - 1] │ │ ├── volatile, mutations │ │ ├── key: () - │ │ ├── fd: ()-->(52) + │ │ ├── fd: ()-->(53) │ │ └── project - │ │ ├── columns: b_comm_total_new:68 b_num_trades_new:67!null b_id:59!null b_num_trades:62!null b_comm_total:63!null + │ │ ├── columns: column69:69!null b_num_trades_new:68!null b_id:60!null b_num_trades:63!null b_comm_total:64!null │ │ ├── cardinality: [0 - 1] │ │ ├── immutable │ │ ├── key: () - │ │ ├── fd: ()-->(59,62,63,67,68) + │ │ ├── fd: ()-->(60,63,64,68,69) │ │ ├── scan broker - │ │ │ ├── columns: b_id:59!null b_num_trades:62!null b_comm_total:63!null - │ │ │ ├── constraint: /59: [/0 - /0] + │ │ │ ├── columns: b_id:60!null b_num_trades:63!null b_comm_total:64!null + │ │ │ ├── constraint: /60: [/0 - /0] │ │ │ ├── cardinality: [0 - 1] │ │ │ ├── key: () - │ │ │ └── fd: ()-->(59,62,63) + │ │ │ └── fd: ()-->(60,63,64) │ │ └── projections - │ │ ├── crdb_internal.round_decimal_values(b_comm_total:63::DECIMAL + 5E+1, 2) [as=b_comm_total_new:68, outer=(63), immutable] - │ │ └── b_num_trades:62 + 1 [as=b_num_trades_new:67, outer=(62), immutable] + │ │ ├── assignment-cast: DECIMAL(12,2) [as=column69:69, outer=(64), immutable] + │ │ │ └── b_comm_total:64::DECIMAL + 5E+1 + │ │ └── b_num_trades:63 + 1 [as=b_num_trades_new:68, outer=(63), immutable] │ └── projections - │ └── 1 [as="?column?":69] + │ └── 1 [as="?column?":70] └── with &6 (insert_trade_history) - ├── columns: "?column?":103!null + ├── columns: "?column?":104!null ├── cardinality: [1 - 1] ├── volatile, mutations ├── key: () - ├── fd: ()-->(103) + ├── fd: ()-->(104) ├── project - │ ├── columns: "?column?":102!null + │ ├── columns: "?column?":103!null │ ├── cardinality: [1 - 1] │ ├── volatile, mutations │ ├── key: () - │ ├── fd: ()-->(102) + │ ├── fd: ()-->(103) │ ├── insert trade_history - │ │ ├── columns: trade_history.th_t_id:70!null trade_history.th_st_id:72!null + │ │ ├── columns: trade_history.th_t_id:71!null trade_history.th_st_id:73!null │ │ ├── insert-mapping: - │ │ │ ├── column1:75 => trade_history.th_t_id:70 - │ │ │ ├── column2:76 => th_dts:71 - │ │ │ └── column78:78 => trade_history.th_st_id:72 + │ │ │ ├── column1:76 => trade_history.th_t_id:71 + │ │ │ ├── column2:77 => th_dts:72 + │ │ │ └── column79:79 => trade_history.th_st_id:73 │ │ ├── input binding: &5 │ │ ├── cardinality: [1 - 1] │ │ ├── volatile, mutations │ │ ├── key: () - │ │ ├── fd: ()-->(70,72) + │ │ ├── fd: ()-->(71,73) │ │ ├── values - │ │ │ ├── columns: column1:75!null column2:76!null column78:78!null + │ │ │ ├── columns: column1:76!null column2:77!null column79:79!null │ │ │ ├── cardinality: [1 - 1] │ │ │ ├── key: () - │ │ │ ├── fd: ()-->(75,76,78) + │ │ │ ├── fd: ()-->(76,77,79) │ │ │ └── (0, '2020-06-15 22:27:42.148484', 'ACTV') │ │ └── f-k-checks │ │ ├── f-k-checks-item: trade_history(th_t_id) -> trade(t_id) │ │ │ └── anti-join (lookup trade) - │ │ │ ├── columns: th_t_id:79!null - │ │ │ ├── key columns: [79] = [80] + │ │ │ ├── columns: th_t_id:80!null + │ │ │ ├── key columns: [80] = [81] │ │ │ ├── lookup columns are key │ │ │ ├── cardinality: [0 - 1] │ │ │ ├── key: () - │ │ │ ├── fd: ()-->(79) + │ │ │ ├── fd: ()-->(80) │ │ │ ├── with-scan &5 - │ │ │ │ ├── columns: th_t_id:79!null + │ │ │ │ ├── columns: th_t_id:80!null │ │ │ │ ├── mapping: - │ │ │ │ │ └── column1:75 => th_t_id:79 + │ │ │ │ │ └── column1:76 => th_t_id:80 │ │ │ │ ├── cardinality: [1 - 1] │ │ │ │ ├── key: () - │ │ │ │ └── fd: ()-->(79) + │ │ │ │ └── fd: ()-->(80) │ │ │ └── filters (true) │ │ └── f-k-checks-item: trade_history(th_st_id) -> status_type(st_id) │ │ └── anti-join (lookup status_type) - │ │ ├── columns: th_st_id:97!null - │ │ ├── key columns: [97] = [98] + │ │ ├── columns: th_st_id:98!null + │ │ ├── key columns: [98] = [99] │ │ ├── lookup columns are key │ │ ├── cardinality: [0 - 1] │ │ ├── key: () - │ │ ├── fd: ()-->(97) + │ │ ├── fd: ()-->(98) │ │ ├── with-scan &5 - │ │ │ ├── columns: th_st_id:97!null + │ │ │ ├── columns: th_st_id:98!null │ │ │ ├── mapping: - │ │ │ │ └── column78:78 => th_st_id:97 + │ │ │ │ └── column79:79 => th_st_id:98 │ │ │ ├── cardinality: [1 - 1] │ │ │ ├── key: () - │ │ │ └── fd: ()-->(97) + │ │ │ └── fd: ()-->(98) │ │ └── filters (true) │ └── projections - │ └── 1 [as="?column?":102] + │ └── 1 [as="?column?":103] └── values - ├── columns: "?column?":103!null + ├── columns: "?column?":104!null ├── cardinality: [1 - 1] ├── key: () - ├── fd: ()-->(103) + ├── fd: ()-->(104) └── (1,) @@ -4491,13 +4493,13 @@ with &2 (insert_settlement) │ ├── columns: ca_id:63!null customer_account.ca_bal:68!null │ ├── fetch columns: ca_id:71 ca_b_id:72 ca_c_id:73 ca_name:74 ca_tax_st:75 customer_account.ca_bal:76 │ ├── update-mapping: - │ │ └── ca_bal_new:80 => customer_account.ca_bal:68 + │ │ └── column80:80 => customer_account.ca_bal:68 │ ├── cardinality: [0 - 1] │ ├── volatile, mutations │ ├── key: () │ ├── fd: ()-->(63,68) │ └── project - │ ├── columns: ca_bal_new:80 ca_id:71!null ca_b_id:72!null ca_c_id:73!null ca_name:74 ca_tax_st:75!null customer_account.ca_bal:76!null + │ ├── columns: column80:80!null ca_id:71!null ca_b_id:72!null ca_c_id:73!null ca_name:74 ca_tax_st:75!null customer_account.ca_bal:76!null │ ├── cardinality: [0 - 1] │ ├── immutable │ ├── key: () @@ -4509,7 +4511,8 @@ with &2 (insert_settlement) │ │ ├── key: () │ │ └── fd: ()-->(71-76) │ └── projections - │ └── crdb_internal.round_decimal_values(customer_account.ca_bal:76::DECIMAL + 1E+2, 2) [as=ca_bal_new:80, outer=(76), immutable] + │ └── assignment-cast: DECIMAL(12,2) [as=column80:80, outer=(76), immutable] + │ └── customer_account.ca_bal:76::DECIMAL + 1E+2 └── projections └── customer_account.ca_bal:68::FLOAT8 [as=ca_bal:82, outer=(68), immutable] @@ -5068,15 +5071,15 @@ update trade ├── columns: ├── fetch columns: t_id:18 t_dts:19 t_st_id:20 t_tt_id:21 t_is_cash:22 t_s_symb:23 t_qty:24 t_bid_price:25 t_ca_id:26 t_exec_name:27 t_trade_price:28 t_chrg:29 t_comm:30 t_lifo:32 ├── update-mapping: - │ └── t_exec_name_new:35 => t_exec_name:10 + │ └── column36:36 => t_exec_name:10 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: t_exec_name_new:35 t_id:18!null t_dts:19!null t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null + ├── columns: column36:36 t_id:18!null t_dts:19!null t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null ├── cardinality: [0 - 4] ├── immutable ├── key: (18) - ├── fd: (18)-->(19-30,32), (27)-->(35) + ├── fd: (18)-->(19-30,32), (27)-->(36) ├── scan trade │ ├── columns: t_id:18!null t_dts:19!null t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null │ ├── constraint: /18: [/0 - /3] @@ -5084,7 +5087,8 @@ update trade │ ├── key: (18) │ └── fd: (18)-->(19-30,32) └── projections - └── CASE t_exec_name:27 LIKE '% X %' WHEN true THEN replace(t_exec_name:27, ' X ', ' ') ELSE replace(t_exec_name:27, ' ', ' X ') END [as=t_exec_name_new:35, outer=(27), immutable] + └── assignment-cast: VARCHAR(49) [as=column36:36, outer=(27), immutable] + └── CASE t_exec_name:27 LIKE '% X %' WHEN true THEN replace(t_exec_name:27, ' X ', ' ') ELSE replace(t_exec_name:27, ' ', ' X ') END # Q3 opt @@ -5253,14 +5257,15 @@ update settlement ├── columns: ├── fetch columns: se_t_id:7 se_cash_type:8 se_cash_due_date:9 se_amt:10 ├── update-mapping: - │ └── se_cash_type_new:15 => se_cash_type:2 + │ └── column16:16 => se_cash_type:2 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: se_cash_type_new:15!null se_t_id:7!null se_cash_type:8!null se_cash_due_date:9!null se_amt:10!null unnest:13!null unnest:14!null + ├── columns: column16:16!null se_t_id:7!null se_cash_type:8!null se_cash_due_date:9!null se_amt:10!null unnest:13!null unnest:14!null ├── cardinality: [0 - 4] + ├── immutable ├── key: (7) - ├── fd: (7)-->(8-10,13,14), (7)==(13), (13)==(7), (8,14)-->(15) + ├── fd: (7)-->(8-10,13,14), (7)==(13), (13)==(7), (8,14)-->(16) ├── distinct-on │ ├── columns: se_t_id:7!null se_cash_type:8!null se_cash_due_date:9!null se_amt:10!null unnest:13!null unnest:14!null │ ├── grouping columns: se_t_id:7!null @@ -5293,7 +5298,8 @@ update settlement │ └── first-agg [as=unnest:14, outer=(14)] │ └── unnest:14 └── projections - └── CASE unnest:14 WHEN true THEN CASE se_cash_type:8 = 'Cash Account' WHEN true THEN 'Cash' ELSE 'Cash Account' END ELSE CASE se_cash_type:8 = 'Margin Account' WHEN true THEN 'Margin' ELSE 'Margin Account' END END [as=se_cash_type_new:15, outer=(8,14)] + └── assignment-cast: VARCHAR(40) [as=column16:16, outer=(8,14), immutable] + └── CASE unnest:14 WHEN true THEN CASE se_cash_type:8 = 'Cash Account' WHEN true THEN 'Cash' ELSE 'Cash Account' END ELSE CASE se_cash_type:8 = 'Margin Account' WHEN true THEN 'Margin' ELSE 'Margin Account' END END # Q6 opt @@ -5516,15 +5522,15 @@ update cash_transaction ├── columns: ├── fetch columns: ct_t_id:7 ct_dts:8 ct_amt:9 ct_name:10 ├── update-mapping: - │ └── ct_name_new:17 => ct_name:4 + │ └── column18:18 => ct_name:4 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: ct_name_new:17 ct_t_id:7!null ct_dts:8!null ct_amt:9!null ct_name:10 unnest:13!null unnest:14!null unnest:15!null unnest:16!null + ├── columns: column18:18 ct_t_id:7!null ct_dts:8!null ct_amt:9!null ct_name:10 unnest:13!null unnest:14!null unnest:15!null unnest:16!null ├── cardinality: [0 - 4] ├── immutable ├── key: (7) - ├── fd: (7)-->(8-10,13-16), (7)==(13), (13)==(7), (10,14-16)-->(17) + ├── fd: (7)-->(8-10,13-16), (7)==(13), (13)==(7), (10,14-16)-->(18) ├── distinct-on │ ├── columns: ct_t_id:7!null ct_dts:8!null ct_amt:9!null ct_name:10 unnest:13!null unnest:14!null unnest:15!null unnest:16!null │ ├── grouping columns: ct_t_id:7!null @@ -5561,7 +5567,8 @@ update cash_transaction │ └── first-agg [as=unnest:16, outer=(16)] │ └── unnest:16 └── projections - └── concat_ws(' ', unnest:14, unnest:15::STRING, CASE ct_name:10 LIKE '% shares of %' WHEN true THEN 'Shares of' ELSE 'shares of' END, unnest:16) [as=ct_name_new:17, outer=(10,14-16), immutable] + └── assignment-cast: VARCHAR(100) [as=column18:18, outer=(10,14-16), immutable] + └── concat_ws(' ', unnest:14, unnest:15::STRING, CASE ct_name:10 LIKE '% shares of %' WHEN true THEN 'Shares of' ELSE 'shares of' END, unnest:16) # -------------------------------------------------- # T11 @@ -5603,14 +5610,14 @@ update account_permission ├── columns: ├── fetch columns: ap_ca_id:8 ap_acl:9 ap_tax_id:10 ap_l_name:11 ap_f_name:12 ├── update-mapping: - │ └── ap_acl_new:15 => ap_acl:2 + │ └── column16:16 => ap_acl:2 ├── cardinality: [0 - 0] ├── volatile, mutations └── values - ├── columns: ap_ca_id:8!null ap_acl:9!null ap_tax_id:10!null ap_l_name:11!null ap_f_name:12!null ap_acl_new:15!null + ├── columns: ap_ca_id:8!null ap_acl:9!null ap_tax_id:10!null ap_l_name:11!null ap_f_name:12!null column16:16!null ├── cardinality: [0 - 0] ├── key: () - └── fd: ()-->(8-12,15) + └── fd: ()-->(8-12,16) # Q3 opt @@ -5672,14 +5679,14 @@ update address ├── columns: ├── fetch columns: ad_id:8 ad_line1:9 ad_line2:10 ad_zc_code:11 ad_ctry:12 ├── update-mapping: - │ └── ad_line2_new:15 => ad_line2:3 + │ └── column16:16 => ad_line2:3 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: ad_line2_new:15!null ad_id:8!null ad_line1:9 ad_line2:10 ad_zc_code:11!null ad_ctry:12 + ├── columns: column16:16!null ad_id:8!null ad_line1:9 ad_line2:10 ad_zc_code:11!null ad_ctry:12 ├── cardinality: [0 - 1] ├── key: () - ├── fd: ()-->(8-12,15) + ├── fd: ()-->(8-12,16) ├── scan address │ ├── columns: ad_id:8!null ad_line1:9 ad_line2:10 ad_zc_code:11!null ad_ctry:12 │ ├── constraint: /8: [/0 - /0] @@ -5687,7 +5694,7 @@ update address │ ├── key: () │ └── fd: ()-->(8-12) └── projections - └── '' [as=ad_line2_new:15] + └── '' [as=column16:16] # Q6 opt @@ -5697,14 +5704,15 @@ update company ├── columns: ├── fetch columns: co_id:12 co_st_id:13 co_name:14 co_in_id:15 co_sp_rate:16 co_ceo:17 co_ad_id:18 co_desc:19 co_open_date:20 ├── update-mapping: - │ └── co_sp_rate_new:23 => co_sp_rate:5 + │ └── column24:24 => co_sp_rate:5 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: co_sp_rate_new:23!null co_id:12!null co_st_id:13!null co_name:14!null co_in_id:15!null co_sp_rate:16!null co_ceo:17!null co_ad_id:18!null co_desc:19!null co_open_date:20!null + ├── columns: column24:24!null co_id:12!null co_st_id:13!null co_name:14!null co_in_id:15!null co_sp_rate:16!null co_ceo:17!null co_ad_id:18!null co_desc:19!null co_open_date:20!null ├── cardinality: [0 - 1] + ├── immutable ├── key: () - ├── fd: ()-->(12-20,23) + ├── fd: ()-->(12-20,24) ├── scan company │ ├── columns: co_id:12!null co_st_id:13!null co_name:14!null co_in_id:15!null co_sp_rate:16!null co_ceo:17!null co_ad_id:18!null co_desc:19!null co_open_date:20!null │ ├── constraint: /12: [/0 - /0] @@ -5712,7 +5720,8 @@ update company │ ├── key: () │ └── fd: ()-->(12-20) └── projections - └── CASE co_sp_rate:16 != 'ABA' WHEN true THEN 'ABA' ELSE 'AAA' END [as=co_sp_rate_new:23, outer=(16)] + └── assignment-cast: VARCHAR(4) [as=column24:24, outer=(16), immutable] + └── CASE co_sp_rate:16 != 'ABA' WHEN true THEN 'ABA' ELSE 'AAA' END # Q7 opt @@ -5725,15 +5734,15 @@ update customer ├── columns: ├── fetch columns: c_id:27 c_tax_id:28 c_st_id:29 c_l_name:30 c_f_name:31 c_m_name:32 c_gndr:33 c_tier:34 c_dob:35 c_ad_id:36 c_ctry_1:37 c_area_1:38 c_local_1:39 c_ext_1:40 c_ctry_2:41 c_area_2:42 c_local_2:43 c_ext_2:44 c_ctry_3:45 c_area_3:46 c_local_3:47 c_ext_3:48 c_email_1:49 c_email_2:50 ├── update-mapping: - │ └── c_email_2_new:53 => c_email_2:24 + │ └── column54:54 => c_email_2:24 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: c_email_2_new:53 c_id:27!null c_tax_id:28!null c_st_id:29!null c_l_name:30!null c_f_name:31!null c_m_name:32 c_gndr:33 c_tier:34!null c_dob:35!null c_ad_id:36!null c_ctry_1:37 c_area_1:38 c_local_1:39 c_ext_1:40 c_ctry_2:41 c_area_2:42 c_local_2:43 c_ext_2:44 c_ctry_3:45 c_area_3:46 c_local_3:47 c_ext_3:48 c_email_1:49 c_email_2:50 + ├── columns: column54:54 c_id:27!null c_tax_id:28!null c_st_id:29!null c_l_name:30!null c_f_name:31!null c_m_name:32 c_gndr:33 c_tier:34!null c_dob:35!null c_ad_id:36!null c_ctry_1:37 c_area_1:38 c_local_1:39 c_ext_1:40 c_ctry_2:41 c_area_2:42 c_local_2:43 c_ext_2:44 c_ctry_3:45 c_area_3:46 c_local_3:47 c_ext_3:48 c_email_1:49 c_email_2:50 ├── cardinality: [0 - 1] ├── immutable ├── key: () - ├── fd: ()-->(27-50,53) + ├── fd: ()-->(27-50,54) ├── scan customer │ ├── columns: c_id:27!null c_tax_id:28!null c_st_id:29!null c_l_name:30!null c_f_name:31!null c_m_name:32 c_gndr:33 c_tier:34!null c_dob:35!null c_ad_id:36!null c_ctry_1:37 c_area_1:38 c_local_1:39 c_ext_1:40 c_ctry_2:41 c_area_2:42 c_local_2:43 c_ext_2:44 c_ctry_3:45 c_area_3:46 c_local_3:47 c_ext_3:48 c_email_1:49 c_email_2:50 │ ├── constraint: /27: [/0 - /0] @@ -5741,7 +5750,8 @@ update customer │ ├── key: () │ └── fd: ()-->(27-50) └── projections - └── left(c_email_2:50, strpos(c_email_2:50, '@')) || CASE c_email_2:50 LIKE '%@mindspring.com' WHEN true THEN 'earthlink.com' ELSE 'mindspring.com' END [as=c_email_2_new:53, outer=(50), immutable] + └── assignment-cast: VARCHAR(50) [as=column54:54, outer=(50), immutable] + └── left(c_email_2:50, strpos(c_email_2:50, '@')) || CASE c_email_2:50 LIKE '%@mindspring.com' WHEN true THEN 'earthlink.com' ELSE 'mindspring.com' END # Q8 opt @@ -5765,15 +5775,15 @@ update customer_taxrate ├── columns: ├── fetch columns: customer_taxrate.cx_tx_id:5 cx_c_id:6 ├── update-mapping: - │ └── cx_tx_id_new:9 => customer_taxrate.cx_tx_id:1 + │ └── column10:10 => customer_taxrate.cx_tx_id:1 ├── input binding: &1 ├── cardinality: [0 - 0] ├── volatile, mutations ├── project - │ ├── columns: cx_tx_id_new:9 customer_taxrate.cx_tx_id:5!null cx_c_id:6!null + │ ├── columns: column10:10 customer_taxrate.cx_tx_id:5!null cx_c_id:6!null │ ├── immutable │ ├── key: (5) - │ ├── fd: ()-->(6), (5)-->(9) + │ ├── fd: ()-->(6), (5)-->(10) │ ├── scan customer_taxrate@customer_taxrate_cx_c_id_idx │ │ ├── columns: customer_taxrate.cx_tx_id:5!null cx_c_id:6!null │ │ ├── constraint: /6/5 @@ -5782,17 +5792,18 @@ update customer_taxrate │ │ ├── key: (5) │ │ └── fd: ()-->(6) │ └── projections - │ └── CASE left(customer_taxrate.cx_tx_id:5, 2) = 'US' WHEN true THEN CASE customer_taxrate.cx_tx_id:5 = 'US5' WHEN true THEN 'US1' ELSE 'US' || (right(customer_taxrate.cx_tx_id:5, 1)::INT8 + 1)::STRING END ELSE CASE customer_taxrate.cx_tx_id:5 = 'CN4' WHEN true THEN 'CN1' ELSE 'CN' || (right(customer_taxrate.cx_tx_id:5, 1)::INT8 + 1)::STRING END END [as=cx_tx_id_new:9, outer=(5), immutable] + │ └── assignment-cast: VARCHAR(4) [as=column10:10, outer=(5), immutable] + │ └── CASE left(customer_taxrate.cx_tx_id:5, 2) = 'US' WHEN true THEN CASE customer_taxrate.cx_tx_id:5 = 'US5' WHEN true THEN 'US1' ELSE 'US' || (right(customer_taxrate.cx_tx_id:5, 1)::INT8 + 1)::STRING END ELSE CASE customer_taxrate.cx_tx_id:5 = 'CN4' WHEN true THEN 'CN1' ELSE 'CN' || (right(customer_taxrate.cx_tx_id:5, 1)::INT8 + 1)::STRING END END └── f-k-checks └── f-k-checks-item: customer_taxrate(cx_tx_id) -> taxrate(tx_id) └── anti-join (lookup taxrate) - ├── columns: cx_tx_id:10 - ├── key columns: [10] = [11] + ├── columns: cx_tx_id:11 + ├── key columns: [11] = [12] ├── lookup columns are key ├── with-scan &1 - │ ├── columns: cx_tx_id:10 + │ ├── columns: cx_tx_id:11 │ └── mapping: - │ └── cx_tx_id_new:9 => cx_tx_id:10 + │ └── column10:10 => cx_tx_id:11 └── filters (true) # Q9 @@ -5842,20 +5853,21 @@ update exchange ├── columns: ├── fetch columns: ex_id:10 ex_name:11 ex_num_symb:12 ex_open:13 ex_close:14 ex_desc:15 ex_ad_id:16 ├── update-mapping: - │ └── ex_desc_new:19 => ex_desc:6 + │ └── column20:20 => ex_desc:6 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: ex_desc_new:19 ex_id:10!null ex_name:11!null ex_num_symb:12!null ex_open:13!null ex_close:14!null ex_desc:15 ex_ad_id:16!null + ├── columns: column20:20 ex_id:10!null ex_name:11!null ex_num_symb:12!null ex_open:13!null ex_close:14!null ex_desc:15 ex_ad_id:16!null ├── immutable ├── key: (10) - ├── fd: (10)-->(11-16), (15)-->(19) + ├── fd: (10)-->(11-16), (15)-->(20) ├── scan exchange │ ├── columns: ex_id:10!null ex_name:11!null ex_num_symb:12!null ex_open:13!null ex_close:14!null ex_desc:15 ex_ad_id:16!null │ ├── key: (10) │ └── fd: (10)-->(11-16) └── projections - └── CASE ex_desc:15 NOT LIKE '%LAST UPDATED%' WHEN true THEN (ex_desc:15::STRING || ' LAST UPDATED ') || '2017-05-10 13:00:00' ELSE substring(ex_desc:15, 1, length(ex_desc:15) - 19) || '2017-05-10 13:00:00' END [as=ex_desc_new:19, outer=(15), immutable] + └── assignment-cast: VARCHAR(150) [as=column20:20, outer=(15), immutable] + └── CASE ex_desc:15 NOT LIKE '%LAST UPDATED%' WHEN true THEN (ex_desc:15::STRING || ' LAST UPDATED ') || '2017-05-10 13:00:00' ELSE substring(ex_desc:15, 1, length(ex_desc:15) - 19) || '2017-05-10 13:00:00' END # Q11 opt @@ -5968,15 +5980,15 @@ update taxrate ├── columns: ├── fetch columns: tx_id:6 tx_name:7 tx_rate:8 ├── update-mapping: - │ └── tx_name_new:11 => tx_name:2 + │ └── column12:12 => tx_name:2 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: tx_name_new:11 tx_id:6!null tx_name:7!null tx_rate:8!null + ├── columns: column12:12 tx_id:6!null tx_name:7!null tx_rate:8!null ├── cardinality: [0 - 1] ├── immutable ├── key: () - ├── fd: ()-->(6-8,11) + ├── fd: ()-->(6-8,12) ├── scan taxrate │ ├── columns: tx_id:6!null tx_name:7!null tx_rate:8!null │ ├── constraint: /6: [/'US1' - /'US1'] @@ -5984,7 +5996,8 @@ update taxrate │ ├── key: () │ └── fd: ()-->(6-8) └── projections - └── CASE tx_name:7 LIKE '% Tax %' WHEN true THEN replace(tx_name:7, ' Tax ', ' tax ') ELSE replace(tx_name:7, ' tax ', ' Tax ') END [as=tx_name_new:11, outer=(7), immutable] + └── assignment-cast: VARCHAR(50) [as=column12:12, outer=(7), immutable] + └── CASE tx_name:7 LIKE '% Tax %' WHEN true THEN replace(tx_name:7, ' Tax ', ' tax ') ELSE replace(tx_name:7, ' tax ', ' Tax ') END # Q15 opt @@ -6110,24 +6123,24 @@ update watch_item ├── columns: ├── fetch columns: wi_wl_id:5 watch_item.wi_s_symb:6 ├── update-mapping: - │ └── wi_s_symb_new:13 => watch_item.wi_s_symb:2 + │ └── column14:14 => watch_item.wi_s_symb:2 ├── input binding: &1 ├── cardinality: [0 - 0] ├── volatile, mutations ├── project - │ ├── columns: wi_s_symb_new:13!null wi_wl_id:5!null watch_item.wi_s_symb:6!null wl_id:9!null wl_c_id:10!null watch_list.crdb_internal_mvcc_timestamp:11 watch_list.tableoid:12 + │ ├── columns: column14:14!null wi_wl_id:5!null watch_item.wi_s_symb:6!null wl_id:9!null wl_c_id:10!null watch_list.crdb_internal_mvcc_timestamp:11 watch_list.tableoid:12 │ ├── key: (9) - │ ├── fd: ()-->(6,10,13), (9)-->(11,12), (5)==(9), (9)==(5) + │ ├── fd: ()-->(6,10,14), (9)-->(11,12), (5)==(9), (9)==(5) │ ├── inner-join (lookup watch_item) │ │ ├── columns: wi_wl_id:5!null watch_item.wi_s_symb:6!null wl_id:9!null wl_c_id:10!null watch_list.crdb_internal_mvcc_timestamp:11 watch_list.tableoid:12 - │ │ ├── key columns: [9 34] = [5 6] + │ │ ├── key columns: [9 35] = [5 6] │ │ ├── lookup columns are key │ │ ├── key: (9) │ │ ├── fd: ()-->(6,10), (9)-->(11,12), (5)==(9), (9)==(5) │ │ ├── project - │ │ │ ├── columns: "lookup_join_const_col_@6":34!null wl_id:9!null wl_c_id:10!null watch_list.crdb_internal_mvcc_timestamp:11 watch_list.tableoid:12 + │ │ │ ├── columns: "lookup_join_const_col_@6":35!null wl_id:9!null wl_c_id:10!null watch_list.crdb_internal_mvcc_timestamp:11 watch_list.tableoid:12 │ │ │ ├── key: (9) - │ │ │ ├── fd: ()-->(10,34), (9)-->(11,12) + │ │ │ ├── fd: ()-->(10,35), (9)-->(11,12) │ │ │ ├── index-join watch_list │ │ │ │ ├── columns: wl_id:9!null wl_c_id:10!null watch_list.crdb_internal_mvcc_timestamp:11 watch_list.tableoid:12 │ │ │ │ ├── key: (9) @@ -6138,22 +6151,22 @@ update watch_item │ │ │ │ ├── key: (9) │ │ │ │ └── fd: ()-->(10) │ │ │ └── projections - │ │ │ └── 'ROACH' [as="lookup_join_const_col_@6":34] + │ │ │ └── 'ROACH' [as="lookup_join_const_col_@6":35] │ │ └── filters (true) │ └── projections - │ └── 'ROACH' [as=wi_s_symb_new:13] + │ └── 'ROACH' [as=column14:14] └── f-k-checks └── f-k-checks-item: watch_item(wi_s_symb) -> security(s_symb) └── anti-join (lookup security) - ├── columns: wi_s_symb:14!null - ├── key columns: [14] = [15] + ├── columns: wi_s_symb:15!null + ├── key columns: [15] = [16] ├── lookup columns are key - ├── fd: ()-->(14) + ├── fd: ()-->(15) ├── with-scan &1 - │ ├── columns: wi_s_symb:14!null + │ ├── columns: wi_s_symb:15!null │ ├── mapping: - │ │ └── wi_s_symb_new:13 => wi_s_symb:14 - │ └── fd: ()-->(14) + │ │ └── column14:14 => wi_s_symb:15 + │ └── fd: ()-->(15) └── filters (true) # -------------------------------------------------- @@ -6238,15 +6251,15 @@ update trade ├── fetch columns: t_id:18 t_dts:19 trade.t_st_id:20 t_tt_id:21 t_is_cash:22 t_s_symb:23 t_qty:24 t_bid_price:25 t_ca_id:26 t_exec_name:27 t_trade_price:28 t_chrg:29 t_comm:30 t_lifo:32 ├── update-mapping: │ ├── t_dts_new:36 => t_dts:2 - │ └── t_st_id_new:35 => trade.t_st_id:3 + │ └── column37:37 => trade.t_st_id:3 ├── input binding: &1 ├── cardinality: [0 - 0] ├── volatile, mutations ├── project - │ ├── columns: t_st_id_new:35!null t_dts_new:36!null t_id:18!null t_dts:19!null trade.t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null + │ ├── columns: column37:37!null t_dts_new:36!null t_id:18!null t_dts:19!null trade.t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null │ ├── cardinality: [0 - 5] │ ├── key: (18) - │ ├── fd: ()-->(35,36), (18)-->(19-30,32) + │ ├── fd: ()-->(36,37), (18)-->(19-30,32) │ ├── scan trade │ │ ├── columns: t_id:18!null t_dts:19!null trade.t_st_id:20!null t_tt_id:21!null t_is_cash:22!null t_s_symb:23!null t_qty:24!null t_bid_price:25!null t_ca_id:26!null t_exec_name:27!null t_trade_price:28 t_chrg:29!null t_comm:30!null t_lifo:32!null │ │ ├── constraint: /18: [/1 - /5] @@ -6254,22 +6267,22 @@ update trade │ │ ├── key: (18) │ │ └── fd: (18)-->(19-30,32) │ └── projections - │ ├── 'PNDG' [as=t_st_id_new:35] + │ ├── 'PNDG' [as=column37:37] │ └── '2020-06-15 22:27:42.148484' [as=t_dts_new:36] └── f-k-checks └── f-k-checks-item: trade(t_st_id) -> status_type(st_id) └── anti-join (lookup status_type) - ├── columns: t_st_id:42!null - ├── key columns: [42] = [43] + ├── columns: t_st_id:43!null + ├── key columns: [43] = [44] ├── lookup columns are key ├── cardinality: [0 - 5] - ├── fd: ()-->(42) + ├── fd: ()-->(43) ├── with-scan &1 - │ ├── columns: t_st_id:42!null + │ ├── columns: t_st_id:43!null │ ├── mapping: - │ │ └── t_st_id_new:35 => t_st_id:42 + │ │ └── column37:37 => t_st_id:43 │ ├── cardinality: [0 - 5] - │ └── fd: ()-->(42) + │ └── fd: ()-->(43) └── filters (true) # Q4 diff --git a/pkg/sql/opt/xform/testdata/external/trading-mutation b/pkg/sql/opt/xform/testdata/external/trading-mutation index d0eb6bc782b4..f37383a637d5 100644 --- a/pkg/sql/opt/xform/testdata/external/trading-mutation +++ b/pkg/sql/opt/xform/testdata/external/trading-mutation @@ -1480,13 +1480,13 @@ update cardsinfo [as=ci] ├── fetch columns: ci.dealerid:21 ci.cardid:22 buyprice:23 sellprice:24 discount:25 desiredinventory:26 actualinventory:27 maxinventory:28 ci.version:29 discountbuyprice:30 notes:31 oldinventory:32 ci.extra:33 ├── update-mapping: │ ├── actualinventory_new:49 => actualinventory:12 - │ ├── discountbuyprice_comp:53 => discountbuyprice:15 + │ ├── column53:53 => discountbuyprice:15 │ ├── notes_default:50 => notes:16 │ └── oldinventory_default:51 => oldinventory:17 ├── cardinality: [0 - 0] ├── volatile, mutations └── project - ├── columns: discountbuyprice_comp:53 notes_default:50 oldinventory_default:51!null actualinventory_new:49 ci.dealerid:21!null ci.cardid:22!null buyprice:23!null sellprice:24!null discount:25!null desiredinventory:26!null actualinventory:27!null maxinventory:28!null ci.version:29!null discountbuyprice:30 notes:31 oldinventory:32 ci.extra:33 c:36!null q:37!null + ├── columns: column53:53!null notes_default:50 oldinventory_default:51!null actualinventory_new:49 ci.dealerid:21!null ci.cardid:22!null buyprice:23!null sellprice:24!null discount:25!null desiredinventory:26!null actualinventory:27!null maxinventory:28!null ci.version:29!null discountbuyprice:30 notes:31 oldinventory:32 ci.extra:33 c:36!null q:37!null ├── immutable ├── key: (22) ├── fd: ()-->(21,50,51), (22)-->(23-33,36,37,49,53), (29)-->(22-28,30-33), (22)==(36), (36)==(22) @@ -1592,7 +1592,8 @@ update cardsinfo [as=ci] │ └── const-agg [as=q:37, outer=(37)] │ └── q:37 └── projections - ├── crdb_internal.round_decimal_values(buyprice:23::DECIMAL - discount:25::DECIMAL, 4) [as=discountbuyprice_comp:53, outer=(23,25), immutable] + ├── assignment-cast: DECIMAL(10,4) [as=column53:53, outer=(23,25), immutable] + │ └── buyprice:23::DECIMAL - discount:25::DECIMAL ├── CAST(NULL AS STRING) [as=notes_default:50] ├── 0 [as=oldinventory_default:51] └── COALESCE(sum_int:47, 0) [as=actualinventory_new:49, outer=(47)]