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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy