agent_patch
runs/2026-02-28__18-27-22__gpt-5-1-codex-mini/flux-pr-1747/flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/agent-logs/agent.patch
30593 bytes
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/dml.rs b/app/src/ast/dml.rs
index 9cdb1ca..a6bfec7 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/dml.rs
+++ b/app/src/ast/dml.rs
@@ -33,11 +33,11 @@ pub use super::ddl::{ColumnDef, TableConstraint};
use super::{
display_comma_separated, display_separated, query::InputFormatClause, Assignment, ClusteredBy,
- CommentDef, Expr, FileFormat, FromTable, HiveDistributionStyle, HiveFormat, HiveIOFormat,
- HiveRowFormat, Ident, IndexType, InsertAliases, MysqlInsertPriority, ObjectName, OnCommit,
- OnInsert, OneOrManyWithParens, OrderByExpr, Query, RowAccessPolicy, SelectItem, Setting,
- SqlOption, SqliteOnConflict, StorageSerializationPolicy, TableEngine, TableObject,
- TableWithJoins, Tag, WrappedCollection,
+ CommentDef, CreateTableOptions, Expr, FileFormat, FromTable, HiveDistributionStyle, HiveFormat,
+ HiveIOFormat, HiveRowFormat, Ident, IndexType, InsertAliases, MysqlInsertPriority, ObjectName,
+ OnCommit, OnInsert, OneOrManyWithParens, OrderByExpr, Query, RowAccessPolicy, SelectItem,
+ Setting, SqlOption, SqliteOnConflict, StorageSerializationPolicy, TableObject, TableWithJoins,
+ Tag, WrappedCollection,
};
/// Index column type.
@@ -146,19 +146,14 @@ pub struct CreateTable {
pub constraints: Vec<TableConstraint>,
pub hive_distribution: HiveDistributionStyle,
pub hive_formats: Option<HiveFormat>,
- pub table_properties: Vec<SqlOption>,
- pub with_options: Vec<SqlOption>,
+ pub options: CreateTableOptions,
pub file_format: Option<FileFormat>,
pub location: Option<String>,
pub query: Option<Box<Query>>,
pub without_rowid: bool,
pub like: Option<ObjectName>,
pub clone: Option<ObjectName>,
- pub engine: Option<TableEngine>,
pub comment: Option<CommentDef>,
- pub auto_increment_offset: Option<u32>,
- pub default_charset: Option<String>,
- pub collation: Option<String>,
pub on_commit: Option<OnCommit>,
/// ClickHouse "ON CLUSTER" clause:
/// <https://clickhouse.com/docs/en/sql-reference/distributed-ddl/>
@@ -375,34 +370,8 @@ impl Display for CreateTable {
}
write!(f, " LOCATION '{}'", self.location.as_ref().unwrap())?;
}
- if !self.table_properties.is_empty() {
- write!(
- f,
- " TBLPROPERTIES ({})",
- display_comma_separated(&self.table_properties)
- )?;
- }
- if !self.with_options.is_empty() {
- write!(f, " WITH ({})", display_comma_separated(&self.with_options))?;
- }
- if let Some(engine) = &self.engine {
- write!(f, " ENGINE={engine}")?;
- }
- if let Some(comment_def) = &self.comment {
- match comment_def {
- CommentDef::WithEq(comment) => {
- write!(f, " COMMENT = '{comment}'")?;
- }
- CommentDef::WithoutEq(comment) => {
- write!(f, " COMMENT '{comment}'")?;
- }
- // For CommentDef::AfterColumnDefsWithoutEq will be displayed after column definition
- CommentDef::AfterColumnDefsWithoutEq(_) => (),
- }
- }
-
- if let Some(auto_increment_offset) = self.auto_increment_offset {
- write!(f, " AUTO_INCREMENT {auto_increment_offset}")?;
+ if self.options != CreateTableOptions::None {
+ write!(f, " {}", self.options)?;
}
if let Some(primary_key) = &self.primary_key {
write!(f, " PRIMARY KEY {}", primary_key)?;
@@ -420,14 +389,6 @@ impl Display for CreateTable {
write!(f, " CLUSTER BY {cluster_by}")?;
}
- if let Some(options) = self.options.as_ref() {
- write!(
- f,
- " OPTIONS({})",
- display_comma_separated(options.as_slice())
- )?;
- }
-
if let Some(external_volume) = self.external_volume.as_ref() {
write!(f, " EXTERNAL_VOLUME = '{external_volume}'")?;
}
@@ -503,13 +464,6 @@ impl Display for CreateTable {
write!(f, " WITH TAG ({})", display_comma_separated(tag.as_slice()))?;
}
- if let Some(default_charset) = &self.default_charset {
- write!(f, " DEFAULT CHARSET={default_charset}")?;
- }
- if let Some(collation) = &self.collation {
- write!(f, " COLLATE={collation}")?;
- }
-
if self.on_commit.is_some() {
let on_commit = match self.on_commit {
Some(OnCommit::DeleteRows) => "ON COMMIT DELETE ROWS",
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/helpers/stmt_create_table.rs b/app/src/ast/helpers/stmt_create_table.rs
index 1c50cb8..a7ed3ce 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/helpers/stmt_create_table.rs
+++ b/app/src/ast/helpers/stmt_create_table.rs
@@ -26,9 +26,9 @@ use sqlparser_derive::{Visit, VisitMut};
use super::super::dml::CreateTable;
use crate::ast::{
- ClusteredBy, ColumnDef, CommentDef, Expr, FileFormat, HiveDistributionStyle, HiveFormat, Ident,
- ObjectName, OnCommit, OneOrManyWithParens, Query, RowAccessPolicy, SqlOption, Statement,
- StorageSerializationPolicy, TableConstraint, TableEngine, Tag, WrappedCollection,
+ ClusteredBy, ColumnDef, CommentDef, CreateTableOptions, Expr, FileFormat, HiveDistributionStyle,
+ HiveFormat, Ident, ObjectName, OnCommit, OneOrManyWithParens, Query, RowAccessPolicy, SqlOption,
+ Statement, StorageSerializationPolicy, TableConstraint, Tag, WrappedCollection,
};
use crate::parser::ParserError;
@@ -76,19 +76,14 @@ pub struct CreateTableBuilder {
pub constraints: Vec<TableConstraint>,
pub hive_distribution: HiveDistributionStyle,
pub hive_formats: Option<HiveFormat>,
- pub table_properties: Vec<SqlOption>,
- pub with_options: Vec<SqlOption>,
+ pub options: CreateTableOptions,
pub file_format: Option<FileFormat>,
pub location: Option<String>,
pub query: Option<Box<Query>>,
pub without_rowid: bool,
pub like: Option<ObjectName>,
pub clone: Option<ObjectName>,
- pub engine: Option<TableEngine>,
pub comment: Option<CommentDef>,
- pub auto_increment_offset: Option<u32>,
- pub default_charset: Option<String>,
- pub collation: Option<String>,
pub on_commit: Option<OnCommit>,
pub on_cluster: Option<Ident>,
pub primary_key: Option<Box<Expr>>,
@@ -96,7 +91,6 @@ pub struct CreateTableBuilder {
pub partition_by: Option<Box<Expr>>,
pub cluster_by: Option<WrappedCollection<Vec<Ident>>>,
pub clustered_by: Option<ClusteredBy>,
- pub options: Option<Vec<SqlOption>>,
pub inherits: Option<Vec<ObjectName>>,
pub strict: bool,
pub copy_grants: bool,
@@ -131,19 +125,14 @@ impl CreateTableBuilder {
constraints: vec![],
hive_distribution: HiveDistributionStyle::NONE,
hive_formats: None,
- table_properties: vec![],
- with_options: vec![],
+ options: CreateTableOptions::None,
file_format: None,
location: None,
query: None,
without_rowid: false,
like: None,
clone: None,
- engine: None,
comment: None,
- auto_increment_offset: None,
- default_charset: None,
- collation: None,
on_commit: None,
on_cluster: None,
primary_key: None,
@@ -231,12 +220,12 @@ impl CreateTableBuilder {
}
pub fn table_properties(mut self, table_properties: Vec<SqlOption>) -> Self {
- self.table_properties = table_properties;
+ self.options = CreateTableOptions::TblProperties(table_properties);
self
}
pub fn with_options(mut self, with_options: Vec<SqlOption>) -> Self {
- self.with_options = with_options;
+ self.options = CreateTableOptions::With(with_options);
self
}
pub fn file_format(mut self, file_format: Option<FileFormat>) -> Self {
@@ -268,31 +257,11 @@ impl CreateTableBuilder {
self
}
- pub fn engine(mut self, engine: Option<TableEngine>) -> Self {
- self.engine = engine;
- self
- }
-
pub fn comment(mut self, comment: Option<CommentDef>) -> Self {
self.comment = comment;
self
}
- pub fn auto_increment_offset(mut self, offset: Option<u32>) -> Self {
- self.auto_increment_offset = offset;
- self
- }
-
- pub fn default_charset(mut self, default_charset: Option<String>) -> Self {
- self.default_charset = default_charset;
- self
- }
-
- pub fn collation(mut self, collation: Option<String>) -> Self {
- self.collation = collation;
- self
- }
-
pub fn on_commit(mut self, on_commit: Option<OnCommit>) -> Self {
self.on_commit = on_commit;
self
@@ -328,7 +297,7 @@ impl CreateTableBuilder {
self
}
- pub fn options(mut self, options: Option<Vec<SqlOption>>) -> Self {
+ pub fn options(mut self, options: CreateTableOptions) -> Self {
self.options = options;
self
}
@@ -437,19 +406,13 @@ impl CreateTableBuilder {
constraints: self.constraints,
hive_distribution: self.hive_distribution,
hive_formats: self.hive_formats,
- table_properties: self.table_properties,
- with_options: self.with_options,
file_format: self.file_format,
location: self.location,
query: self.query,
without_rowid: self.without_rowid,
like: self.like,
clone: self.clone,
- engine: self.engine,
comment: self.comment,
- auto_increment_offset: self.auto_increment_offset,
- default_charset: self.default_charset,
- collation: self.collation,
on_commit: self.on_commit,
on_cluster: self.on_cluster,
primary_key: self.primary_key,
@@ -499,19 +462,14 @@ impl TryFrom<Statement> for CreateTableBuilder {
constraints,
hive_distribution,
hive_formats,
- table_properties,
- with_options,
+ options,
file_format,
location,
query,
without_rowid,
like,
clone,
- engine,
comment,
- auto_increment_offset,
- default_charset,
- collation,
on_commit,
on_cluster,
primary_key,
@@ -519,7 +477,6 @@ impl TryFrom<Statement> for CreateTableBuilder {
partition_by,
cluster_by,
clustered_by,
- options,
inherits,
strict,
copy_grants,
@@ -548,19 +505,14 @@ impl TryFrom<Statement> for CreateTableBuilder {
constraints,
hive_distribution,
hive_formats,
- table_properties,
- with_options,
+ options,
file_format,
location,
query,
without_rowid,
like,
clone,
- engine,
comment,
- auto_increment_offset,
- default_charset,
- collation,
on_commit,
on_cluster,
primary_key,
@@ -568,7 +520,6 @@ impl TryFrom<Statement> for CreateTableBuilder {
partition_by,
cluster_by,
clustered_by,
- options,
inherits,
strict,
iceberg,
@@ -600,7 +551,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
pub(crate) struct CreateTableConfiguration {
pub partition_by: Option<Box<Expr>>,
pub cluster_by: Option<WrappedCollection<Vec<Ident>>>,
- pub options: Option<Vec<SqlOption>>,
+ pub options: CreateTableOptions,
pub inherits: Option<Vec<ObjectName>>,
}
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/mod.rs b/app/src/ast/mod.rs
index 582922a..af7a3db 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/mod.rs
+++ b/app/src/ast/mod.rs
@@ -284,7 +284,7 @@ impl fmt::Display for Ident {
}
/// A name of a table, view, custom type, etc., possibly multi-part, i.e. db.schema.obj
-#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[derive(Default, Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ObjectName(pub Vec<ObjectNamePart>);
@@ -2681,6 +2681,10 @@ pub enum CreateTableOptions {
///
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list>
Options(Vec<SqlOption>),
+ /// Plain key/value or keyword-only options that follow the column definition in MySQL-style syntax.
+ Plain(Vec<SqlOption>),
+ /// `TBLPROPERTIES` clause used by Hive.
+ TblProperties(Vec<SqlOption>),
}
impl fmt::Display for CreateTableOptions {
@@ -2692,6 +2696,12 @@ impl fmt::Display for CreateTableOptions {
CreateTableOptions::Options(options) => {
write!(f, "OPTIONS({})", display_comma_separated(options))
}
+ CreateTableOptions::Plain(options) => {
+ write!(f, "{}", display_separated(options, " "))
+ }
+ CreateTableOptions::TblProperties(options) => {
+ write!(f, "TBLPROPERTIES ({})", display_comma_separated(options))
+ }
CreateTableOptions::None => Ok(()),
}
}
@@ -7549,6 +7559,12 @@ pub enum SqlOption {
///
/// WITH(DISTRIBUTION = ROUND_ROBIN)
KeyValue { key: Ident, value: Expr },
+ /// Table engine specification like `ENGINE = InnoDB` or `ENGINE = MergeTree()`.
+ Engine(TableEngine),
+ /// Tablespace option used by MySQL, e.g. `TABLESPACE = filegroup`.
+ Tablespace(Ident),
+ /// Table comment clause, with or without `=`.
+ Comment(CommentDef),
/// One or more table partitions and represents which partition the boundary values belong to,
/// e.g.
///
@@ -7572,6 +7588,15 @@ impl fmt::Display for SqlOption {
SqlOption::KeyValue { key: name, value } => {
write!(f, "{} = {}", name, value)
}
+ SqlOption::Engine(engine) => write!(f, "ENGINE = {engine}"),
+ SqlOption::Tablespace(name) => write!(f, "TABLESPACE = {name}"),
+ SqlOption::Comment(comment) => match comment {
+ CommentDef::WithEq(value) => write!(f, "COMMENT = '{value}'"),
+ CommentDef::WithoutEq(value) => write!(f, "COMMENT '{value}'"),
+ CommentDef::AfterColumnDefsWithoutEq(value) => {
+ write!(f, "COMMENT '{value}'")
+ }
+ },
SqlOption::Partition {
column_name,
range_direction,
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/spans.rs b/app/src/ast/spans.rs
index 836f229..4856501 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/ast/spans.rs
+++ b/app/src/ast/spans.rs
@@ -567,19 +567,13 @@ impl Spanned for CreateTable {
constraints,
hive_distribution: _, // hive specific
hive_formats: _, // hive specific
- table_properties,
- with_options,
file_format: _, // enum
location: _, // string, no span
query,
without_rowid: _, // bool
like,
clone,
- engine: _, // todo
comment: _, // todo, no span
- auto_increment_offset: _, // u32, no span
- default_charset: _, // string, no span
- collation: _, // string, no span
on_commit: _, // enum
on_cluster: _, // todo, clickhouse specific
primary_key: _, // todo, clickhouse specific
@@ -587,7 +581,7 @@ impl Spanned for CreateTable {
partition_by: _, // todo, BigQuery specific
cluster_by: _, // todo, BigQuery specific
clustered_by: _, // todo, Hive specific
- options: _, // todo, BigQuery specific
+ options,
inherits: _, // todo, PostgreSQL specific
strict: _, // bool
copy_grants: _, // bool
@@ -610,8 +604,7 @@ impl Spanned for CreateTable {
core::iter::once(name.span())
.chain(columns.iter().map(|i| i.span()))
.chain(constraints.iter().map(|i| i.span()))
- .chain(table_properties.iter().map(|i| i.span()))
- .chain(with_options.iter().map(|i| i.span()))
+ .chain(core::iter::once(options.span()))
.chain(query.iter().map(|i| i.span()))
.chain(like.iter().map(|i| i.span()))
.chain(clone.iter().map(|i| i.span())),
@@ -997,6 +990,9 @@ impl Spanned for SqlOption {
SqlOption::Clustered(table_options_clustered) => table_options_clustered.span(),
SqlOption::Ident(ident) => ident.span,
SqlOption::KeyValue { key, value } => key.span.union(&value.span()),
+ SqlOption::Engine(_) => Span::empty(),
+ SqlOption::Tablespace(ident) => ident.span,
+ SqlOption::Comment(_) => Span::empty(),
SqlOption::Partition {
column_name,
range_direction: _,
@@ -1041,6 +1037,8 @@ impl Spanned for CreateTableOptions {
CreateTableOptions::None => Span::empty(),
CreateTableOptions::With(vec) => union_spans(vec.iter().map(|i| i.span())),
CreateTableOptions::Options(vec) => union_spans(vec.iter().map(|i| i.span())),
+ CreateTableOptions::Plain(vec) => union_spans(vec.iter().map(|i| i.span())),
+ CreateTableOptions::TblProperties(vec) => union_spans(vec.iter().map(|i| i.span())),
}
}
}
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/parser/mod.rs b/app/src/parser/mod.rs
index cbd464c..d98c2c7 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-1-codex-mini/app/src/parser/mod.rs
+++ b/app/src/parser/mod.rs
@@ -7059,39 +7059,20 @@ impl<'a> Parser<'a> {
let hive_distribution = self.parse_hive_distribution()?;
let clustered_by = self.parse_optional_clustered_by()?;
let hive_formats = self.parse_hive_formats()?;
+ let mut table_options = CreateTableOptions::None;
// PostgreSQL supports `WITH ( options )`, before `AS`
let with_options = self.parse_options(Keyword::WITH)?;
+ if !with_options.is_empty() {
+ table_options = CreateTableOptions::With(with_options);
+ }
let table_properties = self.parse_options(Keyword::TBLPROPERTIES)?;
-
- let engine = if self.parse_keyword(Keyword::ENGINE) {
- self.expect_token(&Token::Eq)?;
- let next_token = self.next_token();
- match next_token.token {
- Token::Word(w) => {
- let name = w.value;
- let parameters = if self.peek_token() == Token::LParen {
- Some(self.parse_parenthesized_identifiers()?)
- } else {
- None
- };
- Some(TableEngine { name, parameters })
- }
- _ => self.expected("identifier", next_token)?,
- }
- } else {
- None
- };
-
- let auto_increment_offset = if self.parse_keyword(Keyword::AUTO_INCREMENT) {
- let _ = self.consume_token(&Token::Eq);
- let next_token = self.next_token();
- match next_token.token {
- Token::Number(s, _) => Some(Self::parse::<u32>(s, next_token.span.start)?),
- _ => self.expected("literal int", next_token)?,
- }
- } else {
- None
- };
+ if !table_properties.is_empty() {
+ table_options = CreateTableOptions::TblProperties(table_properties);
+ }
+ let plain_options = self.parse_plain_table_options()?;
+ if !plain_options.is_empty() {
+ table_options = CreateTableOptions::Plain(plain_options);
+ }
// ClickHouse supports `PRIMARY KEY`, before `ORDER BY`
// https://clickhouse.com/docs/en/sql-reference/statements/create/table#primary-key
@@ -7120,28 +7101,15 @@ impl<'a> Parser<'a> {
};
let create_table_config = self.parse_optional_create_table_config()?;
-
- let default_charset = if self.parse_keywords(&[Keyword::DEFAULT, Keyword::CHARSET]) {
- self.expect_token(&Token::Eq)?;
- let next_token = self.next_token();
- match next_token.token {
- Token::Word(w) => Some(w.value),
- _ => self.expected("identifier", next_token)?,
- }
- } else {
- None
- };
-
- let collation = if self.parse_keywords(&[Keyword::COLLATE]) {
- self.expect_token(&Token::Eq)?;
- let next_token = self.next_token();
- match next_token.token {
- Token::Word(w) => Some(w.value),
- _ => self.expected("identifier", next_token)?,
- }
- } else {
- None
- };
+ let CreateTableConfiguration {
+ partition_by,
+ cluster_by,
+ options: config_options,
+ inherits,
+ } = create_table_config;
+ if config_options != CreateTableOptions::None {
+ table_options = config_options;
+ }
let on_commit = if self.parse_keywords(&[Keyword::ON, Keyword::COMMIT]) {
Some(self.parse_create_table_on_commit()?)
@@ -7152,12 +7120,6 @@ impl<'a> Parser<'a> {
let strict = self.parse_keyword(Keyword::STRICT);
// Excludes Hive dialect here since it has been handled after table column definitions.
- if !dialect_of!(self is HiveDialect) && self.parse_keyword(Keyword::COMMENT) {
- // rewind the COMMENT keyword
- self.prev_token();
- comment = self.parse_optional_inline_comment()?
- };
-
// Parse optional `AS ( query )`
let query = if self.parse_keyword(Keyword::AS) {
Some(self.parse_query()?)
@@ -7174,8 +7136,6 @@ impl<'a> Parser<'a> {
.temporary(temporary)
.columns(columns)
.constraints(constraints)
- .with_options(with_options)
- .table_properties(table_properties)
.or_replace(or_replace)
.if_not_exists(if_not_exists)
.transient(transient)
@@ -7186,19 +7146,15 @@ impl<'a> Parser<'a> {
.without_rowid(without_rowid)
.like(like)
.clone_clause(clone)
- .engine(engine)
.comment(comment)
- .auto_increment_offset(auto_increment_offset)
.order_by(order_by)
- .default_charset(default_charset)
- .collation(collation)
.on_commit(on_commit)
.on_cluster(on_cluster)
.clustered_by(clustered_by)
- .partition_by(create_table_config.partition_by)
- .cluster_by(create_table_config.cluster_by)
- .options(create_table_config.options)
- .inherits(create_table_config.inherits)
+ .partition_by(partition_by)
+ .cluster_by(cluster_by)
+ .options(table_options)
+ .inherits(inherits)
.primary_key(primary_key)
.strict(strict)
.build())
@@ -7974,6 +7930,116 @@ impl<'a> Parser<'a> {
}
}
+ pub fn parse_plain_table_options(&mut self) -> Result<Vec<SqlOption>, ParserError> {
+ let mut options = Vec::new();
+ while let Some(option) = self.parse_plain_table_option()? {
+ options.push(option);
+ }
+ Ok(options)
+ }
+
+ pub fn parse_plain_table_option(&mut self) -> Result<Option<SqlOption>, ParserError> {
+ if let Token::Word(word) = self.peek_token().token {
+ match word.keyword {
+ Keyword::ENGINE => {
+ self.expect_keyword_is(Keyword::ENGINE)?;
+ let _ = self.consume_token(&Token::Eq);
+ let next_token = self.next_token();
+ match next_token.token {
+ Token::Word(w) => {
+ let name = w.value;
+ let parameters = if self.peek_token() == Token::LParen {
+ Some(self.parse_parenthesized_identifiers()?)
+ } else {
+ None
+ };
+ return Ok(Some(SqlOption::Engine(TableEngine { name, parameters })));
+ }
+ _ => return self.expected("identifier", next_token),
+ }
+ }
+ Keyword::AUTO_INCREMENT => {
+ self.expect_keyword_is(Keyword::AUTO_INCREMENT);
+ let _ = self.consume_token(&Token::Eq);
+ let next_token = self.next_token();
+ let value = match next_token.token {
+ Token::Number(s, _) => Expr::Value(Value::Number(s, false)),
+ _ => return self.expected("literal int", next_token),
+ };
+ return Ok(Some(SqlOption::KeyValue {
+ key: Ident::new("AUTO_INCREMENT"),
+ value,
+ }));
+ }
+ Keyword::COMMENT => {
+ self.expect_keyword_is(Keyword::COMMENT);
+ let has_eq = self.consume_token(&Token::Eq);
+ let comment = self.parse_comment_value()?;
+ let comment_def = if has_eq {
+ CommentDef::WithEq(comment)
+ } else {
+ CommentDef::WithoutEq(comment)
+ };
+ return Ok(Some(SqlOption::Comment(comment_def)));
+ }
+ Keyword::TABLESPACE => {
+ self.expect_keyword_is(Keyword::TABLESPACE);
+ let _ = self.consume_token(&Token::Eq);
+ let value = self.parse_identifier()?;
+ return Ok(Some(SqlOption::Tablespace(value)));
+ }
+ Keyword::DEFAULT => {
+ if let Token::Word(next_word) = self.peek_nth_token_ref(1).token {
+ if next_word.keyword == Keyword::CHARSET {
+ self.expect_keywords(&[Keyword::DEFAULT, Keyword::CHARSET])?;
+ let _ = self.consume_token(&Token::Eq);
+ let value = self.parse_identifier()?;
+ return Ok(Some(SqlOption::KeyValue {
+ key: Ident::new("DEFAULT CHARSET"),
+ value: Expr::Identifier(value),
+ }));
+ }
+ if next_word.keyword == Keyword::CHARACTER
+ && matches!(self.peek_nth_token_ref(2).token, Token::Word(word) if word.keyword == Keyword::SET)
+ {
+ self.expect_keywords(&[
+ Keyword::DEFAULT,
+ Keyword::CHARACTER,
+ Keyword::SET,
+ ])?;
+ let _ = self.consume_token(&Token::Eq);
+ let value = self.parse_identifier()?;
+ return Ok(Some(SqlOption::KeyValue {
+ key: Ident::new("DEFAULT CHARACTER SET"),
+ value: Expr::Identifier(value),
+ }));
+ }
+ }
+ return Ok(None);
+ }
+ Keyword::COLLATE => {
+ self.expect_keyword_is(Keyword::COLLATE)?;
+ let _ = self.consume_token(&Token::Eq);
+ let value = self.parse_identifier()?;
+ return Ok(Some(SqlOption::KeyValue {
+ key: Ident::new("COLLATE"),
+ value: Expr::Identifier(value),
+ }));
+ }
+ _ => {
+ if self.peek_nth_token_ref(1).token == Token::Eq {
+ let key = self.parse_identifier()?;
+ self.expect_token(&Token::Eq)?;
+ let value = self.parse_expr()?;
+ return Ok(Some(SqlOption::KeyValue { key, value }));
+ }
+ return Ok(None);
+ }
+ }
+ }
+ Ok(None)
+ }
+
pub fn parse_index_type(&mut self) -> Result<IndexType, ParserError> {
Ok(if self.parse_keyword(Keyword::BTREE) {
IndexType::BTree