中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PostgreSQL如何解析表達式.

發布時間:2021-11-09 14:32:57 來源:億速云 閱讀:469 作者:iii 欄目:關系型數據庫

本篇內容介紹了“PostgreSQL如何解析表達式.”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!


SQL樣例腳本.

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

一、數據結構

FmgrInfo
在函數通過fmgr調用前,該結構體持有系統目錄(字典)信息,用于檢索相關信息.
如果相同的函數將被調用多次,檢索只需要完成一次即可,該結構體會緩存多次使用.

/*
 * 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.
 * 在函數通過fmgr調用前,該結構體持有系統目錄(字典)信息,用于檢索相關信息.
 * 如果相同的函數將被調用多次,檢索只需要完成一次即可,該結構體會緩存多次使用.
 *
 * 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實際上是關于參數的解析時確定的信息,而不是函數自身.
 * 但fn_expr在這里存儲而不是FunctionCallInfoData中存儲,因為從邏輯上來說,它就應該屬于那.
 *
 * 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可用于被調用函數的使用;所有其他字段應該在結構體創建后被處理為只讀.
 */
typedef struct FmgrInfo
{
    //指向函數或者將被調用的處理器
    PGFunction  fn_addr;        /* pointer to function or handler to be called */
    //函數的oid
    Oid         fn_oid;         /* OID of function (NOT of handler, if any) */
    //輸入參數的個數,0..FUNC_MAX_ARGS
    short       fn_nargs;       /* number of input args (0..FUNC_MAX_ARGS) */
    //函數是否嚴格(strict),輸入NULL,輸出NULL
    bool        fn_strict;      /* function is "strict" (NULL in => NULL out) */
    //函數是否返回集合
    bool        fn_retset;      /* function returns a set */
    //如track_functions > this,則收集統計信息
    unsigned char fn_stats;     /* collect stats if track_functions > this */
    //handler使用的額外空間
    void       *fn_extra;       /* extra space for use by handler */
    //存儲fn_extra的內存上下文
    MemoryContext fn_mcxt;      /* memory context to store fn_extra in */
    //表達式解析樹,或者為NULL
    fmNodePtr   fn_expr;        /* expression parse tree for call, or NULL */
} FmgrInfo;
typedef struct Node *fmNodePtr;

FunctionCallInfoData
該結構體存儲了實際傳遞給fmgr-called函數的參數

/*
 * This struct is the data actually passed to an fmgr-called function.
 * 該結構體存儲了實際傳遞給fmgr-called函數的參數
 *
 * 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.)
 * 被調用的函數期望設置isnull以及可能的resultinfo或者resultinfo指向的域字段.
 * 不應該改變其他字段.
 * (特別的,在參數數組上亂寫是個壞主意,因為某些調用者假定它們可以使用相同的參數重復調用)
 */
typedef struct FunctionCallInfoData
{
    //指向該調用的檢索信息
    FmgrInfo   *flinfo;         /* ptr to lookup info used for this call */
    //調用上下文
    fmNodePtr   context;        /* pass info about context of call */
    //傳遞或返回關于結果的特別信息
    fmNodePtr   resultinfo;     /* pass or return extra info about result */
    //函數的collation
    Oid         fncollation;    /* collation for function to use */
#define FIELDNO_FUNCTIONCALLINFODATA_ISNULL 4
    //如結果為NULL,則必須設置為T
    bool        isnull;         /* function must set true if result is NULL */
    //實際傳遞的參數個數
    short       nargs;          /* # arguments actually passed */
#define FIELDNO_FUNCTIONCALLINFODATA_ARG 6
    //傳遞給函數的參數
    Datum       arg[FUNC_MAX_ARGS]; /* Arguments passed to function */
#define FIELDNO_FUNCTIONCALLINFODATA_ARGNULL 7
    //如arg[i]為NULL,則對應的值為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.)
 * 所有函數可以通過fmgr直接調用,但必須持有簽名.
 * (其他函數可通過使用handler的方式調用,也有此簽名)
 */
typedef struct FunctionCallInfoData *FunctionCallInfo;

二、源碼解讀

ExecInterpExpr
ExecInterpExpr中與表達式求值相關的代碼片段如下:

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();
        }

如為函數表達式,則從ExecInitFunc初始化的步驟信息中獲取統一的調用參數fcinfo,然后通過函數指針(用于封裝)調用實際的函數進行表達式求值.通過統一的參數,統一的返回值,做到了實現的統一,體現了面向對象OO中多態的思想,這再次說明了OO是思想,用過程性語言一樣可以實現.

int4pl
SQL樣例腳本相應的實現函數是int4pl,其實現代碼如下:

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
}

函數實現相對比較簡單,兩個數簡單相加,如溢出則返回T,否則返回F.

“PostgreSQL如何解析表達式.”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

平邑县| 景宁| 松溪县| 桂林市| 鹤峰县| 通海县| 玉田县| 尖扎县| 都昌县| 石泉县| 鄢陵县| 桑日县| 开化县| 广汉市| 乌鲁木齐市| 神农架林区| 昌吉市| 新泰市| 淮阳县| 张家界市| 共和县| 苗栗市| 高密市| 林芝县| 青海省| 南江县| 淅川县| 海伦市| 临猗县| 日喀则市| 邻水| 芜湖市| 门源| 邓州市| 宝坻区| 类乌齐县| 石狮市| 永德县| 灵璧县| 甘孜县| 永丰县|