29
29
#include "utils/lsyscache.h"
30
30
31
31
32
- static void create_hash_partitions (CreateStmt * stmt , Oid relid , const char * attname );
33
- static void create_range_partitions (CreateStmt * stmt , Oid relid , const char * attname );
32
+ static void create_hash_partitions (PartitionInfo * pinfo ,
33
+ Oid relid ,
34
+ const char * attname ,
35
+ bool partition_data );
36
+ static void create_range_partitions (PartitionInfo * pinfo , Oid relid , const char * attname , bool partition_data );
34
37
static Node * cookPartitionKeyValue (Oid relid , const char * raw , Node * raw_value );
35
38
static char * RangeVarGetString (const RangeVar * rangevar );
36
39
static Oid RangeVarGetNamespaceId (const RangeVar * rangevar );
@@ -40,9 +43,8 @@ static Oid RangeVarGetNamespaceId(const RangeVar *rangevar);
40
43
41
44
42
45
void
43
- create_partitions (CreateStmt * stmt , Oid relid )
46
+ create_partitions (PartitionInfo * pinfo , Oid relid , bool partition_data )
44
47
{
45
- PartitionInfo * pinfo = (PartitionInfo * ) stmt -> partition_info ;
46
48
Value * attname = (Value * ) linitial (((ColumnRef * ) pinfo -> key )-> fields );
47
49
48
50
if (SPI_connect () != SPI_OK_CONNECT )
@@ -52,12 +54,12 @@ create_partitions(CreateStmt *stmt, Oid relid)
52
54
{
53
55
case P_HASH :
54
56
{
55
- create_hash_partitions (stmt , relid , strVal (attname ));
57
+ create_hash_partitions (pinfo , relid , strVal (attname ), partition_data );
56
58
break ;
57
59
}
58
60
case P_RANGE :
59
61
{
60
- create_range_partitions (stmt , relid , strVal (attname ));
62
+ create_range_partitions (pinfo , relid , strVal (attname ), partition_data );
61
63
break ;
62
64
}
63
65
}
@@ -67,11 +69,13 @@ create_partitions(CreateStmt *stmt, Oid relid)
67
69
68
70
69
71
static void
70
- create_hash_partitions (CreateStmt * stmt , Oid relid , const char * attname )
72
+ create_hash_partitions (PartitionInfo * pinfo ,
73
+ Oid relid ,
74
+ const char * attname ,
75
+ bool partition_data )
71
76
{
72
- PartitionInfo * pinfo = (PartitionInfo * ) stmt -> partition_info ;
73
- char * * relnames = NULL ;
74
- char * * tablespaces = NULL ;
77
+ char * * relnames = NULL ;
78
+ char * * tablespaces = NULL ;
75
79
76
80
if (list_length (pinfo -> partitions ) > 0 )
77
81
{
@@ -96,6 +100,7 @@ create_hash_partitions(CreateStmt *stmt, Oid relid, const char* attname)
96
100
pm_create_hash_partitions (relid ,
97
101
attname ,
98
102
pinfo -> partitions_count ,
103
+ partition_data ,
99
104
relnames ,
100
105
tablespaces );
101
106
@@ -112,34 +117,34 @@ create_hash_partitions(CreateStmt *stmt, Oid relid, const char* attname)
112
117
* and all partitions via pg_pathman's wrapper functions
113
118
*/
114
119
static void
115
- create_range_partitions (CreateStmt * stmt , Oid relid , const char * attname )
120
+ create_range_partitions (PartitionInfo * pinfo ,
121
+ Oid relid ,
122
+ const char * attname ,
123
+ bool partition_data )
116
124
{
117
125
ListCell * lc ;
118
126
Datum last_bound = (Datum ) 0 ;
119
127
bool last_bound_is_null = true;
120
- PartitionInfo * pinfo = (PartitionInfo * ) stmt -> partition_info ;
121
128
122
129
/* partitioning key */
123
- AttrNumber attnum = get_attnum (relid , attname );
124
- Oid atttype ;
125
- int32 atttypmod ;
130
+ AttrNumber attnum = get_attnum (relid , attname );
131
+ Oid atttype ;
132
+ int32 atttypmod ;
133
+ Datum start_value ;
126
134
127
135
/* parameters */
128
- Datum interval_datum = (Datum ) 0 ;
129
- Oid interval_type ;
130
-
131
- /* for parsing interval */
132
- Const * interval_const ;
133
- ParseState * pstate = make_parsestate (NULL );
136
+ Datum interval_datum = (Datum ) 0 ;
137
+ Oid interval_type ;
138
+ Const * interval_const ;
139
+ ParseState * pstate = make_parsestate (NULL );
134
140
135
141
if (!attnum )
136
- elog (ERROR ,
137
- "Unknown attribute '%s'" ,
138
- attname );
142
+ elog (ERROR , "Unknown attribute '%s'" , attname );
143
+
139
144
atttype = get_atttype (relid , attnum );
140
145
atttypmod = get_atttypmod (relid , attnum );
141
146
142
- /* Convert interval to Const node */
147
+ /* If interval is set then convert it to a suitable Datum value */
143
148
if (pinfo -> interval != NULL )
144
149
{
145
150
if (IsA (pinfo -> interval , A_Const ))
@@ -152,44 +157,75 @@ create_range_partitions(CreateStmt *stmt, Oid relid, const char *attname)
152
157
else
153
158
elog (ERROR , "Constant interval value is expected" );
154
159
155
- /* If attribute is of type DATE or TIMESTAMP then convert interval to Interval type */
156
- if (atttype == DATEOID || atttype == TIMESTAMPOID || atttype == TIMESTAMPTZOID )
160
+ /*
161
+ * If attribute is of type DATE or TIMESTAMP then convert interval to
162
+ * Interval type
163
+ */
164
+ switch (atttype )
157
165
{
158
- char * interval_literal ;
159
-
160
- /* We should get an UNKNOWN type here */
161
- if (interval_const -> consttype != UNKNOWNOID )
162
- elog (ERROR , "Expected a literal as an interval value" );
163
-
164
- /* Get a text representation of the interval */
165
- interval_literal = DatumGetCString (interval_const -> constvalue );
166
- interval_datum = DirectFunctionCall3 (interval_in ,
167
- CStringGetDatum (interval_literal ),
168
- ObjectIdGetDatum (InvalidOid ),
169
- Int32GetDatum (-1 ));
170
- interval_type = INTERVALOID ;
166
+ case DATEOID :
167
+ case TIMESTAMPOID :
168
+ case TIMESTAMPTZOID :
169
+ {
170
+ char * interval_literal ;
171
+
172
+ /* We should get an UNKNOWN type here */
173
+ if (interval_const -> consttype != UNKNOWNOID )
174
+ elog (ERROR , "Expected a literal as an interval value" );
175
+
176
+ /* Get a text representation of the interval */
177
+ interval_literal = DatumGetCString (interval_const -> constvalue );
178
+ interval_datum = DirectFunctionCall3 (interval_in ,
179
+ CStringGetDatum (interval_literal ),
180
+ ObjectIdGetDatum (InvalidOid ),
181
+ Int32GetDatum (-1 ));
182
+ interval_type = INTERVALOID ;
183
+ }
184
+ break ;
185
+ default :
186
+ interval_datum = interval_const -> constvalue ;
187
+ interval_type = interval_const -> consttype ;
171
188
}
172
- else
189
+ }
190
+ else /* If interval is not set */
191
+ {
192
+ switch (atttype )
173
193
{
174
- interval_datum = interval_const -> constvalue ;
175
- interval_type = interval_const -> consttype ;
194
+ case DATEOID :
195
+ case TIMESTAMPOID :
196
+ case TIMESTAMPTZOID :
197
+ interval_type = INTERVALOID ;
198
+ default :
199
+ interval_type = atttype ;
176
200
}
177
201
}
178
- else /* If interval is not set */
202
+
203
+ /*
204
+ * Start value. It is always non-NULL whenever partition_data = True.
205
+ * Otherwise the actual start value doesn't matter
206
+ */
207
+ Assert ( (pinfo -> start_value != NULL ) == partition_data );
208
+ if (pinfo -> start_value )
179
209
{
180
- if (atttype == DATEOID || atttype == TIMESTAMPOID || atttype == TIMESTAMPTZOID )
181
- interval_type = INTERVALOID ;
182
- else
183
- interval_type = atttype ;
210
+ Node * n = cookPartitionKeyValue (relid ,
211
+ attname ,
212
+ (Node * ) pinfo -> start_value );
213
+ if (!IsA (n , Const ))
214
+ elog (ERROR , "Start value must be a constatnt" );
215
+ start_value = ((Const * ) n )-> constvalue ;
184
216
}
217
+ else
218
+ start_value = (Datum ) 0 ;
185
219
186
220
/* Invoke pg_pathman's wrapper */
187
221
pm_create_range_partitions (relid ,
188
222
attname ,
189
223
atttype ,
224
+ start_value ,
190
225
interval_datum ,
191
226
interval_type ,
192
- pinfo -> interval == NULL );
227
+ pinfo -> interval == NULL ,
228
+ partition_data );
193
229
194
230
/* Add partitions */
195
231
foreach (lc , pinfo -> partitions )
@@ -522,3 +558,9 @@ RangeVarGetNamespaceId(const RangeVar *rangevar)
522
558
523
559
return namespace_id ;
524
560
}
561
+
562
+ void
563
+ partition_existing_table (Oid relid , AlterTableCmd * cmd )
564
+ {
565
+
566
+ }
0 commit comments