真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

PostgreSQL如何解析表達(dá)式.

本篇內(nèi)容介紹了“PostgreSQL如何解析表達(dá)式.”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)公司是一家專業(yè)提供荷塘企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、HTML5、小程序制作等業(yè)務(wù)。10年已為荷塘眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進(jìn)行中。


SQL樣例腳本.

testdb=# select 1+id,c2 from t_expr where id < 3;

一、數(shù)據(jù)結(jié)構(gòu)

FmgrInfo
在函數(shù)通過fmgr調(diào)用前,該結(jié)構(gòu)體持有系統(tǒng)目錄(字典)信息,用于檢索相關(guān)信息.
如果相同的函數(shù)將被調(diào)用多次,檢索只需要完成一次即可,該結(jié)構(gòu)體會(huì)緩存多次使用.

/*
 * This struct holds the system-catalog information that must be looked up
 * before a function can be called through fmgr.  If the same function is
 * to be called multiple times, the lookup need be done only once and the
 * info struct saved for re-use.
 * 在函數(shù)通過fmgr調(diào)用前,該結(jié)構(gòu)體持有系統(tǒng)目錄(字典)信息,用于檢索相關(guān)信息.
 * 如果相同的函數(shù)將被調(diào)用多次,檢索只需要完成一次即可,該結(jié)構(gòu)體會(huì)緩存多次使用.
 *
 * Note that fn_expr really is parse-time-determined information about the
 * arguments, rather than about the function itself.  But it's convenient
 * to store it here rather than in FunctionCallInfoData, where it might more
 * logically belong.
 * 注意,fn_expr實(shí)際上是關(guān)于參數(shù)的解析時(shí)確定的信息,而不是函數(shù)自身.
 * 但fn_expr在這里存儲(chǔ)而不是FunctionCallInfoData中存儲(chǔ),因?yàn)閺倪壿嬌蟻碚f,它就應(yīng)該屬于那.
 *
 * fn_extra is available for use by the called function; all other fields
 * should be treated as read-only after the struct is created.
 * fn_extra可用于被調(diào)用函數(shù)的使用;所有其他字段應(yīng)該在結(jié)構(gòu)體創(chuàng)建后被處理為只讀.
 */
typedef struct FmgrInfo
{
    //指向函數(shù)或者將被調(diào)用的處理器
    PGFunction  fn_addr;        /* pointer to function or handler to be called */
    //函數(shù)的oid
    Oid         fn_oid;         /* OID of function (NOT of handler, if any) */
    //輸入?yún)?shù)的個(gè)數(shù),0..FUNC_MAX_ARGS
    short       fn_nargs;       /* number of input args (0..FUNC_MAX_ARGS) */
    //函數(shù)是否嚴(yán)格(strict),輸入NULL,輸出NULL
    bool        fn_strict;      /* function is "strict" (NULL in => NULL out) */
    //函數(shù)是否返回集合
    bool        fn_retset;      /* function returns a set */
    //如track_functions > this,則收集統(tǒng)計(jì)信息
    unsigned char fn_stats;     /* collect stats if track_functions > this */
    //handler使用的額外空間
    void       *fn_extra;       /* extra space for use by handler */
    //存儲(chǔ)fn_extra的內(nèi)存上下文
    MemoryContext fn_mcxt;      /* memory context to store fn_extra in */
    //表達(dá)式解析樹,或者為NULL
    fmNodePtr   fn_expr;        /* expression parse tree for call, or NULL */
} FmgrInfo;
typedef struct Node *fmNodePtr;

FunctionCallInfoData
該結(jié)構(gòu)體存儲(chǔ)了實(shí)際傳遞給fmgr-called函數(shù)的參數(shù)

/*
 * This struct is the data actually passed to an fmgr-called function.
 * 該結(jié)構(gòu)體存儲(chǔ)了實(shí)際傳遞給fmgr-called函數(shù)的參數(shù)
 *
 * The called function is expected to set isnull, and possibly resultinfo or
 * fields in whatever resultinfo points to.  It should not change any other
 * fields.  (In particular, scribbling on the argument arrays is a bad idea,
 * since some callers assume they can re-call with the same arguments.)
 * 被調(diào)用的函數(shù)期望設(shè)置isnull以及可能的resultinfo或者resultinfo指向的域字段.
 * 不應(yīng)該改變其他字段.
 * (特別的,在參數(shù)數(shù)組上亂寫是個(gè)壞主意,因?yàn)槟承┱{(diào)用者假定它們可以使用相同的參數(shù)重復(fù)調(diào)用)
 */
typedef struct FunctionCallInfoData
{
    //指向該調(diào)用的檢索信息
    FmgrInfo   *flinfo;         /* ptr to lookup info used for this call */
    //調(diào)用上下文
    fmNodePtr   context;        /* pass info about context of call */
    //傳遞或返回關(guān)于結(jié)果的特別信息
    fmNodePtr   resultinfo;     /* pass or return extra info about result */
    //函數(shù)的collation
    Oid         fncollation;    /* collation for function to use */
#define FIELDNO_FUNCTIONCALLINFODATA_ISNULL 4
    //如結(jié)果為NULL,則必須設(shè)置為T
    bool        isnull;         /* function must set true if result is NULL */
    //實(shí)際傳遞的參數(shù)個(gè)數(shù)
    short       nargs;          /* # arguments actually passed */
#define FIELDNO_FUNCTIONCALLINFODATA_ARG 6
    //傳遞給函數(shù)的參數(shù)
    Datum       arg[FUNC_MAX_ARGS]; /* Arguments passed to function */
#define FIELDNO_FUNCTIONCALLINFODATA_ARGNULL 7
    //如arg[i]為NULL,則對(duì)應(yīng)的值為T
    bool        argnull[FUNC_MAX_ARGS]; /* T if arg[i] is actually NULL */
} FunctionCallInfoData;
/*
 * All functions that can be called directly by fmgr must have this signature.
 * (Other functions can be called by using a handler that does have this
 * signature.)
 * 所有函數(shù)可以通過fmgr直接調(diào)用,但必須持有簽名.
 * (其他函數(shù)可通過使用handler的方式調(diào)用,也有此簽名)
 */
typedef struct FunctionCallInfoData *FunctionCallInfo;

二、源碼解讀

ExecInterpExpr
ExecInterpExpr中與表達(dá)式求值相關(guān)的代碼片段如下:

EEO_CASE(EEOP_FUNCEXPR)
        {
            FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
            Datum       d;
            fcinfo->isnull = false;
            d = op->d.func.fn_addr(fcinfo);
            *op->resvalue = d;
            *op->resnull = fcinfo->isnull;
            EEO_NEXT();
        }

如為函數(shù)表達(dá)式,則從ExecInitFunc初始化的步驟信息中獲取統(tǒng)一的調(diào)用參數(shù)fcinfo,然后通過函數(shù)指針(用于封裝)調(diào)用實(shí)際的函數(shù)進(jìn)行表達(dá)式求值.通過統(tǒng)一的參數(shù),統(tǒng)一的返回值,做到了實(shí)現(xiàn)的統(tǒng)一,體現(xiàn)了面向?qū)ο驩O中多態(tài)的思想,這再次說明了OO是思想,用過程性語言一樣可以實(shí)現(xiàn).

int4pl
SQL樣例腳本相應(yīng)的實(shí)現(xiàn)函數(shù)是int4pl,其實(shí)現(xiàn)代碼如下:

Datum
int4pl(PG_FUNCTION_ARGS)
{
    int32       arg1 = PG_GETARG_INT32(0);
    int32       arg2 = PG_GETARG_INT32(1);
    int32       result;
    if (unlikely(pg_add_s32_overflow(arg1, arg2, &result)))
        ereport(ERROR,
                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                 errmsg("integer out of range")));
    PG_RETURN_INT32(result);
}
/*
 * If a + b overflows, return true, otherwise store the result of a + b into
 * *result. The content of *result is implementation defined in case of
 * overflow.
 */
static inline bool
pg_add_s32_overflow(int32 a, int32 b, int32 *result)
{
#if defined(HAVE__BUILTIN_OP_OVERFLOW)
    return __builtin_add_overflow(a, b, result);
#else
    int64       res = (int64) a + (int64) b;
    if (res > PG_INT32_MAX || res < PG_INT32_MIN)
    {
        *result = 0x5EED;       /* to avoid spurious warnings */
        return true;
    }
    *result = (int32) res;
    return false;
#endif
}

函數(shù)實(shí)現(xiàn)相對(duì)比較簡(jiǎn)單,兩個(gè)數(shù)簡(jiǎn)單相加,如溢出則返回T,否則返回F.

“PostgreSQL如何解析表達(dá)式.”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


新聞標(biāo)題:PostgreSQL如何解析表達(dá)式.
標(biāo)題網(wǎng)址:http://weahome.cn/article/poisho.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部