<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 52.2\. 外數據封裝回調程序 FDW處理函數返回包含指向下面描述的回調函數指針的palloc'd `FdwRoutine`結構。 掃描相關函數是必須的,其余的是可選的。 在`src/include/foreign/fdwapi.h`中聲明`FdwRoutine`結構類型, 參閱額外詳情。 ## 52.2.1\. 掃描外表的FDW程序 ``` void GetForeignRelSize (PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid); ``` 獲得評估外表關系大小。這就是所謂的開始掃描外表的查詢規劃。 `root`是關于查詢的規劃器的全局信息; `baserel`是關于這個表的規劃器信息; `foreigntableid`是外表的`pg_class` OID。 (`foreigntableid`可以從規劃器數據結構中獲得, 但是它明確被傳遞用來節省力氣。) 在說明限制資格測試執行過濾之后, 該函數應該更新`baserel-&gt;rows`為通過表掃描返回的行期望數。 `baserel-&gt;rows`的初始值僅僅是恒定缺省估計, 如果可能的話,這應該被替換。如果它可以對平均結果行寬度計算出更好的評估,那么 該函數可能也會選擇更新`baserel-&gt;width`。 參閱[Section 52.4](#calibre_link-1502)可以獲取額外信息。 ``` void GetForeignPaths (PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid); ``` 創建外表掃描的可能訪問路徑。 這就是所謂的查詢規劃。 它被調用的參數和`GetForeignRelSize`相同。 該函數必須為外表掃描產生至少1個訪問路徑(`ForeignPath`節點)而且 必須調用`add_path`添加每個這樣的路徑到`baserel-&gt;pathlist`中。 推薦使用`create_foreignscan_path`建立`ForeignPath`節點。 該函數可以生成多個訪問路徑,比如具有有效`pathkeys`表示預排序結果路徑。 每個訪問路徑必須包含成本估計,并且包含需要標識具體預期掃描方法的任何FDW-私有信息。 參閱[Section 52.4](#calibre_link-1502)獲取額外信息。 ``` ForeignScan * GetForeignPlan (PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid, ForeignPath *best_path, List *tlist, List *scan_clauses); ``` 從所選擇的外訪問路徑中創建`ForeignScan`規劃節點。 這從查詢規劃結尾被調用。 該參數為`GetForeignRelSize`,加上所選擇的`ForeignPath` (通過`GetForeignPaths`預先生成), 通過規劃節點發出目標列表,并且限制子句通過規劃節點被執行。 該函數必須創建并且返回`ForeignScan`規劃節點; 推薦使用`make_foreignscan`建立`ForeignScan`節點。 參閱[Section 52.4](#calibre_link-1502)獲取額外信息。 ``` void BeginForeignScan (ForeignScanState *node, int eflags); ``` 開始執行一個外部掃描。這是在執行器啟動期間調用。它應該執行掃描開始前需要的任何初始化。 但沒有開始執行實際掃描(應該執行第一次調用`IterateForeignScan`)。 `ForeignScanState`節點已經被創建,但是它的`fdw_state`字段仍然是NULL。 通過`ForeignScanState`節點掃描的表信息(尤其是,來自底層的`ForeignScan`規劃節點, 它包含任何通過`GetForeignPlan`提供的FDW-私有信息)。 `eflags`包含描述該規劃節點執行器的操作模式的標志位。 注意當`(eflags & EXEC_FLAG_EXPLAIN_ONLY)`為真時, 該函數不應該執行任何外部可見行為; 它應該為`ExplainForeignScan`和 `EndForeignScan`執行最小需求使得節點狀態有效。 ``` TupleTableSlot * IterateForeignScan (ForeignScanState *node); ``` 從外部源讀取一行,在元組表槽中返回它(節點的`ScanTupleSlot`用于這個目的)。 如果沒有更多行可用,那么返回NULL。元組表槽基礎設施允許返回物理或者虛擬元組。 在大多數情況下后者選擇從性能角度更可取。 注意這被稱為在調用期間被重置的短暫內存語境。如果 你需要較長時間存儲,或者使用節點的`EState`的`es_query_cxt`, 那么在`BeginForeignScan`中創建內存上下文。 返回的行必須匹配掃描外表的列標志。如果你選擇優化掉不需要的列,那么 你應該在那些列位置插入空值。 注意PostgreSQL的執行器并不在乎返回的行是否違反任何在外表列定義的`NOT NULL` 約束— 但是規劃器關心,如果`NULL`值出現在聲明列中而不包含它們,那么可能錯誤地優化查詢。 當用戶聲明不應該存在時,如果遇到`NULL`值,它可能會適當提高錯誤 (正如你需要在數據類型不匹配的情況下執行)。 ``` void ReScanForeignScan (ForeignScanState *node); ``` 從開始重啟掃描。注意任何參數掃描取決于已改變的值, 因此掃描不一定返回完全相同的行。 ``` void EndForeignScan (ForeignScanState *node); ``` 結束掃描并且釋放資源。釋放palloc內存往往不重要,但是比如打開文件并且鏈接遠程服務器應該 被清理干凈。 ## 52.2.2\. 更新外表FDW程序 如果FDW支持可寫外表, 那么它應該提供一些或者所有下面的依賴于 FDW的需要和能力的回調函數: ``` void AddForeignUpdateTargets (Query *parsetree, RangeTblEntry *target_rte, Relation target_relation); ``` 在通過表掃描函數預先讀取行之前執行`UPDATE`和`DELETE`操作。 FDW可能需要額外信息,比如行ID或者主鍵列值,為了確保它可以找到確切行更新或者刪除。 為了支持它,該函數可以添加額外隱藏,或者"junk",在`UPDATE`或者 `DELETE`中從外表中檢索列表中的目標列。 要做到這一點,添加`TargetEntry`項到 `parsetree-&gt;targetList`,包含讀取的額外值的表達式。 每個這樣的項必須被標記`resjunk` = `true`, 并且有一個不同的`resname`在執行期間標識它。 避免使用匹配`ctid``_N_`或者 `wholerow``_N_`的名稱,正如核心系統可以 產生這些名字的垃圾列。 在改寫過程中調用該函數,而不是規劃器,因此該可用信息不同于可用的規劃程序。 當`target_rte`和 `target_relation`描述目標外表時,`parsetree`是`UPDATE`或者 `DELETE`命令的解析樹。 如果`AddForeignUpdateTargets`指針被設置為`NULL`, 那么沒有額外目標表達式被添加。 (這將不可能實現`DELETE`操作,盡管`UPDATE`可能仍然是可行的, 如果FDW依賴于一個標識行的未改變主鍵)。 ``` List * PlanForeignModify (PlannerInfo *root, ModifyTable *plan, Index resultRelation, int subplan_index); ``` 執行任何額外規劃操作需要插入,更新或者刪除外表。 該函數產生附屬于執行更新操作的`ModifyTable`規劃節點 的FDW-私有信息。這個私有信息必須有`List`形式,并且 在執行階段將轉交給`BeginForeignModify`。 `root`是關于查詢的規劃器的全局信息。 `plan`是`ModifyTable`規劃節點, 除了`fdwPrivLists`字段外它是完整的。 `resultRelation`通過射程表索引識別目標外表。 `subplan_index`識別從零開始計算的`ModifyTable`規劃節點是哪個目標; 如果你想要索引`plan-&gt;plans`或者其他`plan`節點的子結構,那么使用它。 參閱[Section 52.4](#calibre_link-1502)獲取更多額外信息。 如果`PlanForeignModify`指針被設置為`NULL`, 沒有采取額外規劃時間操作,并且`fdw_private`列表轉交給 `BeginForeignModify`為零。 ``` void BeginForeignModify (ModifyTableState *mtstate, ResultRelInfo *rinfo, List *fdw_private, int subplan_index, int eflags); ``` 開始執行一個外表修改操作。這個程序在執行器啟動時調用。 應該在實際表修改前執行任何初始化。隨后,`ExecForeignInsert`, `ExecForeignUpdate`或者 `ExecForeignDelete`需要每個元組被插入,更新或者刪除。 `mtstate`是被執行的`ModifyTable`規劃節點的整體狀態; 關于規劃的全局數據和執行狀態通過該結構是可用的。 `rinfo`是描述目標外表的`ResultRelInfo`結構。 (`ResultRelInfo`的`ri_FdwState`字段用于FDW存儲任何需要該操作的私有狀態。) 如果任何的,那么`fdw_private`包含通過`PlanForeignModify`產生的私有數據。 `subplan_index`識別`ModifyTable`規劃節點是哪個目標。 `eflags`包含描述這個規劃節點的執行器操作模式的標志位。 注意當`(eflags & EXEC_FLAG_EXPLAIN_ONLY)`為真時, 該函數不應該執行任何外部可見操作; 它應該為`ExplainForeignModify`和 `EndForeignModify`執行最小需求使得節點狀態有效。 如果`BeginForeignModify`指針被設置為`NULL`, 那么在執行器啟動期間不采取任何操作。 ``` TupleTableSlot * ExecForeignInsert (EState *estate, ResultRelInfo *rinfo, TupleTableSlot *slot, TupleTableSlot *planSlot); ``` 插入一個元組到外表。`estate`是查詢的全局執行狀態。 `rinfo`是描述目標外表的`ResultRelInfo`結構。 `slot`包含要插入的元組;它將匹配外表rowtype定義。 `planSlot`包含通過`ModifyTable`規劃節點的子計劃產生的元組; 它不同于可能包含額外"junk"列的`slot`。 返回值要么是包含實際插入的數據的槽(這可能與提供的數據不同,比如作為觸發器操作結果), 如果沒有行實際被插入,那么返回NULL(再次,通常作為觸發器結果)。 傳入的`slot`可以重新用于這個目的。 只有`INSERT`查詢有`RETURNING`子句時, 才使用返回槽中的數據。因此,FDW可能選擇優化返回依賴于`RETURNING`子句內容的一些或者全部列。 然而,必須返回一些插槽表示成功,或者查詢報告的行數是錯誤的。 如果`ExecForeignInsert`指針被設置為`NULL`, 嘗試插入外表將帶有錯誤信息而失敗。 ``` TupleTableSlot * ExecForeignUpdate (EState *estate, ResultRelInfo *rinfo, TupleTableSlot *slot, TupleTableSlot *planSlot); ``` 更新外表上的元組。 `estate`是查詢的全局執行狀態。`rinfo`是描述目標外表的 `ResultRelInfo`結構。`slot`包含元組的新數據; 它將匹配外表rowtype定義。 `planSlot`包含通過`ModifyTable`規劃節點的子計劃產生的元組; 它不同于可能包含額外"junk"列的`slot`。 尤其是,通過`AddForeignUpdateTargets`請求的任何垃圾列將從該槽中提供。 返回值要么是包含實際更新的行的槽(這可能與提供的數據不同,比如作為觸發器操作結果), 如果沒有行實際被更新,那么返回NULL(再次,通常作為觸發器結果)。 傳入的`slot`可以重新用于這個目的。 只有`UPDATE`查詢有`RETURNING`子句時, 才使用返回槽中的數據。因此,FDW可能選擇優化返回依賴于`RETURNING`子句內容的一些或者全部列。 然而,必須返回一些插槽表示成功,或者查詢報告的行數是錯誤的。 如果`ExecForeignUpdate`指針被設置為`NULL`, 嘗試更新外表將帶有錯誤信息而失敗。 ``` TupleTableSlot * ExecForeignDelete (EState *estate, ResultRelInfo *rinfo, TupleTableSlot *slot, TupleTableSlot *planSlot); ``` 刪除外表上的元組。 `estate`是查詢的全局執行狀態。`rinfo`是描述目標外表的 `ResultRelInfo`結構。`slot`不包含任何有用調用, 但是可以用于保留返回的元組。 `planSlot`包含通過`ModifyTable`規劃節點的子計劃產生的元組; 尤其是,它將具有通過`AddForeignUpdateTargets`請求的任何垃圾列。 垃圾列必須用于標識要刪除的元組。 返回值要么是包含實際被刪除行的槽, 如果沒有行實際被刪除,那么返回NULL(再次,通常作為觸發器結果)。 傳入的`slot`可以用于保留返回的元組。 只有`DELETE`查詢有`RETURNING`子句時, 才使用返回槽中的數據。因此,FDW可能選擇優化返回依賴于`RETURNING`子句內容的一些或者全部列。 然而,必須返回一些插槽表示成功,或者查詢報告的行數是錯誤的。 如果`ExecForeignDelete`指針被設置為`NULL`, 嘗試刪除外表將帶有錯誤信息而失敗。 ``` void EndForeignModify (EState *estate, ResultRelInfo *rinfo); ``` 結束表更新并且釋放資源。釋放palloc內存往往不重要,但是比如打開文件并且鏈接遠程服務器應該 被清理干凈。 如果`EndForeignModify`指針被設置為`NULL`, 那么在執行器關閉期間不采取任何操作。 ``` int IsForeignRelUpdatable (Relation rel); ``` 報告指定外表支持的更新操作。返回值應該是規則事件數的位掩碼,標志著 使用`CmdType`枚舉通過外表支持的操作;即`(1 &lt;&lt; CMD_UPDATE) = 4`為`UPDATE`, `(1 &lt;&lt; CMD_INSERT) = 8`為`INSERT`并且 `(1 &lt;&lt; CMD_DELETE) = 16`為`DELETE`。 如果`IsForeignRelUpdatable`指針被設置為`NULL`,那么FDW分別 提供`ExecForeignInsert`, `ExecForeignUpdate`或者`ExecForeignDelete`,那么 外表被認為是可插入,可更新或者可刪除的。 如果FDW支持一些可更新的和一些不可更新的表,那么需要這個函數。 (即使這樣,它允許在執行程序中拋出錯誤而不是在這個函數中進行檢查。然而,該函數 用于在`information_schema`視圖中顯示可更新。) ## 52.2.3\. `EXPLAIN`的FDW程序 ``` void ExplainForeignScan (ForeignScanState *node, ExplainState *es); ``` 為外表掃描打印額外`EXPLAIN`輸出。 該函數可以調用`ExplainPropertyText`和相關函數添加到`EXPLAIN`輸出字段。 `es`中的標志位可以用于決定打印什么,并且檢查`ForeignScanState`節點狀態 用來在`EXPLAIN ANALYZE`情況下提供運行時統計。 如果`ExplainForeignScan`指針被設置為`NULL`,那么 在`EXPLAIN`期間不打印額外信息。 ``` void ExplainForeignModify (ModifyTableState *mtstate, ResultRelInfo *rinfo, List *fdw_private, int subplan_index, struct ExplainState *es); ``` 為外表更新打印額外`EXPLAIN`輸出。 該函數可以調用`ExplainPropertyText`和相關函數添加到`EXPLAIN`輸出字段。 `es`中的標志位可以用于決定打印什么,并且檢查`ModifyTableState`節點狀態 用來在`EXPLAIN ANALYZE`情況下提供運行時統計。前四個參數為`BeginForeignModify` 是相同的。 如果`ExplainForeignModify`指針被設置為`NULL`,那么 在`EXPLAIN`期間不打印任何額外信息。 ## 52.2.4\. `ANALYZE`的FDW程序 ``` bool AnalyzeForeignTable (Relation relation, AcquireSampleRowsFunc *func, BlockNumber *totalpages); ``` 當在外表上執行[ANALYZE](#calibre_link-589)時,調用該函數。 如果FDW可以收集外表的統計,它應該返回`真`, 并且提供一個指針給函數,該函數從`func`中的表中收集樣本行。 以及`totalpages`的頁中表的估計大小。 否則,返回`false`。 如果FDW不支持任何表的統計,那么`AnalyzeForeignTable`指針可以設置為`NULL`。 如果提供,那么樣本收集函數必須有識別標志 ``` int AcquireSampleRowsFunc (Relation relation, int elevel, HeapTuple *rows, int targrows, double *totalrows, double *totaldeadrows); ``` 應該從表中收集達到`targrows`行的隨機抽樣調查,并且存儲到 調用者提供的`rows`數組。必須返回收集行的真實數。 此外,將表中死的和活行 總數估計存儲到輸出參數`totalrows`和 `totaldeadrows`中。(如果FDW 沒有死行的任何概念,那么設置`totaldeadrows`為零。)
                  <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>

                              哎呀哎呀视频在线观看