Skip to content

Commit a0f38b5

Browse files
committed
Modify range sql scripts according expression use
1 parent ff97121 commit a0f38b5

File tree

10 files changed

+86
-105
lines changed

10 files changed

+86
-105
lines changed

init.sql

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,17 @@ LANGUAGE C;
3333
*/
3434
CREATE TABLE IF NOT EXISTS @extschema@.pathman_config (
3535
partrel REGCLASS NOT NULL PRIMARY KEY,
36-
attname TEXT NOT NULL,
37-
raw_expression TEXT NOT NULL,
38-
atttype OID NOT NULL,
36+
attname TEXT NOT NULL, /* expression */
3937
parttype INTEGER NOT NULL,
4038
range_interval TEXT,
39+
expression_p TEXT NOT NULL, /* parsed expression (until plan) */
40+
atttype OID NOT NULL, /* expression type */
4141

4242
/* check for allowed part types */
43-
CHECK (parttype IN (1, 2))
43+
CHECK (parttype IN (1, 2)),
4444

4545
/* check for correct interval */
46-
CHECK (@extschema@.validate_interval_value(partrel,
47-
atttype,
46+
CHECK (@extschema@.validate_interval_value(atttype,
4847
parttype,
4948
range_interval))
5049
);

range.sql

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,15 @@ BEGIN
132132
/* Check boundaries */
133133
EXECUTE format('SELECT @extschema@.check_boundaries(''%s'', ''%s'', ''%s'', ''%s''::%s)',
134134
parent_relid,
135-
attribute,
135+
expression,
136136
start_value,
137137
end_value,
138138
v_atttype::TEXT);
139139
END IF;
140140

141141
/* Insert new entry to pathman config */
142-
INSERT INTO @extschema@.pathman_config (partrel, attname, parttype, range_interval)
143-
VALUES (parent_relid, attribute, 2, p_interval::TEXT);
142+
PERFORM @extschema@.add_to_pathman_config(parent_relid, expression,
143+
p_interval::TEXT, false);
144144

145145
/* Create sequence for child partitions names */
146146
PERFORM @extschema@.create_or_replace_sequence(parent_relid)
@@ -177,11 +177,11 @@ END
177177
$$ LANGUAGE plpgsql;
178178

179179
/*
180-
* Creates RANGE partitions for specified relation based on numerical attribute
180+
* Creates RANGE partitions for specified relation based on numerical expression
181181
*/
182182
CREATE OR REPLACE FUNCTION @extschema@.create_range_partitions(
183183
parent_relid REGCLASS,
184-
attribute TEXT,
184+
expression TEXT,
185185
start_value ANYELEMENT,
186186
p_interval ANYELEMENT,
187187
p_count INTEGER DEFAULT NULL,
@@ -206,24 +206,24 @@ BEGIN
206206
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
207207
END IF;
208208

209-
attribute := lower(attribute);
210-
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
209+
expression := lower(expression);
210+
PERFORM @extschema@.common_relation_checks(parent_relid, expression);
211211

212212
IF p_count < 0 THEN
213213
RAISE EXCEPTION 'partitions count must not be less than zero';
214214
END IF;
215215

216216
/* Try to determine partitions count if not set */
217217
IF p_count IS NULL THEN
218-
EXECUTE format('SELECT count(*), max(%s) FROM %s', attribute, parent_relid)
218+
EXECUTE format('SELECT count(*), max(%s) FROM %s', expression, parent_relid)
219219
INTO v_rows_count, v_max;
220220

221221
IF v_rows_count = 0 THEN
222222
RAISE EXCEPTION 'cannot determine partitions count for empty table';
223223
END IF;
224224

225225
IF v_max IS NULL THEN
226-
RAISE EXCEPTION 'column "%" has NULL values', attribute;
226+
RAISE EXCEPTION 'expression "%" can return NULL values', expression;
227227
END IF;
228228

229229
p_count := 0;
@@ -248,17 +248,14 @@ BEGIN
248248

249249
/* check boundaries */
250250
PERFORM @extschema@.check_boundaries(parent_relid,
251-
attribute,
251+
expression,
252252
start_value,
253253
end_value);
254254
END IF;
255255

256256
/* Insert new entry to pathman config */
257-
PERFORM @extschema@.add_to_pathman_config(parent_relid, expression, NULL, false);
258-
259-
/* Insert new entry to pathman config */
260-
INSERT INTO @extschema@.pathman_config (partrel, attname, parttype, range_interval)
261-
VALUES (parent_relid, attribute, 2, p_interval::TEXT);
257+
PERFORM @extschema@.add_to_pathman_config(parent_relid, expression,
258+
p_interval::TEXT, false);
262259

263260
/* Create sequence for child partitions names */
264261
PERFORM @extschema@.create_or_replace_sequence(parent_relid)
@@ -296,7 +293,7 @@ $$ LANGUAGE plpgsql;
296293
*/
297294
CREATE OR REPLACE FUNCTION @extschema@.create_partitions_from_range(
298295
parent_relid REGCLASS,
299-
attribute TEXT,
296+
expression TEXT,
300297
start_value ANYELEMENT,
301298
end_value ANYELEMENT,
302299
p_interval ANYELEMENT,
@@ -317,22 +314,22 @@ BEGIN
317314
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
318315
END IF;
319316

320-
attribute := lower(attribute);
321-
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
317+
expression := lower(expression);
318+
PERFORM @extschema@.common_relation_checks(parent_relid, expression);
322319

323320
IF p_interval <= 0 THEN
324321
RAISE EXCEPTION 'interval must be positive';
325322
END IF;
326323

327324
/* Check boundaries */
328325
PERFORM @extschema@.check_boundaries(parent_relid,
329-
attribute,
326+
expression,
330327
start_value,
331328
end_value);
332329

333330
/* Insert new entry to pathman config */
334-
INSERT INTO @extschema@.pathman_config (partrel, attname, parttype, range_interval)
335-
VALUES (parent_relid, attribute, 2, p_interval::TEXT);
331+
PERFORM @extschema@.add_to_pathman_config(parent_relid, expression,
332+
p_interval::TEXT, false);
336333

337334
/* Create sequence for child partitions names */
338335
PERFORM @extschema@.create_or_replace_sequence(parent_relid)
@@ -366,11 +363,11 @@ END
366363
$$ LANGUAGE plpgsql;
367364

368365
/*
369-
* Creates RANGE partitions for specified range based on datetime attribute
366+
* Creates RANGE partitions for specified range based on datetime expression
370367
*/
371368
CREATE OR REPLACE FUNCTION @extschema@.create_partitions_from_range(
372369
parent_relid REGCLASS,
373-
attribute TEXT,
370+
expression TEXT,
374371
start_value ANYELEMENT,
375372
end_value ANYELEMENT,
376373
p_interval INTERVAL,
@@ -391,18 +388,18 @@ BEGIN
391388
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
392389
END IF;
393390

394-
attribute := lower(attribute);
395-
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
391+
expression := lower(expression);
392+
PERFORM @extschema@.common_relation_checks(parent_relid, expression);
396393

397394
/* Check boundaries */
398395
PERFORM @extschema@.check_boundaries(parent_relid,
399-
attribute,
396+
expression,
400397
start_value,
401398
end_value);
402399

403400
/* Insert new entry to pathman config */
404-
INSERT INTO @extschema@.pathman_config (partrel, attname, parttype, range_interval)
405-
VALUES (parent_relid, attribute, 2, p_interval::TEXT);
401+
PERFORM @extschema@.add_to_pathman_config(parent_relid, expression,
402+
p_interval::TEXT, false);
406403

407404
/* Create sequence for child partitions names */
408405
PERFORM @extschema@.create_or_replace_sequence(parent_relid)
@@ -1124,7 +1121,7 @@ SET client_min_messages = WARNING;
11241121
*/
11251122
CREATE OR REPLACE FUNCTION @extschema@.build_range_condition(
11261123
p_relid REGCLASS,
1127-
attribute TEXT,
1124+
expression TEXT,
11281125
start_value ANYELEMENT,
11291126
end_value ANYELEMENT)
11301127
RETURNS TEXT AS 'pg_pathman', 'build_range_condition'

src/include/partition_creation.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Node * build_raw_hash_check_tree(Node *raw_expression,
7575
Oid relid,
7676
Oid value_type);
7777

78-
void drop_check_constraint(Oid relid, AttrNumber attnum);
78+
void drop_check_constraint(Oid relid);
7979

8080
typedef struct
8181
{
@@ -84,10 +84,11 @@ typedef struct
8484
Node *raw_expr;
8585
} PartExpressionInfo;
8686

87-
/* expression parsing functions */
87+
/* Expression parsing functions */
8888
PartExpressionInfo *get_part_expression_info(Oid relid,
8989
const char *expr_string, bool check_hash_func, bool make_plan);
9090

91+
Node *get_raw_expression(Oid relid, const char *expr, char **query_string_out);
9192

9293
/* Partitioning callback type */
9394
typedef enum

src/include/pathman.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@
4646
#define PATHMAN_CONFIG "pathman_config"
4747
#define Natts_pathman_config 6
4848
#define Anum_pathman_config_partrel 1 /* partitioned relation (regclass) */
49-
#define Anum_pathman_config_expression 2 /* partitioned expression (text) */
50-
#define Anum_pathman_config_raw_expression 3 /* partitioned raw expression (text) */
51-
#define Anum_pathman_config_atttype 4 /* partitioned atttype */
52-
#define Anum_pathman_config_parttype 5 /* partitioning type (1|2) */
53-
#define Anum_pathman_config_range_interval 6 /* interval for RANGE pt. (text) */
49+
#define Anum_pathman_config_expression 2 /* partition expression (original) */
50+
#define Anum_pathman_config_parttype 3 /* partitioning type (1|2) */
51+
#define Anum_pathman_config_range_interval 4 /* interval for RANGE pt. (text) */
52+
#define Anum_pathman_config_expression_p 5 /* parsed partition expression (text) */
53+
#define Anum_pathman_config_atttype 6 /* partitioned atttype */
5454

5555
/* type modifier (typmod) for 'range_interval' */
5656
#define PATHMAN_CONFIG_interval_typmod -1

src/include/relation_info.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ typedef struct
127127
Oid *children; /* Oids of child partitions */
128128
RangeEntry *ranges; /* per-partition range entry or NULL */
129129

130+
char *attname; /* original expression */
130131
Node *expr; /* planned expression */
131-
char *expr_string; /* string with original expression */
132132
PartType parttype; /* partitioning type (HASH | RANGE) */
133133
Oid atttype; /* expression type */
134134
int32 atttypmod; /* expression type modifier */
@@ -206,7 +206,6 @@ PrelLastChild(const PartRelationInfo *prel)
206206

207207
const PartRelationInfo *refresh_pathman_relation_info(Oid relid,
208208
Datum *values,
209-
bool *isnull,
210209
bool allow_incomplete);
211210
void invalidate_pathman_relation_info(Oid relid, bool *found);
212211
void remove_pathman_relation_info(Oid relid);

src/init.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ pathman_config_contains_relation(Oid relid, Datum *values, bool *isnull,
712712
/* Perform checks for non-NULL columns */
713713
Assert(!isnull[Anum_pathman_config_partrel - 1]);
714714
Assert(!isnull[Anum_pathman_config_expression - 1]);
715-
Assert(!isnull[Anum_pathman_config_raw_expression - 1]);
715+
Assert(!isnull[Anum_pathman_config_expression_p - 1]);
716716
Assert(!isnull[Anum_pathman_config_parttype - 1]);
717717
}
718718

@@ -827,7 +827,7 @@ read_pathman_config(void)
827827
Assert(!isnull[Anum_pathman_config_partrel - 1]);
828828
Assert(!isnull[Anum_pathman_config_parttype - 1]);
829829
Assert(!isnull[Anum_pathman_config_expression - 1]);
830-
Assert(!isnull[Anum_pathman_config_raw_expression - 1]);
830+
Assert(!isnull[Anum_pathman_config_expression_p - 1]);
831831

832832
/* Extract values from Datums */
833833
relid = DatumGetObjectId(values[Anum_pathman_config_partrel - 1]);
@@ -845,7 +845,6 @@ read_pathman_config(void)
845845
/* get_pathman_relation_info() will refresh this entry */
846846
refresh_pathman_relation_info(relid,
847847
values,
848-
isnull,
849848
true); /* allow lazy prel loading */
850849
}
851850

src/partition_creation.c

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -694,15 +694,11 @@ create_single_partition_internal(Oid parent_relid,
694694
if (expr && expr_type)
695695
{
696696
char *expr_string;
697-
PartExpressionInfo *expr_info;
698697

699698
*expr_type = DatumGetObjectId(config_values[Anum_pathman_config_atttype - 1]);
700-
expr_string = TextDatumGetCString(config_values[Anum_pathman_config_raw_expression - 1]);
701-
expr_info = get_part_expression_info(parent_relid, expr_string, false, false);
702-
703-
*expr = expr_info->raw_expr;
699+
expr_string = TextDatumGetCString(config_values[Anum_pathman_config_expression - 1]);
700+
*expr = get_raw_expression(parent_relid, expr_string, NULL);
704701
pfree(expr_string);
705-
pfree(expr_info);
706702
}
707703

708704
/* Make up parent's RangeVar */
@@ -1120,9 +1116,9 @@ copy_foreign_keys(Oid parent_relid, Oid partition_oid)
11201116
* -----------------------------
11211117
*/
11221118

1123-
/* Drop pg_pathman's check constraint by 'relid' and 'attnum' */
1119+
/* Drop pg_pathman's check constraint by 'relid' */
11241120
void
1125-
drop_check_constraint(Oid relid, AttrNumber attnum)
1121+
drop_check_constraint(Oid relid)
11261122
{
11271123
char *constr_name;
11281124
AlterTableStmt *stmt;
@@ -1689,9 +1685,13 @@ text_to_regprocedure(text *proc_signature)
16891685
}
16901686

16911687
/* Wraps expression by SELECT query and returns parsed tree */
1692-
static Node *
1693-
parse_expression(Oid relid, const char *expr, char **query_string_out)
1688+
Node *
1689+
get_raw_expression(Oid relid, const char *expr, char **query_string_out)
16941690
{
1691+
Node *result;
1692+
SelectStmt *select_stmt;
1693+
ResTarget *target;
1694+
16951695
char *fmt = "SELECT (%s) FROM ONLY %s.%s";
16961696
char *relname = get_rel_name(relid),
16971697
*namespace_name = get_namespace_name(get_rel_namespace(relid));
@@ -1705,7 +1705,10 @@ parse_expression(Oid relid, const char *expr, char **query_string_out)
17051705
{
17061706
*query_string_out = query_string;
17071707
}
1708-
return (Node *)(lfirst(list_head(parsetree_list)));
1708+
select_stmt = (SelectStmt *) lfirst(list_head(parsetree_list));
1709+
target = (ResTarget *) lfirst(list_head(select_stmt->targetList));
1710+
result = (Node *) target->val;
1711+
return result;
17091712
}
17101713

17111714
/*
@@ -1716,34 +1719,27 @@ PartExpressionInfo *
17161719
get_part_expression_info(Oid relid, const char *expr_string,
17171720
bool check_hash_func, bool make_plan)
17181721
{
1719-
Node *parsetree,
1720-
*expr_node,
1721-
*raw_expression;
1722+
Node *expr_node;
17221723
Query *query;
17231724
char *query_string, *out_string;
17241725
PartExpressionInfo *expr_info;
1725-
List *querytree_list,
1726-
*raw_target_list;
1726+
List *querytree_list;
17271727
PlannedStmt *plan;
17281728
TargetEntry *target_entry;
17291729

17301730
expr_info = palloc(sizeof(PartExpressionInfo));
1731-
parsetree = parse_expression(relid, expr_string, &query_string);
1732-
1733-
/* Convert raw expression to string and return it as datum*/
1734-
raw_target_list = ((SelectStmt *)parsetree)->targetList;
1735-
raw_expression = (Node *)(((ResTarget *)(lfirst(list_head(raw_target_list))))->val);
17361731

17371732
/* Keep raw expression */
1738-
expr_info->raw_expr = raw_expression;
1733+
expr_info->raw_expr = get_raw_expression(relid, expr_string, &query_string);
17391734
expr_info->expr_datum = (Datum) 0;
17401735

17411736
/* We don't need pathman activity initialization for this relation yet */
17421737
pathman_hooks_enabled = false;
17431738

17441739
/* This will fail with elog in case of wrong expression
17451740
* with more or less understable text */
1746-
querytree_list = pg_analyze_and_rewrite(parsetree, query_string, NULL, 0);
1741+
querytree_list = pg_analyze_and_rewrite(expr_info->raw_expr,
1742+
query_string, NULL, 0);
17471743
query = (Query *) lfirst(list_head(querytree_list));
17481744

17491745
/* expr_node is node that we need for further use */

0 commit comments

Comments
 (0)