• postgres外部表如何修改源码适配pg升级


    postgres中外部表的应用如下:

    但是许多在github上的fdw开源代码都是基于9.3以及9.4版本开发,原作者没有随着pg的版本升级而将外部表扩展升级,那只能靠自己去手动修改源码来让这些扩展能够使用。

    typedef struct FdwRoutine此结构是外部表当中的关键,结构体内部挂接的都是读写外部表的钩子函数(函数指针),在内核部分是如果判断读写的表是外部表,就会走外部表的case分支。

    如何9.5以前的外部表使其能够使用呢

    一、fdwRoutine->GetForeignPlan结构体中的函数指针在9.5之前都是6个参数,9.5含9.5之后变成了7个参数

    因此需要将fdwRoutine->GetForeignPlan = xxxxGetForeignPlan; 这个函数的实现修改正确了,一般新增参数用NULL或者nill去替代,特殊情况,还需要研读源码。

    还要注意了在函数体中也会常调用make_foreignscan,此函数也需要修改,修改如下

    #if PG_VERSION_NUM >= 90500
    static ForeignScan *
    XXXGetForeignPlan(PlannerInfo *root, RelOptInfo *baserel, Oid foreignTableId,
    					 ForeignPath *bestPath, List *targetList, List *scanClauses,
    					 Plan *outerPlan)
    #else
    static ForeignScan *
    XXXGetForeignPlan(PlannerInfo *root, RelOptInfo *baserel, Oid foreignTableId,
    					 ForeignPath *bestPath, List *targetList, List *scanClauses)
    #endif
    {
        ......
        ......
    #if PG_VERSION_NUM >= 90500
    	foreignScan = make_foreignscan(targetList, scanClauses, baserel->relid,
    								   NIL, /* no expressions to evaluate */
    								   foreignPrivateList,
    								   NIL,
    								   NIL,
    								   NULL); /* no outer path */
    #else
    	foreignScan = make_foreignscan(targetList, scanClauses, baserel->relid,
    								   NIL, /* no expressions to evaluate */
    								   foreignPrivateList);
    #endif
        ......    
        ......
    	return foreignScan;
    }
    

      

    二、fdwRoutine->GetForeignPaths这个函数指针一般会调用create_foreignscan_path这个函数,此函数不同版本参数也不同,在调用处修改为

    #if PG_VERSION_NUM >= 90600
    	foreignScanPath = (Path *) create_foreignscan_path(root, baserel,
    													   NULL, /* path target */
    													   baserel->rows,
    													   startupCost, totalCost,
    													   NIL,  /* no known ordering */
    													   NULL, /* not parameterized */
    													   NULL, /* no outer path */
    													   NIL); /* no fdw_private */
    
    #elif PG_VERSION_NUM >= 90500
    	foreignScanPath = (Path *) create_foreignscan_path(root, baserel, baserel->rows,
    													   startupCost, totalCost,
    													   NIL,  /* no known ordering */
    													   NULL, /* not parameterized */
    													   NULL, /* no outer path */
    													   NIL); /* no fdw_private */
    #else
    	foreignScanPath = (Path *) create_foreignscan_path(root, baserel, baserel->rows,
    													   startupCost, totalCost,
    													   NIL,  /* no known ordering */
    													   NULL, /* not parameterized */
    													   NIL); /* no fdw_private */
    #endif
    

    三、typedef struct RelOptInfo结构体中的targetlist改变了,修改如下

    #if PG_VERSION_NUM >= 90600
    	List *targetColumnList = baserel->reltarget->exprs;
    #else
    	List *targetColumnList = baserel->reltargetlist;
    #endif
    

    四、pull_var_clause()函数的改变,修改如下

    #if PG_VERSION_NUM >= 90600
    		targetVarList = pull_var_clause(targetExpr,
    										PVC_RECURSE_AGGREGATES |
    										PVC_RECURSE_PLACEHOLDERS);
    #else
    		targetVarList = pull_var_clause(targetExpr,
    										PVC_RECURSE_AGGREGATES,
    										PVC_RECURSE_PLACEHOLDERS);
    #endif
    

    五、头文件使用,像cstore_fdw中就存在,pg_lzcompress.h关于压缩的头文件,内核部分将这个头文件更改了目录,修改如下

    #if PG_VERSION_NUM >= 90600
    #include "common/pg_lzcompress.h"
    #else
    #include "utils/pg_lzcompress.h"
    #endif
    

    按照以上步骤修改,现有的pg版本都可适用!!(如有问题,欢迎一起讨论)

      

  • 相关阅读:
    洛谷 P1567 统计天数【最长上升子序列/断则归一】
    洛谷 P3742 umi的函数【构造】
    洛谷 P1036 选数【背包型DFS/选or不选】
    nyoj zb的生日【背包型DFS/选or不选】
    POJ 3628 Bookshelf 2【背包型DFS/选or不选】
    【AHOI2013复仇】从一道题来看DFS及其优化的一般步骤和数组分层问题【转】
    洛谷 P1217 [USACO1.5]回文质数 Prime Palindromes【取回文数/数论/字符串】
    洛谷 P1004 方格取数 【多线程DP/四维DP/】
    Codeforces Round #449 (Div. 2) B. Chtholly's request【偶数位回文数】
    Codeforces Round #449 (Div. 2) A. Scarborough Fair【多次区间修改字符串】
  • 原文地址:https://www.cnblogs.com/lujunfeng/p/6293168.html
Copyright © 2020-2023  润新知