支持 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,该组 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
集合的 future,该集合表示连接器特定信息,这些信息与已处理的行有关。通常,这将包括行计数,并且可能包括诸如已创建或更改的文件或分区之类的信息。
ConnectorMetadata
DELETE
API¶
实现 DELETE
的连接器必须指定三个 ConnectorMetadata
方法。
getDeleteRowIdColumnHandle()
:ColumnHandle getDeleteRowIdColumnHandle( ConnectorSession session, ConnectorTableHandle tableHandle)
此方法返回的 ColumnHandle 提供 rowId 列句柄,连接器使用该句柄来标识待删除的行,以及连接器完成
DELETE
操作所需的任何其他行字段。对于 JDBC 连接器,该 rowId 通常是表的 primary key,不需要其他字段。对于其他连接器,识别行的所需信息通常由多个物理列组成。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
操作。这些操作可能包括提交事务,假设连接器支持事务范式。