mod common;
use vibesql_executor::InsertExecutor;
#[test]
fn test_character_varying_column_with_length() {
let mut db = vibesql_storage::Database::new();
let schema = vibesql_catalog::TableSchema::new(
"test_cv".to_string(),
vec![
vibesql_catalog::ColumnSchema::new(
"id".to_string(),
vibesql_types::DataType::Integer,
false,
),
vibesql_catalog::ColumnSchema::new(
"description".to_string(),
vibesql_types::DataType::Varchar { max_length: Some(100) },
false,
),
],
);
db.create_table(schema).unwrap();
let stmt = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "test_cv".to_string(),
columns: vec![],
source: vibesql_ast::InsertSource::Values(vec![vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(1)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("Test description"),
)),
]]),
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
let rows = InsertExecutor::execute(&mut db, &stmt).unwrap();
assert_eq!(rows, 1);
let table = db.get_table("test_cv").unwrap();
assert_eq!(table.row_count(), 1);
}
#[test]
fn test_character_varying_column_without_length() {
let mut db = vibesql_storage::Database::new();
let schema = vibesql_catalog::TableSchema::new(
"test_cv_nolen".to_string(),
vec![
vibesql_catalog::ColumnSchema::new(
"id".to_string(),
vibesql_types::DataType::Integer,
false,
),
vibesql_catalog::ColumnSchema::new(
"text".to_string(),
vibesql_types::DataType::Varchar { max_length: None },
false,
),
],
);
db.create_table(schema).unwrap();
let stmt = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "test_cv_nolen".to_string(),
columns: vec![],
source: vibesql_ast::InsertSource::Values(vec![vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(1)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("Unlimited length text"),
)),
]]),
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
let rows = InsertExecutor::execute(&mut db, &stmt).unwrap();
assert_eq!(rows, 1);
let table = db.get_table("test_cv_nolen").unwrap();
assert_eq!(table.row_count(), 1);
}
#[test]
fn test_insert_with_default_value() {
let mut db = vibesql_storage::Database::new();
let mut id_column = vibesql_catalog::ColumnSchema::new(
"id".to_string(),
vibesql_types::DataType::Integer,
false,
);
id_column.default_value =
Some(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(999)));
let schema = vibesql_catalog::TableSchema::new(
"users".to_string(),
vec![
id_column,
vibesql_catalog::ColumnSchema::new(
"name".to_string(),
vibesql_types::DataType::Varchar { max_length: Some(50) },
false,
),
],
);
db.create_table(schema).unwrap();
let stmt = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "users".to_string(),
columns: vec!["id".to_string(), "name".to_string()],
source: vibesql_ast::InsertSource::Values(vec![vec![
vibesql_ast::Expression::Default,
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("Alice"),
)),
]]),
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
let rows = InsertExecutor::execute(&mut db, &stmt).unwrap();
assert_eq!(rows, 1);
let table = db.get_table("users").unwrap();
let row = &table.scan()[0];
assert_eq!(row.get(0), Some(&vibesql_types::SqlValue::Integer(999)));
assert_eq!(row.get(1), Some(&vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("Alice"))));
}
#[test]
fn test_insert_default_no_default_value_defined() {
let mut db = vibesql_storage::Database::new();
let schema = vibesql_catalog::TableSchema::new(
"users".to_string(),
vec![
vibesql_catalog::ColumnSchema::new(
"id".to_string(),
vibesql_types::DataType::Integer,
true,
),
vibesql_catalog::ColumnSchema::new(
"name".to_string(),
vibesql_types::DataType::Varchar { max_length: Some(50) },
false,
),
],
);
db.create_table(schema).unwrap();
let stmt = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "users".to_string(),
columns: vec!["id".to_string(), "name".to_string()],
source: vibesql_ast::InsertSource::Values(vec![vec![
vibesql_ast::Expression::Default,
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("Alice"),
)),
]]),
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
let rows = InsertExecutor::execute(&mut db, &stmt).unwrap();
assert_eq!(rows, 1);
let table = db.get_table("users").unwrap();
let row = &table.scan()[0];
assert_eq!(row.get(0), Some(&vibesql_types::SqlValue::Null));
assert_eq!(row.get(1), Some(&vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("Alice"))));
}
#[test]
fn test_insert_default_values_syntax() {
let mut db = vibesql_storage::Database::new();
let mut id_column = vibesql_catalog::ColumnSchema::new(
"id".to_string(),
vibesql_types::DataType::Integer,
true,
);
id_column.default_value =
Some(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(42)));
let mut name_column = vibesql_catalog::ColumnSchema::new(
"name".to_string(),
vibesql_types::DataType::Varchar { max_length: None },
true,
);
name_column.default_value = Some(vibesql_ast::Expression::Literal(
vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("default_name")),
));
let value_column = vibesql_catalog::ColumnSchema::new(
"value".to_string(),
vibesql_types::DataType::Real,
true, );
let schema = vibesql_catalog::TableSchema::new(
"test_defaults".to_string(),
vec![id_column, name_column, value_column],
);
db.create_table(schema).unwrap();
let stmt = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "test_defaults".to_string(),
columns: vec![], source: vibesql_ast::InsertSource::DefaultValues,
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
let rows = InsertExecutor::execute(&mut db, &stmt).unwrap();
assert_eq!(rows, 1);
let table = db.get_table("test_defaults").unwrap();
let row = &table.scan()[0];
assert_eq!(row.get(0), Some(&vibesql_types::SqlValue::Integer(42)));
assert_eq!(
row.get(1),
Some(&vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("default_name")))
);
assert_eq!(row.get(2), Some(&vibesql_types::SqlValue::Null));
}
#[test]
fn test_insert_default_values_with_integer_primary_key() {
let mut db = vibesql_storage::Database::new();
let mut name_column = vibesql_catalog::ColumnSchema::new(
"name".to_string(),
vibesql_types::DataType::Varchar { max_length: None },
true,
);
name_column.default_value = Some(vibesql_ast::Expression::Literal(
vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("test")),
));
let schema = vibesql_catalog::TableSchema::with_primary_key(
"autoincrement_test".to_string(),
vec![
vibesql_catalog::ColumnSchema::new(
"id".to_string(),
vibesql_types::DataType::Integer,
false,
),
name_column,
],
vec!["id".to_string()],
);
db.create_table(schema).unwrap();
for _ in 0..3 {
let stmt = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "autoincrement_test".to_string(),
columns: vec![],
source: vibesql_ast::InsertSource::DefaultValues,
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
InsertExecutor::execute(&mut db, &stmt).unwrap();
}
let table = db.get_table("autoincrement_test").unwrap();
assert_eq!(table.row_count(), 3);
let rows = table.scan();
assert_eq!(rows[0].get(0), Some(&vibesql_types::SqlValue::Integer(1)));
assert_eq!(rows[1].get(0), Some(&vibesql_types::SqlValue::Integer(2)));
assert_eq!(rows[2].get(0), Some(&vibesql_types::SqlValue::Integer(3)));
}
#[test]
fn test_integer_primary_key_null_autogen_empty_table() {
let mut db = vibesql_storage::Database::new();
let schema = vibesql_catalog::TableSchema::with_primary_key(
"track".to_string(),
vec![
vibesql_catalog::ColumnSchema::new(
"tid".to_string(),
vibesql_types::DataType::Integer,
false, ),
vibesql_catalog::ColumnSchema::new(
"name".to_string(),
vibesql_types::DataType::Varchar { max_length: None },
true,
),
],
vec!["tid".to_string()],
);
db.create_table(schema).unwrap();
let stmt = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "track".to_string(),
columns: vec![],
source: vibesql_ast::InsertSource::Values(vec![vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("song1"),
)),
]]),
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
let rows = InsertExecutor::execute(&mut db, &stmt).unwrap();
assert_eq!(rows, 1);
let table = db.get_table("track").unwrap();
let row = &table.scan()[0];
assert_eq!(row.get(0), Some(&vibesql_types::SqlValue::Integer(1)));
assert_eq!(row.get(1), Some(&vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("song1"))));
}
#[test]
fn test_integer_primary_key_null_autogen_sequential() {
let mut db = vibesql_storage::Database::new();
let schema = vibesql_catalog::TableSchema::with_primary_key(
"items".to_string(),
vec![
vibesql_catalog::ColumnSchema::new(
"id".to_string(),
vibesql_types::DataType::Integer,
false,
),
vibesql_catalog::ColumnSchema::new(
"val".to_string(),
vibesql_types::DataType::Varchar { max_length: None },
true,
),
],
vec!["id".to_string()],
);
db.create_table(schema).unwrap();
let stmt1 = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "items".to_string(),
columns: vec![],
source: vibesql_ast::InsertSource::Values(vec![vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("a"),
)),
]]),
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
InsertExecutor::execute(&mut db, &stmt1).unwrap();
let stmt2 = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "items".to_string(),
columns: vec![],
source: vibesql_ast::InsertSource::Values(vec![vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("b"),
)),
]]),
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
InsertExecutor::execute(&mut db, &stmt2).unwrap();
let table = db.get_table("items").unwrap();
assert_eq!(table.row_count(), 2);
assert_eq!(table.scan()[0].get(0), Some(&vibesql_types::SqlValue::Integer(1)));
assert_eq!(table.scan()[1].get(0), Some(&vibesql_types::SqlValue::Integer(2)));
}
#[test]
fn test_integer_primary_key_null_autogen_after_explicit() {
let mut db = vibesql_storage::Database::new();
let schema = vibesql_catalog::TableSchema::with_primary_key(
"t".to_string(),
vec![
vibesql_catalog::ColumnSchema::new(
"id".to_string(),
vibesql_types::DataType::Integer,
false,
),
vibesql_catalog::ColumnSchema::new(
"data".to_string(),
vibesql_types::DataType::Varchar { max_length: None },
true,
),
],
vec!["id".to_string()],
);
db.create_table(schema).unwrap();
let stmt1 = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "t".to_string(),
columns: vec![],
source: vibesql_ast::InsertSource::Values(vec![vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(100)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("explicit"),
)),
]]),
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
InsertExecutor::execute(&mut db, &stmt1).unwrap();
let stmt2 = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "t".to_string(),
columns: vec![],
source: vibesql_ast::InsertSource::Values(vec![vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("auto"),
)),
]]),
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
InsertExecutor::execute(&mut db, &stmt2).unwrap();
let table = db.get_table("t").unwrap();
assert_eq!(table.row_count(), 2);
let auto_row = table.scan().iter().find(|r| {
r.get(1) == Some(&vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("auto")))
});
assert!(auto_row.is_some());
assert_eq!(auto_row.unwrap().get(0), Some(&vibesql_types::SqlValue::Integer(101)));
}
#[test]
fn test_bigint_primary_key_no_autogen() {
let mut db = vibesql_storage::Database::new();
let schema = vibesql_catalog::TableSchema::with_primary_key(
"bigint_pk".to_string(),
vec![
vibesql_catalog::ColumnSchema::new(
"id".to_string(),
vibesql_types::DataType::Bigint, true, ),
vibesql_catalog::ColumnSchema::new(
"data".to_string(),
vibesql_types::DataType::Varchar { max_length: None },
true,
),
],
vec!["id".to_string()],
);
db.create_table(schema).unwrap();
let stmt = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "bigint_pk".to_string(),
columns: vec![],
source: vibesql_ast::InsertSource::Values(vec![vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("test"),
)),
]]),
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
InsertExecutor::execute(&mut db, &stmt).unwrap();
let table = db.get_table("bigint_pk").unwrap();
assert_eq!(table.scan()[0].get(0), Some(&vibesql_types::SqlValue::Null));
}
#[test]
fn test_integer_primary_key_null_autogen_multirow() {
let mut db = vibesql_storage::Database::new();
let schema = vibesql_catalog::TableSchema::with_primary_key(
"track".to_string(),
vec![
vibesql_catalog::ColumnSchema::new(
"tid".to_string(),
vibesql_types::DataType::Integer,
false,
),
vibesql_catalog::ColumnSchema::new(
"name".to_string(),
vibesql_types::DataType::Varchar { max_length: None },
true,
),
],
vec!["tid".to_string()],
);
db.create_table(schema).unwrap();
let stmt = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "track".to_string(),
columns: vec![],
source: vibesql_ast::InsertSource::Values(vec![
vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("one"),
)),
],
vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("two"),
)),
],
vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("three"),
)),
],
]),
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
let rows = InsertExecutor::execute(&mut db, &stmt).unwrap();
assert_eq!(rows, 3);
let table = db.get_table("track").unwrap();
assert_eq!(table.row_count(), 3);
let ids: Vec<i64> = table
.scan()
.iter()
.filter_map(|r| {
if let Some(vibesql_types::SqlValue::Integer(id)) = r.get(0) {
Some(*id)
} else {
None
}
})
.collect();
let mut sorted_ids = ids.clone();
sorted_ids.sort();
assert_eq!(sorted_ids, vec![1, 2, 3], "Expected sequential ids 1, 2, 3");
}
#[test]
fn test_composite_primary_key_no_autogen() {
let mut db = vibesql_storage::Database::new();
let schema = vibesql_catalog::TableSchema::with_primary_key(
"composite_pk".to_string(),
vec![
vibesql_catalog::ColumnSchema::new(
"a".to_string(),
vibesql_types::DataType::Integer,
true, ),
vibesql_catalog::ColumnSchema::new(
"b".to_string(),
vibesql_types::DataType::Integer,
true,
),
],
vec!["a".to_string(), "b".to_string()], );
db.create_table(schema).unwrap();
let stmt = vibesql_ast::InsertStmt {
with_clause: None,
schema_name: None,
schema_quoted: false,
table_quoted: false,
table_name: "composite_pk".to_string(),
columns: vec![],
source: vibesql_ast::InsertSource::Values(vec![vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(1)),
]]),
conflict_clause: None,
on_conflict: None,
on_duplicate_key_update: None,
returning: None,
};
InsertExecutor::execute(&mut db, &stmt).unwrap();
let table = db.get_table("composite_pk").unwrap();
assert_eq!(table.scan()[0].get(0), Some(&vibesql_types::SqlValue::Null));
}