~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqltest.c

  • Committer: Brian Aker
  • Date: 2008-07-02 15:58:43 UTC
  • mfrom: (37.1.1 remove_unittest)
  • Revision ID: brian@tangent.org-20080702155843-b30y15sirrcb874u
Removing unittest (merge from patg's tree)

Show diffs side-by-side

added added

removed removed

Lines of Context:
195
195
  /* Used when creating views and sp, to avoid implicit commit */
196
196
  MYSQL* util_mysql;
197
197
  char *name;
 
198
  MYSQL_STMT* stmt;
 
199
 
 
200
#ifdef EMBEDDED_LIBRARY
 
201
  const char *cur_query;
 
202
  int cur_query_len;
 
203
  pthread_mutex_t mutex;
 
204
  pthread_cond_t cond;
 
205
  int query_done;
 
206
#endif /*EMBEDDED_LIBRARY*/
198
207
};
199
208
struct st_connection connections[128];
200
209
struct st_connection* cur_con= NULL, *next_con, *connections_end;
831
840
  DBUG_ENTER("close_connections");
832
841
  for (--next_con; next_con >= connections; --next_con)
833
842
  {
 
843
    if (next_con->stmt)
 
844
      mysql_stmt_close(next_con->stmt);
 
845
    next_con->stmt= 0;
834
846
    mysql_close(&next_con->mysql);
835
847
    if (next_con->util_mysql)
836
848
      mysql_close(next_con->util_mysql);
840
852
}
841
853
 
842
854
 
 
855
void close_statements()
 
856
{
 
857
  struct st_connection *con;
 
858
  DBUG_ENTER("close_statements");
 
859
  for (con= connections; con < next_con; con++)
 
860
  {
 
861
    if (con->stmt)
 
862
      mysql_stmt_close(con->stmt);
 
863
    con->stmt= 0;
 
864
  }
 
865
  DBUG_VOID_RETURN;
 
866
}
 
867
 
 
868
 
843
869
void close_files()
844
870
{
845
871
  DBUG_ENTER("close_files");
3020
3046
                     sizeof(change_user_args)/sizeof(struct command_arg),
3021
3047
                     ',');
3022
3048
 
 
3049
  if (cur_con->stmt)
 
3050
  {
 
3051
    mysql_stmt_close(cur_con->stmt);
 
3052
    cur_con->stmt= NULL;
 
3053
  }
 
3054
 
3023
3055
  if (!ds_user.length)
3024
3056
    dynstr_set(&ds_user, mysql->user);
3025
3057
 
3897
3929
    die("connection '%s' not found in connection pool", name);
3898
3930
 
3899
3931
  DBUG_PRINT("info", ("Closing connection %s", con->name));
 
3932
#ifndef EMBEDDED_LIBRARY
3900
3933
  if (command->type == Q_DIRTY_CLOSE)
3901
3934
  {
3902
3935
    if (con->mysql.net.vio)
3905
3938
      con->mysql.net.vio = 0;
3906
3939
    }
3907
3940
  }
 
3941
#else
 
3942
  /*
 
3943
    As query could be still executed in a separate theread
 
3944
    we need to check if the query's thread was finished and probably wait
 
3945
    (embedded-server specific)
 
3946
  */
 
3947
  wait_query_thread_end(con);
 
3948
#endif /*EMBEDDED_LIBRARY*/
 
3949
  if (con->stmt)
 
3950
    mysql_stmt_close(con->stmt);
 
3951
  con->stmt= 0;
3908
3952
 
3909
3953
  mysql_close(&con->mysql);
3910
3954
 
5290
5334
 
5291
5335
 
5292
5336
/*
 
5337
  Append all results from ps execution to the dynamic string separated
 
5338
  with '\t'. Values may be converted with 'replace_column'
 
5339
*/
 
5340
 
 
5341
void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
 
5342
                        MYSQL_FIELD *fields, uint num_fields)
 
5343
{
 
5344
  MYSQL_BIND *my_bind;
 
5345
  my_bool *is_null;
 
5346
  ulong *length;
 
5347
  uint i;
 
5348
 
 
5349
  /* Allocate array with bind structs, lengths and NULL flags */
 
5350
  my_bind= (MYSQL_BIND*) my_malloc(num_fields * sizeof(MYSQL_BIND),
 
5351
                                MYF(MY_WME | MY_FAE | MY_ZEROFILL));
 
5352
  length= (ulong*) my_malloc(num_fields * sizeof(ulong),
 
5353
                             MYF(MY_WME | MY_FAE));
 
5354
  is_null= (my_bool*) my_malloc(num_fields * sizeof(my_bool),
 
5355
                                MYF(MY_WME | MY_FAE));
 
5356
 
 
5357
  /* Allocate data for the result of each field */
 
5358
  for (i= 0; i < num_fields; i++)
 
5359
  {
 
5360
    uint max_length= fields[i].max_length + 1;
 
5361
    my_bind[i].buffer_type= MYSQL_TYPE_STRING;
 
5362
    my_bind[i].buffer= (char *)my_malloc(max_length, MYF(MY_WME | MY_FAE));
 
5363
    my_bind[i].buffer_length= max_length;
 
5364
    my_bind[i].is_null= &is_null[i];
 
5365
    my_bind[i].length= &length[i];
 
5366
 
 
5367
    DBUG_PRINT("bind", ("col[%d]: buffer_type: %d, buffer_length: %lu",
 
5368
                        i, my_bind[i].buffer_type, my_bind[i].buffer_length));
 
5369
  }
 
5370
 
 
5371
  if (mysql_stmt_bind_result(stmt, my_bind))
 
5372
    die("mysql_stmt_bind_result failed: %d: %s",
 
5373
        mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
 
5374
 
 
5375
  while (mysql_stmt_fetch(stmt) == 0)
 
5376
  {
 
5377
    for (i= 0; i < num_fields; i++)
 
5378
      append_field(ds, i, &fields[i], (const char *) my_bind[i].buffer,
 
5379
                   *my_bind[i].length, *my_bind[i].is_null);
 
5380
    if (!display_result_vertically)
 
5381
      dynstr_append_mem(ds, "\n", 1);
 
5382
  }
 
5383
 
 
5384
  if (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
 
5385
    die("fetch didn't end with MYSQL_NO_DATA from statement: %d %s",
 
5386
        mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
 
5387
 
 
5388
  for (i= 0; i < num_fields; i++)
 
5389
  {
 
5390
    /* Free data for output */
 
5391
    my_free(my_bind[i].buffer, MYF(MY_WME | MY_FAE));
 
5392
  }
 
5393
  /* Free array with bind structs, lengths and NULL flags */
 
5394
  my_free(my_bind    , MYF(MY_WME | MY_FAE));
 
5395
  my_free(length  , MYF(MY_WME | MY_FAE));
 
5396
  my_free(is_null , MYF(MY_WME | MY_FAE));
 
5397
}
 
5398
 
 
5399
 
 
5400
/*
5293
5401
  Append metadata for fields to output
5294
5402
*/
5295
5403
 
5700
5808
}
5701
5809
 
5702
5810
 
 
5811
/*
 
5812
  Run query using prepared statement C API
 
5813
 
 
5814
  SYNPOSIS
 
5815
  run_query_stmt
 
5816
  mysql - mysql handle
 
5817
  command - currrent command pointer
 
5818
  query - query string to execute
 
5819
  query_len - length query string to execute
 
5820
  ds - output buffer where to store result form query
 
5821
 
 
5822
  RETURN VALUE
 
5823
  error - function will not return
 
5824
*/
 
5825
 
 
5826
void run_query_stmt(MYSQL *mysql, struct st_command *command,
 
5827
                    char *query, int query_len, DYNAMIC_STRING *ds,
 
5828
                    DYNAMIC_STRING *ds_warnings)
 
5829
{
 
5830
  MYSQL_RES *res= NULL;     /* Note that here 'res' is meta data result set */
 
5831
  MYSQL_STMT *stmt;
 
5832
  DYNAMIC_STRING ds_prepare_warnings;
 
5833
  DYNAMIC_STRING ds_execute_warnings;
 
5834
  DBUG_ENTER("run_query_stmt");
 
5835
  DBUG_PRINT("query", ("'%-.60s'", query));
 
5836
 
 
5837
  /*
 
5838
    Init a new stmt if it's not already one created for this connection
 
5839
  */
 
5840
  if(!(stmt= cur_con->stmt))
 
5841
  {
 
5842
    if (!(stmt= mysql_stmt_init(mysql)))
 
5843
      die("unable to init stmt structure");
 
5844
    cur_con->stmt= stmt;
 
5845
  }
 
5846
 
 
5847
  /* Init dynamic strings for warnings */
 
5848
  if (!disable_warnings)
 
5849
  {
 
5850
    init_dynamic_string(&ds_prepare_warnings, NULL, 0, 256);
 
5851
    init_dynamic_string(&ds_execute_warnings, NULL, 0, 256);
 
5852
  }
 
5853
 
 
5854
  /*
 
5855
    Prepare the query
 
5856
  */
 
5857
  if (mysql_stmt_prepare(stmt, query, query_len))
 
5858
  {
 
5859
    handle_error(command,  mysql_stmt_errno(stmt),
 
5860
                 mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
 
5861
    goto end;
 
5862
  }
 
5863
 
 
5864
  /*
 
5865
    Get the warnings from mysql_stmt_prepare and keep them in a
 
5866
    separate string
 
5867
  */
 
5868
  if (!disable_warnings)
 
5869
    append_warnings(&ds_prepare_warnings, mysql);
 
5870
 
 
5871
  /*
 
5872
    No need to call mysql_stmt_bind_param() because we have no
 
5873
    parameter markers.
 
5874
  */
 
5875
 
 
5876
#if MYSQL_VERSION_ID >= 50000
 
5877
  if (cursor_protocol_enabled)
 
5878
  {
 
5879
    /*
 
5880
      Use cursor when retrieving result
 
5881
    */
 
5882
    ulong type= CURSOR_TYPE_READ_ONLY;
 
5883
    if (mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type))
 
5884
      die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s",
 
5885
          mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
 
5886
  }
 
5887
#endif
 
5888
 
 
5889
  /*
 
5890
    Execute the query
 
5891
  */
 
5892
  if (mysql_stmt_execute(stmt))
 
5893
  {
 
5894
    handle_error(command, mysql_stmt_errno(stmt),
 
5895
                 mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
 
5896
    goto end;
 
5897
  }
 
5898
 
 
5899
  /*
 
5900
    When running in cursor_protocol get the warnings from execute here
 
5901
    and keep them in a separate string for later.
 
5902
  */
 
5903
  if (cursor_protocol_enabled && !disable_warnings)
 
5904
    append_warnings(&ds_execute_warnings, mysql);
 
5905
 
 
5906
  /*
 
5907
    We instruct that we want to update the "max_length" field in
 
5908
    mysql_stmt_store_result(), this is our only way to know how much
 
5909
    buffer to allocate for result data
 
5910
  */
 
5911
  {
 
5912
    my_bool one= 1;
 
5913
    if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one))
 
5914
      die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s",
 
5915
          mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
 
5916
  }
 
5917
 
 
5918
  /*
 
5919
    If we got here the statement succeeded and was expected to do so,
 
5920
    get data. Note that this can still give errors found during execution!
 
5921
    Store the result of the query if if will return any fields
 
5922
  */
 
5923
  if (mysql_stmt_field_count(stmt) && mysql_stmt_store_result(stmt))
 
5924
  {
 
5925
    handle_error(command, mysql_stmt_errno(stmt),
 
5926
                 mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
 
5927
    goto end;
 
5928
  }
 
5929
 
 
5930
  /* If we got here the statement was both executed and read successfully */
 
5931
  handle_no_error(command);
 
5932
  if (!disable_result_log)
 
5933
  {
 
5934
    /*
 
5935
      Not all statements creates a result set. If there is one we can
 
5936
      now create another normal result set that contains the meta
 
5937
      data. This set can be handled almost like any other non prepared
 
5938
      statement result set.
 
5939
    */
 
5940
    if ((res= mysql_stmt_result_metadata(stmt)) != NULL)
 
5941
    {
 
5942
      /* Take the column count from meta info */
 
5943
      MYSQL_FIELD *fields= mysql_fetch_fields(res);
 
5944
      uint num_fields= mysql_num_fields(res);
 
5945
 
 
5946
      if (display_metadata)
 
5947
        append_metadata(ds, fields, num_fields);
 
5948
 
 
5949
      if (!display_result_vertically)
 
5950
        append_table_headings(ds, fields, num_fields);
 
5951
 
 
5952
      append_stmt_result(ds, stmt, fields, num_fields);
 
5953
 
 
5954
      mysql_free_result(res);     /* Free normal result set with meta data */
 
5955
 
 
5956
      /* Clear prepare warnings */
 
5957
      dynstr_set(&ds_prepare_warnings, NULL);
 
5958
    }
 
5959
    else
 
5960
    {
 
5961
      /*
 
5962
        This is a query without resultset
 
5963
      */
 
5964
    }
 
5965
 
 
5966
    if (!disable_warnings)
 
5967
    {
 
5968
      /* Get the warnings from execute */
 
5969
 
 
5970
      /* Append warnings to ds - if there are any */
 
5971
      if (append_warnings(&ds_execute_warnings, mysql) ||
 
5972
          ds_execute_warnings.length ||
 
5973
          ds_prepare_warnings.length ||
 
5974
          ds_warnings->length)
 
5975
      {
 
5976
        dynstr_append_mem(ds, "Warnings:\n", 10);
 
5977
        if (ds_warnings->length)
 
5978
          dynstr_append_mem(ds, ds_warnings->str,
 
5979
                            ds_warnings->length);
 
5980
        if (ds_prepare_warnings.length)
 
5981
          dynstr_append_mem(ds, ds_prepare_warnings.str,
 
5982
                            ds_prepare_warnings.length);
 
5983
        if (ds_execute_warnings.length)
 
5984
          dynstr_append_mem(ds, ds_execute_warnings.str,
 
5985
                            ds_execute_warnings.length);
 
5986
      }
 
5987
    }
 
5988
 
 
5989
    if (!disable_info)
 
5990
      append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql));
 
5991
 
 
5992
  }
 
5993
 
 
5994
end:
 
5995
  if (!disable_warnings)
 
5996
  {
 
5997
    dynstr_free(&ds_prepare_warnings);
 
5998
    dynstr_free(&ds_execute_warnings);
 
5999
  }
 
6000
 
 
6001
 
 
6002
  /* Close the statement if - no reconnect, need new prepare */
 
6003
  if (mysql->reconnect)
 
6004
  {
 
6005
    mysql_stmt_close(stmt);
 
6006
    cur_con->stmt= NULL;
 
6007
  }
 
6008
 
 
6009
  /*
 
6010
    We save the return code (mysql_stmt_errno(stmt)) from the last call sent
 
6011
    to the server into the mysqltest builtin variable $mysql_errno. This
 
6012
    variable then can be used from the test case itself.
 
6013
  */
 
6014
 
 
6015
  var_set_errno(mysql_stmt_errno(stmt));
 
6016
 
 
6017
  DBUG_VOID_RETURN;
 
6018
}
 
6019
 
 
6020
 
5703
6021
 
5704
6022
/*
5705
6023
  Create a util connection if one does not already exists
6297
6615
        break;
6298
6616
      case Q_ENABLE_RECONNECT:
6299
6617
        set_reconnect(&cur_con->mysql, 1);
 
6618
        /* Close any open statements - no reconnect, need new prepare */
 
6619
        close_statements();
6300
6620
        break;
6301
6621
      case Q_DISABLE_PARSING:
6302
6622
        if (parsing_disabled == 0)