<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # Chapter 51\. 書寫一個過程語言處理器 調用函數的時候,如果函數的書寫語言不是目前的"版本-1"的編譯語言接口 (這包括用戶定義的過程語言寫的函數,用SQL寫的函數,以及用版本0的編譯語言接口寫的函數),都會通過一個_調用處理器_處理具體的語言。 調用處理器有責任用一種有意義的方法執行這個函數,比如說解析所提供的文本等等。 本章簡介如何書寫一個新的過程語言調用處理器。 過程語言的調用處理器是一個"普通"的函數,必須使用一種編譯語言來寫,比如 C ,使用版本-1的接口,并且在PostgreSQL里注冊成接受零個參數并且返回類型為`language_handler`。 這個特殊的偽類型標識該函數為一個調用處理器并且避免它直接在 SQL 命令中被調用。 關于C語言調用規范以及動態加載的更過細節請參考[Section 35.9](#calibre_link-835)。 調用處理器的調用方式和其它函數一樣:它接受一個指向一個 `FunctionCallInfoData` `struct`的指針, 這個指針包含參數值和有關被調用的函數的信息,并且預期它返回一個`Datum`結果(如果它希望返回一個 SQL 的空結果,那么可能設置 `isnull` 字段)。 調用處理器和普通的被調函數的區別是 `FunctionCallInfoData` 結構的 `flinfo-&gt;fn_oid` 字段包含實際要調用的函數的 OID ,而不是調用處理器自身。 調用處理器必須使用這個字段判斷要執行哪個函數。通常,傳遞進來的參數列表也是按照目標函數的聲明設置的,而不是給調用處理器設置的。 從系統表`pg_proc`里抓取函數入口以及分析被調函數的參數和返回類型就是調用處理器的事了。 來自`CREATE FUNCTION`命令中的`AS` 子句將會在`pg_proc` 行的 `prosrc` 字段中找到。 這個通常是過程語言本身的源文本,但也可以是別的東西,比如一個指向某個文件的路徑名,或者任何告訴調用處理器如何詳細處理的東西。 通常,每個 SQL 語句里面可能要調用同一個函數多次。 調用處理器可以利用`flinfo-&gt;fn_extra`字段避免重復地查找有關被調函數的信息。 這個字段初始為`NULL`,但是可以被調用處理器設置為指向有關被調函數的信息。 在隨后的調用中,如果`flinfo-&gt;fn_extra`已經為非 NULL ,那么就可以直接使用它而免于重新查找信息。 調用處理器必須確保`flinfo-&gt;fn_extra`是用于指向一塊至少會生存到當前查詢結束的內存區里,因為一個`FmgrInfo` 數據結構將會保存那么長的時間。 一個實現這個要求的方法是在 `flinfo-&gt;fn_mcxt`聲明的內存環境里分配一塊額外的數據;這樣的數據通常和 `FmgrInfo` 自己有一樣的生命期。 但是處理器也可以同樣選擇使用一個更長生存期的環境,這樣它就可以跨查詢緩存函數定義。 在過程語言函數以觸發器的形式調用的時候,就沒有什么參數以通常的方式傳遞進來, 而是 `FunctionCallInfoData` 的 `context` 字段指向一個 `TriggerData` 結構,而不是像普通函數調用里面的 `NULL`那樣。 一個語言處理器應該為過程語言函數提供獲取觸發器信息的機制。 下面是一個用 C 寫的存儲過程語言處理器的模版: ``` #include "postgres.h" #include "executor/spi.h" #include "commands/trigger.h" #include "fmgr.h" #include "access/heapam.h" #include "utils/syscache.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC; #endif PG_FUNCTION_INFO_V1(plsample_call_handler); Datum plsample_call_handler(PG_FUNCTION_ARGS) { Datum retval; if (CALLED_AS_TRIGGER(fcinfo)) { /* * 作為觸發器過程調用 */ TriggerData *trigdata = (TriggerData *) fcinfo->context; retval = ... } else { /* * 作為函數調用 */ retval = ... } return retval; } ``` 在打點的地方放上幾千行代碼就可以完成調用處理器。 在把處理器函數編譯成一個可加載的模塊(參閱[Section 35.9.6](#calibre_link-926))之后,下面的命令就可以注冊這個例子過程語言: ``` CREATE FUNCTION plsample_call_handler() RETURNS language_handler AS '_filename_' LANGUAGE C; CREATE LANGUAGE plsample HANDLER plsample_call_handler; ``` 盡管提供一個調用處理器對創建一個最小的過程語言已經足夠了,但是還有另外兩個可選的函數如果也能提供的話將會讓這個語言更加容易使用。 它們是_有效性驗證函數_和_內聯處理器_。 提供有效性驗證函數將會允許[CREATE FUNCTION](#calibre_link-4)時進行語言方面的檢查。 提供內聯處理器將會允許該語言支持通過[DO](#calibre_link-521)命令執行的匿名代碼塊。 如果過程語言提供了有效性驗證函數,必須將它聲明為帶單個`oid`類型參數的函數。 有效性驗證函數的返回結果會被忽略,因此習慣上將其聲明為返回`void`。 有效性驗證函數在`CREATE FUNCTION`命令執行的末尾被調用,這時已經創建或者更新了一個使用這個過程語言書寫的函數。 傳入的OID是這個函數在`pg_proc`中對應行的OID。 有效性驗證函數必須以通常的方式獲取這一行并做一些恰當的檢查。 通常的檢查包括:確認函數的參數和結果類型是被該語言支持的,函數體是符合該語言語法的。 如果有效性驗證函數發現函數是正確的,只需要返回就可以了。 如果發現了錯誤應該通過`ereport()`報告錯誤。 拋出一個錯誤將強行回滾事務并避免了不正確的函數定義被提交。 有效性驗證函數通常應該遵循[check_function_bodies](#calibre_link-2299)參數的設置。 如果被設置為無效,任何昂貴的或依賴于上下文的檢查應該被跳過。 這個參數會被pg_dump關閉,這樣就不用擔心函數體對其他數據庫中的對象有依賴關系了。 (因為這個要求,調用處理器不應該假定有效性驗證函數已經做過了完整的檢查。 有效性驗證函數存在的目的并不是讓調用處理器可以省略檢查,而是為了在`CREATE FUNCTION`命令中包含明顯的錯誤時可以立即通知用戶) 精確的選擇要檢查哪些東西是由有效性驗證函數決定的,注意當`check_function_bodies`有效時,核心的`CREATE FUNCTION`代碼僅執行附加在函數上`SET`子句。 因此,當`check_function_bodies`無效時,很明顯應該跳過哪些東西的結果將被GUC參數影響的檢查,以避免加載dump時出現錯誤的失敗。 如果過程語言提供了內聯處理器,必須將它聲明為帶單個`internal`類型參數的函數。 內聯處理器的返回結果會被忽略,因此習慣上將其聲明為返回`void`。 當一個使用該語言的`DO`語句執行時,內聯處理器將被調用。 實際傳遞的參數是一個`InlineCodeBlock`結構的指針。 這個結構包含了`DO`語句的參數信息,尤其是要執行的匿名代碼塊的文本。 內聯處理器將執行這個代碼并返回。 建議打包所有這些函數的聲明以及`CREATE LANGUAGE`命令自身到一個_擴展_中, 這樣只需要一個簡單的`CREATE EXTENSION`命令就可以安裝這個語言了。 關于書寫擴展的方法,請參考[Section 35.15](#calibre_link-840) 。 如果想書寫自己的調用處理器,那么包含在標準發布里面的過程語言是很好的例子。參考一下源代碼樹中的`src/pl` 子目錄。 [CREATE LANGUAGE](#calibre_link-605)參考頁面中也有一些有用的信息。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看