1616#include "partition_filter.h"
1717#include "runtimeappend.h"
1818#include "runtime_merge_append.h"
19+ #include "xact_handling.h"
1920
2021#include "postgres.h"
2122#include "access/heapam.h"
@@ -60,6 +61,9 @@ static Node *wrapper_make_expression(WrapperNode *wrap, int index, bool *alwaysT
6061static bool disable_inheritance_subselect_walker (Node * node , void * context );
6162
6263/* "Partition creation"-related functions */
64+ static Datum extract_binary_interval_from_text (Datum interval_text ,
65+ Oid part_atttype ,
66+ Oid * interval_type );
6367static bool spawn_partitions (Oid partitioned_rel ,
6468 Datum value ,
6569 Datum leading_bound ,
@@ -128,14 +132,15 @@ _PG_init(void)
128132
129133 if (!process_shared_preload_libraries_in_progress )
130134 {
131- elog (ERROR , "Pathman module must be initialized in postmaster . "
135+ elog (ERROR , "pg_pathman module must be initialized by Postmaster . "
132136 "Put the following line to configuration file: "
133137 "shared_preload_libraries='pg_pathman'" );
134138 }
135139
136140 /* Request additional shared resources */
137141 RequestAddinShmemSpace (estimate_pathman_shmem_size ());
138- RequestAddinLWLocks (3 );
142+
143+ /* NOTE: we don't need LWLocks now. RequestAddinLWLocks(1); */
139144
140145 /* Assign pg_pathman's initial state */
141146 temp_init_state .initialization_needed = true;
@@ -791,6 +796,57 @@ spawn_partitions(Oid partitioned_rel, /* parent's Oid */
791796 return spawned ;
792797}
793798
799+ /*
800+ * Convert interval from TEXT to binary form using partitioned column's type.
801+ */
802+ static Datum
803+ extract_binary_interval_from_text (Datum interval_text , /* interval as TEXT */
804+ Oid part_atttype , /* partitioned column's type */
805+ Oid * interval_type ) /* returned value */
806+ {
807+ Datum interval_binary ;
808+ const char * interval_cstring ;
809+
810+ interval_cstring = TextDatumGetCString (interval_text );
811+
812+ /* If 'part_atttype' is a *date type*, cast 'range_interval' to INTERVAL */
813+ if (is_date_type_internal (part_atttype ))
814+ {
815+ int32 interval_typmod = PATHMAN_CONFIG_interval_typmod ;
816+
817+ /* Convert interval from CSTRING to internal form */
818+ interval_binary = DirectFunctionCall3 (interval_in ,
819+ CStringGetDatum (interval_cstring ),
820+ ObjectIdGetDatum (InvalidOid ),
821+ Int32GetDatum (interval_typmod ));
822+ if (interval_type )
823+ * interval_type = INTERVALOID ;
824+ }
825+ /* Otherwise cast it to the partitioned column's type */
826+ else
827+ {
828+ HeapTuple htup ;
829+ Oid typein_proc = InvalidOid ;
830+
831+ htup = SearchSysCache1 (TYPEOID , ObjectIdGetDatum (part_atttype ));
832+ if (HeapTupleIsValid (htup ))
833+ {
834+ typein_proc = ((Form_pg_type ) GETSTRUCT (htup ))-> typinput ;
835+ ReleaseSysCache (htup );
836+ }
837+ else
838+ elog (ERROR , "Cannot find input function for type %u" , part_atttype );
839+
840+ /* Convert interval from CSTRING to 'prel->atttype' */
841+ interval_binary = OidFunctionCall1 (typein_proc ,
842+ CStringGetDatum (interval_cstring ));
843+ if (interval_type )
844+ * interval_type = part_atttype ;
845+ }
846+
847+ return interval_binary ;
848+ }
849+
794850/*
795851 * Append partitions (if needed) and return Oid of the partition to contain value.
796852 *
@@ -808,9 +864,6 @@ create_partitions_internal(Oid relid, Datum value, Oid value_type)
808864 Datum values [Natts_pathman_config ];
809865 bool isnull [Natts_pathman_config ];
810866
811- prel = get_pathman_relation_info (relid );
812- shout_if_prel_is_invalid (relid , prel , PT_RANGE );
813-
814867 /* Get both PartRelationInfo & PATHMAN_CONFIG contents for this relation */
815868 if (pathman_config_contains_relation (relid , values , isnull , NULL ))
816869 {
@@ -820,54 +873,27 @@ create_partitions_internal(Oid relid, Datum value, Oid value_type)
820873 Oid interval_type = InvalidOid ;
821874 Datum interval_binary , /* assigned 'width' of a single partition */
822875 interval_text ;
823- const char * interval_cstring ;
824876
825877 FmgrInfo interval_type_cmp ;
826878
827- /* Fill the FmgrInfo struct with a cmp(value, part_attribute) function */
828- fill_type_cmp_fmgr_info (& interval_type_cmp , value_type , prel -> atttype );
829-
830- /* Convert interval from TEXT to CSTRING */
831- interval_text = values [Anum_pathman_config_range_interval - 1 ];
832- interval_cstring = TextDatumGetCString (interval_text );
879+ /* Fetch PartRelationInfo by 'relid' */
880+ prel = get_pathman_relation_info (relid );
881+ shout_if_prel_is_invalid (relid , prel , PT_RANGE );
833882
834883 /* Read max & min range values from PartRelationInfo */
835884 min_rvalue = prel -> ranges [0 ].min ;
836885 max_rvalue = prel -> ranges [PrelLastChild (prel )].max ;
837886
838- /* If this is a *date type*, cast 'range_interval' to INTERVAL */
839- if (is_date_type_internal (value_type ))
840- {
841- int32 interval_typmod = PATHMAN_CONFIG_interval_typmod ;
842-
843- /* Convert interval from CSTRING to internal form */
844- interval_binary = DirectFunctionCall3 (interval_in ,
845- CStringGetDatum (interval_cstring ),
846- ObjectIdGetDatum (InvalidOid ),
847- Int32GetDatum (interval_typmod ));
848- interval_type = INTERVALOID ;
849- }
850- /* Otherwise cast it to the partitioned column's type */
851- else
852- {
853- HeapTuple htup ;
854- Oid typein_proc = InvalidOid ;
887+ /* Retrieve interval as TEXT from tuple */
888+ interval_text = values [Anum_pathman_config_range_interval - 1 ];
855889
856- htup = SearchSysCache1 (TYPEOID , ObjectIdGetDatum (prel -> atttype ));
857- if (HeapTupleIsValid (htup ))
858- {
859- typein_proc = ((Form_pg_type ) GETSTRUCT (htup ))-> typinput ;
860- ReleaseSysCache (htup );
861- }
862- else
863- elog (ERROR , "Cannot find input function for type %u" ,
864- prel -> atttype );
865-
866- /* Convert interval from CSTRING to 'prel->atttype' */
867- interval_binary = OidFunctionCall1 (typein_proc ,
868- CStringGetDatum (interval_cstring ));
869- interval_type = prel -> atttype ;
870- }
890+ /* Convert interval to binary representation */
891+ interval_binary = extract_binary_interval_from_text (interval_text ,
892+ prel -> atttype ,
893+ & interval_type );
894+
895+ /* Fill the FmgrInfo struct with a cmp(value, part_attribute) function */
896+ fill_type_cmp_fmgr_info (& interval_type_cmp , value_type , prel -> atttype );
871897
872898 if (SPI_connect () != SPI_OK_CONNECT )
873899 elog (ERROR , "Could not connect using SPI" );
0 commit comments