Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5253c51

Browse files
committed
Fix broken list-slinging logic in func_select_candidate and
agg_select_candidate, which could cause them to keep more candidates than they should and thus fail to select a single match. I had previously fixed the identical bug in oper_select_candidate, but didn't realize that the same error was repeated over here. Also, repair func_select_candidate's curious notion that it could scribble on the input type-OID vector. That was causing failure to apply necessary type coercion later on, leading to malfunction of examples such as select date('now').
1 parent f4d108a commit 5253c51

File tree

1 file changed

+42
-24
lines changed

1 file changed

+42
-24
lines changed

src/backend/parser/parse_func.c

Lines changed: 42 additions & 24 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.69 2000/02/15 03:37:47 thomas Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.70 2000/02/20 06:35:08 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -45,14 +45,13 @@ static Oid **argtype_inherit(int nargs, Oid *oid_array);
4545

4646
static int find_inheritors(Oid relid, Oid **supervec);
4747
static CandidateList func_get_candidates(char *funcname, int nargs);
48-
static bool
49-
func_get_detail(char *funcname,
50-
int nargs,
51-
Oid *oid_array,
52-
Oid *funcid, /* return value */
53-
Oid *rettype, /* return value */
54-
bool *retset, /* return value */
55-
Oid **true_typeids);
48+
static bool func_get_detail(char *funcname,
49+
int nargs,
50+
Oid *oid_array,
51+
Oid *funcid, /* return value */
52+
Oid *rettype, /* return value */
53+
bool *retset, /* return value */
54+
Oid **true_typeids);
5655
static Oid **gen_cross_product(InhPaths *arginh, int nargs);
5756
static void make_arguments(ParseState *pstate,
5857
int nargs,
@@ -228,10 +227,11 @@ agg_select_candidate(Oid typeid, CandidateList candidates)
228227
}
229228
}
230229
/* otherwise, don't bother keeping this one around... */
231-
else if (last_candidate != NULL)
232-
last_candidate->next = NULL;
233230
}
234231

232+
if (last_candidate) /* terminate rebuilt list */
233+
last_candidate->next = NULL;
234+
235235
return ((ncandidates == 1) ? candidates->args[0] : 0);
236236
} /* agg_select_candidate() */
237237

@@ -559,8 +559,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
559559
}
560560

561561
/* Most of the rest of the parser just assumes that functions do not
562-
* have more than FUNC_MAX_ARGS parameters. We have to test here to protect
563-
* against array overruns, etc.
562+
* have more than FUNC_MAX_ARGS parameters. We have to test here
563+
* to protect against array overruns, etc.
564564
*/
565565
if (nargs >= FUNC_MAX_ARGS)
566566
elog(ERROR, "Cannot pass more than %d arguments to a function",
@@ -892,23 +892,27 @@ func_select_candidate(int nargs,
892892
if ((nmatch + nident) == nargs)
893893
return current_candidate->args;
894894

895+
/* take this one as the best choice so far? */
895896
if ((nmatch > nbestMatch) || (last_candidate == NULL))
896897
{
897898
nbestMatch = nmatch;
898899
candidates = current_candidate;
899900
last_candidate = current_candidate;
900901
ncandidates = 1;
901902
}
903+
/* no worse than the last choice, so keep this one too? */
902904
else if (nmatch == nbestMatch)
903905
{
904906
last_candidate->next = current_candidate;
905907
last_candidate = current_candidate;
906908
ncandidates++;
907909
}
908-
else
909-
last_candidate->next = NULL;
910+
/* otherwise, don't bother keeping this one... */
910911
}
911912

913+
if (last_candidate) /* terminate rebuilt list */
914+
last_candidate->next = NULL;
915+
912916
if (ncandidates == 1)
913917
return candidates->args;
914918

@@ -922,6 +926,7 @@ func_select_candidate(int nargs,
922926
{
923927
slot_category = INVALID_TYPE;
924928
slot_type = InvalidOid;
929+
last_candidate = NULL;
925930
for (current_candidate = candidates;
926931
current_candidate != NULL;
927932
current_candidate = current_candidate->next)
@@ -935,26 +940,39 @@ func_select_candidate(int nargs,
935940
slot_category = current_category;
936941
slot_type = current_type;
937942
}
938-
else if ((current_category != slot_category)
939-
&& IS_BUILTIN_TYPE(current_type))
943+
else if (current_category != slot_category)
944+
{
945+
/* punt if more than one category for this slot */
940946
return NULL;
947+
}
941948
else if (current_type != slot_type)
942949
{
943950
if (IsPreferredType(slot_category, current_type))
944951
{
945952
slot_type = current_type;
953+
/* forget all previous candidates */
946954
candidates = current_candidate;
955+
last_candidate = current_candidate;
947956
}
948957
else if (IsPreferredType(slot_category, slot_type))
949-
candidates->next = current_candidate->next;
958+
{
959+
/* forget this candidate */
960+
if (last_candidate)
961+
last_candidate->next = current_candidate->next;
962+
else
963+
candidates = current_candidate->next;
964+
}
965+
else
966+
last_candidate = current_candidate;
967+
}
968+
else
969+
{
970+
/* keep this candidate */
971+
last_candidate = current_candidate;
950972
}
951973
}
952-
953-
if (slot_type != InvalidOid)
954-
input_typeids[i] = slot_type;
955-
}
956-
else
957-
{
974+
if (last_candidate) /* terminate rebuilt list */
975+
last_candidate->next = NULL;
958976
}
959977
}
960978

0 commit comments

Comments
 (0)