mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
WL#1622 "SQL Syntax for Prepared Statements": Post-review fixes (1 of 2)
This commit is contained in:
@@ -21,7 +21,7 @@ a b
|
||||
2 two
|
||||
3 three
|
||||
deallocate prepare no_such_statement;
|
||||
ERROR HY000: Undefined prepared statement
|
||||
ERROR HY000: Unknown prepared statement handler (no_such_statement) given to DEALLOCATE PREPARE
|
||||
execute stmt1;
|
||||
ERROR HY000: Wrong arguments to mysql_execute
|
||||
prepare stmt2 from 'prepare nested_stmt from "select 1"';
|
||||
@@ -98,4 +98,18 @@ set @arg00=NULL ;
|
||||
prepare stmt1 from 'select 1 FROM t2 where a=?' ;
|
||||
execute stmt1 using @arg00 ;
|
||||
1
|
||||
prepare stmt1 from @nosuchvar;
|
||||
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1
|
||||
set @ivar= 1234;
|
||||
prepare stmt1 from @ivar;
|
||||
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '1234' at line 1
|
||||
set @fvar= 123.4567;
|
||||
prepare stmt1 from @fvar;
|
||||
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '123.4567' at line 1
|
||||
set @str1 = 'select ?';
|
||||
set @str2 = convert(@str1 using ucs2);
|
||||
prepare stmt1 from @str2;
|
||||
execute stmt1 using @ivar;
|
||||
?
|
||||
1234
|
||||
drop table t1,t2;
|
||||
|
@@ -98,5 +98,22 @@ set @arg00=NULL ;
|
||||
prepare stmt1 from 'select 1 FROM t2 where a=?' ;
|
||||
execute stmt1 using @arg00 ;
|
||||
|
||||
# prepare using variables:
|
||||
--error 1064
|
||||
prepare stmt1 from @nosuchvar;
|
||||
|
||||
set @ivar= 1234;
|
||||
--error 1064
|
||||
prepare stmt1 from @ivar;
|
||||
|
||||
set @fvar= 123.4567;
|
||||
--error 1064
|
||||
prepare stmt1 from @fvar;
|
||||
|
||||
set @str1 = 'select ?';
|
||||
set @str2 = convert(@str1 using ucs2);
|
||||
prepare stmt1 from @str2;
|
||||
execute stmt1 using @ivar;
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
|
@@ -33,6 +33,12 @@ char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE];
|
||||
nr Errno
|
||||
MyFlags Flags
|
||||
... variable list
|
||||
NOTE
|
||||
The following subset of printf format is supported:
|
||||
"%[0-9.-]*l?[sdu]", where all length flags are parsed but ignored.
|
||||
|
||||
Additionally "%.*s" is supported and "%.*[ud]" is correctly parsed but
|
||||
length value is ignored.
|
||||
*/
|
||||
|
||||
int my_error(int nr,myf MyFlags, ...)
|
||||
@@ -43,7 +49,10 @@ int my_error(int nr,myf MyFlags, ...)
|
||||
reg2 char *endpos;
|
||||
char * par;
|
||||
char ebuff[ERRMSGSIZE+20];
|
||||
int prec_chars;
|
||||
my_bool prec_supplied;
|
||||
DBUG_ENTER("my_error");
|
||||
LINT_INIT(prec_chars); /* protected by prec_supplied */
|
||||
|
||||
va_start(ap,MyFlags);
|
||||
DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d", nr, MyFlags, errno));
|
||||
@@ -59,7 +68,6 @@ int my_error(int nr,myf MyFlags, ...)
|
||||
if (tpos[0] != '%')
|
||||
{
|
||||
*endpos++= *tpos++; /* Copy ordinary char */
|
||||
olen++;
|
||||
continue;
|
||||
}
|
||||
if (*++tpos == '%') /* test if %% */
|
||||
@@ -68,18 +76,45 @@ int my_error(int nr,myf MyFlags, ...)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skipp if max size is used (to be compatible with printf) */
|
||||
while (my_isdigit(&my_charset_latin1, *tpos) || *tpos == '.' || *tpos == '-')
|
||||
/*
|
||||
Skip size/precision flags to be compatible with printf.
|
||||
The only size/precision flag supported is "%.*s".
|
||||
"%.*u" and "%.*d" cause
|
||||
*/
|
||||
prec_supplied= 0;
|
||||
if (*tpos== '.')
|
||||
{
|
||||
tpos++;
|
||||
olen--;
|
||||
if (*tpos == '*')
|
||||
{
|
||||
tpos++;
|
||||
olen--;
|
||||
prec_chars= va_arg(ap, int); /* get length parameter */
|
||||
prec_supplied= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!prec_supplied)
|
||||
{
|
||||
while (my_isdigit(&my_charset_latin1, *tpos) || *tpos == '.' ||
|
||||
*tpos == '-')
|
||||
tpos++;
|
||||
|
||||
if (*tpos == 'l') /* Skipp 'l' argument */
|
||||
tpos++;
|
||||
}
|
||||
|
||||
if (*tpos == 's') /* String parameter */
|
||||
{
|
||||
par = va_arg(ap, char *);
|
||||
plen = (uint) strlen(par);
|
||||
if (prec_supplied && prec_chars > 0)
|
||||
plen= min((uint)prec_chars, plen);
|
||||
if (olen + plen < ERRMSGSIZE+2) /* Replace if possible */
|
||||
{
|
||||
endpos=strmov(endpos,par);
|
||||
memcpy(endpos,par, plen);
|
||||
endpos += plen;
|
||||
tpos++;
|
||||
olen+=plen-2;
|
||||
continue;
|
||||
|
@@ -253,7 +253,7 @@ bool Item::get_time(TIME *ltime)
|
||||
return 0;
|
||||
}
|
||||
|
||||
CHARSET_INFO * Item::default_charset() const
|
||||
CHARSET_INFO * Item::default_charset()
|
||||
{
|
||||
return current_thd->variables.collation_connection;
|
||||
}
|
||||
@@ -678,11 +678,6 @@ void Item_param::set_value(const char *str, uint length, CHARSET_INFO *ci)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void Item_param::set_value(const char *str, uint length)
|
||||
{
|
||||
set_value(str, length, default_charset());
|
||||
}
|
||||
|
||||
|
||||
void Item_param::set_time(TIME *tm, timestamp_type type)
|
||||
{
|
||||
|
@@ -220,7 +220,7 @@ public:
|
||||
virtual Item *real_item() { return this; }
|
||||
virtual Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); }
|
||||
|
||||
CHARSET_INFO *default_charset() const;
|
||||
static CHARSET_INFO *default_charset();
|
||||
virtual CHARSET_INFO *compare_collation() { return NULL; }
|
||||
|
||||
virtual bool walk(Item_processor processor, byte *arg)
|
||||
@@ -413,7 +413,6 @@ public:
|
||||
void set_null();
|
||||
void set_int(longlong i);
|
||||
void set_double(double i);
|
||||
void set_value(const char *str, uint length);
|
||||
void set_value(const char *str, uint length, CHARSET_INFO *ci);
|
||||
void set_long_str(const char *str, ulong length);
|
||||
void set_long_binary(const char *str, ulong length);
|
||||
|
@@ -4842,9 +4842,12 @@ struct show_var_st status_vars[]= {
|
||||
{"Com_unlock_tables", (char*) (com_stat+(uint) SQLCOM_UNLOCK_TABLES),SHOW_LONG},
|
||||
{"Com_update", (char*) (com_stat+(uint) SQLCOM_UPDATE),SHOW_LONG},
|
||||
{"Com_update_multi", (char*) (com_stat+(uint) SQLCOM_UPDATE_MULTI),SHOW_LONG},
|
||||
{"Com_prepare_sql", (char*) (com_stat+(uint) SQLCOM_PREPARE), SHOW_LONG},
|
||||
{"Com_execute_sql", (char*) (com_stat+(uint) SQLCOM_EXECUTE), SHOW_LONG},
|
||||
{"Com_dealloc_sql", (char*) (com_stat+(uint) SQLCOM_DEALLOCATE_PREPARE), SHOW_LONG},
|
||||
{"Com_prepare_sql", (char*) (com_stat+(uint) SQLCOM_PREPARE),
|
||||
SHOW_LONG},
|
||||
{"Com_execute_sql", (char*) (com_stat+(uint) SQLCOM_EXECUTE),
|
||||
SHOW_LONG},
|
||||
{"Com_dealloc_sql", (char*) (com_stat+(uint)
|
||||
SQLCOM_DEALLOCATE_PREPARE), SHOW_LONG},
|
||||
{"Connections", (char*) &thread_id, SHOW_LONG_CONST},
|
||||
{"Created_tmp_disk_tables", (char*) &created_tmp_disk_tables,SHOW_LONG},
|
||||
{"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG},
|
||||
|
@@ -255,7 +255,7 @@ character-set=latin2
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -257,7 +257,7 @@ character-set=latin1
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -246,7 +246,7 @@ character-set=latin1
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -251,7 +251,7 @@ character-set=latin7
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -246,7 +246,7 @@ character-set=latin1
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -258,7 +258,7 @@ character-set=latin1
|
||||
"Schl<68>ssel- und Tabellenverweis passen nicht zusammen",
|
||||
"Operand solle %d Spalte(n) enthalten",
|
||||
"Unterabfrage lieferte mehr als einen Datensatz zur<75>ck",
|
||||
"Unbekannter Prepared-Statement-Handler (%ld) f<>r %s angegeben",
|
||||
"Unbekannter Prepared-Statement-Handler (%.*s) f<>r %s angegeben",
|
||||
"Die Hilfe-Datenbank ist besch<63>digt oder existiert nicht",
|
||||
"Zyklischer Verweis in Unterabfragen",
|
||||
"Spalte '%s' wird von %s nach %s umgewandelt",
|
||||
|
@@ -246,7 +246,7 @@ character-set=greek
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -248,7 +248,7 @@ character-set=latin2
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -246,7 +246,7 @@ character-set=latin1
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -248,7 +248,7 @@ character-set=ujis
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -246,7 +246,7 @@ character-set=euckr
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -248,7 +248,7 @@ character-set=latin1
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -248,7 +248,7 @@ character-set=latin1
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -250,7 +250,7 @@ character-set=latin2
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -247,7 +247,7 @@ character-set=latin1
|
||||
"Refer<65>ncia da chave e refer<65>ncia da tabela n<>o coincidem",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subconsulta retorna mais que 1 registro",
|
||||
"Desconhecido manipulador de declara<72><61>o preparado (%ld) determinado para %s",
|
||||
"Desconhecido manipulador de declara<72><61>o preparado (%.*s) determinado para %s",
|
||||
"Banco de dado de ajuda corrupto ou n<>o existente",
|
||||
"Refer<65>ncia c<>clica em subconsultas",
|
||||
"Convertendo coluna '%s' de %s para %s",
|
||||
|
@@ -250,7 +250,7 @@ character-set=latin2
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -248,7 +248,7 @@ character-set=koi8r
|
||||
"Key reference and table reference doesn't match",
|
||||
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %d <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> '%s' <20><> %s <20> %s",
|
||||
|
@@ -254,7 +254,7 @@ character-set=latin2
|
||||
"Key reference and table reference doesn't match",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returns more than 1 row",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
|
@@ -248,7 +248,7 @@ character-set=latin1
|
||||
"Referencia de llave y referencia de tabla no coinciden",
|
||||
"Operando debe tener %d columna(s)",
|
||||
"Subconsulta retorna mas que 1 l<>nea",
|
||||
"Desconocido preparado comando handler (%ld) dado para %s",
|
||||
"Desconocido preparado comando handler (%.*s) dado para %s",
|
||||
"Base de datos Help est<73> corrupto o no existe",
|
||||
"C<>clica referencia en subconsultas",
|
||||
"Convirtiendo columna '%s' de %s para %s",
|
||||
|
@@ -246,7 +246,7 @@ character-set=latin1
|
||||
"Nyckelreferensen och tabellreferensen st<73>mmer inte <20>verens",
|
||||
"Operand should contain %d column(s)",
|
||||
"Subquery returnerade mer <20>n 1 rad",
|
||||
"Ok<4F>nd PREPARED STATEMENT id (%ld) var given till %s",
|
||||
"Ok<4F>nd PREPARED STATEMENT id (%.*s) var given till %s",
|
||||
"Hj<48>lpdatabasen finns inte eller <20>r skadad",
|
||||
"Cyklisk referens i subqueries",
|
||||
"Konvertar kolumn '%s' fr<66>n %s till %s",
|
||||
|
@@ -251,7 +251,7 @@ character-set=koi8u
|
||||
"Key reference and table reference doesn't match",
|
||||
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> %d <20><><EFBFBD><EFBFBD><EFBFBD>æ<EFBFBD>",
|
||||
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ¦<><C2A6><EFBFBD> <20>i<EFBFBD> 1 <20><><EFBFBD><EFBFBD><EFBFBD>",
|
||||
"Unknown prepared statement handler (%ld) given to %s",
|
||||
"Unknown prepared statement handler (%.*s) given to %s",
|
||||
"Help database is corrupt or does not exist",
|
||||
"<22><><EFBFBD>̦<EFBFBD><CCA6><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> Ц<><D0A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '%s' <20> %s <20> %s",
|
||||
|
@@ -556,8 +556,13 @@ public:
|
||||
Statement *find(ulong id)
|
||||
{
|
||||
if (last_found_statement == 0 || id != last_found_statement->id)
|
||||
last_found_statement= (Statement *) hash_search(&st_hash, (byte *) &id,
|
||||
sizeof(id));
|
||||
{
|
||||
Statement *stmt;
|
||||
stmt= (Statement *) hash_search(&st_hash, (byte *) &id, sizeof(id));
|
||||
if (stmt->name.str)
|
||||
return NULL;
|
||||
last_found_statement= stmt;
|
||||
}
|
||||
return last_found_statement;
|
||||
}
|
||||
void erase(Statement *statement)
|
||||
|
@@ -608,7 +608,13 @@ typedef struct st_lex
|
||||
bool safe_to_cache_query;
|
||||
/* Prepared statements SQL syntax:*/
|
||||
LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
|
||||
LEX_STRING prepared_stmt_code; /* Statement query (in PREPARE )*/
|
||||
/*
|
||||
Prepared statement query text or name of variable that holds the
|
||||
prepared statement (in PREPARE ... queries)
|
||||
*/
|
||||
LEX_STRING prepared_stmt_code;
|
||||
/* If true, prepared_stmt_code is a name of variable that holds the query */
|
||||
bool prepared_stmt_code_is_varref;
|
||||
/* Names of user variables holding parameters (in EXECUTE) */
|
||||
List<LEX_STRING> prepared_stmt_params;
|
||||
st_lex() {}
|
||||
|
@@ -1971,15 +1971,91 @@ mysql_execute_command(THD *thd)
|
||||
break;
|
||||
}
|
||||
case SQLCOM_PREPARE:
|
||||
{
|
||||
char *query_str;
|
||||
uint query_len;
|
||||
if (lex->prepared_stmt_code_is_varref)
|
||||
{
|
||||
/* This is PREPARE stmt FROM @var*/
|
||||
String str;
|
||||
CHARSET_INFO *to_cs= thd->variables.collation_connection;
|
||||
CHARSET_INFO *from_cs;
|
||||
const char *buf;
|
||||
uint buf_len;
|
||||
bool need_conversion;
|
||||
//// psergey: find the variable and convert it.
|
||||
LINT_INIT(from_cs);
|
||||
user_var_entry *entry;
|
||||
uint32 unused;
|
||||
if ((entry=
|
||||
(user_var_entry*)hash_search(&thd->user_vars,
|
||||
(byte*)lex->prepared_stmt_code.str,
|
||||
lex->prepared_stmt_code.length))
|
||||
&& entry->value)
|
||||
{
|
||||
switch (entry->type)
|
||||
{
|
||||
case REAL_RESULT:
|
||||
str.set(*(double*)entry->value, NOT_FIXED_DEC, to_cs);
|
||||
buf_len= str.length();
|
||||
buf= str.ptr();
|
||||
need_conversion= false;
|
||||
break;
|
||||
case INT_RESULT:
|
||||
str.set(*(longlong*)entry->value, to_cs);
|
||||
buf_len= str.length();
|
||||
buf= str.ptr();
|
||||
need_conversion= false;
|
||||
break;
|
||||
case STRING_RESULT:
|
||||
buf_len= entry->length;
|
||||
buf= entry->value;
|
||||
from_cs = entry->collation.collation;
|
||||
need_conversion= String::needs_conversion(entry->length, from_cs,
|
||||
to_cs, &unused);
|
||||
break;
|
||||
default:
|
||||
buf= "";
|
||||
need_conversion= false;
|
||||
buf_len= 0;
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from_cs= &my_charset_bin;
|
||||
str.set("NULL", 4, from_cs);
|
||||
buf= str.ptr();
|
||||
buf_len= str.length();
|
||||
need_conversion= String::needs_conversion(str.length(), from_cs,
|
||||
to_cs, &unused);
|
||||
}
|
||||
|
||||
query_len = need_conversion? (buf_len* to_cs->mbmaxlen) : buf_len;
|
||||
if (!(query_str= alloc_root(&thd->mem_root, query_len+1)))
|
||||
{
|
||||
send_error(thd, ER_OUT_OF_RESOURCES);
|
||||
}
|
||||
|
||||
if (need_conversion)
|
||||
query_len= copy_and_convert(query_str, query_len, to_cs, buf, buf_len,
|
||||
from_cs);
|
||||
else
|
||||
memcpy(query_str, buf, query_len);
|
||||
query_str[query_len] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_PRINT("info", ("PREPARE: %.*s FROM '%.*s' \n",
|
||||
lex->prepared_stmt_name.length,
|
||||
lex->prepared_stmt_name.str,
|
||||
lex->prepared_stmt_code.length,
|
||||
lex->prepared_stmt_code.str));
|
||||
query_str= lex->prepared_stmt_code.str;
|
||||
query_len= lex->prepared_stmt_code.length + 1;
|
||||
}
|
||||
thd->command= COM_PREPARE;
|
||||
if (!mysql_stmt_prepare(thd, lex->prepared_stmt_code.str,
|
||||
lex->prepared_stmt_code.length + 1,
|
||||
if (!mysql_stmt_prepare(thd, query_str, query_len + 1,
|
||||
&lex->prepared_stmt_name))
|
||||
send_ok(thd, 0L, 0L, "Statement prepared");
|
||||
break;
|
||||
@@ -2005,7 +2081,12 @@ mysql_execute_command(THD *thd)
|
||||
send_ok(thd);
|
||||
}
|
||||
else
|
||||
send_error(thd,ER_UNKNOWN_STMT_HANDLER,"Undefined prepared statement");
|
||||
{
|
||||
res= -1;
|
||||
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0),
|
||||
lex->prepared_stmt_name.length, lex->prepared_stmt_name.str,
|
||||
"DEALLOCATE PREPARE");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SQLCOM_DO:
|
||||
|
@@ -135,7 +135,8 @@ find_prepared_statement(THD *thd, ulong id, const char *where,
|
||||
|
||||
if (stmt == 0 || stmt->type() != Statement::PREPARED_STATEMENT)
|
||||
{
|
||||
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), id, where);
|
||||
char llbuf[22];
|
||||
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), 22, llstr(id, llbuf), where);
|
||||
if (se == SEND_ERROR)
|
||||
send_error(thd);
|
||||
return 0;
|
||||
@@ -392,7 +393,7 @@ void set_param_date(Item_param *param, uchar **pos, ulong len)
|
||||
void set_param_str(Item_param *param, uchar **pos, ulong len)
|
||||
{
|
||||
ulong length= get_param_length(pos, len);
|
||||
param->set_value((const char *)*pos, length);
|
||||
param->set_value((const char *)*pos, length, Item::default_charset());
|
||||
*pos+= length;
|
||||
}
|
||||
|
||||
@@ -1376,7 +1377,7 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol)
|
||||
goto error;
|
||||
}
|
||||
if (res == 0)
|
||||
DBUG_RETURN(text_protocol?0:send_prep_stmt(stmt, 0));
|
||||
DBUG_RETURN(text_protocol? 0 : send_prep_stmt(stmt, 0));
|
||||
error:
|
||||
if (res < 0)
|
||||
send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
||||
@@ -1417,25 +1418,31 @@ static bool init_param_array(Prepared_statement *stmt)
|
||||
|
||||
|
||||
/*
|
||||
Given a query string with parameter markers, create a Prepared Statement
|
||||
from it and send PS info back to the client.
|
||||
|
||||
SYNOPSIS
|
||||
mysql_stmt_prepare()
|
||||
packet Prepared query
|
||||
packet_length query length, with ignored trailing NULL or quote char.
|
||||
packet query to be prepared
|
||||
packet_length query string length, including ignored trailing NULL or
|
||||
quote char.
|
||||
name NULL or statement name. For unnamed statements binary PS
|
||||
protocol is used, for named statmenents text protocol is
|
||||
protocol is used, for named statements text protocol is
|
||||
used.
|
||||
RETURN
|
||||
0 OK, statement prepared successfully
|
||||
other Error
|
||||
|
||||
Parse the query and send the total number of parameters
|
||||
and resultset metadata information back to client (if any),
|
||||
without executing the query i.e. without any log/disk
|
||||
writes. This will allow the queries to be re-executed
|
||||
without re-parsing during execute.
|
||||
NOTES
|
||||
This function parses the query and sends the total number of parameters
|
||||
and resultset metadata information back to client (if any), without
|
||||
executing the query i.e. without any log/disk writes. This allows the
|
||||
queries to be re-executed without re-parsing during execute.
|
||||
|
||||
If parameter markers are found in the query, then store
|
||||
the information using Item_param along with maintaining a
|
||||
list in lex->param_array, so that a fast and direct
|
||||
retrieval can be made without going through all field
|
||||
items.
|
||||
If parameter markers are found in the query, then store the information
|
||||
using Item_param along with maintaining a list in lex->param_array, so
|
||||
that a fast and direct retrieval can be made without going through all
|
||||
field items.
|
||||
|
||||
*/
|
||||
|
||||
@@ -1672,12 +1679,13 @@ set_params_data_err:
|
||||
void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
|
||||
{
|
||||
Prepared_statement *stmt;
|
||||
DBUG_ENTER("mysql_stmt_execute");
|
||||
DBUG_ENTER("mysql_sql_stmt_execute");
|
||||
|
||||
if (!(stmt= (Prepared_statement*)thd->stmt_map.find_by_name(stmt_name)))
|
||||
{
|
||||
send_error(thd, ER_UNKNOWN_STMT_HANDLER,
|
||||
"Undefined prepared statement");
|
||||
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), stmt_name->length,
|
||||
stmt_name->str, "EXECUTE");
|
||||
send_error(thd);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@@ -726,7 +726,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
||||
precision subselect_start opt_and charset
|
||||
subselect_end select_var_list select_var_list_init help opt_len
|
||||
opt_extended_describe
|
||||
prepare execute deallocate
|
||||
prepare prepare_src execute deallocate
|
||||
END_OF_INPUT
|
||||
|
||||
%type <NONE>
|
||||
@@ -816,7 +816,7 @@ deallocate:
|
||||
};
|
||||
|
||||
prepare:
|
||||
PREPARE_SYM ident FROM TEXT_STRING_sys
|
||||
PREPARE_SYM ident FROM prepare_src
|
||||
{
|
||||
THD *thd=YYTHD;
|
||||
LEX *lex= thd->lex;
|
||||
@@ -827,7 +827,22 @@ prepare:
|
||||
}
|
||||
lex->sql_command= SQLCOM_PREPARE;
|
||||
lex->prepared_stmt_name= $2;
|
||||
lex->prepared_stmt_code= $4;
|
||||
};
|
||||
|
||||
prepare_src:
|
||||
TEXT_STRING_sys
|
||||
{
|
||||
THD *thd=YYTHD;
|
||||
LEX *lex= thd->lex;
|
||||
lex->prepared_stmt_code= $1;
|
||||
lex->prepared_stmt_code_is_varref= false;
|
||||
}
|
||||
| '@' ident_or_text
|
||||
{
|
||||
THD *thd=YYTHD;
|
||||
LEX *lex= thd->lex;
|
||||
lex->prepared_stmt_code= $2;
|
||||
lex->prepared_stmt_code_is_varref= true;
|
||||
};
|
||||
|
||||
execute:
|
||||
|
Reference in New Issue
Block a user