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

Commitdff8755

Browse files
committed
pathman:
* load RANGE configuration from pg_constraint* optimization for RANGE trigger (partly rewrited with C)
1 parent4ef4d33 commitdff8755

File tree

6 files changed

+644
-667
lines changed

6 files changed

+644
-667
lines changed

‎contrib/pathman/init.c

Lines changed: 138 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,24 @@
22
#include"executor/spi.h"
33
#include"catalog/pg_type.h"
44

5+
#include"catalog/pg_class.h"
6+
#include"catalog/pg_constraint.h"
7+
#include"utils/syscache.h"
8+
#include"access/htup_details.h"
9+
#include"utils/builtins.h"
10+
#include"utils/typcache.h"
11+
12+
513
HTAB*relations=NULL;
614
HTAB*hash_restrictions=NULL;
715
HTAB*range_restrictions=NULL;
816
boolinitialization_needed= true;
917

18+
19+
staticboolvalidate_range_constraint(Expr*,PartRelationInfo*,Datum*,Datum*);
20+
staticintcmp_range_entries(constvoid*p1,constvoid*p2);
21+
22+
1023
/*
1124
* Initialize hashtables
1225
*/
@@ -63,8 +76,8 @@ load_part_relations_hashtable()
6376
for (i=0;i<proc;i++)
6477
{
6578
HeapTupletuple=tuptable->vals[i];
66-
6779
intoid=DatumGetObjectId(SPI_getbinval(tuple,tupdesc,1,&isnull));
80+
6881
prinfo= (PartRelationInfo*)
6982
hash_search(relations, (constvoid*)&oid,HASH_ENTER,NULL);
7083
prinfo->oid=oid;
@@ -87,10 +100,13 @@ load_part_relations_hashtable()
87100
prinfo= (PartRelationInfo*)
88101
hash_search(relations, (constvoid*)&oid,HASH_FIND,NULL);
89102

103+
// load_check_constraints(oid);
104+
90105
switch(prinfo->parttype)
91106
{
92107
casePT_RANGE:
93-
load_range_restrictions(oid);
108+
// load_range_restrictions(oid);
109+
load_check_constraints(oid);
94110
break;
95111
casePT_HASH:
96112
load_hash_restrictions(oid);
@@ -203,14 +219,16 @@ create_hash_restrictions_hashtable()
203219
&ctl,HASH_ELEM |HASH_BLOBS);
204220
}
205221

222+
/*
223+
* Load and validate constraints
224+
* TODO: make it work for HASH partitioning
225+
*/
206226
void
207-
load_range_restrictions(Oidparent_oid)
227+
load_check_constraints(Oidparent_oid)
208228
{
209229
boolfound;
210230
PartRelationInfo*prel;
211231
RangeRelation*rangerel;
212-
// HashRelation *hashrel;
213-
// HashRelationKey key;
214232
intret;
215233
inti;
216234
intproc;
@@ -224,24 +242,15 @@ load_range_restrictions(Oid parent_oid)
224242
prel= (PartRelationInfo*)
225243
hash_search(relations, (constvoid*)&parent_oid,HASH_FIND,&found);
226244

227-
/* if already loaded then quit */
228-
if (prel->children_count>0)
229-
return;
245+
// /* if already loaded then quit */
246+
//if (prel->children_count > 0)
247+
//return;
230248

231249
// SPI_connect();
232-
ret=SPI_execute_with_args("SELECT p.relfilenode, c.relfilenode, "
233-
"rr.min_num, rr.max_num, "
234-
"rr.min_dt, "
235-
"rr.max_dt, "
236-
"rr.min_dt::DATE, "
237-
"rr.max_dt::DATE, "
238-
"rr.min_num::INTEGER, "
239-
"rr.max_num::INTEGER "
240-
"FROM pg_pathman_range_rels rr "
241-
"JOIN pg_class p ON p.relname = rr.parent "
242-
"JOIN pg_class c ON c.relname = rr.child "
243-
"WHERE p.relfilenode = $1 "
244-
"ORDER BY rr.parent, rr.min_num, rr.min_dt",
250+
ret=SPI_execute_with_args("select pg_constraint.* "
251+
"from pg_constraint "
252+
"join pg_inherits on inhrelid = conrelid "
253+
"where inhparent = $1 and contype='c';",
245254
1,oids,vals,nulls, true,0);
246255
proc=SPI_processed;
247256

@@ -251,6 +260,8 @@ load_range_restrictions(Oid parent_oid)
251260
SPITupleTable*tuptable=SPI_tuptable;
252261
Oid*children;
253262
RangeEntry*ranges;
263+
Datummin;
264+
Datummax;
254265

255266
rangerel= (RangeRelation*)
256267
hash_search(range_restrictions, (void*)&parent_oid,HASH_ENTER,&found);
@@ -264,60 +275,115 @@ load_range_restrictions(Oid parent_oid)
264275

265276
for (i=0;i<proc;i++)
266277
{
267-
Datummin;
268-
Datummax;
269-
RangeEntryre;
270-
HeapTupletuple=tuptable->vals[i];
271-
272-
// int parent_oid = DatumGetObjectId(SPI_getbinval(tuple, tupdesc, 1, &arg1_isnull));
273-
re.child_oid=DatumGetObjectId(SPI_getbinval(tuple,tupdesc,2,&arg1_isnull));
274-
275-
/* date */
276-
// switch (prinfo->atttype)
277-
// {
278-
// case AT_INT:
279-
// min = SPI_getbinval(tuple, tupdesc, 3, &isnull);
280-
// max = SPI_getbinval(tuple, tupdesc, 4, &isnull);
281-
// re.min.integer = DatumGetInt32(min);
282-
// re.max.integer = DatumGetInt32(max);
283-
// break;
284-
// case AT_DATE:
285-
// min = SPI_getbinval(tuple, tupdesc, 5, &isnull);
286-
// max = SPI_getbinval(tuple, tupdesc, 6, &isnull);
287-
// re.min.date = DatumGetDateADT(min);
288-
// re.max.date = DatumGetDateADT(max);
289-
// break;
290-
// }
291-
292-
switch(prel->atttype)
293-
{
294-
caseDATEOID:
295-
re.min=SPI_getbinval(tuple,tupdesc,7,&arg1_isnull);
296-
re.max=SPI_getbinval(tuple,tupdesc,8,&arg2_isnull);
297-
break;
298-
caseTIMESTAMPOID:
299-
re.min=SPI_getbinval(tuple,tupdesc,5,&arg1_isnull);
300-
re.max=SPI_getbinval(tuple,tupdesc,6,&arg2_isnull);
301-
break;
302-
caseINT2OID:
303-
caseINT4OID:
304-
caseINT8OID:
305-
re.min=SPI_getbinval(tuple,tupdesc,9,&arg1_isnull);
306-
re.max=SPI_getbinval(tuple,tupdesc,10,&arg2_isnull);
307-
break;
308-
default:
309-
re.min=SPI_getbinval(tuple,tupdesc,3,&arg1_isnull);
310-
re.max=SPI_getbinval(tuple,tupdesc,4,&arg2_isnull);
311-
break;
312-
}
278+
RangeEntryre;
279+
HeapTupletuple=tuptable->vals[i];
280+
boolisnull;
281+
Datumval;
282+
char*conbin;
283+
Expr*expr;
284+
285+
// HeapTuplereltuple;
286+
// Form_pg_class pg_class_tuple;
287+
Form_pg_constraintcon;
288+
289+
con= (Form_pg_constraint)GETSTRUCT(tuple);
290+
291+
val=SysCacheGetAttr(CONSTROID,tuple,Anum_pg_constraint_conbin,
292+
&isnull);
293+
if (isnull)
294+
elog(ERROR,"null conbin for constraint %u",
295+
HeapTupleGetOid(tuple));
296+
conbin=TextDatumGetCString(val);
297+
expr= (Expr*)stringToNode(conbin);
298+
299+
if (prel->parttype==PT_RANGE)
300+
validate_range_constraint(expr,prel,&min,&max);
301+
302+
// re.child_oid = DatumGetObjectId(SPI_getbinval(tuple, tupdesc, 2, &arg1_isnull));
303+
re.child_oid=con->conrelid;
304+
re.min=min;
305+
re.max=max;
313306

314307
ranges[rangerel->nranges++]=re;
315-
// prel->children[prel->children_count++] = re.child_oid;
316-
children[prel->children_count++]=re.child_oid;
317-
}
308+
// children[prel->children_count++] = re.child_oid;
309+
}
310+
311+
/* sort ascending */
312+
qsort(ranges,rangerel->nranges,sizeof(RangeEntry),cmp_range_entries);
313+
314+
/* copy oids to prel */
315+
for(i=0;i<rangerel->nranges;i++,prel->children_count++)
316+
children[i]=ranges[i].child_oid;
317+
318+
/* TODO: check if some ranges overlap! */
318319
}
320+
}
319321

320-
// SPI_finish();
322+
323+
/* qsort comparison function for oids */
324+
staticint
325+
cmp_range_entries(constvoid*p1,constvoid*p2)
326+
{
327+
RangeEntry*v1= (constRangeEntry*)p1;
328+
RangeEntry*v2= (constRangeEntry*)p2;
329+
330+
if (v1->min<v2->min)
331+
return-1;
332+
if (v1->min>v2->min)
333+
return1;
334+
return0;
335+
}
336+
337+
338+
staticbool
339+
validate_range_constraint(Expr*expr,PartRelationInfo*prel,Datum*min,Datum*max)
340+
{
341+
TypeCacheEntry*tce;
342+
intstrategy;
343+
BoolExpr*boolexpr= (BoolExpr*)expr;
344+
OpExpr*opexpr;
345+
346+
/* it should be an AND operator on top */
347+
if ( !(IsA(expr,BoolExpr)&&boolexpr->boolop==AND_EXPR) )
348+
return false;
349+
350+
/* and it should have exactly two operands */
351+
if (list_length(boolexpr->args)!=2)
352+
return false;
353+
354+
tce=lookup_type_cache(prel->atttype,TYPECACHE_EQ_OPR |TYPECACHE_LT_OPR |TYPECACHE_GT_OPR);
355+
// strategy = get_op_opfamily_strategy(boolexpr->opno, tce->btree_opf);
356+
357+
/* check that left operand is >= operator */
358+
opexpr= (OpExpr*)linitial(boolexpr->args);
359+
if (get_op_opfamily_strategy(opexpr->opno,tce->btree_opf)==BTGreaterEqualStrategyNumber)
360+
{
361+
Node*left=linitial(opexpr->args);
362+
Node*right=lsecond(opexpr->args);
363+
if ( !IsA(left,Var)|| !IsA(right,Const) )
364+
return false;
365+
if ( ((Var*)left)->varattno!=prel->attnum )
366+
return false;
367+
*min= ((Const*)right)->constvalue;
368+
}
369+
else
370+
return false;
371+
372+
/* TODO: rewrite this */
373+
/* check that right operand is < operator */
374+
opexpr= (OpExpr*)lsecond(boolexpr->args);
375+
if (get_op_opfamily_strategy(opexpr->opno,tce->btree_opf)==BTLessStrategyNumber)
376+
{
377+
Node*left=linitial(opexpr->args);
378+
Node*right=lsecond(opexpr->args);
379+
if ( !IsA(left,Var)|| !IsA(right,Const) )
380+
return false;
381+
if ( ((Var*)left)->varattno!=prel->attnum )
382+
return false;
383+
*max= ((Const*)right)->constvalue;
384+
}
385+
else
386+
return false;
321387
}
322388

323389
/*
@@ -376,4 +442,4 @@ remove_relation_info(Oid relid)
376442
}
377443
prel->children_count=0;
378444
hash_search(relations, (constvoid*)&relid,HASH_REMOVE,0);
379-
}
445+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp