List:Internals« Previous MessageNext Message »
From:Konstantin Osipov Date:September 2 2005 11:26pm
Subject:bk commit into 5.0 tree (konstantin:1.1946)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of kostja. When kostja does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1946 05/09/03 03:25:59 konstantin@stripped +3 -0
  Merge bk-internal.mysql.com:/home/bk/mysql-5.0
  into  mysql.com:/home/kostja/mysql/mysql-5.0-dsql3

  sql/share/errmsg.txt
    1.42 05/09/03 03:25:41 konstantin@stripped +2 -2
    manual merge

  sql/sql_parse.cc
    1.478 05/09/03 03:15:02 konstantin@stripped +0 -0
    Auto merged

  sql/mysql_priv.h
    1.346 05/09/03 03:15:02 konstantin@stripped +0 -0
    Auto merged

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	konstantin
# Host:	oak.local
# Root:	/home/kostja/mysql/mysql-5.0-dsql3/RESYNC

--- 1.345/sql/mysql_priv.h	2005-09-02 18:06:09 +04:00
+++ 1.346/sql/mysql_priv.h	2005-09-03 03:15:02 +04:00
@@ -589,7 +589,7 @@
 void mysql_parse(THD *thd,char *inBuf,uint length);
 bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
 bool is_update_query(enum enum_sql_command command);
-bool alloc_query(THD *thd, char *packet, ulong packet_length);
+bool alloc_query(THD *thd, const char *packet, uint packet_length);
 void mysql_init_select(LEX *lex);
 void mysql_reset_thd_for_next_command(THD *thd);
 void mysql_init_query(THD *thd, uchar *buf, uint length);
@@ -848,16 +848,17 @@
 bool get_schema_tables_result(JOIN *join);
 
 /* sql_prepare.cc */
-bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, 
-                        LEX_STRING *name);
+
+void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length);
 void mysql_stmt_execute(THD *thd, char *packet, uint packet_length);
-void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name);
-void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length);
 void mysql_stmt_close(THD *thd, char *packet);
+void mysql_sql_stmt_prepare(THD *thd);
+void mysql_sql_stmt_execute(THD *thd);
+void mysql_sql_stmt_close(THD *thd);
+void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length);
 void mysql_stmt_reset(THD *thd, char *packet);
 void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
 void reinit_stmt_before_use(THD *thd, LEX *lex);
-void init_stmt_after_parse(THD*, LEX*);
 
 /* sql_handler.cc */
 bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen);
@@ -1364,8 +1365,8 @@
 /* item_func.cc */
 Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
 		     LEX_STRING component);
-int get_var_with_binlog(THD *thd, LEX_STRING &name,
-                        user_var_entry **out_entry);
+int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
+                        LEX_STRING &name, user_var_entry **out_entry);
 /* log.cc */
 bool flush_error_log(void);
 

--- 1.477/sql/sql_parse.cc	2005-09-02 18:06:09 +04:00
+++ 1.478/sql/sql_parse.cc	2005-09-03 03:15:02 +04:00
@@ -1644,7 +1644,7 @@
   }
   case COM_STMT_PREPARE:
   {
-    mysql_stmt_prepare(thd, packet, packet_length, 0);
+    mysql_stmt_prepare(thd, packet, packet_length);
     break;
   }
   case COM_STMT_CLOSE:
@@ -1664,6 +1664,10 @@
     char *packet_end= thd->query + thd->query_length;
     mysql_log.write(thd,command,"%s",thd->query);
     DBUG_PRINT("query",("%-.4096s",thd->query));
+
+    if (!(specialflag & SPECIAL_NO_PRIOR))
+      my_pthread_setprio(pthread_self(),QUERY_PRIOR);
+
     mysql_parse(thd,thd->query, thd->query_length);
 
     while (!thd->killed && thd->lex->found_semicolon && !thd->net.report_error)
@@ -2220,7 +2224,7 @@
     TRUE  error;  In this case thd->fatal_error is set
 */
 
-bool alloc_query(THD *thd, char *packet, ulong packet_length)
+bool alloc_query(THD *thd, const char *packet, uint packet_length)
 {
   packet_length--;				// Remove end null
   /* Remove garbage at start and end of query */
@@ -2229,7 +2233,7 @@
     packet++;
     packet_length--;
   }
-  char *pos=packet+packet_length;		// Point at end null
+  const char *pos= packet + packet_length;     // Point at end null
   while (packet_length > 0 &&
 	 (pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1])))
   {
@@ -2250,8 +2254,6 @@
   thd->packet.shrink(thd->variables.net_buffer_length);
   thd->convert_buffer.shrink(thd->variables.net_buffer_length);
 
-  if (!(specialflag & SPECIAL_NO_PRIOR))
-    my_pthread_setprio(pthread_self(),QUERY_PRIOR);
   return FALSE;
 }
 
@@ -2466,112 +2468,17 @@
   }
   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;
-      bool need_conversion;
-      user_var_entry *entry;
-      String *pstr= &str;
-      uint32 unused;
-      /*
-        Convert @var contents to string in connection character set. Although
-        it is known that int/real/NULL value cannot be a valid query we still
-        convert it for error messages to uniform.
-      */
-      if ((entry=
-             (user_var_entry*)hash_search(&thd->user_vars,
-                                          (byte*)lex->prepared_stmt_code.str,
-                                          lex->prepared_stmt_code.length))
-          && entry->value)
-      {
-        my_bool is_var_null;
-        pstr= 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)
-          goto error;
-      }
-      else
-      {
-        /*
-          variable absent or equal to NULL, so we need to set variable to
-          something reasonable to get readable error message during parsing
-        */
-        str.set("NULL", 4, &my_charset_latin1);
-      }
-
-      need_conversion=
-        String::needs_conversion(pstr->length(), pstr->charset(),
-                                 to_cs, &unused);
-
-      query_len= need_conversion? (pstr->length() * to_cs->mbmaxlen) :
-                                  pstr->length();
-      if (!(query_str= alloc_root(thd->mem_root, query_len+1)))
-        goto error;
- 
-      if (need_conversion)
-      {
-        uint dummy_errors;
-        query_len= copy_and_convert(query_str, query_len, to_cs,
-                                    pstr->ptr(), pstr->length(),
-                                    pstr->charset(), &dummy_errors);
-      }
-      else
-        memcpy(query_str, pstr->ptr(), pstr->length());
-      query_str[query_len]= 0;
-    }
-    else
-    {
-      query_str= lex->prepared_stmt_code.str;
-      query_len= lex->prepared_stmt_code.length;
-      DBUG_PRINT("info", ("PREPARE: %.*s FROM '%.*s' \n",
-                          lex->prepared_stmt_name.length,
-                          lex->prepared_stmt_name.str,
-                          query_len, query_str));
-    }
-    thd->command= COM_STMT_PREPARE;
-    if (!(res= mysql_stmt_prepare(thd, query_str, query_len + 1,
-                                  &lex->prepared_stmt_name)))
-      send_ok(thd, 0L, 0L, "Statement prepared");
+    mysql_sql_stmt_prepare(thd);
     break;
   }
   case SQLCOM_EXECUTE:
   {
-    DBUG_PRINT("info", ("EXECUTE: %.*s\n",
-                        lex->prepared_stmt_name.length,
-                        lex->prepared_stmt_name.str));
-    mysql_sql_stmt_execute(thd, &lex->prepared_stmt_name);
-    lex->prepared_stmt_params.empty();
+    mysql_sql_stmt_execute(thd);
     break;
   }
   case SQLCOM_DEALLOCATE_PREPARE:
   {
-    Statement* stmt;
-    DBUG_PRINT("info", ("DEALLOCATE PREPARE: %.*s\n", 
-                        lex->prepared_stmt_name.length,
-                        lex->prepared_stmt_name.str));
-    /* We account deallocate in the same manner as mysql_stmt_close */
-    statistic_increment(thd->status_var.com_stmt_close, &LOCK_status);
-    if ((stmt= thd->stmt_map.find_by_name(&lex->prepared_stmt_name)))
-    {
-      thd->stmt_map.erase(stmt);
-      send_ok(thd);
-    }
-    else
-    {
-      my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0),
-               lex->prepared_stmt_name.length,
-               lex->prepared_stmt_name.str,
-               "DEALLOCATE PREPARE");
-      goto error;
-    }
+    mysql_sql_stmt_close(thd);
     break;
   }
   case SQLCOM_DO:
@@ -4128,7 +4035,7 @@
     }
 #endif
     if (lex->sphead->m_type == TYPE_ENUM_FUNCTION &&
-	!lex->sphead->m_has_return)
+	!(lex->sphead->m_flags & sp_head::HAS_RETURN))
     {
       my_error(ER_SP_NORETURN, MYF(0), name);
       delete lex->sphead;
@@ -4217,15 +4124,31 @@
 	ha_rows select_limit;
         /* bits that should be cleared in thd->server_status */
 	uint bits_to_be_cleared= 0;
+        /*
+          Check that the stored procedure doesn't contain Dynamic SQL
+          and doesn't return result sets: such stored procedures can't
+          be called from a function or trigger.
+        */
+        if (thd->in_sub_stmt)
+        {
+          const char *where= (thd->in_sub_stmt & SUB_STMT_TRIGGER ?
+                              "trigger" : "function");
+          if (sp->is_not_allowed_in_function(where))
+            goto error;
+        }
 
 #ifndef EMBEDDED_LIBRARY
 	my_bool nsok= thd->net.no_send_ok;
 	thd->net.no_send_ok= TRUE;
 #endif
-	if (sp->m_multi_results)
+	if (sp->m_flags & sp_head::MULTI_RESULTS)
 	{
 	  if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
 	  {
+            /*
+              The client does not support multiple result sets being sent
+              back
+            */
 	    my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
 #ifndef EMBEDDED_LIBRARY
 	    thd->net.no_send_ok= nsok;
@@ -4269,7 +4192,7 @@
         thd->row_count_func= 0;
         
         /* 
-          We never write CALL statements int binlog:
+          We never write CALL statements into binlog:
            - If the mode is non-prelocked, each statement will be logged
              separately.
            - If the mode is prelocked, the invoking statement will care

--- 1.41/sql/share/errmsg.txt	2005-08-24 00:17:32 +04:00
+++ 1.42/sql/share/errmsg.txt	2005-09-03 03:25:41 +04:00
@@ -5401,3 +5401,5 @@
         eng "Can't update table '%-.64s' in stored function/trigger because it is already used by statement which invoked this stored function/trigger."
 ER_VIEW_PREVENT_UPDATE
         eng "The definition of table '%-.64s' prevents operation %s on table '%-.64s'."
+ER_PS_NO_RECURSION
+        eng "The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner"
Thread
bk commit into 5.0 tree (konstantin:1.1946)Konstantin Osipov3 Sep