Skip to content

Commit bf826d2

Browse files
committed
Add partial support (creation) of expression based partitions
1 parent ceecae3 commit bf826d2

20 files changed

+693
-230
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ regression.out
1010
*.gcno
1111
*.gcov
1212
pg_pathman--*.sql
13+
tags
14+
cscope*

hash.sql

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ BEGIN
3535
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
3636

3737
/* Insert new entry to pathman config */
38-
INSERT INTO @extschema@.pathman_config (partrel, attname, parttype)
39-
VALUES (parent_relid, attribute, 1);
38+
PERFORM @extschema@.add_to_pathman_config(parent_relid, attribute);
4039

4140
/* Create partitions */
4241
PERFORM @extschema@.create_hash_partitions_internal(parent_relid,
@@ -48,13 +47,13 @@ BEGIN
4847
/* Notify backend about changes */
4948
PERFORM @extschema@.on_create_partitions(parent_relid);
5049

51-
/* Copy data */
50+
/* Copy data
5251
IF partition_data = true THEN
5352
PERFORM @extschema@.set_enable_parent(parent_relid, false);
5453
PERFORM @extschema@.partition_data(parent_relid);
5554
ELSE
5655
PERFORM @extschema@.set_enable_parent(parent_relid, true);
57-
END IF;
56+
END IF; */
5857

5958
RETURN partitions_count;
6059
END
@@ -299,14 +298,3 @@ LANGUAGE C STRICT;
299298
CREATE OR REPLACE FUNCTION @extschema@.get_hash_part_idx(INTEGER, INTEGER)
300299
RETURNS INTEGER AS 'pg_pathman', 'get_hash_part_idx'
301300
LANGUAGE C STRICT;
302-
303-
/*
304-
* Build hash condition for a CHECK CONSTRAINT
305-
*/
306-
CREATE OR REPLACE FUNCTION @extschema@.build_hash_condition(
307-
attribute_type REGTYPE,
308-
attribute TEXT,
309-
partitions_count INT4,
310-
partitions_index INT4)
311-
RETURNS TEXT AS 'pg_pathman', 'build_hash_condition'
312-
LANGUAGE C STRICT;

init.sql

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ LANGUAGE C;
3535
CREATE TABLE IF NOT EXISTS @extschema@.pathman_config (
3636
partrel REGCLASS NOT NULL PRIMARY KEY,
3737
attname TEXT NOT NULL,
38+
atttype OID NOT NULL,
3839
parttype INTEGER NOT NULL,
3940
range_interval TEXT,
4041

@@ -427,7 +428,7 @@ LANGUAGE plpgsql STRICT;
427428
*/
428429
CREATE OR REPLACE FUNCTION @extschema@.common_relation_checks(
429430
relation REGCLASS,
430-
p_attribute TEXT)
431+
expression TEXT)
431432
RETURNS BOOLEAN AS
432433
$$
433434
DECLARE
@@ -450,8 +451,8 @@ BEGIN
450451
RAISE EXCEPTION 'relation "%" has already been partitioned', relation;
451452
END IF;
452453

453-
IF @extschema@.is_attribute_nullable(relation, p_attribute) THEN
454-
RAISE EXCEPTION 'partitioning key "%" must be NOT NULL', p_attribute;
454+
IF NOT @extschema@.is_expression_suitable(relation, expression) THEN
455+
RAISE EXCEPTION 'partitioning expression "%" is not suitable', expression;
455456
END IF;
456457

457458
/* Check if there are foreign keys that reference the relation */
@@ -467,7 +468,7 @@ BEGIN
467468
RAISE EXCEPTION 'relation "%" is referenced from other relations', relation;
468469
END IF;
469470

470-
RETURN TRUE;
471+
RETURN FALSE;
471472
END
472473
$$
473474
LANGUAGE plpgsql;
@@ -796,6 +797,15 @@ CREATE OR REPLACE FUNCTION @extschema@.is_attribute_nullable(
796797
RETURNS BOOLEAN AS 'pg_pathman', 'is_attribute_nullable'
797798
LANGUAGE C STRICT;
798799

800+
/*
801+
* Checks if expression is suitable
802+
*/
803+
CREATE OR REPLACE FUNCTION @extschema@.is_expression_suitable(
804+
relid REGCLASS,
805+
expr TEXT)
806+
RETURNS BOOLEAN AS 'pg_pathman', 'is_expression_suitable'
807+
LANGUAGE C STRICT;
808+
799809
/*
800810
* Check if regclass is date or timestamp.
801811
*/

sql/pathman_basic.sql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ CREATE TABLE test.hash_rel (
1111
INSERT INTO test.hash_rel VALUES (1, 1);
1212
INSERT INTO test.hash_rel VALUES (2, 2);
1313
INSERT INTO test.hash_rel VALUES (3, 3);
14-
SELECT pathman.create_hash_partitions('test.hash_rel', 'value', 3);
14+
:gdb
15+
SELECT pg_sleep(10);
16+
SELECT pathman.create_hash_partitions('test.hash_rel', 'value + 1', 3);
1517
ALTER TABLE test.hash_rel ALTER COLUMN value SET NOT NULL;
1618
SELECT pathman.create_hash_partitions('test.hash_rel', 'value', 3, partition_data:=false);
1719
EXPLAIN (COSTS OFF) SELECT * FROM test.hash_rel;

src/hooks.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,10 +255,11 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
255255
int32 type_mod;
256256
TypeCacheEntry *tce;
257257

258-
/* Make Var from partition column */
259-
get_rte_attribute_type(rte, prel->attnum,
258+
/* Make Var from patition column */
259+
/* FIX: this */
260+
get_rte_attribute_type(rte, 0,
260261
&vartypeid, &type_mod, &varcollid);
261-
var = makeVar(rti, prel->attnum, vartypeid, type_mod, varcollid, 0);
262+
var = makeVar(rti, 0, vartypeid, type_mod, varcollid, 0);
262263
var->location = -1;
263264

264265
/* Determine operator type */

src/include/init.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ void unload_config(void);
132132

133133
void fill_prel_with_partitions(const Oid *partitions,
134134
const uint32 parts_count,
135-
const char *part_column_name,
136135
PartRelationInfo *prel);
137136

138137
/* Result of find_inheritance_children_array() */
@@ -149,11 +148,9 @@ find_children_status find_inheritance_children_array(Oid parentrelId,
149148
uint32 *children_size,
150149
Oid **children);
151150

152-
char *build_check_constraint_name_relid_internal(Oid relid,
153-
AttrNumber attno);
151+
char *build_check_constraint_name_relid_internal(Oid relid);
154152

155-
char *build_check_constraint_name_relname_internal(const char *relname,
156-
AttrNumber attno);
153+
char *build_check_constraint_name_relname_internal(const char *relname);
157154

158155
char *build_sequence_name_internal(Oid relid);
159156

src/include/partition_creation.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,24 @@ bool check_range_available(Oid parent_relid,
6666

6767
/* HASH constraints */
6868
Constraint * build_hash_check_constraint(Oid child_relid,
69-
char *attname,
69+
const char *expr,
7070
uint32 part_idx,
7171
uint32 part_count,
7272
Oid value_type);
7373

74-
Node * build_raw_hash_check_tree(char *attname,
74+
Node * build_raw_hash_check_tree(const char *base_expr,
7575
uint32 part_idx,
76-
uint32 part_count, Oid value_type);
76+
uint32 part_count,
77+
Oid relid,
78+
Oid value_type);
7779

7880
void drop_check_constraint(Oid relid, AttrNumber attnum);
7981

82+
/* expression parsing functions */
83+
Node *get_expression_node(Oid relid, const char *expr, bool analyze);
84+
Oid get_partition_expr_type(Oid relid, const char *expr);
85+
86+
8087

8188
/* Partitioning callback type */
8289
typedef enum

src/include/partition_filter.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
#endif
2626

2727

28-
#define ERR_PART_ATTR_NULL "partitioned column's value should not be NULL"
28+
#define ERR_PART_ATTR_NULL "partition expression's value should not be NULL"
29+
#define ERR_PART_ATTR_MULTIPLE_RESULTS \
30+
"partition expression's value should be single, not set"
2931
#define ERR_PART_ATTR_NO_PART "no suitable partition for key '%s'"
3032
#define ERR_PART_ATTR_MULTIPLE "PartitionFilter selected more than one partition"
3133

src/include/pathman.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "rangeset.h"
1717

1818
#include "postgres.h"
19+
#include "fmgr.h"
1920
#include "nodes/makefuncs.h"
2021
#include "nodes/primnodes.h"
2122
#include "nodes/execnodes.h"
@@ -43,11 +44,12 @@
4344
* Definitions for the "pathman_config" table.
4445
*/
4546
#define PATHMAN_CONFIG "pathman_config"
46-
#define Natts_pathman_config 4
47+
#define Natts_pathman_config 5
4748
#define Anum_pathman_config_partrel 1 /* partitioned relation (regclass) */
4849
#define Anum_pathman_config_attname 2 /* partitioned column (text) */
49-
#define Anum_pathman_config_parttype 3 /* partitioning type (1|2) */
50-
#define Anum_pathman_config_range_interval 4 /* interval for RANGE pt. (text) */
50+
#define Anum_pathman_config_atttype 3 /* partitioned atttype */
51+
#define Anum_pathman_config_parttype 4 /* partitioning type (1|2) */
52+
#define Anum_pathman_config_range_interval 5 /* interval for RANGE pt. (text) */
5153

5254
/* type modifier (typmod) for 'range_interval' */
5355
#define PATHMAN_CONFIG_interval_typmod -1

src/include/relation_info.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include "postgres.h"
1616
#include "access/attnum.h"
1717
#include "fmgr.h"
18+
#include "nodes/nodes.h"
19+
#include "nodes/primnodes.h"
1820
#include "port/atomics.h"
1921
#include "storage/lock.h"
2022
#include "utils/datum.h"
@@ -126,9 +128,9 @@ typedef struct
126128
RangeEntry *ranges; /* per-partition range entry or NULL */
127129

128130
PartType parttype; /* partitioning type (HASH | RANGE) */
129-
AttrNumber attnum; /* partitioned column's index */
130-
Oid atttype; /* partitioned column's type */
131-
int32 atttypmod; /* partitioned column type modifier */
131+
Expr *expr;
132+
Oid atttype; /* expression type */
133+
int32 atttypmod; /* expression type modifier */
132134
bool attbyval; /* is partitioned column stored by value? */
133135
int16 attlen; /* length of the partitioned column's type */
134136
int attalign; /* alignment of the part column's type */
@@ -191,8 +193,8 @@ PrelLastChild(const PartRelationInfo *prel)
191193

192194

193195
const PartRelationInfo *refresh_pathman_relation_info(Oid relid,
194-
PartType partitioning_type,
195-
const char *part_column_name,
196+
Datum *values,
197+
bool *isnull,
196198
bool allow_incomplete);
197199
void invalidate_pathman_relation_info(Oid relid, bool *found);
198200
void remove_pathman_relation_info(Oid relid);

0 commit comments

Comments
 (0)