aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_func.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_func.c')
-rw-r--r--src/backend/parser/parse_func.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 939d7a91ec3..71cda760874 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.70 2000/02/20 06:35:08 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.71 2000/02/20 21:32:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -163,7 +163,10 @@ agg_get_candidates(char *aggname,
} /* agg_get_candidates() */
/* agg_select_candidate()
- * Try to choose only one candidate aggregate function from a list of possibles.
+ *
+ * Try to choose only one candidate aggregate function from a list of
+ * possible matches. Return value is Oid of input type of aggregate
+ * if successful, else InvalidOid.
*/
static Oid
agg_select_candidate(Oid typeid, CandidateList candidates)
@@ -175,10 +178,12 @@ agg_select_candidate(Oid typeid, CandidateList candidates)
CATEGORY category,
current_category;
-/*
- * First look for exact matches or binary compatible matches.
- * (Of course exact matches shouldn't even get here, but anyway.)
- */
+ /*
+ * First look for exact matches or binary compatible matches.
+ * (Of course exact matches shouldn't even get here, but anyway.)
+ */
+ ncandidates = 0;
+ last_candidate = NULL;
for (current_candidate = candidates;
current_candidate != NULL;
current_candidate = current_candidate->next)
@@ -188,15 +193,17 @@ agg_select_candidate(Oid typeid, CandidateList candidates)
if (current_typeid == typeid
|| IS_BINARY_COMPATIBLE(current_typeid, typeid))
{
- /* we're home free */
- return current_typeid;
+ last_candidate = current_candidate;
+ ncandidates++;
}
}
+ if (ncandidates == 1)
+ return last_candidate->args[0];
-/*
- * If no luck that way, look for candidates which allow coersion
- * and have a preferred type. Keep all candidates if none match.
- */
+ /*
+ * If no luck that way, look for candidates which allow coercion
+ * and have a preferred type. Keep all candidates if none match.
+ */
category = TypeCategory(typeid);
ncandidates = 0;
last_candidate = NULL;
@@ -232,7 +239,10 @@ agg_select_candidate(Oid typeid, CandidateList candidates)
if (last_candidate) /* terminate rebuilt list */
last_candidate->next = NULL;
- return ((ncandidates == 1) ? candidates->args[0] : 0);
+ if (ncandidates == 1)
+ return candidates->args[0];
+
+ return InvalidOid;
} /* agg_select_candidate() */
@@ -471,10 +481,9 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
/*
* See if this is a single argument function with the function
* name also a type name and the input argument and type name
- * binary compatible... This means that you are trying for a
- * type conversion which does not need to take place, so we'll
- * just pass through the argument itself. (make this clearer
- * with some extra brackets - thomas 1998-12-05)
+ * binary compatible. If so, we do not need to do any real
+ * conversion, but we do need to build a RelabelType node
+ * so that exprType() sees the result as being of the output type.
*/
if (nargs == 1)
{
@@ -486,8 +495,13 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
if (HeapTupleIsValid(tp) &&
IS_BINARY_COMPATIBLE(typeTypeId(tp), exprType(lfirst(fargs))))
{
- /* XXX FIXME: probably need to change expression's marked type? */
- return (Node *) lfirst(fargs);
+ RelabelType *relabel = makeNode(RelabelType);
+
+ relabel->arg = (Node *) lfirst(fargs);
+ relabel->resulttype = typeTypeId(tp);
+ relabel->resulttypmod = -1;
+
+ return (Node *) relabel;
}
}
@@ -1128,7 +1142,7 @@ func_get_detail(char *funcname,
* inheritance properties of the supplied argv.
*
* This function is used to disambiguate among functions with the
- * same name but different signatures. It takes an array of eight
+ * same name but different signatures. It takes an array of input
* type ids. For each type id in the array that's a complex type
* (a class), it walks up the inheritance tree, finding all
* superclasses of that type. A vector of new Oid type arrays
@@ -1342,7 +1356,7 @@ gen_cross_product(InhPaths *arginh, int nargs)
* 2) the input type can be typecast into the function type
* Right now, we only typecast unknowns, and that is all we check for.
*
- * func_get_detail() now can find coersions for function arguments which
+ * func_get_detail() now can find coercions for function arguments which
* will make this function executable. So, we need to recover these
* results here too.
* - thomas 1998-03-25
@@ -1361,7 +1375,7 @@ make_arguments(ParseState *pstate,
i < nargs;
i++, current_fargs = lnext(current_fargs))
{
- /* types don't match? then force coersion using a function call... */
+ /* types don't match? then force coercion using a function call... */
if (input_typeids[i] != function_typeids[i])
{
lfirst(current_fargs) = coerce_type(pstate,