diff --git a/go/vt/vtgate/planbuilder/insert.go b/go/vt/vtgate/planbuilder/insert.go index 569ebaea69..ab7bb6eb72 100644 --- a/go/vt/vtgate/planbuilder/insert.go +++ b/go/vt/vtgate/planbuilder/insert.go @@ -211,13 +211,23 @@ func generateInsertShardedQuery(node *sqlparser.Insert, eins *engine.Insert, val // modifyForAutoinc modfies the AST and the plan to generate // necessary autoinc values. It must be called only if eins.Table.AutoIncrement -// is set. +// is set. Bind variable names are generated using baseName. func modifyForAutoinc(ins *sqlparser.Insert, eins *engine.Insert) error { - pos := findOrAddColumn(ins, eins.Table.AutoIncrement.Column) - autoIncValues, err := swapBindVariables(ins.Rows.(sqlparser.Values), pos, ":"+engine.SeqVarName) - if err != nil { - return err + colNum := findOrAddColumn(ins, eins.Table.AutoIncrement.Column) + autoIncValues := sqltypes.PlanValue{} + for rowNum, row := range ins.Rows.(sqlparser.Values) { + // Support the DEFAULT keyword by treating it as null + if _, ok := row[colNum].(*sqlparser.Default); ok { + row[colNum] = &sqlparser.NullVal{} + } + pv, err := sqlparser.NewPlanValue(row[colNum]) + if err != nil { + return fmt.Errorf("could not compute value for vindex or auto-inc column: %v", err) + } + autoIncValues.Values = append(autoIncValues.Values, pv) + row[colNum] = sqlparser.NewValArg([]byte(":" + engine.SeqVarName + strconv.Itoa(rowNum))) } + eins.Generate = &engine.Generate{ Keyspace: eins.Table.AutoIncrement.Sequence.Keyspace, Query: fmt.Sprintf("select next :n values from %s", sqlparser.String(eins.Table.AutoIncrement.Sequence.Name)), @@ -226,22 +236,6 @@ func modifyForAutoinc(ins *sqlparser.Insert, eins *engine.Insert) error { return nil } -// swapBindVariables swaps in bind variable names at the specified -// column position in the AST values and returns the converted values back. -// Bind variable names are generated using baseName. -func swapBindVariables(rows sqlparser.Values, colNum int, baseName string) (sqltypes.PlanValue, error) { - pv := sqltypes.PlanValue{} - for rowNum, row := range rows { - innerpv, err := sqlparser.NewPlanValue(row[colNum]) - if err != nil { - return pv, fmt.Errorf("could not compute value for vindex or auto-inc column: %v", err) - } - pv.Values = append(pv.Values, innerpv) - row[colNum] = sqlparser.NewValArg([]byte(baseName + strconv.Itoa(rowNum))) - } - return pv, nil -} - // findOrAddColumn finds the position of a column in the insert. If it's // absent it appends it to the with NULL values and returns that position. func findOrAddColumn(ins *sqlparser.Insert, col sqlparser.ColIdent) int { diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.txt b/go/vt/vtgate/planbuilder/testdata/dml_cases.txt index 7d43fb8f9f..0c31cc937e 100644 --- a/go/vt/vtgate/planbuilder/testdata/dml_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.txt @@ -993,6 +993,32 @@ } } +# insert with default seq +"insert into user(id, nonid) values (default, 2)" +{ + "Original": "insert into user(id, nonid) values (default, 2)", + "Instructions": { + "Opcode": "InsertSharded", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "Query": "insert into user(id, nonid, Name, Costly) values (:_Id0, 2, :_Name0, :_Costly0)", + "Values": [[[":__seq0"]],[[null]],[[null]]], + "Table": "user", + "Generate": { + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "Query": "select next :n values from seq", + "Values": [null] + }, + "Prefix": "insert into user(id, nonid, Name, Costly) values ", + "Mid": ["(:_Id0, 2, :_Name0, :_Costly0)"] + } +} + # insert with non vindex bool value "insert into user(nonid) values (true)" {