STET

agent_patch

runs/2026-02-28__18-27-22__gpt-5-3-codex/flux-pr-1747/flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/agent-logs/agent.patch

44850 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/ast/dml.rs b/app/src/ast/dml.rs
index 9cdb1ca..665df4e 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/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 create_table_options: Vec<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,18 +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}")?;
+        for option in &self.create_table_options {
+            write!(f, " {option}")?;
         }
         if let Some(comment_def) = &self.comment {
             match comment_def {
@@ -401,9 +386,6 @@ impl Display for CreateTable {
             }
         }
 
-        if let Some(auto_increment_offset) = self.auto_increment_offset {
-            write!(f, " AUTO_INCREMENT {auto_increment_offset}")?;
-        }
         if let Some(primary_key) = &self.primary_key {
             write!(f, " PRIMARY KEY {}", primary_key)?;
         }
@@ -503,13 +485,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-3-codex/app/src/ast/helpers/stmt_create_table.rs b/app/src/ast/helpers/stmt_create_table.rs
index 1c50cb8..e03f845 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/ast/helpers/stmt_create_table.rs
+++ b/app/src/ast/helpers/stmt_create_table.rs
@@ -26,9 +26,10 @@ 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 +77,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 create_table_options: Vec<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>>,
@@ -131,19 +127,14 @@ impl CreateTableBuilder {
             constraints: vec![],
             hive_distribution: HiveDistributionStyle::NONE,
             hive_formats: None,
-            table_properties: vec![],
-            with_options: vec![],
+            create_table_options: vec![],
             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,
@@ -230,13 +221,8 @@ impl CreateTableBuilder {
         self
     }
 
-    pub fn table_properties(mut self, table_properties: Vec<SqlOption>) -> Self {
-        self.table_properties = table_properties;
-        self
-    }
-
-    pub fn with_options(mut self, with_options: Vec<SqlOption>) -> Self {
-        self.with_options = with_options;
+    pub fn create_table_options(mut self, create_table_options: Vec<CreateTableOptions>) -> Self {
+        self.create_table_options = create_table_options;
         self
     }
     pub fn file_format(mut self, file_format: Option<FileFormat>) -> Self {
@@ -268,31 +254,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
@@ -437,19 +403,14 @@ 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,
+            create_table_options: self.create_table_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 +460,14 @@ impl TryFrom<Statement> for CreateTableBuilder {
                 constraints,
                 hive_distribution,
                 hive_formats,
-                table_properties,
-                with_options,
+                create_table_options,
                 file_format,
                 location,
                 query,
                 without_rowid,
                 like,
                 clone,
-                engine,
                 comment,
-                auto_increment_offset,
-                default_charset,
-                collation,
                 on_commit,
                 on_cluster,
                 primary_key,
@@ -548,19 +504,14 @@ impl TryFrom<Statement> for CreateTableBuilder {
                 constraints,
                 hive_distribution,
                 hive_formats,
-                table_properties,
-                with_options,
+                create_table_options,
                 file_format,
                 location,
                 query,
                 without_rowid,
                 like,
                 clone,
-                engine,
                 comment,
-                auto_increment_offset,
-                default_charset,
-                collation,
                 on_commit,
                 on_cluster,
                 primary_key,
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/ast/mod.rs b/app/src/ast/mod.rs
index 582922a..76a59a3 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/ast/mod.rs
+++ b/app/src/ast/mod.rs
@@ -2662,6 +2662,12 @@ impl fmt::Display for Declare {
 #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
 pub enum CreateTableOptions {
     None,
+    /// MySQL / ClickHouse-style options specified as a space-separated list.
+    /// e.g. `ENGINE=InnoDB AUTO_INCREMENT=1`
+    Plain(Vec<SqlOption>),
+    /// Hive-style options specified using the `TBLPROPERTIES` keyword.
+    /// e.g. `TBLPROPERTIES ('k'='v')`
+    TblProperties(Vec<SqlOption>),
     /// Options specified using the `WITH` keyword.
     /// e.g. `WITH (description = "123")`
     ///
@@ -2686,6 +2692,12 @@ pub enum CreateTableOptions {
 impl fmt::Display for CreateTableOptions {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
+            CreateTableOptions::Plain(options) => {
+                write!(f, "{}", display_separated(options, " "))
+            }
+            CreateTableOptions::TblProperties(table_properties) => {
+                write!(f, "TBLPROPERTIES ({})", display_comma_separated(table_properties))
+            }
             CreateTableOptions::With(with_options) => {
                 write!(f, "WITH ({})", display_comma_separated(with_options))
             }
@@ -7549,6 +7561,19 @@ pub enum SqlOption {
     ///
     ///   WITH(DISTRIBUTION = ROUND_ROBIN)
     KeyValue { key: Ident, value: Expr },
+    /// Engine option for MySQL / ClickHouse.
+    /// e.g. `ENGINE=MergeTree(...)`
+    Engine(TableEngine),
+    /// MySQL `AUTO_INCREMENT [=] <value>`.
+    AutoIncrement(u32),
+    /// MySQL `DEFAULT CHARSET=<value>`.
+    DefaultCharset(String),
+    /// MySQL `COLLATE=<value>`.
+    Collate(String),
+    /// MySQL `TABLESPACE <value>`.
+    Tablespace(ObjectName),
+    /// COMMENT option. Used by dialects that model comment as a table option.
+    Comment(CommentDef),
     /// One or more table partitions and represents which partition the boundary values belong to,
     /// e.g.
     ///
@@ -7572,6 +7597,17 @@ impl fmt::Display for SqlOption {
             SqlOption::KeyValue { key: name, value } => {
                 write!(f, "{} = {}", name, value)
             }
+            SqlOption::Engine(engine) => write!(f, "ENGINE={engine}"),
+            SqlOption::AutoIncrement(value) => write!(f, "AUTO_INCREMENT {value}"),
+            SqlOption::DefaultCharset(charset) => write!(f, "DEFAULT CHARSET={charset}"),
+            SqlOption::Collate(collation) => write!(f, "COLLATE={collation}"),
+            SqlOption::Tablespace(tablespace) => write!(f, "TABLESPACE {tablespace}"),
+            SqlOption::Comment(comment) => match comment {
+                CommentDef::WithEq(comment) => write!(f, "COMMENT = '{comment}'"),
+                CommentDef::WithoutEq(comment) | CommentDef::AfterColumnDefsWithoutEq(comment) => {
+                    write!(f, "COMMENT '{comment}'")
+                }
+            },
             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-3-codex/app/src/ast/spans.rs b/app/src/ast/spans.rs
index 836f229..df6bb8a 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/ast/spans.rs
+++ b/app/src/ast/spans.rs
@@ -567,19 +567,14 @@ impl Spanned for CreateTable {
             constraints,
             hive_distribution: _, // hive specific
             hive_formats: _,      // hive specific
-            table_properties,
-            with_options,
+            create_table_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
@@ -610,8 +605,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(create_table_options.iter().map(|i| i.span()))
                 .chain(query.iter().map(|i| i.span()))
                 .chain(like.iter().map(|i| i.span()))
                 .chain(clone.iter().map(|i| i.span())),
@@ -997,6 +991,12 @@ 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::AutoIncrement(_) => Span::empty(),
+            SqlOption::DefaultCharset(_) => Span::empty(),
+            SqlOption::Collate(_) => Span::empty(),
+            SqlOption::Tablespace(object_name) => object_name.span(),
+            SqlOption::Comment(_) => Span::empty(),
             SqlOption::Partition {
                 column_name,
                 range_direction: _,
@@ -1039,6 +1039,8 @@ impl Spanned for CreateTableOptions {
     fn span(&self) -> Span {
         match self {
             CreateTableOptions::None => Span::empty(),
+            CreateTableOptions::Plain(vec) => union_spans(vec.iter().map(|i| i.span())),
+            CreateTableOptions::TblProperties(vec) => union_spans(vec.iter().map(|i| i.span())),
             CreateTableOptions::With(vec) => union_spans(vec.iter().map(|i| i.span())),
             CreateTableOptions::Options(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-3-codex/app/src/parser/mod.rs b/app/src/parser/mod.rs
index cbd464c..7ed6c31 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/parser/mod.rs
+++ b/app/src/parser/mod.rs
@@ -5524,12 +5524,16 @@ impl<'a> Parser<'a> {
         };
         let location = hive_formats.location.clone();
         let table_properties = self.parse_options(Keyword::TBLPROPERTIES)?;
+        let mut create_table_options = vec![];
+        if !table_properties.is_empty() {
+            create_table_options.push(CreateTableOptions::TblProperties(table_properties));
+        }
         Ok(CreateTableBuilder::new(table_name)
             .columns(columns)
             .constraints(constraints)
             .hive_distribution(hive_distribution)
             .hive_formats(Some(hive_formats))
-            .table_properties(table_properties)
+            .create_table_options(create_table_options)
             .or_replace(or_replace)
             .if_not_exists(if_not_exists)
             .external(true)
@@ -7059,39 +7063,11 @@ 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()?;
-        // PostgreSQL supports `WITH ( options )`, before `AS`
-        let with_options = self.parse_options(Keyword::WITH)?;
-        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
-        };
+        // Parse table options in source order.
+        let mut create_table_options = vec![];
+        while let Some(option) = self.parse_optional_create_table_option()? {
+            create_table_options.push(option);
+        }
 
         // ClickHouse supports `PRIMARY KEY`, before `ORDER BY`
         // https://clickhouse.com/docs/en/sql-reference/statements/create/table#primary-key
@@ -7121,27 +7097,9 @@ 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
-        };
+        while let Some(option) = self.parse_optional_create_table_option()? {
+            create_table_options.push(option);
+        }
 
         let on_commit = if self.parse_keywords(&[Keyword::ON, Keyword::COMMIT]) {
             Some(self.parse_create_table_on_commit()?)
@@ -7174,8 +7132,7 @@ impl<'a> Parser<'a> {
             .temporary(temporary)
             .columns(columns)
             .constraints(constraints)
-            .with_options(with_options)
-            .table_properties(table_properties)
+            .create_table_options(create_table_options)
             .or_replace(or_replace)
             .if_not_exists(if_not_exists)
             .transient(transient)
@@ -7186,12 +7143,8 @@ 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)
@@ -7219,6 +7172,83 @@ impl<'a> Parser<'a> {
         }
     }
 
+    fn parse_optional_create_table_option(
+        &mut self,
+    ) -> Result<Option<CreateTableOptions>, ParserError> {
+        if let Some(with_options) = self.maybe_parse_options(Keyword::WITH)? {
+            return Ok(Some(CreateTableOptions::With(with_options)));
+        }
+        if let Some(table_properties) = self.maybe_parse_options(Keyword::TBLPROPERTIES)? {
+            return Ok(Some(CreateTableOptions::TblProperties(table_properties)));
+        }
+        if self.parse_keyword(Keyword::ENGINE) {
+            self.expect_token(&Token::Eq)?;
+            let next_token = self.next_token();
+            let engine = 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
+                    };
+                    TableEngine { name, parameters }
+                }
+                _ => self.expected("identifier", next_token)?,
+            };
+            return Ok(Some(CreateTableOptions::Plain(vec![SqlOption::Engine(engine)])));
+        }
+        if self.parse_keyword(Keyword::AUTO_INCREMENT) {
+            let _ = self.consume_token(&Token::Eq);
+            let next_token = self.next_token();
+            let value = match next_token.token {
+                Token::Number(s, _) => Self::parse::<u32>(s, next_token.span.start)?,
+                _ => self.expected("literal int", next_token)?,
+            };
+            return Ok(Some(CreateTableOptions::Plain(vec![
+                SqlOption::AutoIncrement(value),
+            ])));
+        }
+        if self.parse_keywords(&[Keyword::DEFAULT, Keyword::CHARSET]) {
+            self.expect_token(&Token::Eq)?;
+            let next_token = self.next_token();
+            let value = match next_token.token {
+                Token::Word(w) => w.value,
+                _ => self.expected("identifier", next_token)?,
+            };
+            return Ok(Some(CreateTableOptions::Plain(vec![
+                SqlOption::DefaultCharset(value),
+            ])));
+        }
+        if self.parse_keyword(Keyword::COLLATE) {
+            self.expect_token(&Token::Eq)?;
+            let next_token = self.next_token();
+            let value = match next_token.token {
+                Token::Word(w) => w.value,
+                _ => self.expected("identifier", next_token)?,
+            };
+            return Ok(Some(CreateTableOptions::Plain(vec![SqlOption::Collate(value)])));
+        }
+        if dialect_of!(self is MySqlDialect | GenericDialect) && self.parse_keyword(Keyword::COMMENT)
+        {
+            self.prev_token();
+            if let Some(comment) = self.parse_optional_inline_comment()? {
+                return Ok(Some(CreateTableOptions::Plain(vec![SqlOption::Comment(
+                    comment,
+                )])));
+            }
+        }
+        if let Token::Word(word) = self.peek_token().token {
+            if word.value.eq_ignore_ascii_case("TABLESPACE") {
+                self.next_token();
+                return Ok(Some(CreateTableOptions::Plain(vec![SqlOption::Tablespace(
+                    self.parse_object_name(false)?,
+                )])));
+            }
+        }
+        Ok(None)
+    }
+
     /// Parse configuration like inheritance, partitioning, clustering information during the table creation.
     ///
     /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_2)
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_clickhouse.rs b/app/tests/sqlparser_clickhouse.rs
index c56f988..b3fbb52 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_clickhouse.rs
+++ b/app/tests/sqlparser_clickhouse.rs
@@ -721,7 +721,7 @@ fn parse_create_table_with_primary_key() {
         Statement::CreateTable(CreateTable {
             name,
             columns,
-            engine,
+            create_table_options,
             primary_key,
             order_by,
             ..
@@ -743,14 +743,16 @@ fn parse_create_table_with_primary_key() {
                 columns
             );
             assert_eq!(
-                engine,
-                Some(TableEngine {
-                    name: "SharedMergeTree".to_string(),
-                    parameters: Some(vec![
-                        Ident::with_quote('\'', "/clickhouse/tables/{uuid}/{shard}"),
-                        Ident::with_quote('\'', "{replica}"),
-                    ]),
-                })
+                create_table_options,
+                vec![CreateTableOptions::Plain(vec![SqlOption::Engine(
+                    TableEngine {
+                        name: "SharedMergeTree".to_string(),
+                        parameters: Some(vec![
+                            Ident::with_quote('\'', "/clickhouse/tables/{uuid}/{shard}"),
+                            Ident::with_quote('\'', "{replica}"),
+                        ]),
+                    }
+                )])]
             );
             fn assert_function(actual: &Function, name: &str, arg: &str) -> bool {
                 assert_eq!(actual.name, ObjectName::from(vec![Ident::new(name)]));
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_common.rs b/app/tests/sqlparser_common.rs
index 1ddf3f9..fe4c2a1 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_common.rs
+++ b/app/tests/sqlparser_common.rs
@@ -3657,7 +3657,7 @@ fn parse_create_table() {
             name,
             columns,
             constraints,
-            with_options,
+            create_table_options,
             if_not_exists: false,
             external: false,
             file_format: None,
@@ -3795,7 +3795,7 @@ fn parse_create_table() {
                     },
                 ]
             );
-            assert_eq!(with_options, vec![]);
+            assert_eq!(create_table_options, vec![]);
         }
         _ => unreachable!(),
     }
@@ -3840,7 +3840,7 @@ fn parse_create_table_with_constraint_characteristics() {
             name,
             columns,
             constraints,
-            with_options,
+            create_table_options,
             if_not_exists: false,
             external: false,
             file_format: None,
@@ -3934,7 +3934,7 @@ fn parse_create_table_with_constraint_characteristics() {
                     },
                 ]
             );
-            assert_eq!(with_options, vec![]);
+            assert_eq!(create_table_options, vec![]);
         }
         _ => unreachable!(),
     }
@@ -4421,9 +4421,12 @@ fn parse_create_table_with_options() {
 
     let sql = "CREATE TABLE t (c INT) WITH (foo = 'bar', a = 123)";
     match generic.verified_stmt(sql) {
-        Statement::CreateTable(CreateTable { with_options, .. }) => {
+        Statement::CreateTable(CreateTable {
+            create_table_options,
+            ..
+        }) => {
             assert_eq!(
-                vec![
+                vec![CreateTableOptions::With(vec![
                     SqlOption::KeyValue {
                         key: "foo".into(),
                         value: Expr::Value(
@@ -4434,8 +4437,8 @@ fn parse_create_table_with_options() {
                         key: "a".into(),
                         value: Expr::value(number("123")),
                     },
-                ],
-                with_options
+                ])],
+                create_table_options
             );
         }
         _ => unreachable!(),
@@ -4482,7 +4485,7 @@ fn parse_create_external_table() {
             name,
             columns,
             constraints,
-            with_options,
+            create_table_options,
             if_not_exists,
             external,
             file_format,
@@ -4525,7 +4528,7 @@ fn parse_create_external_table() {
             assert_eq!(FileFormat::TEXTFILE, file_format.unwrap());
             assert_eq!("/tmp/example.csv", location.unwrap());
 
-            assert_eq!(with_options, vec![]);
+            assert_eq!(create_table_options, vec![]);
             assert!(!if_not_exists);
         }
         _ => unreachable!(),
@@ -4550,7 +4553,7 @@ fn parse_create_or_replace_external_table() {
             name,
             columns,
             constraints,
-            with_options,
+            create_table_options,
             if_not_exists,
             external,
             file_format,
@@ -4579,7 +4582,7 @@ fn parse_create_or_replace_external_table() {
             assert_eq!(FileFormat::TEXTFILE, file_format.unwrap());
             assert_eq!("/tmp/example.csv", location.unwrap());
 
-            assert_eq!(with_options, vec![]);
+            assert_eq!(create_table_options, vec![]);
             assert!(!if_not_exists);
             assert!(or_replace);
         }
@@ -4784,12 +4787,12 @@ fn parse_alter_view() {
             name,
             columns,
             query,
-            with_options,
+            create_table_options,
         } => {
             assert_eq!("myschema.myview", name.to_string());
             assert_eq!(Vec::<Ident>::new(), columns);
             assert_eq!("SELECT foo FROM bar", query.to_string());
-            assert_eq!(with_options, vec![]);
+            assert_eq!(create_table_options, vec![]);
         }
         _ => unreachable!(),
     }
@@ -4828,12 +4831,12 @@ fn parse_alter_view_with_columns() {
             name,
             columns,
             query,
-            with_options,
+            create_table_options,
         } => {
             assert_eq!("v", name.to_string());
             assert_eq!(columns, vec![Ident::new("has"), Ident::new("cols")]);
             assert_eq!("SELECT 1, 2", query.to_string());
-            assert_eq!(with_options, vec![]);
+            assert_eq!(create_table_options, vec![]);
         }
         _ => unreachable!(),
     }
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_duckdb.rs b/app/tests/sqlparser_duckdb.rs
index 3205832..8220466 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_duckdb.rs
+++ b/app/tests/sqlparser_duckdb.rs
@@ -735,19 +735,14 @@ fn test_duckdb_union_datatype() {
                 storage: Default::default(),
                 location: Default::default()
             }),
-            table_properties: Default::default(),
-            with_options: Default::default(),
+            create_table_options: Default::default(),
             file_format: Default::default(),
             location: Default::default(),
             query: Default::default(),
             without_rowid: Default::default(),
             like: Default::default(),
             clone: Default::default(),
-            engine: Default::default(),
             comment: Default::default(),
-            auto_increment_offset: Default::default(),
-            default_charset: Default::default(),
-            collation: Default::default(),
             on_commit: Default::default(),
             on_cluster: Default::default(),
             primary_key: Default::default(),
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_mssql.rs b/app/tests/sqlparser_mssql.rs
index 88e7a1f..4da0d1b 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_mssql.rs
+++ b/app/tests/sqlparser_mssql.rs
@@ -1747,19 +1747,14 @@ fn parse_create_table_with_valid_options() {
                     storage: None,
                     location: None,
                 },),
-                table_properties: vec![],
-                with_options,
+                create_table_options: vec![CreateTableOptions::With(with_options)],
                 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,
@@ -1918,19 +1913,14 @@ fn parse_create_table_with_identity_column() {
                     storage: None,
                     location: None,
                 },),
-                table_properties: vec![],
-                with_options: vec![],
+                create_table_options: vec![],
                 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,
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_mysql.rs b/app/tests/sqlparser_mysql.rs
index 990107b..3497c7c 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_mysql.rs
+++ b/app/tests/sqlparser_mysql.rs
@@ -848,9 +848,22 @@ fn parse_create_table_comment() {
 
     for sql in [without_equal, with_equal] {
         match mysql().verified_stmt(sql) {
-            Statement::CreateTable(CreateTable { name, comment, .. }) => {
+            Statement::CreateTable(CreateTable {
+                name,
+                create_table_options,
+                ..
+            }) => {
                 assert_eq!(name.to_string(), "foo");
-                assert_eq!(comment.expect("Should exist").to_string(), "baz");
+                assert_eq!(
+                    create_table_options,
+                    vec![CreateTableOptions::Plain(vec![SqlOption::Comment(
+                        if sql.contains(" = ") {
+                            CommentDef::WithEq("baz".to_string())
+                        } else {
+                            CommentDef::WithoutEq("baz".to_string())
+                        }
+                    )])]
+                );
             }
             _ => unreachable!(),
         }
@@ -868,13 +881,19 @@ fn parse_create_table_auto_increment_offset() {
         match mysql().one_statement_parses_to(sql, canonical) {
             Statement::CreateTable(CreateTable {
                 name,
-                auto_increment_offset,
+                create_table_options,
                 ..
             }) => {
                 assert_eq!(name.to_string(), "foo");
                 assert_eq!(
-                    auto_increment_offset.expect("Should exist").to_string(),
-                    "123"
+                    create_table_options,
+                    vec![
+                        CreateTableOptions::Plain(vec![SqlOption::Engine(TableEngine {
+                            name: "InnoDB".to_string(),
+                            parameters: None,
+                        })]),
+                        CreateTableOptions::Plain(vec![SqlOption::AutoIncrement(123)]),
+                    ]
                 );
             }
             _ => unreachable!(),
@@ -921,8 +940,7 @@ fn parse_create_table_engine_default_charset() {
         Statement::CreateTable(CreateTable {
             name,
             columns,
-            engine,
-            default_charset,
+            create_table_options,
             ..
         }) => {
             assert_eq!(name.to_string(), "foo");
@@ -935,13 +953,17 @@ fn parse_create_table_engine_default_charset() {
                 columns
             );
             assert_eq!(
-                engine,
-                Some(TableEngine {
-                    name: "InnoDB".to_string(),
-                    parameters: None
-                })
+                create_table_options,
+                vec![
+                    CreateTableOptions::Plain(vec![SqlOption::Engine(TableEngine {
+                        name: "InnoDB".to_string(),
+                        parameters: None,
+                    })]),
+                    CreateTableOptions::Plain(vec![SqlOption::DefaultCharset(
+                        "utf8mb3".to_string(),
+                    )]),
+                ]
             );
-            assert_eq!(default_charset, Some("utf8mb3".to_string()));
         }
         _ => unreachable!(),
     }
@@ -954,7 +976,7 @@ fn parse_create_table_collate() {
         Statement::CreateTable(CreateTable {
             name,
             columns,
-            collation,
+            create_table_options,
             ..
         }) => {
             assert_eq!(name.to_string(), "foo");
@@ -966,7 +988,12 @@ fn parse_create_table_collate() {
                 },],
                 columns
             );
-            assert_eq!(collation, Some("utf8mb4_0900_ai_ci".to_string()));
+            assert_eq!(
+                create_table_options,
+                vec![CreateTableOptions::Plain(vec![SqlOption::Collate(
+                    "utf8mb4_0900_ai_ci".to_string()
+                )])]
+            );
         }
         _ => unreachable!(),
     }
@@ -978,12 +1005,26 @@ fn parse_create_table_both_options_and_as_query() {
     match mysql_and_generic().verified_stmt(sql) {
         Statement::CreateTable(CreateTable {
             name,
-            collation,
+            create_table_options,
             query,
             ..
         }) => {
             assert_eq!(name.to_string(), "foo");
-            assert_eq!(collation, Some("utf8mb4_0900_ai_ci".to_string()));
+            assert_eq!(
+                create_table_options,
+                vec![
+                    CreateTableOptions::Plain(vec![SqlOption::Engine(TableEngine {
+                        name: "InnoDB".to_string(),
+                        parameters: None,
+                    })]),
+                    CreateTableOptions::Plain(vec![SqlOption::DefaultCharset(
+                        "utf8mb3".to_string(),
+                    )]),
+                    CreateTableOptions::Plain(vec![SqlOption::Collate(
+                        "utf8mb4_0900_ai_ci".to_string(),
+                    )]),
+                ]
+            );
             assert_eq!(
                 query.unwrap().body.as_select().unwrap().projection,
                 vec![SelectItem::UnnamedExpr(Expr::Value(
@@ -1001,6 +1042,39 @@ fn parse_create_table_both_options_and_as_query() {
     ));
 }
 
+#[test]
+fn parse_create_table_options_any_order() {
+    let sql = "CREATE TABLE foo (id INT) COLLATE=utf8mb4_0900_ai_ci DEFAULT CHARSET=utf8mb3 ENGINE=InnoDB COMMENT 'x' AUTO_INCREMENT=3";
+    let canonical = "CREATE TABLE foo (id INT) COLLATE=utf8mb4_0900_ai_ci DEFAULT CHARSET=utf8mb3 ENGINE=InnoDB COMMENT 'x' AUTO_INCREMENT 3";
+    match mysql().one_statement_parses_to(sql, canonical) {
+        Statement::CreateTable(CreateTable {
+            create_table_options,
+            ..
+        }) => {
+            assert_eq!(
+                create_table_options,
+                vec![
+                    CreateTableOptions::Plain(vec![SqlOption::Collate(
+                        "utf8mb4_0900_ai_ci".to_string(),
+                    )]),
+                    CreateTableOptions::Plain(vec![SqlOption::DefaultCharset(
+                        "utf8mb3".to_string(),
+                    )]),
+                    CreateTableOptions::Plain(vec![SqlOption::Engine(TableEngine {
+                        name: "InnoDB".to_string(),
+                        parameters: None,
+                    })]),
+                    CreateTableOptions::Plain(vec![SqlOption::Comment(CommentDef::WithoutEq(
+                        "x".to_string(),
+                    ))]),
+                    CreateTableOptions::Plain(vec![SqlOption::AutoIncrement(3)]),
+                ]
+            );
+        }
+        _ => unreachable!(),
+    }
+}
+
 #[test]
 fn parse_create_table_comment_character_set() {
     let sql = "CREATE TABLE foo (s TEXT CHARACTER SET utf8mb4 COMMENT 'comment')";
diff --git a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_postgres.rs b/app/tests/sqlparser_postgres.rs
index 6c008c8..3141ce4 100644
--- a/tmp/agent-patch-flux-pr-1747.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_postgres.rs
+++ b/app/tests/sqlparser_postgres.rs
@@ -4668,7 +4668,7 @@ fn parse_create_table_with_alias() {
             name,
             columns,
             constraints,
-            with_options: _with_options,
+            create_table_options: _create_table_options,
             if_not_exists: false,
             external: false,
             file_format: None,
@@ -5078,9 +5078,12 @@ fn parse_at_time_zone() {
 fn parse_create_table_with_options() {
     let sql = "CREATE TABLE t (c INT) WITH (foo = 'bar', a = 123)";
     match pg().verified_stmt(sql) {
-        Statement::CreateTable(CreateTable { with_options, .. }) => {
+        Statement::CreateTable(CreateTable {
+            create_table_options,
+            ..
+        }) => {
             assert_eq!(
-                vec![
+                vec![CreateTableOptions::With(vec![
                     SqlOption::KeyValue {
                         key: "foo".into(),
                         value: Expr::Value(
@@ -5091,8 +5094,8 @@ fn parse_create_table_with_options() {
                         key: "a".into(),
                         value: Expr::value(number("123")),
                     },
-                ],
-                with_options
+                ])],
+                create_table_options
             );
         }
         _ => unreachable!(),
@@ -5506,19 +5509,14 @@ fn parse_trigger_related_functions() {
                 storage: None,
                 location: None
             }),
-            table_properties: vec![],
-            with_options: vec![],
+            create_table_options: vec![],
             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,