feat: proper column definition parsing

This commit is contained in:
Levy A.
2025-05-21 00:46:56 -03:00
parent f92e000277
commit 3bc24eb86f
2 changed files with 76 additions and 11 deletions

View File

@@ -4,7 +4,7 @@ use crate::{util::normalize_ident, Result};
use crate::{LimboError, VirtualTable};
use core::fmt;
use fallible_iterator::FallibleIterator;
use limbo_sqlite3_parser::ast::{Expr, Literal, SortOrder, TableOptions};
use limbo_sqlite3_parser::ast::{self, ColumnDefinition, Expr, Literal, SortOrder, TableOptions};
use limbo_sqlite3_parser::{
ast::{Cmd, CreateTableBody, QualifiedName, ResultColumn, Stmt},
lexer::sql::Parser,
@@ -586,6 +586,80 @@ impl Column {
}
}
// TODO: This might replace some of util::columns_from_create_table_body
impl From<ColumnDefinition> for Column {
fn from(value: ColumnDefinition) -> Self {
let ast::Name(name) = value.col_name;
let mut default = None;
let mut notnull = false;
let mut primary_key = false;
let mut unique = false;
let mut collation = None;
for ast::NamedColumnConstraint { constraint, .. } in value.constraints {
match constraint {
ast::ColumnConstraint::PrimaryKey { .. } => primary_key = true,
ast::ColumnConstraint::NotNull { .. } => notnull = true,
ast::ColumnConstraint::Unique(..) => unique = true,
ast::ColumnConstraint::Default(expr) => {
default.replace(expr);
}
ast::ColumnConstraint::Collate { collation_name } => {
collation.replace(
CollationSeq::new(&collation_name.0)
.expect("collation should have been set correctly in create table"),
);
}
_ => {}
};
}
let ty = match value.col_type {
Some(ref data_type) => {
// https://www.sqlite.org/datatype3.html
let type_name = data_type.name.clone().to_uppercase();
if type_name.contains("INT") {
Type::Integer
} else if type_name.contains("CHAR")
|| type_name.contains("CLOB")
|| type_name.contains("TEXT")
{
Type::Text
} else if type_name.contains("BLOB") || type_name.is_empty() {
Type::Blob
} else if type_name.contains("REAL")
|| type_name.contains("FLOA")
|| type_name.contains("DOUB")
{
Type::Real
} else {
Type::Numeric
}
}
None => Type::Null,
};
let ty_str = value
.col_type
.map(|t| t.name.to_string())
.unwrap_or_default();
Column {
name: Some(name),
ty,
default,
notnull,
ty_str,
primary_key,
is_rowid_alias: false,
unique,
collation,
}
}
}
/// 3.1. Determination Of Column Affinity
/// For tables not declared as STRICT, the affinity of a column is determined by the declared type of the column, according to the following rules in the order shown:
///

View File

@@ -269,16 +269,7 @@ pub fn translate_inner(
)?
}
ast::AlterTableBody::AddColumn(col_def) => {
btree.columns.push(Column {
name: Some(col_def.col_name.0),
ty: crate::schema::Type::Null,
ty_str: "".to_string(),
primary_key: false,
is_rowid_alias: false,
notnull: false,
default: None,
unique: false,
});
btree.columns.push(Column::from(col_def));
let sql = btree.to_sql();