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

Commit13cc7eb

Browse files
committed
Clean up two rather nasty bugs in operator selection code.
1. If there is exactly one pg_operator entry of the right name and oprkind,oper() and related routines would return that entry whether its input typehad anything to do with the request or not. This is just prematureoptimization: we shouldn't return the single candidate until after we verifythat it really is a valid candidate, ie, is at least coercion-compatiblewith the given types.2. oper() and related routines only promise a coercion-compatible result.Unfortunately, there were quite a few callers that assumed the returnedoperator is binary-compatible with the given datatype; they would proceedto call it without making any datatype coercions. These callers includesorting, grouping, aggregation, and VACUUM ANALYZE. In general I thinkit is appropriate for these callers to require an exact or binary-compatiblematch, so I've added a new routine compatible_oper() that only succeeds ifit can find an operator that doesn't require any run-time conversions.Callers now call oper() or compatible_oper() depending on whether they areprepared to deal with type conversion or not.The upshot of these bugs is revealed by the following silliness in PL/Tcl'sselftest: it creates an operator @< on int4, and then tries to use it tosort a char(N) column. The system would let it do that :-( (and evidentlyhas done so since 6.3 :-( :-(). The result in this case was just a sillysort order, but the reverse combination would've provoked coredump fromtrying to dereference integers. With this fix you get more reasonablebehavior:pltcl_test=# select * from T_pkey1 order by key1, key2 using @<;ERROR: Unable to identify an operator '@<' for types 'bpchar' and 'bpchar' You will have to retype this query using an explicit cast
1 parentb24b2a5 commit13cc7eb

File tree

9 files changed

+162
-90
lines changed

9 files changed

+162
-90
lines changed

‎src/backend/commands/analyze.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.13 2001/01/24 19:42:52 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.14 2001/02/16 03:16:58 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -152,7 +152,6 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
152152
for (i=0;i<attr_cnt;i++)
153153
{
154154
Operatorfunc_operator;
155-
Form_pg_operatorpgopform;
156155
VacAttrStats*stats;
157156

158157
stats=&vacattrstats[i];
@@ -167,21 +166,25 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
167166
stats->best_cnt=stats->guess1_cnt=stats->guess1_hits=stats->guess2_hits=0;
168167
stats->max_cnt=stats->min_cnt=stats->null_cnt=stats->nonnull_cnt=0;
169168

170-
func_operator=oper("=",stats->attr->atttypid,stats->attr->atttypid, true);
169+
func_operator=compatible_oper("=",
170+
stats->attr->atttypid,
171+
stats->attr->atttypid,
172+
true);
171173
if (func_operator!=NULL)
172174
{
173-
pgopform= (Form_pg_operator)GETSTRUCT(func_operator);
174-
fmgr_info(pgopform->oprcode,&(stats->f_cmpeq));
175+
fmgr_info(oprfuncid(func_operator),&(stats->f_cmpeq));
175176
ReleaseSysCache(func_operator);
176177
}
177178
else
178179
stats->f_cmpeq.fn_addr=NULL;
179180

180-
func_operator=oper("<",stats->attr->atttypid,stats->attr->atttypid, true);
181+
func_operator=compatible_oper("<",
182+
stats->attr->atttypid,
183+
stats->attr->atttypid,
184+
true);
181185
if (func_operator!=NULL)
182186
{
183-
pgopform= (Form_pg_operator)GETSTRUCT(func_operator);
184-
fmgr_info(pgopform->oprcode,&(stats->f_cmplt));
187+
fmgr_info(oprfuncid(func_operator),&(stats->f_cmplt));
185188
stats->op_cmplt=oprid(func_operator);
186189
ReleaseSysCache(func_operator);
187190
}
@@ -191,11 +194,13 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
191194
stats->op_cmplt=InvalidOid;
192195
}
193196

194-
func_operator=oper(">",stats->attr->atttypid,stats->attr->atttypid, true);
197+
func_operator=compatible_oper(">",
198+
stats->attr->atttypid,
199+
stats->attr->atttypid,
200+
true);
195201
if (func_operator!=NULL)
196202
{
197-
pgopform= (Form_pg_operator)GETSTRUCT(func_operator);
198-
fmgr_info(pgopform->oprcode,&(stats->f_cmpgt));
203+
fmgr_info(oprfuncid(func_operator),&(stats->f_cmpgt));
199204
ReleaseSysCache(func_operator);
200205
}
201206
else

‎src/backend/executor/nodeAgg.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
* Portions Copyright (c) 1994, Regents of the University of California
4747
*
4848
* IDENTIFICATION
49-
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.74 2001/02/15 21:47:08 tgl Exp $
49+
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.75 2001/02/16 03:16:57 tgl Exp $
5050
*
5151
*-------------------------------------------------------------------------
5252
*/
@@ -909,21 +909,19 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
909909
* (Consider COUNT(*).)
910910
*/
911911
OidinputType=exprType(aggref->target);
912-
Operatoreq_operator;
913-
Form_pg_operatorpgopform;
912+
Oideq_function;
914913

915914
peraggstate->inputType=inputType;
916915
get_typlenbyval(inputType,
917916
&peraggstate->inputtypeLen,
918917
&peraggstate->inputtypeByVal);
919918

920-
eq_operator=oper("=",inputType,inputType, true);
921-
if (!HeapTupleIsValid(eq_operator))
919+
eq_function=compatible_oper_funcid("=",inputType,inputType,
920+
true);
921+
if (!OidIsValid(eq_function))
922922
elog(ERROR,"Unable to identify an equality operator for type '%s'",
923923
typeidTypeName(inputType));
924-
pgopform= (Form_pg_operator)GETSTRUCT(eq_operator);
925-
fmgr_info(pgopform->oprcode,&(peraggstate->equalfn));
926-
ReleaseSysCache(eq_operator);
924+
fmgr_info(eq_function,&(peraggstate->equalfn));
927925
peraggstate->sortOperator=any_ordering_op(inputType);
928926
peraggstate->sortstate=NULL;
929927
}

‎src/backend/executor/nodeGroup.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* locate group boundaries.
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.40 2001/01/24 19:42:54 momjian Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.41 2001/02/16 03:16:57 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -495,16 +495,13 @@ execTuplesMatchPrepare(TupleDesc tupdesc,
495495
{
496496
AttrNumberatt=matchColIdx[i];
497497
Oidtypid=tupdesc->attrs[att-1]->atttypid;
498-
Operatoreq_operator;
499-
Form_pg_operatorpgopform;
498+
Oideq_function;
500499

501-
eq_operator=oper("=",typid,typid, true);
502-
if (!HeapTupleIsValid(eq_operator))
500+
eq_function=compatible_oper_funcid("=",typid,typid, true);
501+
if (!OidIsValid(eq_function))
503502
elog(ERROR,"Unable to identify an equality operator for type '%s'",
504503
typeidTypeName(typid));
505-
pgopform= (Form_pg_operator)GETSTRUCT(eq_operator);
506-
fmgr_info(pgopform->oprcode,&eqfunctions[i]);
507-
ReleaseSysCache(eq_operator);
504+
fmgr_info(eq_function,&eqfunctions[i]);
508505
}
509506

510507
returneqfunctions;

‎src/backend/optimizer/path/indxpath.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.101 2001/01/24 19:42:57momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.102 2001/02/16 03:16:57tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -878,7 +878,7 @@ indexable_operator(Expr *clause, Oid opclass, Oid relam,
878878
* (In theory this might find a non-semantically-comparable operator,
879879
* but in practice that seems pretty unlikely for binary-compatible types.)
880880
*/
881-
new_op=oper_oid(opname,indexkeytype,indexkeytype, true);
881+
new_op=compatible_oper_opid(opname,indexkeytype,indexkeytype, true);
882882

883883
if (OidIsValid(new_op))
884884
{

‎src/backend/optimizer/plan/initsplan.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.56 2001/01/24 19:42:58 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.57 2001/02/16 03:16:57 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -617,7 +617,7 @@ process_implied_equality(Query *root, Node *item1, Node *item2,
617617
*/
618618
ltype=exprType(item1);
619619
rtype=exprType(item2);
620-
eq_operator=oper("=",ltype,rtype, true);
620+
eq_operator=compatible_oper("=",ltype,rtype, true);
621621
if (!HeapTupleIsValid(eq_operator))
622622
{
623623
/*

‎src/backend/parser/parse_clause.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.76 2001/02/14 21:35:03 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.77 2001/02/16 03:16:57 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1155,10 +1155,10 @@ addTargetToSortList(TargetEntry *tle, List *sortlist, List *targetlist,
11551155
sortcl->tleSortGroupRef=assignSortGroupRef(tle,targetlist);
11561156

11571157
if (opname)
1158-
sortcl->sortop=oper_oid(opname,
1159-
tle->resdom->restype,
1160-
tle->resdom->restype,
1161-
false);
1158+
sortcl->sortop=compatible_oper_opid(opname,
1159+
tle->resdom->restype,
1160+
tle->resdom->restype,
1161+
false);
11621162
else
11631163
sortcl->sortop=any_ordering_op(tle->resdom->restype);
11641164

‎src/backend/parser/parse_expr.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.90 2001/02/14 21:35:04 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.91 2001/02/16 03:16:58 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -383,6 +383,11 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
383383
lexpr=lfirst(left_list);
384384
left_list=lnext(left_list);
385385

386+
/*
387+
* It's OK to use oper() not compatible_oper() here,
388+
* because make_subplan() will insert type coercion
389+
* calls if needed.
390+
*/
386391
optup=oper(op,
387392
exprType(lexpr),
388393
exprType(tent->expr),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp