4343#include <postgres.h>
4444#include <fmgr.h>
4545#include <funcapi.h>
46+ #include <access/genam.h>
4647#include <access/htup.h>
48+ #include <access/table.h>
4749#include <catalog/namespace.h>
4850#include <catalog/pg_type.h>
51+ #include <catalog/pg_extension.h>
4952#include <catalog/dependency.h>
5053#include <commands/extension.h>
5154#include <lib/stringinfo.h>
5861#include <utils/lsyscache.h>
5962#include <utils/syscache.h>
6063#include <utils/typcache.h>
64+ #include <utils/fmgroids.h>
6165#include <utils/guc.h>
6266
6367#if PG_VERSION_NUM >= 100000
@@ -574,6 +578,43 @@ header_array_to_slist(ArrayType *array, struct curl_slist *headers)
574578 return headers ;
575579}
576580
581+ /**
582+ * Look up the namespace the extension is installed in
583+ */
584+ static Oid
585+ get_extension_schema (Oid ext_oid )
586+ {
587+ Oid result ;
588+ Relation rel ;
589+ SysScanDesc scandesc ;
590+ HeapTuple tuple ;
591+ ScanKeyData entry [1 ];
592+
593+ rel = table_open (ExtensionRelationId , AccessShareLock );
594+
595+ ScanKeyInit (& entry [0 ],
596+ Anum_pg_extension_oid ,
597+ BTEqualStrategyNumber , F_OIDEQ ,
598+ ObjectIdGetDatum (ext_oid ));
599+
600+ scandesc = systable_beginscan (rel , ExtensionOidIndexId , true,
601+ NULL , 1 , entry );
602+
603+ tuple = systable_getnext (scandesc );
604+
605+ /* We assume that there can be at most one matching tuple */
606+ if (HeapTupleIsValid (tuple ))
607+ result = ((Form_pg_extension ) GETSTRUCT (tuple ))-> extnamespace ;
608+ else
609+ result = InvalidOid ;
610+
611+ systable_endscan (scandesc );
612+
613+ table_close (rel , AccessShareLock );
614+
615+ return result ;
616+ }
617+
577618/**
578619* Look up the tuple description for a extension-defined type,
579620* avoiding the pitfalls of using relations that are not part
@@ -584,33 +625,30 @@ static TupleDesc
584625typname_get_tupledesc (const char * extname , const char * typname )
585626{
586627 Oid extoid = get_extension_oid (extname , true);
587- ListCell * l ;
628+ Oid extschemaoid ;
588629
589630 if ( ! OidIsValid (extoid ) )
590631 elog (ERROR , "could not lookup '%s' extension oid" , extname );
591632
592- foreach (l , fetch_search_path (true))
593- {
594- Oid typnamespace = lfirst_oid (l );
633+ extschemaoid = get_extension_schema (extoid );
595634
596635#if PG_VERSION_NUM >= 120000
597- Oid typoid = GetSysCacheOid2 (TYPENAMENSP , Anum_pg_type_oid ,
598- PointerGetDatum (typname ),
599- ObjectIdGetDatum (typnamespace ));
636+ Oid typoid = GetSysCacheOid2 (TYPENAMENSP , Anum_pg_type_oid ,
637+ PointerGetDatum (typname ),
638+ ObjectIdGetDatum (extschemaoid ));
600639#else
601- Oid typoid = GetSysCacheOid2 (TYPENAMENSP ,
602- PointerGetDatum (typname ),
603- ObjectIdGetDatum (typnamespace ));
640+ Oid typoid = GetSysCacheOid2 (TYPENAMENSP ,
641+ PointerGetDatum (typname ),
642+ ObjectIdGetDatum (extschemaoid ));
604643#endif
605644
606- if ( OidIsValid (typoid ) )
645+ if ( OidIsValid (typoid ) )
646+ {
647+ // Oid typ_oid = get_typ_typrelid(rel_oid);
648+ Oid relextoid = getExtensionOfObject (TypeRelationId , typoid );
649+ if ( relextoid == extoid )
607650 {
608- // Oid typ_oid = get_typ_typrelid(rel_oid);
609- Oid relextoid = getExtensionOfObject (TypeRelationId , typoid );
610- if ( relextoid == extoid )
611- {
612- return TypeGetTupleDesc (typoid , NIL );
613- }
651+ return TypeGetTupleDesc (typoid , NIL );
614652 }
615653 }
616654
@@ -1206,7 +1244,11 @@ Datum http_request(PG_FUNCTION_ARGS)
12061244 }
12071245
12081246 /* Prepare our return object */
1209- tup_desc = RelationNameGetTupleDesc ("http_response" );
1247+ if (get_call_result_type (fcinfo , 0 , & tup_desc ) != TYPEFUNC_COMPOSITE ) {
1248+ ereport (ERROR , (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
1249+ errmsg ("%s called with incompatible return type" , __func__ )));
1250+ }
1251+
12101252 ncolumns = tup_desc -> natts ;
12111253 values = palloc0 (sizeof (Datum )* ncolumns );
12121254 nulls = palloc0 (sizeof (bool )* ncolumns );
0 commit comments