支援 DELETE
和 UPDATE
¶
Presto 引擎提供 API 來支援資料列層級的 SQL DELETE
和 UPDATE
。若要實作 DELETE
或 UPDATE
,連接器必須
在連接器的
ConnectorPageSource
之上,疊加一層UpdatablePageSource
定義
ConnectorMetadata
方法來取得 rowId 資料行控制代碼使用
beginUpdate()
或beginDelete()
開始作業使用
finishUpdate()
或finishDelete()
完成作業
DELETE
和 UPDATE
資料流¶
DELETE
和 UPDATE
有類似的流程
對於每個分割區,連接器會建立一個
UpdatablePageSource
執行個體,該執行個體疊加在連接器的ConnectorPageSource
之上,以代表 Presto 引擎讀取頁面,並將刪除或更新寫入至基礎資料儲存區。連接器的
UpdatablePageSource.getNextPage()
實作會從基礎ConnectorPageSource
擷取下一頁,選擇性地重新格式化頁面,並將其傳回至 Presto 引擎。Presto 引擎會在讀取的頁面上執行篩選和投影,產生篩選和投影結果的頁面。
Presto 引擎會將已篩選和投影的結果頁面傳遞至連接器的
UpdatablePageSource
deleteRows()
或updateRows()
方法。這些方法會將刪除或更新持久儲存在基礎資料儲存區中。當特定分割區的所有頁面都已處理完成時,Presto 引擎會呼叫
UpdatablePageSource.finish()
,此方法會傳回一個Collection<Slice>
,其中包含代表連接器特定資訊的片段,該資訊關於對deleteRows
或updateRows
的呼叫所處理的資料列。當所有分割區的所有頁面都已處理完成時,Presto 引擎會呼叫
ConnectorMetadata.finishDelete()
或finishUpdate
,並傳遞一個包含所有分割區的所有片段的集合。連接器會執行完成作業所需的動作,例如,提交交易。
rowId 資料行控制代碼抽象概念¶
Presto 引擎和連接器會使用 rowId 資料行控制代碼抽象概念來協商要更新或刪除的資料列身分。rowId 資料行控制代碼對於 Presto 引擎是不透明的。根據連接器而定,rowId 資料行控制代碼抽象概念可能代表多個實體資料行。
用於 DELETE
的 rowId 資料行控制代碼¶
Presto 引擎會使用連接器特定的 rowId 資料行控制代碼來識別要刪除的資料列,此控制代碼由連接器的 ConnectorMetadata.getDeleteRowIdColumnHandle()
方法傳回,其完整簽章為
ColumnHandle getDeleteRowIdColumnHandle(
ConnectorSession session,
ConnectorTableHandle tableHandle)
用於 UPDATE
的 rowId 資料行控制代碼¶
Presto 引擎會使用連接器特定的 rowId 資料行控制代碼來識別要更新的資料列,此控制代碼由連接器的 ConnectorMetadata.getUpdateRowIdColumnHandle()
方法傳回。除了識別資料列的資料行之外,對於 UPDATE
,rowId 資料行還會包含連接器執行 UPDATE
作業所需的任何資料行。
UpdatablePageSource API¶
如上所述,為了支援 DELETE
或 UPDATE
,連接器必須定義 UpdatablePageSource
的子類別,此子類別疊加在連接器的 ConnectorPageSource
之上。感興趣的方法有
Page getNextPage()
。當 Presto 引擎呼叫getNextPage()
時,UpdatablePageSource
會呼叫其基礎ConnectorPageSource.getNextPage()
方法來取得頁面。某些連接器會在將頁面傳回至 Presto 引擎之前重新格式化頁面。void deleteRows(Block rowIds)
。Presto 引擎會呼叫提供原始頁面的相同UpdatablePageSource
執行個體的deleteRows()
方法,並傳遞一個 rowId 區塊,該區塊由 Presto 引擎根據ConnectorMetadata.getDeleteRowIdColumnHandle()
傳回的資料行控制代碼建立void updateRows(Page page, List<Integer> columnValueAndRowIdChannels)
。Presto 引擎會呼叫提供原始頁面的相同UpdatablePageSource
執行個體的updateRows()
方法,並傳遞一個投影資料行的頁面,每個更新的資料行各一個,最後一個用於 rowId 資料行。投影資料行的順序由 Presto 引擎定義,並且該順序會反映在columnValueAndRowIdChannels
引數中。updateRows()
的工作是從投影頁面中擷取已更新的資料行區塊和 rowId 區塊。
以連接器儲存所需的任何順序組合它們。
將更新結果儲存在基礎檔案儲存區中。
CompletableFuture<Collection<Slice>> finish()
。當分割區的所有頁面都已處理完成時,Presto 引擎會呼叫finish()
。連接器會傳回一個包含Slice
集合的未來,此集合代表關於已處理資料列的連接器特定資訊。通常,這會包含資料列計數,並可能包含諸如建立或變更的檔案或分割區之類的資訊。
ConnectorMetadata
DELETE
API¶
實作 DELETE
的連接器必須指定三個 ConnectorMetadata
方法。
getDeleteRowIdColumnHandle()
:ColumnHandle getDeleteRowIdColumnHandle( ConnectorSession session, ConnectorTableHandle tableHandle)
此方法傳回的 ColumnHandle 會提供連接器用來識別要刪除的資料列的 rowId 資料行控制代碼,以及連接器完成
DELETE
作業所需的資料列的其他任何欄位。對於 JDBC 連接器,該 rowId 通常是表格的主索引鍵,且不需要其他欄位。對於其他連接器,識別資料列所需資訊通常由多個實體資料行組成。beginDelete()
:ConnectorTableHandle beginDelete( ConnectorSession session, ConnectorTableHandle tableHandle)
在建立
DELETE
執行計畫的最後一個步驟,會呼叫連接器的beginDelete()
方法,並傳遞session
和tableHandle
。beginDelete()
執行連接器中啟動處理DELETE
所需的任何協調。此協調因連接器而異。beginDelete()
會返回一個ConnectorTableHandle
,其中包含當句柄傳遞回finishDelete()
和分割生成機制時,連接器所需的任何額外資訊。對於大多數連接器,返回的資料表句柄包含一個標記,用於將該資料表句柄識別為DELETE
操作的資料表句柄。finishDelete()
:void finishDelete( ConnectorSession session, ConnectorTableHandle tableHandle, Collection<Slice> fragments)
在
DELETE
處理期間,Presto 引擎會累計由UpdatablePageSource.finish()
返回的Slice
集合。在處理完所有分割後,引擎會調用finishDelete()
,傳遞資料表句柄和該Slice
片段的集合。作為回應,連接器會採取適當的行動來完成Delete
操作。這些行動可能包括提交交易,假設連接器支援交易範例。
ConnectorMetadata
UPDATE
API¶
實作 UPDATE
的連接器必須指定三個 ConnectorMetadata
方法。
getUpdateRowIdColumnHandle
:ColumnHandle getUpdateRowIdColumnHandle( ConnectorSession session, ConnectorTableHandle tableHandle, List<ColumnHandle> updatedColumns)
updatedColumns
清單包含資料表中所有被UPDATE
操作更新的欄位的欄位句柄,依照資料表欄位順序排列。此方法返回的 ColumnHandle 提供連接器用於識別要更新的行的 rowId,以及連接器完成
UPDATE
操作所需的行的任何其他欄位。beginUpdate
:ConnectorTableHandle beginUpdate( ConnectorSession session, ConnectorTableHandle tableHandle, List<ColumnHandle> updatedColumns)
作為建立
UPDATE
執行計畫的最後一步,會調用連接器的beginUpdate()
方法,並傳遞定義傳遞到連接器的UPDATE
的引數。除了session
和tableHandle
之外,引數還包括已更新欄位的句柄清單,依照資料表欄位順序排列。beginUpdate()
執行連接器中啟動處理UPDATE
所需的任何協調。此協調因連接器而異。beginUpdate
會返回一個ConnectorTableHandle
,其中包含當句柄傳遞回finishUpdate()
和分割生成機制時,連接器所需的任何額外資訊。對於大多數連接器,返回的資料表句柄包含一個標記,用於將該資料表句柄識別為UPDATE
操作的資料表句柄。對於某些支援分區的連接器,資料表句柄將反映該分區。finishUpdate
:void finishUpdate( ConnectorSession session, ConnectorTableHandle tableHandle, Collection<Slice> fragments)
在
UPDATE
處理期間,Presto 引擎會累計由UpdatablePageSource.finish()
返回的Slice
集合。在處理完所有分割後,引擎會調用finishUpdate()
,傳遞資料表句柄和該Slice
片段的集合。作為回應,連接器會採取適當的行動來完成UPDATE
操作。這些行動可能包括提交交易,假設連接器支援交易範例。