-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle last_insert_id()
and database()
in vtgate
#5451
Conversation
9440d6f
to
88e44ff
Compare
01e7718
to
88e44ff
Compare
88e44ff
to
59acdbf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the builder APIs don't need to be changed. This is because the primitiveBuilder can keep track of the flag. We can see it as analogous to the relationship that Plan
has with Instruction
. Essentially, Rewrite
can just set this flag into primitiveBuilder, and then our job is done.
I think this will lead to a much smaller code change.
exec(t, conn, "insert into t1_last_insert_id(id1) values(42)") | ||
|
||
qr := exec(t, conn, "select last_insert_id()") | ||
if got, want := fmt.Sprintf("%v", qr.Rows), `[[INT64(1)]]`; got != want { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised you didn't use assert
:)
go/vt/vtgate/planbuilder/builder.go
Outdated
} | ||
|
||
// lastInsertIDTracker implements common functionality amongst most builders | ||
type lastInsertIDTracker struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can just be type lastInsertIDTracker bool
.
|
||
for _, node := range matchingNodes { | ||
in = sqlparser.ReplaceExpr(in, node, bindVarExpression()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, this won't work for subqueries, but we need to think of a more elaborate solution for those.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added subquery tests, and they seem to work. Not sure how that works
1c15506
to
daa439e
Compare
last_insert_id()
and database()
in vtgate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good. Found couple of issues that could be addressed as a follow-up PR. Do you want to do that or rework this PR itself?
go/vt/vtgate/planbuilder/builder.go
Outdated
case *sqlparser.Insert: | ||
plan.Instructions, err = buildInsertPlan(stmt, vschema) | ||
instruction, err = buildInsertPlan(stmt, vschema) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It just occurred to me that these statements can also use last_insert_id
as well as database
:
mysql> create table a(id int auto_increment, val int, primary key(id));
Query OK, 0 rows affected (0.04 sec)
mysql> insert into a(val) values(10);
Query OK, 1 row affected (0.01 sec)
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 1 |
+------------------+
1 row in set (0.01 sec)
mysql> insert into a(val) values(last_insert_id());
Query OK, 1 row affected (0.01 sec)
mysql> select * from a;
+----+------+
| id | val |
+----+------+
| 1 | 10 |
| 2 | 1 |
+----+------+
2 rows in set (0.00 sec)
) | ||
|
||
// RewriteResult contains the rewritten expression and meta information about it | ||
type RewriteResult struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional improvement: we probably don't need this struct: Rewrite
could directly update primitiveBuilder
instead. I can't think of a situation where we'd do a rewrite without updating primitiveBuilder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like having this intermediate struct to make it easy to write unit tests for the expression rewriting without having to first create a primitiveBuilder
a0dcf1d
to
790cfef
Compare
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Rohit Nayak <rohit@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two final nits.
go/vt/vtgate/planbuilder/builder.go
Outdated
case *sqlparser.Delete: | ||
plan.Instructions, err = buildDeletePlan(stmt, vschema) | ||
instruction, err = buildDeletePlan(stmt, vschema) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think delete could also need last insert id.
|
||
// Rewrite will rewrite an expression. Currently it does the following rewrites: | ||
// - `last_insert_id()` => `:vtlastid` | ||
// - `database()` => `:vtdbname` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to update these to use the new bind var names.
Signed-off-by: Andres Taylor <andres@planetscale.com>
Fixes #3668
Fixes #5417