mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Two Sprint tasks and two behaviour changes.
sql/sql_acl.cc: Fix for a grant bug. If there is a table privilege, for which no column privileges are defined , and the same privilege is granted for a column, new code prevents that table privilege is reduced to a column privilege. To accomplish that, now a REVOKE command has to be used first. sql/sql_parse.cc: SCRUM TASK No 1. Adding support for INSERT .. SELECT with a table in the join that is to be inserted into. test case pending. sql/sql_union.cc: Changing behaviour for SQL_OPTION_FOUND_ROWS in unins. sql/sql_yacc.yy: SCRUM TASK no 2. Making CREATE and INSERT to work with any UNION>
This commit is contained in:
@ -2038,7 +2038,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||||||
check->column.c_ptr(), table_list->alias);
|
check->column.c_ptr(), table_list->alias);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
column_priv |= check->rights | (rights & COL_ACLS);
|
column_priv |= check->rights & COL_ACLS;
|
||||||
}
|
}
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
}
|
}
|
||||||
@ -2173,7 +2173,12 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
column_priv|= grant_table->cols;
|
/*
|
||||||
|
This code makes sure that if there is X privilege on the entire table and
|
||||||
|
X can be also a column privilege, that granting column privilege does not
|
||||||
|
revoke a table privilege.
|
||||||
|
*/
|
||||||
|
column_priv&= ~(grant_table->privs & ~grant_table->cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2186,13 +2191,13 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||||||
{ // Crashend table ??
|
{ // Crashend table ??
|
||||||
result= -1; /* purecov: deadcode */
|
result= -1; /* purecov: deadcode */
|
||||||
}
|
}
|
||||||
else if (tables[2].table)
|
else if (tables[2].table && (column_priv | revoke_grant))
|
||||||
{
|
{
|
||||||
if ((replace_column_table(grant_table,tables[2].table, *Str,
|
if ((replace_column_table(grant_table,tables[2].table, *Str,
|
||||||
columns,
|
columns,
|
||||||
table_list->db,
|
table_list->db,
|
||||||
table_list->real_name,
|
table_list->real_name,
|
||||||
rights, revoke_grant)))
|
(revoke_grant) ? rights : column_priv, revoke_grant)))
|
||||||
{
|
{
|
||||||
result= -1;
|
result= -1;
|
||||||
}
|
}
|
||||||
|
@ -1959,11 +1959,6 @@ mysql_execute_command(void)
|
|||||||
if (thd->select_limit < select_lex->select_limit)
|
if (thd->select_limit < select_lex->select_limit)
|
||||||
thd->select_limit= HA_POS_ERROR; // No limit
|
thd->select_limit= HA_POS_ERROR; // No limit
|
||||||
|
|
||||||
if (check_dup(tables->db, tables->real_name, tables->next))
|
|
||||||
{
|
|
||||||
net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name);
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
/* TODO: Delete the following loop when locks is set by sql_yacc */
|
/* TODO: Delete the following loop when locks is set by sql_yacc */
|
||||||
TABLE_LIST *table;
|
TABLE_LIST *table;
|
||||||
@ -3361,8 +3356,16 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
|
|||||||
{
|
{
|
||||||
if (!strcmp(alias_str,tables->alias) && !strcmp(ptr->db, tables->db))
|
if (!strcmp(alias_str,tables->alias) && !strcmp(ptr->db, tables->db))
|
||||||
{
|
{
|
||||||
net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */
|
if ((thd->lex.sql_command & (SQLCOM_INSERT_SELECT | SQLCOM_REPLACE_SELECT))
|
||||||
DBUG_RETURN(0); /* purecov: tested */
|
&& (tables->lock_type & (TL_WRITE_CONCURRENT_INSERT |
|
||||||
|
TL_WRITE_LOW_PRIORITY | TL_WRITE_DELAYED |
|
||||||
|
TL_WRITE)))
|
||||||
|
thd->lex.select->options |= OPTION_BUFFER_RESULT;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */
|
||||||
|
DBUG_RETURN(0); /* purecov: tested */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,10 +63,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
|||||||
*/
|
*/
|
||||||
lex_sl= sl;
|
lex_sl= sl;
|
||||||
order= (ORDER *) lex_sl->order_list.first;
|
order= (ORDER *) lex_sl->order_list.first;
|
||||||
found_rows_for_union = (lex->select_lex.options & OPTION_FOUND_ROWS &&
|
found_rows_for_union = lex->select_lex.options & OPTION_FOUND_ROWS && sl->select_limit;
|
||||||
!describe && sl->select_limit);
|
|
||||||
if (found_rows_for_union)
|
|
||||||
lex->select_lex.options ^= OPTION_FOUND_ROWS;
|
|
||||||
// This is done to eliminate unnecessary slowing down of the first query
|
// This is done to eliminate unnecessary slowing down of the first query
|
||||||
if (!order || !describe)
|
if (!order || !describe)
|
||||||
last_sl->next=0; // Remove this extra element
|
last_sl->next=0; // Remove this extra element
|
||||||
@ -144,7 +141,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
|||||||
thd->select_limit=sl->select_limit+sl->offset_limit;
|
thd->select_limit=sl->select_limit+sl->offset_limit;
|
||||||
if (thd->select_limit < sl->select_limit)
|
if (thd->select_limit < sl->select_limit)
|
||||||
thd->select_limit= HA_POS_ERROR; // no limit
|
thd->select_limit= HA_POS_ERROR; // no limit
|
||||||
if (thd->select_limit == HA_POS_ERROR)
|
if (thd->select_limit == HA_POS_ERROR || sl->braces)
|
||||||
sl->options&= ~OPTION_FOUND_ROWS;
|
sl->options&= ~OPTION_FOUND_ROWS;
|
||||||
|
|
||||||
res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ?
|
res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ?
|
||||||
@ -203,9 +200,12 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
|||||||
{
|
{
|
||||||
thd->offset_limit= 0;
|
thd->offset_limit= 0;
|
||||||
thd->select_limit= thd->variables.select_limit;
|
thd->select_limit= thd->variables.select_limit;
|
||||||
|
if (found_rows_for_union && !describe)
|
||||||
|
thd->options|= OPTION_FOUND_ROWS;
|
||||||
}
|
}
|
||||||
if (describe)
|
if (describe)
|
||||||
thd->select_limit= HA_POS_ERROR; // no limit
|
thd->select_limit= HA_POS_ERROR; // no limit
|
||||||
|
|
||||||
res=mysql_select(thd,&result_table_list,
|
res=mysql_select(thd,&result_table_list,
|
||||||
item_list, NULL, (describe) ? 0 : order,
|
item_list, NULL, (describe) ? 0 : order,
|
||||||
(ORDER*) NULL, NULL, (ORDER*) NULL,
|
(ORDER*) NULL, NULL, (ORDER*) NULL,
|
||||||
@ -264,7 +264,7 @@ bool select_union::send_data(List<Item> &values)
|
|||||||
if ((write_record(table,&info)))
|
if ((write_record(table,&info)))
|
||||||
{
|
{
|
||||||
if (create_myisam_from_heap(thd, table, tmp_table_param, info.last_errno,
|
if (create_myisam_from_heap(thd, table, tmp_table_param, info.last_errno,
|
||||||
0))
|
1))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -595,7 +595,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||||||
table_to_table_list table_to_table opt_table_list opt_as
|
table_to_table_list table_to_table opt_table_list opt_as
|
||||||
handler_rkey_function handler_read_or_scan
|
handler_rkey_function handler_read_or_scan
|
||||||
single_multi table_wild_list table_wild_one opt_wild opt_union union_list
|
single_multi table_wild_list table_wild_one opt_wild opt_union union_list
|
||||||
precision union_option opt_and
|
precision union_option
|
||||||
END_OF_INPUT
|
END_OF_INPUT
|
||||||
|
|
||||||
%type <NONE>
|
%type <NONE>
|
||||||
@ -787,17 +787,31 @@ create:
|
|||||||
|
|
||||||
create2:
|
create2:
|
||||||
'(' field_list ')' opt_create_table_options create3 {}
|
'(' field_list ')' opt_create_table_options create3 {}
|
||||||
| opt_create_table_options create3 {};
|
| opt_create_table_options create3 {}
|
||||||
|
| select_for_create {}
|
||||||
|
;
|
||||||
|
|
||||||
create3:
|
create3:
|
||||||
/* empty */ {}
|
/* empty */ {}
|
||||||
| opt_duplicate opt_as SELECT_SYM
|
| opt_duplicate opt_as select_for_create {}
|
||||||
|
;
|
||||||
|
|
||||||
|
select_for_create:
|
||||||
|
SELECT_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
|
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
|
||||||
mysql_init_select(lex);
|
mysql_init_select(lex);
|
||||||
}
|
}
|
||||||
select_options select_item_list opt_select_from opt_union {};
|
select_options select_item_list opt_select_from { Select->braces= 0;} opt_union
|
||||||
|
|'(' SELECT_SYM
|
||||||
|
{
|
||||||
|
LEX *lex=Lex;
|
||||||
|
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
|
||||||
|
mysql_init_select(lex);
|
||||||
|
}
|
||||||
|
select_options select_item_list opt_select_from ')' { Select->braces= 1;} union_opt
|
||||||
|
;
|
||||||
|
|
||||||
opt_as:
|
opt_as:
|
||||||
/* empty */ {}
|
/* empty */ {}
|
||||||
@ -2600,7 +2614,9 @@ insert_field_spec:
|
|||||||
lex->many_values.push_back(lex->insert_list))
|
lex->many_values.push_back(lex->insert_list))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
ident_eq_list;
|
ident_eq_list
|
||||||
|
| select_for_insert {}
|
||||||
|
;
|
||||||
|
|
||||||
opt_field_spec:
|
opt_field_spec:
|
||||||
/* empty */ { }
|
/* empty */ { }
|
||||||
@ -2609,20 +2625,34 @@ opt_field_spec:
|
|||||||
|
|
||||||
fields:
|
fields:
|
||||||
fields ',' insert_ident { Lex->field_list.push_back($3); }
|
fields ',' insert_ident { Lex->field_list.push_back($3); }
|
||||||
| insert_ident { Lex->field_list.push_back($1); };
|
| insert_ident { Lex->field_list.push_back($1); }
|
||||||
|
;
|
||||||
|
|
||||||
insert_values:
|
insert_values:
|
||||||
VALUES values_list {}
|
VALUES values_list {}
|
||||||
| SELECT_SYM
|
| select_for_insert {}
|
||||||
{
|
;
|
||||||
|
|
||||||
|
select_for_insert:
|
||||||
|
SELECT_SYM
|
||||||
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->sql_command = (lex->sql_command == SQLCOM_INSERT ?
|
lex->sql_command = (lex->sql_command == SQLCOM_INSERT ?
|
||||||
SQLCOM_INSERT_SELECT : SQLCOM_REPLACE_SELECT);
|
SQLCOM_INSERT_SELECT : SQLCOM_REPLACE_SELECT);
|
||||||
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
|
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
|
||||||
mysql_init_select(lex);
|
mysql_init_select(lex);
|
||||||
}
|
}
|
||||||
select_options select_item_list select_from select_lock_type
|
select_options select_item_list opt_select_from select_lock_type { Select->braces= 0;} opt_union
|
||||||
opt_union {};
|
|'(' SELECT_SYM
|
||||||
|
{
|
||||||
|
LEX *lex=Lex;
|
||||||
|
lex->sql_command = (lex->sql_command == SQLCOM_INSERT ?
|
||||||
|
SQLCOM_INSERT_SELECT : SQLCOM_REPLACE_SELECT);
|
||||||
|
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
|
||||||
|
mysql_init_select(lex);
|
||||||
|
}
|
||||||
|
select_options select_item_list opt_select_from select_lock_type ')' { Select->braces= 1;} union_opt
|
||||||
|
;
|
||||||
|
|
||||||
values_list:
|
values_list:
|
||||||
values_list ',' no_braces
|
values_list ',' no_braces
|
||||||
|
Reference in New Issue
Block a user