mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-18 17:14:20 +01:00
241 lines
9.6 KiB
Tcl
Executable File
241 lines
9.6 KiB
Tcl
Executable File
#!/usr/bin/env tclsh
|
|
|
|
set testdir [file dirname $argv0]
|
|
source $testdir/tester.tcl
|
|
|
|
do_execsql_test_on_specific_db {:memory:} alter-column-rename-and-type {
|
|
CREATE TABLE t (a INTEGER);
|
|
CREATE INDEX i ON t (a);
|
|
ALTER TABLE t ALTER COLUMN a TO b BLOB;
|
|
SELECT sql FROM sqlite_schema;
|
|
} {
|
|
"CREATE TABLE t (b BLOB)"
|
|
"CREATE INDEX i ON t (b)"
|
|
}
|
|
|
|
do_execsql_test_in_memory_any_error fail-alter-column-primary-key {
|
|
CREATE TABLE t (a);
|
|
ALTER TABLE t ALTER COLUMN a TO a PRIMARY KEY;
|
|
}
|
|
|
|
do_execsql_test_in_memory_any_error fail-alter-column-unique {
|
|
CREATE TABLE t (a);
|
|
ALTER TABLE t ALTER COLUMN a TO a UNIQUE;
|
|
}
|
|
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-pk-column {
|
|
CREATE TABLE customers (cust_id INTEGER PRIMARY KEY, cust_name TEXT);
|
|
INSERT INTO customers VALUES (1, 'Alice'), (2, 'Bob');
|
|
|
|
ALTER TABLE customers RENAME COLUMN cust_id TO customer_id;
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 'customers';
|
|
SELECT customer_id, cust_name FROM customers ORDER BY customer_id;
|
|
} {
|
|
"CREATE TABLE customers (customer_id INTEGER PRIMARY KEY, cust_name TEXT)"
|
|
"1|Alice"
|
|
"2|Bob"
|
|
}
|
|
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-composite-pk {
|
|
CREATE TABLE products (category TEXT, prod_code TEXT, name TEXT, PRIMARY KEY (category, prod_code));
|
|
INSERT INTO products VALUES ('Electronics', 'E001', 'Laptop');
|
|
|
|
ALTER TABLE products RENAME COLUMN prod_code TO product_code;
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 'products';
|
|
SELECT category, product_code, name FROM products;
|
|
} {
|
|
"CREATE TABLE products (category TEXT, product_code TEXT, name TEXT, PRIMARY KEY (category, product_code))"
|
|
"Electronics|E001|Laptop"
|
|
}
|
|
|
|
# Foreign key child column rename
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-fk-child {
|
|
CREATE TABLE parent (id INTEGER PRIMARY KEY);
|
|
CREATE TABLE child (cid INTEGER PRIMARY KEY, pid INTEGER, FOREIGN KEY (pid) REFERENCES parent(id));
|
|
INSERT INTO parent VALUES (1);
|
|
INSERT INTO child VALUES (1, 1);
|
|
|
|
ALTER TABLE child RENAME COLUMN pid TO parent_id;
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 'child';
|
|
} {
|
|
"CREATE TABLE child (cid INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY (parent_id) REFERENCES parent (id))"
|
|
}
|
|
|
|
# Foreign key parent column rename - critical test
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-fk-parent {
|
|
CREATE TABLE orders (order_id INTEGER PRIMARY KEY, date TEXT);
|
|
CREATE TABLE items (item_id INTEGER PRIMARY KEY, oid INTEGER, FOREIGN KEY (oid) REFERENCES orders(order_id));
|
|
|
|
ALTER TABLE orders RENAME COLUMN order_id TO ord_id;
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 'orders';
|
|
SELECT sql FROM sqlite_schema WHERE name = 'items';
|
|
} {
|
|
"CREATE TABLE orders (ord_id INTEGER PRIMARY KEY, date TEXT)"
|
|
"CREATE TABLE items (item_id INTEGER PRIMARY KEY, oid INTEGER, FOREIGN KEY (oid) REFERENCES orders (ord_id))"
|
|
}
|
|
|
|
# Composite foreign key parent rename
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-composite-fk-parent {
|
|
CREATE TABLE products (cat TEXT, code TEXT, PRIMARY KEY (cat, code));
|
|
CREATE TABLE inventory (id INTEGER PRIMARY KEY, cat TEXT, code TEXT, FOREIGN KEY (cat, code) REFERENCES products(cat, code));
|
|
|
|
ALTER TABLE products RENAME COLUMN code TO sku;
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 'products';
|
|
SELECT sql FROM sqlite_schema WHERE name = 'inventory';
|
|
} {
|
|
"CREATE TABLE products (cat TEXT, sku TEXT, PRIMARY KEY (cat, sku))"
|
|
"CREATE TABLE inventory (id INTEGER PRIMARY KEY, cat TEXT, code TEXT, FOREIGN KEY (cat, code) REFERENCES products (cat, sku))"
|
|
}
|
|
|
|
# Multiple foreign keys to same parent
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-multiple-fks {
|
|
CREATE TABLE users (uid INTEGER PRIMARY KEY);
|
|
CREATE TABLE messages (mid INTEGER PRIMARY KEY, sender INTEGER, receiver INTEGER,
|
|
FOREIGN KEY (sender) REFERENCES users(uid),
|
|
FOREIGN KEY (receiver) REFERENCES users(uid));
|
|
|
|
ALTER TABLE users RENAME COLUMN uid TO user_id;
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 'messages';
|
|
} {
|
|
"CREATE TABLE messages (mid INTEGER PRIMARY KEY, sender INTEGER, receiver INTEGER, FOREIGN KEY (sender) REFERENCES users (user_id), FOREIGN KEY (receiver) REFERENCES users (user_id))"
|
|
}
|
|
|
|
# Self-referencing foreign key
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-self-ref-fk {
|
|
CREATE TABLE employees (emp_id INTEGER PRIMARY KEY, manager_id INTEGER,
|
|
FOREIGN KEY (manager_id) REFERENCES employees(emp_id));
|
|
|
|
ALTER TABLE employees RENAME COLUMN emp_id TO employee_id;
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 'employees';
|
|
} {
|
|
"CREATE TABLE employees (employee_id INTEGER PRIMARY KEY, manager_id INTEGER, FOREIGN KEY (manager_id) REFERENCES employees (employee_id))"
|
|
}
|
|
|
|
# Chain of FK renames - parent is both PK and referenced
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-fk-chain {
|
|
CREATE TABLE t1 (a INTEGER PRIMARY KEY);
|
|
CREATE TABLE t2 (b INTEGER PRIMARY KEY, a_ref INTEGER, FOREIGN KEY (a_ref) REFERENCES t1(a));
|
|
CREATE TABLE t3 (c INTEGER PRIMARY KEY, b_ref INTEGER, FOREIGN KEY (b_ref) REFERENCES t2(b));
|
|
|
|
ALTER TABLE t1 RENAME COLUMN a TO a_new;
|
|
ALTER TABLE t2 RENAME COLUMN b TO b_new;
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 't2';
|
|
SELECT sql FROM sqlite_schema WHERE name = 't3';
|
|
} {
|
|
"CREATE TABLE t2 (b_new INTEGER PRIMARY KEY, a_ref INTEGER, FOREIGN KEY (a_ref) REFERENCES t1 (a_new))"
|
|
"CREATE TABLE t3 (c INTEGER PRIMARY KEY, b_ref INTEGER, FOREIGN KEY (b_ref) REFERENCES t2 (b_new))"
|
|
}
|
|
|
|
# FK with ON DELETE/UPDATE actions
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-fk-actions {
|
|
CREATE TABLE parent (pid INTEGER PRIMARY KEY);
|
|
CREATE TABLE child (cid INTEGER PRIMARY KEY, pid INTEGER,
|
|
FOREIGN KEY (pid) REFERENCES parent(pid) ON DELETE CASCADE ON UPDATE RESTRICT);
|
|
|
|
ALTER TABLE parent RENAME COLUMN pid TO parent_id;
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 'child';
|
|
} {
|
|
"CREATE TABLE child (cid INTEGER PRIMARY KEY, pid INTEGER, FOREIGN KEY (pid) REFERENCES parent (parent_id) ON DELETE CASCADE ON UPDATE RESTRICT)"
|
|
}
|
|
|
|
# FK with DEFERRABLE
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-fk-deferrable {
|
|
CREATE TABLE parent (id INTEGER PRIMARY KEY);
|
|
CREATE TABLE child (id INTEGER PRIMARY KEY, pid INTEGER,
|
|
FOREIGN KEY (pid) REFERENCES parent(id) DEFERRABLE INITIALLY DEFERRED);
|
|
|
|
ALTER TABLE parent RENAME COLUMN id TO parent_id;
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 'child';
|
|
} {
|
|
"CREATE TABLE child (id INTEGER PRIMARY KEY, pid INTEGER, FOREIGN KEY (pid) REFERENCES parent (parent_id) DEFERRABLE INITIALLY DEFERRED)"
|
|
}
|
|
|
|
# Rename with quoted identifiers in FK
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-fk-quoted {
|
|
CREATE TABLE "parent table" ("parent id" INTEGER PRIMARY KEY);
|
|
CREATE TABLE child (id INTEGER PRIMARY KEY, pid INTEGER,
|
|
FOREIGN KEY (pid) REFERENCES "parent table"("parent id"));
|
|
|
|
ALTER TABLE "parent table" RENAME COLUMN "parent id" TO "new id";
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 'child';
|
|
} {
|
|
"CREATE TABLE child (id INTEGER PRIMARY KEY, pid INTEGER, FOREIGN KEY (pid) REFERENCES \"parent table\" (\"new id\"))"
|
|
}
|
|
|
|
# Verify FK constraint still works after rename
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-fk-constraint-after-rename {
|
|
PRAGMA foreign_keys = ON;
|
|
CREATE TABLE parent (id INTEGER PRIMARY KEY);
|
|
CREATE TABLE child (id INTEGER PRIMARY KEY, pid INTEGER, FOREIGN KEY (pid) REFERENCES parent(id));
|
|
INSERT INTO parent VALUES (1);
|
|
INSERT INTO child VALUES (1, 1);
|
|
|
|
ALTER TABLE parent RENAME COLUMN id TO parent_id;
|
|
|
|
-- This should work
|
|
INSERT INTO child VALUES (2, 1);
|
|
SELECT COUNT(*) FROM child;
|
|
} {
|
|
"2"
|
|
}
|
|
|
|
# FK constraint violation after rename should still fail
|
|
do_execsql_test_in_memory_any_error alter-table-fk-violation-after-rename {
|
|
PRAGMA foreign_keys = ON;
|
|
CREATE TABLE parent (id INTEGER PRIMARY KEY);
|
|
CREATE TABLE child (id INTEGER PRIMARY KEY, pid INTEGER, FOREIGN KEY (pid) REFERENCES parent(id));
|
|
INSERT INTO parent VALUES (1);
|
|
|
|
ALTER TABLE parent RENAME COLUMN id TO parent_id;
|
|
|
|
-- This should fail with FK violation
|
|
INSERT INTO child VALUES (1, 999);
|
|
}
|
|
|
|
# Complex scenario with multiple table constraints
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-complex-constraints {
|
|
CREATE TABLE t (
|
|
a INTEGER,
|
|
b TEXT,
|
|
c REAL,
|
|
PRIMARY KEY (a, b),
|
|
UNIQUE (b, c),
|
|
FOREIGN KEY (a) REFERENCES t(a)
|
|
);
|
|
|
|
ALTER TABLE t RENAME COLUMN a TO x;
|
|
ALTER TABLE t RENAME COLUMN b TO y;
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 't';
|
|
} {
|
|
"CREATE TABLE t (x INTEGER, y TEXT, c REAL, PRIMARY KEY (x, y), UNIQUE (y, c), FOREIGN KEY (x) REFERENCES t (x))"
|
|
}
|
|
|
|
# Rename column that appears in both PK and FK
|
|
do_execsql_test_on_specific_db {:memory:} alter-table-rename-pk-and-fk {
|
|
CREATE TABLE parent (id INTEGER PRIMARY KEY);
|
|
CREATE TABLE child (
|
|
id INTEGER PRIMARY KEY,
|
|
parent_ref INTEGER,
|
|
FOREIGN KEY (id) REFERENCES parent(id),
|
|
FOREIGN KEY (parent_ref) REFERENCES parent(id)
|
|
);
|
|
|
|
ALTER TABLE parent RENAME COLUMN id TO pid;
|
|
|
|
SELECT sql FROM sqlite_schema WHERE name = 'child';
|
|
} {
|
|
"CREATE TABLE child (id INTEGER PRIMARY KEY, parent_ref INTEGER, FOREIGN KEY (id) REFERENCES parent (pid), FOREIGN KEY (parent_ref) REFERENCES parent (pid))"
|
|
}
|