/* * regnamespacein - converts "nspname" to namespace OID * * We also accept a numeric OID, for symmetry with the output routine. * * '-' signifies unknown (OID 0). In all other cases, the input must * match an existing pg_namespace entry. */ Datum regnamespacein(PG_FUNCTION_ARGS) { char *nsp_name_or_oid = PG_GETARG_CSTRING(0); Oid result = InvalidOid; /* '-' ? */ if (strcmp(nsp_name_or_oid, "-") == 0) PG_RETURN_OID(InvalidOid); /* Numeric OID? */ if (nsp_name_or_oid[0] >= '0' && nsp_name_or_oid[0] <= '9' && strspn(nsp_name_or_oid, "0123456789") == strlen(nsp_name_or_oid)) { result = DatumGetObjectId(DirectFunctionCall1(oidin, CStringGetDatum(nsp_name_or_oid))); PG_RETURN_OID(result); } /* Normal case: see if the name matches any pg_namespace entry. */ result = get_namespace_oid(nsp_name_or_oid, false); PG_RETURN_OID(result); }
Datum create_empty_extension(PG_FUNCTION_ARGS) { text *extName = PG_GETARG_TEXT_PP(0); text *schemaName = PG_GETARG_TEXT_PP(1); bool relocatable = PG_GETARG_BOOL(2); text *extVersion = PG_GETARG_TEXT_PP(3); Datum extConfig; Datum extCondition; List *requiredExtensions; if (PG_ARGISNULL(4)) extConfig = PointerGetDatum(NULL); else extConfig = PG_GETARG_DATUM(4); if (PG_ARGISNULL(5)) extCondition = PointerGetDatum(NULL); else extCondition = PG_GETARG_DATUM(5); requiredExtensions = NIL; if (!PG_ARGISNULL(6)) { ArrayType *textArray = PG_GETARG_ARRAYTYPE_P(6); Datum *textDatums; int ndatums; int i; deconstruct_array(textArray, TEXTOID, -1, false, 'i', &textDatums, NULL, &ndatums); for (i = 0; i < ndatums; i++) { text *txtname = DatumGetTextPP(textDatums[i]); char *extName = text_to_cstring(txtname); Oid extOid = get_extension_oid(extName, false); requiredExtensions = lappend_oid(requiredExtensions, extOid); } } InsertExtensionTuple(text_to_cstring(extName), GetUserId(), get_namespace_oid(text_to_cstring(schemaName), false), relocatable, text_to_cstring(extVersion), extConfig, extCondition, requiredExtensions); PG_RETURN_VOID(); }
/* * to_regnamespace - converts "nspname" to namespace OID * * If the name is not found, we return NULL. */ Datum to_regnamespace(PG_FUNCTION_ARGS) { char *nsp_name = PG_GETARG_CSTRING(0); Oid result; result = get_namespace_oid(nsp_name, true); if (OidIsValid(result)) PG_RETURN_OID(result); else PG_RETURN_NULL(); }
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; }
Datum binary_upgrade_create_empty_extension(PG_FUNCTION_ARGS) { text *extName; text *schemaName; bool relocatable; text *extVersion; Datum extConfig; Datum extCondition; List *requiredExtensions; CHECK_IS_BINARY_UPGRADE; /* We must check these things before dereferencing the arguments */ if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3)) elog(ERROR, "null argument to binary_upgrade_create_empty_extension is not allowed"); extName = PG_GETARG_TEXT_PP(0); schemaName = PG_GETARG_TEXT_PP(1); relocatable = PG_GETARG_BOOL(2); extVersion = PG_GETARG_TEXT_PP(3); if (PG_ARGISNULL(4)) extConfig = PointerGetDatum(NULL); else extConfig = PG_GETARG_DATUM(4); if (PG_ARGISNULL(5)) extCondition = PointerGetDatum(NULL); else extCondition = PG_GETARG_DATUM(5); requiredExtensions = NIL; if (!PG_ARGISNULL(6)) { ArrayType *textArray = PG_GETARG_ARRAYTYPE_P(6); Datum *textDatums; int ndatums; int i; deconstruct_array(textArray, TEXTOID, -1, false, 'i', &textDatums, NULL, &ndatums); for (i = 0; i < ndatums; i++) { text *txtname = DatumGetTextPP(textDatums[i]); char *extName = text_to_cstring(txtname); Oid extOid = get_extension_oid(extName, false); requiredExtensions = lappend_oid(requiredExtensions, extOid); } } InsertExtensionTuple(text_to_cstring(extName), GetUserId(), get_namespace_oid(text_to_cstring(schemaName), false), relocatable, text_to_cstring(extVersion), extConfig, extCondition, requiredExtensions); PG_RETURN_VOID(); }
/* * Find an ObjectAddress for a type of object that is identified by an * unqualified name. */ static ObjectAddress get_object_address_unqualified(ObjectType objtype, List *qualname) { const char *name; ObjectAddress address; /* * The types of names handled by this function are not permitted to be * schema-qualified or catalog-qualified. */ if (list_length(qualname) != 1) { const char *msg; switch (objtype) { case OBJECT_DATABASE: msg = gettext_noop("database name cannot be qualified"); break; case OBJECT_EXTENSION: msg = gettext_noop("extension name cannot be qualified"); break; case OBJECT_TABLESPACE: msg = gettext_noop("tablespace name cannot be qualified"); break; case OBJECT_ROLE: msg = gettext_noop("role name cannot be qualified"); break; case OBJECT_SCHEMA: msg = gettext_noop("schema name cannot be qualified"); break; case OBJECT_LANGUAGE: msg = gettext_noop("language name cannot be qualified"); break; case OBJECT_FDW: msg = gettext_noop("foreign-data wrapper name cannot be qualified"); break; case OBJECT_FOREIGN_SERVER: msg = gettext_noop("server name cannot be qualified"); break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); msg = NULL; /* placate compiler */ } ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("%s", _(msg)))); } /* Format is valid, extract the actual name. */ name = strVal(linitial(qualname)); /* Translate name to OID. */ switch (objtype) { case OBJECT_DATABASE: address.classId = DatabaseRelationId; address.objectId = get_database_oid(name, false); address.objectSubId = 0; break; case OBJECT_EXTENSION: address.classId = ExtensionRelationId; address.objectId = get_extension_oid(name, false); address.objectSubId = 0; break; case OBJECT_TABLESPACE: address.classId = TableSpaceRelationId; address.objectId = get_tablespace_oid(name, false); address.objectSubId = 0; break; case OBJECT_ROLE: address.classId = AuthIdRelationId; address.objectId = get_role_oid(name, false); address.objectSubId = 0; break; case OBJECT_SCHEMA: address.classId = NamespaceRelationId; address.objectId = get_namespace_oid(name, false); address.objectSubId = 0; break; case OBJECT_LANGUAGE: address.classId = LanguageRelationId; address.objectId = get_language_oid(name, false); address.objectSubId = 0; break; case OBJECT_FDW: address.classId = ForeignDataWrapperRelationId; address.objectId = get_foreign_data_wrapper_oid(name, false); address.objectSubId = 0; break; case OBJECT_FOREIGN_SERVER: address.classId = ForeignServerRelationId; address.objectId = get_foreign_server_oid(name, false); address.objectSubId = 0; break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); /* placate compiler, which doesn't know elog won't return */ address.classId = InvalidOid; address.objectId = InvalidOid; address.objectSubId = 0; } return address; }
/* * get_args * Retrieve arguments from FunctionCallInfo and validate them. We assume * that order of arguments is: * 1) schema name * 2) relation oid * 3) attribute name * 4) absolute path of source file, or 'stdin' (case insensitive) */ static void get_args(FunctionCallInfo fcinfo, char **nspname, char **relname, char **attname, char **filename) { Oid nspid; Oid relid; AttrNumber attnum; HeapTuple tp; Form_pg_class reltup; char relkind; *nspname = *relname = *attname = *filename = NULL; /* * First of all, check whether combination of arguments is consistent. * * 1) relid and attname can't be used with schemaname. * 2) relid is required when attname is given. */ if (!PG_ARGISNULL(0) && (!PG_ARGISNULL(1) || !PG_ARGISNULL(2))) elog(ERROR, "relid and attnum can not be used with schemaname"); else if (PG_ARGISNULL(1) && !PG_ARGISNULL(2)) elog(ERROR, "relation is required"); /* filepath validation */ if (!PG_ARGISNULL(3)) { *filename = get_text_arg(fcinfo, 3, false); /* * If given filepath is "stdin", clear filename to tell caller to * import from standard input. Note that we accept only absolute path * for security reason. */ if (pg_strcasecmp(*filename, "stdin") == 0) *filename = NULL; else if (!is_absolute_path(*filename)) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), errmsg("relative path not allowed for dbms_stats_export" " to file"))); } /* schemaname validation */ if (!PG_ARGISNULL(0)) { *nspname = get_text_arg(fcinfo, 0, true); /* check that a schema with given name exists */ get_namespace_oid(*nspname, false); /* check that given schema is not one of system schemas */ if (dbms_stats_is_system_schema_internal(*nspname)) elog(ERROR, "\"%s\" is a system catalog", *nspname); } /* table oid validation */ if (!PG_ARGISNULL(1)) { relid = PG_GETARG_OID(1); tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tp)) elog(ERROR, "relid %d does not exist", relid); /* check that the target is an ordinary table or an index */ reltup = (Form_pg_class) GETSTRUCT(tp); *relname = pstrdup(reltup->relname.data); relkind = reltup->relkind; nspid = reltup->relnamespace; ReleaseSysCache(tp); if (relkind != RELKIND_RELATION && relkind != RELKIND_INDEX #if PG_VERSION_NUM >= 90200 && relkind != RELKIND_FOREIGN_TABLE #endif #if PG_VERSION_NUM >= 90300 && relkind != RELKIND_MATVIEW #endif ) elog(ERROR, "relkind of \"%s\" is \"%c\", can not import", get_rel_name(relid), relkind); /* check that the relation is not in one of system schemas */ *nspname = get_namespace_name(nspid); if (dbms_stats_is_system_schema_internal(*nspname)) elog(ERROR, "\"%s\" is a system catalog", *nspname); /* attribute name validation */ if (!PG_ARGISNULL(2)) { *attname = get_text_arg(fcinfo, 2, true); attnum = get_attnum(relid, *attname); if (!AttributeNumberIsValid(attnum)) elog(ERROR, "column \"%s\" of \"%s.%s\" does not exist", *attname, *nspname, *relname); } } }