Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support SQLite column definitions with no type #1075

Merged
merged 4 commits into from
Jan 1, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/ast/data_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ pub enum DataType {
/// [hive]: https://docs.cloudera.com/cdw-runtime/cloud/impala-sql-reference/topics/impala-struct.html
/// [bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
Struct(Vec<StructField>),
/// Specific to SQLite: no type specified (no coercion)
takluyver marked this conversation as resolved.
Show resolved Hide resolved
Unspecified,
}

impl fmt::Display for DataType {
Expand Down Expand Up @@ -379,6 +381,7 @@ impl fmt::Display for DataType {
write!(f, "STRUCT")
}
}
DataType::Unspecified => Ok(()),
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,11 @@ pub struct ColumnDef {

impl fmt::Display for ColumnDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", self.name, self.data_type)?;
if self.data_type == DataType::Unspecified {
write!(f, "{}", self.name)?;
} else {
write!(f, "{} {}", self.name, self.data_type)?;
}
if let Some(collation) = &self.collation {
write!(f, " COLLATE {collation}")?;
}
Expand Down
29 changes: 28 additions & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4183,7 +4183,11 @@ impl<'a> Parser<'a> {

pub fn parse_column_def(&mut self) -> Result<ColumnDef, ParserError> {
let name = self.parse_identifier()?;
let data_type = self.parse_data_type()?;
let data_type = if self.sqlite_untyped_col_helper() {
DataType::Unspecified
} else {
self.parse_data_type()?
};
let mut collation = if self.parse_keyword(Keyword::COLLATE) {
Some(self.parse_object_name()?)
} else {
Expand Down Expand Up @@ -4219,6 +4223,29 @@ impl<'a> Parser<'a> {
})
}

fn sqlite_untyped_col_helper(&mut self) -> bool {
takluyver marked this conversation as resolved.
Show resolved Hide resolved
if dialect_of!(self is SQLiteDialect) {
match self.peek_token().token {
Token::Word(word) => matches!(
word.keyword,
Keyword::CONSTRAINT
| Keyword::PRIMARY
| Keyword::NOT
| Keyword::UNIQUE
| Keyword::CHECK
| Keyword::DEFAULT
| Keyword::COLLATE
| Keyword::REFERENCES
| Keyword::GENERATED
| Keyword::AS
),
_ => true, // e.g. comma immediately after column name
}
} else {
false
}
}

pub fn parse_optional_column_option(&mut self) -> Result<Option<ColumnOption>, ParserError> {
if self.parse_keywords(&[Keyword::CHARACTER, Keyword::SET]) {
Ok(Some(ColumnOption::CharacterSet(self.parse_object_name()?)))
Expand Down
5 changes: 5 additions & 0 deletions tests/sqlparser_sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,11 @@ fn parse_create_table_gencol() {
sqlite_and_generic().verified_stmt("CREATE TABLE t1 (a INT, b INT AS (a * 2) STORED)");
}

#[test]
fn parse_create_table_untyped() {
sqlite().verified_stmt("CREATE TABLE t1 (a, b AS (a * 2), c NOT NULL)");
}

#[test]
fn test_placeholder() {
// In postgres, this would be the absolute value operator '@' applied to the column 'xxx'
Expand Down
Loading