Skip to content

Commit 01ef629

Browse files
committed
further refactoring and improvements (new function is_pathman_related_table_rename(), remove redundant function get_rel_parent()
1 parent fa6f4c1 commit 01ef629

File tree

9 files changed

+120
-108
lines changed

9 files changed

+120
-108
lines changed

expected/pathman_utility_stmt_hooking.out

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,16 @@ Inherits: rename.test
220220
CREATE OR REPLACE FUNCTION add_constraint(rel regclass, att text)
221221
RETURNS VOID AS $$
222222
declare
223-
constraint_name text := build_check_constraint_name(rel, 'a');
223+
constraint_name text := build_check_constraint_name(rel, 'a');
224224
BEGIN
225-
EXECUTE format('ALTER TABLE %s ADD CONSTRAINT %s CHECK (a < 100);',
226-
rel, constraint_name);
225+
EXECUTE format('ALTER TABLE %s ADD CONSTRAINT %s CHECK (a < 100);',
226+
rel, constraint_name);
227227
END
228228
$$
229229
LANGUAGE plpgsql;
230230
/*
231-
* Check that it doesn't affect regular inherited tables that aren't managed
232-
* by pg_pathman
231+
* Check that it doesn't affect regular inherited
232+
* tables that aren't managed by pg_pathman
233233
*/
234234
CREATE TABLE rename.test_inh (LIKE rename.test INCLUDING ALL);
235235
CREATE TABLE rename.test_inh_1 (LIKE rename.test INCLUDING ALL);

sql/pathman_utility_stmt_hooking.sql

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ SELECT * FROM copy_stmt_hooking.test ORDER BY val;
9393

9494
DROP SCHEMA copy_stmt_hooking CASCADE;
9595

96+
9697
/*
9798
* Test auto check constraint renaming
9899
*/
@@ -108,17 +109,17 @@ ALTER TABLE rename.test_0 RENAME TO test_one;
108109
CREATE OR REPLACE FUNCTION add_constraint(rel regclass, att text)
109110
RETURNS VOID AS $$
110111
declare
111-
constraint_name text := build_check_constraint_name(rel, 'a');
112+
constraint_name text := build_check_constraint_name(rel, 'a');
112113
BEGIN
113-
EXECUTE format('ALTER TABLE %s ADD CONSTRAINT %s CHECK (a < 100);',
114-
rel, constraint_name);
114+
EXECUTE format('ALTER TABLE %s ADD CONSTRAINT %s CHECK (a < 100);',
115+
rel, constraint_name);
115116
END
116117
$$
117118
LANGUAGE plpgsql;
118119

119120
/*
120-
* Check that it doesn't affect regular inherited tables that aren't managed
121-
* by pg_pathman
121+
* Check that it doesn't affect regular inherited
122+
* tables that aren't managed by pg_pathman
122123
*/
123124
CREATE TABLE rename.test_inh (LIKE rename.test INCLUDING ALL);
124125
CREATE TABLE rename.test_inh_1 (LIKE rename.test INCLUDING ALL);

src/hooks.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ shmem_startup_hook_type shmem_startup_hook_next = NULL;
3535
ProcessUtility_hook_type process_utility_hook_next = NULL;
3636

3737

38-
#define is_table_rename_statement(s) \
39-
IsA((s), RenameStmt) && ((RenameStmt *)(s))->renameType == OBJECT_TABLE
40-
41-
4238
/* Take care of joins */
4339
void
4440
pathman_join_pathlist_hook(PlannerInfo *root,
@@ -631,9 +627,12 @@ pathman_process_utility_hook(Node *parsetree,
631627
DestReceiver *dest,
632628
char *completionTag)
633629
{
634-
/* Override standard COPY statement if needed */
635630
if (IsPathmanReady())
636631
{
632+
Oid partition_relid;
633+
AttrNumber partitioned_col;
634+
635+
/* Override standard COPY statement if needed */
637636
if (is_pathman_related_copy(parsetree))
638637
{
639638
uint64 processed;
@@ -647,14 +646,13 @@ pathman_process_utility_hook(Node *parsetree,
647646
return; /* don't call standard_ProcessUtility() or hooks */
648647
}
649648

650-
if (is_table_rename_statement(parsetree))
651-
{
652-
/*
653-
* Rename check constraint of a table if it is a partition managed
654-
* by pg_pathman
655-
*/
656-
PathmanRenameConstraint((RenameStmt *) parsetree);
657-
}
649+
/* Override standard RENAME statement if needed */
650+
if (is_pathman_related_table_rename(parsetree,
651+
&partition_relid,
652+
&partitioned_col))
653+
PathmanRenameConstraint(partition_relid,
654+
partitioned_col,
655+
(const RenameStmt *) parsetree);
658656
}
659657

660658
/* Call hooks set by other extensions if needed */

src/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ build_check_constraint_name_relid_internal(Oid relid, AttrNumber attno)
602602
}
603603

604604
char *
605-
build_check_constraint_name_relname_internal(char *relname, AttrNumber attno)
605+
build_check_constraint_name_relname_internal(const char *relname, AttrNumber attno)
606606
{
607607
return psprintf("pathman_%s_%u_check", relname, attno);
608608
}

src/init.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ find_children_status find_inheritance_children_array(Oid parentrelId,
126126
char *build_check_constraint_name_relid_internal(Oid relid,
127127
AttrNumber attno);
128128

129-
char *build_check_constraint_name_relname_internal(char *relname,
129+
char *build_check_constraint_name_relname_internal(const char *relname,
130130
AttrNumber attno);
131131

132132
bool pathman_config_contains_relation(Oid relid,

src/utility_stmt_hooking.c

Lines changed: 85 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,23 @@
1111
* ------------------------------------------------------------------------
1212
*/
1313

14-
#include "utility_stmt_hooking.h"
1514
#include "init.h"
15+
#include "utility_stmt_hooking.h"
1616
#include "partition_filter.h"
1717
#include "relation_info.h"
1818

1919
#include "access/htup_details.h"
2020
#include "access/sysattr.h"
2121
#include "access/xact.h"
2222
#include "catalog/namespace.h"
23-
#include "catalog/pg_attribute.h"
2423
#include "commands/copy.h"
2524
#include "commands/trigger.h"
2625
#include "commands/tablecmds.h"
27-
#include "executor/executor.h"
2826
#include "foreign/fdwapi.h"
2927
#include "miscadmin.h"
30-
#include "nodes/makefuncs.h"
3128
#include "utils/builtins.h"
3229
#include "utils/lsyscache.h"
3330
#include "utils/memutils.h"
34-
#include "utils/rel.h"
3531
#include "utils/rls.h"
3632

3733
#include "libpq/libpq.h"
@@ -74,7 +70,7 @@ bool
7470
is_pathman_related_copy(Node *parsetree)
7571
{
7672
CopyStmt *copy_stmt = (CopyStmt *) parsetree;
77-
Oid partitioned_table;
73+
Oid parent_relid;
7874

7975
Assert(IsPathmanReady());
8076

@@ -93,14 +89,14 @@ is_pathman_related_copy(Node *parsetree)
9389
return false;
9490

9591
/* Get partition's Oid while locking it */
96-
partitioned_table = RangeVarGetRelid(copy_stmt->relation,
97-
(copy_stmt->is_from ?
98-
RowExclusiveLock :
99-
AccessShareLock),
100-
false);
92+
parent_relid = RangeVarGetRelid(copy_stmt->relation,
93+
(copy_stmt->is_from ?
94+
RowExclusiveLock :
95+
AccessShareLock),
96+
false);
10197

10298
/* Check that relation is partitioned */
103-
if (get_pathman_relation_info(partitioned_table))
99+
if (get_pathman_relation_info(parent_relid))
104100
{
105101
ListCell *lc;
106102

@@ -121,7 +117,7 @@ is_pathman_related_copy(Node *parsetree)
121117
elog(ERROR, "COPY is not supported for partitioned tables on Windows");
122118
#else
123119
elog(DEBUG1, "Overriding default behavior for COPY [%u]",
124-
partitioned_table);
120+
parent_relid);
125121
#endif
126122

127123
return true;
@@ -130,6 +126,57 @@ is_pathman_related_copy(Node *parsetree)
130126
return false;
131127
}
132128

129+
/*
130+
* Is pg_pathman supposed to handle this table rename stmt?
131+
*/
132+
bool
133+
is_pathman_related_table_rename(Node *parsetree,
134+
Oid *partition_relid_out, /* ret value */
135+
AttrNumber *partitioned_col_out) /* ret value */
136+
{
137+
RenameStmt *rename_stmt = (RenameStmt *) parsetree;
138+
Oid partition_relid,
139+
parent_relid;
140+
const PartRelationInfo *prel;
141+
PartParentSearch parent_search;
142+
143+
Assert(IsPathmanReady());
144+
145+
/* Set default values */
146+
if (partition_relid_out) *partition_relid_out = InvalidOid;
147+
if (partitioned_col_out) *partitioned_col_out = InvalidAttrNumber;
148+
149+
if (!IsA(parsetree, RenameStmt))
150+
return false;
151+
152+
/* Are we going to rename some table? */
153+
if (rename_stmt->renameType != OBJECT_TABLE)
154+
return false;
155+
156+
/* Assume it's a partition, fetch its Oid */
157+
partition_relid = RangeVarGetRelid(rename_stmt->relation,
158+
AccessShareLock,
159+
false);
160+
161+
/* Try fetching parent of this table */
162+
parent_relid = get_parent_of_partition(partition_relid, &parent_search);
163+
if (parent_search != PPS_ENTRY_PART_PARENT)
164+
return false;
165+
166+
/* Is parent partitioned? */
167+
if ((prel = get_pathman_relation_info(parent_relid)) != NULL)
168+
{
169+
/* Return 'partition_relid' and 'prel->attnum' */
170+
if (partition_relid_out) *partition_relid_out = partition_relid;
171+
if (partitioned_col_out) *partitioned_col_out = prel->attnum;
172+
173+
return true;
174+
}
175+
176+
return false;
177+
}
178+
179+
133180
/*
134181
* CopyGetAttnums - build an integer list of attnums to be copied
135182
*
@@ -238,6 +285,7 @@ PathmanDoCopy(const CopyStmt *stmt, const char *queryString, uint64 *processed)
238285
"psql's \\copy command also works for anyone.")));
239286
}
240287

288+
/* Check that we have a relation */
241289
if (stmt->relation)
242290
{
243291
TupleDesc tupDesc;
@@ -363,13 +411,9 @@ PathmanDoCopy(const CopyStmt *stmt, const char *queryString, uint64 *processed)
363411
rel = NULL;
364412
}
365413
}
366-
else
367-
{
368-
Assert(stmt->query);
369414

370-
query = stmt->query;
371-
rel = NULL;
372-
}
415+
/* This should never happen (see is_pathman_related_copy()) */
416+
else elog(ERROR, "error in function \"%s\"", CppAsString(PathmanDoCopy));
373417

374418
/* COPY ... FROM ... */
375419
if (is_from)
@@ -626,45 +670,35 @@ prepare_rri_fdw_for_copy(EState *estate,
626670
}
627671

628672
/*
629-
* Rename check constraint of table if it's a partition
673+
* Rename RANGE\HASH check constraint of a partition on table rename event.
630674
*/
631675
void
632-
PathmanRenameConstraint(const RenameStmt *stmt)
676+
PathmanRenameConstraint(Oid partition_relid, /* cached partition Oid */
677+
AttrNumber partitioned_col, /* partitioned column */
678+
const RenameStmt *part_rename_stmt) /* partition rename stmt */
633679
{
634-
Oid partition_relid,
635-
parent_relid;
636-
char *old_constraint_name,
637-
*new_constraint_name;
638-
RenameStmt *rename_stmt;
639-
const PartRelationInfo *prel;
640-
641-
partition_relid = RangeVarGetRelid(stmt->relation, AccessShareLock, false);
642-
parent_relid = get_rel_parent(partition_relid);
643-
644-
/* Skip if there's no parent */
645-
if (!OidIsValid(parent_relid)) return;
646-
647-
/* Fetch partitioning data */
648-
prel = get_pathman_relation_info(parent_relid);
649-
650-
/* Skip if this table is not partitioned */
651-
if (!prel) return;
680+
char *old_constraint_name,
681+
*new_constraint_name;
682+
RenameStmt rename_stmt;
652683

653684
/* Generate old constraint name */
654-
old_constraint_name = build_check_constraint_name_relid_internal(partition_relid,
655-
prel->attnum);
685+
old_constraint_name =
686+
build_check_constraint_name_relid_internal(partition_relid,
687+
partitioned_col);
656688

657689
/* Generate new constraint name */
658-
new_constraint_name = build_check_constraint_name_relname_internal(stmt->newname,
659-
prel->attnum);
690+
new_constraint_name =
691+
build_check_constraint_name_relname_internal(part_rename_stmt->newname,
692+
partitioned_col);
660693

661694
/* Build check constraint RENAME statement */
662-
rename_stmt = makeNode(RenameStmt);
663-
rename_stmt->renameType = OBJECT_TABCONSTRAINT;
664-
rename_stmt->relation = stmt->relation;
665-
rename_stmt->subname = old_constraint_name;
666-
rename_stmt->newname = new_constraint_name;
667-
rename_stmt->missing_ok = false;
668-
669-
RenameConstraint(rename_stmt);
695+
memset((void *) &rename_stmt, 0, sizeof(RenameStmt));
696+
NodeSetTag(&rename_stmt, T_RenameStmt);
697+
rename_stmt.renameType = OBJECT_TABCONSTRAINT;
698+
rename_stmt.relation = part_rename_stmt->relation;
699+
rename_stmt.subname = old_constraint_name;
700+
rename_stmt.newname = new_constraint_name;
701+
rename_stmt.missing_ok = false;
702+
703+
RenameConstraint(&rename_stmt);
670704
}

src/utility_stmt_hooking.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/* ------------------------------------------------------------------------
22
*
33
* utility_stmt_hooking.h
4-
* Transaction-specific locks and other functions
4+
* Override COPY TO/FROM and ALTER TABLE ... RENAME statements
5+
* for partitioned tables
56
*
67
* Copyright (c) 2016, Postgres Professional
78
*
@@ -17,8 +18,16 @@
1718
#include "nodes/nodes.h"
1819

1920

21+
/* Various traits */
2022
bool is_pathman_related_copy(Node *parsetree);
23+
bool is_pathman_related_table_rename(Node *parsetree,
24+
Oid *partition_relid_out,
25+
AttrNumber *partitioned_col_out);
26+
27+
/* Statement handlers */
2128
void PathmanDoCopy(const CopyStmt *stmt, const char *queryString, uint64 *processed);
22-
void PathmanRenameConstraint(const RenameStmt *stmt);
29+
void PathmanRenameConstraint(Oid partition_relid,
30+
AttrNumber partitioned_col,
31+
const RenameStmt *partition_rename_stmt);
2332

2433
#endif

src/utils.c

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -259,35 +259,6 @@ get_rel_owner(Oid relid)
259259
return InvalidOid;
260260
}
261261

262-
/*
263-
* Lookup for a parent table
264-
*/
265-
Oid
266-
get_rel_parent(Oid relid)
267-
{
268-
ScanKeyData key[1];
269-
Relation relation;
270-
HeapTuple inheritsTuple;
271-
Oid inhparent = InvalidOid;
272-
SysScanDesc scan;
273-
274-
relation = heap_open(InheritsRelationId, AccessShareLock);
275-
ScanKeyInit(&key[0],
276-
Anum_pg_inherits_inhrelid,
277-
BTEqualStrategyNumber, F_OIDEQ,
278-
ObjectIdGetDatum(relid));
279-
scan = systable_beginscan(relation, InvalidOid, false,
280-
NULL, 1, key);
281-
282-
if ((inheritsTuple = systable_getnext(scan)) != NULL)
283-
inhparent = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhparent;
284-
285-
systable_endscan(scan);
286-
heap_close(relation, AccessShareLock);
287-
288-
return inhparent;
289-
}
290-
291262
/*
292263
* Checks that callback function meets specific requirements.
293264
* It must have the only JSONB argument and BOOL return type.

0 commit comments

Comments
 (0)