| Bug #115111 | last_insert_id evaluated twice if used nested | ||
|---|---|---|---|
| Submitted: | 24 May 2024 7:33 | Modified: | 24 May 2024 7:41 |
| Reporter: | ximin liang (OCA) | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server: DML | Severity: | S3 (Non-critical) |
| Version: | 8.4.0, 8.0.37 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
[24 May 2024 7:33]
ximin liang
[24 May 2024 7:35]
ximin liang
may be 3 is correct result for final select last_insert_id();
[24 May 2024 7:41]
MySQL Verification Team
Hello ximin liang, Thank you for the report and test case. Verified as described. regards, Umesh
[7 Jun 2024 11:56]
huahua xu
Hi liang,
It myebe fix the bugs:
```
diff --git a/sql/item_func.cc b/sql/item_func.cc
index ac6875c..81d5385 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -5693,9 +5693,10 @@ bool Item_func_last_insert_id::do_itemize(Parse_context *pc, Item **res) {
longlong Item_func_last_insert_id::val_int() {
THD *thd = current_thd;
assert(fixed);
- if (arg_count) {
+ if (arg_count && !const_value_cache) {
const longlong value = args[0]->val_int();
null_value = args[0]->null_value;
+ const_value_cache = true;
/*
LAST_INSERT_ID(X) must affect the client's mysql_insert_id() as
documented in the manual. We don't want to touch
@@ -5704,7 +5705,7 @@ longlong Item_func_last_insert_id::val_int() {
value for this row.
*/
thd->arg_of_last_insert_id_function = true;
- thd->first_successful_insert_id_in_prev_stmt = value;
+ thd->first_successful_insert_id_in_prev_stmt = value;
return value;
}
return static_cast<longlong>(
diff --git a/sql/item_func.h b/sql/item_func.h
index e4b7626..188407a 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -2072,6 +2072,10 @@ class Item_func_bit_neg final : public Item_func_bit {
class Item_func_last_insert_id final : public Item_int_func {
typedef Item_int_func super;
+ protected:
+ // Tells if last_insert_id(#expression) was called and the result had been cached.
+ bool const_value_cache;
+
public:
Item_func_last_insert_id() : Item_int_func() {}
explicit Item_func_last_insert_id(const POS &pos) : Item_int_func(pos) {}
```
