github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/sqle/schema_table_test.go (about)

     1  // Copyright 2020 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package sqle
    16  
    17  import (
    18  	"context"
    19  	"io"
    20  	"strings"
    21  	"testing"
    22  
    23  	"github.com/dolthub/go-mysql-server/sql"
    24  	gmstypes "github.com/dolthub/go-mysql-server/sql/types"
    25  	"github.com/stretchr/testify/assert"
    26  	"github.com/stretchr/testify/require"
    27  
    28  	"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
    29  	"github.com/dolthub/dolt/go/libraries/doltcore/dtestutils"
    30  	"github.com/dolthub/dolt/go/libraries/doltcore/table/editor"
    31  )
    32  
    33  func TestSchemaTableMigrationOriginal(t *testing.T) {
    34  	dEnv := dtestutils.CreateTestEnv()
    35  	tmpDir, err := dEnv.TempTableFilesDir()
    36  	require.NoError(t, err)
    37  	opts := editor.Options{Deaf: dEnv.DbEaFactory(), Tempdir: tmpDir}
    38  	db, err := NewDatabase(context.Background(), "dolt", dEnv.DbData(), opts)
    39  	require.NoError(t, err)
    40  
    41  	_, ctx, err := NewTestEngine(dEnv, context.Background(), db)
    42  	require.NoError(t, err)
    43  
    44  	err = db.createSqlTable(ctx, doltdb.SchemasTableName, "", sql.NewPrimaryKeySchema(sql.Schema{ // original schema of dolt_schemas table
    45  		{Name: doltdb.SchemasTablesTypeCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: true},
    46  		{Name: doltdb.SchemasTablesNameCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: true},
    47  		{Name: doltdb.SchemasTablesFragmentCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: false},
    48  	}), sql.Collation_Default, "")
    49  	require.NoError(t, err)
    50  
    51  	sqlTbl, found, err := db.GetTableInsensitive(ctx, doltdb.SchemasTableName)
    52  	require.NoError(t, err)
    53  	require.True(t, found)
    54  
    55  	inserter := sqlTbl.(*WritableDoltTable).Inserter(ctx)
    56  	err = inserter.Insert(ctx, sql.Row{"view", "view1", "SELECT v1 FROM test;"})
    57  	require.NoError(t, err)
    58  	err = inserter.Insert(ctx, sql.Row{"view", "view2", "SELECT v2 FROM test;"})
    59  	require.NoError(t, err)
    60  	err = inserter.Close(ctx)
    61  	require.NoError(t, err)
    62  
    63  	tbl, err := getOrCreateDoltSchemasTable(ctx, db) // removes the old table and recreates it with the new schema
    64  	require.NoError(t, err)
    65  
    66  	iter, err := SqlTableToRowIter(ctx, tbl.DoltTable, nil)
    67  	require.NoError(t, err)
    68  
    69  	var rows []sql.Row
    70  	for {
    71  		row, err := iter.Next(ctx)
    72  		if err == io.EOF {
    73  			break
    74  		}
    75  
    76  		require.NoError(t, err)
    77  		rows = append(rows, row)
    78  	}
    79  
    80  	require.NoError(t, iter.Close(ctx))
    81  	expectedRows := []sql.Row{
    82  		{"view", "view1", "SELECT v1 FROM test;", nil, nil},
    83  		{"view", "view2", "SELECT v2 FROM test;", nil, nil},
    84  	}
    85  
    86  	assert.Equal(t, expectedRows, rows)
    87  }
    88  
    89  func TestSchemaTableMigrationV1(t *testing.T) {
    90  	dEnv := dtestutils.CreateTestEnv()
    91  	tmpDir, err := dEnv.TempTableFilesDir()
    92  	require.NoError(t, err)
    93  	opts := editor.Options{Deaf: dEnv.DbEaFactory(), Tempdir: tmpDir}
    94  	db, err := NewDatabase(context.Background(), "dolt", dEnv.DbData(), opts)
    95  	require.NoError(t, err)
    96  
    97  	_, ctx, err := NewTestEngine(dEnv, context.Background(), db)
    98  	require.NoError(t, err)
    99  
   100  	// original schema of dolt_schemas table with the ID column
   101  	err = db.createSqlTable(ctx, doltdb.SchemasTableName, "", sql.NewPrimaryKeySchema(sql.Schema{
   102  		{Name: doltdb.SchemasTablesTypeCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: false},
   103  		{Name: doltdb.SchemasTablesNameCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: false},
   104  		{Name: doltdb.SchemasTablesFragmentCol, Type: gmstypes.Text, Source: doltdb.SchemasTableName, PrimaryKey: false},
   105  		{Name: doltdb.SchemasTablesIdCol, Type: gmstypes.Int64, Source: doltdb.SchemasTableName, PrimaryKey: true},
   106  		{Name: doltdb.SchemasTablesExtraCol, Type: gmstypes.JsonType{}, Source: doltdb.SchemasTableName, PrimaryKey: false, Nullable: true},
   107  	}), sql.Collation_Default, "")
   108  	require.NoError(t, err)
   109  
   110  	sqlTbl, found, err := db.GetTableInsensitive(ctx, doltdb.SchemasTableName)
   111  	require.NoError(t, err)
   112  	require.True(t, found)
   113  
   114  	inserter := sqlTbl.(*WritableDoltTable).Inserter(ctx)
   115  	// JSON string has no spaces because our various JSON libraries don't agree on how to marshall it
   116  	err = inserter.Insert(ctx, sql.Row{"view", "view1", "SELECT v1 FROM test;", 1, `{"extra":"data"}`})
   117  	require.NoError(t, err)
   118  	err = inserter.Insert(ctx, sql.Row{"view", "view2", "SELECT v2 FROM test;", 2, nil})
   119  	require.NoError(t, err)
   120  	err = inserter.Close(ctx)
   121  	require.NoError(t, err)
   122  
   123  	tbl, err := getOrCreateDoltSchemasTable(ctx, db) // removes the old table and recreates it with the new schema
   124  	require.NoError(t, err)
   125  
   126  	iter, err := SqlTableToRowIter(ctx, tbl.DoltTable, nil)
   127  	require.NoError(t, err)
   128  
   129  	var rows []sql.Row
   130  	for {
   131  		row, err := iter.Next(ctx)
   132  		if err == io.EOF {
   133  			break
   134  		}
   135  
   136  		require.NoError(t, err)
   137  		// convert the JSONDocument to a string for comparison
   138  		if row[3] != nil {
   139  			jsonDoc, ok := row[3].(sql.JSONWrapper)
   140  			if ok {
   141  				row[3], err = gmstypes.StringifyJSON(jsonDoc)
   142  				row[3] = strings.ReplaceAll(row[3].(string), " ", "") // remove spaces
   143  			}
   144  
   145  			require.NoError(t, err)
   146  		}
   147  
   148  		rows = append(rows, row)
   149  	}
   150  
   151  	require.NoError(t, iter.Close(ctx))
   152  
   153  	expectedRows := []sql.Row{
   154  		{"view", "view1", "SELECT v1 FROM test;", `{"extra":"data"}`, nil},
   155  		{"view", "view2", "SELECT v2 FROM test;", nil, nil},
   156  	}
   157  
   158  	assert.Equal(t, expectedRows, rows)
   159  }