From 010b7da90dc1d88d3ae03255b7a9317de2206e93 Mon Sep 17 00:00:00 2001
From: Nick Tobey <nick@dolthub.com>
Date: Mon, 21 Oct 2024 17:04:56 -0700
Subject: [PATCH] Replace ConvertToSecondaryKeylessIndex with AddHashToSchema

---
 go/cmd/dolt/commands/schcmds/import.go           |  2 +-
 .../doltcore/doltdb/commit_hooks_test.go         |  2 +-
 go/libraries/doltcore/doltdb/doltdb_test.go      |  4 ++--
 go/libraries/doltcore/doltdb/durable/index.go    | 16 ++++++++++------
 go/libraries/doltcore/doltdb/durable/table.go    |  2 +-
 go/libraries/doltcore/doltdb/root_val.go         |  2 +-
 go/libraries/doltcore/doltdb/table.go            |  2 +-
 .../doltcore/dtestutils/testcommands/multienv.go |  2 +-
 go/libraries/doltcore/merge/fulltext_rebuild.go  |  2 +-
 .../doltcore/merge/merge_prolly_indexes.go       |  3 ---
 go/libraries/doltcore/merge/merge_prolly_rows.go |  3 ---
 .../doltcore/merge/mutable_secondary_index.go    | 13 ++++++-------
 go/libraries/doltcore/merge/violations_fk.go     |  8 ++++----
 go/libraries/doltcore/sqle/alterschema_test.go   |  2 +-
 go/libraries/doltcore/sqle/common_test.go        |  2 +-
 .../sqle/dtables/conflicts_tables_prolly.go      |  2 +-
 go/libraries/doltcore/sqle/dtables/diff_table.go |  2 +-
 .../doltcore/sqle/enginetest/validation.go       |  1 -
 go/libraries/doltcore/sqle/tables.go             |  6 +++---
 go/libraries/doltcore/sqle/temp_table.go         |  2 +-
 go/libraries/doltcore/sqle/testutil.go           |  2 +-
 .../doltcore/sqle/writer/prolly_table_writer.go  |  2 --
 .../editor/creation/external_build_index.go      |  5 +----
 .../doltcore/table/editor/creation/index.go      |  5 +----
 .../table/untyped/sqlexport/sqlwriter_test.go    |  2 +-
 go/store/datas/statistics.go                     |  2 +-
 go/store/prolly/shim/shim.go                     |  5 ++++-
 go/store/prolly/tuple_map.go                     | 13 ++-----------
 28 files changed, 48 insertions(+), 66 deletions(-)

diff --git a/go/cmd/dolt/commands/schcmds/import.go b/go/cmd/dolt/commands/schcmds/import.go
index 3937bc41d7f..c4cb9da28f7 100644
--- a/go/cmd/dolt/commands/schcmds/import.go
+++ b/go/cmd/dolt/commands/schcmds/import.go
@@ -330,7 +330,7 @@ func putEmptyTableWithSchema(ctx context.Context, tblName string, root doltdb.Ro
 		return nil, errhand.BuildDError("error: failed to get table.").AddCause(err).Build()
 	}
 
-	empty, err := durable.NewEmptyIndex(ctx, root.VRW(), root.NodeStore(), sch)
+	empty, err := durable.NewEmptyIndex(ctx, root.VRW(), root.NodeStore(), sch, false)
 	if err != nil {
 		return nil, errhand.BuildDError("error: failed to get table.").AddCause(err).Build()
 	}
diff --git a/go/libraries/doltcore/doltdb/commit_hooks_test.go b/go/libraries/doltcore/doltdb/commit_hooks_test.go
index 961e40945a7..e94894acd3c 100644
--- a/go/libraries/doltcore/doltdb/commit_hooks_test.go
+++ b/go/libraries/doltcore/doltdb/commit_hooks_test.go
@@ -251,7 +251,7 @@ func TestAsyncPushOnWrite(t *testing.T) {
 			assert.NoError(t, err)
 
 			tSchema := createTestSchema(t)
-			rowData, err := durable.NewEmptyIndex(ctx, ddb.vrw, ddb.ns, tSchema)
+			rowData, err := durable.NewEmptyIndex(ctx, ddb.vrw, ddb.ns, tSchema, false)
 			require.NoError(t, err)
 			tbl, err := CreateTestTable(ddb.vrw, ddb.ns, tSchema, rowData)
 			require.NoError(t, err)
diff --git a/go/libraries/doltcore/doltdb/doltdb_test.go b/go/libraries/doltcore/doltdb/doltdb_test.go
index 4992c9a8b9e..5332ac8f987 100644
--- a/go/libraries/doltcore/doltdb/doltdb_test.go
+++ b/go/libraries/doltcore/doltdb/doltdb_test.go
@@ -83,7 +83,7 @@ func CreateTestTable(vrw types.ValueReadWriter, ns tree.NodeStore, tSchema schem
 
 func createTestRowData(t *testing.T, vrw types.ValueReadWriter, ns tree.NodeStore, sch schema.Schema) durable.Index {
 	if types.Format_Default == types.Format_DOLT {
-		idx, err := durable.NewEmptyIndex(context.Background(), vrw, ns, sch)
+		idx, err := durable.NewEmptyIndex(context.Background(), vrw, ns, sch, false)
 		require.NoError(t, err)
 		return idx
 	}
@@ -303,7 +303,7 @@ func TestLDNoms(t *testing.T) {
 
 		ctx := context.Background()
 		tSchema := createTestSchema(t)
-		rowData, err := durable.NewEmptyIndex(ctx, ddb.vrw, ddb.ns, tSchema)
+		rowData, err := durable.NewEmptyIndex(ctx, ddb.vrw, ddb.ns, tSchema, false)
 		if err != nil {
 			t.Fatal("Failed to create new empty index")
 		}
diff --git a/go/libraries/doltcore/doltdb/durable/index.go b/go/libraries/doltcore/doltdb/durable/index.go
index 9103563d38c..9897bf893be 100644
--- a/go/libraries/doltcore/doltdb/durable/index.go
+++ b/go/libraries/doltcore/doltdb/durable/index.go
@@ -96,11 +96,12 @@ func RefFromIndex(ctx context.Context, vrw types.ValueReadWriter, idx Index) (ty
 }
 
 // indexFromRef reads the types.Ref from storage and returns the Index it points to.
+// This is only used by noms format and can be removed.
 func indexFromRef(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, sch schema.Schema, r types.Ref) (Index, error) {
-	return indexFromAddr(ctx, vrw, ns, sch, r.TargetHash())
+	return indexFromAddr(ctx, vrw, ns, sch, r.TargetHash(), false)
 }
 
-func indexFromAddr(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, sch schema.Schema, addr hash.Hash) (Index, error) {
+func indexFromAddr(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, sch schema.Schema, addr hash.Hash, isKeylessTable bool) (Index, error) {
 	v, err := vrw.ReadValue(ctx, addr)
 	if err != nil {
 		return nil, err
@@ -111,7 +112,7 @@ func indexFromAddr(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeS
 		return IndexFromNomsMap(v.(types.Map), vrw, ns), nil
 
 	case types.Format_DOLT:
-		pm, err := shim.MapFromValue(v, sch, ns)
+		pm, err := shim.MapFromValue(v, sch, ns, isKeylessTable)
 		if err != nil {
 			return nil, err
 		}
@@ -123,7 +124,7 @@ func indexFromAddr(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeS
 }
 
 // NewEmptyIndex returns an index with no rows.
-func NewEmptyIndex(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, sch schema.Schema) (Index, error) {
+func NewEmptyIndex(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, sch schema.Schema, isKeylessSecondary bool) (Index, error) {
 	switch vrw.Format() {
 	case types.Format_LD_1:
 		m, err := types.NewMap(ctx, vrw)
@@ -134,6 +135,9 @@ func NewEmptyIndex(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeS
 
 	case types.Format_DOLT:
 		kd, vd := sch.GetMapDescriptors()
+		if isKeylessSecondary {
+			kd = prolly.AddHashToSchema(kd)
+		}
 		m, err := prolly.NewMapFromTuples(ctx, ns, kd, vd)
 		if err != nil {
 			return nil, err
@@ -370,7 +374,7 @@ func NewIndexSetWithEmptyIndexes(ctx context.Context, vrw types.ValueReadWriter,
 		return nil, err
 	}
 	for _, index := range sch.Indexes().AllIndexes() {
-		empty, err := NewEmptyIndex(ctx, vrw, ns, index.Schema())
+		empty, err := NewEmptyIndex(ctx, vrw, ns, index.Schema(), false)
 		if err != nil {
 			return nil, err
 		}
@@ -507,7 +511,7 @@ func (is doltDevIndexSet) GetIndex(ctx context.Context, tableSch schema.Schema,
 	if idxSch == nil {
 		idxSch = idx.Schema()
 	}
-	return indexFromAddr(ctx, is.vrw, is.ns, idxSch, foundAddr)
+	return indexFromAddr(ctx, is.vrw, is.ns, idxSch, foundAddr, schema.IsKeyless(tableSch))
 }
 
 func (is doltDevIndexSet) PutIndex(ctx context.Context, name string, idx Index) (IndexSet, error) {
diff --git a/go/libraries/doltcore/doltdb/durable/table.go b/go/libraries/doltcore/doltdb/durable/table.go
index f2792b51ef3..3d1637980f3 100644
--- a/go/libraries/doltcore/doltdb/durable/table.go
+++ b/go/libraries/doltcore/doltdb/durable/table.go
@@ -850,7 +850,7 @@ func (t doltDevTable) GetTableRows(ctx context.Context) (Index, error) {
 	if err != nil {
 		return nil, err
 	}
-	m, err := shim.MapFromValue(types.SerialMessage(rowbytes), sch, t.ns)
+	m, err := shim.MapFromValue(types.SerialMessage(rowbytes), sch, t.ns, false)
 	if err != nil {
 		return nil, err
 	}
diff --git a/go/libraries/doltcore/doltdb/root_val.go b/go/libraries/doltcore/doltdb/root_val.go
index 261256d147e..bbc9e186721 100644
--- a/go/libraries/doltcore/doltdb/root_val.go
+++ b/go/libraries/doltcore/doltdb/root_val.go
@@ -887,7 +887,7 @@ func (root *rootValue) putTable(ctx context.Context, tName TableName, ref types.
 func CreateEmptyTable(ctx context.Context, root RootValue, tName TableName, sch schema.Schema) (RootValue, error) {
 	ns := root.NodeStore()
 	vrw := root.VRW()
-	empty, err := durable.NewEmptyIndex(ctx, vrw, ns, sch)
+	empty, err := durable.NewEmptyIndex(ctx, vrw, ns, sch, false)
 	if err != nil {
 		return nil, err
 	}
diff --git a/go/libraries/doltcore/doltdb/table.go b/go/libraries/doltcore/doltdb/table.go
index db89ff8a237..bafce8b00f3 100644
--- a/go/libraries/doltcore/doltdb/table.go
+++ b/go/libraries/doltcore/doltdb/table.go
@@ -92,7 +92,7 @@ func NewTableFromDurable(table durable.Table) *Table {
 }
 
 func NewEmptyTable(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, sch schema.Schema) (*Table, error) {
-	rows, err := durable.NewEmptyIndex(ctx, vrw, ns, sch)
+	rows, err := durable.NewEmptyIndex(ctx, vrw, ns, sch, false)
 	if err != nil {
 		return nil, err
 	}
diff --git a/go/libraries/doltcore/dtestutils/testcommands/multienv.go b/go/libraries/doltcore/dtestutils/testcommands/multienv.go
index edc6fc1785d..93fef0de294 100644
--- a/go/libraries/doltcore/dtestutils/testcommands/multienv.go
+++ b/go/libraries/doltcore/dtestutils/testcommands/multienv.go
@@ -390,7 +390,7 @@ func createTestTable(dEnv *env.DoltEnv, tableName string, sch schema.Schema) err
 	vrw := dEnv.DoltDB.ValueReadWriter()
 	ns := dEnv.DoltDB.NodeStore()
 
-	idx, err := durable.NewEmptyIndex(ctx, vrw, ns, sch)
+	idx, err := durable.NewEmptyIndex(ctx, vrw, ns, sch, false)
 	if err != nil {
 		return err
 	}
diff --git a/go/libraries/doltcore/merge/fulltext_rebuild.go b/go/libraries/doltcore/merge/fulltext_rebuild.go
index 294772f9028..e439e663f1e 100644
--- a/go/libraries/doltcore/merge/fulltext_rebuild.go
+++ b/go/libraries/doltcore/merge/fulltext_rebuild.go
@@ -330,7 +330,7 @@ func purgeFulltextTableData(ctx *sql.Context, root doltdb.RootValue, tableNames
 		if err != nil {
 			return nil, err
 		}
-		rows, err := durable.NewEmptyIndex(ctx, tbl.ValueReadWriter(), tbl.NodeStore(), sch)
+		rows, err := durable.NewEmptyIndex(ctx, tbl.ValueReadWriter(), tbl.NodeStore(), sch, false)
 		if err != nil {
 			return nil, err
 		}
diff --git a/go/libraries/doltcore/merge/merge_prolly_indexes.go b/go/libraries/doltcore/merge/merge_prolly_indexes.go
index 120e9292a51..2b9e488776d 100644
--- a/go/libraries/doltcore/merge/merge_prolly_indexes.go
+++ b/go/libraries/doltcore/merge/merge_prolly_indexes.go
@@ -60,9 +60,6 @@ func mergeProllySecondaryIndexes(
 				return prolly.Map{}, false, err
 			}
 			m := durable.ProllyMapFromIndex(idx)
-			if schema.IsKeyless(sch) {
-				m = prolly.ConvertToSecondaryKeylessIndex(m)
-			}
 			return m, true, nil
 		}
 		return prolly.Map{}, false, nil
diff --git a/go/libraries/doltcore/merge/merge_prolly_rows.go b/go/libraries/doltcore/merge/merge_prolly_rows.go
index 536b87eb6a8..82b69b70295 100644
--- a/go/libraries/doltcore/merge/merge_prolly_rows.go
+++ b/go/libraries/doltcore/merge/merge_prolly_rows.go
@@ -715,9 +715,6 @@ func newUniqIndex(ctx *sql.Context, sch schema.Schema, tableName string, def sch
 		return uniqIndex{}, err
 	}
 
-	if schema.IsKeyless(sch) { // todo(andy): sad panda
-		secondary = prolly.ConvertToSecondaryKeylessIndex(secondary)
-	}
 	p := clustered.Pool()
 
 	prefixDesc := secondary.KeyDesc().PrefixDesc(def.Count())
diff --git a/go/libraries/doltcore/merge/mutable_secondary_index.go b/go/libraries/doltcore/merge/mutable_secondary_index.go
index 20ae4478ae2..f91e1ee16b3 100644
--- a/go/libraries/doltcore/merge/mutable_secondary_index.go
+++ b/go/libraries/doltcore/merge/mutable_secondary_index.go
@@ -35,9 +35,6 @@ func GetMutableSecondaryIdxs(ctx *sql.Context, ourSch, sch schema.Schema, tableN
 			return nil, err
 		}
 		m := durable.ProllyMapFromIndex(idx)
-		if schema.IsKeyless(sch) {
-			m = prolly.ConvertToSecondaryKeylessIndex(m)
-		}
 		mods[i], err = NewMutableSecondaryIdx(ctx, m, ourSch, sch, tableName, index)
 		if err != nil {
 			return nil, err
@@ -76,7 +73,12 @@ func GetMutableSecondaryIdxsWithPending(ctx *sql.Context, ourSch, sch schema.Sch
 		// TODO: This isn't technically required, but correctly handling updating secondary indexes when only some
 		// of the table's rows have been updated is difficult to get right.
 		// Dropping the index is potentially slower but guaranteed to be correct.
-		if !m.KeyDesc().Equals(index.Schema().GetKeyDescriptorWithNoConversion()) {
+		idxKeyDesc := m.KeyDesc()
+		if schema.IsKeyless(sch) {
+			idxKeyDesc = idxKeyDesc.PrefixDesc(idxKeyDesc.Count() - 1)
+		}
+
+		if !idxKeyDesc.Equals(index.Schema().GetKeyDescriptorWithNoConversion()) {
 			continue
 		}
 
@@ -84,9 +86,6 @@ func GetMutableSecondaryIdxsWithPending(ctx *sql.Context, ourSch, sch schema.Sch
 			continue
 		}
 
-		if schema.IsKeyless(sch) {
-			m = prolly.ConvertToSecondaryKeylessIndex(m)
-		}
 		newMutableSecondaryIdx, err := NewMutableSecondaryIdx(ctx, m, ourSch, sch, tableName, index)
 		if err != nil {
 			return nil, err
diff --git a/go/libraries/doltcore/merge/violations_fk.go b/go/libraries/doltcore/merge/violations_fk.go
index 687084d57d0..43afa9c6864 100644
--- a/go/libraries/doltcore/merge/violations_fk.go
+++ b/go/libraries/doltcore/merge/violations_fk.go
@@ -109,7 +109,7 @@ func GetForeignKeyViolations(ctx context.Context, newRoot, baseRoot doltdb.RootV
 				return err
 			}
 			// Parent does not exist in the ancestor so we use an empty map
-			emptyIdx, err := durable.NewEmptyIndex(ctx, postParent.Table.ValueReadWriter(), postParent.Table.NodeStore(), postParent.Schema)
+			emptyIdx, err := durable.NewEmptyIndex(ctx, postParent.Table.ValueReadWriter(), postParent.Table.NodeStore(), postParent.Schema, false)
 			if err != nil {
 				return err
 			}
@@ -131,7 +131,7 @@ func GetForeignKeyViolations(ctx context.Context, newRoot, baseRoot doltdb.RootV
 				return err
 			}
 			// Child does not exist in the ancestor so we use an empty map
-			emptyIdx, err := durable.NewEmptyIndex(ctx, postChild.Table.ValueReadWriter(), postChild.Table.NodeStore(), postChild.Schema)
+			emptyIdx, err := durable.NewEmptyIndex(ctx, postChild.Table.ValueReadWriter(), postChild.Table.NodeStore(), postChild.Schema, false)
 			if err != nil {
 				return err
 			}
@@ -372,7 +372,7 @@ func parentFkConstraintViolations(
 	}
 	var idx durable.Index
 	if empty {
-		idx, err = durable.NewEmptyIndex(ctx, postChild.Table.ValueReadWriter(), postParent.Table.NodeStore(), postParent.Schema)
+		idx, err = durable.NewEmptyIndex(ctx, postChild.Table.ValueReadWriter(), postParent.Table.NodeStore(), postParent.Schema, false)
 		if err != nil {
 			return err
 		}
@@ -407,7 +407,7 @@ func childFkConstraintViolations(
 	}
 	var idx durable.Index
 	if empty {
-		idx, err = durable.NewEmptyIndex(ctx, postChild.Table.ValueReadWriter(), postChild.Table.NodeStore(), postChild.Schema)
+		idx, err = durable.NewEmptyIndex(ctx, postChild.Table.ValueReadWriter(), postChild.Table.NodeStore(), postChild.Schema, false)
 		if err != nil {
 			return err
 		}
diff --git a/go/libraries/doltcore/sqle/alterschema_test.go b/go/libraries/doltcore/sqle/alterschema_test.go
index 3aace41aa1e..f9737116ae6 100644
--- a/go/libraries/doltcore/sqle/alterschema_test.go
+++ b/go/libraries/doltcore/sqle/alterschema_test.go
@@ -269,7 +269,7 @@ func makePeopleTable(ctx context.Context, dEnv *env.DoltEnv) (*env.DoltEnv, erro
 	if err != nil {
 		return nil, err
 	}
-	rows, err := durable.NewEmptyIndex(ctx, root.VRW(), root.NodeStore(), sch)
+	rows, err := durable.NewEmptyIndex(ctx, root.VRW(), root.NodeStore(), sch, false)
 	if err != nil {
 		return nil, err
 	}
diff --git a/go/libraries/doltcore/sqle/common_test.go b/go/libraries/doltcore/sqle/common_test.go
index 894ba1ece3e..1c5e3a45137 100644
--- a/go/libraries/doltcore/sqle/common_test.go
+++ b/go/libraries/doltcore/sqle/common_test.go
@@ -181,7 +181,7 @@ func CreateTestTable(t *testing.T, dEnv *env.DoltEnv, tableName string, sch sche
 	vrw := dEnv.DoltDB.ValueReadWriter()
 	ns := dEnv.DoltDB.NodeStore()
 
-	rows, err := durable.NewEmptyIndex(ctx, vrw, ns, sch)
+	rows, err := durable.NewEmptyIndex(ctx, vrw, ns, sch, false)
 	require.NoError(t, err)
 	tbl, err := doltdb.NewTable(ctx, vrw, ns, sch, rows, nil, nil)
 	require.NoError(t, err)
diff --git a/go/libraries/doltcore/sqle/dtables/conflicts_tables_prolly.go b/go/libraries/doltcore/sqle/dtables/conflicts_tables_prolly.go
index e25320ae955..f73ac6d4a65 100644
--- a/go/libraries/doltcore/sqle/dtables/conflicts_tables_prolly.go
+++ b/go/libraries/doltcore/sqle/dtables/conflicts_tables_prolly.go
@@ -416,7 +416,7 @@ func (itr *prollyConflictRowIter) loadTableMaps(ctx *sql.Context, baseHash, thei
 
 		var idx durable.Index
 		if !ok {
-			idx, err = durable.NewEmptyIndex(ctx, itr.vrw, itr.ns, itr.ourSch)
+			idx, err = durable.NewEmptyIndex(ctx, itr.vrw, itr.ns, itr.ourSch, false)
 		} else {
 			idx, err = baseTbl.GetRowData(ctx)
 		}
diff --git a/go/libraries/doltcore/sqle/dtables/diff_table.go b/go/libraries/doltcore/sqle/dtables/diff_table.go
index f20e95f71a5..ec4a93bcc69 100644
--- a/go/libraries/doltcore/sqle/dtables/diff_table.go
+++ b/go/libraries/doltcore/sqle/dtables/diff_table.go
@@ -595,7 +595,7 @@ func tableData(ctx *sql.Context, tbl *doltdb.Table, ddb *doltdb.DoltDB) (durable
 	var err error
 
 	if tbl == nil {
-		data, err = durable.NewEmptyIndex(ctx, ddb.ValueReadWriter(), ddb.NodeStore(), schema.EmptySchema)
+		data, err = durable.NewEmptyIndex(ctx, ddb.ValueReadWriter(), ddb.NodeStore(), schema.EmptySchema, false)
 		if err != nil {
 			return nil, nil, err
 		}
diff --git a/go/libraries/doltcore/sqle/enginetest/validation.go b/go/libraries/doltcore/sqle/enginetest/validation.go
index 9b92ad0e39d..6521743f292 100644
--- a/go/libraries/doltcore/sqle/enginetest/validation.go
+++ b/go/libraries/doltcore/sqle/enginetest/validation.go
@@ -175,7 +175,6 @@ func validateKeylessIndex(ctx context.Context, sch schema.Schema, def schema.Ind
 		return nil
 	}
 
-	secondary = prolly.ConvertToSecondaryKeylessIndex(secondary)
 	idxDesc, _ := secondary.Descriptors()
 	builder := val.NewTupleBuilder(idxDesc)
 	mapping := ordinalMappingsForSecondaryIndex(sch, def)
diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go
index e94573dcb9d..9038c7552f4 100644
--- a/go/libraries/doltcore/sqle/tables.go
+++ b/go/libraries/doltcore/sqle/tables.go
@@ -932,7 +932,7 @@ func emptyFulltextTable(
 		return nil, nil, err
 	}
 
-	empty, err := durable.NewEmptyIndex(ctx, dt.ValueReadWriter(), dt.NodeStore(), doltSchema)
+	empty, err := durable.NewEmptyIndex(ctx, dt.ValueReadWriter(), dt.NodeStore(), doltSchema, false)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -1036,7 +1036,7 @@ func (t *WritableDoltTable) truncate(
 	}
 
 	for _, idx := range sch.Indexes().AllIndexes() {
-		empty, err := durable.NewEmptyIndex(ctx, table.ValueReadWriter(), table.NodeStore(), idx.Schema())
+		empty, err := durable.NewEmptyIndex(ctx, table.ValueReadWriter(), table.NodeStore(), idx.Schema(), false)
 		if err != nil {
 			return nil, err
 		}
@@ -1060,7 +1060,7 @@ func (t *WritableDoltTable) truncate(
 		}
 	}
 
-	empty, err := durable.NewEmptyIndex(ctx, table.ValueReadWriter(), table.NodeStore(), sch)
+	empty, err := durable.NewEmptyIndex(ctx, table.ValueReadWriter(), table.NodeStore(), sch, false)
 	if err != nil {
 		return nil, err
 	}
diff --git a/go/libraries/doltcore/sqle/temp_table.go b/go/libraries/doltcore/sqle/temp_table.go
index 13f9d025d19..daabc958452 100644
--- a/go/libraries/doltcore/sqle/temp_table.go
+++ b/go/libraries/doltcore/sqle/temp_table.go
@@ -109,7 +109,7 @@ func NewTempTable(
 	vrw := ddb.ValueReadWriter()
 	ns := ddb.NodeStore()
 
-	idx, err := durable.NewEmptyIndex(ctx, vrw, ns, sch)
+	idx, err := durable.NewEmptyIndex(ctx, vrw, ns, sch, false)
 	if err != nil {
 		return nil, err
 	}
diff --git a/go/libraries/doltcore/sqle/testutil.go b/go/libraries/doltcore/sqle/testutil.go
index 580b7117355..aa6276acbf2 100644
--- a/go/libraries/doltcore/sqle/testutil.go
+++ b/go/libraries/doltcore/sqle/testutil.go
@@ -425,7 +425,7 @@ func CreateEmptyTestTable(dEnv *env.DoltEnv, tableName string, sch schema.Schema
 	vrw := dEnv.DoltDB.ValueReadWriter()
 	ns := dEnv.DoltDB.NodeStore()
 
-	rows, err := durable.NewEmptyIndex(ctx, vrw, ns, sch)
+	rows, err := durable.NewEmptyIndex(ctx, vrw, ns, sch, false)
 	if err != nil {
 		return err
 	}
diff --git a/go/libraries/doltcore/sqle/writer/prolly_table_writer.go b/go/libraries/doltcore/sqle/writer/prolly_table_writer.go
index 380a82c4c9a..30c8ddf15ca 100644
--- a/go/libraries/doltcore/sqle/writer/prolly_table_writer.go
+++ b/go/libraries/doltcore/sqle/writer/prolly_table_writer.go
@@ -26,7 +26,6 @@ import (
 	"github.com/dolthub/dolt/go/libraries/doltcore/sqle/globalstate"
 	"github.com/dolthub/dolt/go/libraries/doltcore/sqle/index"
 	"github.com/dolthub/dolt/go/store/pool"
-	"github.com/dolthub/dolt/go/store/prolly"
 	"github.com/dolthub/dolt/go/store/val"
 )
 
@@ -118,7 +117,6 @@ func getSecondaryKeylessProllyWriters(ctx context.Context, t *doltdb.Table, schS
 			return nil, err
 		}
 		m := durable.ProllyMapFromIndex(idxRows)
-		m = prolly.ConvertToSecondaryKeylessIndex(m)
 
 		keyDesc, _ := m.Descriptors()
 
diff --git a/go/libraries/doltcore/table/editor/creation/external_build_index.go b/go/libraries/doltcore/table/editor/creation/external_build_index.go
index cd7613a78ba..1b7f2e20846 100644
--- a/go/libraries/doltcore/table/editor/creation/external_build_index.go
+++ b/go/libraries/doltcore/table/editor/creation/external_build_index.go
@@ -41,14 +41,11 @@ const (
 // single prolly tree materialization by presorting the index keys in an
 // intermediate file format.
 func BuildProllyIndexExternal(ctx *sql.Context, vrw types.ValueReadWriter, ns tree.NodeStore, sch schema.Schema, tableName string, idx schema.Index, primary prolly.Map, uniqCb DupEntryCb) (durable.Index, error) {
-	empty, err := durable.NewEmptyIndex(ctx, vrw, ns, idx.Schema())
+	empty, err := durable.NewEmptyIndex(ctx, vrw, ns, idx.Schema(), schema.IsKeyless(sch))
 	if err != nil {
 		return nil, err
 	}
 	secondary := durable.ProllyMapFromIndex(empty)
-	if schema.IsKeyless(sch) {
-		secondary = prolly.ConvertToSecondaryKeylessIndex(secondary)
-	}
 
 	iter, err := primary.IterAll(ctx)
 	if err != nil {
diff --git a/go/libraries/doltcore/table/editor/creation/index.go b/go/libraries/doltcore/table/editor/creation/index.go
index 033b61606aa..7c9ea3a6dc2 100644
--- a/go/libraries/doltcore/table/editor/creation/index.go
+++ b/go/libraries/doltcore/table/editor/creation/index.go
@@ -214,14 +214,11 @@ func BuildUniqueProllyIndex(
 	primary prolly.Map,
 	cb DupEntryCb,
 ) (durable.Index, error) {
-	empty, err := durable.NewEmptyIndex(ctx, vrw, ns, idx.Schema())
+	empty, err := durable.NewEmptyIndex(ctx, vrw, ns, idx.Schema(), schema.IsKeyless(sch))
 	if err != nil {
 		return nil, err
 	}
 	secondary := durable.ProllyMapFromIndex(empty)
-	if schema.IsKeyless(sch) {
-		secondary = prolly.ConvertToSecondaryKeylessIndex(secondary)
-	}
 
 	iter, err := primary.IterAll(ctx)
 	if err != nil {
diff --git a/go/libraries/doltcore/table/untyped/sqlexport/sqlwriter_test.go b/go/libraries/doltcore/table/untyped/sqlexport/sqlwriter_test.go
index 9743e6ea7f9..0332d7576ef 100644
--- a/go/libraries/doltcore/table/untyped/sqlexport/sqlwriter_test.go
+++ b/go/libraries/doltcore/table/untyped/sqlexport/sqlwriter_test.go
@@ -92,7 +92,7 @@ func TestEndToEnd(t *testing.T) {
 			root, err := dEnv.WorkingRoot(ctx)
 			require.NoError(t, err)
 
-			empty, err := durable.NewEmptyIndex(ctx, root.VRW(), root.NodeStore(), tt.sch)
+			empty, err := durable.NewEmptyIndex(ctx, root.VRW(), root.NodeStore(), tt.sch, false)
 			require.NoError(t, err)
 
 			indexes, err := durable.NewIndexSet(ctx, root.VRW(), root.NodeStore())
diff --git a/go/store/datas/statistics.go b/go/store/datas/statistics.go
index 01ef00ca5e3..1de1894f8a0 100644
--- a/go/store/datas/statistics.go
+++ b/go/store/datas/statistics.go
@@ -120,7 +120,7 @@ func parse_Statistics(ctx context.Context, bs []byte, ns tree.NodeStore, vr type
 		return nil, err
 	}
 
-	m, err := shim.MapFromValue(value, schema.StatsTableDoltSchema, ns)
+	m, err := shim.MapFromValue(value, schema.StatsTableDoltSchema, ns, false)
 	if err != nil {
 		return nil, err
 	}
diff --git a/go/store/prolly/shim/shim.go b/go/store/prolly/shim/shim.go
index 937084f725f..6ddc47d9cd6 100644
--- a/go/store/prolly/shim/shim.go
+++ b/go/store/prolly/shim/shim.go
@@ -34,12 +34,15 @@ func ValueFromArtifactMap(m prolly.ArtifactMap) types.Value {
 	return tree.ValueFromNode(m.Node())
 }
 
-func MapFromValue(v types.Value, sch schema.Schema, ns tree.NodeStore) (prolly.Map, error) {
+func MapFromValue(v types.Value, sch schema.Schema, ns tree.NodeStore, isKeylessSecondary bool) (prolly.Map, error) {
 	root, err := NodeFromValue(v)
 	if err != nil {
 		return prolly.Map{}, err
 	}
 	kd := sch.GetKeyDescriptor()
+	if isKeylessSecondary {
+		kd = prolly.AddHashToSchema(kd)
+	}
 	vd := sch.GetValueDescriptor()
 	return prolly.NewMap(root, ns, kd, vd), nil
 }
diff --git a/go/store/prolly/tuple_map.go b/go/store/prolly/tuple_map.go
index 38bb73a5b9a..bdca03c622c 100644
--- a/go/store/prolly/tuple_map.go
+++ b/go/store/prolly/tuple_map.go
@@ -441,24 +441,15 @@ func DebugFormat(ctx context.Context, m Map) (string, error) {
 	return sb.String(), nil
 }
 
-// ConvertToSecondaryKeylessIndex converts the given map to a keyless index map.
-func ConvertToSecondaryKeylessIndex(m Map) Map {
-	keyDesc, valDesc := m.Descriptors()
+func AddHashToSchema(keyDesc val.TupleDesc) val.TupleDesc {
 	newTypes := make([]val.Type, len(keyDesc.Types)+1)
 	handlers := make([]val.TupleTypeHandler, len(keyDesc.Types)+1)
 	copy(newTypes, keyDesc.Types)
 	copy(handlers, keyDesc.Handlers)
 	newTypes[len(newTypes)-1] = val.Type{Enc: val.Hash128Enc}
 	handlers[len(handlers)-1] = nil
-	newKeyDesc := val.NewTupleDescriptorWithArgs(val.TupleDescriptorArgs{
+	return val.NewTupleDescriptorWithArgs(val.TupleDescriptorArgs{
 		Comparator: keyDesc.Comparator(),
 		Handlers:   handlers,
 	}, newTypes...)
-	newTuples := m.tuples
-	newTuples.Order = newKeyDesc
-	return Map{
-		tuples:  newTuples,
-		keyDesc: newKeyDesc,
-		valDesc: valDesc,
-	}
 }