@@ -2697,6 +2697,14 @@ pub struct CreateTable {
26972697 /// <https://www.postgresql.org/docs/current/ddl-inherit.html>
26982698 /// <https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-PARMS-INHERITS>
26992699 pub inherits : Option < Vec < ObjectName > > ,
2700+ /// PostgreSQL `PARTITION OF` clause to create a partition of a parent table.
2701+ /// Contains the parent table name.
2702+ /// <https://www.postgresql.org/docs/current/sql-createtable.html>
2703+ #[ cfg_attr( feature = "visitor" , visit( with = "visit_relation" ) ) ]
2704+ pub partition_of : Option < ObjectName > ,
2705+ /// PostgreSQL partition bound specification for PARTITION OF.
2706+ /// <https://www.postgresql.org/docs/current/sql-createtable.html>
2707+ pub for_values : Option < ForValues > ,
27002708 /// SQLite "STRICT" clause.
27012709 /// if the "STRICT" table-option keyword is added to the end, after the closing ")",
27022710 /// then strict typing rules apply to that table.
@@ -2792,6 +2800,9 @@ impl fmt::Display for CreateTable {
27922800 dynamic = if self . dynamic { "DYNAMIC " } else { "" } ,
27932801 name = self . name,
27942802 ) ?;
2803+ if let Some ( partition_of) = & self . partition_of {
2804+ write ! ( f, " PARTITION OF {partition_of}" ) ?;
2805+ }
27952806 if let Some ( on_cluster) = & self . on_cluster {
27962807 write ! ( f, " ON CLUSTER {on_cluster}" ) ?;
27972808 }
@@ -2806,12 +2817,19 @@ impl fmt::Display for CreateTable {
28062817 Indent ( DisplayCommaSeparated ( & self . constraints ) ) . fmt ( f) ?;
28072818 NewLine . fmt ( f) ?;
28082819 f. write_str ( ")" ) ?;
2809- } else if self . query . is_none ( ) && self . like . is_none ( ) && self . clone . is_none ( ) {
2820+ } else if self . query . is_none ( )
2821+ && self . like . is_none ( )
2822+ && self . clone . is_none ( )
2823+ && self . partition_of . is_none ( )
2824+ {
28102825 // PostgreSQL allows `CREATE TABLE t ();`, but requires empty parens
28112826 f. write_str ( " ()" ) ?;
28122827 } else if let Some ( CreateTableLikeKind :: Parenthesized ( like_in_columns_list) ) = & self . like {
28132828 write ! ( f, " ({like_in_columns_list})" ) ?;
28142829 }
2830+ if let Some ( for_values) = & self . for_values {
2831+ write ! ( f, " {for_values}" ) ?;
2832+ }
28152833
28162834 // Hive table comment should be after column definitions, please refer to:
28172835 // [Hive](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-CreateTable)
@@ -3053,6 +3071,76 @@ impl fmt::Display for CreateTable {
30533071 }
30543072}
30553073
3074+ /// PostgreSQL partition bound specification for PARTITION OF.
3075+ ///
3076+ /// Specifies partition bounds for a child partition table.
3077+ ///
3078+ /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createtable.html)
3079+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
3080+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
3081+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
3082+ pub enum ForValues {
3083+ /// `FOR VALUES IN (expr, ...)`
3084+ In ( Vec < Expr > ) ,
3085+ /// `FOR VALUES FROM (expr|MINVALUE|MAXVALUE, ...) TO (expr|MINVALUE|MAXVALUE, ...)`
3086+ From {
3087+ from : Vec < PartitionBoundValue > ,
3088+ to : Vec < PartitionBoundValue > ,
3089+ } ,
3090+ /// `FOR VALUES WITH (MODULUS n, REMAINDER r)`
3091+ With { modulus : u64 , remainder : u64 } ,
3092+ /// `DEFAULT`
3093+ Default ,
3094+ }
3095+
3096+ impl fmt:: Display for ForValues {
3097+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
3098+ match self {
3099+ ForValues :: In ( values) => {
3100+ write ! ( f, "FOR VALUES IN ({})" , display_comma_separated( values) )
3101+ }
3102+ ForValues :: From { from, to } => {
3103+ write ! (
3104+ f,
3105+ "FOR VALUES FROM ({}) TO ({})" ,
3106+ display_comma_separated( from) ,
3107+ display_comma_separated( to)
3108+ )
3109+ }
3110+ ForValues :: With { modulus, remainder } => {
3111+ write ! (
3112+ f,
3113+ "FOR VALUES WITH (MODULUS {modulus}, REMAINDER {remainder})"
3114+ )
3115+ }
3116+ ForValues :: Default => write ! ( f, "DEFAULT" ) ,
3117+ }
3118+ }
3119+ }
3120+
3121+ /// A value in a partition bound specification.
3122+ ///
3123+ /// Used in RANGE partition bounds where values can be expressions,
3124+ /// MINVALUE (negative infinity), or MAXVALUE (positive infinity).
3125+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
3126+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
3127+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
3128+ pub enum PartitionBoundValue {
3129+ Expr ( Expr ) ,
3130+ MinValue ,
3131+ MaxValue ,
3132+ }
3133+
3134+ impl fmt:: Display for PartitionBoundValue {
3135+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
3136+ match self {
3137+ PartitionBoundValue :: Expr ( expr) => write ! ( f, "{expr}" ) ,
3138+ PartitionBoundValue :: MinValue => write ! ( f, "MINVALUE" ) ,
3139+ PartitionBoundValue :: MaxValue => write ! ( f, "MAXVALUE" ) ,
3140+ }
3141+ }
3142+ }
3143+
30563144#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
30573145#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
30583146#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
0 commit comments