GridDB FDW中系统列SELECT与WHERE条件行为不一致问题排查
解决GridDB FDW下系统列WHERE条件下推失败的问题
问题现象
查询tableoid、ctid这类PostgreSQL系统列时,出现行为不一致的情况:
- 直接执行SELECT语句可正常获取结果:
SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; tableoid | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ----------+----+----+-------+--------------------------+--------------------------+----+----+----- ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo (1 row)
- 但带WHERE条件过滤系统列时会报错,原因是GridDB FDW将系统列条件下推至远端,而GridDB本身不存在这些PostgreSQL系统列:
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; QUERY PLAN -------------------------------------------------------------------- Limit Output: c1, c2, c3, c4, c5, c6, c7, c8 -> Foreign Scan on public.ft1 t1 Output: c1, c2, c3, c4, c5, c6, c7, c8 Remote SQL: SELECT * FROM "T1" WHERE ((tableoid = 1259)) (5 rows) SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass LIMIT 1; ERROR: GridDB-API is failed by 150012 at griddb_fdw.c: 2276 No such column tableoid
解决方法
方法1:强制本地过滤系统列条件
使用子查询先将远端数据拉取到PostgreSQL本地,再在本地应用系统列的过滤条件:SELECT * FROM ( SELECT tableoid::regclass, * FROM ft1 t1 ) sub WHERE sub.tableoid = 'ft1'::regclass LIMIT 1;如果GridDB FDW支持
NO_PUSH_DOWN提示,也可以直接在查询中禁用该列的下推:SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass LIMIT 1 OPTIONS (NO_PUSH_DOWN 'tableoid');方法2:修改GridDB FDW源码(自定义扩展场景)
在griddb_fdw.c的Remote SQL生成逻辑中,添加系统列识别规则,当WHERE条件包含tableoid、ctid等PostgreSQL专属系统列时,不将该条件下推至远端,交由PostgreSQL本地处理。方法3:用视图封装查询
创建包含系统列的视图,通过查询视图实现本地过滤:CREATE VIEW v_ft1 AS SELECT tableoid::regclass, * FROM ft1; SELECT * FROM v_ft1 WHERE tableoid = 'ft1'::regclass LIMIT 1;视图会先将远端数据拉取到本地,再执行WHERE条件过滤,避免系统列下推到GridDB。
内容的提问来源于stack exchange,提问作者Nooruddin Lakhani
相关产品推荐
相关产品推荐

