github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/memo/testdata/logprops/upsert (about)

     1  exec-ddl
     2  CREATE TABLE abc (
     3      a INT NOT NULL,
     4      b INT DEFAULT (10),
     5      c INT AS (b + 1) STORED,
     6      UNIQUE(a),
     7      UNIQUE(b, c)
     8  )
     9  ----
    10  
    11  exec-ddl
    12  CREATE TABLE xyz (
    13      x INT PRIMARY KEY,
    14      y INT,
    15      z INT,
    16      UNIQUE (y, z),
    17      UNIQUE (z, y)
    18  )
    19  ----
    20  
    21  # INSERT..ON CONFLICT case. Don't inherit FDs.
    22  build
    23  INSERT INTO abc (a, b)
    24  SELECT x, y FROM xyz WHERE y=1
    25  ON CONFLICT (b, c) DO
    26  UPDATE SET a=1, b=excluded.b+abc.c
    27  RETURNING *
    28  ----
    29  project
    30   ├── columns: a:1(int!null) b:2(int) c:3(int)
    31   ├── volatile, side-effects, mutations
    32   ├── prune: (1-3)
    33   └── upsert abc
    34        ├── columns: a:1(int!null) b:2(int) c:3(int) rowid:4(int!null)
    35        ├── canary column: 13
    36        ├── fetch columns: a:10(int) b:11(int) c:12(int) rowid:13(int)
    37        ├── insert-mapping:
    38        │    ├── x:5 => a:1
    39        │    ├── y:6 => b:2
    40        │    ├── column9:9 => c:3
    41        │    └── column8:8 => rowid:4
    42        ├── update-mapping:
    43        │    ├── upsert_a:17 => a:1
    44        │    ├── upsert_b:18 => b:2
    45        │    └── upsert_c:19 => c:3
    46        ├── return-mapping:
    47        │    ├── upsert_a:17 => a:1
    48        │    ├── upsert_b:18 => b:2
    49        │    ├── upsert_c:19 => c:3
    50        │    └── upsert_rowid:20 => rowid:4
    51        ├── volatile, side-effects, mutations
    52        └── project
    53             ├── columns: upsert_a:17(int!null) upsert_b:18(int) upsert_c:19(int) upsert_rowid:20(int) x:5(int!null) y:6(int!null) column8:8(int) column9:9(int!null) a:10(int) b:11(int) c:12(int) rowid:13(int) a_new:14(int!null) b_new:15(int) column16:16(int)
    54             ├── volatile, side-effects
    55             ├── key: (13)
    56             ├── fd: ()-->(5,6,8,9,14), (13)-->(10-12), (10)-->(11-13), (11,12)~~>(10,13), (12)-->(15), (15)-->(16), (13)-->(17), (13,15)-->(18), (13,16)-->(19), (13)-->(20)
    57             ├── prune: (5,6,8-20)
    58             ├── reject-nulls: (10-13)
    59             ├── interesting orderings: (+13) (+10) (+11,+12,+13)
    60             ├── project
    61             │    ├── columns: column16:16(int) x:5(int!null) y:6(int!null) column8:8(int) column9:9(int!null) a:10(int) b:11(int) c:12(int) rowid:13(int) a_new:14(int!null) b_new:15(int)
    62             │    ├── volatile, side-effects
    63             │    ├── key: (13)
    64             │    ├── fd: ()-->(5,6,8,9,14), (13)-->(10-12), (10)-->(11-13), (11,12)~~>(10,13), (12)-->(15), (15)-->(16)
    65             │    ├── prune: (5,6,8-16)
    66             │    ├── reject-nulls: (10-13)
    67             │    ├── interesting orderings: (+13) (+10) (+11,+12,+13)
    68             │    ├── project
    69             │    │    ├── columns: a_new:14(int!null) b_new:15(int) x:5(int!null) y:6(int!null) column8:8(int) column9:9(int!null) a:10(int) b:11(int) c:12(int) rowid:13(int)
    70             │    │    ├── volatile, side-effects
    71             │    │    ├── key: (13)
    72             │    │    ├── fd: ()-->(5,6,8,9,14), (13)-->(10-12), (10)-->(11-13), (11,12)~~>(10,13), (12)-->(15)
    73             │    │    ├── prune: (5,6,8-15)
    74             │    │    ├── reject-nulls: (10-13)
    75             │    │    ├── interesting orderings: (+13) (+10) (+11,+12,+13)
    76             │    │    ├── left-join (hash)
    77             │    │    │    ├── columns: x:5(int!null) y:6(int!null) column8:8(int) column9:9(int!null) a:10(int) b:11(int) c:12(int) rowid:13(int)
    78             │    │    │    ├── volatile, side-effects
    79             │    │    │    ├── key: (13)
    80             │    │    │    ├── fd: ()-->(5,6,8,9), (13)-->(10-12), (10)-->(11-13), (11,12)~~>(10,13)
    81             │    │    │    ├── prune: (10,13)
    82             │    │    │    ├── reject-nulls: (10-13)
    83             │    │    │    ├── interesting orderings: (+13) (+10) (+11,+12,+13)
    84             │    │    │    ├── multiplicity: left-rows(exactly-one), right-rows(one-or-zero)
    85             │    │    │    ├── ensure-upsert-distinct-on
    86             │    │    │    │    ├── columns: x:5(int!null) y:6(int!null) column8:8(int) column9:9(int!null)
    87             │    │    │    │    ├── grouping columns: y:6(int!null) column9:9(int!null)
    88             │    │    │    │    ├── error: "UPSERT or INSERT...ON CONFLICT command cannot affect row a second time"
    89             │    │    │    │    ├── cardinality: [0 - 1]
    90             │    │    │    │    ├── volatile, side-effects
    91             │    │    │    │    ├── key: ()
    92             │    │    │    │    ├── fd: ()-->(5,6,8,9)
    93             │    │    │    │    ├── project
    94             │    │    │    │    │    ├── columns: column9:9(int!null) x:5(int!null) y:6(int!null) column8:8(int)
    95             │    │    │    │    │    ├── volatile, side-effects
    96             │    │    │    │    │    ├── key: (5)
    97             │    │    │    │    │    ├── fd: ()-->(6,9), (5)-->(8)
    98             │    │    │    │    │    ├── prune: (5,6,8,9)
    99             │    │    │    │    │    ├── interesting orderings: (+5) (+6)
   100             │    │    │    │    │    ├── project
   101             │    │    │    │    │    │    ├── columns: column8:8(int) x:5(int!null) y:6(int!null)
   102             │    │    │    │    │    │    ├── volatile, side-effects
   103             │    │    │    │    │    │    ├── key: (5)
   104             │    │    │    │    │    │    ├── fd: ()-->(6), (5)-->(8)
   105             │    │    │    │    │    │    ├── prune: (5,6,8)
   106             │    │    │    │    │    │    ├── interesting orderings: (+5) (+6)
   107             │    │    │    │    │    │    ├── project
   108             │    │    │    │    │    │    │    ├── columns: x:5(int!null) y:6(int!null)
   109             │    │    │    │    │    │    │    ├── key: (5)
   110             │    │    │    │    │    │    │    ├── fd: ()-->(6)
   111             │    │    │    │    │    │    │    ├── prune: (5,6)
   112             │    │    │    │    │    │    │    ├── interesting orderings: (+5) (+6)
   113             │    │    │    │    │    │    │    └── select
   114             │    │    │    │    │    │    │         ├── columns: x:5(int!null) y:6(int!null) z:7(int)
   115             │    │    │    │    │    │    │         ├── key: (5)
   116             │    │    │    │    │    │    │         ├── fd: ()-->(6), (5)-->(7), (6,7)~~>(5)
   117             │    │    │    │    │    │    │         ├── prune: (5,7)
   118             │    │    │    │    │    │    │         ├── interesting orderings: (+5) (+6,+7,+5) (+7,+6,+5)
   119             │    │    │    │    │    │    │         ├── scan xyz
   120             │    │    │    │    │    │    │         │    ├── columns: x:5(int!null) y:6(int) z:7(int)
   121             │    │    │    │    │    │    │         │    ├── key: (5)
   122             │    │    │    │    │    │    │         │    ├── fd: (5)-->(6,7), (6,7)~~>(5)
   123             │    │    │    │    │    │    │         │    ├── prune: (5-7)
   124             │    │    │    │    │    │    │         │    └── interesting orderings: (+5) (+6,+7,+5) (+7,+6,+5)
   125             │    │    │    │    │    │    │         └── filters
   126             │    │    │    │    │    │    │              └── eq [type=bool, outer=(6), constraints=(/6: [/1 - /1]; tight), fd=()-->(6)]
   127             │    │    │    │    │    │    │                   ├── variable: y:6 [type=int]
   128             │    │    │    │    │    │    │                   └── const: 1 [type=int]
   129             │    │    │    │    │    │    └── projections
   130             │    │    │    │    │    │         └── function: unique_rowid [as=column8:8, type=int, volatile, side-effects]
   131             │    │    │    │    │    └── projections
   132             │    │    │    │    │         └── plus [as=column9:9, type=int, outer=(6)]
   133             │    │    │    │    │              ├── variable: y:6 [type=int]
   134             │    │    │    │    │              └── const: 1 [type=int]
   135             │    │    │    │    └── aggregations
   136             │    │    │    │         ├── first-agg [as=x:5, type=int, outer=(5)]
   137             │    │    │    │         │    └── variable: x:5 [type=int]
   138             │    │    │    │         └── first-agg [as=column8:8, type=int, outer=(8)]
   139             │    │    │    │              └── variable: column8:8 [type=int]
   140             │    │    │    ├── scan abc
   141             │    │    │    │    ├── columns: a:10(int!null) b:11(int) c:12(int) rowid:13(int!null)
   142             │    │    │    │    ├── computed column expressions
   143             │    │    │    │    │    └── c:12
   144             │    │    │    │    │         └── plus [type=int]
   145             │    │    │    │    │              ├── variable: b:11 [type=int]
   146             │    │    │    │    │              └── const: 1 [type=int]
   147             │    │    │    │    ├── key: (13)
   148             │    │    │    │    ├── fd: (13)-->(10-12), (10)-->(11-13), (11,12)~~>(10,13)
   149             │    │    │    │    ├── prune: (10-13)
   150             │    │    │    │    └── interesting orderings: (+13) (+10) (+11,+12,+13)
   151             │    │    │    └── filters
   152             │    │    │         ├── eq [type=bool, outer=(6,11), constraints=(/6: (/NULL - ]; /11: (/NULL - ]), fd=(6)==(11), (11)==(6)]
   153             │    │    │         │    ├── variable: y:6 [type=int]
   154             │    │    │         │    └── variable: b:11 [type=int]
   155             │    │    │         └── eq [type=bool, outer=(9,12), constraints=(/9: (/NULL - ]; /12: (/NULL - ]), fd=(9)==(12), (12)==(9)]
   156             │    │    │              ├── variable: column9:9 [type=int]
   157             │    │    │              └── variable: c:12 [type=int]
   158             │    │    └── projections
   159             │    │         ├── const: 1 [as=a_new:14, type=int]
   160             │    │         └── plus [as=b_new:15, type=int, outer=(6,12)]
   161             │    │              ├── variable: y:6 [type=int]
   162             │    │              └── variable: c:12 [type=int]
   163             │    └── projections
   164             │         └── plus [as=column16:16, type=int, outer=(15)]
   165             │              ├── variable: b_new:15 [type=int]
   166             │              └── const: 1 [type=int]
   167             └── projections
   168                  ├── case [as=upsert_a:17, type=int, outer=(5,13,14)]
   169                  │    ├── true [type=bool]
   170                  │    ├── when [type=int]
   171                  │    │    ├── is [type=bool]
   172                  │    │    │    ├── variable: rowid:13 [type=int]
   173                  │    │    │    └── null [type=unknown]
   174                  │    │    └── variable: x:5 [type=int]
   175                  │    └── variable: a_new:14 [type=int]
   176                  ├── case [as=upsert_b:18, type=int, outer=(6,13,15)]
   177                  │    ├── true [type=bool]
   178                  │    ├── when [type=int]
   179                  │    │    ├── is [type=bool]
   180                  │    │    │    ├── variable: rowid:13 [type=int]
   181                  │    │    │    └── null [type=unknown]
   182                  │    │    └── variable: y:6 [type=int]
   183                  │    └── variable: b_new:15 [type=int]
   184                  ├── case [as=upsert_c:19, type=int, outer=(9,13,16)]
   185                  │    ├── true [type=bool]
   186                  │    ├── when [type=int]
   187                  │    │    ├── is [type=bool]
   188                  │    │    │    ├── variable: rowid:13 [type=int]
   189                  │    │    │    └── null [type=unknown]
   190                  │    │    └── variable: column9:9 [type=int]
   191                  │    └── variable: column16:16 [type=int]
   192                  └── case [as=upsert_rowid:20, type=int, outer=(8,13)]
   193                       ├── true [type=bool]
   194                       ├── when [type=int]
   195                       │    ├── is [type=bool]
   196                       │    │    ├── variable: rowid:13 [type=int]
   197                       │    │    └── null [type=unknown]
   198                       │    └── variable: column8:8 [type=int]
   199                       └── variable: rowid:13 [type=int]
   200  
   201  # DO NOTHING case.
   202  build
   203  INSERT INTO abc (a, b)
   204  SELECT x, y FROM xyz
   205  ON CONFLICT DO NOTHING
   206  RETURNING *
   207  ----
   208  project
   209   ├── columns: a:1(int!null) b:2(int) c:3(int)
   210   ├── volatile, side-effects, mutations
   211   ├── key: (1)
   212   ├── fd: (1)-->(2,3), (2)-->(3), (2,3)~~>(1)
   213   ├── prune: (1-3)
   214   └── insert abc
   215        ├── columns: a:1(int!null) b:2(int) c:3(int) rowid:4(int!null)
   216        ├── insert-mapping:
   217        │    ├── x:5 => a:1
   218        │    ├── y:6 => b:2
   219        │    ├── column9:9 => c:3
   220        │    └── column8:8 => rowid:4
   221        ├── volatile, side-effects, mutations
   222        ├── key: (1)
   223        ├── fd: (1)-->(2-4), (2)-->(3), (4)~~>(1-3), (2,3)~~>(1,4)
   224        └── upsert-distinct-on
   225             ├── columns: x:5(int!null) y:6(int) column8:8(int) column9:9(int)
   226             ├── grouping columns: y:6(int) column9:9(int)
   227             ├── volatile, side-effects
   228             ├── key: (5)
   229             ├── fd: (5)-->(6,8,9), (6)-->(9), (8)~~>(5,6,9), (6,9)~~>(5,8)
   230             ├── project
   231             │    ├── columns: x:5(int!null) y:6(int) column8:8(int) column9:9(int)
   232             │    ├── volatile, side-effects
   233             │    ├── key: (5)
   234             │    ├── fd: (5)-->(6,8,9), (6)-->(9), (8)~~>(5,6,9)
   235             │    ├── prune: (5,6,8,9)
   236             │    └── select
   237             │         ├── columns: x:5(int!null) y:6(int) column8:8(int) column9:9(int) a:18(int) b:19(int) c:20(int) rowid:21(int)
   238             │         ├── volatile, side-effects
   239             │         ├── key: (5)
   240             │         ├── fd: ()-->(18-21), (5)-->(6,8,9), (6)-->(9), (8)~~>(5,6,9)
   241             │         ├── prune: (18)
   242             │         ├── interesting orderings: (+21) (+18) (+19,+20,+21)
   243             │         ├── left-join (hash)
   244             │         │    ├── columns: x:5(int!null) y:6(int) column8:8(int) column9:9(int) a:18(int) b:19(int) c:20(int) rowid:21(int)
   245             │         │    ├── volatile, side-effects
   246             │         │    ├── key: (5,21)
   247             │         │    ├── fd: (5)-->(6,8,9), (6)-->(9), (8)~~>(5,6,9), (21)-->(18-20), (18)-->(19-21), (19,20)~~>(18,21)
   248             │         │    ├── prune: (18,21)
   249             │         │    ├── reject-nulls: (18-21)
   250             │         │    ├── interesting orderings: (+21) (+18) (+19,+20,+21)
   251             │         │    ├── multiplicity: left-rows(exactly-one), right-rows(zero-or-more)
   252             │         │    ├── upsert-distinct-on
   253             │         │    │    ├── columns: x:5(int!null) y:6(int) column8:8(int) column9:9(int)
   254             │         │    │    ├── grouping columns: x:5(int!null)
   255             │         │    │    ├── volatile, side-effects
   256             │         │    │    ├── key: (5)
   257             │         │    │    ├── fd: (5)-->(6,8,9), (6)-->(9), (8)~~>(5,6,9)
   258             │         │    │    ├── project
   259             │         │    │    │    ├── columns: x:5(int!null) y:6(int) column8:8(int) column9:9(int)
   260             │         │    │    │    ├── volatile, side-effects
   261             │         │    │    │    ├── key: (5)
   262             │         │    │    │    ├── fd: (5)-->(6,8), (6)-->(9), (8)~~>(5,6,9)
   263             │         │    │    │    ├── prune: (5,6,8,9)
   264             │         │    │    │    └── select
   265             │         │    │    │         ├── columns: x:5(int!null) y:6(int) column8:8(int) column9:9(int) a:14(int) b:15(int) c:16(int) rowid:17(int)
   266             │         │    │    │         ├── volatile, side-effects
   267             │         │    │    │         ├── key: (5)
   268             │         │    │    │         ├── fd: ()-->(14-17), (5)-->(6,8), (6)-->(9), (8)~~>(5,6,9)
   269             │         │    │    │         ├── prune: (15-17)
   270             │         │    │    │         ├── interesting orderings: (+17) (+14) (+15,+16,+17)
   271             │         │    │    │         ├── left-join (hash)
   272             │         │    │    │         │    ├── columns: x:5(int!null) y:6(int) column8:8(int) column9:9(int) a:14(int) b:15(int) c:16(int) rowid:17(int)
   273             │         │    │    │         │    ├── volatile, side-effects
   274             │         │    │    │         │    ├── key: (5)
   275             │         │    │    │         │    ├── fd: (5)-->(6,8,14-17), (6)-->(9), (8)~~>(5,6,9), (17)-->(14-16), (14)-->(15-17), (15,16)~~>(14,17)
   276             │         │    │    │         │    ├── prune: (15-17)
   277             │         │    │    │         │    ├── reject-nulls: (14-17)
   278             │         │    │    │         │    ├── interesting orderings: (+17) (+14) (+15,+16,+17)
   279             │         │    │    │         │    ├── multiplicity: left-rows(exactly-one), right-rows(one-or-zero)
   280             │         │    │    │         │    ├── upsert-distinct-on
   281             │         │    │    │         │    │    ├── columns: x:5(int!null) y:6(int) column8:8(int) column9:9(int)
   282             │         │    │    │         │    │    ├── grouping columns: column8:8(int)
   283             │         │    │    │         │    │    ├── volatile, side-effects
   284             │         │    │    │         │    │    ├── key: (5)
   285             │         │    │    │         │    │    ├── fd: (5)-->(6,8), (6)-->(9), (8)~~>(5,6,9)
   286             │         │    │    │         │    │    ├── project
   287             │         │    │    │         │    │    │    ├── columns: x:5(int!null) y:6(int) column8:8(int) column9:9(int)
   288             │         │    │    │         │    │    │    ├── volatile, side-effects
   289             │         │    │    │         │    │    │    ├── key: (5)
   290             │         │    │    │         │    │    │    ├── fd: (5)-->(6,8), (6)-->(9)
   291             │         │    │    │         │    │    │    ├── prune: (5,6,8,9)
   292             │         │    │    │         │    │    │    ├── interesting orderings: (+5) (+6)
   293             │         │    │    │         │    │    │    └── select
   294             │         │    │    │         │    │    │         ├── columns: x:5(int!null) y:6(int) column8:8(int) column9:9(int) a:10(int) b:11(int) c:12(int) rowid:13(int)
   295             │         │    │    │         │    │    │         ├── volatile, side-effects
   296             │         │    │    │         │    │    │         ├── key: (5)
   297             │         │    │    │         │    │    │         ├── fd: ()-->(10-13), (5)-->(6,8), (6)-->(9)
   298             │         │    │    │         │    │    │         ├── prune: (5,6,9-12)
   299             │         │    │    │         │    │    │         ├── interesting orderings: (+5) (+6) (+13) (+10) (+11,+12,+13)
   300             │         │    │    │         │    │    │         ├── left-join (hash)
   301             │         │    │    │         │    │    │         │    ├── columns: x:5(int!null) y:6(int) column8:8(int) column9:9(int) a:10(int) b:11(int) c:12(int) rowid:13(int)
   302             │         │    │    │         │    │    │         │    ├── volatile, side-effects
   303             │         │    │    │         │    │    │         │    ├── key: (5)
   304             │         │    │    │         │    │    │         │    ├── fd: (5)-->(6,8,10-13), (6)-->(9), (13)-->(10-12), (10)-->(11-13), (11,12)~~>(10,13)
   305             │         │    │    │         │    │    │         │    ├── prune: (5,6,9-12)
   306             │         │    │    │         │    │    │         │    ├── reject-nulls: (10-13)
   307             │         │    │    │         │    │    │         │    ├── interesting orderings: (+5) (+6) (+13) (+10) (+11,+12,+13)
   308             │         │    │    │         │    │    │         │    ├── multiplicity: left-rows(exactly-one), right-rows(zero-or-more)
   309             │         │    │    │         │    │    │         │    ├── project
   310             │         │    │    │         │    │    │         │    │    ├── columns: column9:9(int) x:5(int!null) y:6(int) column8:8(int)
   311             │         │    │    │         │    │    │         │    │    ├── volatile, side-effects
   312             │         │    │    │         │    │    │         │    │    ├── key: (5)
   313             │         │    │    │         │    │    │         │    │    ├── fd: (5)-->(6,8), (6)-->(9)
   314             │         │    │    │         │    │    │         │    │    ├── prune: (5,6,8,9)
   315             │         │    │    │         │    │    │         │    │    ├── interesting orderings: (+5) (+6)
   316             │         │    │    │         │    │    │         │    │    ├── project
   317             │         │    │    │         │    │    │         │    │    │    ├── columns: column8:8(int) x:5(int!null) y:6(int)
   318             │         │    │    │         │    │    │         │    │    │    ├── volatile, side-effects
   319             │         │    │    │         │    │    │         │    │    │    ├── key: (5)
   320             │         │    │    │         │    │    │         │    │    │    ├── fd: (5)-->(6,8)
   321             │         │    │    │         │    │    │         │    │    │    ├── prune: (5,6,8)
   322             │         │    │    │         │    │    │         │    │    │    ├── interesting orderings: (+5) (+6)
   323             │         │    │    │         │    │    │         │    │    │    ├── project
   324             │         │    │    │         │    │    │         │    │    │    │    ├── columns: x:5(int!null) y:6(int)
   325             │         │    │    │         │    │    │         │    │    │    │    ├── key: (5)
   326             │         │    │    │         │    │    │         │    │    │    │    ├── fd: (5)-->(6)
   327             │         │    │    │         │    │    │         │    │    │    │    ├── prune: (5,6)
   328             │         │    │    │         │    │    │         │    │    │    │    ├── interesting orderings: (+5) (+6)
   329             │         │    │    │         │    │    │         │    │    │    │    └── scan xyz
   330             │         │    │    │         │    │    │         │    │    │    │         ├── columns: x:5(int!null) y:6(int) z:7(int)
   331             │         │    │    │         │    │    │         │    │    │    │         ├── key: (5)
   332             │         │    │    │         │    │    │         │    │    │    │         ├── fd: (5)-->(6,7), (6,7)~~>(5)
   333             │         │    │    │         │    │    │         │    │    │    │         ├── prune: (5-7)
   334             │         │    │    │         │    │    │         │    │    │    │         └── interesting orderings: (+5) (+6,+7,+5) (+7,+6,+5)
   335             │         │    │    │         │    │    │         │    │    │    └── projections
   336             │         │    │    │         │    │    │         │    │    │         └── function: unique_rowid [as=column8:8, type=int, volatile, side-effects]
   337             │         │    │    │         │    │    │         │    │    └── projections
   338             │         │    │    │         │    │    │         │    │         └── plus [as=column9:9, type=int, outer=(6)]
   339             │         │    │    │         │    │    │         │    │              ├── variable: y:6 [type=int]
   340             │         │    │    │         │    │    │         │    │              └── const: 1 [type=int]
   341             │         │    │    │         │    │    │         │    ├── scan abc
   342             │         │    │    │         │    │    │         │    │    ├── columns: a:10(int!null) b:11(int) c:12(int) rowid:13(int!null)
   343             │         │    │    │         │    │    │         │    │    ├── computed column expressions
   344             │         │    │    │         │    │    │         │    │    │    └── c:12
   345             │         │    │    │         │    │    │         │    │    │         └── plus [type=int]
   346             │         │    │    │         │    │    │         │    │    │              ├── variable: b:11 [type=int]
   347             │         │    │    │         │    │    │         │    │    │              └── const: 1 [type=int]
   348             │         │    │    │         │    │    │         │    │    ├── key: (13)
   349             │         │    │    │         │    │    │         │    │    ├── fd: (13)-->(10-12), (10)-->(11-13), (11,12)~~>(10,13)
   350             │         │    │    │         │    │    │         │    │    ├── prune: (10-13)
   351             │         │    │    │         │    │    │         │    │    └── interesting orderings: (+13) (+10) (+11,+12,+13)
   352             │         │    │    │         │    │    │         │    └── filters
   353             │         │    │    │         │    │    │         │         └── eq [type=bool, outer=(8,13), constraints=(/8: (/NULL - ]; /13: (/NULL - ]), fd=(8)==(13), (13)==(8)]
   354             │         │    │    │         │    │    │         │              ├── variable: column8:8 [type=int]
   355             │         │    │    │         │    │    │         │              └── variable: rowid:13 [type=int]
   356             │         │    │    │         │    │    │         └── filters
   357             │         │    │    │         │    │    │              └── is [type=bool, outer=(13), constraints=(/13: [/NULL - /NULL]; tight), fd=()-->(13)]
   358             │         │    │    │         │    │    │                   ├── variable: rowid:13 [type=int]
   359             │         │    │    │         │    │    │                   └── null [type=unknown]
   360             │         │    │    │         │    │    └── aggregations
   361             │         │    │    │         │    │         ├── first-agg [as=x:5, type=int, outer=(5)]
   362             │         │    │    │         │    │         │    └── variable: x:5 [type=int]
   363             │         │    │    │         │    │         ├── first-agg [as=y:6, type=int, outer=(6)]
   364             │         │    │    │         │    │         │    └── variable: y:6 [type=int]
   365             │         │    │    │         │    │         └── first-agg [as=column9:9, type=int, outer=(9)]
   366             │         │    │    │         │    │              └── variable: column9:9 [type=int]
   367             │         │    │    │         │    ├── scan abc
   368             │         │    │    │         │    │    ├── columns: a:14(int!null) b:15(int) c:16(int) rowid:17(int!null)
   369             │         │    │    │         │    │    ├── computed column expressions
   370             │         │    │    │         │    │    │    └── c:16
   371             │         │    │    │         │    │    │         └── plus [type=int]
   372             │         │    │    │         │    │    │              ├── variable: b:15 [type=int]
   373             │         │    │    │         │    │    │              └── const: 1 [type=int]
   374             │         │    │    │         │    │    ├── key: (17)
   375             │         │    │    │         │    │    ├── fd: (17)-->(14-16), (14)-->(15-17), (15,16)~~>(14,17)
   376             │         │    │    │         │    │    ├── prune: (14-17)
   377             │         │    │    │         │    │    └── interesting orderings: (+17) (+14) (+15,+16,+17)
   378             │         │    │    │         │    └── filters
   379             │         │    │    │         │         └── eq [type=bool, outer=(5,14), constraints=(/5: (/NULL - ]; /14: (/NULL - ]), fd=(5)==(14), (14)==(5)]
   380             │         │    │    │         │              ├── variable: x:5 [type=int]
   381             │         │    │    │         │              └── variable: a:14 [type=int]
   382             │         │    │    │         └── filters
   383             │         │    │    │              └── is [type=bool, outer=(14), constraints=(/14: [/NULL - /NULL]; tight), fd=()-->(14)]
   384             │         │    │    │                   ├── variable: a:14 [type=int]
   385             │         │    │    │                   └── null [type=unknown]
   386             │         │    │    └── aggregations
   387             │         │    │         ├── first-agg [as=y:6, type=int, outer=(6)]
   388             │         │    │         │    └── variable: y:6 [type=int]
   389             │         │    │         ├── first-agg [as=column8:8, type=int, outer=(8)]
   390             │         │    │         │    └── variable: column8:8 [type=int]
   391             │         │    │         └── first-agg [as=column9:9, type=int, outer=(9)]
   392             │         │    │              └── variable: column9:9 [type=int]
   393             │         │    ├── scan abc
   394             │         │    │    ├── columns: a:18(int!null) b:19(int) c:20(int) rowid:21(int!null)
   395             │         │    │    ├── computed column expressions
   396             │         │    │    │    └── c:20
   397             │         │    │    │         └── plus [type=int]
   398             │         │    │    │              ├── variable: b:19 [type=int]
   399             │         │    │    │              └── const: 1 [type=int]
   400             │         │    │    ├── key: (21)
   401             │         │    │    ├── fd: (21)-->(18-20), (18)-->(19-21), (19,20)~~>(18,21)
   402             │         │    │    ├── prune: (18-21)
   403             │         │    │    └── interesting orderings: (+21) (+18) (+19,+20,+21)
   404             │         │    └── filters
   405             │         │         ├── eq [type=bool, outer=(6,19), constraints=(/6: (/NULL - ]; /19: (/NULL - ]), fd=(6)==(19), (19)==(6)]
   406             │         │         │    ├── variable: y:6 [type=int]
   407             │         │         │    └── variable: b:19 [type=int]
   408             │         │         └── eq [type=bool, outer=(9,20), constraints=(/9: (/NULL - ]; /20: (/NULL - ]), fd=(9)==(20), (20)==(9)]
   409             │         │              ├── variable: column9:9 [type=int]
   410             │         │              └── variable: c:20 [type=int]
   411             │         └── filters
   412             │              └── is [type=bool, outer=(21), constraints=(/21: [/NULL - /NULL]; tight), fd=()-->(21)]
   413             │                   ├── variable: rowid:21 [type=int]
   414             │                   └── null [type=unknown]
   415             └── aggregations
   416                  ├── first-agg [as=x:5, type=int, outer=(5)]
   417                  │    └── variable: x:5 [type=int]
   418                  └── first-agg [as=column8:8, type=int, outer=(8)]
   419                       └── variable: column8:8 [type=int]
   420  
   421  # UPSERT case.
   422  build
   423  UPSERT INTO abc (a) VALUES (1), (2) RETURNING b+c
   424  ----
   425  project
   426   ├── columns: "?column?":17(int)
   427   ├── cardinality: [1 - ]
   428   ├── volatile, side-effects, mutations
   429   ├── prune: (17)
   430   ├── upsert abc
   431   │    ├── columns: a:1(int!null) b:2(int) c:3(int) rowid:4(int!null)
   432   │    ├── canary column: 12
   433   │    ├── fetch columns: a:9(int) b:10(int) c:11(int) rowid:12(int)
   434   │    ├── insert-mapping:
   435   │    │    ├── column1:5 => a:1
   436   │    │    ├── column6:6 => b:2
   437   │    │    ├── column8:8 => c:3
   438   │    │    └── column7:7 => rowid:4
   439   │    ├── update-mapping:
   440   │    │    ├── column1:5 => a:1
   441   │    │    └── upsert_c:15 => c:3
   442   │    ├── return-mapping:
   443   │    │    ├── column1:5 => a:1
   444   │    │    ├── upsert_b:14 => b:2
   445   │    │    ├── upsert_c:15 => c:3
   446   │    │    └── upsert_rowid:16 => rowid:4
   447   │    ├── cardinality: [1 - ]
   448   │    ├── volatile, side-effects, mutations
   449   │    └── project
   450   │         ├── columns: upsert_b:14(int) upsert_c:15(int) upsert_rowid:16(int) column1:5(int!null) column6:6(int!null) column7:7(int) column8:8(int!null) a:9(int) b:10(int) c:11(int) rowid:12(int) column13:13(int)
   451   │         ├── cardinality: [1 - ]
   452   │         ├── volatile, side-effects
   453   │         ├── lax-key: (7,12)
   454   │         ├── fd: ()-->(6,8), (7)~~>(5), (12)-->(9-11), (9)-->(10-12), (10,11)~~>(9,12), (10)-->(13), (10,12)-->(14), (12,13)-->(15), (7,12)-->(16)
   455   │         ├── prune: (5-16)
   456   │         ├── reject-nulls: (9-12)
   457   │         ├── interesting orderings: (+12) (+9) (+10,+11,+12)
   458   │         ├── project
   459   │         │    ├── columns: column13:13(int) column1:5(int!null) column6:6(int!null) column7:7(int) column8:8(int!null) a:9(int) b:10(int) c:11(int) rowid:12(int)
   460   │         │    ├── cardinality: [1 - ]
   461   │         │    ├── volatile, side-effects
   462   │         │    ├── lax-key: (7,12)
   463   │         │    ├── fd: ()-->(6,8), (7)~~>(5), (12)-->(9-11), (9)-->(10-12), (10,11)~~>(9,12), (10)-->(13)
   464   │         │    ├── prune: (5-13)
   465   │         │    ├── reject-nulls: (9-12)
   466   │         │    ├── interesting orderings: (+12) (+9) (+10,+11,+12)
   467   │         │    ├── left-join (hash)
   468   │         │    │    ├── columns: column1:5(int!null) column6:6(int!null) column7:7(int) column8:8(int!null) a:9(int) b:10(int) c:11(int) rowid:12(int)
   469   │         │    │    ├── cardinality: [1 - ]
   470   │         │    │    ├── volatile, side-effects
   471   │         │    │    ├── lax-key: (7,12)
   472   │         │    │    ├── fd: ()-->(6,8), (7)~~>(5), (12)-->(9-11), (9)-->(10-12), (10,11)~~>(9,12)
   473   │         │    │    ├── prune: (9-11)
   474   │         │    │    ├── reject-nulls: (9-12)
   475   │         │    │    ├── interesting orderings: (+12) (+9) (+10,+11,+12)
   476   │         │    │    ├── multiplicity: left-rows(exactly-one), right-rows(one-or-zero)
   477   │         │    │    ├── ensure-upsert-distinct-on
   478   │         │    │    │    ├── columns: column1:5(int!null) column6:6(int!null) column7:7(int) column8:8(int!null)
   479   │         │    │    │    ├── grouping columns: column7:7(int)
   480   │         │    │    │    ├── error: "UPSERT or INSERT...ON CONFLICT command cannot affect row a second time"
   481   │         │    │    │    ├── cardinality: [1 - 2]
   482   │         │    │    │    ├── volatile, side-effects
   483   │         │    │    │    ├── lax-key: (7)
   484   │         │    │    │    ├── fd: ()-->(6,8), (7)~~>(5,6,8)
   485   │         │    │    │    ├── project
   486   │         │    │    │    │    ├── columns: column8:8(int!null) column1:5(int!null) column6:6(int!null) column7:7(int)
   487   │         │    │    │    │    ├── cardinality: [2 - 2]
   488   │         │    │    │    │    ├── volatile, side-effects
   489   │         │    │    │    │    ├── fd: ()-->(6,8)
   490   │         │    │    │    │    ├── prune: (5-8)
   491   │         │    │    │    │    ├── project
   492   │         │    │    │    │    │    ├── columns: column6:6(int!null) column7:7(int) column1:5(int!null)
   493   │         │    │    │    │    │    ├── cardinality: [2 - 2]
   494   │         │    │    │    │    │    ├── volatile, side-effects
   495   │         │    │    │    │    │    ├── fd: ()-->(6)
   496   │         │    │    │    │    │    ├── prune: (5-7)
   497   │         │    │    │    │    │    ├── values
   498   │         │    │    │    │    │    │    ├── columns: column1:5(int!null)
   499   │         │    │    │    │    │    │    ├── cardinality: [2 - 2]
   500   │         │    │    │    │    │    │    ├── prune: (5)
   501   │         │    │    │    │    │    │    ├── tuple [type=tuple{int}]
   502   │         │    │    │    │    │    │    │    └── const: 1 [type=int]
   503   │         │    │    │    │    │    │    └── tuple [type=tuple{int}]
   504   │         │    │    │    │    │    │         └── const: 2 [type=int]
   505   │         │    │    │    │    │    └── projections
   506   │         │    │    │    │    │         ├── const: 10 [as=column6:6, type=int]
   507   │         │    │    │    │    │         └── function: unique_rowid [as=column7:7, type=int, volatile, side-effects]
   508   │         │    │    │    │    └── projections
   509   │         │    │    │    │         └── plus [as=column8:8, type=int, outer=(6)]
   510   │         │    │    │    │              ├── variable: column6:6 [type=int]
   511   │         │    │    │    │              └── const: 1 [type=int]
   512   │         │    │    │    └── aggregations
   513   │         │    │    │         ├── first-agg [as=column1:5, type=int, outer=(5)]
   514   │         │    │    │         │    └── variable: column1:5 [type=int]
   515   │         │    │    │         ├── first-agg [as=column6:6, type=int, outer=(6)]
   516   │         │    │    │         │    └── variable: column6:6 [type=int]
   517   │         │    │    │         └── first-agg [as=column8:8, type=int, outer=(8)]
   518   │         │    │    │              └── variable: column8:8 [type=int]
   519   │         │    │    ├── scan abc
   520   │         │    │    │    ├── columns: a:9(int!null) b:10(int) c:11(int) rowid:12(int!null)
   521   │         │    │    │    ├── computed column expressions
   522   │         │    │    │    │    └── c:11
   523   │         │    │    │    │         └── plus [type=int]
   524   │         │    │    │    │              ├── variable: b:10 [type=int]
   525   │         │    │    │    │              └── const: 1 [type=int]
   526   │         │    │    │    ├── key: (12)
   527   │         │    │    │    ├── fd: (12)-->(9-11), (9)-->(10-12), (10,11)~~>(9,12)
   528   │         │    │    │    ├── prune: (9-12)
   529   │         │    │    │    └── interesting orderings: (+12) (+9) (+10,+11,+12)
   530   │         │    │    └── filters
   531   │         │    │         └── eq [type=bool, outer=(7,12), constraints=(/7: (/NULL - ]; /12: (/NULL - ]), fd=(7)==(12), (12)==(7)]
   532   │         │    │              ├── variable: column7:7 [type=int]
   533   │         │    │              └── variable: rowid:12 [type=int]
   534   │         │    └── projections
   535   │         │         └── plus [as=column13:13, type=int, outer=(10)]
   536   │         │              ├── variable: b:10 [type=int]
   537   │         │              └── const: 1 [type=int]
   538   │         └── projections
   539   │              ├── case [as=upsert_b:14, type=int, outer=(6,10,12)]
   540   │              │    ├── true [type=bool]
   541   │              │    ├── when [type=int]
   542   │              │    │    ├── is [type=bool]
   543   │              │    │    │    ├── variable: rowid:12 [type=int]
   544   │              │    │    │    └── null [type=unknown]
   545   │              │    │    └── variable: column6:6 [type=int]
   546   │              │    └── variable: b:10 [type=int]
   547   │              ├── case [as=upsert_c:15, type=int, outer=(8,12,13)]
   548   │              │    ├── true [type=bool]
   549   │              │    ├── when [type=int]
   550   │              │    │    ├── is [type=bool]
   551   │              │    │    │    ├── variable: rowid:12 [type=int]
   552   │              │    │    │    └── null [type=unknown]
   553   │              │    │    └── variable: column8:8 [type=int]
   554   │              │    └── variable: column13:13 [type=int]
   555   │              └── case [as=upsert_rowid:16, type=int, outer=(7,12)]
   556   │                   ├── true [type=bool]
   557   │                   ├── when [type=int]
   558   │                   │    ├── is [type=bool]
   559   │                   │    │    ├── variable: rowid:12 [type=int]
   560   │                   │    │    └── null [type=unknown]
   561   │                   │    └── variable: column7:7 [type=int]
   562   │                   └── variable: rowid:12 [type=int]
   563   └── projections
   564        └── plus [as="?column?":17, type=int, outer=(2,3)]
   565             ├── variable: b:2 [type=int]
   566             └── variable: c:3 [type=int]
   567  
   568  # ensure-upsert-distinct-on should create strict key in case where all grouping
   569  # columns are not NULL.
   570  build
   571  INSERT INTO abc (a)
   572  SELECT y FROM xyz WHERE y IS NOT NULL
   573  ON CONFLICT (a) DO
   574  UPDATE SET b=2
   575  ----
   576  upsert abc
   577   ├── columns: <none>
   578   ├── canary column: 14
   579   ├── fetch columns: a:11(int) b:12(int) c:13(int) rowid:14(int)
   580   ├── insert-mapping:
   581   │    ├── y:6 => a:1
   582   │    ├── column8:8 => b:2
   583   │    ├── column10:10 => c:3
   584   │    └── column9:9 => rowid:4
   585   ├── update-mapping:
   586   │    ├── upsert_b:18 => b:2
   587   │    └── upsert_c:19 => c:3
   588   ├── cardinality: [0 - 0]
   589   ├── volatile, side-effects, mutations
   590   └── project
   591        ├── columns: upsert_a:17(int) upsert_b:18(int!null) upsert_c:19(int!null) upsert_rowid:20(int) y:6(int!null) column8:8(int!null) column9:9(int) column10:10(int!null) a:11(int) b:12(int) c:13(int) rowid:14(int) b_new:15(int!null) column16:16(int!null)
   592        ├── volatile, side-effects
   593        ├── key: (6)
   594        ├── fd: ()-->(8,10,15,16), (6)-->(9,11-14), (14)-->(11-13), (11)-->(12-14), (12,13)~~>(11,14), (6,11,14)-->(17), (14)-->(18), (14)-->(19), (9,14)-->(20)
   595        ├── prune: (6,8-20)
   596        ├── reject-nulls: (11-14)
   597        ├── interesting orderings: (+14) (+11) (+12,+13,+14)
   598        ├── project
   599        │    ├── columns: column16:16(int!null) y:6(int!null) column8:8(int!null) column9:9(int) column10:10(int!null) a:11(int) b:12(int) c:13(int) rowid:14(int) b_new:15(int!null)
   600        │    ├── volatile, side-effects
   601        │    ├── key: (6)
   602        │    ├── fd: ()-->(8,10,15,16), (6)-->(9,11-14), (14)-->(11-13), (11)-->(12-14), (12,13)~~>(11,14)
   603        │    ├── prune: (6,8-16)
   604        │    ├── reject-nulls: (11-14)
   605        │    ├── interesting orderings: (+14) (+11) (+12,+13,+14)
   606        │    ├── project
   607        │    │    ├── columns: b_new:15(int!null) y:6(int!null) column8:8(int!null) column9:9(int) column10:10(int!null) a:11(int) b:12(int) c:13(int) rowid:14(int)
   608        │    │    ├── volatile, side-effects
   609        │    │    ├── key: (6)
   610        │    │    ├── fd: ()-->(8,10,15), (6)-->(9,11-14), (14)-->(11-13), (11)-->(12-14), (12,13)~~>(11,14)
   611        │    │    ├── prune: (6,8-15)
   612        │    │    ├── reject-nulls: (11-14)
   613        │    │    ├── interesting orderings: (+14) (+11) (+12,+13,+14)
   614        │    │    ├── left-join (hash)
   615        │    │    │    ├── columns: y:6(int!null) column8:8(int!null) column9:9(int) column10:10(int!null) a:11(int) b:12(int) c:13(int) rowid:14(int)
   616        │    │    │    ├── volatile, side-effects
   617        │    │    │    ├── key: (6)
   618        │    │    │    ├── fd: ()-->(8,10), (6)-->(9,11-14), (14)-->(11-13), (11)-->(12-14), (12,13)~~>(11,14)
   619        │    │    │    ├── prune: (12-14)
   620        │    │    │    ├── reject-nulls: (11-14)
   621        │    │    │    ├── interesting orderings: (+14) (+11) (+12,+13,+14)
   622        │    │    │    ├── multiplicity: left-rows(exactly-one), right-rows(one-or-zero)
   623        │    │    │    ├── ensure-upsert-distinct-on
   624        │    │    │    │    ├── columns: y:6(int!null) column8:8(int!null) column9:9(int) column10:10(int!null)
   625        │    │    │    │    ├── grouping columns: y:6(int!null)
   626        │    │    │    │    ├── error: "UPSERT or INSERT...ON CONFLICT command cannot affect row a second time"
   627        │    │    │    │    ├── volatile, side-effects
   628        │    │    │    │    ├── key: (6)
   629        │    │    │    │    ├── fd: ()-->(8,10), (6)-->(8-10)
   630        │    │    │    │    ├── project
   631        │    │    │    │    │    ├── columns: column10:10(int!null) y:6(int!null) column8:8(int!null) column9:9(int)
   632        │    │    │    │    │    ├── volatile, side-effects
   633        │    │    │    │    │    ├── fd: ()-->(8,10)
   634        │    │    │    │    │    ├── prune: (6,8-10)
   635        │    │    │    │    │    ├── interesting orderings: (+6)
   636        │    │    │    │    │    ├── project
   637        │    │    │    │    │    │    ├── columns: column8:8(int!null) column9:9(int) y:6(int!null)
   638        │    │    │    │    │    │    ├── volatile, side-effects
   639        │    │    │    │    │    │    ├── fd: ()-->(8)
   640        │    │    │    │    │    │    ├── prune: (6,8,9)
   641        │    │    │    │    │    │    ├── interesting orderings: (+6)
   642        │    │    │    │    │    │    ├── project
   643        │    │    │    │    │    │    │    ├── columns: y:6(int!null)
   644        │    │    │    │    │    │    │    ├── prune: (6)
   645        │    │    │    │    │    │    │    ├── interesting orderings: (+6)
   646        │    │    │    │    │    │    │    └── select
   647        │    │    │    │    │    │    │         ├── columns: x:5(int!null) y:6(int!null) z:7(int)
   648        │    │    │    │    │    │    │         ├── key: (5)
   649        │    │    │    │    │    │    │         ├── fd: (5)-->(6,7), (6,7)~~>(5)
   650        │    │    │    │    │    │    │         ├── prune: (5,7)
   651        │    │    │    │    │    │    │         ├── interesting orderings: (+5) (+6,+7,+5) (+7,+6,+5)
   652        │    │    │    │    │    │    │         ├── scan xyz
   653        │    │    │    │    │    │    │         │    ├── columns: x:5(int!null) y:6(int) z:7(int)
   654        │    │    │    │    │    │    │         │    ├── key: (5)
   655        │    │    │    │    │    │    │         │    ├── fd: (5)-->(6,7), (6,7)~~>(5)
   656        │    │    │    │    │    │    │         │    ├── prune: (5-7)
   657        │    │    │    │    │    │    │         │    └── interesting orderings: (+5) (+6,+7,+5) (+7,+6,+5)
   658        │    │    │    │    │    │    │         └── filters
   659        │    │    │    │    │    │    │              └── is-not [type=bool, outer=(6), constraints=(/6: (/NULL - ]; tight)]
   660        │    │    │    │    │    │    │                   ├── variable: y:6 [type=int]
   661        │    │    │    │    │    │    │                   └── null [type=unknown]
   662        │    │    │    │    │    │    └── projections
   663        │    │    │    │    │    │         ├── const: 10 [as=column8:8, type=int]
   664        │    │    │    │    │    │         └── function: unique_rowid [as=column9:9, type=int, volatile, side-effects]
   665        │    │    │    │    │    └── projections
   666        │    │    │    │    │         └── plus [as=column10:10, type=int, outer=(8)]
   667        │    │    │    │    │              ├── variable: column8:8 [type=int]
   668        │    │    │    │    │              └── const: 1 [type=int]
   669        │    │    │    │    └── aggregations
   670        │    │    │    │         ├── first-agg [as=column8:8, type=int, outer=(8)]
   671        │    │    │    │         │    └── variable: column8:8 [type=int]
   672        │    │    │    │         ├── first-agg [as=column9:9, type=int, outer=(9)]
   673        │    │    │    │         │    └── variable: column9:9 [type=int]
   674        │    │    │    │         └── first-agg [as=column10:10, type=int, outer=(10)]
   675        │    │    │    │              └── variable: column10:10 [type=int]
   676        │    │    │    ├── scan abc
   677        │    │    │    │    ├── columns: a:11(int!null) b:12(int) c:13(int) rowid:14(int!null)
   678        │    │    │    │    ├── computed column expressions
   679        │    │    │    │    │    └── c:13
   680        │    │    │    │    │         └── plus [type=int]
   681        │    │    │    │    │              ├── variable: b:12 [type=int]
   682        │    │    │    │    │              └── const: 1 [type=int]
   683        │    │    │    │    ├── key: (14)
   684        │    │    │    │    ├── fd: (14)-->(11-13), (11)-->(12-14), (12,13)~~>(11,14)
   685        │    │    │    │    ├── prune: (11-14)
   686        │    │    │    │    └── interesting orderings: (+14) (+11) (+12,+13,+14)
   687        │    │    │    └── filters
   688        │    │    │         └── eq [type=bool, outer=(6,11), constraints=(/6: (/NULL - ]; /11: (/NULL - ]), fd=(6)==(11), (11)==(6)]
   689        │    │    │              ├── variable: y:6 [type=int]
   690        │    │    │              └── variable: a:11 [type=int]
   691        │    │    └── projections
   692        │    │         └── const: 2 [as=b_new:15, type=int]
   693        │    └── projections
   694        │         └── plus [as=column16:16, type=int, outer=(15)]
   695        │              ├── variable: b_new:15 [type=int]
   696        │              └── const: 1 [type=int]
   697        └── projections
   698             ├── case [as=upsert_a:17, type=int, outer=(6,11,14)]
   699             │    ├── true [type=bool]
   700             │    ├── when [type=int]
   701             │    │    ├── is [type=bool]
   702             │    │    │    ├── variable: rowid:14 [type=int]
   703             │    │    │    └── null [type=unknown]
   704             │    │    └── variable: y:6 [type=int]
   705             │    └── variable: a:11 [type=int]
   706             ├── case [as=upsert_b:18, type=int, outer=(8,14,15)]
   707             │    ├── true [type=bool]
   708             │    ├── when [type=int]
   709             │    │    ├── is [type=bool]
   710             │    │    │    ├── variable: rowid:14 [type=int]
   711             │    │    │    └── null [type=unknown]
   712             │    │    └── variable: column8:8 [type=int]
   713             │    └── variable: b_new:15 [type=int]
   714             ├── case [as=upsert_c:19, type=int, outer=(10,14,16)]
   715             │    ├── true [type=bool]
   716             │    ├── when [type=int]
   717             │    │    ├── is [type=bool]
   718             │    │    │    ├── variable: rowid:14 [type=int]
   719             │    │    │    └── null [type=unknown]
   720             │    │    └── variable: column10:10 [type=int]
   721             │    └── variable: column16:16 [type=int]
   722             └── case [as=upsert_rowid:20, type=int, outer=(9,14)]
   723                  ├── true [type=bool]
   724                  ├── when [type=int]
   725                  │    ├── is [type=bool]
   726                  │    │    ├── variable: rowid:14 [type=int]
   727                  │    │    └── null [type=unknown]
   728                  │    └── variable: column9:9 [type=int]
   729                  └── variable: rowid:14 [type=int]