summaryrefslogtreecommitdiff
path: root/sql/sql_prepare.cc
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2005-10-06 17:54:43 +0300
committerunknown <monty@mysql.com>2005-10-06 17:54:43 +0300
commitc807724f36aa0ecd9f2fa5eca270df949f697803 (patch)
treed92cfa6fa6040c06b41cafe2869f42c993c0ab2b /sql/sql_prepare.cc
parentb34d5bd24733e2e50d4d32c37fa9ebc722177bf2 (diff)
downloadmariadb-git-c807724f36aa0ecd9f2fa5eca270df949f697803.tar.gz
Review of code pushed since last 5.0 pull:
Ensure that ccache is also used for C programs mysql: Ensure that 'delimiter' works the same way in batch mode as in normal mode mysqldump: Change to use ;; (instead of //) as a stored procedure/trigger delimiter Fixed test cases by adding missing DROP's and rename views to be of type 'v#' Removed MY_UNIX_PATH from fn_format() Removed current_db_used from TABLE_LIST Removed usage of 'current_thd' in Item_splocal Removed some compiler warnings A bit faster longlong2str code BUILD/FINISH.sh: Ensure that ccache is also used for C programs BUILD/SETUP.sh: Ensure that ccache is also used for C programs client/mysql.cc: More debugging Ensure that 'delimiter' works the same way in batch mode as in normal mode. Compare 'delimiter' command case-insensitive. The above fixes the delimiter bugs so that we can now use ;; as a trigger/SP function delimiter in mysqldump. client/mysqldump.c: Indentation fixes Use ;; as a delmimiter for stored procedures and triggers instead of // client/mysqltest.c: Indentation fixes include/my_sys.h: Remove not needed MY_UNIX_PATH parameter mysql-test/r/alter_table.result: Better to reuse mysqltest database (test didn't properly delete mysqltest1 at start) mysql-test/r/func_str.result: More testing of CONV() (to ensure that longlong2str() works correctly) mysql-test/r/information_schema.result: Drop all used tables and views Rename view tables to 'v#' to ensure that if this test fails, not a lot of other test fails mysql-test/r/information_schema_inno.result: Drop all used tables mysql-test/r/multi_statement.result: Drop used tables mysql-test/r/mysql.result: Add error messages to result mysql-test/r/mysqldump.result: ;; is now used as SP/trigger delimiter mysql-test/r/mysqlshow.result: Drop used tables mysql-test/r/temp_table.result: Drop used views Rename views to v# mysql-test/t/alter_table.test: Better to reuse mysqltest database (test didn't properly delete mysqltest1 at start) mysql-test/t/func_str.test: More testing of CONV() (to ensure that longlong2str() works correctly) mysql-test/t/information_schema.test: Drop all used tables and views Rename view tables to 'v#' to ensure that if this test fails, not a lot of other test fails mysql-test/t/information_schema_inno.test: Drop all used tables mysql-test/t/multi_statement.test: Drop used tables mysql-test/t/mysql.test: Add error messages to result mysql-test/t/mysqlshow.test: Drop used tables mysql-test/t/temp_table.test: Drop used views Rename views to v# mysys/mf_format.c: Remove not needed MY_UNIX_PATH parameter (This goes against how fn_format() is supposed to work and also conflicts with other options like MY_RETURN_REAL_PATH) sql/ha_federated.cc: Removed extra empty line sql/item.cc: Use 'str_value' instead of 'str_value_ptr' to hold result for Item_splocal Remove some calls to 'thd' in Item_splocal by making 'thd' a class variable One doesn't have to set 'null_value' when calling 'is_null()' sql/item.h: Add THD as a class variable to Item_splocal Use 'str_value' instead of 'str_value_ptr' to hold temp result Fixed bug in Item_hex when used in CAST() sql/item_func.cc: Optimize new code sql/log_event.cc: Move 'to_unix_path()' out of fn_format() sql/opt_range.cc: Simplify code sql/sp_head.cc: Ensure that Item_splocal has thd set before we call '->this_item()' sql/sql_class.cc: Return error if Statement::insert() fails in either hash_insert() sql/sql_parse.cc: Remove 'current_db_used' as we can trivially check if db table qualifier was used without this. Simplify code sql/sql_prepare.cc: Use enum instead of const int, to avoid ugly code for VC++ sql/structs.h: Remove compiler warnings when using STRING_WITH_LEN() with constant strings. sql/table.cc: Fixed indentation sql/table.h: Remove not needed current_db_used strings/decimal.c: Simplify code strings/longlong2str-x86.s: A bit faster longlong2str. (Took some ideas from Peter Gulutzan's code) strings/my_strtoll10.c: Simplify code for MetroWerks compiler
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r--sql/sql_prepare.cc100
1 files changed, 47 insertions, 53 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 6eea101de8f..e9777951db4 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -88,6 +88,11 @@ When one supplies long data for a placeholder:
class Prepared_statement: public Statement
{
public:
+ enum flag_values
+ {
+ IS_IN_USE= 1
+ };
+
THD *thd;
Protocol *protocol;
Item_param **param_array;
@@ -116,19 +121,8 @@ public:
bool execute(String *expanded_query, bool open_cursor);
/* Destroy this statement */
bool deallocate();
-
- /* Possible values of flags */
-#if defined(_MSC_VER) && _MSC_VER < 1300
- static const int IS_IN_USE;
-#else
- static const int IS_IN_USE= 1;
-#endif
};
-/* VC6 can't handle initializing in declaration */
-#if defined(_MSC_VER) && _MSC_VER < 1300
-const int Prepared_statement::IS_IN_USE= 1;
-#endif
/******************************************************************************
Implementation
@@ -1830,7 +1824,7 @@ static void cleanup_stmt_and_thd_after_use(Statement *stmt, THD *thd)
void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length)
{
Prepared_statement *stmt= new Prepared_statement(thd, &thd->protocol_prep);
- bool rc;
+ bool error;
DBUG_ENTER("mysql_stmt_prepare");
DBUG_PRINT("prep_query", ("%s", packet));
@@ -1853,12 +1847,12 @@ void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length)
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
- rc= stmt->prepare(packet, packet_length);
+ error= stmt->prepare(packet, packet_length);
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),WAIT_PRIOR);
- if (rc)
+ if (error)
{
/* Statement map deletes statement on erase */
thd->stmt_map.erase(stmt);
@@ -1900,7 +1894,7 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len)
CHARSET_INFO *to_cs= thd->variables.collation_connection;
bool needs_conversion;
user_var_entry *entry;
- String *pstr= &str;
+ String *var_value= &str;
uint32 unused, len;
/*
Convert @var contents to string in connection character set. Although
@@ -1914,13 +1908,13 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len)
&& entry->value)
{
my_bool is_var_null;
- pstr= entry->val_str(&is_var_null, &str, NOT_FIXED_DEC);
+ var_value= entry->val_str(&is_var_null, &str, NOT_FIXED_DEC);
/*
NULL value of variable checked early as entry->value so here
we can't get NULL in normal conditions
*/
DBUG_ASSERT(!is_var_null);
- if (!pstr)
+ if (!var_value)
goto end;
}
else
@@ -1932,22 +1926,25 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len)
str.set("NULL", 4, &my_charset_latin1);
}
- needs_conversion= String::needs_conversion(pstr->length(),
- pstr->charset(), to_cs, &unused);
+ needs_conversion= String::needs_conversion(var_value->length(),
+ var_value->charset(), to_cs,
+ &unused);
- len= needs_conversion ? pstr->length() * to_cs->mbmaxlen : pstr->length();
+ len= (needs_conversion ? var_value->length() * to_cs->mbmaxlen :
+ var_value->length());
if (!(query_str= alloc_root(thd->mem_root, len+1)))
goto end;
if (needs_conversion)
{
uint dummy_errors;
- len= copy_and_convert(query_str, len, to_cs, pstr->ptr(), pstr->length(),
- pstr->charset(), &dummy_errors);
+ len= copy_and_convert(query_str, len, to_cs, var_value->ptr(),
+ var_value->length(), var_value->charset(),
+ &dummy_errors);
}
else
- memcpy(query_str, pstr->ptr(), pstr->length());
- query_str[len]= '\0';
+ memcpy(query_str, var_value->ptr(), var_value->length());
+ query_str[len]= '\0'; // Safety (mostly for debug)
*query_len= len;
}
else
@@ -1997,10 +1994,9 @@ void mysql_sql_stmt_prepare(THD *thd)
Prepared_statement *stmt;
const char *query;
uint query_len;
-
DBUG_ENTER("mysql_sql_stmt_prepare");
-
DBUG_ASSERT(thd->protocol == &thd->protocol_simple);
+
if ((stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
{
/*
@@ -2182,7 +2178,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
uchar *packet_end= (uchar *) packet + packet_length - 1;
#endif
Prepared_statement *stmt;
- bool rc;
+ bool error;
DBUG_ENTER("mysql_stmt_execute");
packet+= 9; /* stmt_id + 5 bytes of flags */
@@ -2217,11 +2213,11 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
#endif
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
- rc= stmt->execute(&expanded_query,
+ error= stmt->execute(&expanded_query,
test(flags & (ulong) CURSOR_TYPE_READ_ONLY));
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
- if (rc)
+ if (error)
goto err;
mysql_log.write(thd, COM_STMT_EXECUTE, "[%lu] %s", stmt->id, thd->query);
@@ -2263,9 +2259,7 @@ void mysql_sql_stmt_execute(THD *thd)
LEX_STRING *name= &lex->prepared_stmt_name;
/* Query text for binary, general or slow log, if any of them is open */
String expanded_query;
-
DBUG_ENTER("mysql_sql_stmt_execute");
-
DBUG_PRINT("info", ("EXECUTE: %.*s\n", name->length, name->str));
if (!(stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
@@ -2412,7 +2406,6 @@ void mysql_stmt_close(THD *thd, char *packet)
/* There is always space for 4 bytes in packet buffer */
ulong stmt_id= uint4korr(packet);
Prepared_statement *stmt;
-
DBUG_ENTER("mysql_stmt_close");
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close")))
@@ -2422,7 +2415,7 @@ void mysql_stmt_close(THD *thd, char *packet)
The only way currently a statement can be deallocated when it's
in use is from within Dynamic SQL.
*/
- DBUG_ASSERT(! (stmt->flags & Prepared_statement::IS_IN_USE));
+ DBUG_ASSERT(! (stmt->flags & (uint) Prepared_statement::IS_IN_USE));
(void) stmt->deallocate();
DBUG_VOID_RETURN;
@@ -2466,7 +2459,7 @@ void mysql_sql_stmt_close(THD *thd)
mysql_stmt_get_longdata()
thd Thread handle
packet String to append
- packet_length Length of string
+ packet_length Length of string (including end \0)
DESCRIPTION
Get a part of a long data. To make the protocol efficient, we are
@@ -2483,13 +2476,12 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
Prepared_statement *stmt;
Item_param *param;
char *packet_end= packet + packet_length - 1;
-
DBUG_ENTER("mysql_stmt_get_longdata");
statistic_increment(thd->status_var.com_stmt_send_long_data, &LOCK_status);
#ifndef EMBEDDED_LIBRARY
/* Minimal size of long data packet is 6 bytes */
- if ((ulong) (packet_end - packet) < MYSQL_LONG_DATA_HEADER)
+ if (packet_length <= MYSQL_LONG_DATA_HEADER)
{
my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_send_long_data");
DBUG_VOID_RETURN;
@@ -2542,7 +2534,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg)
param_array(0),
param_count(0),
last_errno(0),
- flags(IS_IN_USE)
+ flags((uint) IS_IN_USE)
{
*last_error= '\0';
}
@@ -2676,7 +2668,7 @@ bool Prepared_statement::set_name(LEX_STRING *name_arg)
bool Prepared_statement::prepare(const char *packet, uint packet_len)
{
- bool rc;
+ bool error;
Statement stmt_backup;
Query_arena *old_stmt_arena;
DBUG_ENTER("Prepared_statement::prepare");
@@ -2707,7 +2699,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
lex->safe_to_cache_query= FALSE;
lex->stmt_prepare_mode= TRUE;
- rc= yyparse((void *)thd) || thd->is_fatal_error ||
+ error= yyparse((void *)thd) || thd->is_fatal_error ||
thd->net.report_error || init_param_array(this);
/*
While doing context analysis of the query (in check_prepared_statement)
@@ -2731,10 +2723,10 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
*/
DBUG_ASSERT(thd->free_list == NULL);
- if (rc == 0)
- rc= check_prepared_statement(this, name.str != 0);
+ if (error == 0)
+ error= check_prepared_statement(this, name.str != 0);
- if (rc && thd->lex->sphead)
+ if (error && thd->lex->sphead)
{
delete thd->lex->sphead;
thd->lex->sphead= NULL;
@@ -2745,14 +2737,14 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
thd->restore_backup_statement(this, &stmt_backup);
thd->stmt_arena= old_stmt_arena;
- if (rc == 0)
+ if (error == 0)
{
setup_set_params();
init_stmt_after_parse(lex);
state= Query_arena::PREPARED;
- flags&= ~IS_IN_USE;
+ flags&= ~ (uint) IS_IN_USE;
}
- DBUG_RETURN(rc);
+ DBUG_RETURN(error);
}
/*
@@ -2774,6 +2766,10 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
Preconditions, postconditions.
------------------------------
See the comment for Prepared_statement::prepare().
+
+ RETURN
+ FALSE ok
+ TRUE Error
*/
bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
@@ -2781,7 +2777,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
Statement stmt_backup;
Query_arena *old_stmt_arena;
Item *old_free_list;
- bool rc= 1;
+ bool error= TRUE;
statistic_increment(thd->status_var.com_stmt_execute, &LOCK_status);
@@ -2791,13 +2787,11 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
my_message(last_errno, last_error, MYF(0));
return 1;
}
- if (flags & IS_IN_USE)
+ if (flags & (uint) IS_IN_USE)
{
my_error(ER_PS_NO_RECURSION, MYF(0));
return 1;
}
- /* In case the command has a call to SP which re-uses this statement name */
- flags|= IS_IN_USE;
if (cursor && cursor->is_open())
close_cursor();
@@ -2891,11 +2885,11 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
if (state == Query_arena::PREPARED)
state= Query_arena::EXECUTED;
- rc= 0;
+ error= FALSE;
error:
thd->lock_id= &thd->main_lock_id;
- flags&= ~IS_IN_USE;
- return rc;
+ flags&= ~ (uint) IS_IN_USE;
+ return error;
}
@@ -2905,7 +2899,7 @@ bool Prepared_statement::deallocate()
{
/* We account deallocate in the same manner as mysql_stmt_close */
statistic_increment(thd->status_var.com_stmt_close, &LOCK_status);
- if (flags & IS_IN_USE)
+ if (flags & (uint) IS_IN_USE)
{
my_error(ER_PS_NO_RECURSION, MYF(0));
return TRUE;