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 */
595596check_lt (& cmp_value_bound_finfo ,collid ,value ,cur_leading_bound ))
596597{
597598Bound 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 */
600609cur_following_bound = cur_leading_bound ;
@@ -607,10 +616,45 @@ spawn_partitions_val(Oid parent_relid,/* parent's Oid */
607616bounds [0 ]= MakeBound (should_append ?cur_following_bound :cur_leading_bound );
608617bounds [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
616660elog (DEBUG2 ,"%s partition with following='%s' & leading='%s' [%u]" ,