pub const CREATE_EXTENSION: &str = "CREATE EXTENSION IF NOT EXISTS vector";
pub fn create_table_sql(table: &str, dimensions: usize) -> String {
format!(
"CREATE TABLE IF NOT EXISTS {table} (\
id TEXT PRIMARY KEY, \
embedding vector({dimensions}), \
content TEXT NOT NULL, \
metadata JSONB NOT NULL DEFAULT '{{}}'::jsonb\
)"
)
}
pub fn create_hnsw_index_sql(
table: &str,
ops_class: &str,
m: Option<usize>,
ef_construction: Option<usize>,
) -> String {
let mut with_parts = Vec::new();
if let Some(m) = m {
with_parts.push(format!("m = {m}"));
}
if let Some(ef) = ef_construction {
with_parts.push(format!("ef_construction = {ef}"));
}
let with_clause = if with_parts.is_empty() {
String::new()
} else {
format!(" WITH ({})", with_parts.join(", "))
};
format!(
"CREATE INDEX IF NOT EXISTS {table}_embedding_hnsw_idx \
ON {table} USING hnsw (embedding {ops_class}){with_clause}"
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_table_sql() {
let sql = create_table_sql("docs", 1536);
assert!(sql.contains("docs"));
assert!(sql.contains("vector(1536)"));
assert!(sql.contains("id TEXT PRIMARY KEY"));
assert!(sql.contains("content TEXT NOT NULL"));
assert!(sql.contains("metadata JSONB"));
}
#[test]
fn test_create_hnsw_index_defaults() {
let sql = create_hnsw_index_sql("docs", "vector_cosine_ops", None, None);
assert!(sql.contains("USING hnsw"));
assert!(sql.contains("vector_cosine_ops"));
assert!(!sql.contains("WITH"));
}
#[test]
fn test_create_hnsw_index_custom_params() {
let sql = create_hnsw_index_sql("docs", "vector_l2_ops", Some(32), Some(128));
assert!(sql.contains("WITH (m = 32, ef_construction = 128)"));
}
}