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

Commit63e03ac

Browse files
committed
pathman: IndexScan for child relations fixed; some improvements in RANGE partitioning
1 parent637ad38 commit63e03ac

File tree

5 files changed

+164
-43
lines changed

5 files changed

+164
-43
lines changed

‎contrib/pathman/init.c

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ load_part_relations_hashtable()
3131
ListCell*lc;
3232

3333
SPI_connect();
34-
ret=SPI_exec("SELECT pg_class.relfilenode, pg_attribute.attnum, pg_pathman_rels.parttype "
34+
ret=SPI_exec("SELECT pg_class.relfilenode, pg_attribute.attnum, pg_pathman_rels.parttype, pg_attribute.atttypid "
3535
"FROM pg_pathman_rels "
3636
"JOIN pg_class ON pg_class.relname = pg_pathman_rels.relname "
3737
"JOIN pg_attribute ON pg_attribute.attname = pg_pathman_rels.attname "
@@ -48,10 +48,12 @@ load_part_relations_hashtable()
4848
HeapTupletuple=tuptable->vals[i];
4949

5050
intoid=DatumGetObjectId(SPI_getbinval(tuple,tupdesc,1,&isnull));
51-
prinfo= (PartRelationInfo*)hash_search(relations, (constvoid*)&oid,HASH_ENTER,NULL);
51+
prinfo= (PartRelationInfo*)
52+
hash_search(relations, (constvoid*)&oid,HASH_ENTER,NULL);
5253
prinfo->oid=oid;
5354
prinfo->attnum=DatumGetInt32(SPI_getbinval(tuple,tupdesc,2,&isnull));
5455
prinfo->parttype=DatumGetInt32(SPI_getbinval(tuple,tupdesc,3,&isnull));
56+
prinfo->atttype=DatumGetObjectId(SPI_getbinval(tuple,tupdesc,4,&isnull));
5557

5658
part_oids=lappend_int(part_oids,oid);
5759

@@ -204,14 +206,16 @@ load_range_restrictions(Oid parent_oid)
204206

205207
// SPI_connect();
206208
ret=SPI_execute_with_args("SELECT p.relfilenode, c.relfilenode, "
207-
"rr.min_int, rr.max_int, "
208-
"rr.min_dt - '1 microsecond'::INTERVAL, "
209-
"rr.max_dt - '1 microsecond'::INTERVAL "
209+
"rr.min_num, rr.max_num, "
210+
"rr.min_dt, "
211+
"rr.max_dt - '1 microsecond'::INTERVAL, "
212+
"rr.min_dt::DATE, "
213+
"(rr.max_dt - '1 day'::INTERVAL)::DATE "
210214
"FROM pg_pathman_range_rels rr "
211215
"JOIN pg_class p ON p.relname = rr.parent "
212216
"JOIN pg_class c ON c.relname = rr.child "
213217
"WHERE p.relfilenode = $1 "
214-
"ORDER BY rr.parent, rr.min_int, rr.min_dt",
218+
"ORDER BY rr.parent, rr.min_num, rr.min_dt",
215219
1,oids,vals,nulls, true,0);
216220
proc=SPI_processed;
217221

@@ -250,19 +254,35 @@ load_range_restrictions(Oid parent_oid)
250254
// break;
251255
// }
252256

253-
re.min=SPI_getbinval(tuple,tupdesc,3,&arg1_isnull);
254-
re.max=SPI_getbinval(tuple,tupdesc,4,&arg2_isnull);
255-
prel->atttype=AT_INT;
256-
257-
if (arg1_isnull||arg2_isnull)
257+
switch(prel->atttype)
258258
{
259-
re.min=SPI_getbinval(tuple,tupdesc,5,&arg1_isnull);
260-
re.max=SPI_getbinval(tuple,tupdesc,6,&arg2_isnull);
261-
prel->atttype=AT_DATE;
262-
263-
if (arg1_isnull||arg2_isnull)
264-
ereport(ERROR, (errmsg("Range relation should be of type either INTEGER or DATE")));
259+
caseDATEOID:
260+
re.min=SPI_getbinval(tuple,tupdesc,7,&arg1_isnull);
261+
re.max=SPI_getbinval(tuple,tupdesc,8,&arg2_isnull);
262+
break;
263+
caseTIMESTAMPOID:
264+
re.min=SPI_getbinval(tuple,tupdesc,5,&arg1_isnull);
265+
re.max=SPI_getbinval(tuple,tupdesc,6,&arg2_isnull);
266+
break;
267+
default:
268+
re.min=SPI_getbinval(tuple,tupdesc,3,&arg1_isnull);
269+
re.max=SPI_getbinval(tuple,tupdesc,4,&arg2_isnull);
270+
break;
265271
}
272+
273+
// re.min = SPI_getbinval(tuple, tupdesc, 3, &arg1_isnull);
274+
// re.max = SPI_getbinval(tuple, tupdesc, 4, &arg2_isnull);
275+
// // prel->atttype = AT_INT;
276+
277+
// if (arg1_isnull || arg2_isnull)
278+
// {
279+
// re.min = SPI_getbinval(tuple, tupdesc, 5, &arg1_isnull);
280+
// re.max = SPI_getbinval(tuple, tupdesc, 6, &arg2_isnull);
281+
// // prel->atttype = AT_DATE;
282+
283+
// if (arg1_isnull || arg2_isnull)
284+
// ereport(ERROR, (errmsg("Range relation should be of type either INTEGER or DATE")));
285+
// }
266286
rangerel->ranges[rangerel->nranges++]=re;
267287

268288
prel->children[prel->children_count++]=re.child_oid;

‎contrib/pathman/pathman.c

Lines changed: 91 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ PG_FUNCTION_INFO_V1( on_partitions_updated );
5050
PG_FUNCTION_INFO_V1(on_partitions_removed );
5151

5252

53+
typedefstruct
54+
{
55+
Oidold_varno;
56+
Oidnew_varno;
57+
}change_varno_context;
58+
59+
5360
/*
5461
* Entry point
5562
*/
@@ -274,6 +281,9 @@ append_child_relation(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEnt
274281
IndexchildRTindex;
275282
AppendRelInfo*appinfo;
276283

284+
Node*node;
285+
ListCell*lc;
286+
277287
/* Create RangeTblEntry for child relation */
278288
childrte=copyObject(rte);
279289
childrte->relid=childOID;
@@ -285,8 +295,52 @@ append_child_relation(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEnt
285295

286296
/* Create RelOptInfo */
287297
childrel=build_simple_rel(root,childRTindex,RELOPT_BASEREL);
288-
childrel->reltargetlist=rel->reltargetlist;
289-
childrel->baserestrictinfo=list_copy(rel->baserestrictinfo);
298+
299+
/* copy targetlist */
300+
childrel->reltargetlist=NIL;
301+
foreach(lc,rel->reltargetlist)
302+
{
303+
Node*new_target;
304+
305+
node= (Node*)lfirst(lc);
306+
new_target=copyObject(node);
307+
change_varnos(new_target,rel->relid,childrel->relid);
308+
childrel->reltargetlist=lappend(childrel->reltargetlist,new_target);
309+
}
310+
311+
/* copy restrictions */
312+
childrel->baserestrictinfo=NIL;
313+
foreach(lc,rel->baserestrictinfo)
314+
{
315+
RestrictInfo*new_rinfo;
316+
317+
node= (Node*)lfirst(lc);
318+
new_rinfo=copyObject(node);
319+
320+
/* replace old relids with new ones */
321+
change_varnos(new_rinfo->clause,rel->relid,childrel->relid);
322+
change_varnos(new_rinfo->left_em->em_expr,rel->relid,childrel->relid);
323+
change_varnos(new_rinfo->right_em->em_expr,rel->relid,childrel->relid);
324+
325+
/* TODO: find some elegant way to do this */
326+
if (bms_is_member(rel->relid,new_rinfo->clause_relids))
327+
{
328+
bms_del_member(new_rinfo->clause_relids,rel->relid);
329+
bms_add_member(new_rinfo->clause_relids,childrel->relid);
330+
}
331+
if (bms_is_member(rel->relid,new_rinfo->left_relids))
332+
{
333+
bms_del_member(new_rinfo->left_relids,rel->relid);
334+
bms_add_member(new_rinfo->left_relids,childrel->relid);
335+
}
336+
if (bms_is_member(rel->relid,new_rinfo->right_relids))
337+
{
338+
bms_del_member(new_rinfo->right_relids,rel->relid);
339+
bms_add_member(new_rinfo->right_relids,childrel->relid);
340+
}
341+
childrel->baserestrictinfo=lappend(childrel->baserestrictinfo,
342+
new_rinfo);
343+
}
290344

291345
/* Build an AppendRelInfo for this parent and child */
292346
appinfo=makeNode(AppendRelInfo);
@@ -301,6 +355,37 @@ append_child_relation(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEnt
301355
}
302356

303357

358+
void
359+
change_varnos(Node*node,Oidold_varno,Oidnew_varno)
360+
{
361+
change_varno_contextcontext;
362+
context.old_varno=old_varno;
363+
context.new_varno=new_varno;
364+
365+
change_varno_walker(node,&context);
366+
}
367+
368+
void
369+
change_varno_walker(Node*node,change_varno_context*context)
370+
{
371+
if (node==NULL)
372+
return false;
373+
if (IsA(node,Var))
374+
{
375+
Var*var= (Var*)node;
376+
377+
if (var->varno==context->old_varno)
378+
var->varno=context->new_varno;
379+
return false;
380+
}
381+
382+
/* Should not find an unplanned subquery */
383+
Assert(!IsA(node,Query));
384+
385+
returnexpression_tree_walker(node,change_varno_walker, (void*)context);
386+
}
387+
388+
304389
/*
305390
* Recursive function to walk through conditions tree
306391
*/
@@ -368,10 +453,10 @@ handle_binary_opexpr(const PartRelationInfo *prel, const OpExpr *expr,
368453
returnALL;
369454
}
370455
casePT_RANGE:
371-
if (c->consttype==DATEOID)
372-
value=TimeTzADTPGetDatum(date2timestamp_no_overflow(c->constvalue));
373-
else
374-
value=c->constvalue;
456+
//if (c->consttype == DATEOID)
457+
//value = TimeTzADTPGetDatum(date2timestamp_no_overflow(c->constvalue));
458+
//else
459+
value=c->constvalue;
375460
rangerel= (RangeRelation*)
376461
hash_search(range_restrictions, (constvoid*)&prel->oid,HASH_FIND,NULL);
377462
if (rangerel!=NULL)

‎contrib/pathman/pathman.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ typedef struct PartRelationInfo
5555
intchildren_count;
5656
PartTypeparttype;
5757
Indexattnum;
58-
AttTypeatttype;
58+
Oidatttype;
5959

6060
}PartRelationInfo;
6161

‎contrib/pathman/sql/init.sql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ CREATE TABLE IF NOT EXISTS @extschema@.pg_pathman_hash_rels (
2525
CREATETABLEIF NOT EXISTS @extschema@.pg_pathman_range_rels (
2626
idSERIALPRIMARY KEY,
2727
parentVARCHAR(127),
28-
min_intINTEGER,
29-
max_intINTEGER,
30-
min_dtTIMESTAMPTZ,
31-
max_dtTIMESTAMPTZ,
28+
min_numDOUBLE PRECISION,
29+
max_numDOUBLE PRECISION,
30+
min_dtTIMESTAMP,
31+
max_dtTIMESTAMP,
3232
childVARCHAR(127)
3333
);
3434

‎contrib/pathman/sql/range.sql

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
CREATE OR REPLACEFUNCTIONcreate_range_partitions(
55
v_relationTEXT
66
, v_attributeTEXT
7-
, v_start_timestampTIMESTAMPTZ
7+
, v_start_timestampTIMESTAMP
88
, v_interval INTERVAL
99
, v_premakeINTEGER)
1010
RETURNS VOIDAS
1111
$$
1212
DECLARE
1313
v_relidINTEGER;
14+
v_dtTIMESTAMP;
1415
BEGIN
1516
SELECT relfilenode INTO v_relid
1617
FROM pg_classWHERE relname= v_relation;
@@ -19,14 +20,14 @@ BEGIN
1920
RAISE EXCEPTION'Reltion "%s" has already been partitioned', v_relation;
2021
END IF;
2122

22-
IF v_start_timestamp!=NULL THEN
23-
v_start_timestamp := v_start_timestamp;
23+
IFNOTv_start_timestampISNULL THEN
24+
v_dt := v_start_timestamp;
2425
ELSE
25-
SELECTcurrent_date INTOv_start_timestamp;
26+
SELECTcurrent_date INTOv_dt;
2627
END IF;
2728

2829
PERFORM create_single_range_partition(v_relation
29-
,v_start_timestamp
30+
,v_dt
3031
, v_interval);
3132

3233
INSERT INTO pg_pathman_rels (
@@ -51,28 +52,43 @@ $$ LANGUAGE plpgsql;
5152
*/
5253
CREATE OR REPLACEFUNCTIONappend_range_partitions(
5354
v_relationTEXT
54-
, v_intervalINTERVAL
55+
, v_intervalTEXT
5556
, v_premakeINTEGER)
5657
RETURNS VOIDAS
5758
$$
5859
DECLARE
59-
v_part_timestampTIMESTAMPTZ;
60+
v_part_timestampTIMESTAMP;
61+
v_part_numDOUBLE PRECISION;
6062
v_partnumINTEGER;
6163
v_relidINTEGER;
6264
BEGIN
6365
SELECT relfilenode INTO v_relid
6466
FROM pg_classWHERE relname= v_relation;
6567

66-
SELECTmax(max_dt) INTO v_part_timestampFROM pg_pathman_range_rels;
68+
SELECTmax(max_dt),max(max_num)
69+
INTO v_part_timestamp, v_part_num
70+
FROM pg_pathman_range_rels
71+
WHERE parent= v_relation;
6772

6873
/* Create partitions and update pg_pathman configuration*/
69-
FOR v_partnumIN0..v_premake-1
70-
LOOP
71-
PERFORM create_single_range_partition(v_relation
72-
, v_part_timestamp
73-
, v_interval);
74-
v_part_timestamp := v_part_timestamp+ v_interval;
75-
END LOOP;
74+
if NOT v_part_timestamp ISNULL THEN
75+
FOR v_partnumIN0..v_premake-1
76+
LOOP
77+
PERFORM create_single_range_partition(v_relation
78+
, v_part_timestamp
79+
, v_interval::INTERVAL);
80+
v_part_timestamp := v_part_timestamp+ v_interval::INTERVAL;
81+
END LOOP;
82+
ELSIF NOT v_part_num ISNULL THEN
83+
/* Numerical range partitioning*/
84+
FOR v_partnumIN0..v_premake-1
85+
LOOP
86+
PERFORM create_single_range_partition(v_relation
87+
, v_part_timestamp
88+
, v_interval::INTEGER);
89+
v_part_timestamp := v_part_timestamp+ v_interval;
90+
END LOOP;
91+
END IF;
7692

7793
PERFORM pg_pathman_on_update_partitions(v_relid);
7894
END

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp