aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/parse_func.c32
-rw-r--r--src/backend/parser/parse_oper.c4
-rw-r--r--src/backend/parser/parse_type.c88
3 files changed, 76 insertions, 48 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 32179aacb55..63be2a44f16 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -1259,7 +1259,8 @@ func_get_detail(List *funcname,
/* Get list of possible candidates from namespace search */
raw_candidates = FuncnameGetCandidates(funcname, nargs, fargnames,
- expand_variadic, expand_defaults);
+ expand_variadic, expand_defaults,
+ false);
/*
* Quickly check if there is an exact match to the input datatypes (there
@@ -1714,7 +1715,7 @@ FuncNameAsType(List *funcname)
Oid result;
Type typtup;
- typtup = LookupTypeName(NULL, makeTypeNameFromNameList(funcname), NULL);
+ typtup = LookupTypeName(NULL, makeTypeNameFromNameList(funcname), NULL, false);
if (typtup == NULL)
return InvalidOid;
@@ -1873,7 +1874,7 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
{
FuncCandidateList clist;
- clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false);
+ clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false, noError);
while (clist)
{
@@ -1893,27 +1894,6 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
}
/*
- * LookupTypeNameOid
- * Convenience routine to look up a type, silently accepting shell types
- */
-static Oid
-LookupTypeNameOid(const TypeName *typename)
-{
- Oid result;
- Type typtup;
-
- typtup = LookupTypeName(NULL, typename, NULL);
- if (typtup == NULL)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("type \"%s\" does not exist",
- TypeNameToString(typename))));
- result = typeTypeId(typtup);
- ReleaseSysCache(typtup);
- return result;
-}
-
-/*
* LookupFuncNameTypeNames
* Like LookupFuncName, but the argument types are specified by a
* list of TypeName nodes.
@@ -1940,7 +1920,7 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
{
TypeName *t = (TypeName *) lfirst(args_item);
- argoids[i] = LookupTypeNameOid(t);
+ argoids[i] = LookupTypeNameOid(NULL, t, noError);
args_item = lnext(args_item);
}
@@ -1980,7 +1960,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
{
TypeName *t = (TypeName *) lfirst(lc);
- argoids[i] = LookupTypeNameOid(t);
+ argoids[i] = LookupTypeNameOid(NULL, t, noError);
i++;
}
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index 387f7fd0b36..99dbd30d758 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -148,12 +148,12 @@ LookupOperNameTypeNames(ParseState *pstate, List *opername,
if (oprleft == NULL)
leftoid = InvalidOid;
else
- leftoid = typenameTypeId(pstate, oprleft);
+ leftoid = LookupTypeNameOid(pstate, oprleft, noError);
if (oprright == NULL)
rightoid = InvalidOid;
else
- rightoid = typenameTypeId(pstate, oprright);
+ rightoid = LookupTypeNameOid(pstate, oprright, noError);
return LookupOperName(pstate, opername, leftoid, rightoid,
noError, location);
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index 635aa1d3631..b329dfb1684 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -56,7 +56,7 @@ static int32 typenameTypeMod(ParseState *pstate, const TypeName *typeName,
*/
Type
LookupTypeName(ParseState *pstate, const TypeName *typeName,
- int32 *typmod_p)
+ int32 *typmod_p, bool missing_ok)
{
Oid typoid;
HeapTuple tup;
@@ -116,24 +116,32 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName,
* concurrent DDL. But taking a lock would carry a performance
* penalty and would also require a permissions check.
*/
- relid = RangeVarGetRelid(rel, NoLock, false);
+ relid = RangeVarGetRelid(rel, NoLock, missing_ok);
attnum = get_attnum(relid, field);
if (attnum == InvalidAttrNumber)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("column \"%s\" of relation \"%s\" does not exist",
- field, rel->relname),
- parser_errposition(pstate, typeName->location)));
- typoid = get_atttype(relid, attnum);
+ {
+ if (missing_ok)
+ typoid = InvalidOid;
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_COLUMN),
+ errmsg("column \"%s\" of relation \"%s\" does not exist",
+ field, rel->relname),
+ parser_errposition(pstate, typeName->location)));
+ }
+ else
+ {
+ typoid = get_atttype(relid, attnum);
- /* this construct should never have an array indicator */
- Assert(typeName->arrayBounds == NIL);
+ /* this construct should never have an array indicator */
+ Assert(typeName->arrayBounds == NIL);
- /* emit nuisance notice (intentionally not errposition'd) */
- ereport(NOTICE,
- (errmsg("type reference %s converted to %s",
- TypeNameToString(typeName),
- format_type_be(typoid))));
+ /* emit nuisance notice (intentionally not errposition'd) */
+ ereport(NOTICE,
+ (errmsg("type reference %s converted to %s",
+ TypeNameToString(typeName),
+ format_type_be(typoid))));
+ }
}
else
{
@@ -149,10 +157,13 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName,
/* Look in specific schema only */
Oid namespaceId;
- namespaceId = LookupExplicitNamespace(schemaname, false);
- typoid = GetSysCacheOid2(TYPENAMENSP,
- PointerGetDatum(typname),
- ObjectIdGetDatum(namespaceId));
+ namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
+ if (OidIsValid(namespaceId))
+ typoid = GetSysCacheOid2(TYPENAMENSP,
+ PointerGetDatum(typname),
+ ObjectIdGetDatum(namespaceId));
+ else
+ typoid = InvalidOid;
}
else
{
@@ -185,6 +196,43 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName,
}
/*
+ * LookupTypeNameOid
+ * Given a TypeName object, lookup the pg_type syscache entry of the type.
+ * Returns InvalidOid if no such type can be found. If the type is found,
+ * return its Oid.
+ *
+ * NB: direct callers of this function need to be aware that the type OID
+ * returned may correspond to a shell type. Most code should go through
+ * typenameTypeId instead.
+ *
+ * pstate is only used for error location info, and may be NULL.
+ */
+Oid
+LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok)
+{
+ Oid typoid;
+ Type tup;
+
+ tup = LookupTypeName(pstate, typeName, NULL, missing_ok);
+ if (tup == NULL)
+ {
+ if (!missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("type \"%s\" does not exist",
+ TypeNameToString(typeName)),
+ parser_errposition(pstate, typeName->location)));
+
+ return InvalidOid;
+ }
+
+ typoid = HeapTupleGetOid(tup);
+ ReleaseSysCache(tup);
+
+ return typoid;
+}
+
+/*
* typenameType - given a TypeName, return a Type structure and typmod
*
* This is equivalent to LookupTypeName, except that this will report
@@ -196,7 +244,7 @@ typenameType(ParseState *pstate, const TypeName *typeName, int32 *typmod_p)
{
Type tup;
- tup = LookupTypeName(pstate, typeName, typmod_p);
+ tup = LookupTypeName(pstate, typeName, typmod_p, false);
if (tup == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),