summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
authorunknown <pem@mysql.com>2003-02-18 15:05:35 +0100
committerunknown <pem@mysql.com>2003-02-18 15:05:35 +0100
commit3de0f8d38a0af9311ea970fa032b502341195704 (patch)
tree921e4017c320c9b487bd10d94256dc6227c157f3 /sql/sql_parse.cc
parent49e6a2d0e443f5ba788026a6f9218db12ad23cc4 (diff)
parentd6303970e91fbb072909bdf6d5affc19b2ed4786 (diff)
downloadmariadb-git-3de0f8d38a0af9311ea970fa032b502341195704.tar.gz
Merging 4.1 into 5.0
BitKeeper/etc/gone: auto-union BitKeeper/etc/logging_ok: auto-union client/mysql.cc: Auto merged configure.in: Auto merged client/mysqltest.c: Auto merged mysql-test/r/connect.result: Auto merged mysql-test/r/insert.result: Auto merged mysql-test/r/subselect.result: Auto merged mysql-test/t/insert.test: Auto merged mysql-test/t/subselect.test: Auto merged scripts/mysql_install_db.sh: Auto merged sql/Makefile.am: Auto merged sql/item.h: Auto merged sql/lex.h: Auto merged sql/mysql_priv.h: Auto merged sql/sql_parse.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/share/english/errmsg.txt: Auto merged
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc141
1 files changed, 120 insertions, 21 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d69f95e7248..5d82877d1b3 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -26,6 +26,9 @@
#include "ha_innodb.h"
#endif
+#include "sp_head.h"
+#include "sp.h"
+
#ifdef HAVE_OPENSSL
/*
Without SSL the handshake consists of one packet. This packet
@@ -1570,7 +1573,7 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length)
** Execute command saved in thd and current_lex->sql_command
****************************************************************************/
-void
+int
mysql_execute_command(THD *thd)
{
int res= 0;
@@ -1602,7 +1605,7 @@ mysql_execute_command(THD *thd)
given and the table list says the query should not be replicated
*/
if (table_rules_on && tables && !tables_ok(thd,tables))
- DBUG_VOID_RETURN;
+ DBUG_RETURN(0);
#ifndef TO_BE_DELETED
/*
This is a workaround to deal with the shortcoming in 3.23.44-3.23.46
@@ -1637,7 +1640,7 @@ mysql_execute_command(THD *thd)
{
if (res < 0 || thd->net.report_error)
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(res);
}
}
}
@@ -1650,7 +1653,7 @@ mysql_execute_command(THD *thd)
!tables_ok(thd,tables))
#endif
)
- DBUG_VOID_RETURN;
+ DBUG_RETURN(0);
statistic_increment(com_stat[lex->sql_command],&LOCK_status);
switch (lex->sql_command) {
@@ -1689,7 +1692,7 @@ mysql_execute_command(THD *thd)
if (!(result= new select_send()))
{
send_error(thd, ER_OUT_OF_RESOURCES);
- DBUG_VOID_RETURN;
+ goto error;
}
else
thd->send_explain_fields(result);
@@ -1943,7 +1946,7 @@ mysql_execute_command(THD *thd)
find_real_table_in_list(tables->next, tables->db, tables->real_name))
{
net_printf(thd,ER_UPDATE_TABLE_USED,tables->real_name);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(-1);
}
if (tables->next)
{
@@ -2024,7 +2027,7 @@ mysql_execute_command(THD *thd)
if (thd->locked_tables || thd->active_transaction())
{
send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION);
- break;
+ goto error;
}
{
LOCK_ACTIVE_MI;
@@ -2037,7 +2040,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_ALTER_TABLE:
#if defined(DONT_ALLOW_SHOW_COMMANDS)
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
- break;
+ goto error;
#else
{
ulong priv=0;
@@ -2129,7 +2132,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_BINLOGS:
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
- DBUG_VOID_RETURN;
+ goto error;
#else
{
if (check_global_access(thd, SUPER_ACL))
@@ -2142,7 +2145,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_CREATE:
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
- DBUG_VOID_RETURN;
+ goto error;
#else
{
if (check_db_used(thd, tables) ||
@@ -2214,7 +2217,7 @@ mysql_execute_command(THD *thd)
if (select_lex->item_list.elements != lex->value_list.elements)
{
send_error(thd,ER_WRONG_VALUE_COUNT);
- DBUG_VOID_RETURN;
+ goto error;
}
res= mysql_update(thd,tables,
select_lex->item_list,
@@ -2235,7 +2238,7 @@ mysql_execute_command(THD *thd)
if (select_lex->item_list.elements != lex->value_list.elements)
{
send_error(thd,ER_WRONG_VALUE_COUNT);
- DBUG_VOID_RETURN;
+ goto error;
}
{
const char *msg= 0;
@@ -2271,7 +2274,7 @@ mysql_execute_command(THD *thd)
if (select_lex->item_list.elements != lex->value_list.elements)
{
send_error(thd,ER_WRONG_VALUE_COUNT);
- DBUG_VOID_RETURN;
+ goto error;
}
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
select_lex->item_list, lex->value_list,
@@ -2310,8 +2313,7 @@ mysql_execute_command(THD *thd)
if (find_real_table_in_list(tables->next, tables->db, tables->real_name))
{
- net_printf(thd,ER_UPDATE_TABLE_USED,tables->real_name);
- DBUG_VOID_RETURN;
+ lex->select_lex.options |= OPTION_BUFFER_RESULT;
}
/* Skip first table, which is the table we are inserting in */
@@ -2471,7 +2473,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_DATABASES:
#if defined(DONT_ALLOW_SHOW_COMMANDS)
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
- DBUG_VOID_RETURN;
+ goto error;
#else
if ((specialflag & SPECIAL_SKIP_SHOW_DB) &&
check_global_access(thd, SHOW_DB_ACL))
@@ -2505,7 +2507,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_LOGS:
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
- DBUG_VOID_RETURN;
+ goto error;
#else
{
if (grant_option && check_access(thd, FILE_ACL, any_db))
@@ -2518,7 +2520,7 @@ mysql_execute_command(THD *thd)
/* FALL THROUGH */
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
- DBUG_VOID_RETURN;
+ goto error;
#else
{
char *db=select_lex->db ? select_lex->db : thd->db;
@@ -2554,7 +2556,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_FIELDS:
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
- DBUG_VOID_RETURN;
+ goto error;
#else
{
char *db=tables->db;
@@ -2579,7 +2581,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_KEYS:
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
- DBUG_VOID_RETURN;
+ goto error;
#else
{
char *db=tables->db;
@@ -2949,16 +2951,113 @@ mysql_execute_command(THD *thd)
res= -1;
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
break;
+ case SQLCOM_CREATE_PROCEDURE:
+ if (!lex->sphead)
+ {
+ send_error(thd, ER_SP_NO_RECURSIVE_CREATE);
+ goto error;
+ }
+ else
+ {
+ res= lex->sphead->create(thd);
+ if (res != 0)
+ {
+ send_error(thd, ER_SP_ALREADY_EXISTS);
+ goto error;
+ }
+ send_ok(thd);
+ }
+ break;
+ case SQLCOM_CALL:
+ {
+ Item_string *s;
+ sp_head *sp;
+
+ s= (Item_string*)lex->value_list.head();
+ sp= sp_find_procedure(thd, s);
+ if (! sp)
+ {
+ send_error(thd, ER_SP_DOES_NOT_EXIST);
+ goto error;
+ }
+ else
+ {
+ // When executing substatements, they're assumed to send_error when
+ // it happens, but not to send_ok.
+ my_bool nsok= thd->net.no_send_ok;
+
+ thd->net.no_send_ok= TRUE;
+ res= sp->execute(thd);
+ thd->net.no_send_ok= nsok;
+
+ if (res == 0)
+ send_ok(thd);
+ else
+ goto error; // Substatement should already have sent error
+ }
+ }
+ break;
+ case SQLCOM_ALTER_PROCEDURE:
+ {
+ Item_string *s;
+ sp_head *sp;
+
+ s= (Item_string*)lex->value_list.head();
+ sp= sp_find_procedure(thd, s);
+ if (! sp)
+ {
+ send_error(thd, ER_SP_DOES_NOT_EXIST);
+ goto error;
+ }
+ else
+ {
+ /* QQ This is an no-op right now, since we haven't
+ put the characteristics in yet. */
+ send_ok(thd);
+ }
+ }
+ break;
+ case SQLCOM_DROP_PROCEDURE:
+ {
+ Item_string *s;
+ sp_head *sp;
+
+ s = (Item_string*)lex->value_list.head();
+ sp = sp_find_procedure(thd, s);
+ if (! sp)
+ {
+ send_error(thd, ER_SP_DOES_NOT_EXIST);
+ goto error;
+ }
+ else
+ {
+ String *name = s->const_string();
+
+ res= sp_drop_procedure(thd, name->c_ptr(), name->length());
+ if (res != 0)
+ {
+ send_error(thd, ER_SP_DROP_FAILED);
+ goto error;
+ }
+ send_ok(thd);
+ }
+ }
+ break;
default: /* Impossible */
send_ok(thd);
break;
}
thd->proc_info="query end"; // QQ
+
+ // We end up here if res == 0 and send_ok() has been done,
+ // or res != 0 and no send_error() has yet been done.
if (res < 0)
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
+ DBUG_RETURN(res);
error:
- DBUG_VOID_RETURN;
+ // We end up here if send_error() has already been done.
+ DBUG_RETURN(-1);
}