Skip to content

Commit db95be3

Browse files
committed
Fix rare case where geometry oid cannot be looked up during materialized view refresh, causing NULL return values in the matview. Closes #263
1 parent 91731ce commit db95be3

File tree

2 files changed

+94
-5
lines changed

2 files changed

+94
-5
lines changed

ogr_fdw.c

Lines changed: 90 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
269321
Oid
270322
ogrGetGeometryOid(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.

ogr_fdw.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
#include "access/reloptions.h"
2323
#include "access/sysattr.h"
2424
#include "access/transam.h"
25+
#include "catalog/indexing.h"
2526
#include "catalog/namespace.h"
2627
#include "catalog/pg_collation.h"
28+
#include "catalog/pg_extension.h"
2729
#include "catalog/pg_foreign_table.h"
2830
#include "catalog/pg_foreign_server.h"
2931
#include "catalog/pg_namespace.h"
@@ -33,6 +35,7 @@
3335
#include "commands/copy.h"
3436
#include "commands/defrem.h"
3537
#include "commands/explain.h"
38+
#include "commands/extension.h"
3639
#include "commands/vacuum.h"
3740
#include "foreign/fdwapi.h"
3841
#include "foreign/foreign.h"
@@ -49,6 +52,7 @@
4952
#include "storage/ipc.h"
5053
#include "utils/builtins.h"
5154
#include "utils/date.h"
55+
#include "utils/fmgroids.h"
5256
#include "utils/lsyscache.h"
5357
#include "utils/memutils.h"
5458
#include "utils/numeric.h"

0 commit comments

Comments
 (0)