mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
System Versioning pre0.12
Merge remote-tracking branch 'origin/archive/2017-10-17' into 10.3
This commit is contained in:
166
sql/sql_view.cc
166
sql/sql_view.cc
@ -455,6 +455,140 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (SELECT_LEX *sl= select_lex; sl; sl= sl->next_select())
|
||||
{ /* System Versioning: fix system fields of versioned view */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
#pragma GCC diagnostic ignored "-Wformat-extra-args"
|
||||
// Similar logic as in mysql_derived_prepare()
|
||||
// Leading versioning table detected implicitly (first one selected)
|
||||
TABLE_LIST *impli_table= NULL;
|
||||
// Leading versioning table specified explicitly
|
||||
// (i.e. if at least one system field is selected)
|
||||
TABLE_LIST *expli_table= NULL;
|
||||
const LString_i *impli_start, *impli_end;
|
||||
Item_field *expli_start= NULL, *expli_end= NULL;
|
||||
|
||||
for (TABLE_LIST *table= tables; table; table= table->next_local)
|
||||
{
|
||||
DBUG_ASSERT(!table->is_view() || table->view);
|
||||
|
||||
// Any versioned table in VIEW will add `FOR SYSTEM_TIME ALL` + WHERE:
|
||||
// if there are at least one versioned table then VIEW will contain FOR_SYSTEM_TIME_ALL
|
||||
// (because it is in fact LEX used to parse its SELECT).
|
||||
if (table->is_view() && table->view->vers_conditions == FOR_SYSTEM_TIME_ALL)
|
||||
{
|
||||
my_printf_error(
|
||||
ER_VERS_VIEW_PROHIBITED,
|
||||
"Creating VIEW %`s is prohibited: versioned VIEW %`s in query!", MYF(0),
|
||||
view->table_name,
|
||||
table->table_name);
|
||||
res= true;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!table->table || !table->table->versioned())
|
||||
continue;
|
||||
|
||||
const LString_i table_start= table->table->vers_start_field()->field_name;
|
||||
const LString_i table_end= table->table->vers_end_field()->field_name;
|
||||
|
||||
if (!impli_table)
|
||||
{
|
||||
impli_table= table;
|
||||
impli_start= &table_start;
|
||||
impli_end= &table_end;
|
||||
}
|
||||
|
||||
/* Implicitly add versioning fields if needed */
|
||||
Item *item;
|
||||
List_iterator_fast<Item> it(sl->item_list);
|
||||
|
||||
DBUG_ASSERT(table->alias);
|
||||
while ((item= it++))
|
||||
{
|
||||
if (item->real_item()->type() != Item::FIELD_ITEM)
|
||||
continue;
|
||||
Item_field *fld= (Item_field*) item->real_item();
|
||||
if (fld->table_name && 0 != my_strcasecmp(table_alias_charset, table->alias, fld->table_name))
|
||||
continue;
|
||||
DBUG_ASSERT(fld->field_name.str);
|
||||
if (table_start == fld->field_name)
|
||||
{
|
||||
if (expli_start)
|
||||
{
|
||||
my_printf_error(
|
||||
ER_VERS_VIEW_PROHIBITED,
|
||||
"Creating VIEW %`s is prohibited: multiple start system fields `%s.%s`, `%s.%s` in query!", MYF(0),
|
||||
view->table_name,
|
||||
expli_table->alias,
|
||||
expli_start->field_name.str,
|
||||
table->alias,
|
||||
fld->field_name.str);
|
||||
res= true;
|
||||
goto err;
|
||||
}
|
||||
if (expli_table)
|
||||
{
|
||||
if (expli_table != table)
|
||||
{
|
||||
expli_table_err:
|
||||
my_printf_error(
|
||||
ER_VERS_VIEW_PROHIBITED,
|
||||
"Creating VIEW %`s is prohibited: system fields from multiple tables %`s, %`s in query!", MYF(0),
|
||||
view->table_name,
|
||||
expli_table->alias,
|
||||
table->alias);
|
||||
res= true;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
expli_table= table;
|
||||
expli_start= fld;
|
||||
impli_end= &table_end;
|
||||
}
|
||||
else if (table_end == fld->field_name)
|
||||
{
|
||||
if (expli_end)
|
||||
{
|
||||
my_printf_error(
|
||||
ER_VERS_VIEW_PROHIBITED,
|
||||
"Creating VIEW %`s is prohibited: multiple end system fields `%s.%s`, `%s.%s` in query!", MYF(0),
|
||||
view->table_name,
|
||||
expli_table->alias,
|
||||
expli_end->field_name.str,
|
||||
table->alias,
|
||||
fld->field_name.str);
|
||||
res= true;
|
||||
goto err;
|
||||
}
|
||||
if (expli_table)
|
||||
{
|
||||
if (expli_table != table)
|
||||
goto expli_table_err;
|
||||
}
|
||||
else
|
||||
expli_table= table;
|
||||
expli_end= fld;
|
||||
impli_start= &table_start;
|
||||
}
|
||||
} // while ((item= it++))
|
||||
} // for (TABLE_LIST *table)
|
||||
|
||||
if (expli_table)
|
||||
impli_table= expli_table;
|
||||
|
||||
if (impli_table)
|
||||
{
|
||||
if (!expli_start && sl->vers_push_field(thd, impli_table, *impli_start))
|
||||
goto err;
|
||||
if (!expli_end && sl->vers_push_field(thd, impli_table, *impli_end))
|
||||
goto err;
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
} /* System Versioning end */
|
||||
|
||||
view= lex->unlink_first_table(&link_to_local);
|
||||
|
||||
if (check_db_dir_existence(view->db))
|
||||
@ -607,14 +741,22 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
|
||||
view->table_name, item->name.str) &
|
||||
VIEW_ANY_ACL);
|
||||
|
||||
if (fld && !fld->field->table->s->tmp_table)
|
||||
if (!fld)
|
||||
continue;
|
||||
TABLE_SHARE *s= fld->field->table->s;
|
||||
const LString_i field_name= fld->field->field_name;
|
||||
if (s->tmp_table ||
|
||||
(s->versioned &&
|
||||
(field_name == s->vers_start_field()->field_name ||
|
||||
field_name == s->vers_end_field()->field_name)))
|
||||
{
|
||||
|
||||
final_priv&= fld->have_privileges;
|
||||
|
||||
if (~fld->have_privileges & priv)
|
||||
report_item= item;
|
||||
continue;
|
||||
}
|
||||
|
||||
final_priv&= fld->have_privileges;
|
||||
|
||||
if (~fld->have_privileges & priv)
|
||||
report_item= item;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2017,7 +2159,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
|
||||
|
||||
RETURN
|
||||
FALSE OK
|
||||
TRUE error (is not sent to cliet)
|
||||
TRUE error (is not sent to client)
|
||||
*/
|
||||
|
||||
bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
|
||||
@ -2034,7 +2176,15 @@ bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
|
||||
{
|
||||
Item_field *fld;
|
||||
if ((fld= entry->item->field_for_view_update()))
|
||||
{
|
||||
TABLE_SHARE *s= fld->context->table_list->table->s;
|
||||
LString_i field_name= fld->field_name;
|
||||
if (s->versioned &&
|
||||
(field_name == s->vers_start_field()->field_name ||
|
||||
field_name == s->vers_end_field()->field_name))
|
||||
continue;
|
||||
list->push_back(fld, thd->mem_root);
|
||||
}
|
||||
else
|
||||
{
|
||||
my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias, "INSERT");
|
||||
@ -2045,7 +2195,7 @@ bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
|
||||
}
|
||||
|
||||
/*
|
||||
checking view md5 check suum
|
||||
checking view md5 check sum
|
||||
|
||||
SINOPSYS
|
||||
view_checksum()
|
||||
|
Reference in New Issue
Block a user