Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit4d8e430

Browse files
committed
refactoring, introduce create_partitions() (switch between backend\BGW), fixes
1 parent57305e2 commit4d8e430

File tree

9 files changed

+190
-131
lines changed

9 files changed

+190
-131
lines changed

‎range.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,8 @@ BEGIN
449449
EXECUTE v_sql;
450450
RETURN v_child_relname;
451451
END
452-
$$ LANGUAGE plpgsql;
452+
$$ LANGUAGE plpgsql
453+
SET client_min_messages= WARNING;
453454

454455
/*
455456
* Split RANGE partition

‎src/init.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include"utils.h"
1919

2020
#include"access/htup_details.h"
21+
#include"access/sysattr.h"
2122
#include"catalog/indexing.h"
2223
#include"catalog/pg_inherits_fn.h"
2324
#include"catalog/pg_type.h"
@@ -368,7 +369,8 @@ build_check_constraint_name_internal(Oid relid, AttrNumber attno)
368369
* Extract tuple into 'values' and 'isnull' if they're provided.
369370
*/
370371
bool
371-
pathman_config_contains_relation(Oidrelid,Datum*values,bool*isnull)
372+
pathman_config_contains_relation(Oidrelid,Datum*values,bool*isnull,
373+
TransactionId*xmin)
372374
{
373375
Oidpathman_config;
374376
Relationrel;
@@ -404,6 +406,21 @@ pathman_config_contains_relation(Oid relid, Datum *values, bool *isnull)
404406
/* Extract data if necessary */
405407
if (values&&isnull)
406408
heap_deformtuple(htup,RelationGetDescr(rel),values,isnull);
409+
410+
/* Set xmin if necessary */
411+
if (xmin)
412+
{
413+
Datumvalue;
414+
boolisnull;
415+
416+
value=heap_getsysattr(htup,
417+
MinTransactionIdAttributeNumber,
418+
RelationGetDescr(rel),
419+
&isnull);
420+
421+
Assert(!isnull);
422+
*xmin=DatumGetTransactionId(value);
423+
}
407424
}
408425

409426
/* Clean resources */

‎src/init.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ char *build_check_constraint_name_internal(Oid relid,
4242

4343
boolpathman_config_contains_relation(Oidrelid,
4444
Datum*values,
45-
bool*isnull);
45+
bool*isnull,
46+
TransactionId*xmin);
4647

4748
#endif

‎src/partition_filter.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,14 +184,13 @@ partition_filter_exec(CustomScanState *node)
184184
ranges=walk_expr_tree((Expr*)&state->temp_const,&state->wcxt)->rangeset;
185185
parts=get_partition_oids(ranges,&nparts,state->prel);
186186

187-
188187
if (nparts>1)
189188
elog(ERROR,"PartitionFilter selected more than one partition");
190189
elseif (nparts==0)
191190
{
192-
selected_partid=create_partitions_bg_worker(state->partitioned_table,
193-
state->temp_const.constvalue,
194-
state->temp_const.consttype);
191+
selected_partid=create_partitions(state->partitioned_table,
192+
state->temp_const.constvalue,
193+
state->temp_const.consttype);
195194

196195
/* Now we have to refresh state->wcxt->ranges manually */
197196
refresh_walker_context_ranges(&state->wcxt);

‎src/pathman.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ typedef struct
194194
/* Check that WalkerContext contains ExprContext (plan execution stage) */
195195
#defineWcxtHasExprContext(wcxt) ( (wcxt)->econtext )
196196

197+
Oidcreate_partitions_internal(Oidrelid,Datumvalue,Oidvalue_type);
198+
Oidcreate_partitions(Oidrelid,Datumvalue,Oidvalue_type);
199+
197200
voidselect_range_partitions(constDatumvalue,
198201
FmgrInfo*cmp_func,
199202
constRangeEntry*ranges,

‎src/pg_pathman.c

Lines changed: 126 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,24 @@
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

5041
PG_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
*/
117108
void
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 toprevent PostgresSQL fromexhaustive search.
166157
*/
167158
void
168159
disable_inheritance(Query*parse)
@@ -171,7 +162,6 @@ disable_inheritance(Query *parse)
171162
RangeTblEntry*rte;
172163
PartRelationInfo*prel;
173164
MemoryContextoldcontext;
174-
boolfound;
175165

176166
/* If query contains CTE (WITH statement) then handle subqueries too */
177167
disable_inheritance_cte(parse);
@@ -189,10 +179,12 @@ disable_inheritance(Query *parse)
189179
if (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 */
195186
rte->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)
754746
context->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(Oidrelid,Datumvalue,Oidvalue_type)
756+
{
757+
intret;
758+
char*sql;
759+
PartRelationInfo*prel;
760+
FmgrInfocmp_func;
761+
MemoryContextold_mcxt=CurrentMemoryContext;
762+
Oidpartid=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+
returnInvalidOid;
770+
}
771+
772+
if ((ret=SPI_connect())<0)
773+
{
774+
elog(LOG,"create_partitions_internal(): SPI_connect returned %d",ret);
775+
776+
returnInvalidOid;
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+
Oidoids[]= {OIDOID,value_type };
789+
Datumvals[]= {ObjectIdGetDatum(relid),value };
790+
boolnulls[]= { false, false };
791+
boolisnull;
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+
TupleDesctupdesc=SPI_tuptable->tupdesc;
798+
HeapTupletuple=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+
returnpartid;
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(Oidrelid,Datumvalue,Oidvalue_type)
832+
{
833+
TransactionIdrel_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+
returncreate_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+
returncreate_partitions_internal(relid,value,value_type);
849+
}
850+
}
851+
else
852+
elog(ERROR,"Relation %u is not partitioned by pg_pathman",relid);
853+
854+
returnInvalidOid;/* keep compiler happy */
855+
}
856+
857+
/*
858+
* Given RangeEntry array and 'value', return selected
859+
* RANGE partitions inside the WrapperNode.
860+
*/
757861
void
758862
select_range_partitions(constDatumvalue,
759863
FmgrInfo*cmp_func,

‎src/pl_funcs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,7 @@ find_or_create_range_partition(PG_FUNCTION_ARGS)
152152
PG_RETURN_OID(found_rentry.child_oid);
153153
}
154154

155-
/* Start background worker to create new partitions */
156-
child_oid=create_partitions_bg_worker(relid,value,value_type);
155+
child_oid=create_partitions(relid,value,value_type);
157156

158157
LWLockRelease(pmstate->load_config_lock);
159158
LWLockRelease(pmstate->edit_partitions_lock);

‎src/relation_info.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ get_pathman_relation_info(Oid relid, bool *found)
183183
boolisnull[Natts_pathman_config];
184184

185185
/* Check that PATHMAN_CONFIG table contains this relation */
186-
if (pathman_config_contains_relation(relid,values,isnull))
186+
if (pathman_config_contains_relation(relid,values,isnull,NULL))
187187
{
188188
PartTypepart_type;
189189
constchar*attname;
@@ -355,7 +355,7 @@ try_syscache_parent_search(Oid partition, PartParentSearch *status)
355355
parent= ((Form_pg_inherits)GETSTRUCT(inheritsTuple))->inhparent;
356356

357357
/* Check that PATHMAN_CONFIG contains this table */
358-
if (pathman_config_contains_relation(parent,NULL,NULL))
358+
if (pathman_config_contains_relation(parent,NULL,NULL,NULL))
359359
{
360360
/* We've found the entry, update status */
361361
if (status)*status=PPS_ENTRY_FOUND;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp