DELETEUPDATE のサポート

Presto エンジンは、行レベルの SQL DELETEUPDATE をサポートするための API を提供します。 DELETE または UPDATE を実装するには、コネクタは次のことを行う必要があります。

  • コネクタの ConnectorPageSource の上に UpdatablePageSource を重ねます

  • rowId 列ハンドルを取得するための ConnectorMetadata メソッドを定義します

  • beginUpdate() または beginDelete() を使用して操作を開始します

  • finishUpdate() または finishDelete() を使用して操作を完了します

DELETE および UPDATE のデータフロー

DELETEUPDATE は同様のフローを持ちます

  • 各スプリットに対して、コネクタは、Presto エンジンに代わってページを読み取り、基になるデータストアに削除または更新を書き込むために、コネクタの ConnectorPageSource の上に重ねられた UpdatablePageSource インスタンスを作成します。

  • コネクタの UpdatablePageSource.getNextPage() 実装は、基になる ConnectorPageSource から次のページをフェッチし、必要に応じてページを再フォーマットして、Presto エンジンに返します。

  • Presto エンジンは、読み取られたページに対してフィルタリングと射影を実行し、フィルタリングおよび射影された結果のページを生成します。

  • Presto エンジンは、フィルタリングおよび射影された結果のページを、コネクタの UpdatablePageSourcedeleteRows() または 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()メソッドが呼び出され、sessiontableHandleが渡されます。

    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を定義する引数が渡されます。sessiontableHandleに加えて、引数には、テーブルカラム順の更新されたカラムハンドルのリストが含まれます。

    beginUpdate()は、コネクタでUPDATEの処理を開始するために必要なオーケストレーションを実行します。このオーケストレーションは、コネクタによって異なります。

    beginUpdateは、finishUpdate()および分割生成メカニズムにハンドルが返されるときにコネクタが必要とする追加情報を含むConnectorTableHandleを返します。ほとんどのコネクタの場合、返されるテーブルハンドルには、テーブルハンドルをUPDATE操作のテーブルハンドルとして識別するフラグが含まれています。パーティショニングをサポートする一部のコネクタの場合、テーブルハンドルはそのパーティショニングを反映します。

  • finishUpdate:

    void finishUpdate(
        ConnectorSession session,
        ConnectorTableHandle tableHandle,
        Collection<Slice> fragments)
    

    UPDATE処理中、Prestoエンジンは、UpdatablePageSource.finish()によって返されるSliceコレクションを累積します。すべての分割が処理された後、エンジンはfinishUpdate()を呼び出し、テーブルハンドルとSliceフラグメントのコレクションを渡します。これに対し、コネクタはUPDATE操作を完了するための適切なアクションを実行します。これらのアクションには、コネクタがトランザクションパラダイムをサポートしていると仮定して、トランザクションのコミットが含まれる場合があります。