use spg_engine::Engine;
fn setup_parent(e: &mut Engine) {
e.execute("CREATE TABLE parent (id INT NOT NULL PRIMARY KEY)")
.unwrap();
e.execute("INSERT INTO parent VALUES (1), (2), (3)")
.unwrap();
}
#[test]
fn fk_deferrable_initially_deferred_parses() {
let mut e = Engine::new();
setup_parent(&mut e);
e.execute(
"CREATE TABLE child (\
id INT NOT NULL, \
parent_id INT NOT NULL, \
CONSTRAINT child_parent_fkey FOREIGN KEY (parent_id) \
REFERENCES parent (id) DEFERRABLE INITIALLY DEFERRED\
)",
)
.unwrap();
e.execute("INSERT INTO child VALUES (1, 1)").unwrap();
}
#[test]
fn fk_deferrable_initially_immediate_parses() {
let mut e = Engine::new();
setup_parent(&mut e);
e.execute(
"CREATE TABLE child (\
id INT NOT NULL, \
parent_id INT NOT NULL, \
FOREIGN KEY (parent_id) REFERENCES parent (id) \
DEFERRABLE INITIALLY IMMEDIATE\
)",
)
.unwrap();
}
#[test]
fn fk_bare_deferrable_no_initially_parses() {
let mut e = Engine::new();
setup_parent(&mut e);
e.execute(
"CREATE TABLE child (\
id INT NOT NULL, \
parent_id INT NOT NULL, \
FOREIGN KEY (parent_id) REFERENCES parent (id) DEFERRABLE\
)",
)
.unwrap();
}
#[test]
fn fk_not_deferrable_still_parses() {
let mut e = Engine::new();
setup_parent(&mut e);
e.execute(
"CREATE TABLE child (\
id INT NOT NULL, \
parent_id INT NOT NULL, \
FOREIGN KEY (parent_id) REFERENCES parent (id) NOT DEFERRABLE\
)",
)
.unwrap();
}
#[test]
fn fk_not_deferrable_initially_immediate_n5_shape() {
let mut e = Engine::new();
setup_parent(&mut e);
e.execute(
"CREATE TABLE child (\
id INT NOT NULL, \
parent_id INT NOT NULL, \
FOREIGN KEY (parent_id) REFERENCES parent (id) \
NOT DEFERRABLE INITIALLY IMMEDIATE\
)",
)
.unwrap();
}
#[test]
fn fk_initially_deferred_alone_parses() {
let mut e = Engine::new();
setup_parent(&mut e);
e.execute(
"CREATE TABLE child (\
id INT NOT NULL, \
parent_id INT NOT NULL, \
FOREIGN KEY (parent_id) REFERENCES parent (id) INITIALLY DEFERRED\
)",
)
.unwrap();
}
#[test]
fn fk_deferrable_runs_constraint_immediately() {
let mut e = Engine::new();
setup_parent(&mut e);
e.execute(
"CREATE TABLE child (\
id INT NOT NULL, \
parent_id INT NOT NULL, \
FOREIGN KEY (parent_id) REFERENCES parent (id) \
DEFERRABLE INITIALLY DEFERRED\
)",
)
.unwrap();
let r = e.execute("INSERT INTO child VALUES (1, 999)");
assert!(
r.is_err(),
"FK violation should error immediately even with DEFERRABLE"
);
}
#[test]
fn fk_deferrable_on_delete_combo() {
let mut e = Engine::new();
setup_parent(&mut e);
e.execute(
"CREATE TABLE child (\
id INT NOT NULL, \
parent_id INT NOT NULL, \
FOREIGN KEY (parent_id) REFERENCES parent (id) \
ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED\
)",
)
.unwrap();
}
#[test]
fn inline_column_fk_with_deferrable() {
let mut e = Engine::new();
setup_parent(&mut e);
e.execute(
"CREATE TABLE child (\
id INT NOT NULL, \
parent_id INT NOT NULL REFERENCES parent (id) \
DEFERRABLE INITIALLY DEFERRED\
)",
)
.unwrap();
}