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

Commit9d388e1

Browse files
committed
Fix a pair of related issues with estimation of inequalities that involve
binary-compatible relabeling of one or both operands. examine_variableshould avoid stripping RelabelType from non-variable expressions, so thatthey will continue to have the correct type; and convert_to_scalar shouldjust use that type and ignore the other input type. This isn't perfectbut it beats failing entirely. Per example from Michael Fuhr.
1 parentbb34970 commit9d388e1

File tree

1 file changed

+36
-27
lines changed

1 file changed

+36
-27
lines changed

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

Lines changed: 36 additions & 27 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.173 2005/03/07 04:30:51 momjian Exp $
18+
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.174 2005/03/26 20:55:39 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -2309,14 +2309,17 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
23092309
* constant-folding will ensure that any Const passed to the operator
23102310
* has been reduced to the correct type). However, the boundstypid is
23112311
* the type of some variable that might be only binary-compatible with
2312-
* the declared type; in particular it might be a domain type.Must
2313-
* fold the variable type down to base type so we can recognize it.
2314-
* (But we can skip that lookup if the variable type matches the
2315-
* const.)
2312+
* the declared type; for example it might be a domain type. So we
2313+
* ignore it and work with the valuetypid only.
2314+
*
2315+
* XXX What's really going on here is that we assume that the scalar
2316+
* representations of binary-compatible types are enough alike that we
2317+
* can use a histogram generated with one type's operators to estimate
2318+
* selectivity for the other's. This is outright wrong in some cases ---
2319+
* in particular signed versus unsigned interpretation could trip us up.
2320+
* But it's useful enough in the majority of cases that we do it anyway.
2321+
* Should think about more rigorous ways to do it.
23162322
*/
2317-
if (boundstypid!=valuetypid)
2318-
boundstypid=getBaseType(boundstypid);
2319-
23202323
switch (valuetypid)
23212324
{
23222325
/*
@@ -2337,8 +2340,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
23372340
caseREGCLASSOID:
23382341
caseREGTYPEOID:
23392342
*scaledvalue=convert_numeric_to_scalar(value,valuetypid);
2340-
*scaledlobound=convert_numeric_to_scalar(lobound,boundstypid);
2341-
*scaledhibound=convert_numeric_to_scalar(hibound,boundstypid);
2343+
*scaledlobound=convert_numeric_to_scalar(lobound,valuetypid);
2344+
*scaledhibound=convert_numeric_to_scalar(hibound,valuetypid);
23422345
return true;
23432346

23442347
/*
@@ -2351,8 +2354,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
23512354
caseNAMEOID:
23522355
{
23532356
unsignedchar*valstr=convert_string_datum(value,valuetypid);
2354-
unsignedchar*lostr=convert_string_datum(lobound,boundstypid);
2355-
unsignedchar*histr=convert_string_datum(hibound,boundstypid);
2357+
unsignedchar*lostr=convert_string_datum(lobound,valuetypid);
2358+
unsignedchar*histr=convert_string_datum(hibound,valuetypid);
23562359

23572360
convert_string_to_scalar(valstr,scaledvalue,
23582361
lostr,scaledlobound,
@@ -2387,8 +2390,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
23872390
caseTIMEOID:
23882391
caseTIMETZOID:
23892392
*scaledvalue=convert_timevalue_to_scalar(value,valuetypid);
2390-
*scaledlobound=convert_timevalue_to_scalar(lobound,boundstypid);
2391-
*scaledhibound=convert_timevalue_to_scalar(hibound,boundstypid);
2393+
*scaledlobound=convert_timevalue_to_scalar(lobound,valuetypid);
2394+
*scaledhibound=convert_timevalue_to_scalar(hibound,valuetypid);
23922395
return true;
23932396

23942397
/*
@@ -2398,8 +2401,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
23982401
caseCIDROID:
23992402
caseMACADDROID:
24002403
*scaledvalue=convert_network_to_scalar(value,valuetypid);
2401-
*scaledlobound=convert_network_to_scalar(lobound,boundstypid);
2402-
*scaledhibound=convert_network_to_scalar(hibound,boundstypid);
2404+
*scaledlobound=convert_network_to_scalar(lobound,valuetypid);
2405+
*scaledhibound=convert_network_to_scalar(hibound,valuetypid);
24032406
return true;
24042407
}
24052408
/* Don't know how to convert */
@@ -2848,8 +2851,7 @@ convert_timevalue_to_scalar(Datum value, Oid typid)
28482851
*
28492852
* Outputs: (these are valid only if TRUE is returned)
28502853
**vardata: gets information about variable (see examine_variable)
2851-
**other: gets other clause argument, stripped of binary relabeling,
2852-
*and aggressively reduced to a constant
2854+
**other: gets other clause argument, aggressively reduced to a constant
28532855
**varonleft: set TRUE if variable is on the left, FALSE if on the right
28542856
*
28552857
* Returns TRUE if a variable is identified, otherwise FALSE.
@@ -2939,7 +2941,8 @@ get_join_variables(Query *root, List *args,
29392941
*varRelid: see specs for restriction selectivity functions
29402942
*
29412943
* Outputs: *vardata is filled as follows:
2942-
*var: the input expression (with any binary relabeling stripped)
2944+
*var: the input expression (with any binary relabeling stripped, if
2945+
*it is or contains a variable; but otherwise the type is preserved)
29432946
*rel: RelOptInfo for relation containing variable; NULL if expression
29442947
*contains no Vars (NOTE this could point to a RelOptInfo of a
29452948
*subquery, not one in the current query).
@@ -2955,27 +2958,29 @@ static void
29552958
examine_variable(Query*root,Node*node,intvarRelid,
29562959
VariableStatData*vardata)
29572960
{
2961+
Node*basenode;
29582962
Relidsvarnos;
29592963
RelOptInfo*onerel;
29602964

29612965
/* Make sure we don't return dangling pointers in vardata */
29622966
MemSet(vardata,0,sizeof(VariableStatData));
29632967

2964-
/*Ignore any binary-compatible relabeling */
2968+
/*Look inside any binary-compatible relabeling */
29652969

29662970
if (IsA(node,RelabelType))
2967-
node= (Node*) ((RelabelType*)node)->arg;
2968-
2969-
vardata->var=node;
2971+
basenode= (Node*) ((RelabelType*)node)->arg;
2972+
else
2973+
basenode=node;
29702974

29712975
/* Fast path for a simple Var */
29722976

2973-
if (IsA(node,Var)&&
2974-
(varRelid==0||varRelid== ((Var*)node)->varno))
2977+
if (IsA(basenode,Var)&&
2978+
(varRelid==0||varRelid== ((Var*)basenode)->varno))
29752979
{
2976-
Var*var= (Var*)node;
2980+
Var*var= (Var*)basenode;
29772981
Oidrelid;
29782982

2983+
vardata->var=basenode;/* return Var without relabeling */
29792984
vardata->rel=find_base_rel(root,var->varno);
29802985
vardata->atttype=var->vartype;
29812986
vardata->atttypmod=var->vartypmod;
@@ -3009,7 +3014,7 @@ examine_variable(Query *root, Node *node, int varRelid,
30093014
* membership.Note that when varRelid isn't zero, only vars of that
30103015
* relation are considered "real" vars.
30113016
*/
3012-
varnos=pull_varnos(node);
3017+
varnos=pull_varnos(basenode);
30133018

30143019
onerel=NULL;
30153020

@@ -3024,6 +3029,7 @@ examine_variable(Query *root, Node *node, int varRelid,
30243029
onerel=find_base_rel(root,
30253030
(varRelid ?varRelid :bms_singleton_member(varnos)));
30263031
vardata->rel=onerel;
3032+
node=basenode;/* strip any relabeling */
30273033
}
30283034
/* else treat it as a constant */
30293035
break;
@@ -3032,11 +3038,13 @@ examine_variable(Query *root, Node *node, int varRelid,
30323038
{
30333039
/* treat it as a variable of a join relation */
30343040
vardata->rel=find_join_rel(root,varnos);
3041+
node=basenode;/* strip any relabeling */
30353042
}
30363043
elseif (bms_is_member(varRelid,varnos))
30373044
{
30383045
/* ignore the vars belonging to other relations */
30393046
vardata->rel=find_base_rel(root,varRelid);
3047+
node=basenode;/* strip any relabeling */
30403048
/* note: no point in expressional-index search here */
30413049
}
30423050
/* else treat it as a constant */
@@ -3045,6 +3053,7 @@ examine_variable(Query *root, Node *node, int varRelid,
30453053

30463054
bms_free(varnos);
30473055

3056+
vardata->var=node;
30483057
vardata->atttype=exprType(node);
30493058
vardata->atttypmod=exprTypmod(node);
30503059

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp