1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

after review PS fixes

sql/item_cmpfunc.cc:
  merged in one if
sql/mysql_priv.h:
  removed unused paremeter of check_one_table_access
  declaration of new function for SP share code
sql/set_var.cc:
  function descriotion added
  unneeded parantses removed
sql/sql_acl.cc:
  new parameter to limit number of checked tables for check_grant
sql/sql_acl.h:
  new parameter to limit number of checked tables for check_grant
sql/sql_delete.cc:
  preparation moved in separate function
sql/sql_insert.cc:
  preparation moved in separate function
sql/sql_lex.cc:
  comment style fixed
  unneeded assignment removed
sql/sql_parse.cc:
  new parameter to limit number of checked tables for check_grant
  table list manipulation removed (because of above)
  new precheck function
sql/sql_prepare.cc:
  function rewrited to shere code with sql_prepare.cc
  flow control fixed
sql/sql_show.cc:
  new parameter to limit number of checked tables for check_grant
sql/sql_update.cc:
  preparation moved in separate function
sql/table.h:
  flag renamed
This commit is contained in:
unknown
2004-04-10 01:14:32 +03:00
parent 2384ed8c01
commit 8ab58393c5
13 changed files with 528 additions and 318 deletions

View File

@ -631,42 +631,40 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt)
#endif /*!EMBEDDED_LIBRARY*/
/*
Validate the following information for INSERT statement:
- field existence
- fields count
Validate INSERT statement:
SYNOPSIS
mysql_test_insert_fields()
mysql_test_insert()
stmt prepared statemen handler
tables list of tables queries
RETURN VALUE
0 ok
1 error, sent to the client
-1 error, not sent to client
*/
static int mysql_test_insert_fields(Prepared_statement *stmt,
TABLE_LIST *table_list,
List<Item> &fields,
List<List_item> &values_list,
List<Item> &update_fields,
List<Item> &update_values,
enum_duplicates duplic)
static int mysql_test_insert(Prepared_statement *stmt,
TABLE_LIST *table_list,
List<Item> &fields,
List<List_item> &values_list,
List<Item> &update_fields,
List<Item> &update_values,
enum_duplicates duplic)
{
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
TABLE *table;
List_iterator_fast<List_item> its(values_list);
List_item *values;
int res= -1;
TABLE_LIST *insert_table_list=
(TABLE_LIST*) lex->select_lex.table_list.first;
my_bool update= (lex->value_list.elements ? UPDATE_ACL : 0);
DBUG_ENTER("mysql_test_insert_fields");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong privilege= (lex->duplicates == DUP_REPLACE ?
INSERT_ACL | DELETE_ACL : INSERT_ACL);
if (check_one_table_access(thd, privilege, table_list, 0))
DBUG_RETURN(1);
#endif
if ((res= insert_precheck(thd, table_list, update)))
DBUG_RETURN(res);
/*
open temporary memory pool for temporary data allocated by derived
@ -679,27 +677,16 @@ static int mysql_test_insert_fields(Prepared_statement *stmt,
DBUG_RETURN(-1);
}
table= table_list->table;
if ((values= its++))
{
uint value_count;
ulong counter= 0;
if (check_insert_fields(thd, table, fields, *values, 1) ||
setup_tables(insert_table_list) ||
setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0) ||
(duplic == DUP_UPDATE &&
(setup_fields(thd, 0, insert_table_list, update_fields, 0, 0, 0) ||
setup_fields(thd, 0, insert_table_list, update_values, 0, 0, 0))))
goto error;
if (find_real_table_in_list(table_list->next,
table_list->db, table_list->real_name))
{
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
goto error;
}
if ((res= mysql_prepare_insert(thd, table_list, insert_table_list,
table_list->table, fields, values,
update_fields, update_values, duplic)))
goto error;
value_count= values->elements;
its.rewind();
@ -717,50 +704,38 @@ static int mysql_test_insert_fields(Prepared_statement *stmt,
goto error;
}
}
lex->unit.cleanup();
thd->free_temporary_memory_pool_for_ps_preparing();
DBUG_RETURN(0);
res= 0;
error:
lex->unit.cleanup();
thd->free_temporary_memory_pool_for_ps_preparing();
DBUG_RETURN(-1);
DBUG_RETURN(res);
}
/*
Validate the following information:
UPDATE - set and where clause
DELETE - where clause
Validate UPDATE statement
SYNOPSIS
mysql_test_upd_fields()
mysql_test_delete()
stmt prepared statemen handler
tables list of tables queries
RETURN VALUE
0 success
1 error, sent to client
-1 error, not sent to client
*/
static int mysql_test_upd_fields(Prepared_statement *stmt,
TABLE_LIST *table_list,
List<Item> &fields, List<Item> &values,
COND *conds, ulong privelege)
static int mysql_test_update(Prepared_statement *stmt,
TABLE_LIST *table_list)
{
int res;
THD *thd= stmt->thd;
SELECT_LEX *select_lex= &stmt->lex->select_lex;
TABLE_LIST *upd_table_list=
(TABLE_LIST*) select_lex->table_list.first;
List<Item> all_fields;
uint order_num= select_lex->order_list.elements;
ORDER *order= (ORDER *) select_lex->order_list.first;
SELECT_LEX *select= &stmt->lex->select_lex;
DBUG_ENTER("mysql_test_update");
DBUG_ENTER("mysql_test_upd_fields");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_one_table_access(thd, privelege, table_list, 0))
DBUG_RETURN(1);
// Set privilege for the WHERE clause
table_list->grant.want_privilege= (SELECT_ACL &
~table_list->grant.privilege);
#endif
if ((res= update_precheck(thd, table_list)))
DBUG_RETURN(res);
/*
open temporary memory pool for temporary data allocated by derived
@ -769,57 +744,97 @@ static int mysql_test_upd_fields(Prepared_statement *stmt,
thd->allocate_temporary_memory_pool_for_ps_preparing();
if (open_and_lock_tables(thd, table_list))
goto err;
if (setup_tables(upd_table_list) ||
setup_conds(thd, upd_table_list, &conds) ||
thd->lex->select_lex.setup_ref_array(thd, order_num) ||
setup_fields(thd, 0, upd_table_list, fields, 1, 0, 0) ||
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
upd_table_list, all_fields, all_fields, order) ||
thd->net.report_error)
res= -1;
else
{
TABLE_LIST *update_table_list= (TABLE_LIST *)select->table_list.first;
if (!(res= mysql_prepare_update(thd, table_list,
update_table_list,
&select->where,
select->order_list.elements,
(ORDER *) select->order_list.first)))
{
if (setup_fields(thd, 0, update_table_list,
select->item_list, 1, 0, 0) ||
setup_fields(thd, 0, update_table_list,
stmt->lex->value_list, 0, 0, 0))
res= -1;
}
stmt->lex->unit.cleanup();
goto err;
}
stmt->lex->unit.cleanup();
thd->free_temporary_memory_pool_for_ps_preparing();
/* TODO: here we should send types of placeholders to the client. */
DBUG_RETURN(0);
err:
thd->free_temporary_memory_pool_for_ps_preparing();
DBUG_RETURN(-1);
/* TODO: here we should send types of placeholders to the client. */
DBUG_RETURN(res);
}
/*
Validate the following information:
SELECT - column list
- where clause
- order clause
- having clause
- group by clause
- if no column spec i.e. '*', then setup all fields
Validate DELETE statement
SYNOPSIS
mysql_test_delete()
stmt prepared statemen handler
tables list of tables queries
RETURN VALUE
0 success
1 error, sent to client
-1 error, not sent to client
*/
static int mysql_test_delete(Prepared_statement *stmt,
TABLE_LIST *table_list)
{
int res;
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
DBUG_ENTER("mysql_test_delete");
if ((res= delete_precheck(thd, table_list)))
DBUG_RETURN(res);
/*
open temporary memory pool for temporary data allocated by derived
tables & preparation procedure
*/
thd->allocate_temporary_memory_pool_for_ps_preparing();
if (open_and_lock_tables(thd, table_list))
res= -1;
else
{
res= mysql_prepare_delete(thd, table_list, &lex->select_lex.where);
lex->unit.cleanup();
}
thd->free_temporary_memory_pool_for_ps_preparing();
/* TODO: here we should send types of placeholders to the client. */
DBUG_RETURN(res);
}
/*
Validate SELECT statement.
In case of success, if this query is not EXPLAIN, send column list info
back to client.
SYNOPSIS
mysql_test_select_fields()
mysql_test_select()
stmt prepared statemen handler
tables list of tables queries
RETURN VALUE
0 success
1 error, sent to client
-1 error, not sent to client
*/
static int mysql_test_select_fields(Prepared_statement *stmt,
TABLE_LIST *tables,
List<Item> &fields)
static int mysql_test_select(Prepared_statement *stmt,
TABLE_LIST *tables)
{
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
SELECT_LEX_UNIT *unit= &lex->unit;
DBUG_ENTER("mysql_test_select_fields");
DBUG_ENTER("mysql_test_select");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL;
@ -852,14 +867,15 @@ static int mysql_test_select_fields(Prepared_statement *stmt,
{
thd->used_tables= 0; // Updated by setup_fields
// JOIN::prepare calls
if (unit->prepare(thd, 0, 0))
{
send_error(thd);
goto err_prep;
}
if (send_prep_stmt(stmt, fields.elements) ||
thd->protocol_simple.send_fields(&fields, 0)
if (send_prep_stmt(stmt, lex->select_lex.item_list.elements) ||
thd->protocol_simple.send_fields(&lex->select_lex.item_list, 0)
#ifndef EMBEDDED_LIBRARY
|| net_flush(&thd->net)
#endif
@ -964,11 +980,8 @@ static int mysql_test_set_fields(Prepared_statement *stmt,
goto error;
}
}
stmt->lex->unit.cleanup();
thd->free_temporary_memory_pool_for_ps_preparing();
DBUG_RETURN(0);
error:
stmt->lex->unit.cleanup();
thd->free_temporary_memory_pool_for_ps_preparing();
DBUG_RETURN(res);
}
@ -982,7 +995,7 @@ error:
stmt - prepared table handler
tables - global list of tables
RETURN
RETURN VALUE
0 success
1 error, sent to client
-1 error, not sent to client
@ -1004,6 +1017,7 @@ static int select_like_statement_test(Prepared_statement *stmt,
thd->used_tables= 0; // Updated by setup_fields
// JOIN::prepare calls
if (lex->unit.prepare(thd, 0, 0))
{
res= thd->net.report_error ? -1 : 1;
@ -1035,37 +1049,23 @@ static int mysql_test_create_table(Prepared_statement *stmt,
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
int res= 0;
ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
CREATE_TMP_ACL : CREATE_ACL);
if (check_one_table_access(thd, want_priv, tables, 0) ||
check_merge_table_access(thd, tables->db,
(TABLE_LIST *)
lex->create_info.merge_list.first))
DBUG_RETURN(1);
/* Skip first table, which is the table we are creating */
TABLE_LIST *create_table, *create_table_local;
tables= lex->unlink_first_table(tables, &create_table,
&create_table_local);
&create_table_local);
if (grant_option && want_priv != CREATE_TMP_ACL &&
check_grant(thd, want_priv, create_table,0,0))
{
res= 1;
goto end;
}
if (tables)
if (!(res= create_table_precheck(thd, tables, create_table)) &&
lex->select_lex.item_list.elements)
res= select_like_statement_test(stmt, tables);
end:
// put tables back for PS rexecuting
/* put tables back for PS rexecuting */
tables= lex->link_first_table_back(tables, create_table,
create_table_local);
DBUG_RETURN(res);
}
/*
Validate and prepare for execution multy update statement
@ -1110,7 +1110,7 @@ static int mysql_test_multidelete(Prepared_statement *stmt,
if (add_item_to_list(stmt->thd, new Item_null()))
return -1;
uint fake_counter= 0;
uint fake_counter;
if ((res= multi_delete_precheck(stmt->thd, tables, &fake_counter)))
return res;
return select_like_statement_test(stmt, tables);
@ -1161,78 +1161,68 @@ static int mysql_test_insert_select(Prepared_statement *stmt,
*/
static int send_prepare_results(Prepared_statement *stmt)
{
DBUG_ENTER("send_prepare_results");
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
SELECT_LEX *select_lex= &lex->select_lex;
TABLE_LIST *tables=(TABLE_LIST*) select_lex->table_list.first;
enum enum_sql_command sql_command= lex->sql_command;
int res;
int res= 0;
DBUG_ENTER("send_prepare_results");
DBUG_PRINT("enter",("command: %d, param_count: %ld",
sql_command, stmt->param_count));
if (&lex->select_lex != lex->all_selects_list &&
if (select_lex != lex->all_selects_list &&
lex->unit.create_total_list(thd, lex, &tables))
DBUG_RETURN(1);
switch (sql_command) {
case SQLCOM_REPLACE:
case SQLCOM_INSERT:
if ((res=
mysql_test_insert_fields(stmt, tables, lex->field_list,
lex->many_values,
select_lex->item_list, lex->value_list,
(lex->value_list.elements ?
DUP_UPDATE : lex->duplicates))))
goto error;
res= mysql_test_insert(stmt, tables, lex->field_list,
lex->many_values,
select_lex->item_list, lex->value_list,
(lex->value_list.elements ?
DUP_UPDATE : lex->duplicates));
break;
case SQLCOM_UPDATE:
/* XXX: fallthrough */
res= mysql_test_update(stmt, tables);
break;
case SQLCOM_DELETE:
if ((res= mysql_test_upd_fields(stmt, tables, select_lex->item_list,
lex->value_list, select_lex->where,
((sql_command == SQLCOM_DELETE)?
DELETE_ACL : UPDATE_ACL))))
goto error;
res= mysql_test_delete(stmt, tables);
break;
case SQLCOM_SELECT:
if ((res= mysql_test_select_fields(stmt, tables, select_lex->item_list)))
if ((res= mysql_test_select(stmt, tables)))
goto error;
/* Statement and field info has already been sent */
DBUG_RETURN(0);
case SQLCOM_CREATE_TABLE:
if ((res= mysql_test_create_table(stmt, tables)))
goto error;
res= mysql_test_create_table(stmt, tables);
break;
case SQLCOM_DO:
if ((res= mysql_test_do_fields(stmt, tables, lex->insert_list)))
goto error;
break;
res= mysql_test_do_fields(stmt, tables, lex->insert_list);
break;
case SQLCOM_SET_OPTION:
if ((res= mysql_test_set_fields(stmt, tables, &lex->var_list)))
goto error;
res= mysql_test_set_fields(stmt, tables, &lex->var_list);
break;
case SQLCOM_DELETE_MULTI:
if ((res= mysql_test_multidelete(stmt, tables)))
goto error;
res= mysql_test_multidelete(stmt, tables);
break;
case SQLCOM_UPDATE_MULTI:
if ((res= mysql_test_multiupdate(stmt, tables)))
goto error;
res= mysql_test_multiupdate(stmt, tables);
break;
case SQLCOM_INSERT_SELECT:
if ((res= mysql_test_insert_select(stmt, tables)))
goto error;
res= mysql_test_insert_select(stmt, tables);
break;
case SQLCOM_SHOW_DATABASES:
@ -1263,8 +1253,8 @@ static int send_prepare_results(Prepared_statement *stmt)
my_error(ER_UNSUPPORTED_PS, MYF(0));
goto error;
}
DBUG_RETURN(send_prep_stmt(stmt, 0));
if (res == 0)
DBUG_RETURN(send_prep_stmt(stmt, 0));
error:
if (res < 0)
send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0);