Skip to content

Commit

Permalink
Make sure to rewrite last_insert_id() for DELETEs
Browse files Browse the repository at this point in the history
Signed-off-by: Andres Taylor <andres@planetscale.com>
  • Loading branch information
systay committed Jan 7, 2020
1 parent a3acc14 commit a40f4ce
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 14 deletions.
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ func BuildFromStmt(query string, stmt sqlparser.Statement, vschema ContextVSchem
case *sqlparser.Update:
instruction, needsLastInsertID, needsDBName, err = buildUpdatePlan(stmt, vschema)
case *sqlparser.Delete:
instruction, err = buildDeletePlan(stmt, vschema)
instruction, needsLastInsertID, needsDBName, err = buildDeletePlan(stmt, vschema)
case *sqlparser.Union:
instruction, needsLastInsertID, needsDBName, err = buildUnionPlan(stmt, vschema)
case *sqlparser.Set:
Expand Down
22 changes: 11 additions & 11 deletions go/vt/vtgate/planbuilder/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,31 @@ import (
)

// buildDeletePlan builds the instructions for a DELETE statement.
func buildDeletePlan(del *sqlparser.Delete, vschema ContextVSchema) (*engine.Delete, error) {
func buildDeletePlan(del *sqlparser.Delete, vschema ContextVSchema) (_ *engine.Delete, needsLastInsertID bool, needDbName bool, _ error) {
edel := &engine.Delete{}
pb := newPrimitiveBuilder(vschema, newJointab(sqlparser.GetBindvars(del)))
ro, err := pb.processDMLTable(del.TableExprs)
if err != nil {
return nil, err
return nil, false, false, err
}
edel.Query = generateQuery(del)
edel.Keyspace = ro.eroute.Keyspace
if !edel.Keyspace.Sharded {
// We only validate non-table subexpressions because the previous analysis has already validated them.
if !pb.finalizeUnshardedDMLSubqueries(del.Targets, del.Where, del.OrderBy, del.Limit) {
return nil, errors.New("unsupported: sharded subqueries in DML")
return nil, false, false, errors.New("unsupported: sharded subqueries in DML")
}
edel.Opcode = engine.DeleteUnsharded
// Generate query after all the analysis. Otherwise table name substitutions for
// routed tables won't happen.
edel.Query = generateQuery(del)
return edel, nil
return edel, pb.needsLastInsertID, pb.needsDbName, nil
}
if del.Targets != nil || ro.vschemaTable == nil {
return nil, errors.New("unsupported: multi-table delete statement in sharded keyspace")
return nil, false, false, errors.New("unsupported: multi-table delete statement in sharded keyspace")
}
if hasSubquery(del) {
return nil, errors.New("unsupported: subqueries in sharded DML")
return nil, false, false, errors.New("unsupported: subqueries in sharded DML")
}
edel.Table = ro.vschemaTable
// Generate query after all the analysis. Otherwise table name substitutions for
Expand All @@ -68,11 +68,11 @@ func buildDeletePlan(del *sqlparser.Delete, vschema ContextVSchema) (*engine.Del
edel.QueryTimeout = queryTimeout(directives)
if ro.eroute.TargetDestination != nil {
if ro.eroute.TargetTabletType != topodatapb.TabletType_MASTER {
return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unsupported: DELETE statement with a replica target")
return nil, false, false, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unsupported: DELETE statement with a replica target")
}
edel.Opcode = engine.DeleteByDestination
edel.TargetDestination = ro.eroute.TargetDestination
return edel, nil
return edel, pb.needsLastInsertID, pb.needsDbName, nil
}
edel.Vindex, edel.Values, err = getDMLRouting(del.Where, edel.Table)
// We couldn't generate a route for a single shard
Expand All @@ -85,15 +85,15 @@ func buildDeletePlan(del *sqlparser.Delete, vschema ContextVSchema) (*engine.Del

if edel.Opcode == engine.DeleteScatter {
if len(edel.Table.Owned) != 0 {
return edel, errors.New("unsupported: multi shard delete on a table with owned lookup vindexes")
return nil, false, false, errors.New("unsupported: multi shard delete on a table with owned lookup vindexes")
}
if del.Limit != nil {
return edel, errors.New("unsupported: multi shard delete with limit")
return nil, false, false, errors.New("unsupported: multi shard delete with limit")
}
}

edel.OwnedVindexQuery = generateDeleteSubquery(del, edel.Table)
return edel, nil
return edel, pb.needsLastInsertID, pb.needsDbName, nil
}

// generateDeleteSubquery generates the query to fetch the rows
Expand Down
4 changes: 2 additions & 2 deletions go/vt/vtgate/planbuilder/expression_rewriting.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ func RewriteAndUpdateBuilder(in sqlparser.Expr, pb *primitiveBuilder) (sqlparser
}

// Rewrite will rewrite an expression. Currently it does the following rewrites:
// - `last_insert_id()` => `:vtlastid`
// - `database()` => `:vtdbname`
// - `last_insert_id()` => `:__lastInsertId`
// - `database()` => `:__vtdbname`
func Rewrite(in sqlparser.Expr) (*RewriteResult, error) {
rewrites := make(map[*sqlparser.FuncExpr]sqlparser.Expr)
liid := false
Expand Down

0 comments on commit a40f4ce

Please sign in to comment.