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

Commitc9f287e

Browse files
committed
Further fixes for bogus list-slinging, scribbling on input, etc in type
coercion code. I'm beginning to wonder why we have separate candidateselection routines for functions, operators, and aggregates --- shouldn'tthis code all be unified? But meanwhile,SELECT 'a' LIKE 'a';finally works; the code for dealing with unknown input types for operatorswas pretty busted.
1 parent1d75298 commitc9f287e

File tree

2 files changed

+84
-35
lines changed

2 files changed

+84
-35
lines changed

‎src/backend/parser/parse_func.c

Lines changed: 32 additions & 19 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_func.c,v 1.72 2000/02/20 23:04:06 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.73 2000/03/11 23:17:47 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -854,11 +854,6 @@ match_argtypes(int nargs,
854854
* for the function argtype array, attempt to resolve the conflict.
855855
* returns the selected argtype array if the conflict can be resolved,
856856
* otherwise returns NULL.
857-
*
858-
* If all input Oids are UNKNOWNOID, then try matching with TEXTOID.
859-
* Otherwise, could return first function arguments on list of candidates.
860-
* But for now, return NULL and make the user give a better hint.
861-
* - thomas 1998-03-17
862857
*/
863858
staticOid*
864859
func_select_candidate(intnargs,
@@ -869,12 +864,10 @@ func_select_candidate(int nargs,
869864
CandidateListlast_candidate;
870865
Oid*current_typeids;
871866
inti;
872-
873867
intncandidates;
874868
intnbestMatch,
875869
nmatch,
876-
nident;
877-
870+
ncompat;
878871
CATEGORYslot_category,
879872
current_category;
880873
Oidslot_type,
@@ -893,19 +886,29 @@ func_select_candidate(int nargs,
893886
{
894887
current_typeids=current_candidate->args;
895888
nmatch=0;
896-
nident=0;
889+
ncompat=0;
897890
for (i=0;i<nargs;i++)
898891
{
899-
if ((input_typeids[i]!=UNKNOWNOID)
900-
&& (current_typeids[i]==input_typeids[i]))
901-
nmatch++;
902-
elseif (IS_BINARY_COMPATIBLE(current_typeids[i],input_typeids[i]))
903-
nident++;
892+
if (input_typeids[i]!=UNKNOWNOID)
893+
{
894+
if (current_typeids[i]==input_typeids[i])
895+
nmatch++;
896+
elseif (IS_BINARY_COMPATIBLE(current_typeids[i],
897+
input_typeids[i]))
898+
ncompat++;
899+
}
904900
}
905901

906-
if ((nmatch+nident)==nargs)
902+
/*
903+
* If we find an exact match at all arg positions, we're done;
904+
* there can be only one such candidate.
905+
*/
906+
if (nmatch==nargs)
907907
returncurrent_candidate->args;
908908

909+
/* Otherwise, use match+compat as the score. */
910+
nmatch+=ncompat;
911+
909912
/* take this one as the best choice so far? */
910913
if ((nmatch>nbestMatch)|| (last_candidate==NULL))
911914
{
@@ -933,6 +936,16 @@ func_select_candidate(int nargs,
933936
/*
934937
* Still too many candidates?
935938
* Try assigning types for the unknown columns.
939+
*
940+
* We do this by examining each unknown argument position to see if all the
941+
* candidates agree on the type category of that slot. If so, and if some
942+
* candidates accept the preferred type in that category, eliminate the
943+
* candidates with other input types. If we are down to one candidate
944+
* at the end, we win.
945+
*
946+
* XXX It's kinda bogus to do this left-to-right, isn't it? If we eliminate
947+
* some candidates because they are non-preferred at the first slot, we won't
948+
* notice that they didn't have the same type category for a later slot.
936949
*/
937950
for (i=0;i<nargs;i++)
938951
{
@@ -947,12 +960,12 @@ func_select_candidate(int nargs,
947960
{
948961
current_typeids=current_candidate->args;
949962
current_type=current_typeids[i];
950-
current_category=TypeCategory(current_typeids[i]);
951-
952-
if (slot_category==InvalidOid)
963+
current_category=TypeCategory(current_type);
964+
if (slot_category==INVALID_TYPE)
953965
{
954966
slot_category=current_category;
955967
slot_type=current_type;
968+
last_candidate=current_candidate;
956969
}
957970
elseif (current_category!=slot_category)
958971
{

‎src/backend/parser/parse_oper.c

Lines changed: 52 additions & 16 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_oper.c,v 1.36 2000/02/27 02:48:15 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.37 2000/03/11 23:17:47 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -128,7 +128,7 @@ binary_oper_get_candidates(char *opname,
128128
*
129129
* This routine is new code, replacing binary_oper_select_candidate()
130130
* which dates from v4.2/v1.0.x days. It tries very hard to match up
131-
* operators with types, including allowing typecoersions if necessary.
131+
* operators with types, including allowing typecoercions if necessary.
132132
* The important thing is that the code do as much as possible,
133133
* while _never_ doing the wrong thing, where "the wrong thing" would
134134
* be returning an operator when other better choices are available,
@@ -185,7 +185,7 @@ oper_select_candidate(int nargs,
185185

186186
/*
187187
* Run through all candidates and keep those with the most matches
188-
*onexplicit types. Keep all candidates if none match.
188+
*onexact types. Keep all candidates if none match.
189189
*/
190190
ncandidates=0;
191191
nbestMatch=0;
@@ -236,7 +236,7 @@ oper_select_candidate(int nargs,
236236

237237
/*
238238
* Still too many candidates?
239-
* Now look for candidates which allowcoersion and are preferred types.
239+
* Now look for candidates which allowcoercion and are preferred types.
240240
* Keep all candidates if none match.
241241
*/
242242
ncandidates=0;
@@ -292,6 +292,13 @@ oper_select_candidate(int nargs,
292292
/*
293293
* Still too many candidates?
294294
* Try assigning types for the unknown columns.
295+
*
296+
* First try: if we have an unknown and a non-unknown input, see whether
297+
* there is a candidate all of whose input types are the same as the known
298+
* input type (there can be at most one such candidate). If so, use that
299+
* candidate. NOTE that this is cool only because operators can't
300+
* have more than 2 args, so taking the last non-unknown as current_type
301+
* can yield only one possibility if there is also an unknown.
295302
*/
296303
unknownOids= FALSE;
297304
current_type=UNKNOWNOID;
@@ -314,53 +321,82 @@ oper_select_candidate(int nargs,
314321
nmatch=0;
315322
for (i=0;i<nargs;i++)
316323
{
317-
if (current_type==current_typeids[i]||
318-
IS_BINARY_COMPATIBLE(current_type,current_typeids[i]))
324+
if (current_type==current_typeids[i])
319325
nmatch++;
320326
}
321327
if (nmatch==nargs)
322-
returncandidates->args;
328+
{
329+
/* coercion check here is probably redundant, but be safe */
330+
if (can_coerce_type(nargs,input_typeids,current_typeids))
331+
returncurrent_typeids;
332+
}
323333
}
324334
}
325335

336+
/*
337+
* Second try: examine each unknown argument position to see if all the
338+
* candidates agree on the type category of that slot. If so, and if some
339+
* candidates accept the preferred type in that category, eliminate the
340+
* candidates with other input types. If we are down to one candidate
341+
* at the end, we win.
342+
*
343+
* XXX It's kinda bogus to do this left-to-right, isn't it? If we eliminate
344+
* some candidates because they are non-preferred at the first slot, we won't
345+
* notice that they didn't have the same type category for a later slot.
346+
*/
326347
for (i=0;i<nargs;i++)
327348
{
328349
if (input_typeids[i]==UNKNOWNOID)
329350
{
330351
slot_category=INVALID_TYPE;
331352
slot_type=InvalidOid;
353+
last_candidate=NULL;
332354
for (current_candidate=candidates;
333355
current_candidate!=NULL;
334356
current_candidate=current_candidate->next)
335357
{
336358
current_typeids=current_candidate->args;
337359
current_type=current_typeids[i];
338-
current_category=TypeCategory(current_typeids[i]);
339-
if (slot_category==InvalidOid)
360+
current_category=TypeCategory(current_type);
361+
if (slot_category==INVALID_TYPE)
340362
{
341363
slot_category=current_category;
342364
slot_type=current_type;
365+
last_candidate=current_candidate;
343366
}
344367
elseif (current_category!=slot_category)
368+
{
369+
/* punt if more than one category for this slot */
345370
returnNULL;
371+
}
346372
elseif (current_type!=slot_type)
347373
{
348374
if (IsPreferredType(slot_category,current_type))
349375
{
350376
slot_type=current_type;
377+
/* forget all previous candidates */
351378
candidates=current_candidate;
379+
last_candidate=current_candidate;
352380
}
353-
else
381+
elseif (IsPreferredType(slot_category,slot_type))
354382
{
383+
/* forget this candidate */
384+
if (last_candidate)
385+
last_candidate->next=current_candidate->next;
386+
else
387+
candidates=current_candidate->next;
355388
}
389+
else
390+
last_candidate=current_candidate;
391+
}
392+
else
393+
{
394+
/* keep this candidate */
395+
last_candidate=current_candidate;
356396
}
357397
}
358-
359-
if (slot_type!=InvalidOid)
360-
input_typeids[i]=slot_type;
361-
}
362-
else
363-
{
398+
if (last_candidate)/* terminate rebuilt list */
399+
last_candidate->next=NULL;
364400
}
365401
}
366402

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp