summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2025-09-16 12:17:02 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2025-09-16 12:17:02 -0400
commit83a56419457ec0eff2eddfed8eb3aba86bede9cc (patch)
treec93d0986e7d19c763c2d0965d98edc8d336b78ea /src/include
parentc7b0cb367d3c6b007122457ad5deb659fe8cc266 (diff)
Provide more-specific error details/hints for function lookup failures.
Up to now we've contented ourselves with a one-size-fits-all error hint when we fail to find any match to a function or procedure call. That was mostly okay in the beginning, but it was never great, and since the introduction of named arguments it's really not adequate. We at least ought to distinguish "function name doesn't exist" from "function name exists, but not with those argument names". And the rules for named-argument matching are arcane enough that some more detail seems warranted if we match the argument names but the call still doesn't work. This patch creates a framework for dealing with these problems: FuncnameGetCandidates and related code will now pass back a bitmask of flags showing how far the match succeeded. This allows a considerable amount of granularity in the reports. The set-bits-in-a-bitmask approach means that when there are multiple candidate functions, the report will reflect the match(es) that got the furthest, which seems correct. Also, we can avoid mentioning "maybe add casts" unless failure to match argument types is actually the issue. Extend the same return-a-bitmask approach to OpernameGetCandidates. The issues around argument names don't apply to operator syntax, but it still seems worth distinguishing between "there is no operator of that name" and "we couldn't match the argument types". While at it, adjust these messages and related ones to more strictly separate "detail" from "hint", following our message style guidelines' distinction between those. Reported-by: Dominique Devienne <ddevienne@gmail.com> Author: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: Robert Haas <robertmhaas@gmail.com> Discussion: https://postgr.es/m/1756041.1754616558@sss.pgh.pa.us
Diffstat (limited to 'src/include')
-rw-r--r--src/include/catalog/namespace.h24
-rw-r--r--src/include/parser/parse_func.h1
2 files changed, 23 insertions, 2 deletions
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index 8c7ccc69a3c..f1423f28c32 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -40,6 +40,24 @@ typedef struct _FuncCandidateList
} *FuncCandidateList;
/*
+ * FuncnameGetCandidates also returns a bitmask containing these flags,
+ * which report on what it found or didn't find. They can help callers
+ * produce better error reports after a function lookup failure.
+ */
+#define FGC_SCHEMA_GIVEN 0x0001 /* Func name includes a schema */
+#define FGC_SCHEMA_EXISTS 0x0002 /* Found the explicitly-specified schema */
+#define FGC_NAME_EXISTS 0x0004 /* Found a routine by that name */
+#define FGC_NAME_VISIBLE 0x0008 /* Found a routine name/schema match */
+#define FGC_ARGCOUNT_MATCH 0x0010 /* Found a func with right # of args */
+/* These bits relate only to calls using named or mixed arguments: */
+#define FGC_ARGNAMES_MATCH 0x0020 /* Found a func matching all argnames */
+#define FGC_ARGNAMES_NONDUP 0x0040 /* argnames don't overlap positional args */
+#define FGC_ARGNAMES_ALL 0x0080 /* Found a func with no missing args */
+#define FGC_ARGNAMES_VALID 0x0100 /* Found a fully-valid use of argnames */
+/* These bits are actually filled by func_get_detail: */
+#define FGC_VARIADIC_FAIL 0x0200 /* Disallowed VARIADIC with named args */
+
+/*
* Result of checkTempNamespaceStatus
*/
typedef enum TempNamespaceStatus
@@ -102,12 +120,14 @@ extern FuncCandidateList FuncnameGetCandidates(List *names,
bool expand_variadic,
bool expand_defaults,
bool include_out_arguments,
- bool missing_ok);
+ bool missing_ok,
+ int *fgc_flags);
extern bool FunctionIsVisible(Oid funcid);
extern Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright);
extern FuncCandidateList OpernameGetCandidates(List *names, char oprkind,
- bool missing_schema_ok);
+ bool missing_schema_ok,
+ int *fgc_flags);
extern bool OperatorIsVisible(Oid oprid);
extern Oid OpclassnameGetOpcid(Oid amid, const char *opcname);
diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h
index a6f24b83d84..218bb14c5d6 100644
--- a/src/include/parser/parse_func.h
+++ b/src/include/parser/parse_func.h
@@ -40,6 +40,7 @@ extern FuncDetailCode func_get_detail(List *funcname,
int nargs, Oid *argtypes,
bool expand_variadic, bool expand_defaults,
bool include_out_arguments,
+ int *fgc_flags,
Oid *funcid, Oid *rettype,
bool *retset, int *nvargs, Oid *vatype,
Oid **true_typeids, List **argdefaults);