#![cfg(feature = "std")]
use graphitesql::Connection;
fn err(c: &Connection, sql: &str) -> String {
c.query(sql)
.unwrap_err()
.to_string()
.trim_start_matches("error: ")
.trim_start_matches("Error: ")
.to_string()
}
#[test]
fn compound_column_count_mismatch_names_operator() {
let c = Connection::open_memory().unwrap();
for (sql, kw) in [
("SELECT 1 UNION SELECT 1,2", "UNION"),
("SELECT 1 UNION ALL SELECT 1,2", "UNION ALL"),
("SELECT 1 INTERSECT SELECT 1,2", "INTERSECT"),
("SELECT 1 EXCEPT SELECT 1,2", "EXCEPT"),
] {
assert_eq!(
err(&c, sql),
format!("SELECTs to the left and right of {kw} do not have the same number of result columns"),
"{sql}"
);
}
}
#[test]
fn multi_row_values_uneven_keeps_values_message() {
let c = Connection::open_memory().unwrap();
assert_eq!(
err(&c, "VALUES(1),(2,3)"),
"all VALUES must have the same number of terms"
);
assert_eq!(
err(&c, "VALUES(1,2),(3)"),
"all VALUES must have the same number of terms"
);
assert!(c.query("SELECT 1,2 UNION ALL SELECT 3,4").is_ok());
}
#[test]
fn window_function_without_over_is_misuse() {
let c = Connection::open_memory().unwrap();
for (sql, name) in [
("SELECT row_number()", "row_number"),
("SELECT rank()", "rank"),
("SELECT dense_rank()", "dense_rank"),
("SELECT percent_rank()", "percent_rank"),
("SELECT cume_dist()", "cume_dist"),
("SELECT ntile(2)", "ntile"),
("SELECT lag(1)", "lag"),
("SELECT lead(1)", "lead"),
("SELECT first_value(1)", "first_value"),
("SELECT last_value(1)", "last_value"),
("SELECT nth_value(1,2)", "nth_value"),
] {
assert_eq!(
err(&c, sql),
format!("misuse of window function {name}()"),
"{sql}"
);
}
}
#[test]
fn without_rowid_pk_null_names_column() {
let dml_err = |c: &mut Connection, sql: &str| {
c.execute(sql)
.unwrap_err()
.to_string()
.trim_start_matches("error: ")
.trim_start_matches("Error: ")
.to_string()
};
let mut c = Connection::open_memory().unwrap();
c.execute("CREATE TABLE t(a PRIMARY KEY) WITHOUT ROWID")
.unwrap();
assert_eq!(
dml_err(&mut c, "INSERT INTO t VALUES(NULL)"),
"NOT NULL constraint failed: t.a"
);
let mut c2 = Connection::open_memory().unwrap();
c2.execute("CREATE TABLE t(a, b, PRIMARY KEY(a, b)) WITHOUT ROWID")
.unwrap();
assert_eq!(
dml_err(&mut c2, "INSERT INTO t VALUES(1, NULL)"),
"NOT NULL constraint failed: t.b"
);
}
#[test]
fn create_index_and_trigger_schema_qualify_missing_table() {
let mut c = Connection::open_memory().unwrap();
let ddl_err = |c: &mut Connection, sql: &str| {
c.execute(sql)
.unwrap_err()
.to_string()
.trim_start_matches("error: ")
.trim_start_matches("Error: ")
.to_string()
};
assert_eq!(
ddl_err(&mut c, "CREATE INDEX i ON nope(a)"),
"no such table: main.nope"
);
assert_eq!(
ddl_err(
&mut c,
"CREATE TRIGGER tr AFTER INSERT ON nope BEGIN SELECT 1; END"
),
"no such table: main.nope"
);
assert_eq!(ddl_err(&mut c, "DROP TABLE nope"), "no such table: nope");
}