github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/sqle/sqlinsert_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  	"testing"
    20  
    21  	"github.com/dolthub/go-mysql-server/sql"
    22  	"github.com/google/uuid"
    23  	"github.com/stretchr/testify/assert"
    24  	"github.com/stretchr/testify/require"
    25  
    26  	"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
    27  	"github.com/dolthub/dolt/go/libraries/doltcore/schema"
    28  	"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dtables"
    29  	"github.com/dolthub/dolt/go/store/types"
    30  )
    31  
    32  // Set to the name of a single test to run just that test, useful for debugging
    33  const singleInsertQueryTest = "" //"Natural join with join clause"
    34  
    35  // Set to false to run tests known to be broken
    36  const skipBrokenInsert = true
    37  
    38  // Structure for a test of a insert query
    39  type InsertTest struct {
    40  	// The name of this test. Names should be unique and descriptive.
    41  	Name string
    42  	// The insert query to run
    43  	InsertQuery string
    44  	// The select query to run to verify the results
    45  	SelectQuery string
    46  	// The schema of the result of the query, nil if an error is expected
    47  	ExpectedSchema schema.Schema
    48  	// The rows this query should return, nil if an error is expected
    49  	ExpectedRows []sql.Row
    50  	// An expected error string
    51  	ExpectedErr string
    52  	// Setup logic to run before executing this test, after initial tables have been created and populated
    53  	AdditionalSetup SetupFn
    54  	// Whether to skip this test on SqlEngine (go-mysql-server) execution.
    55  	// Over time, this should become false for every query.
    56  	SkipOnSqlEngine bool
    57  }
    58  
    59  // BasicInsertTests cover basic insert statement features and error handling
    60  var BasicInsertTests = []InsertTest{
    61  	{
    62  		Name:           "insert no columns",
    63  		InsertQuery:    "insert into people values (2, 'Bart', 'Simpson', false, 10, 9, '00000000-0000-0000-0000-000000000002', 222)",
    64  		SelectQuery:    "select * from people where id = 2 ORDER BY id",
    65  		ExpectedRows:   ToSqlRows(PeopleTestSchema, Bart),
    66  		ExpectedSchema: CompressSchema(PeopleTestSchema),
    67  	},
    68  	{
    69  		Name:        "insert no columns too few values",
    70  		InsertQuery: "insert into people values (2, 'Bart', 'Simpson', false, 10, 9, '00000000-0000-0000-0000-000000000002')",
    71  		ExpectedErr: "too few values",
    72  	},
    73  	{
    74  		Name:        "insert no columns too many values",
    75  		InsertQuery: "insert into people values (2, 'Bart', 'Simpson', false, 10, 9, '00000000-0000-0000-0000-000000000002', 222, 'abc')",
    76  		ExpectedErr: "too many values",
    77  	},
    78  	{
    79  		Name:           "insert full columns",
    80  		InsertQuery:    "insert into people (id, first_name, last_name, is_married, age, rating, uuid, num_episodes) values (2, 'Bart', 'Simpson', false, 10, 9, '00000000-0000-0000-0000-000000000002', 222)",
    81  		SelectQuery:    "select * from people where id = 2 ORDER BY id",
    82  		ExpectedRows:   ToSqlRows(PeopleTestSchema, Bart),
    83  		ExpectedSchema: CompressSchema(PeopleTestSchema),
    84  	},
    85  	{
    86  		Name:           "insert full columns mixed order",
    87  		InsertQuery:    "insert into people (num_episodes, uuid, rating, age, is_married, last_name, first_name, id) values (222, '00000000-0000-0000-0000-000000000002', 9, 10, false, 'Simpson', 'Bart', 2)",
    88  		SelectQuery:    "select * from people where id = 2 ORDER BY id",
    89  		ExpectedRows:   ToSqlRows(PeopleTestSchema, Bart),
    90  		ExpectedSchema: CompressSchema(PeopleTestSchema),
    91  	},
    92  	{
    93  		Name: "insert full columns negative values",
    94  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating, uuid, num_episodes) values
    95  					    (-7, "Maggie", "Simpson", false, -1, -5.1, '00000000-0000-0000-0000-000000000005', 677)`,
    96  		SelectQuery:    "select * from people where id = -7 ORDER BY id",
    97  		ExpectedRows:   ToSqlRows(PeopleTestSchema, NewPeopleRowWithOptionalFields(-7, "Maggie", "Simpson", false, -1, -5.1, uuid.MustParse("00000000-0000-0000-0000-000000000005"), 677)),
    98  		ExpectedSchema: CompressSchema(PeopleTestSchema),
    99  	},
   100  	{
   101  		Name:           "insert full columns null values",
   102  		InsertQuery:    "insert into people (id, first_name, last_name, is_married, age, rating, uuid, num_episodes) values (2, 'Bart', 'Simpson', null, null, null, null, null)",
   103  		SelectQuery:    "select * from people where id = 2 ORDER BY id",
   104  		ExpectedRows:   ToSqlRows(CompressSchema(PeopleTestSchema), NewResultSetRow(types.Int(2), types.String("Bart"), types.String("Simpson"))),
   105  		ExpectedSchema: CompressSchema(PeopleTestSchema),
   106  	},
   107  	{
   108  		Name:        "insert partial columns",
   109  		InsertQuery: "insert into people (id, first_name, last_name) values (2, 'Bart', 'Simpson')",
   110  		SelectQuery: "select id, first_name, last_name from people where id = 2 ORDER BY id",
   111  		ExpectedRows: ToSqlRows(
   112  			NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind),
   113  			NewResultSetRow(types.Int(2), types.String("Bart"), types.String("Simpson")),
   114  		),
   115  		ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind),
   116  	},
   117  	{
   118  		Name:        "insert partial columns mixed order",
   119  		InsertQuery: "insert into people (last_name, first_name, id) values ('Simpson', 'Bart', 2)",
   120  		SelectQuery: "select id, first_name, last_name from people where id = 2 ORDER BY id",
   121  		ExpectedRows: ToSqlRows(
   122  			NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind),
   123  			NewResultSetRow(types.Int(2), types.String("Bart"), types.String("Simpson")),
   124  		),
   125  		ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind),
   126  	},
   127  	{
   128  		Name:        "insert partial columns duplicate column",
   129  		InsertQuery: "insert into people (id, first_name, last_name, first_name) values (2, 'Bart', 'Simpson', 'Bart')",
   130  		ExpectedErr: "duplicate column",
   131  	},
   132  	{
   133  		Name:        "insert partial columns invalid column",
   134  		InsertQuery: "insert into people (id, first_name, last_name, middle) values (2, 'Bart', 'Simpson', 'Nani')",
   135  		ExpectedErr: "duplicate column",
   136  	},
   137  	{
   138  		Name:        "insert missing non-nullable column",
   139  		InsertQuery: "insert into people (id, first_name) values (2, 'Bart')",
   140  		ExpectedErr: "column <last_name> received nil but is non-nullable",
   141  	},
   142  	{
   143  		Name:        "insert partial columns mismatch too many values",
   144  		InsertQuery: "insert into people (id, first_name, last_name) values (2, 'Bart', 'Simpson', false)",
   145  		ExpectedErr: "too many values",
   146  	},
   147  	{
   148  		Name:        "insert partial columns mismatch too few values",
   149  		InsertQuery: "insert into people (id, first_name, last_name) values (2, 'Bart')",
   150  		ExpectedErr: "too few values",
   151  	},
   152  	{
   153  		Name:        "insert partial columns functions",
   154  		InsertQuery: "insert into people (id, first_name, last_name) values (2, UPPER('Bart'), 'Simpson')",
   155  		SelectQuery: "select id, first_name, last_name from people where id = 2 ORDER BY id",
   156  		ExpectedRows: ToSqlRows(
   157  			NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind),
   158  			NewResultSetRow(types.Int(2), types.String("BART"), types.String("Simpson")),
   159  		),
   160  		ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind),
   161  	},
   162  	{
   163  		Name:        "insert partial columns multiple rows 2",
   164  		InsertQuery: "insert into people (id, first_name, last_name) values (0, 'Bart', 'Simpson'), (1, 'Homer', 'Simpson')",
   165  		SelectQuery: "select id, first_name, last_name from people where id < 2 order by id",
   166  		ExpectedRows: ToSqlRows(
   167  			NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind),
   168  			NewResultSetRow(types.Int(0), types.String("Bart"), types.String("Simpson")),
   169  			NewResultSetRow(types.Int(1), types.String("Homer"), types.String("Simpson")),
   170  		),
   171  		ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind),
   172  	},
   173  	{
   174  		Name: "insert partial columns multiple rows 5",
   175  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values
   176  					(7, "Maggie", "Simpson", false, 1, 5.1),
   177  					(8, "Milhouse", "Van Houten", false, 8, 3.5),
   178  					(9, "Jacqueline", "Bouvier", true, 80, 2),
   179  					(10, "Patty", "Bouvier", false, 40, 7),
   180  					(11, "Selma", "Bouvier", false, 40, 7)`,
   181  		SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id > 6 ORDER BY id",
   182  		ExpectedRows: ToSqlRows(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating"),
   183  			NewPeopleRow(7, "Maggie", "Simpson", false, 1, 5.1),
   184  			NewPeopleRow(8, "Milhouse", "Van Houten", false, 8, 3.5),
   185  			NewPeopleRow(9, "Jacqueline", "Bouvier", true, 80, 2),
   186  			NewPeopleRow(10, "Patty", "Bouvier", false, 40, 7),
   187  			NewPeopleRow(11, "Selma", "Bouvier", false, 40, 7),
   188  		),
   189  		ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind,
   190  			"is_married", types.IntKind, "age", types.IntKind, "rating", types.FloatKind),
   191  	},
   192  	{
   193  		Name: "insert ignore partial columns multiple rows null constraint failure",
   194  		InsertQuery: `insert ignore into people (id, first_name, last_name, is_married, age, rating) values
   195  					(7, "Maggie", null, false, 1, 5.1),
   196  					(8, "Milhouse", "Van Houten", false, 8, 3.5)`,
   197  		SelectQuery:  "select id, first_name, last_name, is_married, age, rating from people where id > 6 ORDER BY id",
   198  		ExpectedRows: ToSqlRows(PeopleTestSchema, NewPeopleRow(8, "Milhouse", "Van Houten", false, 8, 3.5)),
   199  		ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind,
   200  			"is_married", types.IntKind, "age", types.IntKind, "rating", types.FloatKind),
   201  		SkipOnSqlEngine: true,
   202  	},
   203  	{
   204  		Name: "insert ignore partial columns multiple rows existing pk",
   205  		InsertQuery: `insert ignore into people (id, first_name, last_name, is_married, age, rating) values
   206  					(0, "Homer", "Simpson", true, 45, 100),
   207  					(8, "Milhouse", "Van Houten", false, 8, 8.5)`,
   208  		SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where rating = 8.5 order by id",
   209  		ExpectedRows: ToSqlRows(PeopleTestSchema,
   210  			Homer,
   211  			NewPeopleRow(8, "Milhouse", "Van Houten", false, 8, 8.5),
   212  		),
   213  		ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind,
   214  			"is_married", types.IntKind, "age", types.IntKind, "rating", types.FloatKind),
   215  		SkipOnSqlEngine: true,
   216  	},
   217  	{
   218  		Name: "insert ignore partial columns multiple rows duplicate pk",
   219  		InsertQuery: `insert ignore into people (id, first_name, last_name, is_married, age, rating) values
   220  					(7, "Maggie", "Simpson", false, 1, 5.1),
   221  					(7, "Milhouse", "Van Houten", false, 8, 3.5)`,
   222  		SelectQuery:  "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id",
   223  		ExpectedRows: ToSqlRows(PeopleTestSchema, NewPeopleRow(7, "Maggie", "Simpson", false, 1, 5.1)),
   224  		ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind,
   225  			"is_married", types.IntKind, "age", types.IntKind, "rating", types.FloatKind),
   226  		SkipOnSqlEngine: true,
   227  	},
   228  	{
   229  		Name:        "insert partial columns multiple rows null pk",
   230  		InsertQuery: "insert into people (id, first_name, last_name) values (0, 'Bart', 'Simpson'), (1, 'Homer', null)",
   231  		ExpectedErr: "column <last_name> received nil but is non-nullable",
   232  	},
   233  	{
   234  		Name:        "insert partial columns multiple rows duplicate",
   235  		InsertQuery: "insert into people (id, first_name, last_name) values (2, 'Bart', 'Simpson'), (2, 'Bart', 'Simpson')",
   236  		ExpectedErr: "duplicate primary key",
   237  	},
   238  	{
   239  		Name: "insert partial columns existing pk",
   240  		AdditionalSetup: ExecuteSetupSQL(context.Background(), `
   241  			CREATE TABLE temppeople (id bigint primary key, first_name varchar(1023), last_name varchar(1023));
   242  			INSERT INTO temppeople VALUES (2, 'Bart', 'Simpson');`),
   243  		InsertQuery: "insert into temppeople (id, first_name, last_name) values (2, 'Bart', 'Simpson')",
   244  		ExpectedErr: "duplicate primary key",
   245  	},
   246  	{
   247  		Name: "type mismatch int -> string",
   248  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values
   249  					(7, "Maggie", 100, false, 1, 5.1)`,
   250  		SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id",
   251  		ExpectedRows: ToSqlRows(
   252  			CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   253  			NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("100"), types.Int(0), types.Int(1), types.Float(5.1)),
   254  		),
   255  		ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   256  	},
   257  	{
   258  		Name: "type mismatch int -> bool",
   259  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values
   260  					(7, "Maggie", "Simpson", 1, 1, 5.1)`,
   261  		SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id",
   262  		ExpectedRows: ToSqlRows(
   263  			CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   264  			NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Int(1), types.Int(1), types.Float(5.1)),
   265  		),
   266  		ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   267  	},
   268  	{
   269  		Name: "type mismatch string -> int",
   270  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values
   271  					("7", "Maggie", "Simpson", false, 1, 5.1)`,
   272  		SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id",
   273  		ExpectedRows: ToSqlRows(
   274  			CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   275  			NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Int(0), types.Int(1), types.Float(5.1)),
   276  		),
   277  		ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   278  	},
   279  	{
   280  		Name: "type mismatch string -> float",
   281  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values
   282  					(7, "Maggie", "Simpson", false, 1, "5.1")`,
   283  		SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id",
   284  		ExpectedRows: ToSqlRows(
   285  			CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   286  			NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Int(0), types.Int(1), types.Float(5.1)),
   287  		),
   288  		ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   289  	},
   290  	{
   291  		Name: "type mismatch string -> uint",
   292  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, num_episodes) values
   293  					(7, "Maggie", "Simpson", false, 1, "100")`,
   294  		SelectQuery: "select id, first_name, last_name, is_married, age, num_episodes from people where id = 7 ORDER BY id",
   295  		ExpectedRows: ToSqlRows(
   296  			CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "num_episodes")),
   297  			NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Int(0), types.Int(1), types.Uint(100)),
   298  		),
   299  		ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "num_episodes")),
   300  	},
   301  	{
   302  		Name: "type mismatch float -> string",
   303  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values
   304  					(7, 8.1, "Simpson", false, 1, 5.1)`,
   305  		SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id",
   306  		ExpectedRows: ToSqlRows(
   307  			CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   308  			NewResultSetRow(types.Int(7), types.String("8.1"), types.String("Simpson"), types.Int(0), types.Int(1), types.Float(5.1)),
   309  		),
   310  		ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   311  	},
   312  	{
   313  		Name: "type mismatch float -> bool",
   314  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values
   315  					(7, "Maggie", "Simpson", 0.5, 1, 5.1)`,
   316  		SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id",
   317  		ExpectedRows: ToSqlRows(
   318  			CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   319  			NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Int(1), types.Int(1), types.Float(5.1)),
   320  		),
   321  		ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   322  	},
   323  	{
   324  		Name: "type mismatch float -> int",
   325  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values
   326  					(7, "Maggie", "Simpson", false, 1.0, 5.1)`,
   327  		SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id",
   328  		ExpectedRows: ToSqlRows(
   329  			CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   330  			NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Int(0), types.Int(1), types.Float(5.1)),
   331  		),
   332  		ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   333  	},
   334  	{
   335  		Name: "type mismatch bool -> int",
   336  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values
   337  					(true, "Maggie", "Simpson", false, 1, 5.1)`,
   338  		SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 1 ORDER BY id",
   339  		ExpectedRows: ToSqlRows(
   340  			CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   341  			NewResultSetRow(types.Int(1), types.String("Maggie"), types.String("Simpson"), types.Int(0), types.Int(1), types.Float(5.1)),
   342  		),
   343  		ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   344  	},
   345  	{
   346  		Name: "type mismatch bool -> float",
   347  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values
   348  					(7, "Maggie", "Simpson", false, 1, true)`,
   349  		SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id",
   350  		ExpectedRows: ToSqlRows(
   351  			CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   352  			NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Int(0), types.Int(1), types.Float(1.0)),
   353  		),
   354  		ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   355  	},
   356  	{
   357  		Name: "type mismatch bool -> string",
   358  		InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values
   359  					(7, true, "Simpson", false, 1, 5.1)`,
   360  		SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id",
   361  		ExpectedRows: ToSqlRows(
   362  			CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   363  			NewResultSetRow(types.Int(7), types.String("1"), types.String("Simpson" /*"West"*/), types.Int(0), types.Int(1), types.Float(5.1)),
   364  		),
   365  		ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")),
   366  	},
   367  }
   368  
   369  func TestExecuteInsert(t *testing.T) {
   370  	for _, test := range BasicInsertTests {
   371  		t.Run(test.Name, func(t *testing.T) {
   372  			testInsertQuery(t, test)
   373  		})
   374  	}
   375  }
   376  
   377  var systemTableInsertTests = []InsertTest{
   378  	{
   379  		Name:            "insert into dolt_docs",
   380  		AdditionalSetup: CreateTableFn("dolt_docs", doltdb.DocsSchema, ""),
   381  		InsertQuery:     "insert into dolt_docs (doc_name, doc_text) values ('README.md', 'Some text')",
   382  		SelectQuery:     "select * from dolt_docs",
   383  		ExpectedRows:    []sql.Row{{"README.md", "Some text"}},
   384  		ExpectedSchema:  CompressSchema(doltdb.DocsSchema),
   385  	},
   386  	{
   387  		Name: "insert into dolt_query_catalog",
   388  		AdditionalSetup: CreateTableFn(doltdb.DoltQueryCatalogTableName, dtables.DoltQueryCatalogSchema,
   389  			"INSERT INTO dolt_query_catalog VALUES ('existingEntry', 2, 'example', 'select 2+2 from dual', 'description')"),
   390  		InsertQuery: "insert into dolt_query_catalog (id, display_order, name, query, description) values ('abc123', 1, 'example', 'select 1+1 from dual', 'description')",
   391  		SelectQuery: "select * from dolt_query_catalog ORDER BY id",
   392  		ExpectedRows: ToSqlRows(CompressSchema(dtables.DoltQueryCatalogSchema),
   393  			NewRow(types.String("abc123"), types.Uint(1), types.String("example"), types.String("select 1+1 from dual"), types.String("description")),
   394  			NewRow(types.String("existingEntry"), types.Uint(2), types.String("example"), types.String("select 2+2 from dual"), types.String("description")),
   395  		),
   396  		ExpectedSchema: CompressSchema(dtables.DoltQueryCatalogSchema),
   397  	},
   398  	{
   399  		Name:            "insert into dolt_schemas",
   400  		AdditionalSetup: CreateTableFn(doltdb.SchemasTableName, schemaTableSchema, ""),
   401  		InsertQuery:     "insert into dolt_schemas (type, name, fragment) values ('view', 'name', 'create view name as select 2+2 from dual')",
   402  		SelectQuery:     "select * from dolt_schemas ORDER BY name",
   403  		ExpectedRows: ToSqlRows(CompressSchema(schemaTableSchema),
   404  			NewRow(types.String("view"), types.String("name"), types.String("create view name as select 2+2 from dual")),
   405  		),
   406  		ExpectedSchema: CompressSchema(schemaTableSchema),
   407  	},
   408  }
   409  
   410  func TestInsertIntoSystemTables(t *testing.T) {
   411  	for _, test := range systemTableInsertTests {
   412  		t.Run(test.Name, func(t *testing.T) {
   413  			testInsertQuery(t, test)
   414  		})
   415  	}
   416  }
   417  
   418  // Tests the given query on a freshly created dataset, asserting that the result has the given schema and rows. If
   419  // expectedErr is set, asserts instead that the execution returns an error that matches.
   420  func testInsertQuery(t *testing.T, test InsertTest) {
   421  	if (test.ExpectedRows == nil) != (test.ExpectedSchema == nil) {
   422  		require.Fail(t, "Incorrect test setup: schema and rows must both be provided if one is")
   423  	}
   424  
   425  	if len(singleInsertQueryTest) > 0 && test.Name != singleInsertQueryTest {
   426  		t.Skip("Skipping tests until " + singleInsertQueryTest)
   427  	}
   428  
   429  	if len(singleInsertQueryTest) == 0 && test.SkipOnSqlEngine && skipBrokenInsert {
   430  		t.Skip("Skipping test broken on SQL engine")
   431  	}
   432  
   433  	dEnv, err := CreateEmptyTestDatabase()
   434  	require.NoError(t, err)
   435  	defer dEnv.DoltDB.Close()
   436  
   437  	if test.AdditionalSetup != nil {
   438  		test.AdditionalSetup(t, dEnv)
   439  	}
   440  
   441  	root, _ := dEnv.WorkingRoot(context.Background())
   442  	root, err = executeModify(t, context.Background(), dEnv, root, test.InsertQuery)
   443  	if len(test.ExpectedErr) > 0 {
   444  		require.Error(t, err)
   445  		return
   446  	} else {
   447  		require.NoError(t, err)
   448  	}
   449  
   450  	actualRows, sch, err := executeSelect(t, context.Background(), dEnv, root, test.SelectQuery)
   451  	require.NoError(t, err)
   452  
   453  	assert.Equal(t, test.ExpectedRows, actualRows)
   454  	assertSchemasEqual(t, mustSqlSchema(test.ExpectedSchema), sch)
   455  }