This is an automated email from the ASF dual-hosted git repository.

iffyio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new 896c0881 Add support for `INHERITS` option in `CREATE TABLE` statement 
(#1806)
896c0881 is described below

commit 896c088153ac340d18d027ea0c56cd89f794146b
Author: Luca Cappelletti <[email protected]>
AuthorDate: Sat Apr 12 18:03:43 2025 +0200

    Add support for `INHERITS` option in `CREATE TABLE` statement (#1806)
---
 src/ast/dml.rs                       |  8 ++++++++
 src/ast/helpers/stmt_create_table.rs | 11 +++++++++++
 src/ast/spans.rs                     |  1 +
 src/keywords.rs                      |  1 +
 src/parser/mod.rs                    | 13 +++++++++++--
 tests/sqlparser_duckdb.rs            |  1 +
 tests/sqlparser_mssql.rs             |  2 ++
 tests/sqlparser_postgres.rs          | 36 ++++++++++++++++++++++++++++++++++++
 8 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/src/ast/dml.rs b/src/ast/dml.rs
index ccea7fbc..9cdb1ca8 100644
--- a/src/ast/dml.rs
+++ b/src/ast/dml.rs
@@ -182,6 +182,11 @@ pub struct CreateTable {
     /// BigQuery: Table options list.
     /// 
<https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list>
     pub options: Option<Vec<SqlOption>>,
+    /// Postgres `INHERITs` clause, which contains the list of tables from 
which
+    /// the new table inherits.
+    /// <https://www.postgresql.org/docs/current/ddl-inherit.html>
+    /// 
<https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-PARMS-INHERITS>
+    pub inherits: Option<Vec<ObjectName>>,
     /// SQLite "STRICT" clause.
     /// if the "STRICT" table-option keyword is added to the end, after the 
closing ")",
     /// then strict typing rules apply to that table.
@@ -405,6 +410,9 @@ impl Display for CreateTable {
         if let Some(order_by) = &self.order_by {
             write!(f, " ORDER BY {}", order_by)?;
         }
+        if let Some(inherits) = &self.inherits {
+            write!(f, " INHERITS ({})", display_comma_separated(inherits))?;
+        }
         if let Some(partition_by) = self.partition_by.as_ref() {
             write!(f, " PARTITION BY {partition_by}")?;
         }
diff --git a/src/ast/helpers/stmt_create_table.rs 
b/src/ast/helpers/stmt_create_table.rs
index 344e9dec..1c50cb84 100644
--- a/src/ast/helpers/stmt_create_table.rs
+++ b/src/ast/helpers/stmt_create_table.rs
@@ -97,6 +97,7 @@ pub struct CreateTableBuilder {
     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,
     pub enable_schema_evolution: Option<bool>,
@@ -151,6 +152,7 @@ impl CreateTableBuilder {
             cluster_by: None,
             clustered_by: None,
             options: None,
+            inherits: None,
             strict: false,
             copy_grants: false,
             enable_schema_evolution: None,
@@ -331,6 +333,11 @@ impl CreateTableBuilder {
         self
     }
 
+    pub fn inherits(mut self, inherits: Option<Vec<ObjectName>>) -> Self {
+        self.inherits = inherits;
+        self
+    }
+
     pub fn strict(mut self, strict: bool) -> Self {
         self.strict = strict;
         self
@@ -451,6 +458,7 @@ impl CreateTableBuilder {
             cluster_by: self.cluster_by,
             clustered_by: self.clustered_by,
             options: self.options,
+            inherits: self.inherits,
             strict: self.strict,
             copy_grants: self.copy_grants,
             enable_schema_evolution: self.enable_schema_evolution,
@@ -512,6 +520,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
                 cluster_by,
                 clustered_by,
                 options,
+                inherits,
                 strict,
                 copy_grants,
                 enable_schema_evolution,
@@ -560,6 +569,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
                 cluster_by,
                 clustered_by,
                 options,
+                inherits,
                 strict,
                 iceberg,
                 copy_grants,
@@ -591,6 +601,7 @@ pub(crate) struct CreateTableConfiguration {
     pub partition_by: Option<Box<Expr>>,
     pub cluster_by: Option<WrappedCollection<Vec<Ident>>>,
     pub options: Option<Vec<SqlOption>>,
+    pub inherits: Option<Vec<ObjectName>>,
 }
 
 #[cfg(test)]
diff --git a/src/ast/spans.rs b/src/ast/spans.rs
index 31a036b1..23034151 100644
--- a/src/ast/spans.rs
+++ b/src/ast/spans.rs
@@ -581,6 +581,7 @@ impl Spanned for CreateTable {
             cluster_by: _,                      // todo, BigQuery specific
             clustered_by: _,                    // todo, Hive specific
             options: _,                         // todo, BigQuery specific
+            inherits: _,                        // todo, PostgreSQL specific
             strict: _,                          // bool
             copy_grants: _,                     // bool
             enable_schema_evolution: _,         // bool
diff --git a/src/keywords.rs b/src/keywords.rs
index 0b947b61..fb273409 100644
--- a/src/keywords.rs
+++ b/src/keywords.rs
@@ -430,6 +430,7 @@ define_keywords!(
     INDEX,
     INDICATOR,
     INHERIT,
+    INHERITS,
     INITIALLY,
     INNER,
     INOUT,
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 0ccf10d7..c4bec1d5 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -7050,6 +7050,7 @@ impl<'a> Parser<'a> {
             .partition_by(create_table_config.partition_by)
             .cluster_by(create_table_config.cluster_by)
             .options(create_table_config.options)
+            .inherits(create_table_config.inherits)
             .primary_key(primary_key)
             .strict(strict)
             .build())
@@ -7070,13 +7071,20 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parse configuration like partitioning, clustering information during 
the table creation.
+    /// 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)
-    /// 
[PostgreSQL](https://www.postgresql.org/docs/current/ddl-partitioning.html)
+    /// [PostgreSQL 
Partitioning](https://www.postgresql.org/docs/current/ddl-partitioning.html)
+    /// [PostgreSQL 
Inheritance](https://www.postgresql.org/docs/current/ddl-inherit.html)
     fn parse_optional_create_table_config(
         &mut self,
     ) -> Result<CreateTableConfiguration, ParserError> {
+        let inherits = if self.parse_keyword(Keyword::INHERITS) {
+            
Some(self.parse_parenthesized_qualified_column_list(IsOptional::Mandatory, 
false)?)
+        } else {
+            None
+        };
+
         let partition_by = if dialect_of!(self is BigQueryDialect | 
PostgreSqlDialect | GenericDialect)
             && self.parse_keywords(&[Keyword::PARTITION, Keyword::BY])
         {
@@ -7105,6 +7113,7 @@ impl<'a> Parser<'a> {
             partition_by,
             cluster_by,
             options,
+            inherits,
         })
     }
 
diff --git a/tests/sqlparser_duckdb.rs b/tests/sqlparser_duckdb.rs
index a421154a..32058324 100644
--- a/tests/sqlparser_duckdb.rs
+++ b/tests/sqlparser_duckdb.rs
@@ -756,6 +756,7 @@ fn test_duckdb_union_datatype() {
             cluster_by: Default::default(),
             clustered_by: Default::default(),
             options: Default::default(),
+            inherits: Default::default(),
             strict: Default::default(),
             copy_grants: Default::default(),
             enable_schema_evolution: Default::default(),
diff --git a/tests/sqlparser_mssql.rs b/tests/sqlparser_mssql.rs
index bcaf527c..44fd01f1 100644
--- a/tests/sqlparser_mssql.rs
+++ b/tests/sqlparser_mssql.rs
@@ -1594,6 +1594,7 @@ fn parse_create_table_with_valid_options() {
                 cluster_by: None,
                 clustered_by: None,
                 options: None,
+                inherits: None,
                 strict: false,
                 iceberg: false,
                 copy_grants: false,
@@ -1764,6 +1765,7 @@ fn parse_create_table_with_identity_column() {
                 cluster_by: None,
                 clustered_by: None,
                 options: None,
+                inherits: None,
                 strict: false,
                 copy_grants: false,
                 enable_schema_evolution: None,
diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs
index a6d65ec7..098d4b1c 100644
--- a/tests/sqlparser_postgres.rs
+++ b/tests/sqlparser_postgres.rs
@@ -2733,6 +2733,41 @@ fn parse_create_brin() {
     }
 }
 
+#[test]
+fn parse_create_table_with_inherits() {
+    let single_inheritance_sql =
+        "CREATE TABLE child_table (child_column INT) INHERITS 
(public.parent_table)";
+    match pg().verified_stmt(single_inheritance_sql) {
+        Statement::CreateTable(CreateTable {
+            inherits: Some(inherits),
+            ..
+        }) => {
+            assert_eq_vec(&["public", "parent_table"], &inherits[0].0);
+        }
+        _ => unreachable!(),
+    }
+
+    let double_inheritance_sql = "CREATE TABLE child_table (child_column INT) 
INHERITS (public.parent_table, pg_catalog.pg_settings)";
+    match pg().verified_stmt(double_inheritance_sql) {
+        Statement::CreateTable(CreateTable {
+            inherits: Some(inherits),
+            ..
+        }) => {
+            assert_eq_vec(&["public", "parent_table"], &inherits[0].0);
+            assert_eq_vec(&["pg_catalog", "pg_settings"], &inherits[1].0);
+        }
+        _ => unreachable!(),
+    }
+}
+
+#[test]
+fn parse_create_table_with_empty_inherits_fails() {
+    assert!(matches!(
+        pg().parse_sql_statements("CREATE TABLE child_table (child_column INT) 
INHERITS ()"),
+        Err(ParserError::ParserError(_))
+    ));
+}
+
 #[test]
 fn parse_create_index_concurrently() {
     let sql = "CREATE INDEX CONCURRENTLY IF NOT EXISTS my_index ON 
my_table(col1,col2)";
@@ -5426,6 +5461,7 @@ fn parse_trigger_related_functions() {
             cluster_by: None,
             clustered_by: None,
             options: None,
+            inherits: None,
             strict: false,
             copy_grants: false,
             enable_schema_evolution: None,


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to