# LogicTest: local-opt

subtest DeleteCascade_Basic
### Basic Delete Cascade
#     a
#    / \
#   b1 b2
#  / \   \
# c1  c2  c3

statement ok
CREATE TABLE a (
  id STRING PRIMARY KEY
);

statement ok
CREATE TABLE b1 (
  id STRING PRIMARY KEY
 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE
);

statement ok
CREATE TABLE b2 (
  id STRING PRIMARY KEY
 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE
);

statement ok
CREATE TABLE c1 (
  id STRING PRIMARY KEY
 ,delete_cascade STRING NOT NULL REFERENCES b1 ON DELETE CASCADE
);

statement ok
CREATE TABLE c2 (
  id STRING PRIMARY KEY
 ,delete_cascade STRING NOT NULL REFERENCES b1 ON DELETE CASCADE
);

statement ok
CREATE TABLE c3 (
  id STRING PRIMARY KEY REFERENCES b2 ON DELETE CASCADE
);

statement ok
INSERT INTO a VALUES ('a-pk1');
INSERT INTO b1 VALUES ('b1-pk1', 'a-pk1'), ('b1-pk2', 'a-pk1');
INSERT INTO b2 VALUES ('b2-pk1', 'a-pk1'), ('b2-pk2', 'a-pk1');
INSERT INTO c1 VALUES
  ('c1-pk1-b1-pk1', 'b1-pk1')
 ,('c1-pk2-b1-pk1', 'b1-pk1')
 ,('c1-pk3-b1-pk2', 'b1-pk2')
 ,('c1-pk4-b1-pk2', 'b1-pk2')
;
INSERT INTO c2 VALUES
  ('c2-pk1-b1-pk1', 'b1-pk1')
 ,('c2-pk2-b1-pk1', 'b1-pk1')
 ,('c2-pk3-b1-pk2', 'b1-pk2')
 ,('c2-pk4-b1-pk2', 'b1-pk2')
;
INSERT INTO c3 VALUES ('b2-pk1'), ('b2-pk2');

statement ok
SET tracing = on,kv,results; DELETE FROM a WHERE id = 'a-pk1'; SET tracing = off

query I
SELECT count(*) FROM [SHOW KV TRACE FOR SESSION] WHERE message LIKE 'cascading %';
----
5

# Clean up after the test.
statement ok
DROP TABLE c3, c2, c1, b2, b1, a;

subtest UpdateCascade_Basic
### Basic Update Cascade
#     a
#    / \
#   b1 b2
#  / \   \
# c1  c2  c3

statement ok
CREATE TABLE a (
  id STRING PRIMARY KEY
);

statement ok
CREATE TABLE b1 (
  id STRING PRIMARY KEY
 ,update_cascade STRING NOT NULL UNIQUE REFERENCES a ON UPDATE CASCADE
);

statement ok
CREATE TABLE b2 (
  id STRING PRIMARY KEY
 ,update_cascade STRING NOT NULL UNIQUE REFERENCES a ON UPDATE CASCADE
);

statement ok
CREATE TABLE c1 (
  id STRING PRIMARY KEY
 ,update_cascade STRING NOT NULL REFERENCES b1 (update_cascade) ON UPDATE CASCADE
);

statement ok
CREATE TABLE c2 (
  id STRING PRIMARY KEY
 ,update_cascade STRING NOT NULL REFERENCES b1 (update_cascade) ON UPDATE CASCADE
);

statement ok
CREATE TABLE c3 (
  id STRING PRIMARY KEY REFERENCES b2(update_cascade) ON UPDATE CASCADE
);

statement ok
INSERT INTO a VALUES ('original');
INSERT INTO b1 VALUES ('b1-pk1', 'original');
INSERT INTO b2 VALUES ('b2-pk1', 'original');
INSERT INTO c1 VALUES
  ('c1-pk1', 'original')
 ,('c1-pk2', 'original')
 ,('c1-pk3', 'original')
 ,('c1-pk4', 'original')
;
INSERT INTO c2 VALUES
  ('c2-pk1', 'original')
 ,('c2-pk2', 'original')
 ,('c2-pk3', 'original')
 ,('c2-pk4', 'original')
;
INSERT INTO c3 VALUES ('original');

# ON UPDATE CASCADE
statement ok
UPDATE a SET id = 'updated' WHERE id = 'original';

statement ok
SET tracing = on,kv,results; UPDATE a SET id = 'updated2' WHERE id = 'updated'; SET tracing = off

query I
SELECT count(*) FROM [SHOW KV TRACE FOR SESSION] WHERE message LIKE 'cascading %';
----
5

# Clean up after the test.
statement ok
DROP TABLE c3, c2, c1, b2, b1, a;

subtest DeleteSetNull_Basic1
### Basic Delete Set Null
#        a
#      // \\
#    / |  |  \
#   b1 b2 b3 b4

statement ok
CREATE TABLE a (
  id STRING PRIMARY KEY
);
CREATE TABLE b1 (
  id STRING PRIMARY KEY
 ,delete_set_null STRING REFERENCES a ON DELETE SET NULL
);
CREATE TABLE b2 (
  id STRING PRIMARY KEY
 ,delete_set_null STRING REFERENCES a ON DELETE SET NULL
);
CREATE TABLE b3 (
  id STRING PRIMARY KEY
 ,delete_set_null STRING REFERENCES a ON DELETE SET NULL
);
CREATE TABLE b4 (
  id STRING PRIMARY KEY
 ,delete_set_null STRING REFERENCES a ON DELETE SET NULL
);

statement ok
INSERT INTO a VALUES ('delete_me'), ('untouched');
INSERT INTO b1 VALUES ('b1-pk1', 'untouched'), ('b1-pk2', 'untouched');
INSERT INTO b2 VALUES ('b2-pk1', 'untouched'), ('b2-pk2', 'delete_me');
INSERT INTO b3 VALUES ('b3-pk1', 'delete_me'), ('b3-pk2', 'untouched');
INSERT INTO b4 VALUES ('b4-pk1', 'delete_me'), ('b4-pk2', 'delete_me');

# Ensure that show trace adds a cascade message for each of the tables that is
# cascaded into.
statement ok
SET tracing = on,kv,results; DELETE FROM a WHERE id = 'delete_me'; SET tracing = off

query I
SELECT count(*) FROM [SHOW KV TRACE FOR SESSION] WHERE message LIKE 'cascading %';
----
4

# Clean up after the test.
statement ok
DROP TABLE b4, b3, b2, b1, a;

subtest DeleteSetNull_Basic2
### Basic Delete Set Null
#     a
#    / \
#   b1 b2
#  / \   \
# c1  c2  c3

statement ok
CREATE TABLE a (
  id STRING PRIMARY KEY
);
CREATE TABLE b1 (
  id STRING PRIMARY KEY
 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE
);
CREATE TABLE b2 (
  id STRING PRIMARY KEY
 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE
);
CREATE TABLE c1 (
  id STRING PRIMARY KEY
 ,delete_set_null STRING REFERENCES b1 ON DELETE SET NULL
);
CREATE TABLE c2 (
  id STRING PRIMARY KEY
 ,delete_set_null STRING REFERENCES b1 ON DELETE SET NULL
);
CREATE TABLE c3 (
  id STRING PRIMARY KEY
 ,delete_set_null STRING REFERENCES b2 ON DELETE SET NULL
);

statement ok
INSERT INTO a VALUES ('a-pk1');
INSERT INTO b1 VALUES ('b1-pk1', 'a-pk1'), ('b1-pk2', 'a-pk1');
INSERT INTO b2 VALUES ('b2-pk1', 'a-pk1'), ('b2-pk2', 'a-pk1');
INSERT INTO c1 VALUES
  ('c1-pk1-b1-pk1', 'b1-pk1')
 ,('c1-pk2-b1-pk1', 'b1-pk1')
 ,('c1-pk3-b1-pk2', 'b1-pk2')
 ,('c1-pk4-b1-pk2', 'b1-pk2')
;
INSERT INTO c2 VALUES
  ('c2-pk1-b1-pk1', 'b1-pk1')
 ,('c2-pk2-b1-pk1', 'b1-pk1')
 ,('c2-pk3-b1-pk2', 'b1-pk2')
 ,('c2-pk4-b1-pk2', 'b1-pk2')
;
INSERT INTO c3 VALUES
  ('c3-pk1-b2-pk1', 'b2-pk1')
 ,('c3-pk2-b2-pk1', 'b2-pk1')
 ,('c3-pk3-b2-pk2', 'b2-pk2')
 ,('c3-pk4-b2-pk2', 'b2-pk2')
;

statement ok
SET tracing = on,kv,results; DELETE FROM a WHERE id = 'a-pk1'; SET tracing = off

query I
SELECT count(*) FROM [SHOW KV TRACE FOR SESSION] WHERE message LIKE 'cascading %';
----
5

# Clean up after the test.
statement ok
DROP TABLE c3, c2, c1, b2, b1, a;

subtest UpdateSetNull_Basic1
### Basic Update Set Null
#        a
#      // \\
#    / |  |  \
#   b1 b2 b3 b4

statement ok
CREATE TABLE a (
  id STRING PRIMARY KEY
);
CREATE TABLE b1 (
  id STRING PRIMARY KEY
 ,update_set_null STRING REFERENCES a ON UPDATE SET NULL
);
CREATE TABLE b2 (
  id STRING PRIMARY KEY
 ,update_set_null STRING REFERENCES a ON UPDATE SET NULL
);
CREATE TABLE b3 (
  id STRING PRIMARY KEY
 ,update_set_null STRING REFERENCES a ON UPDATE SET NULL
);
CREATE TABLE b4 (
  id STRING PRIMARY KEY
 ,update_set_null STRING REFERENCES a ON UPDATE SET NULL
);

statement ok
INSERT INTO a VALUES ('original'), ('untouched');
INSERT INTO b1 VALUES ('b1-pk1', 'untouched'), ('b1-pk2', 'untouched');
INSERT INTO b2 VALUES ('b2-pk1', 'untouched'), ('b2-pk2', 'original');
INSERT INTO b3 VALUES ('b3-pk1', 'original'), ('b3-pk2', 'untouched');
INSERT INTO b3 VALUES ('b4-pk1', 'original'), ('b4-pk2', 'original');

# Ensure that show trace adds a cascade message for each of the tables that is
# cascaded into.
statement ok
SET tracing = on,kv,results; UPDATE a SET id = 'updated' WHERE id = 'original'; SET tracing = off

query I
SELECT count(*) FROM [SHOW KV TRACE FOR SESSION] WHERE message LIKE 'cascading %';
----
4

# Clean up after the test.
statement ok
DROP TABLE b4, b3, b2, b1, a;

subtest UpdateSetNull_Basic2
### Basic Update Set Null
#     a
#    / \
#   b1 b2
#  / \   \
# c1  c2  c3

statement ok
CREATE TABLE a (
  id STRING PRIMARY KEY
);
CREATE TABLE b1 (
  id STRING PRIMARY KEY
 ,update_cascade STRING UNIQUE NOT NULL REFERENCES a ON UPDATE CASCADE
);
CREATE TABLE b2 (
  id STRING PRIMARY KEY
 ,update_cascade STRING UNIQUE NOT NULL REFERENCES a ON UPDATE CASCADE
);
CREATE TABLE c1 (
  id STRING PRIMARY KEY
 ,update_set_null STRING REFERENCES b1(update_cascade) ON UPDATE SET NULL
);
CREATE TABLE c2 (
  id STRING PRIMARY KEY
 ,update_set_null STRING REFERENCES b1(update_cascade) ON UPDATE SET NULL
);
CREATE TABLE c3 (
  id STRING PRIMARY KEY
 ,update_set_null STRING REFERENCES b2(update_cascade) ON UPDATE SET NULL
);

statement ok
INSERT INTO a VALUES ('original'), ('untouched');
INSERT INTO b1 VALUES ('b1-pk1', 'original'), ('b1-pk2', 'untouched');
INSERT INTO b2 VALUES ('b2-pk1', 'original'), ('b2-pk2', 'untouched');
INSERT INTO c1 VALUES
  ('c1-pk1-b1-pk1', 'original')
 ,('c1-pk2-b1-pk1', 'original')
 ,('c1-pk3-b1-pk2', 'untouched')
 ,('c1-pk4-b1-pk2', 'untouched')
;
INSERT INTO c2 VALUES
  ('c2-pk1-b1-pk1', 'original')
 ,('c2-pk2-b1-pk1', 'original')
 ,('c2-pk3-b1-pk2', 'untouched')
 ,('c2-pk4-b1-pk2', 'untouched')
;
INSERT INTO c3 VALUES
  ('c3-pk1-b2-pk1', 'original')
 ,('c3-pk2-b2-pk1', 'original')
 ,('c3-pk3-b2-pk2', 'untouched')
 ,('c3-pk4-b2-pk2', 'untouched')
;

# Ensure that show trace adds a cascade message for each of the tables that is
# cascaded into.
statement ok
SET tracing = on,kv,results; UPDATE a SET id = 'updated' WHERE id = 'original'; SET tracing = off

query I
SELECT count(*) FROM [SHOW KV TRACE FOR SESSION] WHERE message LIKE 'cascading %';
----
5

# Clean up after the test.
statement ok
DROP TABLE c3, c2, c1, b2, b1, a;

##############

subtest DeleteSetDefault_Basic1
### Basic Delete Set Default
#        a
#      // \\
#    / |  |  \
#   b1 b2 b3 b4

statement ok
CREATE TABLE a (
  id STRING PRIMARY KEY
);
CREATE TABLE b1 (
  id STRING PRIMARY KEY
 ,delete_set_default STRING DEFAULT 'b1-default' REFERENCES a ON DELETE SET DEFAULT
);
CREATE TABLE b2 (
  id STRING PRIMARY KEY
 ,delete_set_default STRING DEFAULT 'b2-default' REFERENCES a ON DELETE SET DEFAULT
);
CREATE TABLE b3 (
  id STRING PRIMARY KEY
 ,delete_set_default STRING DEFAULT 'b3-default' REFERENCES a ON DELETE SET DEFAULT
);
CREATE TABLE b4 (
  id STRING PRIMARY KEY
 ,delete_set_default STRING DEFAULT 'b4-default' REFERENCES a ON DELETE SET DEFAULT
);

statement ok
INSERT INTO a VALUES ('delete_me'), ('untouched'), ('b2-default'), ('b3-default'), ('b4-default');
INSERT INTO b1 VALUES ('b1-pk1', 'untouched'), ('b1-pk2', 'untouched');
INSERT INTO b2 VALUES ('b2-pk1', 'untouched'), ('b2-pk2', 'delete_me');
INSERT INTO b3 VALUES ('b3-pk1', 'delete_me'), ('b3-pk2', 'untouched');
INSERT INTO b4 VALUES ('b4-pk1', 'delete_me'), ('b4-pk2', 'delete_me');

# Ensure that show trace adds a cascade message for each of the tables that is
# cascaded into.
statement ok
SET tracing = on,kv,results; DELETE FROM a WHERE id = 'delete_me'; SET tracing = off

query I
SELECT count(*) FROM [SHOW KV TRACE FOR SESSION] WHERE message LIKE 'cascading %';
----
4

# Clean up after the test.
statement ok
DROP TABLE b4, b3, b2, b1, a;

subtest DeleteSetDefault_Basic2
### Basic Delete Set Null via an ON DELETE CASCADE
#     a
#    / \
#   b1 b2
#  / \   \
# c1  c2  c3

statement ok
CREATE TABLE a (
  id STRING PRIMARY KEY
);
CREATE TABLE b1 (
  id STRING PRIMARY KEY
 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE
);
CREATE TABLE b2 (
  id STRING PRIMARY KEY
 ,delete_cascade STRING NOT NULL REFERENCES a ON DELETE CASCADE
);
CREATE TABLE c1 (
  id STRING PRIMARY KEY
 ,delete_set_default STRING DEFAULT 'b1-default' REFERENCES b1 ON DELETE SET DEFAULT
);
CREATE TABLE c2 (
  id STRING PRIMARY KEY
 ,delete_set_default STRING DEFAULT 'b1-default' REFERENCES b1 ON DELETE SET DEFAULT
);
CREATE TABLE c3 (
  id STRING PRIMARY KEY
 ,delete_set_default STRING DEFAULT 'b2-default' REFERENCES b2 ON DELETE SET DEFAULT
);

statement ok
INSERT INTO a VALUES ('a-pk1'), ('a-default');
INSERT INTO b1 VALUES ('b1-pk1', 'a-pk1'), ('b1-pk2', 'a-pk1'), ('b1-default', 'a-default');
INSERT INTO b2 VALUES ('b2-pk1', 'a-pk1'), ('b2-pk2', 'a-pk1'), ('b2-default', 'a-default');
INSERT INTO c1 VALUES
  ('c1-pk1-b1-pk1', 'b1-pk1')
 ,('c1-pk2-b1-pk1', 'b1-pk1')
 ,('c1-pk3-b1-pk2', 'b1-pk2')
 ,('c1-pk4-b1-pk2', 'b1-pk2')
;
INSERT INTO c2 VALUES
  ('c2-pk1-b1-pk1', 'b1-pk1')
 ,('c2-pk2-b1-pk1', 'b1-pk1')
 ,('c2-pk3-b1-pk2', 'b1-pk2')
 ,('c2-pk4-b1-pk2', 'b1-pk2')
;
INSERT INTO c3 VALUES
  ('c3-pk1-b2-pk1', 'b2-pk1')
 ,('c3-pk2-b2-pk1', 'b2-pk1')
 ,('c3-pk3-b2-pk2', 'b2-pk2')
 ,('c3-pk4-b2-pk2', 'b2-pk2')
;

statement ok
SET tracing = on,kv,results; DELETE FROM a WHERE id = 'a-pk1'; SET tracing = off

query I
SELECT count(*) FROM [SHOW KV TRACE FOR SESSION] WHERE message LIKE 'cascading %';
----
5

# Clean up after the test.
statement ok
DROP TABLE c3, c2, c1, b2, b1, a;

subtest UpdateSetDefault_Basic1
### Basic Update Set Default
#        a
#      // \\
#    / |  |  \
#   b1 b2 b3 b4

statement ok
CREATE TABLE a (
  id STRING PRIMARY KEY
);
CREATE TABLE b1 (
  id STRING PRIMARY KEY
 ,update_set_null STRING DEFAULT 'b1-default' REFERENCES a ON UPDATE SET DEFAULT
);
CREATE TABLE b2 (
  id STRING PRIMARY KEY
 ,update_set_null STRING DEFAULT 'b2-default' REFERENCES a ON UPDATE SET DEFAULT
);
CREATE TABLE b3 (
  id STRING PRIMARY KEY
 ,update_set_null STRING DEFAULT 'b3-default' REFERENCES a ON UPDATE SET DEFAULT
);
CREATE TABLE b4 (
  id STRING PRIMARY KEY
 ,update_set_null STRING DEFAULT 'b4-default' REFERENCES a ON UPDATE SET DEFAULT
);

statement ok
INSERT INTO a VALUES ('original'), ('untouched'), ('b1-default'), ('b2-default'), ('b3-default'), ('b4-default');
INSERT INTO b1 VALUES ('b1-pk1', 'untouched'), ('b1-pk2', 'untouched');
INSERT INTO b2 VALUES ('b2-pk1', 'untouched'), ('b2-pk2', 'original');
INSERT INTO b3 VALUES ('b3-pk1', 'original'), ('b3-pk2', 'untouched');
INSERT INTO b3 VALUES ('b4-pk1', 'original'), ('b4-pk2', 'original');

# Ensure that show trace adds a cascade message for each of the tables that is
# cascaded into.
statement ok
SET tracing = on,kv,results; UPDATE a SET id = 'updated' WHERE id = 'original'; SET tracing = off

query I
SELECT count(*) FROM [SHOW KV TRACE FOR SESSION] WHERE message LIKE 'cascading %';
----
4

# Clean up after the test.
statement ok
DROP TABLE b4, b3, b2, b1, a;

subtest UpdateSetDefault_Basic2
### Basic UPDATE SET DEFAULT via an UPDATE CASCADE
#     a
#    / \
#   b1 b2
#  / \   \
# c1  c2  c3

statement ok
CREATE TABLE a (
  id STRING PRIMARY KEY
);
CREATE TABLE b1 (
  id STRING PRIMARY KEY
 ,update_cascade STRING UNIQUE NOT NULL REFERENCES a ON UPDATE CASCADE
);
CREATE TABLE b2 (
  id STRING PRIMARY KEY
 ,update_cascade STRING UNIQUE NOT NULL REFERENCES a ON UPDATE CASCADE
);
CREATE TABLE c1 (
  id STRING PRIMARY KEY
 ,update_set_null STRING DEFAULT 'b1-default' REFERENCES b1(update_cascade) ON UPDATE SET DEFAULT
);
CREATE TABLE c2 (
  id STRING PRIMARY KEY
 ,update_set_null STRING DEFAULT 'b1-default' REFERENCES b1(update_cascade) ON UPDATE SET DEFAULT
);
CREATE TABLE c3 (
  id STRING PRIMARY KEY
 ,update_set_null STRING DEFAULT 'b2-default' REFERENCES b2(update_cascade) ON UPDATE SET DEFAULT
);

statement ok
INSERT INTO a VALUES ('original'), ('untouched'), ('b1-default'), ('b2-default');
INSERT INTO b1 VALUES ('b1-pk1', 'original'), ('b1-pk2', 'untouched'), ('b1-default', 'b1-default');
INSERT INTO b2 VALUES ('b2-pk1', 'original'), ('b2-pk2', 'untouched'), ('b2-default', 'b2-default');
INSERT INTO c1 VALUES
  ('c1-pk1-b1-pk1', 'original')
 ,('c1-pk2-b1-pk1', 'original')
 ,('c1-pk3-b1-pk2', 'untouched')
 ,('c1-pk4-b1-pk2', 'untouched')
;
INSERT INTO c2 VALUES
  ('c2-pk1-b1-pk1', 'original')
 ,('c2-pk2-b1-pk1', 'original')
 ,('c2-pk3-b1-pk2', 'untouched')
 ,('c2-pk4-b1-pk2', 'untouched')
;
INSERT INTO c3 VALUES
  ('c3-pk1-b2-pk1', 'original')
 ,('c3-pk2-b2-pk1', 'original')
 ,('c3-pk3-b2-pk2', 'untouched')
 ,('c3-pk4-b2-pk2', 'untouched')
;

# Ensure that show trace adds a cascade message for each of the tables that is
# cascaded into.
statement ok
SET tracing = on,kv,results; UPDATE a SET id = 'updated' WHERE id = 'original'; SET tracing = off

query I
SELECT count(*) FROM [SHOW KV TRACE FOR SESSION] WHERE message LIKE 'cascading %';
----
5

# Clean up after the test.
statement ok
DROP TABLE c3, c2, c1, b2, b1, a;
