MDEV-21181 Add Support for Generated Invisible Primary Keys#4718
MDEV-21181 Add Support for Generated Invisible Primary Keys#4718jaeheonshim wants to merge 1 commit intoMariaDB:mainfrom
Conversation
gkodinov
left a comment
There was a problem hiding this comment.
Thank you for your contributions. This is a preliminary review.
Couple of things to fix:
- please squash your changes into a single commit and add a commit message that follows CODING_STANDARDS.md
- please make sure the tests are passing. There's one test to re-record and one to fix.
829e2a2 to
ebe9abd
Compare
This PR implements a new session/global option `sql_generate_invisible_primary_key`. When this option is on, MariaDB will automatically generate an invisible primary key for tables created without an explicit primary key. The type of the auto-generated primary key is `BIGINT UNSIGNED AUTO_INCREMENT`. If an ALTER TABLE ADD PRIMARY KEY statement is executed on a table with an generated primary key, the generated primary key will be silently dropped. Notes: - Internally, the generated primary key has the INVISIBLE_FULL attribute. This means that the key and column effectively do not exist to the user and will not appear in SHOW CREATE TABLE and SHOW COLUMNS. Furthermore, the user cannot explicitly drop the generated primary key. - The column name of the invisible generated primary key is _inv_PK. If the user creates their own column named _inv_PK, the generated primary key column's name will be suffixed with a number. - If the storage engine does not support auto increment, no generated primary key will be added.
| bitmap_clear_all(&table->tmp_set); | ||
| for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++) | ||
| { | ||
| if (field->invisible == INVISIBLE_FULL) |
There was a problem hiding this comment.
I do not quite follow the whole logic here:
if (field->invisible == INVISIBLE_FULL)
{
/*
If the user added a pk of their own, and this was a generated pk field,
we drop the generated pk field. Other wise, we want to carry it over to
the new table.
*/
if (should_replace_generated_pk && generated_pk_field == field)
{
continue;
}
if (generated_pk_field == field)
{
def= new (root) Create_field(thd, field, field);
new_create_list.push_back(def, root);
}
continue;
}
Please simplify!
I would do it as follows:
if (field->invisible == INVISIBLE_FULL)
{
/*
If the user added a pk of their own, and this was a generated pk field,
we drop the generated pk field. Other wise, we want to carry it over to
the new table.
*/
if (generated_pk_field == field && !should_replace_generated_pk)
{
def= new (root) Create_field(thd, field, field);
new_create_list.push_back(def, root);
}
continue;
}
| return 0; | ||
| } | ||
|
|
||
| static bool is_auto_pk_field(Field *field) |
There was a problem hiding this comment.
I'd also check if the name. Not 100 fool-prof vs me doing:
CREATE TABLE t1 (_inv_PK SERIAL INVISIBLE PRIMARY KEY, c2 INT) ENGINE=InnoDB;
then the next ALTER TABLE dropping my manually defined primary key, i.e.
ALTER TABLE t1 ADD uniq_1 PRIMARY KEY;
But still better than nothing.
Please add a test case for this and have it documented in the MDEV that even explicitly created primary keys will be replaced in this case!
| # | ||
| --source include/have_debug.inc | ||
|
|
||
| SET SESSION debug_dbug="+d,test_invisible_index,test_completely_invisible"; |
There was a problem hiding this comment.
I'd also add a non-debug version of all this test: to explore the visible effects of the change. What is it btw?
The PR says "Innodb"! This is important for InnoDB afaik as it uses a clustered primary key to store data, so there's always a primary key of some sort. But Is it important for for the other storage engines?
Maybe it's best done inside InnoDB (as suggested by the MDEV)? Or still at server level, but only for InnoDB tables? Not sure. I guess, it'll have to wait for the final review this one.
But please document the visible effects.
Jira: MDEV-21181
This PR implements a new session/global option
sql_generate_invisible_primary_key. When this option is ON, MariaDB will automatically generate an invisible primary key for tables created without an explicit primary key.The type of the auto-generated primary key is
BIGINT UNSIGNED AUTO_INCREMENT. The primary key has theINVISIBLE_FULLattribute, meaning that to the user, it effectively does not exist and it is hidden fromSHOW CREATE TABLEandSHOW COLUMNS. Furthermore, the user cannot explicitly drop the auto-generated primary key. However, if the user later adds their own primary key, the generated PK field and key are dropped.Internally, the name of the generated primary key is
_inv_PK, but this does not prevent the user from creating or adding their own column named_inv_PK. In that case, the generated primary key will be suffixed with a number (e.g._inv_PK1,_inv_PK2, etc.).