1818#include "runtime_merge_append.h"
1919
2020#include "postgres.h"
21- #include "fmgr.h"
21+ #include "access/heapam.h"
22+ #include "access/transam.h"
23+ #include "access/xact.h"
24+ #include "catalog/pg_type.h"
25+ #include "executor/spi.h"
2226#include "miscadmin.h"
23- #include "nodes/makefuncs.h"
24- #include "nodes/nodeFuncs.h"
25- #include "nodes/pg_list.h"
26- #include "nodes/relation.h"
27- #include "nodes/primnodes.h"
2827#include "optimizer/clauses.h"
29- #include "optimizer/paths.h"
30- #include "optimizer/pathnode.h"
31- #include "optimizer/planner.h"
3228#include "optimizer/prep.h"
3329#include "optimizer/restrictinfo.h"
3430#include "optimizer/cost.h"
35- #include "parser/analyze.h"
36- #include "utils/hsearch.h"
3731#include "utils/rel.h"
38- #include "utils/elog.h"
39- #include "utils/array.h"
4032#include "utils/guc.h"
4133#include "utils/lsyscache.h"
4234#include "utils/selfuncs.h"
35+ #include "utils/snapmgr.h"
4336#include "utils/memutils.h"
44- #include "access/heapam.h"
45- #include "storage/ipc.h"
46- #include "catalog/pg_type.h"
4737#include "foreign/fdwapi.h"
38+ #include "fmgr.h"
4839
4940
5041PG_MODULE_MAGIC ;
@@ -112,7 +103,7 @@ static Path *get_cheapest_parameterized_child_path(PlannerInfo *root, RelOptInfo
112103
113104
114105/*
115- *Entry point
106+ *Set initial values for all Postmaster's forks.
116107 */
117108void
118109_PG_init (void )
@@ -161,8 +152,8 @@ _PG_init(void)
161152}
162153
163154/*
164- * Disables inheritance for partitioned by pathman relations. It must be done to
165- * prevent PostgresSQL fromfull search.
155+ * Disables inheritance for partitioned by pathman relations.
156+ *It must be done to prevent PostgresSQL fromexhaustive search.
166157 */
167158void
168159disable_inheritance (Query * parse )
@@ -171,7 +162,6 @@ disable_inheritance(Query *parse)
171162RangeTblEntry * rte ;
172163PartRelationInfo * prel ;
173164MemoryContext oldcontext ;
174- bool found ;
175165
176166/* If query contains CTE (WITH statement) then handle subqueries too */
177167disable_inheritance_cte (parse );
@@ -189,10 +179,12 @@ disable_inheritance(Query *parse)
189179if (rte -> inh )
190180{
191181/* Look up this relation in pathman relations */
192- prel = get_pathman_relation_info (rte -> relid ,& found );
193- if (prel != NULL && found )
182+ prel = get_pathman_relation_info (rte -> relid ,NULL );
183+ if (prel )
194184{
185+ /* We'll set this flag later */
195186rte -> inh = false;
187+
196188/*
197189 * Sometimes user uses the ONLY statement and in this case
198190 * rte->inh is also false. We should differ the case
@@ -754,6 +746,118 @@ finish_least_greatest(WrapperNode *wrap, WalkerContext *context)
754746context -> hasGreatest = false;
755747}
756748
749+ /*
750+ * Append partitions (if needed) and return Oid of the partition to contain value.
751+ *
752+ * NB: This function should not be called directly, use create_partitions() instead.
753+ */
754+ Oid
755+ create_partitions_internal (Oid relid ,Datum value ,Oid value_type )
756+ {
757+ int ret ;
758+ char * sql ;
759+ PartRelationInfo * prel ;
760+ FmgrInfo cmp_func ;
761+ MemoryContext old_mcxt = CurrentMemoryContext ;
762+ Oid partid = InvalidOid ;/* default value */
763+
764+ if ((prel = get_pathman_relation_info (relid ,NULL ))== NULL )
765+ {
766+ elog (LOG ,"Cannot fetch PartRelationInfo for relation %u [%u]" ,
767+ relid ,MyProcPid );
768+
769+ return InvalidOid ;
770+ }
771+
772+ if ((ret = SPI_connect ())< 0 )
773+ {
774+ elog (LOG ,"create_partitions_internal(): SPI_connect returned %d" ,ret );
775+
776+ return InvalidOid ;
777+ }
778+
779+ /* Comparison function */
780+ fill_type_cmp_fmgr_info (& cmp_func ,value_type ,prel -> atttype );
781+
782+ /* Perform PL procedure */
783+ sql = psprintf ("SELECT %s.append_partitions_on_demand_internal($1, $2)" ,
784+ get_namespace_name (get_pathman_schema ()));
785+
786+ PG_TRY ();
787+ {
788+ Oid oids []= {OIDOID ,value_type };
789+ Datum vals []= {ObjectIdGetDatum (relid ),value };
790+ bool nulls []= { false, false };
791+ bool isnull ;
792+
793+ /* TODO: maybe this could be rewritten with FunctionCall */
794+ ret = SPI_execute_with_args (sql ,2 ,oids ,vals ,nulls , false,0 );
795+ if (ret == SPI_OK_SELECT )
796+ {
797+ TupleDesc tupdesc = SPI_tuptable -> tupdesc ;
798+ HeapTuple tuple = SPI_tuptable -> vals [0 ];
799+
800+ Assert (SPI_processed == 1 );
801+
802+ partid = DatumGetObjectId (SPI_getbinval (tuple ,tupdesc ,1 ,& isnull ));
803+ }
804+ }
805+ PG_CATCH ();
806+ {
807+ ErrorData * edata ;
808+
809+ MemoryContextSwitchTo (old_mcxt );
810+ edata = CopyErrorData ();
811+ FlushErrorState ();
812+
813+ elog (LOG ,"create_partitions_internal(): %s [%u]" ,
814+ edata -> message ,MyProcPid );
815+
816+ FreeErrorData (edata );
817+ }
818+ PG_END_TRY ();
819+
820+ SPI_finish ();
821+
822+ return partid ;
823+ }
824+
825+ /*
826+ * Create RANGE partitions (if needed) using either BGW or current backend.
827+ *
828+ * Returns Oid of the partition to store 'value'.
829+ */
830+ Oid
831+ create_partitions (Oid relid ,Datum value ,Oid value_type )
832+ {
833+ TransactionId rel_xmin ;
834+
835+ /* Check that table is partitioned and fetch xmin */
836+ if (pathman_config_contains_relation (relid ,NULL ,NULL ,& rel_xmin ))
837+ {
838+ /* If table was partitioned in some previous xact, run BGWorker */
839+ if (TransactionIdPrecedes (rel_xmin ,GetCurrentTransactionId ()))
840+ {
841+ elog (DEBUG2 ,"create_partitions(): chose BGW [%u]" ,MyProcPid );
842+ return create_partitions_bg_worker (relid ,value ,value_type );
843+ }
844+ /* Else it'd better for the current backend to create partitions */
845+ else
846+ {
847+ elog (DEBUG2 ,"create_partitions(): chose backend [%u]" ,MyProcPid );
848+ return create_partitions_internal (relid ,value ,value_type );
849+ }
850+ }
851+ else
852+ elog (ERROR ,"Relation %u is not partitioned by pg_pathman" ,relid );
853+
854+ return InvalidOid ;/* keep compiler happy */
855+ }
856+
857+ /*
858+ * Given RangeEntry array and 'value', return selected
859+ * RANGE partitions inside the WrapperNode.
860+ */
757861void
758862select_range_partitions (const Datum value ,
759863FmgrInfo * cmp_func ,