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.c262
1 files changed, 131 insertions, 131 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index b2310587260..4c24d684991 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.106 2001/05/19 00:33:20 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.107 2001/05/19 00:37:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -104,136 +104,6 @@ ParseNestedFuncOrColumn(ParseState *pstate, Attr *attr, int precedence)
return retval;
}
-static int
-agg_get_candidates(char *aggname,
- Oid typeId,
- CandidateList *candidates)
-{
- CandidateList current_candidate;
- Relation pg_aggregate_desc;
- HeapScanDesc pg_aggregate_scan;
- HeapTuple tup;
- Form_pg_aggregate agg;
- int ncandidates = 0;
- ScanKeyData aggKey[1];
-
- *candidates = NULL;
-
- ScanKeyEntryInitialize(&aggKey[0], 0,
- Anum_pg_aggregate_aggname,
- F_NAMEEQ,
- NameGetDatum(aggname));
-
- pg_aggregate_desc = heap_openr(AggregateRelationName, AccessShareLock);
- pg_aggregate_scan = heap_beginscan(pg_aggregate_desc,
- 0,
- SnapshotSelf, /* ??? */
- 1,
- aggKey);
-
- while (HeapTupleIsValid(tup = heap_getnext(pg_aggregate_scan, 0)))
- {
- agg = (Form_pg_aggregate) GETSTRUCT(tup);
-
- current_candidate = (CandidateList) palloc(sizeof(struct _CandidateList));
- current_candidate->args = (Oid *) palloc(sizeof(Oid));
-
- current_candidate->args[0] = agg->aggbasetype;
- current_candidate->next = *candidates;
- *candidates = current_candidate;
- ncandidates++;
- }
-
- heap_endscan(pg_aggregate_scan);
- heap_close(pg_aggregate_desc, AccessShareLock);
-
- return ncandidates;
-} /* agg_get_candidates() */
-
-/* agg_select_candidate()
- *
- * 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)
-{
- CandidateList current_candidate;
- CandidateList last_candidate;
- Oid current_typeid;
- int ncandidates;
- CATEGORY category,
- current_category;
-
- /*
- * 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)
- {
- current_typeid = current_candidate->args[0];
-
- if (current_typeid == typeid
- || IS_BINARY_COMPATIBLE(current_typeid, typeid))
- {
- last_candidate = current_candidate;
- ncandidates++;
- }
- }
- if (ncandidates == 1)
- return last_candidate->args[0];
-
- /*
- * 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;
- for (current_candidate = candidates;
- current_candidate != NULL;
- current_candidate = current_candidate->next)
- {
- current_typeid = current_candidate->args[0];
- current_category = TypeCategory(current_typeid);
-
- if (current_category == category
- && IsPreferredType(current_category, current_typeid)
- && can_coerce_type(1, &typeid, &current_typeid))
- {
- /* only one so far? then keep it... */
- if (last_candidate == NULL)
- {
- candidates = current_candidate;
- last_candidate = current_candidate;
- ncandidates = 1;
- }
- /* otherwise, keep this one too... */
- else
- {
- last_candidate->next = current_candidate;
- last_candidate = current_candidate;
- ncandidates++;
- }
- }
- /* otherwise, don't bother keeping this one around... */
- }
-
- if (last_candidate) /* terminate rebuilt list */
- last_candidate->next = NULL;
-
- if (ncandidates == 1)
- return candidates->args[0];
-
- return InvalidOid;
-} /* agg_select_candidate() */
-
-
/*
* parse function
* This code is confusing because the database can accept
@@ -709,6 +579,136 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
}
+static int
+agg_get_candidates(char *aggname,
+ Oid typeId,
+ CandidateList *candidates)
+{
+ CandidateList current_candidate;
+ Relation pg_aggregate_desc;
+ HeapScanDesc pg_aggregate_scan;
+ HeapTuple tup;
+ Form_pg_aggregate agg;
+ int ncandidates = 0;
+ ScanKeyData aggKey[1];
+
+ *candidates = NULL;
+
+ ScanKeyEntryInitialize(&aggKey[0], 0,
+ Anum_pg_aggregate_aggname,
+ F_NAMEEQ,
+ NameGetDatum(aggname));
+
+ pg_aggregate_desc = heap_openr(AggregateRelationName, AccessShareLock);
+ pg_aggregate_scan = heap_beginscan(pg_aggregate_desc,
+ 0,
+ SnapshotSelf, /* ??? */
+ 1,
+ aggKey);
+
+ while (HeapTupleIsValid(tup = heap_getnext(pg_aggregate_scan, 0)))
+ {
+ agg = (Form_pg_aggregate) GETSTRUCT(tup);
+
+ current_candidate = (CandidateList) palloc(sizeof(struct _CandidateList));
+ current_candidate->args = (Oid *) palloc(sizeof(Oid));
+
+ current_candidate->args[0] = agg->aggbasetype;
+ current_candidate->next = *candidates;
+ *candidates = current_candidate;
+ ncandidates++;
+ }
+
+ heap_endscan(pg_aggregate_scan);
+ heap_close(pg_aggregate_desc, AccessShareLock);
+
+ return ncandidates;
+} /* agg_get_candidates() */
+
+/* agg_select_candidate()
+ *
+ * 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)
+{
+ CandidateList current_candidate;
+ CandidateList last_candidate;
+ Oid current_typeid;
+ int ncandidates;
+ CATEGORY category,
+ current_category;
+
+ /*
+ * 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)
+ {
+ current_typeid = current_candidate->args[0];
+
+ if (current_typeid == typeid
+ || IS_BINARY_COMPATIBLE(current_typeid, typeid))
+ {
+ last_candidate = current_candidate;
+ ncandidates++;
+ }
+ }
+ if (ncandidates == 1)
+ return last_candidate->args[0];
+
+ /*
+ * 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;
+ for (current_candidate = candidates;
+ current_candidate != NULL;
+ current_candidate = current_candidate->next)
+ {
+ current_typeid = current_candidate->args[0];
+ current_category = TypeCategory(current_typeid);
+
+ if (current_category == category
+ && IsPreferredType(current_category, current_typeid)
+ && can_coerce_type(1, &typeid, &current_typeid))
+ {
+ /* only one so far? then keep it... */
+ if (last_candidate == NULL)
+ {
+ candidates = current_candidate;
+ last_candidate = current_candidate;
+ ncandidates = 1;
+ }
+ /* otherwise, keep this one too... */
+ else
+ {
+ last_candidate->next = current_candidate;
+ last_candidate = current_candidate;
+ ncandidates++;
+ }
+ }
+ /* otherwise, don't bother keeping this one around... */
+ }
+
+ if (last_candidate) /* terminate rebuilt list */
+ last_candidate->next = NULL;
+
+ if (ncandidates == 1)
+ return candidates->args[0];
+
+ return InvalidOid;
+} /* agg_select_candidate() */
+
+
/* func_get_candidates()
* get a list of all argument type vectors for which a function named
* funcname taking nargs arguments exists