unskipped BATS for basic SQL CRUD, fixed bugs

This commit is contained in:
Andy Arthur
2020-12-16 09:26:58 -08:00
parent 7d6a83ae26
commit d594bcdd8d
6 changed files with 101 additions and 44 deletions

View File

@@ -4,16 +4,14 @@ load $BATS_TEST_DIRNAME/helper/common.bash
setup() {
setup_common
skip "unimplemented"
dolt sql <<SQL
dolt --keyless sql <<SQL
CREATE TABLE keyless (
c0 int,
c1 int
);
INSERT INTO keyless VALUES (0,0),(2,2),(1,1),(1,1);
SQL
dolt commit -am "init"
dolt --keyless commit -am "init"
}
teardown() {
@@ -23,48 +21,50 @@ teardown() {
@test "create keyless table" {
# created in setup()
run dolt ls
run dolt --keyless ls
[ $status -eq 0 ]
[[ "$lines[@]" = "keyless" ]] || false
[[ "$output" =~ "keyless" ]] || false
run dolt sql -q "SHOW CREATE TABLE keyless;" -r csv
dolt --keyless sql -q "SHOW CREATE TABLE keyless;"
run dolt --keyless sql -q "SHOW CREATE TABLE keyless;"
[ $status -eq 0 ]
[[ "$lines[@]" = "CREATE TABLE \`keyless\` (" ]] || false
[[ "$lines[@]" = "\`c0\` int," ]] || false
[[ "$lines[@]" = "\`c1\` int" ]] || false
[[ "$lines[@]" = ");" ]] || false
[[ "$output" =~ "CREATE TABLE \`keyless\` (" ]] || false
[[ "$output" =~ "\`c0\` int," ]] || false
[[ "$output" =~ "\`c1\` int" ]] || false
[[ "$output" =~ ")" ]] || false
run dolt sql -q "SELECT sum(c0),sum(c1) FROM keyless;" -r csv
dolt --keyless sql -q "SELECT sum(c0),sum(c1) FROM keyless;" -r csv
run dolt --keyless sql -q "SELECT sum(c0),sum(c1) FROM keyless;" -r csv
[ $status -eq 0 ]
[[ "$output" = "4,4" ]] || false
[[ "${lines[1]}" =~ "4,4" ]] || false
}
@test "delete from keyless" {
run dolt sql -q "DELETE FROM keyless WHERE c0 = 2;"
run dolt --keyless sql -q "DELETE FROM keyless WHERE c0 = 2;"
[ $status -eq 0 ]
run dolt sql -q "SELECT * FROM keyless ORDER BY c0;" -r csv
run dolt --keyless sql -q "SELECT * FROM keyless ORDER BY c0;" -r csv
[ $status -eq 0 ]
[[ "$lines[@]" = "0,0" ]] || false
[[ "$lines[@]" = "1,1" ]] || false
[[ "$lines[@]" = "1,1" ]] || false
[[ "${lines[1]}" = "0,0" ]] || false
[[ "${lines[2]}" = "1,1" ]] || false
[[ "${lines[3]}" = "1,1" ]] || false
}
# order will differ without 'ORDER BY' clause
@test "update keyless" {
run dolt sql -q "UPDATE keyless SET c0 = 9 WHERE c0 = 2;"
run dolt --keyless sql -q "UPDATE keyless SET c0 = 9 WHERE c0 = 2;"
[ $status -eq 0 ]
run dolt sql -q "SELECT * FROM keyless ORDER BY c0;" -r csv
run dolt --keyless sql -q "SELECT * FROM keyless ORDER BY c0;" -r csv
[ $status -eq 0 ]
[[ "$lines[@]" = "0,0" ]] || false
[[ "$lines[@]" = "1,1" ]] || false
[[ "$lines[@]" = "1,1" ]] || false
[[ "$lines[@]" = "9,2" ]] || false
[[ "${lines[1]}" = "0,0" ]] || false
[[ "${lines[2]}" = "1,1" ]] || false
[[ "${lines[3]}" = "1,1" ]] || false
[[ "${lines[4]}" = "9,2" ]] || false
}
# keyless tables allow duplicate rows
@test "keyless table import" {
skip "unimplemented"
cat <<CSV > data.csv
c0,c1
0,0
@@ -89,6 +89,7 @@ CSV
# updates are always appends
@test "keyless table update" {
skip "unimplemented"
cat <<CSV > data.csv
c0,c1
0,0
@@ -113,6 +114,7 @@ CSV
}
@test "keyless diff against working set" {
skip "unimplemented"
dolt sql -q "INSERT INTO keyless VALUES (9,9);"
run dolt diff
[ $status -eq 0 ]
@@ -120,6 +122,7 @@ CSV
}
@test "keyless merge fast-forward" {
skip "unimplemented"
dolt checkout -b other
dolt sql -q "INSERT INTO keyless VALUES (9,9);"
dolt commit -am "9,9"
@@ -132,6 +135,7 @@ CSV
}
@test "keyless diff branches with identical mutation history" {
skip "unimplemented"
dolt branch other
dolt sql -q "INSERT INTO keyless VALUES (7,7),(8,8),(9,9);"
@@ -147,6 +151,7 @@ CSV
}
@test "keyless merge branches with identical mutation history" {
skip "unimplemented"
dolt branch other
dolt sql -q "INSERT INTO keyless VALUES (7,7),(8,8),(9,9);"
@@ -166,6 +171,7 @@ CSV
}
@test "keyless diff deletes from two branches" {
skip "unimplemented"
dolt branch left
dolt checkout -b right
@@ -186,6 +192,7 @@ CSV
}
@test "keyless merge deletes from two branches" {
skip "unimplemented"
dolt branch left
dolt checkout -b right
@@ -218,6 +225,7 @@ SQL
}
@test "keyless diff duplicate deletes" {
skip "unimplemented"
make_dupe_table
dolt branch left
@@ -244,6 +252,7 @@ SQL
}
@test "keyless merge duplicate deletes" {
skip "unimplemented"
make_dupe_table
dolt branch left
@@ -262,6 +271,7 @@ SQL
}
@test "keyless diff duplicate updates" {
skip "unimplemented"
make_dupe_table
dolt branch left
@@ -285,6 +295,7 @@ SQL
# order will differ without 'ORDER BY' clause
@test "keyless merge duplicate updates" {
skip "unimplemented"
make_dupe_table
dolt branch left
@@ -303,6 +314,7 @@ SQL
}
@test "keyless sql diff" {
skip "unimplemented"
dolt sql <<SQL
DELETE FROM keyless WHERE c0 = 2;
INSERT INTO keyless VALUES (3,3);
@@ -322,6 +334,7 @@ SQL
}
@test "keyless sql diff as a patch" {
skip "unimplemented"
dolt branch left
dolt checkout -b right
@@ -342,6 +355,7 @@ SQL
@test "keyless tables read in sorted order" {
skip "unimplemented"
run dolt sql -q "SELECT * FROM keyless;" -r csv
[ $status -eq 0 ]
[[ "$output" = "0,0" ]] || false
@@ -352,6 +366,7 @@ SQL
# tables are read/stored in sorted order
@test "keyless table replace" {
skip "unimplemented"
cat <<CSV > data.csv
c0,c1
0,0
@@ -381,6 +396,7 @@ CSV
# in-place updates create become drop/add
@test "keyless diff with in-place updates (working set)" {
skip "unimplemented"
dolt sql -q "UPDATE keyless SET c1 = 9 where c0 = 2;"
run dolt diff
[ $status -eq 0 ]
@@ -390,6 +406,7 @@ CSV
# in-place updates create become drop/add
@test "keyless sql diff with in-place updates (working set)" {
skip "unimplemented"
dolt sql -q "UPDATE keyless SET c1 = 9 where c0 = 2;"
run dolt diff -r sql
[ $status -eq 0 ]
@@ -399,6 +416,7 @@ CSV
# update patch always recreates identical branches
@test "keyless updates as a sql diff patch" {
skip "unimplemented"
dolt branch left
dolt checkout -b right
@@ -421,6 +439,7 @@ CSV
# in-place updates diff as drop/add
@test "keyless diff with in-place updates (branches)" {
skip "unimplemented"
dolt sql -q "INSERT INTO keyless VALUES (7,7),(8,8),(9,9);"
dolt commit -am "added rows"
dolt branch other
@@ -445,6 +464,7 @@ CSV
# where in-place updates are divergent, both versions are kept on merge
# same for hidden key and bag semantics
@test "keyless merge with in-place updates (branches)" {
skip "unimplemented"
dolt sql -q "INSERT INTO keyless VALUES (7,7),(8,8),(9,9);"
dolt commit -am "added rows"
dolt branch other
@@ -463,6 +483,7 @@ CSV
# bag semantics diffs membership, not order
@test "keyless diff branches with reordered mutation history" {
skip "unimplemented"
dolt branch other
dolt sql -q "INSERT INTO keyless VALUES (7,7),(8,8),(9,9);"
@@ -479,6 +500,7 @@ CSV
# bag semantics diffs membership, not order
@test "keyless merge branches with reordered mutation history" {
skip "unimplemented"
dolt branch other
dolt sql -q "INSERT INTO keyless VALUES (7,7),(8,8),(9,9);"
@@ -502,6 +524,7 @@ CSV
# convergent row data history with convergent data has convergent storage representation
@test "keyless diff branches with convergent mutation history" {
skip "unimplemented"
dolt branch other
dolt sql -q "INSERT INTO keyless VALUES (7,7),(8,8),(9,9);"
@@ -522,6 +545,7 @@ SQL
# convergent row data has convergent storage representation
@test "keyless merge branches with convergent mutation history" {
skip "unimplemented"
dolt branch other
dolt sql -q "INSERT INTO keyless VALUES (7,7),(8,8),(9,9);"
@@ -543,6 +567,7 @@ SQL
# bag semantics give minimal diff
@test "keyless diff branches with offset mutation history" {
skip "unimplemented"
dolt branch other
dolt sql -q "INSERT INTO keyless VALUES (7,7),(8,8),(9,9);"
@@ -559,6 +584,7 @@ SQL
}
@test "keyless merge branches with offset mutation history" {
skip "unimplemented"
dolt branch other
dolt sql -q "INSERT INTO keyless VALUES (7,7),(8,8),(9,9);"
@@ -574,6 +600,7 @@ SQL
}
@test "keyless diff delete+add against working" {
skip "unimplemented"
dolt sql <<SQL
DELETE FROM keyless WHERE c0 = 2;
INSERT INTO keyless VALUES (2,2)
@@ -584,6 +611,7 @@ SQL
}
@test "keyless diff delete+add on two branches" {
skip "unimplemented"
dolt branch left
dolt checkout -b right
@@ -605,6 +633,7 @@ SQL
# row gets deleted from the middle and added to the end
@test "keyless merge delete+add on two branches" {
skip "unimplemented"
dolt branch left
dolt checkout -b right

View File

@@ -162,7 +162,7 @@ func runMain() int {
restoreIO := cli.InitIO()
defer restoreIO()
warnIfMaxFilesTooLow()
//warnIfMaxFilesTooLow()
ctx := context.Background()
dEnv := env.Load(ctx, env.GetCurrentUserHomeDir, filesys.LocalFS, doltdb.LocalDirDoltDB, Version)
@@ -211,7 +211,7 @@ func runMain() int {
return 1
}
err = reconfigIfTempFileMoveFails(dEnv)
//err = reconfigIfTempFileMoveFails(dEnv)
if err != nil {
cli.PrintErrln(color.RedString("Failed to setup the temporary directory. %v`", err))

View File

@@ -202,7 +202,7 @@ func GetTableDeltas(ctx context.Context, fromRoot, toRoot *doltdb.RootValue) (de
return true, err
}
pkTag := sch.GetPKCols().GetColumns()[0].Tag
pkTag := getUniqueTag(sch)
fromTables[pkTag] = table
fromTableNames[pkTag] = name
fromTableHashes[pkTag] = th
@@ -241,7 +241,7 @@ func GetTableDeltas(ctx context.Context, fromRoot, toRoot *doltdb.RootValue) (de
toFksParentSch[toFk.ReferencedTableName] = toRefSch
}
pkTag := sch.GetPKCols().GetColumns()[0].Tag
pkTag := getUniqueTag(sch)
oldName, ok := fromTableNames[pkTag]
if !ok {
@@ -317,6 +317,14 @@ func GetStagedUnstagedTableDeltas(ctx context.Context, ddb *doltdb.DoltDB, rsr e
return staged, unstaged, nil
}
func getUniqueTag(sch schema.Schema) uint64 {
if schema.IsKeyless(sch) {
// todo: this will break for column changes
return sch.GetNonPKCols().Tags[0]
}
return sch.GetPKCols().Tags[0]
}
// IsAdd returns true if the table was added between the fromRoot and toRoot.
func (td TableDelta) IsAdd() bool {
return td.FromTable == nil && td.ToTable != nil

View File

@@ -38,7 +38,7 @@ const (
featureVersKey = "feature_ver"
)
// RootValue defines the structure used inside all Liquidata noms dbs
// RootValue defines the structure used inside all Dolthub noms dbs
type RootValue struct {
vrw types.ValueReadWriter
valueSt types.Struct

View File

@@ -309,17 +309,22 @@ func applyEdits(ctx context.Context, tbl *doltdb.Table, acc keylessEditAcc) (*do
return nil, err
}
var ok bool
if v == nil {
// row does not yet exist
v, err = setCardinality(delta.val, delta.delta)
v, ok, err = setCardinality(delta.val, delta.delta)
} else {
v, err = updateCardinality(v.(types.Tuple), delta.delta)
v, ok, err = updateCardinality(v.(types.Tuple), delta.delta)
}
if err != nil {
return nil, err
}
ed.Set(k, v)
if ok {
ed.Set(k, v)
} else {
ed.Remove(k)
}
}
rowData, err = ed.Map(ctx)
@@ -330,24 +335,36 @@ func applyEdits(ctx context.Context, tbl *doltdb.Table, acc keylessEditAcc) (*do
return tbl.UpdateRows(ctx, rowData)
}
func setCardinality(val types.Tuple, delta int64) (types.Tuple, error) {
if delta < 1 {
err := fmt.Errorf("attempted to initialize row with non-positive cardinality")
return types.Tuple{}, err
// for deletes (cardinality < 1): |ok| is set false
func setCardinality(val types.Tuple, card int64) (v types.Tuple, ok bool, err error) {
if card < 1 {
return types.Tuple{}, false, nil
}
return val.Set(0, types.Uint(delta))
v, err = val.Set(0, types.Uint(card))
if err != nil {
return v, false, err
}
return v, true, nil
}
func updateCardinality(val types.Tuple, delta int64) (v types.Tuple, err error) {
// for deletes (cardinality < 1): |ok| is set false
func updateCardinality(val types.Tuple, delta int64) (v types.Tuple, ok bool, err error) {
c, err := val.Get(0)
if err != nil {
return v, err
return v, false, err
}
card := int64(c.(types.Uint)) + delta // lossy
if card < 0 {
card = 0
if card < 1 {
return types.Tuple{}, false, nil
}
return val.Set(0, types.Uint(card))
v, err = val.Set(0, types.Uint(card))
if err != nil {
return v, false, err
}
return v, true, nil
}

View File

@@ -44,7 +44,7 @@ func (rdr *keylessTableReader) GetSchema() schema.Schema {
// ReadSqlRow implements the SqlTableReader interface.
func (rdr *keylessTableReader) ReadRow(ctx context.Context) (row.Row, error) {
if rdr.remainingCopies == 0 {
if rdr.remainingCopies <= 0 {
key, val, err := rdr.iter.Next(ctx)
if err != nil {
return nil, err
@@ -56,6 +56,9 @@ func (rdr *keylessTableReader) ReadRow(ctx context.Context) (row.Row, error) {
if err != nil {
return nil, err
}
if rdr.remainingCopies == 0 {
return nil, row.ErrZeroCardinality
}
}
rdr.remainingCopies -= 1