~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqltest.c

  • Committer: Brian Aker
  • Date: 2008-07-02 20:17:52 UTC
  • Revision ID: brian@tangent.org-20080702201752-5vb7lk1ut6y1bhsk
First pass on removing binary protocol from client library.

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*/
207
198
};
208
199
struct st_connection connections[128];
209
200
struct st_connection* cur_con= NULL, *next_con, *connections_end;
840
831
  DBUG_ENTER("close_connections");
841
832
  for (--next_con; next_con >= connections; --next_con)
842
833
  {
843
 
    if (next_con->stmt)
844
 
      mysql_stmt_close(next_con->stmt);
845
 
    next_con->stmt= 0;
846
834
    mysql_close(&next_con->mysql);
847
835
    if (next_con->util_mysql)
848
836
      mysql_close(next_con->util_mysql);
852
840
}
853
841
 
854
842
 
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
 
 
869
843
void close_files()
870
844
{
871
845
  DBUG_ENTER("close_files");
3046
3020
                     sizeof(change_user_args)/sizeof(struct command_arg),
3047
3021
                     ',');
3048
3022
 
3049
 
  if (cur_con->stmt)
3050
 
  {
3051
 
    mysql_stmt_close(cur_con->stmt);
3052
 
    cur_con->stmt= NULL;
3053
 
  }
3054
 
 
3055
3023
  if (!ds_user.length)
3056
3024
    dynstr_set(&ds_user, mysql->user);
3057
3025
 
3929
3897
    die("connection '%s' not found in connection pool", name);
3930
3898
 
3931
3899
  DBUG_PRINT("info", ("Closing connection %s", con->name));
3932
 
#ifndef EMBEDDED_LIBRARY
3933
3900
  if (command->type == Q_DIRTY_CLOSE)
3934
3901
  {
3935
3902
    if (con->mysql.net.vio)
3938
3905
      con->mysql.net.vio = 0;
3939
3906
    }
3940
3907
  }
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;
3952
3908
 
3953
3909
  mysql_close(&con->mysql);
3954
3910
 
5334
5290
 
5335
5291
 
5336
5292
/*
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
 
/*
5401
5293
  Append metadata for fields to output
5402
5294
*/
5403
5295
 
5808
5700
}
5809
5701
 
5810
5702
 
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
 
 
6021
5703
 
6022
5704
/*
6023
5705
  Create a util connection if one does not already exists
6615
6297
        break;
6616
6298
      case Q_ENABLE_RECONNECT:
6617
6299
        set_reconnect(&cur_con->mysql, 1);
6618
 
        /* Close any open statements - no reconnect, need new prepare */
6619
 
        close_statements();
6620
6300
        break;
6621
6301
      case Q_DISABLE_PARSING:
6622
6302
        if (parsing_disabled == 0)