1313#include "relation_info.h"
1414#include "utils.h"
1515
16+ #include "catalog/namespace.h"
17+ #include "catalog/pg_type.h"
1618#include "utils/builtins.h"
1719#include "utils/typcache.h"
1820#include "utils/lsyscache.h"
1921#include "utils/builtins.h"
22+ #include "utils/array.h"
2023
2124
2225/* Function declarations */
@@ -29,6 +32,9 @@ PG_FUNCTION_INFO_V1( get_hash_part_idx );
2932PG_FUNCTION_INFO_V1 ( build_hash_condition );
3033
3134
35+ static char * * deconstruct_text_array (Datum arr , int * num_elems );
36+
37+
3238/*
3339 * Create HASH partitions implementation (written in C).
3440 */
@@ -41,6 +47,13 @@ create_hash_partitions_internal(PG_FUNCTION_ARGS)
4147 uint32 part_count = PG_GETARG_INT32 (2 ),
4248 i ;
4349
50+ /* Partitions names and tablespaces */
51+ char * * names = NULL ,
52+ * * tablespaces = NULL ;
53+ int names_size = 0 ,
54+ tablespaces_size = 0 ;
55+ RangeVar * * rangevars = NULL ;
56+
4457 /* Check that there's no partitions yet */
4558 if (get_pathman_relation_info (parent_relid ))
4659 elog (ERROR , "cannot add new HASH partitions" );
@@ -49,16 +62,84 @@ create_hash_partitions_internal(PG_FUNCTION_ARGS)
4962 TextDatumGetCString (partitioned_col_name ),
5063 false);
5164
65+ /* Get partition names and tablespaces */
66+ if (!PG_ARGISNULL (3 ))
67+ names = deconstruct_text_array (PG_GETARG_DATUM (3 ), & names_size );
68+
69+ if (!PG_ARGISNULL (4 ))
70+ tablespaces = deconstruct_text_array (PG_GETARG_DATUM (4 ), & tablespaces_size );
71+
72+ /* Convert partition names into RangeVars */
73+ if (names_size > 0 )
74+ {
75+ rangevars = palloc (sizeof (RangeVar ) * names_size );
76+ for (i = 0 ; i < names_size ; i ++ )
77+ {
78+ List * nl = stringToQualifiedNameList (names [i ]);
79+
80+ rangevars [i ] = makeRangeVarFromNameList (nl );
81+ }
82+ }
83+
5284 for (i = 0 ; i < part_count ; i ++ )
5385 {
86+ RangeVar * rel = rangevars != NULL ? rangevars [i ] : NULL ;
87+ char * tablespace = tablespaces != NULL ? tablespaces [i ] : NULL ;
88+
5489 /* Create a partition (copy FKs, invoke callbacks etc) */
5590 create_single_hash_partition_internal (parent_relid , i , part_count ,
56- partitioned_col_type , NULL , NULL );
91+ partitioned_col_type ,
92+ rel , tablespace );
5793 }
5894
5995 PG_RETURN_VOID ();
6096}
6197
98+ /*
99+ * Convert Datum into cstring array
100+ */
101+ static char * *
102+ deconstruct_text_array (Datum arr , int * num_elems )
103+ {
104+ ArrayType * arrayval ;
105+ int16 elemlen ;
106+ bool elembyval ;
107+ char elemalign ;
108+ Datum * elem_values ;
109+ bool * elem_nulls ;
110+ int16 i ;
111+
112+ arrayval = DatumGetArrayTypeP (arr );
113+
114+ Assert (ARR_ELEMTYPE (arrayval ) == TEXTOID );
115+
116+ get_typlenbyvalalign (ARR_ELEMTYPE (arrayval ),
117+ & elemlen , & elembyval , & elemalign );
118+ deconstruct_array (arrayval ,
119+ ARR_ELEMTYPE (arrayval ),
120+ elemlen , elembyval , elemalign ,
121+ & elem_values , & elem_nulls , num_elems );
122+
123+ /* If there are actual values then convert them into cstrings */
124+ if (num_elems > 0 )
125+ {
126+ char * * strings = palloc (sizeof (char * ) * * num_elems );
127+
128+ for (i = 0 ; i < * num_elems ; i ++ )
129+ {
130+ if (elem_nulls [i ])
131+ elog (ERROR ,
132+ "Partition name and tablespace arrays cannot contain nulls" );
133+
134+ strings [i ] = TextDatumGetCString (elem_values [i ]);
135+ }
136+
137+ return strings ;
138+ }
139+
140+ return NULL ;
141+ }
142+
62143/*
63144 * Returns hash function's OID for a specified type.
64145 */
0 commit comments