Exemple #1
0
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;
}
Exemple #2
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;
}
Exemple #3
0
/*
 * 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;
}
Exemple #4
0
/*
 * 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;
}