This implementation forces us to define the first method in
Table_function_last_insert_ids
, a very simple one:
const char *func_name() const override { return "last_insert_ids"; }
Let's run it!
SELECT * FROM LAST_INSERT_IDS() as ids;
...
Assertion failed: (0), function init, file table_function.h, line 440.
…which points to the stub Table_function_last_insert_ids::init()
. Let's say we
have no meaningful initialization at this point, so remove the assert from the stub:
Assertion failed: (false), function get_field_list, file table_function.h, line 464.
This is get_field_list
method, and we have to implement it to describe the schema
of the table we will be returning:
List<Create_field> *Table_function_last_insert_ids::get_field_list() {
assert(fields.is_empty());
auto *const field = new Create_field;
field->init_for_tmp_table(MYSQL_TYPE_LONGLONG, MAX_BIGINT_WIDTH,
DECIMAL_NOT_SPECIFIED, /* is_nullable */ false,
/* is_unsigned */ true, 0, "insert_id");
fields.push_back(field);
return &fields;
}
This implementation assumes it is not a simple getter and thus is called exactly
once. If the assumption will shown to be incorrect by the assert
, I'll move the
code to init
and will reduce this one to a simple getter. Also, something will have
to free the memory we are allocating for the field, that's for later.
Run again…
Assertion failed: (false), function do_init_args, file table_function.h, line 467.
For JSON_TABLE
, this method is documented to "check whether given default values
can be saved to fields." Let's assume that we have no meaningful actions here, remove
the assert, return success, run again:
Assertion failed: (0), function fill_result_table, file table_function.h, line 442.
Finally we get to the second serious method that should provide the payload for the
result table:
bool Table_function_last_insert_ids::fill_result_table() {
assert(!fields.is_empty());
assert(!table->materialized);
assert(table->s->fields == 1);
empty_table();
auto *const field = get_field(0);
assert(field->field_index() == 0);
field->store(current_thd->first_successful_insert_id_in_prev_stmt);
field->set_notnull();
write_row();
return false;
}
And…
SELECT * FROM LAST_INSERT_IDS() as ids;
insert_id
0
Success!