static Oid get_function_oid(const char *funcname, const char *argtype, const char *nspname) { #ifndef PROCNAMENSP Oid typid; Oid nspid; Oid funcid; Oid oids[1]; oidvector *oid_v; HeapTuple tup; if (argtype) { typid = TypenameGetTypid(argtype); elog(DEBUG1, "get_function_oid: %s typid: %d", argtype, typid); oids[0] = typid; oid_v = buildoidvector(oids, 1); } else { oid_v = buildoidvector(NULL, 0); } #if !defined(PG_VERSION_NUM) || (PG_VERSION_NUM < 90300) nspid = LookupExplicitNamespace(nspname); #else /* * LookupExplicitNamespace() of PostgreSQL 9.3 or later, has third * argument "missing_ok" which suppresses ERROR exception, but returns * invlaid_oid. See include/catalog/namespace.h */ nspid = LookupExplicitNamespace(nspname, false); #endif elog(DEBUG1, "get_function_oid: oid of \"%s\": %d", nspname, nspid); tup = SearchSysCache(PROCNAMEARGSNSP, PointerGetDatum(funcname), PointerGetDatum(oid_v), ObjectIdGetDatum(nspid), 0); if (HeapTupleIsValid(tup)) { funcid = HeapTupleGetOid(tup); elog(DEBUG1, "get_function_oid: oid of \"%s\": %d", funcname, funcid); ReleaseSysCache(tup); return funcid; } #endif return 0; }
/* * make_oper_cache_key * Fill the lookup key struct given operator name and arg types. * * Returns TRUE if successful, FALSE if the search_path overflowed * (hence no caching is possible). */ static bool make_oper_cache_key(OprCacheKey *key, List *opname, Oid ltypeId, Oid rtypeId) { char *schemaname; char *opername; /* deconstruct the name list */ DeconstructQualifiedName(opname, &schemaname, &opername); /* ensure zero-fill for stable hashing */ MemSet(key, 0, sizeof(OprCacheKey)); /* save operator name and input types into key */ strlcpy(key->oprname, opername, NAMEDATALEN); key->left_arg = ltypeId; key->right_arg = rtypeId; if (schemaname) { /* search only in exact schema given */ key->search_path[0] = LookupExplicitNamespace(schemaname); } else { /* get the active search path */ if (fetch_search_path_array(key->search_path, MAX_CACHED_PATH_LEN) > MAX_CACHED_PATH_LEN) return false; /* oops, didn't fit */ } return true; }
/* * Fetch type info from the cache. */ Oid logicalrep_typmap_getid(Oid remoteid) { LogicalRepTyp *entry; bool found; Oid nspoid; /* Internal types are mapped directly. */ if (remoteid < FirstNormalObjectId) { if (!get_typisdefined(remoteid)) ereport(ERROR, (errmsg("builtin type %u not found", remoteid), errhint("This can be caused by having publisher with " "higher major version than subscriber"))); return remoteid; } if (LogicalRepTypMap == NULL) logicalrep_relmap_init(); /* Try finding the mapping. */ entry = hash_search(LogicalRepTypMap, (void *) &remoteid, HASH_FIND, &found); if (!found) elog(ERROR, "no type map entry for remote type %u", remoteid); /* Found and mapped, return the oid. */ if (OidIsValid(entry->typoid)) return entry->typoid; /* Otherwise, try to map to local type. */ nspoid = LookupExplicitNamespace(entry->nspname, true); if (OidIsValid(nspoid)) entry->typoid = GetSysCacheOid2(TYPENAMENSP, PointerGetDatum(entry->typname), ObjectIdGetDatum(nspoid)); else entry->typoid = InvalidOid; if (!OidIsValid(entry->typoid)) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("data type \"%s.%s\" required for logical replication does not exist", entry->nspname, entry->typname))); return entry->typoid; }
/* * Copied from src/backend/commands/indexcmds.c, not exported. * Resolve possibly-defaulted operator class specification */ Oid GetIndexOpClass(List *opclass, Oid attrType, char *accessMethodName, Oid accessMethodId) { char *schemaname; char *opcname; HeapTuple tuple; Oid opClassId, opInputType; /* * Release 7.0 removed network_ops, timespan_ops, and datetime_ops, so we * ignore those opclass names so the default *_ops is used. This can be * removed in some later release. bjm 2000/02/07 * * Release 7.1 removes lztext_ops, so suppress that too for a while. tgl * 2000/07/30 * * Release 7.2 renames timestamp_ops to timestamptz_ops, so suppress that * too for awhile. I'm starting to think we need a better approach. tgl * 2000/10/01 * * Release 8.0 removes bigbox_ops (which was dead code for a long while * anyway). tgl 2003/11/11 */ if (list_length(opclass) == 1) { char *claname = strVal(linitial(opclass)); if (strcmp(claname, "network_ops") == 0 || strcmp(claname, "timespan_ops") == 0 || strcmp(claname, "datetime_ops") == 0 || strcmp(claname, "lztext_ops") == 0 || strcmp(claname, "timestamp_ops") == 0 || strcmp(claname, "bigbox_ops") == 0) opclass = NIL; } if (opclass == NIL) { /* no operator class specified, so find the default */ opClassId = GetDefaultOpClass(attrType, accessMethodId); if (!OidIsValid(opClassId)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("data type %s has no default operator class for access method \"%s\"", format_type_be(attrType), accessMethodName), errhint("You must specify an operator class for the index or define a default operator class for the data type."))); return opClassId; } /* * Specific opclass name given, so look up the opclass. */ /* deconstruct the name list */ DeconstructQualifiedName(opclass, &schemaname, &opcname); if (schemaname) { /* Look in specific schema only */ Oid namespaceId; #if PG_VERSION_NUM >= 90300 namespaceId = LookupExplicitNamespace(schemaname, false); #else namespaceId = LookupExplicitNamespace(schemaname); #endif tuple = SearchSysCache3(CLAAMNAMENSP, ObjectIdGetDatum(accessMethodId), PointerGetDatum(opcname), ObjectIdGetDatum(namespaceId)); } else { /* Unqualified opclass name, so search the search path */ opClassId = OpclassnameGetOpcid(accessMethodId, opcname); if (!OidIsValid(opClassId)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("operator class \"%s\" does not exist for access method \"%s\"", opcname, accessMethodName))); tuple = SearchSysCache1(CLAOID, ObjectIdGetDatum(opClassId)); } if (!HeapTupleIsValid(tuple)) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("operator class \"%s\" does not exist for access method \"%s\"", NameListToString(opclass), accessMethodName))); } /* * Verify that the index operator class accepts this datatype. Note we * will accept binary compatibility. */ opClassId = HeapTupleGetOid(tuple); opInputType = ((Form_pg_opclass) GETSTRUCT(tuple))->opcintype; if (!IsBinaryCoercible(attrType, opInputType)) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("operator class \"%s\" does not accept data type %s", NameListToString(opclass), format_type_be(attrType)))); ReleaseSysCache(tuple); return opClassId; }