@@ -264,27 +264,112 @@ ogr_fdw_exit(int code, Datum arg)
264264}
265265
266266/*
267- * Function to get the geometry OID if required
267+ * Given extension oid, lookup installation namespace oid.
268+ * This side steps search_path issues with
269+ * TypenameGetTypid encountered in
270+ * https://github.com/pramsey/pgsql-ogr-fdw/issues/263
271+ */
272+ static Oid
273+ get_extension_nsp_oid (Oid extOid )
274+ {
275+ Oid result ;
276+ SysScanDesc scandesc ;
277+ HeapTuple tuple ;
278+ ScanKeyData entry [1 ];
279+
280+ #if PG_VERSION_NUM < 120000
281+ Relation rel = heap_open (ExtensionRelationId , AccessShareLock );
282+ ScanKeyInit (& entry [0 ],
283+ ObjectIdAttributeNumber ,
284+ BTEqualStrategyNumber , F_OIDEQ ,
285+ ObjectIdGetDatum (extOid ));
286+ #else
287+ Relation rel = table_open (ExtensionRelationId , AccessShareLock );
288+ ScanKeyInit (& entry [0 ],
289+ Anum_pg_extension_oid ,
290+ BTEqualStrategyNumber , F_OIDEQ ,
291+ ObjectIdGetDatum (extOid ));
292+ #endif /* PG_VERSION_NUM */
293+
294+ scandesc = systable_beginscan (rel , ExtensionOidIndexId , true,
295+ NULL , 1 , entry );
296+
297+ tuple = systable_getnext (scandesc );
298+
299+ /* We assume that there can be at most one matching tuple */
300+ if (HeapTupleIsValid (tuple ))
301+ result = ((Form_pg_extension ) GETSTRUCT (tuple ))-> extnamespace ;
302+ else
303+ result = InvalidOid ;
304+
305+ systable_endscan (scandesc );
306+
307+ #if PG_VERSION_NUM < 120000
308+ heap_close (rel , AccessShareLock );
309+ #else
310+ table_close (rel , AccessShareLock );
311+ #endif
312+
313+ return result ;
314+ }
315+
316+
317+ /*
318+ * Get the geometry OID (if postgis is
319+ * installed) and cache it for quick lookup.
268320 */
269321Oid
270322ogrGetGeometryOid (void )
271323{
324+ /* Is value not set yet? */
272325 if (GEOMETRYOID == InvalidOid )
273326 {
274- Oid typoid = TypenameGetTypid ("geometry" );
275- if (OidIsValid (typoid ) && get_typisdefined (typoid ))
327+ const char * extName = "postgis" ;
328+ const char * typName = "geometry" ;
329+ bool missing_ok = true;
330+ Oid extOid , extNspOid , typOid ;
331+
332+ /* Got postgis extension? */
333+ extOid = get_extension_oid (extName , missing_ok );
334+ if (!OidIsValid (extOid ))
276335 {
277- GEOMETRYOID = typoid ;
336+ elog (DEBUG2 , "%s: lookup of extension '%s' failed" , __func__ , extName );
337+ GEOMETRYOID = BYTEAOID ;
338+ return GEOMETRYOID ;
278339 }
279- else
340+
341+ /* Got namespace for extension? */
342+ extNspOid = get_extension_nsp_oid (extOid );
343+ if (!OidIsValid (extNspOid ))
280344 {
345+ elog (DEBUG2 , "%s: lookup of namespace for '%s' (%u) failed" , __func__ , extName , extOid );
281346 GEOMETRYOID = BYTEAOID ;
347+ return GEOMETRYOID ;
282348 }
349+
350+ /* Got geometry type in namespace? */
351+ typOid = GetSysCacheOid2 (TYPENAMENSP ,
352+ #if PG_VERSION_NUM >= 120000
353+ Anum_pg_type_oid ,
354+ #endif
355+ PointerGetDatum (typName ),
356+ ObjectIdGetDatum (extNspOid ));
357+
358+
359+
360+ elog (DEBUG2 , "%s: lookup of type id for '%s' got %u" , __func__ , typName , typOid );
361+
362+ /* Geometry type is good? */
363+ if (OidIsValid (typOid ) && get_typisdefined (typOid ))
364+ GEOMETRYOID = typOid ;
365+ else
366+ GEOMETRYOID = BYTEAOID ;
283367 }
284368
285369 return GEOMETRYOID ;
286370}
287371
372+
288373/*
289374 * Foreign-data wrapper handler function: return a struct with pointers
290375 * to my callback routines.
0 commit comments