Skip to content

Add PostgreSQL PARTITION OF syntax support - #2127

Merged
iffyio merged 10 commits into
apache:mainfrom
fmguerreiro:partition-of-support
Jan 6, 2026
Merged

Add PostgreSQL PARTITION OF syntax support#2127
iffyio merged 10 commits into
apache:mainfrom
fmguerreiro:partition-of-support

Conversation

@fmguerreiro

Copy link
Copy Markdown
Contributor

Summary

This PR adds support for PostgreSQL's CREATE TABLE ... PARTITION OF syntax for creating child partition tables.

Closes#2042

Changes

  • Added MODULUS and REMAINDER keywords to src/keywords.rs
  • Added ForValues enum and PartitionBoundValue enum to src/ast/ddl.rs with Display implementations
  • Added partition_of and for_values fields to CreateTable struct
  • Updated CreateTableBuilder in src/ast/helpers/stmt_create_table.rs
  • Added parser logic in src/parser/mod.rs for PARTITION OF, FOR VALUES IN/FROM/TO/WITH, and DEFAULT
  • Updated src/ast/spans.rs to include new fields
  • Exported new types from src/ast/mod.rs
  • Added 7 comprehensive tests in tests/sqlparser_postgres.rs

Supported Syntax

-- RANGE partitionCREATETABLEt PARTITION OF parent FOR VALUESFROM ('2023-01-01') TO ('2024-01-01');
-- RANGE with MINVALUE/MAXVALUECREATETABLEt PARTITION OF parent FOR VALUESFROM (MINVALUE) TO ('2020-01-01');
-- LIST partitionCREATETABLEt PARTITION OF parent FOR VALUESIN ('US', 'CA', 'MX');
-- HASH partitionCREATETABLEt PARTITION OF parent FOR VALUES WITH (MODULUS 4, REMAINDER 0);
-- DEFAULT partitionCREATETABLEt PARTITION OF parent DEFAULT;
-- Multi-column rangeCREATETABLEt PARTITION OF parent FOR VALUESFROM ('2023-01-01', 1) TO ('2023-04-01', 1);
-- With table constraintsCREATETABLEt PARTITION OF parent (
CONSTRAINT check_date CHECK (order_date >='2023-01-01')
) FOR VALUESFROM ('2023-01-01') TO ('2024-01-01');

Testing

  • All 7 new partition tests pass
  • All 1312 existing tests pass (no regressions)
  • cargo fmt passes
  • Works with both PostgreSqlDialect and GenericDialect as required

Comment threadsrc/parser/mod.rs Outdated
Comment on lines +7836 to +7838
// PostgreSQL PARTITION OF for child partition tables
let partition_of = if dialect_of!(self is PostgreSqlDialect | GenericDialect)
&& self.parse_keywords(&[Keyword::PARTITION, Keyword::OF])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// PostgreSQL PARTITION OF for child partition tables
let partition_of = ifdialect_of!(self is PostgreSqlDialect | GenericDialect)
&&self.parse_keywords(&[Keyword::PARTITION,Keyword::OF])
let partition_of = ifself.parse_keywords(&[Keyword::PARTITION,Keyword::OF])

If possible we can skiip the dialect check and let the parser accept the PARTITION OF clause whenever it shows up in an input sql

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment threadsrc/parser/mod.rs Outdated
}
}

/// Parse a single partition bound value (MINVALUE, MAXVALUE, or expression).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Parse a single partition bound value (MINVALUE, MAXVALUE, or expression).
/// Parse a single [PartitionBoundValue].

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment threadsrc/ast/ddl.rs Outdated
}
}

/// PostgreSQL partition bound specification for PARTITION OF.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// PostgreSQL partition bound specification for PARTITION OF.
/// PostgreSQL partition bound specification for `PARTITION OF`.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment threadsrc/parser/mod.rs Outdated
Comment on lines +8014 to +8016
/// Parse PostgreSQL partition bound specification for PARTITION OF.
///
/// Parses: `FOR VALUES partition_bound_spec | DEFAULT`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Parse PostgreSQL partition bound specification for PARTITION OF.
///
/// Parses: `FOR VALUES partition_bound_spec | DEFAULT`
/// Parse [ForValues] of a `PARTITION OF` clause.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iffyio

Copy link
Copy Markdown
Contributor

just in case @fmguerreiro please feel free to re-request review when ready

Comment threadtests/sqlparser_postgres.rs Outdated
Box::new(PostgreSqlDialect {}),
Box::new(MySqlDialect {}),
Box::new(SQLiteDialect {}),
]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the intent is to test all dialects I think the test could live in sqlparser_common.rs and shouldn't explicitly list the dialects rather it can use all_dialects() - if the syntax conflicts across dialects (thinking probably snowflake for example) then I would suggest we just skip this test and rely on the pg_and_generic coverage after all

@fmguerreirofmguerreiroDec 19, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true, removed f74fd1a

@fmguerreiro
fmguerreiroforce-pushed the partition-of-support branch 2 times, most recently from d85fe74 to 690091cCompareDecember 25, 2025 07:21

@iffyioiffyio left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks @fmguerreiro!

@iffyio
iffyio added this pull request to the merge queueJan 6, 2026
Merged via the queue into apache:main with commit 4de1ac9Jan 6, 2026
10 checks passed
ayman-sigma pushed a commit to sigmacomputing/sqlparser-rs that referenced this pull request Feb 3, 2026
fmguerreiro added a commit to fmguerreiro/datafusion-sqlparser-rs that referenced this pull request Feb 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Postgres partitioning "CREATE TABLE ... PARTITION OF" unparseable

2 participants

@fmguerreiro@iffyio