叩町

叩町

【Dolt】Dolt内置函数

2025-08-22
【Dolt】Dolt内置函数

信息类函数

​ACTIVE_BRANCH()​

​ACTIVE_BRANCH()​ 函数返回当前会话中正在使用的分支名称。

​DOLT_MERGE_BASE()​

​DOLT_MERGE_BASE()​ 返回两个分支之间的共同祖先的哈希值。

考虑以下分支结构:

      A---B---C feature
     /
D---E---F---G main

以下查询将返回提交 E​ 的哈希值:

​DOLT_HASHOF()​

​DOLT_HASHOF()​ 函数返回某个分支或其他提交规范的提交哈希值。

{% embed url="https://www.dolthub.com/repositories/dolthub/docs_examples/embed/main?q=select+dolt_hashof%28%27main%27%29%3B" %}

​DOLT_HASHOF_TABLE()​

​DOLT_HASHOF_TABLE()​ 函数返回一个表的值哈希。该哈希是表中所有行的哈希值,并且依赖于它们的序列化格式。因此,即使一个表包含相同的行,如果序列化格式发生了变化,其哈希值也可能不同。然而,如果表的哈希值没有变化,则可以保证该表的数据没有发生变化。

此函数可以用于监测数据的变化,通过在应用程序中存储之前的哈希值并将其与当前哈希值进行比较。例如,您可以使用此函数获取名为 color​ 的表的哈希值,如下所示:

mysql> SELECT dolt_hashof_table('color');
+----------------------------------+
| dolt_hashof_table('color')       |
+----------------------------------+
| q8t28sb3h5g2lnhiojacpi7s09p4csjv |
+----------------------------------+
1 row in set (0.01 sec)

​DOLT_HASHOF_DB()​

​DOLT_HASHOF_DB()​ 函数返回整个版本化数据库的哈希值。这个哈希值是数据库中所有表(包括模式和数据)的哈希值,并且包含其他版本化项目,例如存储过程和触发器。该哈希值不包括未版本化的项目,例如被忽略的表。该函数可以接受一个可选参数,用于指定一个分支或以下值之一:'STAGED'、'WORKING' 或 'HEAD'(默认情况下,不传入参数等同于 'WORKING')。

此函数可用于通过在您的应用程序中存储先前的哈希值并与当前哈希值进行比较来监控数据库的变化。例如,您可以使用此函数获取整个数据库的哈希值,如下所示:

mysql> SELECT dolt_hashof_db();
+----------------------------------+
| dolt_hashof_db()                 |
+----------------------------------+
| 1q8t28sb3h5g2lnhiojacpi7s09p4csj |
+----------------------------------+

需要注意的是,如果您连接到分支 'main' 并调用 dolt_hashof_db('feature')​,则可能会得到与连接到分支 'feature' 并调用 dolt_hashof_db()​ 不同的哈希值。这种情况发生在分支 'feature' 的工作集存在尚未提交的更改时。在分支 'main' 上调用 dolt_hashof_db('feature')​ 等同于在分支 'feature' 上调用 dolt_hashof_db('HEAD')​。

一般建议,当需要检测数据库的变化时,先连接到您需要使用的分支,然后调用不带参数的 dolt_hashof_db()​。任何哈希值的变化都意味着数据库发生了更改。

​DOLT_VERSION()​

​DOLT_VERSION()​ 函数返回 Dolt 二进制文件的版本字符串。

mysql> select dolt_version();
+----------------+
| dolt_version() |
+----------------+
| 0.40.4         |
+----------------+

​HAS_ANCESTOR()​

​HAS_ANCESTOR(target, ancestor)​ 函数返回一个 boolean​ 值,用于指示候选的 ancestor​ 提交是否存在于 target​ 引用的提交图中。

请参考上面的示例提交图:

      A---B---C feature
     /
D---E---F---G main

一个将字母替换为提交哈希值的假设示例如下:

select has_ancestor('feature', 'A'); -- true
select has_ancestor('feature', 'E'); -- true
select has_ancestor('feature', 'F'); -- false
select has_ancestor('main', 'E');    -- true
select has_ancestor('G', 'main');    -- true

​LAST_INSERT_UUID()​

​last_insert_uuid()​ 函数返回当前会话中最后执行语句插入的第一行的 UUID。这是 MySQL 的 LAST_INSERT_ID()​ 函数的 UUID 对应版本。我们建议在主键中使用 UUID 而不是 auto_increment 值,因为它在支持分布式数据库克隆的值合并方面表现更好。

​last_insert_id()​ 通过检测列上是否存在 auto_increment​ 修饰符来确定返回哪个自动生成的键值,而 last_insert_uuid()​ 则依赖于列的特定定义。为了让 last_insert_uuid()​ 获取插入的 UUID 值,列 必须 是表主键的一部分,并且 必须 满足以下类型定义之一:

  • ​VARCHAR(36)​ 或 CHAR(36)​,且默认值表达式为 (UUID())​

  • ​VARBINARY(16)​ 或 BINARY(16)​,且默认值表达式为 (UUID_TO_BIN(UUID()))​

当列被定义为 VARBINARY​ 或 BINARY​ 并在默认值表达式中使用 UUID_TO_BIN()​ 函数时,可以选择性地指定 UUID_TO_BIN​ 的 swap_flag

以下代码展示了如何创建符合上述要求的表,并演示如何使用 last_insert_uuid()​:

> create table t (pk binary(16) primary key default (UUID_to_bin(UUID())), c1 varchar(100));

> insert into t (c1) values ("one"), ("two");
Query OK, 2 rows affected (0.00 sec)

> select last_insert_uuid();
+--------------------------------------+
| last_insert_uuid()                   |
+--------------------------------------+
| 6cd58555-bb3f-45d8-9302-d32d94d8e28a |
+--------------------------------------+

> select c1 from t where pk = uuid_to_bin(last_insert_uuid());
+-----+
| c1  |
+-----+
| one |
+-----+

表函数

表函数的操作类似于常规的SQL函数,但它们返回的不是单一的标量值,而是像表一样返回多行数据。Dolt的表函数在查询中使用时有一些限制。例如,目前无法为表函数设置别名,也不能将表函数与其他表或表函数进行联接。

​DOLT_DIFF()​

​DOLT_DIFF()​ 表函数用于计算数据库中任意两个提交点之间的表数据差异。
结果集中的每一行描述了底层表中某一行在两个提交点之间的变化,包括该行在起始提交点和目标提交点的值以及变化类型(即 added​、modified​ 或 removed​)。
DOLT_DIFF()​ 是 dolt_commit_diff_$tablename​ 系统表的替代方案。
在可能的情况下,通常应优先使用系统表,因为它们的使用限制较少。然而,对于某些用例,例如查看包含模式更改的表数据差异或查看三点差异,使用 DOLT_DIFF​ 表函数可能更为直观。

​DOLT_DIFF()​ 表函数与 dolt_commit_diff_$tablename​ 系统表的主要区别在于返回结果的模式。
dolt_commit_diff_$tablename​ 根据当前检出的分支上的表模式生成结果模式,而 DOLT_DIFF()​ 会使用 from_commit​ 的模式生成 from_​ 列,并使用 to_commit​ 的模式生成 to_​ 列。
这使得在底层表模式发生更改的情况下,更容易查看差异。

请注意,DOLT_DIFF()​ 表函数目前要求参数值必须是字面值。

参数选项

DOLT_DIFF(<from_revision>, <to_revision>, <tablename>)
DOLT_DIFF(<from_revision..to_revision>, <tablename>)
DOLT_DIFF(<from_revision...to_revision>, <tablename>)

​DOLT_DIFF()​ 表函数接受两个或三个必需参数:

  • ​from_revision​ — 差异起始点的表数据修订版本。这可以是提交、标签、分支名称或其他修订标识符(例如 "main~")。

  • ​to_revision​ — 差异终止点的表数据修订版本。这可以是提交、标签、分支名称或其他修订标识符(例如 "main~")。

  • ​from_revision..to_revision​ — 获取两个点差异,即 from_revision​ 和 to_revision​ 之间的表数据修订差异。这等价于 dolt_diff(<from_revision>, <to_revision>, <tablename>)​。

  • ​from_revision...to_revision​ — 获取三点差异,即从最后一个共同提交点开始的 from_revision​ 和 to_revision​ 之间的表数据修订差异。

  • ​tablename​ — 包含需要比较数据的表名称。

模式

+------------------+----------+
| field            | type     |
+------------------+----------+
| from_commit      | TEXT     |
| from_commit_date | DATETIME |
| to_commit        | TEXT     |
| to_commit_date   | DATETIME |
| diff_type        | TEXT     |
| other cols       |          |
+------------------+----------+

其余列取决于用户表在 from_commit​ 和 to_commit​ 时的模式。
对于 from_commit​ 修订版本中表的每一列 X​,结果集中会有一个名为 from_X​ 的列。同样,对于 to_commit​ 修订版本中表的每一列 Y​,结果集中会有一个名为 to_Y​ 的列。
这是 DOLT_DIFF()​ 表函数与 dolt_commit_diff_$tablename​ 系统表的主要区别——DOLT_DIFF()​ 使用 to_commit​ 和 from_commit​ 修订版本的两个模式来形成结果集中的 to_​ 和 from_​ 列,而 dolt_commit_diff_$tablename​ 仅使用当前检出分支的表模式来形成结果集中的 to_​ 和 from_​ 列。

示例

假设数据库中有一个名为 inventory​ 的表,并且有两个分支:main​ 和 feature_branch​。我们可以使用 DOLT_DIFF()​ 函数计算从 main​ 分支到 feature_branch​ 分支的表数据差异,以查看功能分支上的数据更改。

以下是 main​ 分支顶端的 inventory​ 表模式:

+----------+------+
| field    | type |
+----------+------+
| pk       | int  |
| name     | text |
| quantity | int  |
+----------+------+

以下是 feature_branch​ 分支顶端的 inventory​ 表模式:

+----------+------+
| field    | type |
+----------+------+
| pk       | int  |
| name     | text |
| color    | text |
| size     | int  |
+----------+------+

基于上述两个版本的模式,DOLT_DIFF()​ 的结果模式将为:

+------------------+----------+
| field            | type     |
+------------------+----------+
| from_pk          | int      |
| from_name        | text     |
| from_quantity    | int      |
| from_commit      | TEXT     |
| from_commit_date | DATETIME |
| to_pk            | int      |
| to_name          | text     |
| to_color         | text     |
| to_size          | int      |
| to_commit        | TEXT     |
| to_commit_date   | DATETIME |
| diff_type        | text     |
+------------------+----------+

要计算差异并查看结果,我们可以运行以下查询:

SELECT * FROM DOLT_DIFF("main", "feature_branch", "inventory")

​DOLT_DIFF()​ 的结果显示了从 main​ 到 feature_branch​ 的数据更改:

+---------+-------+---------+----------+----------------+-----------------------------------+-----------+---------+---------------+-------------+-----------------------------------+-----------+
| to_name | to_pk | to_size | to_color | to_commit      | to_commit_date                    | from_name | from_pk | from_quantity | from_commit | from_commit_date                  | diff_type |
+---------+-------+---------+----------+----------------+-----------------------------------+-----------+---------+---------------+-------------+-----------------------------------+-----------+
| shirt   | 1     | 15      | false    | feature_branch | 2022-03-23 18:57:38.476 +0000 UTC | shirt     | 1       | 70            | main        | 2022-03-23 18:51:48.333 +0000 UTC | modified  |
| shoes   | 2     | 9       | brown    | feature_branch | 2022-03-23 18:57:38.476 +0000 UTC | shoes     | 2       | 200           | main        | 2022-03-23 18:51:48.333 +0000 UTC | modified  |
| pants   | 3     | 30      | blue     | feature_branch | 2022-03-23 18:57:38.476 +0000 UTC | pants     | 3       | 150           | main        | 2022-03-23 18:51:48.333 +0000 UTC | modified  |
| hat     | 4     | 6       | grey     | feature_branch | 2022-03-23 18:57:38.476 +0000 UTC | NULL      | NULL    | NULL          | main        | 2022-03-23 18:51:48.333 +0000 UTC | added     |
+---------+-------+---------+----------+----------------+-----------------------------------+-----------+---------+---------------+-------------+-----------------------------------+-----------+

三点差异 DOLT_DIFF​

假设上述数据库的提交图如下所示:

A - B - C - D (main)
         \
          E - F (feature_branch)

上例获取了两个点差异,即 main​ 和 feature_branch​ 两个修订版本之间的差异。
dolt_diff('main', 'feature_branch', 'inventory')​(等价于 dolt_diff('main..feature_branch', 'inventory')​)输出从 F 到 D 的差异(即包含 E 和 F 的影响)。

三点差异用于显示功能分支从主分支*分叉点*开始引入的差异。三点差异通常用于显示拉取请求的差异。

因此,dolt_diff('main...feature_branch')​ 仅输出 feature_branch​ 中的差异(即 E 和 F)。

了解更多关于两点与三点差异的内容,请参考此处

​DOLT_DIFF_STAT()​

*之前称为* dolt_diff_summary()​

​DOLT_DIFF_STAT()​ 表函数用于计算数据库中任意两个提交之间的数据差异统计。对于诸如创建没有行的新表或删除没有行的表等模式更改,将返回空结果。结果集中的每一行描述了单个表的差异统计,包括未修改、添加、删除和修改的行数,添加、删除和修改的单元格数,以及每次提交中表的总行数和单元格数。

​DOLT_DIFF_STAT()​ 的功能类似于 CLIdolt diff --stat 命令,但使用 DOLT_DIFF_STAT()​ 表函数需要提供两个提交,并且表名是可选的。对于无主键表,此表函数仅提供添加和删除的行数。对于没有数据更改的表,将返回空结果。

请注意,DOLT_DIFF_STAT()​ 表函数目前要求参数值必须是字面值。

权限

如果未定义表名,DOLT_DIFF_STAT()​ 表函数需要对所有表具有 SELECT​ 权限;如果定义了表名,则仅需要对该表具有 SELECT​ 权限。

选项

DOLT_DIFF_STAT(<from_revision>, <to_revision>, <optional_tablename>)
DOLT_DIFF_STAT(<from_revision..to_revision>, <optional_tablename>)
DOLT_DIFF_STAT(<from_revision...to_revision>, <optional_tablename>)

​DOLT_DIFF_STAT()​ 表函数接受三个参数:

  • ​from_revision​ — 差异起点表数据的版本。此参数是必需的,可以是提交、标签、分支名称或其他版本指定符(例如 "main~"、"WORKING"、"STAGED")。

  • ​to_revision​ — 差异终点表数据的版本。此参数是必需的,可以是提交、标签、分支名称或其他版本指定符(例如 "main~"、"WORKING"、"STAGED")。

  • ​from_revision..to_revision​ — 获取两点差异统计,或 from_revision​ 和 to_revision​ 之间表数据的版本。这等同于 dolt_diff_stat(<from_revision>, <to_revision>, <tablename>)​。

  • ​from_revision...to_revision​ — 获取三点差异统计,或 from_revision​ 和 to_revision​ 之间表数据的版本,*从最后一个共同提交开始*。

  • ​tablename​ — 包含要比较数据的表的名称。此参数是可选的。如果未定义,将返回所有有数据差异的表。

模式

+-----------------+--------+
| field           | type   |
+-----------------+--------+
| table_name      | TEXT   |
| rows_unmodified | BIGINT |
| rows_added      | BIGINT |
| rows_deleted    | BIGINT |
| rows_modified   | BIGINT |
| cells_added     | BIGINT |
| cells_deleted   | BIGINT |
| cells_modified  | BIGINT |
| old_row_count   | BIGINT |
| new_row_count   | BIGINT |
| old_cell_count  | BIGINT |
| new_cell_count  | BIGINT |
+-----------------+--------+

示例

假设我们从 main​ 分支的数据库中的表 inventory​ 开始。当我们进行任何更改时,可以使用 DOLT_DIFF_STAT()​ 函数计算特定提交之间的表数据差异或所有有数据更改的表的差异。

以下是 main​ 分支顶端的 inventory​ 表的模式:

+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| pk       | int         | NO   | PRI | NULL    |       |
| name     | varchar(50) | YES  |     | NULL    |       |
| quantity | int         | YES  |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+

以下是 main​ 分支顶端的 inventory​ 表的数据:

+----+-------+----------+
| pk | name  | quantity |
+----+-------+----------+
| 1  | shirt | 15       |
| 2  | shoes | 10       |
+----+-------+----------+

我们对 inventory​ 表进行了一些更改,并创建了一个新的无主键表:

ALTER TABLE inventory ADD COLUMN color VARCHAR(10);
INSERT INTO inventory VALUES (3, 'hat', 6, 'red');
UPDATE inventory SET quantity=0 WHERE pk=1;
CREATE TABLE items (name varchar(50));
INSERT INTO items VALUES ('shirt'),('pants');

以下是当前工作集中的 inventory​ 表:

+----+-------+----------+-------+
| pk | name  | quantity | color |
+----+-------+----------+-------+
| 1  | shirt | 0        | NULL  |
| 2  | shoes | 10       | NULL  |
| 3  | hat   | 6        | red   |
+----+-------+----------+-------+

为了计算差异并查看结果,我们运行以下查询:

SELECT * FROM DOLT_DIFF_STAT('main', 'WORKING');

​DOLT_DIFF_STAT()​ 的结果显示了从 main​ 顶端到当前工作集的数据更改情况:

+------------+-----------------+------------+--------------+---------------+-------------+---------------+----------------+---------------+---------------+----------------+----------------+
| table_name | rows_unmodified | rows_added | rows_deleted | rows_modified | cells_added | cells_deleted | cells_modified | old_row_count | new_row_count | old_cell_count | new_cell_count |
+------------+-----------------+------------+--------------+---------------+-------------+---------------+----------------+---------------+---------------+----------------+----------------+
| inventory  | 1               | 1          | 0            | 1             | 6           | 0             | 1              | 2             | 3             | 6              | 12             |
| items      | NULL            | 2          | 0            | NULL          | NULL        | NULL          | NULL           | NULL          | NULL          | NULL           | NULL           |
+------------+-----------------+------------+--------------+---------------+-------------+---------------+----------------+---------------+---------------+----------------+----------------+

为了获取从当前工作集到 main​ 顶端的特定表的更改,我们运行以下查询:

SELECT * FROM DOLT_DIFF_STAT('WORKING', 'main', 'inventory');

结果为单行:

+------------+-----------------+------------+--------------+---------------+-------------+---------------+----------------+---------------+---------------+----------------+----------------+
| table_name | rows_unmodified | rows_added | rows_deleted | rows_modified | cells_added | cells_deleted | cells_modified | old_row_count | new_row_count | old_cell_count | new_cell_count |
+------------+-----------------+------------+--------------+---------------+-------------+---------------+----------------+---------------+---------------+----------------+----------------+
| inventory  | 1               | 0          | 1            | 1             | 0           | 6             | 1              | 3             | 2             | 12             | 6              |
+------------+-----------------+------------+--------------+---------------+-------------+---------------+----------------+---------------+---------------+----------------+----------------+

​DOLT_DIFF_SUMMARY()​

之前版本的dolt_diff_summary​*已重命名为*dolt_diff_stat​*。*

​DOLT_DIFF_SUMMARY()​ 表函数用于总结在数据库中任意两个提交之间发生变化的表及其变化方式。结果中只会列出发生变化的表,并显示差异类型(“新增”、“删除”、“修改”、“重命名”)以及是否存在数据和模式的变化。

​DOLT_DIFF_SUMMARY()​ 的功能类似于 CLIdolt diff --summary命令,但使用 DOLT_DIFF_SUMMARY()​ 表函数时需要指定两个提交,表名则为可选项。如果没有任何表发生变化,将返回空结果。

请注意,DOLT_DIFF()​ 表函数当前要求参数值必须是字面值。

权限

如果未定义表名,DOLT_DIFF_SUMMARY()​ 表函数需要对所有表具有 SELECT​ 权限;如果定义了表名,则仅需对该表具有 SELECT​ 权限。

使用方法

DOLT_DIFF_SUMMARY(<from_revision>, <to_revision>, <optional_tablename>)
DOLT_DIFF_SUMMARY(<from_revision..to_revision>, <optional_tablename>)
DOLT_DIFF_SUMMARY(<from_revision...to_revision>, <optional_tablename>)

​DOLT_DIFF_SUMMARY()​ 表函数接受三个参数:

  • ​from_revision​ — 差异开始的表数据修订版本。此参数为必填项,可以是提交、标签、分支名或其他修订版本说明符(例如 "main~","WORKING","STAGED")。

  • ​to_revision​ — 差异结束的表数据修订版本。此参数为必填项,可以是提交、标签、分支名或其他修订版本说明符(例如 "main~","WORKING","STAGED")。

  • ​from_revision..to_revision​ — 获取两个点的差异摘要,即 from_revision​ 和 to_revision​ 之间的表数据修订版本。这等同于 dolt_diff_summary(<from_revision>, <to_revision>, <tablename>)​。

  • ​from_revision...to_revision​ — 获取三个点的差异摘要,即 from_revision​ 和 to_revision​ 之间的表数据修订版本,*从最后一个共同提交开始*。

  • ​tablename​ — 需要比较数据差异的表名。此参数为可选项。如果未定义,将返回所有有数据差异的表。

数据结构

+-----------------+---------+
| 字段            | 类型    |
+-----------------+---------+
| from_table_name | TEXT    |
| to_table_name   | TEXT    |
| diff_type       | TEXT    |
| data_change     | BOOLEAN |
| schema_change   | BOOLEAN |
+-----------------+---------+

示例

假设我们从 main​ 分支的数据库中有一个名为 inventory​ 的表开始。当我们进行任何更改时,可以使用 DOLT_DIFF_SUMMARY()​ 函数计算表数据的差异,或者查看特定提交之间所有发生数据变化的表。

以下是 main​ 分支末端 inventory​ 表的结构:

+----------+-------------+------+-----+---------+-------+
| 字段     | 类型        | 空值 | 键  | 默认值  | 额外  |
+----------+-------------+------+-----+---------+-------+
| pk       | int         | NO   | PRI | NULL    |       |
| name     | varchar(50) | YES  |     | NULL    |       |
| quantity | int         | YES  |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+

以下是 main​ 分支末端 inventory​ 表的数据:

+----+-------+----------+
| pk | name  | quantity |
+----+-------+----------+
| 1  | shirt | 15       |
| 2  | shoes | 10       |
+----+-------+----------+

我们对 inventory​ 表进行了一些更改,并创建了一个新的无主键表:

ALTER TABLE inventory ADD COLUMN color VARCHAR(10);
INSERT INTO inventory VALUES (3, 'hat', 6, 'red');
UPDATE inventory SET quantity=0 WHERE pk=1;
CREATE TABLE items (name varchar(50));

以下是当前工作集中的 inventory​ 表数据:

+----+-------+----------+-------+
| pk | name  | quantity | color |
+----+-------+----------+-------+
| 1  | shirt | 0        | NULL  |
| 2  | shoes | 10       | NULL  |
| 3  | hat   | 6        | red   |
+----+-------+----------+-------+

要计算差异并查看结果,我们运行以下查询:

SELECT * FROM DOLT_DIFF_SUMMARY('main', 'WORKING');

​DOLT_DIFF_SUMMARY()​ 的结果显示了从 main​ 分支末端到当前工作集中数据的变化:

+-----------------+---------------+-----------+-------------+---------------+
| from_table_name | to_table_name | diff_type | data_change | schema_change |
+-----------------+---------------+-----------+-------------+---------------+
| inventory       | inventory     | modified  | true        | true          |
| items           | items         | added     | false       | true          |
+-----------------+---------------+-----------+-------------+---------------+

要查看从当前工作集到 main​ 分支末端特定表的变化,我们运行以下查询:

SELECT * FROM DOLT_DIFF_SUMMARY('WORKING', 'main', 'inventory');

结果仅包含一行:

+-----------------+---------------+-----------+-------------+---------------+
| from_table_name | to_table_name | diff_type | data_change | schema_change |
+-----------------+---------------+-----------+-------------+---------------+
| inventory       | inventory     | modified  | true        | true          |
+-----------------+---------------+-----------+-------------+---------------+

​DOLT_LOG()​

​DOLT_LOG​ 表函数用于获取从指定修订版的 HEAD​(如果未提供修订版,则为当前 HEAD​)可到达的所有提交的提交日志。DOLT_LOG()​ 的工作方式类似于 CLIdolt log命令

请注意,DOLT_LOG()​ 表函数目前要求参数值必须是文字值。

权限

​DOLT_LOG()​ 表函数需要对所有表具有 SELECT​ 权限。

选项

DOLT_LOG([<optional_revisions>...], [--tables <tables>...])

​DOLT_LOG()​ 表函数接受任意数量的可选修订参数:

  • ​optional_revision​:分支名称、标签或提交引用(可以带或不带祖先规范),用于指定要包含在结果中的祖先提交。如果未指定修订,则默认为当前分支的 HEAD​。

    • 如果您想获取 双点日志(所有由 revision2​ 可到达但 revision1​ 不可到达的提交),可以在修订之间使用 ..​(DOLT_LOG('revision1..revision2')​)或在要排除的修订前使用 ^​(DOLT_LOG('revision2', '^revision1')​)。注意:如果提供两个修订,其中一个必须包含 ^​。

    • 如果您想获取 三点日志(所有由 revision1​ 或 revision2​ 可到达的提交,但排除同时由 revision1​ 和 revision2​ 可到达的提交),可以在修订之间使用 ...​(DOLT_LOG('revision1...revision2')​)。

  • ​--min-parents​:提交必须具有的最少父提交数量,才能包含在日志中。

  • ​--merges​:等价于 min-parents == 2​,将日志限制为具有两个或更多父提交的提交。

  • ​--parents​:显示日志中每个提交的所有父提交。

  • ​--decorate​:在提交旁显示引用。有效选项为 short、full、no 和 auto。注意:CLI 中的 dolt log​ 命令默认值为 "short",而此表函数默认值为 "no"。

  • ​--not​:排除由修订可到达的提交。

  • ​--tables​:将日志限制为影响指定表的提交。可以指定任意数量的以逗号分隔的表。

数据结构

+-------------+----------+
| field       | type     |
+-------------+--------- +
| commit_hash | text     |
| committer   | text     |
| email       | text     |
| date        | datetime |
| message     | text     |
| parents     | text     | -- 除非提供 `--parents` 标志,否则此列隐藏
| refs        | text     | -- 除非 `--decorate` 为 "short" 或 "full",否则此列隐藏
+-------------+--------- +

示例

假设我们有以下提交图:

A - B - C - D (main)
         \
          E - F (feature)

要获取 main​ 分支的提交日志,可以使用以下查询:

SELECT * FROM DOLT_LOG('main');

它将以时间倒序返回提交 - D​、C​、B​ 和 A​。输出可能类似于:

+----------------------------------+-----------+--------------------+-----------------------------------+---------------+
| commit_hash                      | committer | email              | date                              | message       |
+----------------------------------+-----------+--------------------+-----------------------------------+---------------+
| qi331vjgoavqpi5am334cji1gmhlkdv5 | bheni     | brian@dolthub.com | 2019-06-07 00:22:24.856 +0000 UTC | update rating  |
| 137qgvrsve1u458briekqar5f7iiqq2j | bheni     | brian@dolthub.com | 2019-04-04 22:43:00.197 +0000 UTC | change rating  |
| rqpd7ga1nic3jmc54h44qa05i8124vsp | bheni     | brian@dolthub.com | 2019-04-04 21:07:36.536 +0000 UTC | fixes          |
| qfk3bpan8mtrl05n8nihh2e3t68t3hrk | bheni     | brian@dolthub.com | 2019-04-04 21:01:16.649 +0000 UTC | test           |
+----------------------------------+-----------+--------------------+-----------------------------------+---------------+

要获取 feature​ 分支的提交日志,可以在上述查询中更改修订:

SELECT * FROM DOLT_LOG('feature');

它将返回从 feature​ 的 HEAD​ 可到达的所有提交 - F​、E​、C​、B​ 和 A​。

双点和三点日志

我们还支持双点和三点日志。双点日志返回来自一个修订的提交,但排除另一个修订的提交。如果我们想获取 feature​ 中的所有提交,但排除 main​ 中的提交,以下查询都将返回 F​ 和 E​ 提交。

SELECT * FROM DOLT_LOG('main..feature');
SELECT * FROM DOLT_LOG('feature', '^main');
SELECT * FROM DOLT_LOG('feature', '--not', 'main');

三点日志返回在任一修订中的提交,但排除同时在两个修订中的提交。如果我们想获取 main​ 或 feature​ 中的提交,但排除同时在 main​ 和 feature​ 中的提交,此查询将返回 F​、E​ 和 D​。

SELECT * FROM DOLT_LOG('main...feature');

注意:双点日志中修订的顺序很重要,但三点日志中则无关紧要。DOLT_LOG('main..feature')​ 返回 F​ 和 E​,而 DOLT_LOG('feature..main')​ 仅返回 D​。DOLT_LOG('main...feature')​ 和 DOLT_LOG('feature...main')​ 都返回 F​、E​ 和 D​。

了解更多关于双点与三点日志的信息,请访问这里

​DOLT_PATCH()​

生成从起始版本到目标版本修补表(或所有表)所需的SQL语句。这在您希望从外部来源导入数据到Dolt、比较差异并生成修补原始数据源所需的SQL语句时非常有用。此命令等同于dolt diff -r sql CLI命令。如果适用,将返回架构和/或数据差异语句。一些由于架构不兼容更改而无法生成的数据差异将显示为包含发生此问题的表的警告。

语句的顺序是先生成架构修补语句,然后是数据修补语句。如果修补所有表,建议在按照返回的顺序应用这些修补语句之前关闭外键检查(SET foreign_key_checks=0;​),以避免冲突。

获取SQL修补语句目前仅作为表函数提供;未来将支持CLI命令dolt patch​。

权限

​DOLT_PATCH()​表函数需要对所有表(如果未定义表)或仅对定义的表具有SELECT​权限。

选项

DOLT_PATCH(<from_revision>, <to_revision>, <optional_tablename>)
DOLT_PATCH(<from_revision..to_revision>, <optional_tablename>)
DOLT_PATCH(<from_revision...to_revision>, <optional_tablename>)

​DOLT_PATCH()​表函数接受以下参数:

  • ​from_revision​ — 修补起始版本的表数据版本。此参数为必填项。可以是提交、标签、分支名称或其他版本标识符(例如:"main~","WORKING","STAGED")。

  • ​to_revision​ — 修补目标版本的表数据版本。此参数为必填项。可以是提交、标签、分支名称或其他版本标识符(例如:"main~","WORKING","STAGED")。

  • ​from_revision..to_revision​ — 获取两点修补或from_revision​和to_revision​之间的表数据版本。这等同于dolt_patch(<from_revision>, <to_revision>, <tablename>)​。

  • ​from_revision...to_revision​ — 获取三点修补或from_revision​和to_revision​之间的表数据版本,*从最后一个共同提交开始*。

  • ​tablename​ — 包含需要修补的数据和/或架构的表名称。此参数为可选项。如果未定义,将返回所有具有数据和/或架构修补的表。

架构

+------------------+--------+
| 字段             | 类型   |
+------------------+--------+
| statement_order  | BIGINT |
| from_commit_hash | TEXT   |
| to_commit_hash   | TEXT   |
| table_name       | TEXT   |
| diff_type        | TEXT   |
| statement        | TEXT   |
+------------------+--------+

示例

假设我们从main​分支的数据库中的表inventory​开始。当我们进行任何更改时,可以使用DOLT_PATCH()​函数获取特定提交之间表数据或所有表数据更改的SQL修补语句。

以下是main​分支顶部的inventory​表架构:

+----------+-------------+------+-----+---------+-------+
| 字段     | 类型        | 空值 | 键  | 默认值  | 额外  |
+----------+-------------+------+-----+---------+-------+
| pk       | int         | NO   | PRI | NULL    |       |
| name     | varchar(50) | YES  |     | NULL    |       |
| quantity | int         | YES  |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+

以下是main​分支顶部inventory​表的数据:

+----+-------+----------+
| pk | name  | quantity |
+----+-------+----------+
| 1  | shirt | 15       |
| 2  | shoes | 10       |
+----+-------+----------+

我们对inventory​表进行了一些更改并创建了一个新的无主键表:

INSERT INTO inventory VALUES (3, 'hat', 6);
UPDATE inventory SET quantity=0 WHERE pk=1;
CREATE TABLE items (name varchar(50));
INSERT INTO items VALUES ('shirt'),('pants');

以下是当前工作集中的inventory​表数据:

+----+-------+----------+
| pk | name  | quantity |
+----+-------+----------+
| 1  | shirt | 0        |
| 2  | shoes | 10       |
| 3  | hat   | 6        |
+----+-------+----------+

要获取SQL修补语句,我们运行以下查询:

SELECT * FROM DOLT_PATCH('main', 'WORKING');

从DOLT_PATCH()​返回的结果显示从main​分支顶部到当前工作集的数据如何更改:

+-----------------+----------------------------------+----------------+------------+-----------+----------------------------------------------------------------------+
| statement_order | from_commit_hash                 | to_commit_hash | table_name | diff_type | statement                                                            |
+-----------------+----------------------------------+----------------+------------+-----------+----------------------------------------------------------------------+
| 1               | gg4kasjl6tgrtoag8tnn1der09sit4co | WORKING        | inventory  | data      | UPDATE `inventory` SET `quantity`=0 WHERE `pk`=1;                    |
| 2               | gg4kasjl6tgrtoag8tnn1der09sit4co | WORKING        | inventory  | data      | INSERT INTO `inventory` (`pk`,`name`,`quantity`) VALUES (3,'hat',6); |
| 3               | gg4kasjl6tgrtoag8tnn1der09sit4co | WORKING        | items      | schema    | CREATE TABLE `items` (                                               |
|                 |                                  |                |            |           |   `name` varchar(50)                                                 |
|                 |                                  |                |            |           | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;    |
| 4               | gg4kasjl6tgrtoag8tnn1der09sit4co | WORKING        | items      | data      | INSERT INTO `items` (`name`) VALUES ('shirt');                       |
| 5               | gg4kasjl6tgrtoag8tnn1der09sit4co | WORKING        | items      | data      | INSERT INTO `items` (`name`) VALUES ('pants');                       |
+-----------------+----------------------------------+----------------+------------+-----------+----------------------------------------------------------------------+

要获取从当前工作集到main​分支顶部的特定表架构修补语句,我们运行以下查询:

SELECT * FROM DOLT_PATCH('WORKING', 'main', 'items') WHERE diff_type = 'schema';

结果为单行:

+-----------------+------------------+----------------------------------+------------+-----------+---------------------+
| statement_order | from_commit_hash | to_commit_hash                   | table_name | diff_type | statement           |
+-----------------+------------------+----------------------------------+------------+-----------+---------------------+
| 1               | WORKING          | gg4kasjl6tgrtoag8tnn1der09sit4co | items      | schema    | DROP TABLE `items`; |
+-----------------+------------------+----------------------------------+------------+-----------+---------------------+

​DOLT_REFLOG()​

​DOLT_REFLOG()​ 表函数显示命名引用(例如分支和标签)的历史记录,这在您希望了解某个分支或标签如何随着时间的推移指向不同的提交时非常有用,特别是当这些信息无法通过 dolt_log​ 系统表或 dolt_log()​ 表函数获取时。例如,如果您使用 dolt_reset()​ 更改了分支指向的提交,您可以使用 dolt_reflog()​ 查看该分支在更改之前指向的提交。另一个常见的使用场景是恢复意外删除的分支或标签。下面的示例部分展示了如何恢复已删除的分支。

Dolt 的 reflog 数据来自 Dolt 的日志块存储。这些数据是 Dolt 数据库的本地数据,不会在推送、拉取或克隆 Dolt 数据库时包含。这意味着当您克隆一个 Dolt 数据库时,除非执行更改分支或标签指向的操作,否则它不会包含任何 reflog 数据。

Dolt 的 reflog 类似于 Git 的 reflog,但有一些不同之处:

  • Dolt 的 reflog 当前仅支持命名引用,例如分支和标签,而不支持 Git 的特殊引用(例如 HEAD​、FETCH-HEAD​、MERGE-HEAD​)。

  • Dolt 的 reflog 即使在引用被删除后也可以查询该引用的日志。在 Git 中,一旦分支或标签被删除,与该引用相关的 reflog 也会被删除。如果想找到分支或标签最后指向的提交,必须使用 Git 的特殊 HEAD​ reflog,这有时会比较复杂。而 Dolt 则更简单,它允许您查看已删除引用的历史记录,从而轻松找到分支或标签被删除前最后指向的提交。

权限

使用 dolt_reflog()​ 表函数不需要特殊权限。

选项

DOLT_REFLOG()
DOLT_REFLOG(['--all'], <ref_name>)

​dolt_reflog()​ 表函数可以不带参数调用,也可以带一个参数调用。如果不带任何参数调用,它将返回完整的引用日志,按最新到最旧列出所有被跟踪的引用的更改。如果带一个参数调用,该参数是要查询的引用名称。这可以是分支名称(例如 "myBranch")、标签名称(例如 "v1.1.4"),或者是完整的引用路径(例如 "refs/heads/myBranch")。ref_name​ 参数对大小写不敏感。

​dolt_reflog()​ 表函数还可以使用 --all​ 标志调用,以显示所有引用,包括隐藏引用,例如 DoltHub 工作区引用。

数据结构

+-----------------------+-----------+
| 字段                 | 类型      |
+-----------------------+-----------+
| ref                   | TEXT      |
| ref_timestamp         | TIMESTAMP |
| commit_hash           | TEXT      |
| commit_message        | TEXT      |
+-----------------------+-----------+

示例

以下示例展示了如何通过在 Dolt 的 reflog 中找到已删除分支最后指向的提交来恢复该分支。

-- 某人错误地删除了错误的分支!
call dolt_branch('-D', 'prodBranch');

-- 在发现删除了错误的分支后,我们在删除该分支的同一 Dolt 数据库实例中查询 Dolt 的 reflog,
-- 查看 prodBranch 分支曾经指向的提交。使用相同的 Dolt 实例很重要,因为 reflog 信息始终是本地的,
-- 不会在推送/拉取数据库时包含。
select * from dolt_reflog('prodBranch');
+-----------------------+---------------------+----------------------------------+-------------------------------+
| ref                   | ref_timestamp       | commit_hash                      | commit_message                |
+-----------------------+---------------------+----------------------------------+-------------------------------+
| refs/heads/prodBranch | 2023-10-25 20:54:37 | v531ptpmv2tquig8v591tsjghtj84ksg | inserting row 42              |
| refs/heads/prodBranch | 2023-10-25 20:53:12 | rvt34lqrbtdr3dhnjchruu73lik4e398 | inserting row 100000          |
| refs/heads/prodBranch | 2023-10-25 20:53:06 | v531ptpmv2tquig8v591tsjghtj84ksg | inserting row 42              |
| refs/heads/prodBranch | 2023-10-25 20:52:43 | ihuj1l7fmqq37sjhtlrgpup5n76gfhju | inserting row 1 into table xy |
+-----------------------+---------------------+----------------------------------+-------------------------------+

-- prodBranch 最后指向的提交是 v531ptpmv2tquig8v591tsjghtj84ksg,因此要恢复分支,
-- 我们只需创建一个同名分支,并使其指向该最后的提交。
call dolt_branch('prodBranch', 'v531ptpmv2tquig8v591tsjghtj84ksg');

​DOLT_SCHEMA_DIFF()​

​DOLT_SCHEMA_DIFF()​ 表函数用于计算数据库中任意两个提交之间的模式差异。结果集中每一行描述了某张表在两个提交之间的更改情况,包括该表在起始和目标提交中的创建语句。

请注意,DOLT_SCHEMA_DIFF()​ 表函数目前要求参数值必须为字面值。

权限要求

​DOLT_SCHEMA_DIFF()​ 表函数需要对所有表具有 SELECT​ 权限(如果未指定具体表名),或者仅对指定的表具有 SELECT​ 权限。

参数选项

DOLT_SCHEMA_DIFF(<from_commit>, <to_commit>, <optional_tablename>)
DOLT_SCHEMA_DIFF(<from_revision..to_revision>, <optional_tablename>)
DOLT_SCHEMA_DIFF(<from_revision...to_revision>, <optional_tablename>)

​DOLT_SCHEMA_DIFF()​ 表函数接受三个参数:

  • ​from_revision​ —— 表数据差异的起始版本。此参数为必填项,可以是提交、标签、分支名或其他版本标识符(例如:"main~"、"WORKING"、"STAGED")。

  • ​to_revision​ —— 表数据差异的目标版本。此参数为必填项,可以是提交、标签、分支名或其他版本标识符(例如:"main~"、"WORKING"、"STAGED")。

  • ​from_revision..to_revision​ —— 获取两个点的差异,或 from_revision​ 和 to_revision​ 之间的表模式变化。这与 dolt_schema_diff(<from_revision>, <to_revision>, [<tablename>])​ 等效。

  • ​from_revision...to_revision​ —— 获取三个点的差异,或 from_revision​ 和 to_revision​ 之间的表模式变化,*从最后一个共同提交开始*。

  • ​tablename​ —— 需要比较的表名。此参数为可选项。如果未指定,将返回所有有模式差异的表。

返回模式

+-----------------------+------+
| 字段                 | 类型 |
+-----------------------+------+
| from_table_name       | TEXT |
| to_table_name         | TEXT |
| from_create_statement | TEXT |
| to_create_statement   | TEXT |
+-----------------------+------+

示例

以下示例中,我们将考虑两个分支 main​ 和 feature_branch​ 中的三张表:

在 main​ 分支中的表为:employees​、inventory​ 和 vacations​。
在 feature_branch​ 分支中的表为:inventory​、photos​ 和 trips​。

为了查看这些表的变化,我们运行以下查询:

SELECT * FROM DOLT_SCHEMA_DIFF("main", "feature_branch")

​DOLT_SCHEMA_DIFF()​ 的结果显示了从 main​ 分支的最新提交到 feature_branch​ 分支的最新提交之间,所有表的模式如何变化:

+-----------------+---------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
| from_table_name | to_table_name | from_create_statement                                             | to_create_statement                                               |
+-----------------+---------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
| employees       |               | CREATE TABLE `employees` (                                        |                                                                   |
|                 |               |   `pk` int NOT NULL,                                              |                                                                   |
|                 |               |   `name` varchar(50),                                             |                                                                   |
|                 |               |   PRIMARY KEY (`pk`)                                              |                                                                   |
|                 |               | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; |                                                                   |
| inventory       | inventory     | CREATE TABLE `inventory` (                                        | CREATE TABLE `inventory` (                                        |
|                 |               |   `pk` int NOT NULL,                                              |   `pk` int NOT NULL,                                              |
|                 |               |   `name` varchar(50),                                             |   `name` varchar(50),                                             |
|                 |               |   `quantity` int,                                                 |   `color` varchar(10),                                            |
|                 |               |   PRIMARY KEY (`pk`)                                              |   PRIMARY KEY (`pk`)                                              |
|                 |               | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; |
|                 | photos        |                                                                   | CREATE TABLE `photos` (                                           |
|                 |               |                                                                   |   `pk` int NOT NULL,                                              |
|                 |               |                                                                   |   `name` varchar(50),                                             |
|                 |               |                                                                   |   `dt` datetime(6),                                               |
|                 |               |                                                                   |   PRIMARY KEY (`pk`)                                              |
|                 |               |                                                                   | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; |
| vacations       | trips         | CREATE TABLE `vacations` (                                        | CREATE TABLE `trips` (                                            |
|                 |               |   `pk` int NOT NULL,                                              |   `pk` int NOT NULL,                                              |
|                 |               |   `name` varchar(50),                                             |   `name` varchar(50),                                             |
|                 |               |   PRIMARY KEY (`pk`)                                              |   PRIMARY KEY (`pk`)                                              |
|                 |               | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; |
+-----------------+---------------+-------------------------------------------------------------------+-------------------------------------------------------------------+

让我们分析返回的数据。

  1. 第一行中,from_table_name​ 和 from_create_statement​ 列有值,而 to_table_name​ 和 to_create_statement​ 列为空。这表明在 main​ 和 feature_branch​ 之间,表 employees​ 被删除了。

  2. 第二行中,from_table_name​ 和 to_table_name​ 的值相同,但 from_create_statement​ 和 to_create_statement​ 不同。这表明该表的模式在 main​ 和 feature_branch​ 之间发生了变化。

  3. 第三行与第一行类似,但其 to_*​ 列有值,而 from_*​ 列为空。这表明在 main​ 和 feature_branch​ 之间,表 photos​ 被添加了。

  4. 最后一行中,from_create_statement​ 和 to_create_statement​ 大部分相同,但 from_table_name​ 和 to_table_name​ 不同。这表明该表在 main​ 和 feature_branch​ 之间被重命名了。

我们在示例中使用了分支名称调用 DOLT_SCHEMA_DIFF()​,但也可以使用任何版本标识符。例如,我们可以使用提交哈希值或标签名,并获得相同的结果。

使用标签或提交哈希值:

SELECT * FROM DOLT_SCHEMA_DIFF('v1', 'v1.1');
SELECT * FROM DOLT_SCHEMA_DIFF('tjj1kp2mnoad8crv6b94mh4a4jiq7ab2', 'v391rm7r0t4989sgomv0rpn9ue4ugo6g');

到目前为止,我们总是只提供前两个参数,即 from​ 和 to​ 修订版本,但没有指定可选的表参数,因此 DOLT_SCHEMA_DIFF()​ 返回了所有已更改表的模式差异。我们可以通过将特定表作为最后一个参数指定,将 DOLT_SCHEMA_DIFF()​ 限制到某个特定表。

让我们尝试对 inventory​ 表执行此操作。

SELECT * FROM DOLT_SCHEMA_DIFF("main", "feature_branch", "inventory")

我们将看到以下结果集:

+-----------------+---------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
| from_table_name | to_table_name | from_create_statement                                             | to_create_statement                                               |
+-----------------+---------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
| inventory       | inventory     | CREATE TABLE `inventory` (                                        | CREATE TABLE `inventory` (                                        |
|                 |               |   `pk` int NOT NULL,                                              |   `pk` int NOT NULL,                                              |
|                 |               |   `name` varchar(50),                                             |   `name` varchar(50),                                             |
|                 |               |   `quantity` int,                                                 |   `color` varchar(10),                                            |
|                 |               |   PRIMARY KEY (`pk`)                                              |   PRIMARY KEY (`pk`)                                              |
|                 |               | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; |
+-----------------+---------------+-------------------------------------------------------------------+-------------------------------------------------------------------+

当表被重命名时,我们可以指定“旧”表名或“新”表名,两者都会返回相同的结果。以下两个查询将提供相同的结果:

SELECT * FROM DOLT_SCHEMA_DIFF("main", "feature_branch", "trips");
SELECT * FROM DOLT_SCHEMA_DIFF("main", "feature_branch", "vacations");

结果如下:

+-----------------+---------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
| from_table_name | to_table_name | from_create_statement                                             | to_create_statement                                               |
+-----------------+---------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
| vacations       | trips         | CREATE TABLE `vacations` (                                        | CREATE TABLE `trips` (                                            |
|                 |               |   `pk` int NOT NULL,                                              |   `pk` int NOT NULL,                                              |
|                 |               |   `name` varchar(50),                                             |   `name` varchar(50),                                             |
|                 |               |   PRIMARY KEY (`pk`)                                              |   PRIMARY KEY (`pk`)                                              |
|                 |               | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; |
+-----------------+---------------+-------------------------------------------------------------------+-------------------------------------------------------------------+

最后,我们可以交换修订版本的顺序,以获取相反方向的模式差异。

select * from dolt_schema_diff('feature_branch', 'main');

上述查询将生成以下输出:

+-----------------+---------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
| from_table_name | to_table_name | from_create_statement                                             | to_create_statement                                               |
+-----------------+---------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
| photos          |               | CREATE TABLE `photos` (                                           |                                                                   |
|                 |               |   `pk` int NOT NULL,                                              |                                                                   |
|                 |               |   `name` varchar(50),                                             |                                                                   |
|                 |               |   `dt` datetime(6),                                               |                                                                   |
|                 |               |   PRIMARY KEY (`pk`)                                              |                                                                   |
|                 |               | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; |                                                                   |
|                 | employees     |                                                                   | CREATE TABLE `employees` (                                        |
|                 |               |                                                                   |   `pk` int NOT NULL,                                              |
|                 |               |                                                                   |   `name` varchar(50),                                             |
|                 |               |                                                                   |   PRIMARY KEY (`pk`)                                              |
|                 |               |                                                                   | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; |
| inventory       | inventory     | CREATE TABLE `inventory` (                                        | CREATE TABLE `inventory` (                                        |
|                 |               |   `pk` int NOT NULL,                                              |   `pk` int NOT NULL,                                              |
|                 |               |   `name` varchar(50),                                             |   `name` varchar(50),                                             |
|                 |               |   `color` varchar(10),                                            |   `quantity` int,                                                 |
|                 |               |   PRIMARY KEY (`pk`)                                              |   PRIMARY KEY (`pk`)                                              |
|                 |               | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; |
| trips           | vacations     | CREATE TABLE `trips` (                                            | CREATE TABLE `vacations` (                                        |
|                 |               |   `pk` int NOT NULL,                                              |   `pk` int NOT NULL,                                              |
|                 |               |   `name` varchar(50),                                             |   `name` varchar(50),                                             |
|                 |               |   PRIMARY KEY (`pk`)                                              |   PRIMARY KEY (`pk`)                                              |
|                 |               | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin; |
+-----------------+---------------+-------------------------------------------------------------------+-------------------------------------------------------------------+

注意此调用与之前的 dolt_schema_diff('main', 'feature_branch')​ 调用之间的区别:

  1. 第一行表明表 photos​ 被删除

  2. 第二行表明创建了 employees​ 表

  3. 第三行中,from_create_statement​ 和 to_create_statement​ 列被交换

  4. 第四行显示了 trips​ 重命名为 vacations​ 的反向操作

示例查询

您可以尝试对 DoltHub docs_examples 数据库 调用 DOLT_SCHEMA_DIFF()​,以获取 schema_diff_v1​ 和 schema_diff_v2​ 标签之间的模式差异,这两个标签分别对应于这些示例中的 main​ 和 feature_branch​ 分支。

{% embed url="https://www.dolthub.com/repositories/dolthub/docs_examples/embed/main?active=Tables&q=SELECT+*%0AFROM+dolt_schema_diff%28%27schema_diff_v1%27%2C+%27schema_diff_v2%27%29%3B%0A" %}

​DOLT_QUERY_DIFF()​

​DOLT_QUERY_DIFF()​ 表函数用于计算任意两个查询之间的数据差异,生成的表类似于 DOLT_DIFF()​ 表函数。

权限要求

使用 DOLT_QUERY_DIFF()​ 表函数需要对每个查询中使用的所有表具有 SELECT​ 权限。

示例

在本示例中,我们有一个名为 t​ 的表,分别位于两个分支 main​ 和 other​ 中。

在 main​ 分支中,表 t​ 的数据如下:

+---+----+
| i | j  |
+---+----+
| 0 | 0  |
| 1 | 10 |
| 3 | 3  |
| 4 | 4  |
+---+----+

在 other​ 分支中,表 t​ 的数据如下:

+---+---+
| i | j |
+---+---+
| 0 | 0 |
| 1 | 1 |
| 2 | 2 |
| 4 | 4 |
+---+---+

我们可以使用 DOLT_QUERY_DIFF()​ 表函数计算这两个表之间的差异:

dolt> select * from dolt_query_diff('select * from t as of main', 'select * from t as of other');
+--------+--------+------+------+-----------+
| from_i | from_j | to_i | to_j | diff_type |
+--------+--------+------+------+-----------+
| 1      | 10     | 1    | 1    | modified  |
| NULL   | NULL   | 2    | 2    | added     |
| 3      | 3      | NULL | NULL | deleted   |
+--------+--------+------+------+-----------+
3 rows in set (0.00 sec)

注意

查询差异计算采用暴力算法,因此对于大型结果集会较慢。
该算法对结果集的大小是超线性的(n^2​)。
随着时间推移,我们将优化算法,利用存储引擎的特性来提高性能。

  • 0