List:Internals« Previous MessageNext Message »
From:konstantin Date:June 8 2005 3:31pm
Subject:bk commit into 5.0 tree (konstantin:1.1954)
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.1954 05/06/08 19:31:34 konstantin@stripped +1 -0
  Cleanup sql_prepare.cc

  sql/sql_prepare.cc
    1.118 05/06/08 19:31:28 konstantin@stripped +136 -176
    Cleanup mysql_test_* family of calls: now we don't send error message
    from mysql_stmt_prepare, so no need to support -1 return code 
    (meaning error is not sent to client) in these functions.
    Move unit->cleanup() to mysql_stmt_prepare() as it's done in most
    of the mysql_test_ functions, and is a no-op for those which don't
    call unit->prepare(). This should make fixing of Bug#10729 (cursors)
    easier.

# 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:	dragonfly.local
# Root:	/opt/local/work/mysql-5.0-10729

--- 1.117/sql/sql_prepare.cc	2005-06-08 00:34:46 +04:00
+++ 1.118/sql/sql_prepare.cc	2005-06-08 19:31:28 +04:00
@@ -889,8 +889,8 @@
     tables	global/local table list  
 
   RETURN VALUE
-    FALSE OK
-    TRUE  error
+    FALSE  success
+    TRUE   error, error message is set in THD
 */
 
 static bool mysql_test_insert(Prepared_statement *stmt,
@@ -905,11 +905,10 @@
   LEX *lex= stmt->lex;
   List_iterator_fast<List_item> its(values_list);
   List_item *values;
-  bool res;
   DBUG_ENTER("mysql_test_insert");
 
-  if ((res= insert_precheck(thd, table_list)))
-    DBUG_RETURN(res);
+  if (insert_precheck(thd, table_list))
+    goto error;
 
   /*
      open temporary memory pool for temporary data allocated by derived
@@ -920,10 +919,7 @@
      TL_WRITE_DELAYED as having two such locks can cause table corruption.
   */
   if (open_normal_and_derived_tables(thd, table_list))
-  {
-    DBUG_RETURN(TRUE);
-  }
-
+    goto error;
 
   if ((values= its++))
   {
@@ -937,17 +933,14 @@
       table_list->table->insert_values=(byte *)1;
     }
 
-    if ((res= mysql_prepare_insert(thd, table_list, table_list->table, 
-				   fields, values, update_fields,
-				   update_values, duplic,
-                                   &unused_conds, FALSE)))
+    if (mysql_prepare_insert(thd, table_list, table_list->table, fields,
+                             values, update_fields, update_values, duplic,
+                             &unused_conds, FALSE))
       goto error;
 
     value_count= values->elements;
     its.rewind();
 
-    res= TRUE;
-
     if (table_list->lock_type == TL_WRITE_DELAYED &&
         !(table_list->table->file->table_flags() & HA_CAN_INSERT_DELAYED))
     {
@@ -968,12 +961,11 @@
 	goto error;
     }
   }
+  DBUG_RETURN(FALSE);
 
-  res= FALSE;
 error:
-  lex->unit.cleanup();
   /* insert_values is cleared in open_table */
-  DBUG_RETURN(res);
+  DBUG_RETURN(TRUE);
 }
 
 
@@ -987,9 +979,10 @@
 
   RETURN VALUE
     0   success
+    1   error, error message is set in THD
     2   convert to multi_update
-    1   error
 */
+
 static int mysql_test_update(Prepared_statement *stmt,
                               TABLE_LIST *table_list)
 {
@@ -1003,69 +996,60 @@
   DBUG_ENTER("mysql_test_update");
 
   if (update_precheck(thd, table_list))
-    DBUG_RETURN(1);
+    goto error;
+
+  if (open_tables(thd, &table_list, &table_count))
+    goto error;
 
-  if (!open_tables(thd, &table_list, &table_count))
+  if (table_list->multitable_view)
   {
-    if (table_list->multitable_view)
-    {
-      DBUG_ASSERT(table_list->view != 0);
-      DBUG_PRINT("info", ("Switch to multi-update"));
-      /* pass counter value */
-      thd->lex->table_count= table_count;
-      /* convert to multiupdate */
-      return 2;
-    }
+    DBUG_ASSERT(table_list->view != 0);
+    DBUG_PRINT("info", ("Switch to multi-update"));
+    /* pass counter value */
+    thd->lex->table_count= table_count;
+    /* convert to multiupdate */
+    DBUG_RETURN(2);
+  }
 
-    /*
-      thd->fill_derived_tables() is false here for sure (because it is
-      preparation of PS, so we even do not check it
-    */
-    if (lock_tables(thd, table_list, table_count) ||
-	mysql_handle_derived(thd->lex, &mysql_derived_prepare))
-      DBUG_RETURN(1);
+  /*
+    thd->fill_derived_tables() is false here for sure (because it is
+    preparation of PS, so we even do not check it).
+  */
+  if (lock_tables(thd, table_list, table_count) ||
+      mysql_handle_derived(thd->lex, &mysql_derived_prepare))
+    goto error;
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   /* TABLE_LIST contain right privilages request */
   want_privilege= table_list->grant.want_privilege;
 #endif
 
-    if (!(res= mysql_prepare_update(thd, table_list,
-				    &select->where,
-				    select->order_list.elements,
-				    (ORDER *) select->order_list.first)))
-    {
+  if (mysql_prepare_update(thd, table_list, &select->where,
+                           select->order_list.elements,
+                           (ORDER *) select->order_list.first))
+    goto error;
+
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-      table_list->grant.want_privilege=
-        table_list->table->grant.want_privilege=
-        want_privilege;
+  table_list->grant.want_privilege= want_privilege;
+  table_list->table->grant.want_privilege= want_privilege;
 #endif
-      thd->lex->select_lex.no_wrap_view_item= 1;
-      if (setup_fields(thd, 0, table_list, select->item_list, 1, 0, 0))
-      {
-        res= 1;
-        thd->lex->select_lex.no_wrap_view_item= 0;
-      }
-      else
-      {
-        thd->lex->select_lex.no_wrap_view_item= 0;
+  thd->lex->select_lex.no_wrap_view_item= 1;
+  res= setup_fields(thd, 0, table_list, select->item_list, 1, 0, 0);
+  thd->lex->select_lex.no_wrap_view_item= 0;
+  if (res)
+    goto error;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-        /* Check values */
-        table_list->grant.want_privilege=
-          table_list->table->grant.want_privilege=
-          (SELECT_ACL & ~table_list->table->grant.privilege);
+  /* Check values */
+  table_list->grant.want_privilege=
+  table_list->table->grant.want_privilege=
+    (SELECT_ACL & ~table_list->table->grant.privilege);
 #endif
-        if (setup_fields(thd, 0, table_list,
-                         stmt->lex->value_list, 0, 0, 0))
-          res= 1;
-      }
-    }
-    stmt->lex->unit.cleanup();
-  }
-  else
-    res= 1;
+  if (setup_fields(thd, 0, table_list, stmt->lex->value_list, 0, 0, 0))
+    goto error;
   /* TODO: here we should send types of placeholders to the client. */ 
-  DBUG_RETURN(res);
+  DBUG_RETURN(0);
+error:
+  DBUG_RETURN(1);
 }
 
 
@@ -1079,33 +1063,29 @@
 
   RETURN VALUE
     FALSE success
-    TRUE  error
+    TRUE  error, error message is set in THD
 */
-static int mysql_test_delete(Prepared_statement *stmt,
-			     TABLE_LIST *table_list)
+
+static bool mysql_test_delete(Prepared_statement *stmt,
+                              TABLE_LIST *table_list)
 {
   THD *thd= stmt->thd;
   LEX *lex= stmt->lex;
   DBUG_ENTER("mysql_test_delete");
 
-  if (delete_precheck(thd, table_list))
-    DBUG_RETURN(TRUE);
+  if (delete_precheck(thd, table_list) ||
+      open_and_lock_tables(thd, table_list))
+    goto error;
 
-  if (!open_and_lock_tables(thd, table_list))
+  if (!table_list->table)
   {
-    bool res;
-    if (!table_list->table)
-    {
-      my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
-               table_list->view_db.str, table_list->view_name.str);
-      DBUG_RETURN(-1);
-    }
-
-    res= mysql_prepare_delete(thd, table_list, &lex->select_lex.where);
-    lex->unit.cleanup();
-    DBUG_RETURN(res);
+    my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
+             table_list->view_db.str, table_list->view_name.str);
+    goto error;
   }
-  /* TODO: here we should send types of placeholders to the client. */ 
+
+  DBUG_RETURN(mysql_prepare_delete(thd, table_list, &lex->select_lex.where));
+error:
   DBUG_RETURN(TRUE);
 }
 
@@ -1125,13 +1105,12 @@
     TRUE  error, sent to client
 */
 
-static int mysql_test_select(Prepared_statement *stmt,
-			     TABLE_LIST *tables, bool text_protocol)
+static bool mysql_test_select(Prepared_statement *stmt,
+                              TABLE_LIST *tables, bool text_protocol)
 {
   THD *thd= stmt->thd;
   LEX *lex= stmt->lex;
   SELECT_LEX_UNIT *unit= &lex->unit;
-  bool result;
   DBUG_ENTER("mysql_test_select");
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -1139,19 +1118,20 @@
   if (tables)
   {
     if (check_table_access(thd, privilege, tables,0))
-      DBUG_RETURN(TRUE);
+      goto error;
   }
   else if (check_access(thd, privilege, any_db,0,0,0))
-    DBUG_RETURN(TRUE);
+    goto error;
 #endif
 
-  result= TRUE;
   if (!lex->result && !(lex->result= new (stmt->mem_root) select_send))
-    goto err;
+  {
+    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(select_send));
+    goto error;
+  }
 
   if (open_and_lock_tables(thd, tables))
-    goto err;
-
+    goto error;
 
   thd->used_tables= 0;                        // Updated by setup_fields
 
@@ -1161,15 +1141,13 @@
     usual, and we pass 0 as setup_tables_done_option
   */
   if (unit->prepare(thd, 0, 0, ""))
-  {
-    goto err_prep;
-  }
+    goto error;
   if (!text_protocol)
   {
     if (lex->describe)
     {
       if (send_prep_stmt(stmt, 0) || thd->protocol->flush())
-        goto err_prep;
+        goto error;
     }
     else
     {
@@ -1179,7 +1157,7 @@
       /* Change columns if a procedure like analyse() */
       if (unit->last_procedure &&
           unit->last_procedure->change_columns(fields))
-        goto err_prep;
+        goto error;
 
       /*
         We can use lex->result as it should've been
@@ -1188,15 +1166,12 @@
       if (send_prep_stmt(stmt, lex->result->field_count(fields)) ||
           lex->result->send_fields(fields, Protocol::SEND_EOF) ||
           thd->protocol->flush())
-        goto err_prep;
+        goto error;
     }
   }
-  result= FALSE;                                    // ok
-
-err_prep:
-  unit->cleanup();
-err:
-  DBUG_RETURN(result);
+  DBUG_RETURN(FALSE);
+error:
+  DBUG_RETURN(TRUE);
 }
 
 
@@ -1211,26 +1186,22 @@
 
   RETURN VALUE
     FALSE success
-    TRUE  error, sent to client
+    TRUE  error, error message is set in THD
 */
 
 static bool mysql_test_do_fields(Prepared_statement *stmt,
 				TABLE_LIST *tables,
 				List<Item> *values)
 {
-  DBUG_ENTER("mysql_test_do_fields");
   THD *thd= stmt->thd;
-  bool res;
+
+  DBUG_ENTER("mysql_test_do_fields");
   if (tables && check_table_access(thd, SELECT_ACL, tables, 0))
     DBUG_RETURN(TRUE);
 
   if (open_and_lock_tables(thd, tables))
-  {
     DBUG_RETURN(TRUE);
-  }
-  res= setup_fields(thd, 0, 0, *values, 0, 0, 0);
-  stmt->lex->unit.cleanup();
-  DBUG_RETURN(res);
+  DBUG_RETURN(setup_fields(thd, 0, 0, *values, 0, 0, 0));
 }
 
 
@@ -1247,6 +1218,7 @@
     FALSE success
     TRUE  error
 */
+
 static bool mysql_test_set_fields(Prepared_statement *stmt,
                                   TABLE_LIST *tables,
                                   List<set_var_base> *var_list)
@@ -1255,25 +1227,19 @@
   List_iterator_fast<set_var_base> it(*var_list);
   THD *thd= stmt->thd;
   set_var_base *var;
-  bool res;
 
-  if (tables && check_table_access(thd, SELECT_ACL, tables, 0))
-    DBUG_RETURN(TRUE);
-
-  if ((res= open_and_lock_tables(thd, tables)))
+  if (tables && check_table_access(thd, SELECT_ACL, tables, 0) ||
+      open_and_lock_tables(thd, tables))
     goto error;
+
   while ((var= it++))
   {
     if (var->light_check(thd))
-    {
-      stmt->lex->unit.cleanup();
-      res= TRUE;
       goto error;
-    }
   }
+  DBUG_RETURN(FALSE);
 error:
-  stmt->lex->unit.cleanup();
-  DBUG_RETURN(res);
+  DBUG_RETURN(TRUE);
 }
 
 
@@ -1294,7 +1260,7 @@
 
   RETURN VALUE
     FALSE success
-    TRUE  error
+    TRUE  error, error message is set in THD
 */
 
 static bool select_like_stmt_test(Prepared_statement *stmt,
@@ -1304,24 +1270,16 @@
   DBUG_ENTER("select_like_stmt_test");
   THD *thd= stmt->thd;
   LEX *lex= stmt->lex;
-  bool res= FALSE;
 
-  if (specific_prepare && (res= (*specific_prepare)(thd)))
-    goto end;
+  if (specific_prepare && (*specific_prepare)(thd))
+    DBUG_RETURN(TRUE);
 
   thd->used_tables= 0;                        // Updated by setup_fields
 
-  // JOIN::prepare calls
-  if (lex->unit.prepare(thd, 0, setup_tables_done_option, ""))
-  {
-    res= TRUE;
-  }
-end:
-  lex->unit.cleanup();
-  DBUG_RETURN(res);
+  /* Calls JOIN::prepare */
+  DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option, ""));
 }
 
-
 /*
   Check internal SELECT of the prepared command (with opening and
   locking tables used).
@@ -1369,25 +1327,26 @@
     tables	list of tables queries
 
   RETURN VALUE
-    0   success
-    1   error, sent to client
-   -1   error, not sent to client
+    FALSE   success
+    TRUE    error, error message is set in THD
 */
 
-static int mysql_test_create_table(Prepared_statement *stmt)
+static bool mysql_test_create_table(Prepared_statement *stmt)
 {
   DBUG_ENTER("mysql_test_create_table");
   THD *thd= stmt->thd;
   LEX *lex= stmt->lex;
   SELECT_LEX *select_lex= &lex->select_lex;
-  int res= 0;
+  bool res= FALSE;
   /* Skip first table, which is the table we are creating */
   bool link_to_local;
   TABLE_LIST *create_table= lex->unlink_first_table(&link_to_local);
   TABLE_LIST *tables= lex->query_tables;
 
-  if (!(res= create_table_precheck(thd, tables, create_table)) &&
-      select_lex->item_list.elements)
+  if (create_table_precheck(thd, tables, create_table))
+    DBUG_RETURN(TRUE);
+
+  if (select_lex->item_list.elements)
   {
     select_lex->resolve_mode= SELECT_LEX::SELECT_MODE;
     res= select_like_stmt_test_with_open_n_lock(stmt, tables, 0, 0);
@@ -1437,32 +1396,35 @@
 
   RETURN VALUE
     0   success
-    1   error, sent to client
-   -1   error, not sent to client
+    1   error, error message in THD is set.
 */
-static int mysql_test_multidelete(Prepared_statement *stmt,
+
+static bool mysql_test_multidelete(Prepared_statement *stmt,
 				  TABLE_LIST *tables)
 {
-  int res;
+  uint fake_counter;
+
   stmt->thd->lex->current_select= &stmt->thd->lex->select_lex;
   if (add_item_to_list(stmt->thd, new Item_null()))
-    return -1;
+  {
+    my_error(ER_OUTOFMEMORY, MYF(0), 0);
+    goto error;
+  }
 
-  uint fake_counter;
-  if ((res= multi_delete_precheck(stmt->thd, tables, &fake_counter)))
-    return res;
-  if ((res= select_like_stmt_test_with_open_n_lock(stmt, tables,
-                                                   &mysql_multi_delete_prepare,
-                                                   OPTION_SETUP_TABLES_DONE)))
-    return res;
+  if (multi_delete_precheck(stmt->thd, tables, &fake_counter) ||
+      select_like_stmt_test_with_open_n_lock(stmt, tables,
+                                             &mysql_multi_delete_prepare,
+                                             OPTION_SETUP_TABLES_DONE))
+    goto error;
   if (!tables->table)
   {
     my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
 	     tables->view_db.str, tables->view_name.str);
-    return -1;
+    goto error;
   }
-  return 0;
-
+  return FALSE;
+error:
+  return TRUE;
 }
 
 
@@ -1520,8 +1482,8 @@
     tables->table->insert_values=(byte *)1;
   }
 
-  if ((res= insert_precheck(stmt->thd, tables)))
-    return res;
+  if (insert_precheck(stmt->thd, tables))
+    return 1;
 
   /* store it, because mysql_insert_select_prepare_tester change it */
   first_local_table= (TABLE_LIST *)lex->select_lex.table_list.first;
@@ -1552,12 +1514,12 @@
       by calling fix_fields.
 
   RETURN VALUE
-    0   success
-    1   error, sent to client
+    FALSE   success, statement metadata is sent to client
+    TRUE   error, error message is set (but not sent)
 */
 
-static int check_prepared_statement(Prepared_statement *stmt,
-                                    bool text_protocol)
+static bool check_prepared_statement(Prepared_statement *stmt,
+                                     bool text_protocol)
 {
   THD *thd= stmt->thd;
   LEX *lex= stmt->lex;
@@ -1583,7 +1545,7 @@
 
   case SQLCOM_UPDATE:
     res= mysql_test_update(stmt, tables);
-    /* mysql_test_update return 2 if we need to switch to multi-update */
+    /* mysql_test_update returns 2 if we need to switch to multi-update */
     if (res != 2)
       break;
 
@@ -1599,7 +1561,7 @@
     if ((res= mysql_test_select(stmt, tables, text_protocol)))
       goto error;
     /* Statement and field info has already been sent */
-    DBUG_RETURN(0);
+    DBUG_RETURN(FALSE);
 
   case SQLCOM_CREATE_TABLE:
     res= mysql_test_create_table(stmt);
@@ -1650,18 +1612,15 @@
     break;
 
   default:
-    /*
-      All other is not supported yet
-    */
-    res= -1;
+    /* All other statements are not supported yet. */
     my_message(ER_UNSUPPORTED_PS, ER(ER_UNSUPPORTED_PS), MYF(0));
     goto error;
   }
   if (res == 0)
-    DBUG_RETURN(text_protocol? 0 : (send_prep_stmt(stmt, 0) ||
-                                    thd->protocol->flush()));
+    DBUG_RETURN(text_protocol? FALSE : (send_prep_stmt(stmt, 0) ||
+                                        thd->protocol->flush()));
 error:
-  DBUG_RETURN(1);
+  DBUG_RETURN(TRUE);
 }
 
 /*
@@ -1803,6 +1762,7 @@
     thd->lex->sphead= NULL;
   }
   lex_end(lex);
+  lex->unit.cleanup();
   close_thread_tables(thd);
   thd->restore_backup_statement(stmt, &thd->stmt_backup);
   cleanup_items(stmt->free_list);
Thread
bk commit into 5.0 tree (konstantin:1.1954)konstantin8 Jun