• 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版本都可适用!!(如有问题,欢迎一起讨论)

      

  • 相关阅读:
    [Design]设计模式结构模式
    [Design] 设计模式行为模式
    [Design] Decorator Pattern
    ILIST<T>和LIST<T> 枫
    js 如何调用Windows自带的配色控件 枫
    WML语法全接触 WAP建站语言 枫
    Asp.net模板引擎技术 枫
    smarty内建函数 枫
    NameValueCollection详解 枫
    smarty循环调用问题 枫
  • 原文地址:https://www.cnblogs.com/lujunfeng/p/6293168.html
Copyright © 2020-2023  润新知