Files
wehub-resource-sync 5357c39144
Fuzzer / Run Fuzzer (push) Has been cancelled
Race tests / Go race tests (ubuntu-22.04) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:01:40 +08:00

581 lines
26 KiB
Bash

#!/usr/bin/env bats
load $BATS_TEST_DIRNAME/helper/common.bash
# These tests exercise merging branches where a long-value column (TEXT / JSON / BLOB ...)
# has changed between "adaptive" and "non-adaptive" encoding on one side of the merge.
#
# Dolt encodes long-value columns one of two ways:
# - adaptive encoding (the default): small values are stored inline in the row, large
# values are stored out-of-band by address.
# - non-adaptive ("addr") encoding: the value is always stored out-of-band by address.
#
# The default is adaptive. To create a column with non-adaptive encoding we set the
# DOLT_USE_ADAPTIVE_ENCODING=false environment variable for the process that creates the
# column. That variable is read once at process startup, so we control it per `dolt`
# invocation (each CLI call is its own process).
#
# To "convert" a table's encoding on one branch while keeping the *same logical columns*
# (so the merge lines the two sides up by tag, not as unrelated columns) we recreate the
# table from its original schema under the desired encoding setting:
# 1. drop the table,
# 2. re-create it from the identical CREATE TABLE statement, with the encoding env var
# set as desired (preserves column order and any check constraints),
# 3. copy the committed rows back with `insert into t select * from t as of 'HEAD'`.
# Dolt generates column tags deterministically from the schema (a documented invariant),
# so re-creating an identical schema reproduces the original tags automatically -- the two
# branches still line up column-for-column by tag. We deliberately do NOT call
# dolt_update_column_tag to "fix up" tags afterward: that procedure rebuilds the schema as
# a side effect, which changes how the merge classifies the two schemas and ends up masking
# the very encoding-mismatch behavior these tests are meant to exercise.
setup() {
if [ "$SQL_ENGINE" = "remote-engine" ]; then
skip "These tests rely on dolt checkout and per-invocation DOLT_USE_ADAPTIVE_ENCODING env vars, neither of which work against the remote sql-server engine."
fi
setup_common
# Default every dolt invocation in these tests to NON-adaptive encoding, so that any
# table/column we create starts out non-adaptive. recreate_table_with_encoding flips
# the encoding to adaptive with a per-command override.
export DOLT_USE_ADAPTIVE_ENCODING=false
}
teardown() {
assert_feature_version
teardown_common
}
# recreate_table_with_encoding <table> <true|false> <full-create-table-ddl>
# Recreates <table> under the given adaptive-encoding setting, preserving the original
# column order, check constraints, tags, and data. Leaves the result in the working set
# (does not commit). The table's current rows must be present at HEAD.
recreate_table_with_encoding() {
local tbl=$1 adaptive=$2 ddl=$3
dolt sql -q "drop table $tbl"
# The re-created table picks up adaptive (or non-adaptive) encoding because this single
# process overrides the test-wide DOLT_USE_ADAPTIVE_ENCODING default.
DOLT_USE_ADAPTIVE_ENCODING=$adaptive dolt sql -q "$ddl"
dolt sql -q "insert into $tbl select * from $tbl as of 'HEAD'"
}
# assert_col_tag <table> <column> <expected-tag>
assert_col_tag() {
local tbl=$1 col=$2 want=$3 got
got=$(dolt schema tags -r csv | awk -F, -v t="$tbl" -v c="$col" '$1==t && $2==c {print $3}')
[ "$got" = "$want" ] || ( echo "tag mismatch for $tbl.$col: want $want got $got" && return 1 )
}
# ---------------------------------------------------------------------------
# Functional matrix: small tables, TEXT and JSON, case 1 (dest converts) and
# case 2 (source converts), with and without a check constraint.
#
# Layout (independent changes on each side):
# base: pk 1,2,4 present
# source 'other': updates val of pk=1, inserts pk=3
# dest 'main': updates val of pk=2, updates the long-value column of pk=4
# Exactly one side additionally converts the long column's encoding.
# ---------------------------------------------------------------------------
@test "merge-adaptive-encoding: TEXT, dest converts to adaptive (case 1)" {
ddl="create table t (pk int primary key, c text, val int)"
dolt sql -q "$ddl"
dolt sql -q "insert into t (pk,c,val) values (1,'aaa',10),(2,'bbb',20),(4,'ddd',40)"
dolt add . && dolt commit -m base
base_tag=$(dolt schema tags -r csv | awk -F, '$1=="t" && $2=="c"{print $3}')
# source: no conversion, independent changes
dolt checkout -b other
dolt sql -q "update t set val = 11 where pk = 1"
dolt sql -q "insert into t (pk,c,val) values (3,'ccc',30)"
dolt commit -am "source changes"
# dest: convert to adaptive, independent changes
dolt checkout main
recreate_table_with_encoding t true "$ddl"
dolt sql -q "update t set val = 21 where pk = 2"
dolt sql -q "update t set c = 'DDD' where pk = 4"
dolt commit -am "dest converts + changes"
assert_col_tag t c "$base_tag"
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
run dolt sql -r csv -q "select pk, c, val from t order by pk"
[ "$status" -eq 0 ]
[[ "$output" =~ "1,aaa,11" ]] || false
[[ "$output" =~ "2,bbb,21" ]] || false
[[ "$output" =~ "3,ccc,30" ]] || false
[[ "$output" =~ "4,DDD,40" ]] || false
}
@test "merge-adaptive-encoding: TEXT, source converts to adaptive (case 2)" {
ddl="create table t (pk int primary key, c text, val int)"
dolt sql -q "$ddl"
dolt sql -q "insert into t (pk,c,val) values (1,'aaa',10),(2,'bbb',20),(4,'ddd',40)"
dolt add . && dolt commit -m base
base_tag=$(dolt schema tags -r csv | awk -F, '$1=="t" && $2=="c"{print $3}')
# source: convert to adaptive, independent changes
dolt checkout -b other
recreate_table_with_encoding t true "$ddl"
dolt sql -q "update t set val = 11 where pk = 1"
dolt sql -q "insert into t (pk,c,val) values (3,'ccc',30)"
dolt commit -am "source converts + changes"
assert_col_tag t c "$base_tag"
# dest: no conversion, independent changes
dolt checkout main
dolt sql -q "update t set val = 21 where pk = 2"
dolt sql -q "update t set c = 'DDD' where pk = 4"
dolt commit -am "dest changes"
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
run dolt sql -r csv -q "select pk, c, val from t order by pk"
[ "$status" -eq 0 ]
[[ "$output" =~ "1,aaa,11" ]] || false
[[ "$output" =~ "2,bbb,21" ]] || false
[[ "$output" =~ "3,ccc,30" ]] || false
[[ "$output" =~ "4,DDD,40" ]] || false
}
@test "merge-adaptive-encoding: JSON, dest converts to adaptive (case 1)" {
ddl="create table t (pk int primary key, c json, val int)"
dolt sql -q "$ddl"
dolt sql -q "insert into t (pk,c,val) values (1,JSON_OBJECT('v',1),10),(2,JSON_OBJECT('v',2),20),(4,JSON_OBJECT('v',4),40)"
dolt add . && dolt commit -m base
base_tag=$(dolt schema tags -r csv | awk -F, '$1=="t" && $2=="c"{print $3}')
dolt checkout -b other
dolt sql -q "update t set val = 11 where pk = 1"
dolt sql -q "insert into t (pk,c,val) values (3,JSON_OBJECT('v',3),30)"
dolt commit -am "source changes"
dolt checkout main
recreate_table_with_encoding t true "$ddl"
dolt sql -q "update t set val = 21 where pk = 2"
dolt sql -q "update t set c = JSON_OBJECT('v',44) where pk = 4"
dolt commit -am "dest converts + changes"
assert_col_tag t c "$base_tag"
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
run dolt sql -r csv -q "select pk, json_extract(c,'\$.v') v, val from t order by pk"
[ "$status" -eq 0 ]
[[ "$output" =~ "1,1,11" ]] || false
[[ "$output" =~ "2,2,21" ]] || false
[[ "$output" =~ "3,3,30" ]] || false
[[ "$output" =~ "4,44,40" ]] || false
}
@test "merge-adaptive-encoding: JSON, source converts to adaptive (case 2)" {
ddl="create table t (pk int primary key, c json, val int)"
dolt sql -q "$ddl"
dolt sql -q "insert into t (pk,c,val) values (1,JSON_OBJECT('v',1),10),(2,JSON_OBJECT('v',2),20),(4,JSON_OBJECT('v',4),40)"
dolt add . && dolt commit -m base
base_tag=$(dolt schema tags -r csv | awk -F, '$1=="t" && $2=="c"{print $3}')
dolt checkout -b other
recreate_table_with_encoding t true "$ddl"
dolt sql -q "update t set val = 11 where pk = 1"
dolt sql -q "insert into t (pk,c,val) values (3,JSON_OBJECT('v',3),30)"
dolt commit -am "source converts + changes"
assert_col_tag t c "$base_tag"
dolt checkout main
dolt sql -q "update t set val = 21 where pk = 2"
dolt sql -q "update t set c = JSON_OBJECT('v',44) where pk = 4"
dolt commit -am "dest changes"
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
run dolt sql -r csv -q "select pk, json_extract(c,'\$.v') v, val from t order by pk"
[ "$status" -eq 0 ]
[[ "$output" =~ "1,1,11" ]] || false
[[ "$output" =~ "2,2,21" ]] || false
[[ "$output" =~ "3,3,30" ]] || false
[[ "$output" =~ "4,44,40" ]] || false
}
# REGRESSION: when the merge DESTINATION holds the column adaptively encoded and the SOURCE
# holds it non-adaptively, a row ADDED on the source side is validated against the check
# constraint in the destination's (adaptive) context. The validator must build the new row by
# reading its long column -- whose bytes are the source's non-adaptive encoding -- using the
# SOURCE side's value descriptor. Before the fix it read those bytes with the destination's
# adaptive descriptor and panicked ("invalid hash length: 19"). (The trigger is the inserted
# pk=3 row; an update-only merge of the same mismatch does not hit it.)
@test "merge-adaptive-encoding: TEXT with check constraint, dest converts (case 1)" {
ddl="create table t (pk int primary key, c text, val int, check (val >= 0))"
dolt sql -q "$ddl"
dolt sql -q "insert into t (pk,c,val) values (1,'aaa',10),(2,'bbb',20),(4,'ddd',40)"
dolt add . && dolt commit -m base
base_tag=$(dolt schema tags -r csv | awk -F, '$1=="t" && $2=="c"{print $3}')
dolt checkout -b other
dolt sql -q "update t set val = 11 where pk = 1"
dolt sql -q "insert into t (pk,c,val) values (3,'ccc',30)"
dolt commit -am "source changes"
dolt checkout main
recreate_table_with_encoding t true "$ddl"
dolt sql -q "update t set val = 21 where pk = 2"
dolt sql -q "update t set c = 'DDD' where pk = 4"
dolt commit -am "dest converts + changes"
assert_col_tag t c "$base_tag"
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
run dolt sql -r csv -q "select pk, c, val from t order by pk"
[[ "$output" =~ "1,aaa,11" ]] || false
[[ "$output" =~ "2,bbb,21" ]] || false
[[ "$output" =~ "3,ccc,30" ]] || false
[[ "$output" =~ "4,DDD,40" ]] || false
# the check constraint survives the merge and is not violated
run dolt sql -q "show create table t"
[[ "$output" =~ "CHECK" ]] || false
run dolt sql -r csv -q "select count(*) as n from dolt_constraint_violations"
[ "${lines[1]}" = "0" ]
}
@test "merge-adaptive-encoding: TEXT with check constraint, source converts (case 2)" {
ddl="create table t (pk int primary key, c text, val int, check (val >= 0))"
dolt sql -q "$ddl"
dolt sql -q "insert into t (pk,c,val) values (1,'aaa',10),(2,'bbb',20),(4,'ddd',40)"
dolt add . && dolt commit -m base
base_tag=$(dolt schema tags -r csv | awk -F, '$1=="t" && $2=="c"{print $3}')
dolt checkout -b other
recreate_table_with_encoding t true "$ddl"
dolt sql -q "update t set val = 11 where pk = 1"
dolt sql -q "insert into t (pk,c,val) values (3,'ccc',30)"
dolt commit -am "source converts + changes"
assert_col_tag t c "$base_tag"
dolt checkout main
dolt sql -q "update t set val = 21 where pk = 2"
dolt sql -q "update t set c = 'DDD' where pk = 4"
dolt commit -am "dest changes"
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
run dolt sql -r csv -q "select pk, c, val from t order by pk"
[[ "$output" =~ "1,aaa,11" ]] || false
[[ "$output" =~ "2,bbb,21" ]] || false
[[ "$output" =~ "3,ccc,30" ]] || false
[[ "$output" =~ "4,DDD,40" ]] || false
run dolt sql -q "show create table t"
[[ "$output" =~ "CHECK" ]] || false
run dolt sql -r csv -q "select count(*) as n from dolt_constraint_violations"
[ "${lines[1]}" = "0" ]
}
# REGRESSION: same root cause as the TEXT "dest converts (case 1)" check-constraint test
# above, for JSON.
@test "merge-adaptive-encoding: JSON with check constraint, dest converts (case 1)" {
ddl="create table t (pk int primary key, c json, val int, check (val >= 0))"
dolt sql -q "$ddl"
dolt sql -q "insert into t (pk,c,val) values (1,JSON_OBJECT('v',1),10),(2,JSON_OBJECT('v',2),20),(4,JSON_OBJECT('v',4),40)"
dolt add . && dolt commit -m base
base_tag=$(dolt schema tags -r csv | awk -F, '$1=="t" && $2=="c"{print $3}')
dolt checkout -b other
dolt sql -q "update t set val = 11 where pk = 1"
dolt sql -q "insert into t (pk,c,val) values (3,JSON_OBJECT('v',3),30)"
dolt commit -am "source changes"
dolt checkout main
recreate_table_with_encoding t true "$ddl"
dolt sql -q "update t set val = 21 where pk = 2"
dolt sql -q "update t set c = JSON_OBJECT('v',44) where pk = 4"
dolt commit -am "dest converts + changes"
assert_col_tag t c "$base_tag"
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
run dolt sql -r csv -q "select pk, json_extract(c,'\$.v') v, val from t order by pk"
[[ "$output" =~ "1,1,11" ]] || false
[[ "$output" =~ "2,2,21" ]] || false
[[ "$output" =~ "3,3,30" ]] || false
[[ "$output" =~ "4,44,40" ]] || false
run dolt sql -r csv -q "select count(*) as n from dolt_constraint_violations"
[ "${lines[1]}" = "0" ]
}
@test "merge-adaptive-encoding: JSON with check constraint, source converts (case 2)" {
ddl="create table t (pk int primary key, c json, val int, check (val >= 0))"
dolt sql -q "$ddl"
dolt sql -q "insert into t (pk,c,val) values (1,JSON_OBJECT('v',1),10),(2,JSON_OBJECT('v',2),20),(4,JSON_OBJECT('v',4),40)"
dolt add . && dolt commit -m base
base_tag=$(dolt schema tags -r csv | awk -F, '$1=="t" && $2=="c"{print $3}')
dolt checkout -b other
recreate_table_with_encoding t true "$ddl"
dolt sql -q "update t set val = 11 where pk = 1"
dolt sql -q "insert into t (pk,c,val) values (3,JSON_OBJECT('v',3),30)"
dolt commit -am "source converts + changes"
assert_col_tag t c "$base_tag"
dolt checkout main
dolt sql -q "update t set val = 21 where pk = 2"
dolt sql -q "update t set c = JSON_OBJECT('v',44) where pk = 4"
dolt commit -am "dest changes"
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
run dolt sql -r csv -q "select pk, json_extract(c,'\$.v') v, val from t order by pk"
[[ "$output" =~ "1,1,11" ]] || false
[[ "$output" =~ "2,2,21" ]] || false
[[ "$output" =~ "3,3,30" ]] || false
[[ "$output" =~ "4,44,40" ]] || false
run dolt sql -r csv -q "select count(*) as n from dolt_constraint_violations"
[ "${lines[1]}" = "0" ]
}
# ---------------------------------------------------------------------------
# Structural matrix: a base table whose primary index spans many prolly-tree leaf chunks,
# with a layout that gives each side genuinely *exclusive* new subtrees plus a shared range
# that both sides edit and partly delete:
#
# SHARED [2048, 4096) present in the base. The two sides edit disjoint rows in it:
# source owns even pks -> modifies pk%4==0, deletes pk%4==2
# dest owns odd pks -> modifies pk%4==1, deletes pk%4==3
# SRC_INS [0, 2048) inserted only by the source (source's exclusive new subtrees)
# DST_INS [4096, 6144) inserted only by the dest (dest's exclusive new subtrees)
#
# Because each inserted region is brand new and untouched by the other side, the merge can
# represent it with whole-subtree (chunk-level) patches and graft it directly into the other
# branch's tree. If the two branches encode the long column differently and the merge grafts
# a subtree without rewriting it into the destination encoding, the result is a tree whose
# stored chunks don't match the schema's declared encoding -- a corruption that a count(*) or
# a val-only read will not notice. The assertions therefore force the engine to actually read
# and materialize the long column (matching on its content), so an encoding graft bug cannot
# hide behind column pruning.
#
# Values are large enough to be stored out-of-band; ~2k rows per region at ~100 rows/leaf
# gives tens of leaf chunks per region, i.e. real whole-subtree grafts.
# ---------------------------------------------------------------------------
# struct2_val <prefix> <pk-expr> <coltype> -> SQL for a large, out-of-band, content-tagged
# value. The <prefix> records which edit produced the row so assertions can read it back.
struct2_val() {
if [ "$3" = "json" ]; then
echo "json_object('tag','$1','pk',$2,'pad',repeat('x',1190))"
else
echo "rpad(concat('$1-', $2), 1200, '.')"
fi
}
# struct2_present <prefix> <coltype> -> a WHERE predicate matching rows tagged <prefix>.
# Evaluating it touches the long column for every row, forcing materialization.
struct2_present() {
if [ "$2" = "json" ]; then echo "json_extract(c,'\$.tag') = '$1'"; else echo "c like '$1-%'"; fi
}
# struct2_build <coltype> <case 1|2> <check-clause> [base-encoding: nonadaptive|adaptive]
# Builds the base and both branches in the layout above, leaving HEAD on main ready to
# 'dolt merge other'. The base (and the non-converting side) use <base-encoding> (default
# nonadaptive); the converting side (dest for case 1, source for case 2) recreates the table
# in the OPPOSITE encoding. Running with both base encodings covers both directions of the
# adaptive <-> non-adaptive mismatch, which behaved differently before the merge fixes.
struct2_build() {
local typ=$1 cs=$2 chk=$3 base_enc=${4:-nonadaptive} ddl
local base_adaptive convert_to
if [ "$base_enc" = "adaptive" ]; then
base_adaptive=true; convert_to=false
else
base_adaptive=false; convert_to=true
fi
ddl="create table t (pk int primary key, c $typ, val int $chk)"
DOLT_USE_ADAPTIVE_ENCODING=$base_adaptive dolt sql -q "$ddl"
dolt sql -q "insert into t (pk,c,val) with recursive s(n) as (select 2048 union all select n+1 from s where n < 4095) select n, $(struct2_val BASE n $typ), n from s"
dolt add .
dolt commit -m "base (shared range, $base_enc)"
dolt checkout -b other
[ "$cs" = "2" ] && recreate_table_with_encoding t $convert_to "$ddl"
dolt sql -q "update t set c = $(struct2_val SMOD pk $typ), val = val + 100000 where pk >= 2048 and pk < 4096 and pk % 4 = 0"
dolt sql -q "delete from t where pk >= 2048 and pk < 4096 and pk % 4 = 2"
dolt sql -q "insert into t (pk,c,val) with recursive s(n) as (select 0 union all select n+1 from s where n < 2047) select n, $(struct2_val SRC n $typ), n from s"
dolt commit -am "source: shared edits + exclusive inserts [0,2048)"
dolt checkout main
[ "$cs" = "1" ] && recreate_table_with_encoding t $convert_to "$ddl"
dolt sql -q "update t set c = $(struct2_val DMOD pk $typ), val = val + 200000 where pk >= 2048 and pk < 4096 and pk % 4 = 1"
dolt sql -q "delete from t where pk >= 2048 and pk < 4096 and pk % 4 = 3"
dolt sql -q "insert into t (pk,c,val) with recursive s(n) as (select 4096 union all select n+1 from s where n < 6143) select n, $(struct2_val DST n $typ), n from s"
dolt commit -am "dest: shared edits + exclusive inserts [4096,6144)"
}
# struct2_assert <coltype>: forces a full read/materialization of the long column and checks
# every region merged correctly. Surviving rows: 2048 (src inserts) + 2048 (dest inserts)
# + 512 (src-modified shared) + 512 (dest-modified shared) = 5120; the 1024 shared rows
# marked for deletion are gone and no unmodified BASE row remains.
struct2_assert() {
local typ=$1
run dolt sql -r csv -q "select count(*) as n from t"
[ "${lines[1]}" = "5120" ]
# Each of these evaluates the long column for every row -> forces materialization.
run dolt sql -r csv -q "select count(*) as n from t where $(struct2_present SRC $typ)"
[ "${lines[1]}" = "2048" ]
run dolt sql -r csv -q "select count(*) as n from t where $(struct2_present DST $typ)"
[ "${lines[1]}" = "2048" ]
run dolt sql -r csv -q "select count(*) as n from t where $(struct2_present SMOD $typ)"
[ "${lines[1]}" = "512" ]
run dolt sql -r csv -q "select count(*) as n from t where $(struct2_present DMOD $typ)"
[ "${lines[1]}" = "512" ]
run dolt sql -r csv -q "select count(*) as n from t where $(struct2_present BASE $typ)"
[ "${lines[1]}" = "0" ]
# shared rows marked for deletion on either side are gone
run dolt sql -r csv -q "select count(*) as n from t where pk >= 2048 and pk < 4096 and (pk % 4 = 2 or pk % 4 = 3)"
[ "${lines[1]}" = "0" ]
}
@test "merge-adaptive-encoding: structural TEXT, dest converts to adaptive (case 1)" {
struct2_build text 1 ""
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
struct2_assert text
}
# REGRESSION: the merge SOURCE holds the column adaptively encoded and inserts whole new leaf
# subtrees; before the fix, merging into the non-adaptive destination grafted those adaptive
# subtrees in without re-encoding them, so the merge reported success but the resulting table
# was corrupt -- reading the long column failed ("invalid hash length"). The
# forced-materialization assertions below are what expose such corruption.
@test "merge-adaptive-encoding: structural TEXT, source converts to adaptive (case 2)" {
struct2_build text 2 ""
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
struct2_assert text
}
@test "merge-adaptive-encoding: structural JSON, dest converts to adaptive (case 1)" {
struct2_build json 1 ""
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
struct2_assert json
}
# REGRESSION: see the TEXT case-2 note above, for JSON.
@test "merge-adaptive-encoding: structural JSON, source converts to adaptive (case 2)" {
struct2_build json 2 ""
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
struct2_assert json
}
# REGRESSION: case-1 layout with a check constraint. The source (non-adaptive) inserts new
# rows that are validated against the check in the destination's adaptive context; the
# validator must read them with the source side's encoding (before the fix it panicked during
# the merge).
@test "merge-adaptive-encoding: structural TEXT with check constraint, dest converts (case 1)" {
struct2_build text 1 ", check (val >= 0)"
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
struct2_assert text
run dolt sql -r csv -q "select count(*) as n from dolt_constraint_violations"
[ "${lines[1]}" = "0" ]
}
# REGRESSION: case-2 layout with a check constraint -- exercises both the grafted-subtree
# re-encoding (case 2) and constraint validation together.
@test "merge-adaptive-encoding: structural TEXT with check constraint, source converts (case 2)" {
struct2_build text 2 ", check (val >= 0)"
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
struct2_assert text
run dolt sql -r csv -q "select count(*) as n from dolt_constraint_violations"
[ "${lines[1]}" = "0" ]
}
# ---------------------------------------------------------------------------
# Mirror direction: the base (and the non-converting side) are ADAPTIVE, and the converting
# side flips to NON-adaptive. Before the merge fixes these behaved differently from the
# non-adaptive-base cases above -- in particular the source-converts case here CRASHED the
# merge process outright (rather than silently corrupting), and the destination's adaptive
# inserts were the rows left mis-encoded under the merged non-adaptive schema.
# ---------------------------------------------------------------------------
@test "merge-adaptive-encoding: structural TEXT, dest converts to non-adaptive (case 1, adaptive base)" {
struct2_build text 1 "" adaptive
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
struct2_assert text
}
# REGRESSION: mirror of the structural case-2 graft bug. Here the SOURCE converts to
# non-adaptive and the DESTINATION's adaptive leaf subtrees are the ones that must be
# re-encoded into the merged non-adaptive schema rather than left in place. Before the fix
# this crashed the merge.
@test "merge-adaptive-encoding: structural TEXT, source converts to non-adaptive (case 2, adaptive base)" {
struct2_build text 2 "" adaptive
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
struct2_assert text
}
@test "merge-adaptive-encoding: structural JSON, dest converts to non-adaptive (case 1, adaptive base)" {
struct2_build json 1 "" adaptive
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
struct2_assert json
}
# REGRESSION: mirror of the structural case-2 graft bug, for JSON.
@test "merge-adaptive-encoding: structural JSON, source converts to non-adaptive (case 2, adaptive base)" {
struct2_build json 2 "" adaptive
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
struct2_assert json
}
@test "merge-adaptive-encoding: structural TEXT with check constraint, dest converts to non-adaptive (case 1, adaptive base)" {
struct2_build text 1 ", check (val >= 0)" adaptive
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
struct2_assert text
run dolt sql -r csv -q "select count(*) as n from dolt_constraint_violations"
[ "${lines[1]}" = "0" ]
}
# REGRESSION: mirror case-2 layout with a check constraint -- grafted-subtree re-encoding and
# constraint validation together, with the encodings swapped relative to the case above.
@test "merge-adaptive-encoding: structural TEXT with check constraint, source converts to non-adaptive (case 2, adaptive base)" {
struct2_build text 2 ", check (val >= 0)" adaptive
run dolt merge other -m merge
[ "$status" -eq 0 ]
[[ ! "$output" =~ "conflict" ]] || false
struct2_assert text
run dolt sql -r csv -q "select count(*) as n from dolt_constraint_violations"
[ "${lines[1]}" = "0" ]
}