DELETE と UPDATE のサポート¶
Presto エンジンは、行レベルの SQL DELETE と UPDATE をサポートするための API を提供します。 DELETE または UPDATE を実装するには、コネクタは次のことを行う必要があります。
コネクタの
ConnectorPageSourceの上にUpdatablePageSourceを重ねますrowId 列ハンドルを取得するための
ConnectorMetadataメソッドを定義しますbeginUpdate()またはbeginDelete()を使用して操作を開始しますfinishUpdate()またはfinishDelete()を使用して操作を完了します
DELETE および UPDATE のデータフロー¶
DELETE と UPDATE は同様のフローを持ちます
各スプリットに対して、コネクタは、Presto エンジンに代わってページを読み取り、基になるデータストアに削除または更新を書き込むために、コネクタの
ConnectorPageSourceの上に重ねられたUpdatablePageSourceインスタンスを作成します。コネクタの
UpdatablePageSource.getNextPage()実装は、基になるConnectorPageSourceから次のページをフェッチし、必要に応じてページを再フォーマットして、Presto エンジンに返します。Presto エンジンは、読み取られたページに対してフィルタリングと射影を実行し、フィルタリングおよび射影された結果のページを生成します。
Presto エンジンは、フィルタリングおよび射影された結果のページを、コネクタの
UpdatablePageSourceのdeleteRows()またはupdateRows()メソッドに渡します。これらのメソッドは、基になるデータストアに削除または更新を永続化します。特定の分割のすべてのページが処理されたら、Presto エンジンは
UpdatablePageSource.finish()を呼び出し、deleteRowsまたはupdateRowsの呼び出しによって処理された行に関するコネクタ固有の情報を表すフラグメントのCollection<Slice>を返します。すべてのスプリットのすべてのページが処理されると、Presto エンジンは
ConnectorMetadata.finishDelete()またはfinishUpdateを呼び出し、すべてのスプリットからのすべてのフラグメントを含むコレクションを渡します。コネクタは、操作を完了するために必要な処理 (たとえば、トランザクションのコミット) を実行します。
rowId 列ハンドル抽象化¶
Presto エンジンとコネクタは、更新または削除される行の ID に同意するために、rowId 列ハンドル抽象化を使用します。 rowId 列ハンドルは、Presto エンジンに対して不透明です。コネクタによっては、rowId 列ハンドル抽象化は複数の物理列を表す場合があります。
DELETE の rowId 列ハンドル¶
Presto エンジンは、コネクタの ConnectorMetadata.getDeleteRowIdColumnHandle() メソッドによって返される、コネクタ固有の rowId 列ハンドルを使用して、削除される行を識別します。その完全なシグネチャは次のとおりです
ColumnHandle getDeleteRowIdColumnHandle(
ConnectorSession session,
ConnectorTableHandle tableHandle)
UPDATE の rowId 列ハンドル¶
Presto エンジンは、コネクタの ConnectorMetadata.getUpdateRowIdColumnHandle() メソッドによって返される、コネクタ固有の rowId 列ハンドルを使用して、更新される行を識別します。行を識別する列に加えて、UPDATE の場合、rowId 列には、コネクタが UPDATE 操作を実行するために必要なすべての列が含まれます。
UpdatablePageSource API¶
上記のように、DELETE または UPDATE をサポートするには、コネクタは、コネクタの ConnectorPageSource の上に重ねられた UpdatablePageSource のサブクラスを定義する必要があります。興味深いメソッドは次のとおりです
Page getNextPage()。 Presto エンジンがgetNextPage()を呼び出すと、UpdatablePageSourceは、基になるConnectorPageSource.getNextPage()メソッドを呼び出してページを取得します。一部のコネクタは、Presto エンジンに返す前にページを再フォーマットします。void deleteRows(Block rowIds)。 Presto エンジンは、元のページを提供した同じUpdatablePageSourceインスタンスのdeleteRows()メソッドを呼び出し、ConnectorMetadata.getDeleteRowIdColumnHandle()によって返された列ハンドルに基づいて Presto エンジンによって作成された rowId のブロックを渡しますvoid updateRows(Page page, List<Integer> columnValueAndRowIdChannels)。Prestoエンジンは、元のページを提供したのと同じUpdatablePageSourceインスタンスのupdateRows()メソッドを呼び出し、更新された各カラムとrowIdカラムの投影されたカラムのページを渡します。投影されたカラムの順序はPrestoエンジンによって定義され、その順序はcolumnValueAndRowIdChannels引数に反映されます。updateRows()の役割は、次のとおりです。投影されたページから、更新されたカラムブロックとrowIdブロックを抽出します。
ストレージに必要な順序でそれらを組み立てます。
更新結果を、基盤となるファイルストアに保存します。
CompletableFuture<Collection<Slice>> finish()。Prestoエンジンは、分割のすべてのページが処理されたときにfinish()を呼び出します。コネクタは、処理された行に関するコネクタ固有の情報を示すSliceのコレクションを含むfutureを返します。通常、これには行数が含まれ、作成または変更されたファイルやパーティションなどの情報が含まれる場合があります。
ConnectorMetadata DELETE API¶
DELETEを実装するコネクタは、3つの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()は、finishDelete()および分割生成メカニズムにハンドルが返されるときにコネクタが必要とする追加情報を含むConnectorTableHandleを返します。ほとんどのコネクタの場合、返されるテーブルハンドルには、テーブルハンドルをDELETE操作のテーブルハンドルとして識別するフラグが含まれています。finishDelete():void finishDelete( ConnectorSession session, ConnectorTableHandle tableHandle, Collection<Slice> fragments)DELETE処理中、Prestoエンジンは、UpdatablePageSource.finish()によって返されるSliceコレクションを累積します。すべての分割が処理された後、エンジンはfinishDelete()を呼び出し、テーブルハンドルとSliceフラグメントのコレクションを渡します。これに対し、コネクタはDelete操作を完了するための適切なアクションを実行します。これらのアクションには、コネクタがトランザクションパラダイムをサポートしていると仮定して、トランザクションのコミットが含まれる場合があります。
ConnectorMetadata UPDATE API¶
UPDATEを実装するコネクタは、3つの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は、finishUpdate()および分割生成メカニズムにハンドルが返されるときにコネクタが必要とする追加情報を含むConnectorTableHandleを返します。ほとんどのコネクタの場合、返されるテーブルハンドルには、テーブルハンドルをUPDATE操作のテーブルハンドルとして識別するフラグが含まれています。パーティショニングをサポートする一部のコネクタの場合、テーブルハンドルはそのパーティショニングを反映します。finishUpdate:void finishUpdate( ConnectorSession session, ConnectorTableHandle tableHandle, Collection<Slice> fragments)UPDATE処理中、Prestoエンジンは、UpdatablePageSource.finish()によって返されるSliceコレクションを累積します。すべての分割が処理された後、エンジンはfinishUpdate()を呼び出し、テーブルハンドルとSliceフラグメントのコレクションを渡します。これに対し、コネクタはUPDATE操作を完了するための適切なアクションを実行します。これらのアクションには、コネクタがトランザクションパラダイムをサポートしていると仮定して、トランザクションのコミットが含まれる場合があります。