Skip to content

Conversation

@fmguerreiro
Copy link

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 partition
CREATE TABLE t PARTITION OF parent FOR VALUES FROM ('2023-01-01') TO ('2024-01-01');

-- RANGE with MINVALUE/MAXVALUE
CREATE TABLE t PARTITION OF parent FOR VALUES FROM (MINVALUE) TO ('2020-01-01');

-- LIST partition
CREATE TABLE t PARTITION OF parent FOR VALUES IN ('US', 'CA', 'MX');

-- HASH partition
CREATE TABLE t PARTITION OF parent FOR VALUES WITH (MODULUS 4, REMAINDER 0);

-- DEFAULT partition
CREATE TABLE t PARTITION OF parent DEFAULT;

-- Multi-column range
CREATE TABLE t PARTITION OF parent FOR VALUES FROM ('2023-01-01', 1) TO ('2023-04-01', 1);

-- With table constraints
CREATE TABLE t PARTITION OF parent (
    CONSTRAINT check_date CHECK (order_date >= '2023-01-01')
) FOR VALUES FROM ('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 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
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 = if dialect_of!(self is PostgreSqlDialect | GenericDialect)
&& self.parse_keywords(&[Keyword::PARTITION, Keyword::OF])
let partition_of = if self.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

}
}

/// Parse a single partition bound value (MINVALUE, MAXVALUE, or expression).
Copy link
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].

}
}

/// PostgreSQL partition bound specification for PARTITION OF.
Copy link
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`.

Comment on lines +8014 to +8016
/// Parse PostgreSQL partition bound specification for PARTITION OF.
///
/// Parses: `FOR VALUES partition_bound_spec | DEFAULT`
Copy link
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.

Sign up for free to 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