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