Merge 'Throw parse error on CHECK constraint in create table' from Preston Thorpe

RE: https://github.com/tursodatabase/turso/issues/3753
Let's throw parse error until this feature is supported.
Should we throw parse error if we open a DB up that has CHECK
constraints on the columns?

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #3755
This commit is contained in:
Preston Thorpe
2025-10-16 14:22:21 -04:00
committed by GitHub
2 changed files with 37 additions and 25 deletions

View File

@@ -1632,6 +1632,9 @@ pub fn create_table(tbl_name: &str, body: &CreateTableBody, root_page: i64) -> R
let mut collation = None;
for c_def in constraints {
match &c_def.constraint {
ast::ColumnConstraint::Check { .. } => {
crate::bail_parse_error!("CHECK constraints are not yet supported");
}
ast::ColumnConstraint::PrimaryKey {
order: o,
auto_increment,

View File

@@ -26,6 +26,39 @@ use crate::{bail_parse_error, Result};
use turso_ext::VTabKind;
fn validate(body: &ast::CreateTableBody, connection: &Connection) -> Result<()> {
if let ast::CreateTableBody::ColumnsAndConstraints {
options, columns, ..
} = &body
{
if options.contains(ast::TableOptions::STRICT) && !connection.experimental_strict_enabled()
{
bail_parse_error!(
"STRICT tables are an experimental feature. Enable them with --experimental-strict flag"
);
}
for i in 0..columns.len() {
let col_i = &columns[i];
for constraint in &col_i.constraints {
// don't silently ignore CHECK constraints, throw parse error for now
if let ast::ColumnConstraint::Check { .. } = constraint.constraint {
bail_parse_error!("CHECK constraints are not supported yet");
}
}
for j in &columns[(i + 1)..] {
if col_i
.col_name
.as_str()
.eq_ignore_ascii_case(j.col_name.as_str())
{
bail_parse_error!("duplicate column name: {}", j.col_name.as_str());
}
}
}
}
Ok(())
}
pub fn translate_create_table(
tbl_name: ast::QualifiedName,
resolver: &Resolver,
@@ -39,32 +72,8 @@ pub fn translate_create_table(
if temporary {
bail_parse_error!("TEMPORARY table not supported yet");
}
validate(&body, connection)?;
if let ast::CreateTableBody::ColumnsAndConstraints { columns, .. } = &body {
for i in 0..columns.len() {
let col_i = &columns[i];
for j in &columns[(i + 1)..] {
if col_i
.col_name
.as_str()
.eq_ignore_ascii_case(j.col_name.as_str())
{
bail_parse_error!("duplicate column name: {}", j.col_name.as_str());
}
}
}
}
// Check for STRICT mode without experimental flag
if let ast::CreateTableBody::ColumnsAndConstraints { options, .. } = &body {
if options.contains(ast::TableOptions::STRICT) && !connection.experimental_strict_enabled()
{
bail_parse_error!(
"STRICT tables are an experimental feature. Enable them with --experimental-strict flag"
);
}
}
let opts = ProgramBuilderOpts {
num_cursors: 1,
approx_num_insns: 30,