/* * get_subscription_oid - given a subscription name, look up the OID * * If missing_ok is false, throw an error if name not found. If true, just * return InvalidOid. */ Oid get_subscription_oid(const char *subname, bool missing_ok) { Oid oid; oid = GetSysCacheOid2(SUBSCRIPTIONNAME, Anum_pg_subscription_oid, MyDatabaseId, CStringGetDatum(subname)); if (!OidIsValid(oid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("subscription \"%s\" does not exist", subname))); return oid; }
/* * 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; }
bool initialize_constants(constants_t *constants) { #define CheckOid(o) if(constants->o==InvalidOid) return false constants->OID_SCHEMA_PROVSQL = get_namespace_oid("provsql", true); CheckOid(OID_SCHEMA_PROVSQL); constants->OID_TYPE_PROVENANCE_TOKEN = GetSysCacheOid2(TYPENAMENSP,CStringGetDatum("provenance_token"),ObjectIdGetDatum(constants->OID_SCHEMA_PROVSQL)); CheckOid(OID_TYPE_PROVENANCE_TOKEN); constants->OID_TYPE_UUID = TypenameGetTypid("uuid"); CheckOid(OID_TYPE_UUID); constants->OID_TYPE_UUID_ARRAY = TypenameGetTypid("_uuid"); CheckOid(OID_TYPE_UUID_ARRAY); constants->OID_TYPE_INT = TypenameGetTypid("int4"); CheckOid(OID_TYPE_INT); constants->OID_TYPE_INT_ARRAY = TypenameGetTypid("_int4"); CheckOid(OID_TYPE_INT_ARRAY); constants->OID_FUNCTION_PROVENANCE_AGG_PLUS = GetFuncOid("provenance_agg"); CheckOid(OID_FUNCTION_PROVENANCE_AGG_PLUS); constants->OID_FUNCTION_PROVENANCE_TIMES = GetFuncOid("provenance_times"); CheckOid(OID_FUNCTION_PROVENANCE_TIMES); constants->OID_FUNCTION_PROVENANCE_MONUS = GetFuncOid("provenance_monus"); CheckOid(OID_FUNCTION_PROVENANCE_MONUS); constants->OID_FUNCTION_PROVENANCE_PROJECT = GetFuncOid("provenance_project"); CheckOid(OID_FUNCTION_PROVENANCE_PROJECT); constants->OID_FUNCTION_PROVENANCE_EQ = GetFuncOid("provenance_eq"); CheckOid(OID_FUNCTION_PROVENANCE_EQ); constants->OID_FUNCTION_PROVENANCE = GetFuncOid("provenance"); CheckOid(OID_FUNCTION_PROVENANCE); return true; }
/* * RenameTypeInternal * This renames a type, as well as any associated array type. * * Caller must have already checked privileges. * * Currently this is used for renaming table rowtypes and for * ALTER TYPE RENAME TO command. */ void RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace) { Relation pg_type_desc; HeapTuple tuple; Form_pg_type typ; Oid arrayOid; Oid oldTypeOid; pg_type_desc = table_open(TypeRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(TYPEOID, ObjectIdGetDatum(typeOid)); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for type %u", typeOid); typ = (Form_pg_type) GETSTRUCT(tuple); /* We are not supposed to be changing schemas here */ Assert(typeNamespace == typ->typnamespace); arrayOid = typ->typarray; /* Check for a conflicting type name. */ oldTypeOid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, CStringGetDatum(newTypeName), ObjectIdGetDatum(typeNamespace)); /* * If there is one, see if it's an autogenerated array type, and if so * rename it out of the way. (But we must skip that for a shell type * because moveArrayTypeName will do the wrong thing in that case.) * Otherwise, we can at least give a more friendly error than unique-index * violation. */ if (OidIsValid(oldTypeOid)) { if (get_typisdefined(oldTypeOid) && moveArrayTypeName(oldTypeOid, newTypeName, typeNamespace)) /* successfully dodged the problem */ ; else ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("type \"%s\" already exists", newTypeName))); } /* OK, do the rename --- tuple is a copy, so OK to scribble on it */ namestrcpy(&(typ->typname), newTypeName); CatalogTupleUpdate(pg_type_desc, &tuple->t_self, tuple); InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0); heap_freetuple(tuple); table_close(pg_type_desc, RowExclusiveLock); /* * If the type has an array type, recurse to handle that. But we don't * need to do anything more if we already renamed that array type above * (which would happen when, eg, renaming "foo" to "_foo"). */ if (OidIsValid(arrayOid) && arrayOid != oldTypeOid) { char *arrname = makeArrayTypeName(newTypeName, typeNamespace); RenameTypeInternal(arrayOid, arrname, typeNamespace); pfree(arrname); } }