From e13bbf93beb0e76b93c80487489ad3b99ddfd99e Mon Sep 17 00:00:00 2001 From: Andy Arthur Date: Tue, 30 Aug 2022 13:51:52 -0700 Subject: [PATCH] fix setup for cross-index key mapping in prollyFkIndexer --- .../sqle/enginetest/dolt_engine_test.go | 2 + .../doltcore/sqle/enginetest/dolt_queries.go | 2 +- .../doltcore/sqle/writer/prolly_fk_indexer.go | 54 +++++++++++-------- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go index 9dbe1ae9b5..62fea1b16d 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_engine_test.go @@ -108,6 +108,7 @@ func TestSingleQuery(t *testing.T) { // Convenience test for debugging a single query. Unskip and set to the desired query. func TestSingleScript(t *testing.T) { + t.Skip() var scripts = []queries.ScriptTest{ { Name: "Nautobot FOREIGN KEY panic repro", @@ -148,6 +149,7 @@ func TestSingleScript(t *testing.T) { { Query: "INSERT INTO `users_token` (`id`, `user_id`, `created`, `expires`, `key`, `write_enabled`, `description`) " + "VALUES ('acc2e157db2845a79221cc654b1dcecc', '1056443cc03446c592fa4c06bb06a1a6', '2022-08-30 18:27:21.948487', NULL, '0123456789abcdef0123456789abcdef01234567', 1, '');", + Expected: []sql.Row{{sql.OkResult{RowsAffected: 0x1, InsertID: 0x0}}}, }, }, }, diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go index 5b742f2a95..c0a5f278a3 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries.go @@ -691,13 +691,13 @@ var DoltScripts = []queries.ScriptTest{ " CONSTRAINT `users_token_user_id_af964690_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`)" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;", "INSERT INTO `auth_user` (`password`,`last_login`,`is_superuser`,`username`,`first_name`,`last_name`,`email`,`is_staff`,`is_active`,`date_joined`,`id`,`config_data`)" + - "VALUES ('pbkdf2_sha256$216000$KRpZeDPgwc5E$vl/2hwrmtnckaBT0A8pf63Ph+oYuCHYI7qozMTZihTo=',NULL,1,'admin','','','admin@example.com',1,1,'2022-08-30 18:27:21.810049','1056443cc03446c592fa4c06bb06a1a6','{}');", "INSERT INTO `auth_user` (`password`,`last_login`,`is_superuser`,`username`,`first_name`,`last_name`,`email`,`is_staff`,`is_active`,`date_joined`,`id`,`config_data`)" + "VALUES ('pbkdf2_sha256$216000$KRpZeDPgwc5E$vl/2hwrmtnckaBT0A8pf63Ph+oYuCHYI7qozMTZihTo=',NULL,1,'admin','','','admin@example.com',1,1,'2022-08-30 18:27:21.810049','1056443cc03446c592fa4c06bb06a1a6','{}');", }, Assertions: []queries.ScriptTestAssertion{ { Query: "INSERT INTO `users_token` (`id`, `user_id`, `created`, `expires`, `key`, `write_enabled`, `description`) " + "VALUES ('acc2e157db2845a79221cc654b1dcecc', '1056443cc03446c592fa4c06bb06a1a6', '2022-08-30 18:27:21.948487', NULL, '0123456789abcdef0123456789abcdef01234567', 1, '');", + Expected: []sql.Row{{sql.OkResult{RowsAffected: 0x1, InsertID: 0x0}}}, }, }, }, diff --git a/go/libraries/doltcore/sqle/writer/prolly_fk_indexer.go b/go/libraries/doltcore/sqle/writer/prolly_fk_indexer.go index cc14bb9a4d..fbef8e6a5d 100644 --- a/go/libraries/doltcore/sqle/writer/prolly_fk_indexer.go +++ b/go/libraries/doltcore/sqle/writer/prolly_fk_indexer.go @@ -79,7 +79,7 @@ func (n *prollyFkIndexer) PartitionRows(ctx *sql.Context, _ sql.Partition) (sql. } pkToIdxMap := make(val.OrdinalMapping, n.writer.sch.GetPKCols().Size()) - for j, idxCol := range n.index.IndexSchema().GetAllCols().GetColumns() { + for j, idxCol := range n.index.IndexSchema().GetPKCols().GetColumns() { if i, ok := n.writer.sch.GetPKCols().TagToIdx[idxCol.Tag]; ok { pkToIdxMap[i] = j } @@ -121,41 +121,49 @@ var _ sql.RowIter = prollyFkPkRowIter{} // Next implements the interface sql.RowIter. func (iter prollyFkPkRowIter) Next(ctx *sql.Context) (sql.Row, error) { - // |rangeIter| iterates on the foreign key index of the parent table - k, _, err := iter.rangeIter.Next(ctx) - if err != nil { - return nil, err - } - if k == nil { - return nil, io.EOF - } + for { + // |rangeIter| iterates on the foreign key index of the parent table + k, _, err := iter.rangeIter.Next(ctx) + if err != nil { + return nil, err + } + if k == nil { + return nil, io.EOF + } - pkBld := iter.primary.keyBld - for pkPos, idxPos := range iter.pkToIdxMap { - pkBld.PutRaw(pkPos, k.GetField(idxPos)) - } - pkTup := pkBld.BuildPermissive(sharePool) + pkBld := iter.primary.keyBld + for pkPos, idxPos := range iter.pkToIdxMap { + pkBld.PutRaw(pkPos, k.GetField(idxPos)) + } + pkTup := pkBld.BuildPermissive(sharePool) - nextRow := make(sql.Row, len(iter.primary.keyMap)+len(iter.primary.valMap)) - err = iter.primary.mut.Get(ctx, pkTup, func(tblKey, tblVal val.Tuple) error { + var tblKey, tblVal val.Tuple + err = iter.primary.mut.Get(ctx, pkTup, func(k, v val.Tuple) error { + tblKey, tblVal = k, v + return nil + }) + if err != nil { + return nil, err + } + if tblKey == nil { + continue // referential integrity broken + } + + nextRow := make(sql.Row, len(iter.primary.keyMap)+len(iter.primary.valMap)) for from := range iter.primary.keyMap { to := iter.primary.keyMap.MapOrdinal(from) if nextRow[to], err = index.GetField(ctx, iter.primary.keyBld.Desc, from, tblKey, iter.primary.mut.NodeStore()); err != nil { - return err + return nil, err } } for from := range iter.primary.valMap { to := iter.primary.valMap.MapOrdinal(from) if nextRow[to], err = index.GetField(ctx, iter.primary.valBld.Desc, from, tblVal, iter.primary.mut.NodeStore()); err != nil { - return err + return nil, err } } - return nil - }) - if err != nil { - return nil, err + return nextRow, nil } - return nextRow, nil } // Close implements the interface sql.RowIter.