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

Commit7b7df9f

Browse files
committed
Add hooks to let plugins override the planner's lookups in pg_statistic.
Simon Riggs, with some editorialization by me.
1 parentbc965e8 commit7b7df9f

File tree

4 files changed

+109
-23
lines changed

4 files changed

+109
-23
lines changed

‎src/backend/utils/adt/selfuncs.c

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.253 2008/08/25 22:42:34 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.254 2008/09/28 19:51:40 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -119,6 +119,10 @@
119119
#include"utils/syscache.h"
120120

121121

122+
/* Hooks for plugins to get control when we ask for stats */
123+
get_relation_stats_hook_typeget_relation_stats_hook=NULL;
124+
get_index_stats_hook_typeget_index_stats_hook=NULL;
125+
122126
staticdoublevar_eq_const(VariableStatData*vardata,Oidoperator,
123127
Datumconstval,boolconstisnull,
124128
boolvaronleft);
@@ -2935,7 +2939,7 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows)
29352939
* complicated.
29362940
*/
29372941
examine_variable(root,groupexpr,0,&vardata);
2938-
if (vardata.statsTuple!=NULL||vardata.isunique)
2942+
if (HeapTupleIsValid(vardata.statsTuple)||vardata.isunique)
29392943
{
29402944
varinfos=add_unique_group_var(root,varinfos,
29412945
groupexpr,&vardata);
@@ -3942,6 +3946,7 @@ get_join_variables(PlannerInfo *root, List *args, SpecialJoinInfo *sjinfo,
39423946
*subquery, not one in the current query).
39433947
*statsTuple: the pg_statistic entry for the variable, if one exists;
39443948
*otherwise NULL.
3949+
*freefunc: pointer to a function to release statsTuple with.
39453950
*vartype: exposed type of the expression; this should always match
39463951
*the declared input type of the operator we are estimating for.
39473952
*atttype, atttypmod: type data to pass to get_attstatsslot(). This is
@@ -3986,7 +3991,18 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
39863991

39873992
rte=root->simple_rte_array[var->varno];
39883993

3989-
if (rte->inh)
3994+
if (get_relation_stats_hook&&
3995+
(*get_relation_stats_hook) (root,rte,var->varattno,vardata))
3996+
{
3997+
/*
3998+
* The hook took control of acquiring a stats tuple. If it
3999+
* did supply a tuple, it'd better have supplied a freefunc.
4000+
*/
4001+
if (HeapTupleIsValid(vardata->statsTuple)&&
4002+
!vardata->freefunc)
4003+
elog(ERROR,"no function provided to release variable stats with");
4004+
}
4005+
elseif (rte->inh)
39904006
{
39914007
/*
39924008
* XXX This means the Var represents a column of an append
@@ -4000,6 +4016,7 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
40004016
ObjectIdGetDatum(rte->relid),
40014017
Int16GetDatum(var->varattno),
40024018
0,0);
4019+
vardata->freefunc=ReleaseSysCache;
40034020
}
40044021
else
40054022
{
@@ -4116,10 +4133,28 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
41164133
index->indpred==NIL)
41174134
vardata->isunique= true;
41184135
/* Has it got stats? */
4119-
vardata->statsTuple=SearchSysCache(STATRELATT,
4120-
ObjectIdGetDatum(index->indexoid),
4121-
Int16GetDatum(pos+1),
4122-
0,0);
4136+
if (get_index_stats_hook&&
4137+
(*get_index_stats_hook) (root,index->indexoid,
4138+
pos+1,vardata))
4139+
{
4140+
/*
4141+
* The hook took control of acquiring a stats
4142+
* tuple. If it did supply a tuple, it'd better
4143+
* have supplied a freefunc.
4144+
*/
4145+
if (HeapTupleIsValid(vardata->statsTuple)&&
4146+
!vardata->freefunc)
4147+
elog(ERROR,"no function provided to release variable stats with");
4148+
}
4149+
else
4150+
{
4151+
vardata->statsTuple=
4152+
SearchSysCache(STATRELATT,
4153+
ObjectIdGetDatum(index->indexoid),
4154+
Int16GetDatum(pos+1),
4155+
0,0);
4156+
vardata->freefunc=ReleaseSysCache;
4157+
}
41234158
if (vardata->statsTuple)
41244159
break;
41254160
}
@@ -5551,7 +5586,7 @@ btcostestimate(PG_FUNCTION_ARGS)
55515586
double*indexCorrelation= (double*)PG_GETARG_POINTER(7);
55525587
Oidrelid;
55535588
AttrNumbercolnum;
5554-
HeapTupletuple;
5589+
VariableStatDatavardata;
55555590
doublenumIndexTuples;
55565591
List*indexBoundQuals;
55575592
intindexcol;
@@ -5756,17 +5791,34 @@ btcostestimate(PG_FUNCTION_ARGS)
57565791
colnum=1;
57575792
}
57585793

5759-
tuple=SearchSysCache(STATRELATT,
5760-
ObjectIdGetDatum(relid),
5761-
Int16GetDatum(colnum),
5762-
0,0);
5794+
MemSet(&vardata,0,sizeof(vardata));
57635795

5764-
if (HeapTupleIsValid(tuple))
5796+
if (get_index_stats_hook&&
5797+
(*get_index_stats_hook) (root,relid,colnum,&vardata))
5798+
{
5799+
/*
5800+
* The hook took control of acquiring a stats tuple. If it did supply
5801+
* a tuple, it'd better have supplied a freefunc.
5802+
*/
5803+
if (HeapTupleIsValid(vardata.statsTuple)&&
5804+
!vardata.freefunc)
5805+
elog(ERROR,"no function provided to release variable stats with");
5806+
}
5807+
else
5808+
{
5809+
vardata.statsTuple=SearchSysCache(STATRELATT,
5810+
ObjectIdGetDatum(relid),
5811+
Int16GetDatum(colnum),
5812+
0,0);
5813+
vardata.freefunc=ReleaseSysCache;
5814+
}
5815+
5816+
if (HeapTupleIsValid(vardata.statsTuple))
57655817
{
57665818
float4*numbers;
57675819
intnnumbers;
57685820

5769-
if (get_attstatsslot(tuple,InvalidOid,0,
5821+
if (get_attstatsslot(vardata.statsTuple,InvalidOid,0,
57705822
STATISTIC_KIND_CORRELATION,
57715823
index->fwdsortop[0],
57725824
NULL,NULL,&numbers,&nnumbers))
@@ -5783,7 +5835,7 @@ btcostestimate(PG_FUNCTION_ARGS)
57835835

57845836
free_attstatsslot(InvalidOid,NULL,0,numbers,nnumbers);
57855837
}
5786-
elseif (get_attstatsslot(tuple,InvalidOid,0,
5838+
elseif (get_attstatsslot(vardata.statsTuple,InvalidOid,0,
57875839
STATISTIC_KIND_CORRELATION,
57885840
index->revsortop[0],
57895841
NULL,NULL,&numbers,&nnumbers))
@@ -5800,9 +5852,10 @@ btcostestimate(PG_FUNCTION_ARGS)
58005852

58015853
free_attstatsslot(InvalidOid,NULL,0,numbers,nnumbers);
58025854
}
5803-
ReleaseSysCache(tuple);
58045855
}
58055856

5857+
ReleaseVariableStats(vardata);
5858+
58065859
PG_RETURN_VOID();
58075860
}
58085861

‎src/backend/utils/cache/lsyscache.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.159 2008/08/02 21:32:00 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.160 2008/09/28 19:51:40 tgl Exp $
1111
*
1212
* NOTES
1313
* Eventually, the index information should go through here, too.
@@ -35,6 +35,9 @@
3535
#include"utils/lsyscache.h"
3636
#include"utils/syscache.h"
3737

38+
/* Hook for plugins to get control in get_attavgwidth() */
39+
get_attavgwidth_hook_typeget_attavgwidth_hook=NULL;
40+
3841

3942
/*---------- AMOP CACHES ---------- */
4043

@@ -2492,20 +2495,30 @@ get_typmodout(Oid typid)
24922495
*
24932496
* Given the table and attribute number of a column, get the average
24942497
* width of entries in the column. Return zero if no data available.
2498+
*
2499+
* Calling a hook at this point looks somewhat strange, but is required
2500+
* because the optimizer calls this function without any other way for
2501+
* plug-ins to control the result.
24952502
*/
24962503
int32
24972504
get_attavgwidth(Oidrelid,AttrNumberattnum)
24982505
{
24992506
HeapTupletp;
2507+
int32stawidth;
25002508

2509+
if (get_attavgwidth_hook)
2510+
{
2511+
stawidth= (*get_attavgwidth_hook) (relid,attnum);
2512+
if (stawidth>0)
2513+
returnstawidth;
2514+
}
25012515
tp=SearchSysCache(STATRELATT,
25022516
ObjectIdGetDatum(relid),
25032517
Int16GetDatum(attnum),
25042518
0,0);
25052519
if (HeapTupleIsValid(tp))
25062520
{
2507-
int32stawidth= ((Form_pg_statistic)GETSTRUCT(tp))->stawidth;
2508-
2521+
stawidth= ((Form_pg_statistic)GETSTRUCT(tp))->stawidth;
25092522
ReleaseSysCache(tp);
25102523
if (stawidth>0)
25112524
returnstawidth;
@@ -2523,6 +2536,9 @@ get_attavgwidth(Oid relid, AttrNumber attnum)
25232536
* already-looked-up tuple in the pg_statistic cache. We do this since
25242537
* most callers will want to extract more than one value from the cache
25252538
* entry, and we don't want to repeat the cache lookup unnecessarily.
2539+
* Also, this API allows this routine to be used with statistics tuples
2540+
* that have been provided by a stats hook and didn't really come from
2541+
* pg_statistic.
25262542
*
25272543
* statstuple: pg_statistics tuple to be examined.
25282544
* atttype: type OID of attribute (can be InvalidOid if values == NULL).

‎src/include/utils/lsyscache.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.125 2008/08/02 21:32:01 tgl Exp $
9+
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.126 2008/09/28 19:51:40 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -26,6 +26,10 @@ typedef enum IOFuncSelector
2626
IOFunc_send
2727
}IOFuncSelector;
2828

29+
/* Hook for plugins to get control in get_attavgwidth() */
30+
typedefint32 (*get_attavgwidth_hook_type) (Oidrelid,AttrNumberattnum);
31+
externPGDLLIMPORTget_attavgwidth_hook_typeget_attavgwidth_hook;
32+
2933
externboolop_in_opfamily(Oidopno,Oidopfamily);
3034
externintget_op_opfamily_strategy(Oidopno,Oidopfamily);
3135
externvoidget_op_opfamily_properties(Oidopno,Oidopfamily,

‎src/include/utils/selfuncs.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
11-
* $PostgreSQL: pgsql/src/include/utils/selfuncs.h,v 1.46 2008/08/16 00:01:38 tgl Exp $
11+
* $PostgreSQL: pgsql/src/include/utils/selfuncs.h,v 1.47 2008/09/28 19:51:40 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -64,12 +64,13 @@
6464

6565

6666
/* Return data from examine_variable and friends */
67-
typedefstruct
67+
typedefstructVariableStatData
6868
{
6969
Node*var;/* the Var or expression tree */
7070
RelOptInfo*rel;/* Relation, or NULL if not identifiable */
7171
HeapTuplestatsTuple;/* pg_statistic tuple, or NULL if none */
7272
/* NB: if statsTuple!=NULL, it must be freed when caller is done */
73+
void(*freefunc) (HeapTupletuple);/* how to free statsTuple */
7374
Oidvartype;/* exposed type of expression */
7475
Oidatttype;/* type to pass to get_attstatsslot */
7576
int32atttypmod;/* typmod to pass to get_attstatsslot */
@@ -79,7 +80,7 @@ typedef struct
7980
#defineReleaseVariableStats(vardata) \
8081
do { \
8182
if (HeapTupleIsValid((vardata).statsTuple)) \
82-
ReleaseSysCache((vardata).statsTuple); \
83+
(* (vardata).freefunc)((vardata).statsTuple); \
8384
} while(0)
8485

8586

@@ -97,6 +98,18 @@ typedef enum
9798

9899
/* selfuncs.c */
99100

101+
/* Hooks for plugins to get control when we ask for stats */
102+
typedefbool (*get_relation_stats_hook_type) (PlannerInfo*root,
103+
RangeTblEntry*rte,
104+
AttrNumberattnum,
105+
VariableStatData*vardata);
106+
externPGDLLIMPORTget_relation_stats_hook_typeget_relation_stats_hook;
107+
typedefbool (*get_index_stats_hook_type) (PlannerInfo*root,
108+
OidindexOid,
109+
AttrNumberindexattnum,
110+
VariableStatData*vardata);
111+
externPGDLLIMPORTget_index_stats_hook_typeget_index_stats_hook;
112+
100113
externvoidexamine_variable(PlannerInfo*root,Node*node,intvarRelid,
101114
VariableStatData*vardata);
102115
externboolget_restriction_variable(PlannerInfo*root,List*args,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp