@@ -2023,21 +2023,44 @@ impl fmt::Display for DropBehavior {
20232023#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
20242024#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
20252025pub enum UserDefinedTypeRepresentation {
2026+ /// Composite type: `CREATE TYPE name AS (attributes)`
20262027 Composite {
20272028 attributes : Vec < UserDefinedTypeCompositeAttributeDef > ,
20282029 } ,
2030+ /// Enum type: `CREATE TYPE name AS ENUM (labels)`
2031+ ///
20292032 /// Note: this is PostgreSQL-specific. See <https://www.postgresql.org/docs/current/sql-createtype.html>
20302033 Enum { labels : Vec < Ident > } ,
2034+ /// Range type: `CREATE TYPE name AS RANGE (options)`
2035+ ///
2036+ /// Note: this is PostgreSQL-specific. See <https://www.postgresql.org/docs/current/sql-createtype.html>
2037+ Range {
2038+ options : Vec < UserDefinedTypeRangeOption > ,
2039+ } ,
2040+ /// Base type (SQL definition): `CREATE TYPE name (options)`
2041+ ///
2042+ /// Note the lack of `AS` keyword
2043+ ///
2044+ /// Note: this is PostgreSQL-specific. See <https://www.postgresql.org/docs/current/sql-createtype.html>
2045+ SqlDefinition {
2046+ options : Vec < UserDefinedTypeSqlDefinitionOption > ,
2047+ } ,
20312048}
20322049
20332050impl fmt:: Display for UserDefinedTypeRepresentation {
20342051 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
20352052 match self {
2036- UserDefinedTypeRepresentation :: Composite { attributes } => {
2037- write ! ( f, "({})" , display_comma_separated( attributes) )
2053+ Self :: Composite { attributes } => {
2054+ write ! ( f, "AS ({})" , display_comma_separated( attributes) )
2055+ }
2056+ Self :: Enum { labels } => {
2057+ write ! ( f, "AS ENUM ({})" , display_comma_separated( labels) )
20382058 }
2039- UserDefinedTypeRepresentation :: Enum { labels } => {
2040- write ! ( f, "ENUM ({})" , display_comma_separated( labels) )
2059+ Self :: Range { options } => {
2060+ write ! ( f, "AS RANGE ({})" , display_comma_separated( options) )
2061+ }
2062+ Self :: SqlDefinition { options } => {
2063+ write ! ( f, "({})" , display_comma_separated( options) )
20412064 }
20422065 }
20432066 }
@@ -2063,6 +2086,288 @@ impl fmt::Display for UserDefinedTypeCompositeAttributeDef {
20632086 }
20642087}
20652088
2089+ /// Internal length specification for PostgreSQL user-defined base types.
2090+ ///
2091+ /// Specifies the internal length in bytes of the new type's internal representation.
2092+ /// The default assumption is that it is variable-length.
2093+ ///
2094+ /// # PostgreSQL Documentation
2095+ /// See: <https://www.postgresql.org/docs/current/sql-createtype.html>
2096+ ///
2097+ /// # Examples
2098+ /// ```sql
2099+ /// CREATE TYPE mytype (
2100+ /// INPUT = in_func,
2101+ /// OUTPUT = out_func,
2102+ /// INTERNALLENGTH = 16 -- Fixed 16-byte length
2103+ /// );
2104+ ///
2105+ /// CREATE TYPE mytype2 (
2106+ /// INPUT = in_func,
2107+ /// OUTPUT = out_func,
2108+ /// INTERNALLENGTH = VARIABLE -- Variable length
2109+ /// );
2110+ /// ```
2111+ #[ derive( Debug , Copy , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
2112+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
2113+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
2114+ pub enum UserDefinedTypeInternalLength {
2115+ /// Fixed internal length: `INTERNALLENGTH = <number>`
2116+ Fixed ( u64 ) ,
2117+ /// Variable internal length: `INTERNALLENGTH = VARIABLE`
2118+ Variable ,
2119+ }
2120+
2121+ impl fmt:: Display for UserDefinedTypeInternalLength {
2122+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
2123+ match self {
2124+ UserDefinedTypeInternalLength :: Fixed ( n) => write ! ( f, "{}" , n) ,
2125+ UserDefinedTypeInternalLength :: Variable => write ! ( f, "VARIABLE" ) ,
2126+ }
2127+ }
2128+ }
2129+
2130+ /// Alignment specification for PostgreSQL user-defined base types.
2131+ ///
2132+ /// Specifies the storage alignment requirement for values of the data type.
2133+ /// The allowed values equate to alignment on 1, 2, 4, or 8 byte boundaries.
2134+ /// Note that variable-length types must have an alignment of at least 4, since
2135+ /// they necessarily contain an int4 as their first component.
2136+ ///
2137+ /// # PostgreSQL Documentation
2138+ /// See: <https://www.postgresql.org/docs/current/sql-createtype.html>
2139+ ///
2140+ /// # Examples
2141+ /// ```sql
2142+ /// CREATE TYPE mytype (
2143+ /// INPUT = in_func,
2144+ /// OUTPUT = out_func,
2145+ /// ALIGNMENT = int4 -- 4-byte alignment
2146+ /// );
2147+ /// ```
2148+ #[ derive( Debug , Copy , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
2149+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
2150+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
2151+ pub enum Alignment {
2152+ /// Single-byte alignment: `ALIGNMENT = char`
2153+ Char ,
2154+ /// 2-byte alignment: `ALIGNMENT = int2`
2155+ Int2 ,
2156+ /// 4-byte alignment: `ALIGNMENT = int4`
2157+ Int4 ,
2158+ /// 8-byte alignment: `ALIGNMENT = double`
2159+ Double ,
2160+ }
2161+
2162+ impl fmt:: Display for Alignment {
2163+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
2164+ match self {
2165+ Alignment :: Char => write ! ( f, "char" ) ,
2166+ Alignment :: Int2 => write ! ( f, "int2" ) ,
2167+ Alignment :: Int4 => write ! ( f, "int4" ) ,
2168+ Alignment :: Double => write ! ( f, "double" ) ,
2169+ }
2170+ }
2171+ }
2172+
2173+ /// Storage specification for PostgreSQL user-defined base types.
2174+ ///
2175+ /// Specifies the storage strategy for values of the data type:
2176+ /// - `plain`: Prevents compression and out-of-line storage (for fixed-length types)
2177+ /// - `external`: Allows out-of-line storage but not compression
2178+ /// - `extended`: Allows both compression and out-of-line storage (default for most types)
2179+ /// - `main`: Allows compression but discourages out-of-line storage
2180+ ///
2181+ /// # PostgreSQL Documentation
2182+ /// See: <https://www.postgresql.org/docs/current/sql-createtype.html>
2183+ ///
2184+ /// # Examples
2185+ /// ```sql
2186+ /// CREATE TYPE mytype (
2187+ /// INPUT = in_func,
2188+ /// OUTPUT = out_func,
2189+ /// STORAGE = plain
2190+ /// );
2191+ /// ```
2192+ #[ derive( Debug , Copy , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
2193+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
2194+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
2195+ pub enum UserDefinedTypeStorage {
2196+ /// No compression or out-of-line storage: `STORAGE = plain`
2197+ Plain ,
2198+ /// Out-of-line storage allowed, no compression: `STORAGE = external`
2199+ External ,
2200+ /// Both compression and out-of-line storage allowed: `STORAGE = extended`
2201+ Extended ,
2202+ /// Compression allowed, out-of-line discouraged: `STORAGE = main`
2203+ Main ,
2204+ }
2205+
2206+ impl fmt:: Display for UserDefinedTypeStorage {
2207+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
2208+ match self {
2209+ UserDefinedTypeStorage :: Plain => write ! ( f, "plain" ) ,
2210+ UserDefinedTypeStorage :: External => write ! ( f, "external" ) ,
2211+ UserDefinedTypeStorage :: Extended => write ! ( f, "extended" ) ,
2212+ UserDefinedTypeStorage :: Main => write ! ( f, "main" ) ,
2213+ }
2214+ }
2215+ }
2216+
2217+ /// Options for PostgreSQL `CREATE TYPE ... AS RANGE` statement.
2218+ ///
2219+ /// Range types are data types representing a range of values of some element type
2220+ /// (called the range's subtype). These options configure the behavior of the range type.
2221+ ///
2222+ /// # PostgreSQL Documentation
2223+ /// See: <https://www.postgresql.org/docs/current/sql-createtype.html>
2224+ ///
2225+ /// # Examples
2226+ /// ```sql
2227+ /// CREATE TYPE int4range AS RANGE (
2228+ /// SUBTYPE = int4,
2229+ /// SUBTYPE_OPCLASS = int4_ops,
2230+ /// CANONICAL = int4range_canonical,
2231+ /// SUBTYPE_DIFF = int4range_subdiff
2232+ /// );
2233+ /// ```
2234+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
2235+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
2236+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
2237+ pub enum UserDefinedTypeRangeOption {
2238+ /// The element type that the range type will represent: `SUBTYPE = subtype`
2239+ Subtype ( DataType ) ,
2240+ /// The operator class for the subtype: `SUBTYPE_OPCLASS = subtype_operator_class`
2241+ SubtypeOpClass ( ObjectName ) ,
2242+ /// Collation to use for ordering the subtype: `COLLATION = collation`
2243+ Collation ( ObjectName ) ,
2244+ /// Function to convert range values to canonical form: `CANONICAL = canonical_function`
2245+ Canonical ( ObjectName ) ,
2246+ /// Function to compute the difference between two subtype values: `SUBTYPE_DIFF = subtype_diff_function`
2247+ SubtypeDiff ( ObjectName ) ,
2248+ /// Name of the corresponding multirange type: `MULTIRANGE_TYPE_NAME = multirange_type_name`
2249+ MultirangeTypeName ( ObjectName ) ,
2250+ }
2251+
2252+ impl fmt:: Display for UserDefinedTypeRangeOption {
2253+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
2254+ match self {
2255+ UserDefinedTypeRangeOption :: Subtype ( dt) => write ! ( f, "SUBTYPE = {}" , dt) ,
2256+ UserDefinedTypeRangeOption :: SubtypeOpClass ( name) => {
2257+ write ! ( f, "SUBTYPE_OPCLASS = {}" , name)
2258+ }
2259+ UserDefinedTypeRangeOption :: Collation ( name) => write ! ( f, "COLLATION = {}" , name) ,
2260+ UserDefinedTypeRangeOption :: Canonical ( name) => write ! ( f, "CANONICAL = {}" , name) ,
2261+ UserDefinedTypeRangeOption :: SubtypeDiff ( name) => write ! ( f, "SUBTYPE_DIFF = {}" , name) ,
2262+ UserDefinedTypeRangeOption :: MultirangeTypeName ( name) => {
2263+ write ! ( f, "MULTIRANGE_TYPE_NAME = {}" , name)
2264+ }
2265+ }
2266+ }
2267+ }
2268+
2269+ /// Options for PostgreSQL `CREATE TYPE ... (<options>)` statement (base type definition).
2270+ ///
2271+ /// Base types are the lowest-level data types in PostgreSQL. To define a new base type,
2272+ /// you must specify functions that convert it to and from text representation, and optionally
2273+ /// binary representation and other properties.
2274+ ///
2275+ /// Note: This syntax uses parentheses directly after the type name, without the `AS` keyword.
2276+ ///
2277+ /// # PostgreSQL Documentation
2278+ /// See: <https://www.postgresql.org/docs/current/sql-createtype.html>
2279+ ///
2280+ /// # Examples
2281+ /// ```sql
2282+ /// CREATE TYPE complex (
2283+ /// INPUT = complex_in,
2284+ /// OUTPUT = complex_out,
2285+ /// INTERNALLENGTH = 16,
2286+ /// ALIGNMENT = double
2287+ /// );
2288+ /// ```
2289+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
2290+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
2291+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
2292+ pub enum UserDefinedTypeSqlDefinitionOption {
2293+ /// Function to convert from external text representation to internal: `INPUT = input_function`
2294+ Input ( ObjectName ) ,
2295+ /// Function to convert from internal to external text representation: `OUTPUT = output_function`
2296+ Output ( ObjectName ) ,
2297+ /// Function to convert from external binary representation to internal: `RECEIVE = receive_function`
2298+ Receive ( ObjectName ) ,
2299+ /// Function to convert from internal to external binary representation: `SEND = send_function`
2300+ Send ( ObjectName ) ,
2301+ /// Function to convert type modifiers from text array to internal form: `TYPMOD_IN = type_modifier_input_function`
2302+ TypmodIn ( ObjectName ) ,
2303+ /// Function to convert type modifiers from internal to text form: `TYPMOD_OUT = type_modifier_output_function`
2304+ TypmodOut ( ObjectName ) ,
2305+ /// Function to compute statistics for the data type: `ANALYZE = analyze_function`
2306+ Analyze ( ObjectName ) ,
2307+ /// Function to handle subscripting operations: `SUBSCRIPT = subscript_function`
2308+ Subscript ( ObjectName ) ,
2309+ /// Internal storage size in bytes, or VARIABLE for variable-length: `INTERNALLENGTH = { internallength | VARIABLE }`
2310+ InternalLength ( UserDefinedTypeInternalLength ) ,
2311+ /// Indicates values are passed by value rather than by reference: `PASSEDBYVALUE`
2312+ PassedByValue ,
2313+ /// Storage alignment requirement (1, 2, 4, or 8 bytes): `ALIGNMENT = alignment`
2314+ Alignment ( Alignment ) ,
2315+ /// Storage strategy for varlena types: `STORAGE = storage`
2316+ Storage ( UserDefinedTypeStorage ) ,
2317+ /// Copy properties from an existing type: `LIKE = like_type`
2318+ Like ( ObjectName ) ,
2319+ /// Type category for implicit casting rules (single char): `CATEGORY = category`
2320+ Category ( char ) ,
2321+ /// Whether this type is preferred within its category: `PREFERRED = preferred`
2322+ Preferred ( bool ) ,
2323+ /// Default value for the type: `DEFAULT = default`
2324+ Default ( Expr ) ,
2325+ /// Element type for array types: `ELEMENT = element`
2326+ Element ( DataType ) ,
2327+ /// Delimiter character for array value display: `DELIMITER = delimiter`
2328+ Delimiter ( String ) ,
2329+ /// Whether the type supports collation: `COLLATABLE = collatable`
2330+ Collatable ( bool ) ,
2331+ }
2332+
2333+ impl fmt:: Display for UserDefinedTypeSqlDefinitionOption {
2334+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
2335+ match self {
2336+ UserDefinedTypeSqlDefinitionOption :: Input ( name) => write ! ( f, "INPUT = {}" , name) ,
2337+ UserDefinedTypeSqlDefinitionOption :: Output ( name) => write ! ( f, "OUTPUT = {}" , name) ,
2338+ UserDefinedTypeSqlDefinitionOption :: Receive ( name) => write ! ( f, "RECEIVE = {}" , name) ,
2339+ UserDefinedTypeSqlDefinitionOption :: Send ( name) => write ! ( f, "SEND = {}" , name) ,
2340+ UserDefinedTypeSqlDefinitionOption :: TypmodIn ( name) => write ! ( f, "TYPMOD_IN = {}" , name) ,
2341+ UserDefinedTypeSqlDefinitionOption :: TypmodOut ( name) => {
2342+ write ! ( f, "TYPMOD_OUT = {}" , name)
2343+ }
2344+ UserDefinedTypeSqlDefinitionOption :: Analyze ( name) => write ! ( f, "ANALYZE = {}" , name) ,
2345+ UserDefinedTypeSqlDefinitionOption :: Subscript ( name) => {
2346+ write ! ( f, "SUBSCRIPT = {}" , name)
2347+ }
2348+ UserDefinedTypeSqlDefinitionOption :: InternalLength ( len) => {
2349+ write ! ( f, "INTERNALLENGTH = {}" , len)
2350+ }
2351+ UserDefinedTypeSqlDefinitionOption :: PassedByValue => write ! ( f, "PASSEDBYVALUE" ) ,
2352+ UserDefinedTypeSqlDefinitionOption :: Alignment ( align) => {
2353+ write ! ( f, "ALIGNMENT = {}" , align)
2354+ }
2355+ UserDefinedTypeSqlDefinitionOption :: Storage ( storage) => {
2356+ write ! ( f, "STORAGE = {}" , storage)
2357+ }
2358+ UserDefinedTypeSqlDefinitionOption :: Like ( name) => write ! ( f, "LIKE = {}" , name) ,
2359+ UserDefinedTypeSqlDefinitionOption :: Category ( c) => write ! ( f, "CATEGORY = '{}'" , c) ,
2360+ UserDefinedTypeSqlDefinitionOption :: Preferred ( b) => write ! ( f, "PREFERRED = {}" , b) ,
2361+ UserDefinedTypeSqlDefinitionOption :: Default ( expr) => write ! ( f, "DEFAULT = {}" , expr) ,
2362+ UserDefinedTypeSqlDefinitionOption :: Element ( dt) => write ! ( f, "ELEMENT = {}" , dt) ,
2363+ UserDefinedTypeSqlDefinitionOption :: Delimiter ( s) => {
2364+ write ! ( f, "DELIMITER = '{}'" , escape_single_quote_string( s) )
2365+ }
2366+ UserDefinedTypeSqlDefinitionOption :: Collatable ( b) => write ! ( f, "COLLATABLE = {}" , b) ,
2367+ }
2368+ }
2369+ }
2370+
20662371/// PARTITION statement used in ALTER TABLE et al. such as in Hive and ClickHouse SQL.
20672372/// For example, ClickHouse's OPTIMIZE TABLE supports syntax like PARTITION ID 'partition_id' and PARTITION expr.
20682373/// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/optimize)
0 commit comments