Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dbcbd02

Browse filesBrowse files
committed
Pass create_single_range_partition through SPI in spawn_partitions_val.
To allow DDL-wobbling extensions (mtm, in particular) to intercept it (yeah, through targetlist analysis. Seems like this is the only place performing DDL not covered by declarative partitioning (which can be handled as utility statements). Stas Kelvich.
1 parent f093e76 commit dbcbd02
Copy full SHA for dbcbd02

File tree

2 files changed

+49
-6
lines changed
Filter options

2 files changed

+49
-6
lines changed

‎range.sql

Copy file name to clipboardExpand all lines: range.sql
+1-2Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -820,8 +820,7 @@ CREATE OR REPLACE FUNCTION @extschema@.create_single_range_partition(
820820
partition_name TEXT DEFAULT NULL,
821821
tablespace TEXT DEFAULT NULL)
822822
RETURNS REGCLASS AS 'pg_pathman', 'create_single_range_partition_pl'
823-
LANGUAGE C
824-
SET client_min_messages = WARNING;
823+
LANGUAGE C;
825824

826825
/*
827826
* Construct CHECK constraint condition for a range partition.

‎src/partition_creation.c

Copy file name to clipboardExpand all lines: src/partition_creation.c
+48-4Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "commands/tablecmds.h"
3333
#include "commands/tablespace.h"
3434
#include "commands/trigger.h"
35+
#include "executor/spi.h"
3536
#include "miscadmin.h"
3637
#include "nodes/nodeFuncs.h"
3738
#include "parser/parse_func.h"
@@ -595,6 +596,14 @@ spawn_partitions_val(Oid parent_relid, /* parent's Oid */
595596
check_lt(&cmp_value_bound_finfo, collid, value, cur_leading_bound))
596597
{
597598
Bound bounds[2];
599+
int rc;
600+
bool isnull;
601+
char *create_sql;
602+
HeapTuple typeTuple;
603+
char *typname;
604+
Oid parent_nsp = get_rel_namespace(parent_relid);
605+
char *parent_nsp_name = get_namespace_name(parent_nsp);
606+
char *partition_name = choose_range_partition_name(parent_relid, parent_nsp);
598607

599608
/* Assign the 'following' boundary to current 'leading' value */
600609
cur_following_bound = cur_leading_bound;
@@ -607,10 +616,45 @@ spawn_partitions_val(Oid parent_relid, /* parent's Oid */
607616
bounds[0] = MakeBound(should_append ? cur_following_bound : cur_leading_bound);
608617
bounds[1] = MakeBound(should_append ? cur_leading_bound : cur_following_bound);
609618

610-
last_partition = create_single_range_partition_internal(parent_relid,
611-
&bounds[0], &bounds[1],
612-
range_bound_type,
613-
NULL, NULL);
619+
/*
620+
* Instead of directly calling create_single_range_partition_internal()
621+
* we are going to call it through SPI, to make it possible for various
622+
* DDL-replicating extensions to catch that call and do something about
623+
* it. --sk
624+
*/
625+
626+
/* Get typname of range_bound_type to perform cast */
627+
typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(range_bound_type));
628+
Assert(HeapTupleIsValid(typeTuple));
629+
typname = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(typeTuple))->typname));
630+
ReleaseSysCache(typeTuple);
631+
632+
/* Construct call to create_single_range_partition() */
633+
create_sql = psprintf(
634+
"select %s.create_single_range_partition('%s.%s', '%s'::%s, '%s'::%s, '%s.%s')",
635+
get_namespace_name(get_pathman_schema()),
636+
parent_nsp_name,
637+
get_rel_name(parent_relid),
638+
IsInfinite(&bounds[0]) ? "NULL" : datum_to_cstring(bounds[0].value, range_bound_type),
639+
typname,
640+
IsInfinite(&bounds[1]) ? "NULL" : datum_to_cstring(bounds[1].value, range_bound_type),
641+
typname,
642+
parent_nsp_name,
643+
partition_name
644+
);
645+
646+
/* ...and call it. */
647+
SPI_connect();
648+
PushActiveSnapshot(GetTransactionSnapshot());
649+
rc = SPI_execute(create_sql, false, 0);
650+
if (rc <= 0 || SPI_processed != 1)
651+
elog(ERROR, "Failed to create range partition");
652+
last_partition = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0],
653+
SPI_tuptable->tupdesc,
654+
1, &isnull));
655+
Assert(!isnull);
656+
SPI_finish();
657+
PopActiveSnapshot();
614658

615659
#ifdef USE_ASSERT_CHECKING
616660
elog(DEBUG2, "%s partition with following='%s' & leading='%s' [%u]",

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.