Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
8 changes: 8 additions & 0 deletions src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use crate::ast::{
display_comma_separated, display_separated, DataType, Expr, Ident, MySQLColumnPosition,
ObjectName, OrderByExpr, ProjectionSelect, SequenceOptions, SqlOption, Value,
};
use crate::keywords::Keyword;
use crate::tokenizer::Token;

/// An `ALTER TABLE` (`Statement::AlterTable`) operation
Expand Down Expand Up @@ -1146,6 +1147,9 @@ pub enum ColumnOption {
/// ```
/// [MS SQL Server]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property
Identity(Option<IdentityProperty>),
/// Sqlite specific: ON CONFLICT option on column definition
/// https://www.sqlite.org/lang_conflict.html
OnConflict(Keyword),
}

impl fmt::Display for ColumnOption {
Expand Down Expand Up @@ -1254,6 +1258,10 @@ impl fmt::Display for ColumnOption {
}
Ok(())
}
OnConflict(keyword) => {
write!(f, "ON CONFLICT {:?}", keyword)?;
Ok(())
}
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6083,6 +6083,21 @@ impl<'a> Parser<'a> {
None
};
Ok(Some(ColumnOption::Identity(property)))
} else if dialect_of!(self is SQLiteDialect)
&& self.parse_keywords(&[Keyword::ON, Keyword::CONFLICT])
{
// Support ON CONFLICT for SQLite
let on_conflict = self.parse_one_of_keywords(&[
Keyword::ROLLBACK,
Keyword::ABORT,
Keyword::FAIL,
Keyword::IGNORE,
Keyword::REPLACE,
]);
match on_conflict {
Some(keyword) => Ok(Some(ColumnOption::OnConflict(keyword))),
_ => unreachable!(),
}
} else {
Ok(None)
}
Expand Down
33 changes: 33 additions & 0 deletions tests/sqlparser_sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#[macro_use]
mod test_utils;

use sqlparser::keywords::Keyword;
use test_utils::*;

use sqlparser::ast::SelectItem::UnnamedExpr;
Expand Down Expand Up @@ -281,6 +282,38 @@ 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_on_conflict_col() {
for keyword in [
Keyword::ROLLBACK,
Keyword::ABORT,
Keyword::FAIL,
Keyword::IGNORE,
Keyword::REPLACE,
] {
let sql = format!("CREATE TABLE t1 (a INT, b INT ON CONFLICT {:?})", keyword);
match sqlite().verified_stmt(&sql) {
Statement::CreateTable(CreateTable { columns, .. }) => {
assert_eq!(
vec![ColumnOptionDef {
name: None,
option: ColumnOption::OnConflict(keyword),
}],
columns[1].options
);
}
_ => unreachable!(),
}
}
}

#[test]
#[should_panic]
fn test_parse_create_table_on_conflict_col_err() {
let sql_err = "CREATE TABLE t1 (a INT, b INT ON CONFLICT BOH)";
let _ = sqlite().parse_sql_statements(sql_err);
}

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