1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

Allow extracting machine-readable object identity

Introduce pg_identify_object(oid,oid,int4), which is similar in spirit
to pg_describe_object but instead produces a row of machine-readable
information to uniquely identify the given object, without resorting to
OIDs or other internal representation.  This is intended to be used in
the event trigger implementation, to report objects being operated on;
but it has usefulness of its own.

Catalog version bumped because of the new function.
This commit is contained in:
Alvaro Herrera
2013-03-20 18:19:19 -03:00
parent a7921f71a3
commit f8348ea32e
12 changed files with 2141 additions and 955 deletions

View File

@@ -29,7 +29,8 @@
#define MAX_INT32_LEN 11
static char *format_type_internal(Oid type_oid, int32 typemod,
bool typemod_given, bool allow_invalid);
bool typemod_given, bool allow_invalid,
bool force_qualify);
static char *printTypmod(const char *typname, int32 typmod, Oid typmodout);
static char *
psnprintf(size_t len, const char *fmt,...)
@@ -77,11 +78,11 @@ format_type(PG_FUNCTION_ARGS)
type_oid = PG_GETARG_OID(0);
if (PG_ARGISNULL(1))
result = format_type_internal(type_oid, -1, false, true);
result = format_type_internal(type_oid, -1, false, true, false);
else
{
typemod = PG_GETARG_INT32(1);
result = format_type_internal(type_oid, typemod, true, true);
result = format_type_internal(type_oid, typemod, true, true, false);
}
PG_RETURN_TEXT_P(cstring_to_text(result));
@@ -96,7 +97,13 @@ format_type(PG_FUNCTION_ARGS)
char *
format_type_be(Oid type_oid)
{
return format_type_internal(type_oid, -1, false, false);
return format_type_internal(type_oid, -1, false, false, false);
}
char *
format_type_be_qualified(Oid type_oid)
{
return format_type_internal(type_oid, -1, false, false, true);
}
/*
@@ -105,14 +112,13 @@ format_type_be(Oid type_oid)
char *
format_type_with_typemod(Oid type_oid, int32 typemod)
{
return format_type_internal(type_oid, typemod, true, false);
return format_type_internal(type_oid, typemod, true, false, false);
}
static char *
format_type_internal(Oid type_oid, int32 typemod,
bool typemod_given, bool allow_invalid)
bool typemod_given, bool allow_invalid,
bool force_qualify)
{
bool with_typemod = typemod_given && (typemod >= 0);
HeapTuple tuple;
@@ -300,7 +306,7 @@ format_type_internal(Oid type_oid, int32 typemod,
char *nspname;
char *typname;
if (TypeIsVisible(type_oid))
if (!force_qualify && TypeIsVisible(type_oid))
nspname = NULL;
else
nspname = get_namespace_name(typeform->typnamespace);
@@ -421,7 +427,7 @@ oidvectortypes(PG_FUNCTION_ARGS)
for (num = 0; num < numargs; num++)
{
char *typename = format_type_internal(oidArray->values[num], -1,
false, true);
false, true, false);
size_t slen = strlen(typename);
if (left < (slen + 2))

View File

@@ -41,6 +41,8 @@
#include "utils/syscache.h"
#include "utils/tqual.h"
static char *format_operator_internal(Oid operator_oid, bool force_qualify);
static char *format_procedure_internal(Oid procedure_oid, bool force_qualify);
static void parseNameAndArgTypes(const char *string, bool allowNone,
List **names, int *nargs, Oid *argtypes);
@@ -303,6 +305,25 @@ regprocedurein(PG_FUNCTION_ARGS)
*/
char *
format_procedure(Oid procedure_oid)
{
return format_procedure_internal(procedure_oid, false);
}
char *
format_procedure_qualified(Oid procedure_oid)
{
return format_procedure_internal(procedure_oid, true);
}
/*
* Routine to produce regprocedure names; see format_procedure above.
*
* force_qualify says whether to schema-qualify; if true, the name is always
* qualified regardless of search_path visibility. Otherwise the name is only
* qualified if the function is not in path.
*/
static char *
format_procedure_internal(Oid procedure_oid, bool force_qualify)
{
char *result;
HeapTuple proctup;
@@ -326,7 +347,7 @@ format_procedure(Oid procedure_oid)
* Would this proc be found (given the right args) by regprocedurein?
* If not, we need to qualify it.
*/
if (FunctionIsVisible(procedure_oid))
if (!force_qualify && FunctionIsVisible(procedure_oid))
nspname = NULL;
else
nspname = get_namespace_name(procform->pronamespace);
@@ -339,7 +360,10 @@ format_procedure(Oid procedure_oid)
if (i > 0)
appendStringInfoChar(&buf, ',');
appendStringInfoString(&buf, format_type_be(thisargtype));
appendStringInfoString(&buf,
force_qualify ?
format_type_be_qualified(thisargtype) :
format_type_be(thisargtype));
}
appendStringInfoChar(&buf, ')');
@@ -653,8 +677,8 @@ regoperatorin(PG_FUNCTION_ARGS)
* This exports the useful functionality of regoperatorout for use
* in other backend modules. The result is a palloc'd string.
*/
char *
format_operator(Oid operator_oid)
static char *
format_operator_internal(Oid operator_oid, bool force_qualify)
{
char *result;
HeapTuple opertup;
@@ -674,9 +698,9 @@ format_operator(Oid operator_oid)
/*
* Would this oper be found (given the right args) by regoperatorin?
* If not, we need to qualify it.
* If not, or if caller explicitely requests it, we need to qualify it.
*/
if (!OperatorIsVisible(operator_oid))
if (force_qualify || !OperatorIsVisible(operator_oid))
{
nspname = get_namespace_name(operform->oprnamespace);
appendStringInfo(&buf, "%s.",
@@ -687,12 +711,16 @@ format_operator(Oid operator_oid)
if (operform->oprleft)
appendStringInfo(&buf, "%s,",
force_qualify ?
format_type_be_qualified(operform->oprleft) :
format_type_be(operform->oprleft));
else
appendStringInfo(&buf, "NONE,");
if (operform->oprright)
appendStringInfo(&buf, "%s)",
force_qualify ?
format_type_be_qualified(operform->oprright) :
format_type_be(operform->oprright));
else
appendStringInfo(&buf, "NONE)");
@@ -713,6 +741,18 @@ format_operator(Oid operator_oid)
return result;
}
char *
format_operator(Oid operator_oid)
{
return format_operator_internal(operator_oid, false);
}
char *
format_operator_qualified(Oid operator_oid)
{
return format_operator_internal(operator_oid, true);
}
/*
* regoperatorout - converts operator OID to "opr_name(args)"
*/