Skip to content

Commit d7ee82e

Browse files
committed
Add SQL-callable pg_get_object_address
This allows access to get_object_address from SQL, which is useful to obtain OID addressing information from data equivalent to that emitted by the parser. This is necessary infrastructure of a project to let replication systems propagate object dropping events to remote servers, where the schema might be different than the server originating the DROP. This patch also adds support for OBJECT_DEFAULT to get_object_address; that is, it is now possible to refer to a column's default value. Catalog version bumped due to the new function. Reviewed by Stephen Frost, Heikki Linnakangas, Robert Haas, Andres Freund, Abhijit Menon-Sen, Adam Brightwell.
1 parent 1826987 commit d7ee82e

File tree

13 files changed

+1059
-18
lines changed

13 files changed

+1059
-18
lines changed

src/backend/catalog/objectaddress.c

Lines changed: 440 additions & 0 deletions
Large diffs are not rendered by default.

src/backend/commands/event_trigger.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,7 @@ EventTriggerSupportsObjectType(ObjectType obtype)
10551055
case OBJECT_COLUMN:
10561056
case OBJECT_COLLATION:
10571057
case OBJECT_CONVERSION:
1058+
case OBJECT_DEFAULT:
10581059
case OBJECT_DOMAIN:
10591060
case OBJECT_DOMCONSTRAINT:
10601061
case OBJECT_EXTENSION:

src/backend/parser/parse_type.c

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -705,13 +705,11 @@ pts_error_callback(void *arg)
705705
/*
706706
* Given a string that is supposed to be a SQL-compatible type declaration,
707707
* such as "int4" or "integer" or "character varying(32)", parse
708-
* the string and convert it to a type OID and type modifier.
709-
* If missing_ok is true, InvalidOid is returned rather than raising an error
710-
* when the type name is not found.
708+
* the string and return the result as a TypeName.
709+
* If the string cannot be parsed as a type, an error is raised.
711710
*/
712-
void
713-
parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p,
714-
bool missing_ok)
711+
TypeName *
712+
typeStringToTypeName(const char *str)
715713
{
716714
StringInfoData buf;
717715
List *raw_parsetree_list;
@@ -720,7 +718,6 @@ parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p,
720718
TypeCast *typecast;
721719
TypeName *typeName;
722720
ErrorContextCallback ptserrcontext;
723-
Type tup;
724721

725722
/* make sure we give useful error for empty input */
726723
if (strspn(str, " \t\n\r\f") == strlen(str))
@@ -779,13 +776,39 @@ parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p,
779776
typecast->arg == NULL ||
780777
!IsA(typecast->arg, A_Const))
781778
goto fail;
779+
782780
typeName = typecast->typeName;
783781
if (typeName == NULL ||
784782
!IsA(typeName, TypeName))
785783
goto fail;
786784
if (typeName->setof)
787785
goto fail;
788786

787+
pfree(buf.data);
788+
789+
return typeName;
790+
791+
fail:
792+
ereport(ERROR,
793+
(errcode(ERRCODE_SYNTAX_ERROR),
794+
errmsg("invalid type name \"%s\"", str)));
795+
}
796+
797+
/*
798+
* Given a string that is supposed to be a SQL-compatible type declaration,
799+
* such as "int4" or "integer" or "character varying(32)", parse
800+
* the string and convert it to a type OID and type modifier.
801+
* If missing_ok is true, InvalidOid is returned rather than raising an error
802+
* when the type name is not found.
803+
*/
804+
void
805+
parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok)
806+
{
807+
TypeName *typeName;
808+
Type tup;
809+
810+
typeName = typeStringToTypeName(str);
811+
789812
tup = LookupTypeName(NULL, typeName, typmod_p, missing_ok);
790813
if (tup == NULL)
791814
{
@@ -808,13 +831,4 @@ parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p,
808831
*typeid_p = HeapTupleGetOid(tup);
809832
ReleaseSysCache(tup);
810833
}
811-
812-
pfree(buf.data);
813-
814-
return;
815-
816-
fail:
817-
ereport(ERROR,
818-
(errcode(ERRCODE_SYNTAX_ERROR),
819-
errmsg("invalid type name \"%s\"", str)));
820834
}

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 201412232
56+
#define CATALOG_VERSION_NO 201412233
5757

5858
#endif

src/include/catalog/objectaddress.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ extern HeapTuple get_catalog_object_by_oid(Relation catalog,
5555
extern char *getObjectDescription(const ObjectAddress *object);
5656
extern char *getObjectDescriptionOids(Oid classid, Oid objid);
5757

58+
extern int read_objtype_from_string(const char *objtype);
5859
extern char *getObjectTypeDescription(const ObjectAddress *object);
5960
extern char *getObjectIdentity(const ObjectAddress *address);
6061

src/include/catalog/pg_proc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3036,6 +3036,9 @@ DESCR("get identification of SQL object");
30363036
DATA(insert OID = 3839 ( pg_identify_object PGNSP PGUID 12 1 0 0 0 f f f f t f s 3 0 2249 "26 26 23" "{26,26,23,25,25,25,25}" "{i,i,i,o,o,o,o}" "{classid,objid,subobjid,type,schema,name,identity}" _null_ pg_identify_object _null_ _null_ _null_ ));
30373037
DESCR("get machine-parseable identification of SQL object");
30383038

3039+
DATA(insert OID = 3954 ( pg_get_object_address PGNSP PGUID 12 1 0 0 0 f f f f t f s 3 0 2249 "25 1009 1009" "{25,1009,1009,26,26,23}" "{i,i,i,o,o,o}" "{type,name,args,classid,objid,subobjid}" _null_ pg_get_object_address _null_ _null_ _null_ ));
3040+
DESCR("get OID-based object address from name/args arrays");
3041+
30393042
DATA(insert OID = 2079 ( pg_table_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_table_is_visible _null_ _null_ _null_ ));
30403043
DESCR("is table visible in search path?");
30413044
DATA(insert OID = 2080 ( pg_type_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_type_is_visible _null_ _null_ _null_ ));

src/include/nodes/parsenodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,7 @@ typedef enum ObjectType
11851185
OBJECT_COLLATION,
11861186
OBJECT_CONVERSION,
11871187
OBJECT_DATABASE,
1188+
OBJECT_DEFAULT,
11881189
OBJECT_DOMAIN,
11891190
OBJECT_DOMCONSTRAINT,
11901191
OBJECT_EVENT_TRIGGER,

src/include/parser/parse_type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ extern Datum stringTypeDatum(Type tp, char *string, int32 atttypmod);
4747

4848
extern Oid typeidTypeRelid(Oid type_id);
4949

50+
extern TypeName *typeStringToTypeName(const char *str);
5051
extern void parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok);
5152

5253
#define ISCOMPLEX(typeid) (typeidTypeRelid(typeid) != InvalidOid)

src/include/utils/builtins.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,9 @@ extern Datum pg_last_committed_xact(PG_FUNCTION_ARGS);
12011201
extern Datum pg_describe_object(PG_FUNCTION_ARGS);
12021202
extern Datum pg_identify_object(PG_FUNCTION_ARGS);
12031203

1204+
/* catalog/objectaddress.c */
1205+
extern Datum pg_get_object_address(PG_FUNCTION_ARGS);
1206+
12041207
/* commands/constraint.c */
12051208
extern Datum unique_key_recheck(PG_FUNCTION_ARGS);
12061209

0 commit comments

Comments
 (0)