lib_sql.cc 19.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * Copyright (c)  2000
 * SWsoft  company
 *
 * This material is provided "as is", with absolutely no warranty expressed
 * or implied. Any use is at your own risk.
 *
 * Permission to use or copy this software for any purpose is hereby granted 
 * without fee, provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 *
unknown's avatar
unknown committed
14 15 16

  This code was modified by the MySQL team
*/
17

18 19 20 21
/*
  The following is needed to not cause conflicts when we include mysqld.cc
*/

22 23 24 25
#define main main1
#define mysql_unix_port mysql_inix_port1
#define mysql_port mysql_port1

unknown's avatar
unknown committed
26 27 28 29
static int fake_argc= 1;
static char *fake_argv[]= {(char *)"", 0};
static const char *fake_groups[] = { "server", "embedded", 0 };

unknown's avatar
unknown committed
30 31 32
#if defined (__WIN__)
#include "../sql/mysqld.cpp"
#else
33
#include "../sql/mysqld.cc"
unknown's avatar
unknown committed
34
#endif
35

unknown's avatar
unknown committed
36 37 38
int check_user(THD *thd, enum enum_server_command command, 
	       const char *passwd, uint passwd_len, const char *db,
	       bool check_count);
unknown's avatar
unknown committed
39
C_MODE_START
40
#include <mysql.h>
unknown's avatar
unknown committed
41
#undef ER
42
#include "errmsg.h"
unknown's avatar
SCRUM  
unknown committed
43
#include <sql_common.h>
unknown's avatar
unknown committed
44

unknown's avatar
unknown committed
45 46 47
static my_bool  org_my_init_done;
my_bool         server_inited;

unknown's avatar
SCRUM  
unknown committed
48
static my_bool STDCALL
unknown's avatar
SCRUM  
unknown committed
49 50 51
emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
		     const char *header, ulong header_length,
		     const char *arg, ulong arg_length, my_bool skip_check)
52
{
53
  my_bool result= 1;
54
  THD *thd=(THD *) mysql->thd;
unknown's avatar
unknown committed
55
  NET *net= &mysql->net;
56 57 58 59

  /* Check that we are calling the client functions in right order */
  if (mysql->status != MYSQL_STATUS_READY)
  {
unknown's avatar
unknown committed
60 61
    strmov(net->last_error,
	   ER(net->last_errno=CR_COMMANDS_OUT_OF_SYNC));
62 63 64 65
    return 1;
  }

  /* Clear result variables */
unknown's avatar
unknown committed
66
  thd->clear_error();
67
  mysql->affected_rows= ~(my_ulonglong) 0;
unknown's avatar
SCRUM  
unknown committed
68
  mysql->field_count= 0;
69

70
  thd->store_globals();				// Fix if more than one connect
unknown's avatar
unknown committed
71 72 73 74 75 76
  /* 
     We have to call free_old_query before we start to fill mysql->fields 
     for new query. In the case of embedded server we collect field data
     during query execution (not during data retrieval as it is in remote
     client). So we have to call free_old_query here
  */
unknown's avatar
SCRUM  
unknown committed
77
  free_old_query(mysql);
unknown's avatar
SCRUM  
unknown committed
78 79 80 81 82 83
  if (!arg)
  {
    arg= header;
    arg_length= header_length;
  }

unknown's avatar
SCRUM  
unknown committed
84
  result= dispatch_command(command, thd, (char *) arg, arg_length + 1);
unknown's avatar
unknown committed
85

unknown's avatar
SCRUM  
unknown committed
86
  if (!skip_check)
87
    result= thd->net.last_errno ? -1 : 0;
88

unknown's avatar
unknown committed
89
  if ((net->last_errno= thd->net.last_errno))
90
  {
unknown's avatar
unknown committed
91 92
    memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error));
    memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate));
93
  }
unknown's avatar
unknown committed
94 95
  else
    net->last_error[0]= 0;
unknown's avatar
SCRUM  
unknown committed
96
  mysql->warning_count= ((THD*)mysql->thd)->total_warn_count;
97
  return result;
98 99
}

unknown's avatar
SCRUM  
unknown committed
100 101
static MYSQL_DATA * STDCALL 
emb_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)),
unknown's avatar
SCRUM  
unknown committed
102
	      unsigned int fields __attribute__((unused)))
unknown's avatar
SCRUM  
unknown committed
103 104 105
{
  MYSQL_DATA *result= ((THD*)mysql->thd)->data;
  if (!result)
unknown's avatar
SCRUM  
unknown committed
106 107 108 109 110 111 112 113 114 115 116 117
  {
    if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
					 MYF(MY_WME | MY_ZEROFILL))))
    {
      NET *net = &mysql->net;
      net->last_errno=CR_OUT_OF_MEMORY;
      strmov(net->sqlstate, unknown_sqlstate);
      strmov(net->last_error,ER(net->last_errno));
      return NULL;
    }    
    return result;
  }
unknown's avatar
SCRUM  
unknown committed
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
  *result->prev_ptr= NULL;
  ((THD*)mysql->thd)->data= NULL;
  return result;
}

static MYSQL_FIELD * STDCALL emb_list_fields(MYSQL *mysql)
{
  return mysql->fields;
}

static my_bool STDCALL emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
{
  THD *thd= (THD*)mysql->thd;
  stmt->stmt_id= thd->client_stmt_id;
  stmt->param_count= thd->client_param_count;
  stmt->field_count= mysql->field_count;

  if (stmt->field_count != 0)
  {
    if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
      mysql->server_status|= SERVER_STATUS_IN_TRANS;

    stmt->fields= mysql->fields;
    stmt->mem_root= mysql->field_alloc;
unknown's avatar
SCRUM  
unknown committed
142
    mysql->fields= NULL;
unknown's avatar
SCRUM  
unknown committed
143
  }
unknown's avatar
SCRUM  
unknown committed
144

unknown's avatar
SCRUM  
unknown committed
145 146 147 148 149 150 151 152 153
  return 0;
}

/**************************************************************************
  Get column lengths of the current row
  If one uses mysql_use_result, res->lengths contains the length information,
  else the lengths are calculated from the offset between pointers.
**************************************************************************/

unknown's avatar
SCRUM  
unknown committed
154
static void STDCALL emb_fetch_lengths(ulong *to, MYSQL_ROW column, unsigned int field_count)
unknown's avatar
SCRUM  
unknown committed
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
{ 
  MYSQL_ROW end;

  for (end=column + field_count; column != end ; column++,to++)
    *to= *column ? *(uint *)((*column) - sizeof(uint)) : 0;
}

static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql)
{
  if (mysql->net.last_errno)
    return -1;

  if (mysql->field_count)
    mysql->status=MYSQL_STATUS_GET_RESULT;

  return 0;
}

unknown's avatar
SCRUM  
unknown committed
173 174 175 176 177
static int STDCALL emb_stmt_execute(MYSQL_STMT *stmt)
{
  DBUG_ENTER("emb_stmt_execute");
  THD *thd= (THD*)stmt->mysql->thd;
  thd->client_param_count= stmt->param_count;
unknown's avatar
unknown committed
178
  thd->client_params= stmt->params;
unknown's avatar
SCRUM  
unknown committed
179 180 181 182 183 184 185 186 187 188 189
  if (emb_advanced_command(stmt->mysql, COM_EXECUTE,0,0,
			   (const char*)&stmt->stmt_id,sizeof(stmt->stmt_id),1)
      || emb_mysql_read_query_result(stmt->mysql))
  {
    NET *net= &stmt->mysql->net;
    set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
    DBUG_RETURN(1);
  }
  DBUG_RETURN(0);
}

unknown's avatar
unknown committed
190 191 192 193 194
MYSQL_DATA *emb_read_binary_rows(MYSQL_STMT *stmt)
{
  return emb_read_rows(stmt->mysql, 0, 0);
}

unknown's avatar
SCRUM  
unknown committed
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
int STDCALL emb_unbuffered_fetch(MYSQL *mysql, char **row)
{
  MYSQL_DATA *data= ((THD*)mysql->thd)->data;
  if (!data || !data->data)
  {
    *row= NULL;
    if (data)
    {
      free_rows(data);
      ((THD*)mysql->thd)->data= NULL;
    }
  }
  else
  {
    *row= (char *)data->data->data;
    data->data= data->data->next;
  }
  return 0;
}

unknown's avatar
SCRUM  
unknown committed
215 216 217 218 219 220 221 222
static void STDCALL emb_free_embedded_thd(MYSQL *mysql)
{
  THD *thd= (THD*)mysql->thd;
  if (thd->data)
    free_rows(thd->data);
  delete thd;
}

unknown's avatar
SCRUM  
unknown committed
223 224 225 226 227 228 229 230
MYSQL_METHODS embedded_methods= 
{
  emb_mysql_read_query_result,
  emb_advanced_command,
  emb_read_rows,
  mysql_store_result,
  emb_fetch_lengths, 
  emb_list_fields,
unknown's avatar
SCRUM  
unknown committed
231
  emb_read_prepare_result,
unknown's avatar
unknown committed
232
  emb_stmt_execute,
unknown's avatar
SCRUM  
unknown committed
233
  emb_read_binary_rows,
unknown's avatar
SCRUM  
unknown committed
234 235
  emb_unbuffered_fetch,
  emb_free_embedded_thd
unknown's avatar
SCRUM  
unknown committed
236 237
};

unknown's avatar
unknown committed
238
C_MODE_END
239

240
void THD::clear_error()
241
{
242 243 244
  net.last_error[0]= 0;
  net.last_errno= 0;
  net.report_error= 0;
245 246
}

247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
/*
  Make a copy of array and the strings array points to
*/

char **copy_arguments(int argc, char **argv)
{
  uint length= 0;
  char **from, **res, **end= argv+argc;

  for (from=argv ; from != end ; from++)
    length+= strlen(*from);

  if ((res= (char**) my_malloc(sizeof(argv)*(argc+1)+length+argc,
			       MYF(MY_WME))))
  {
    char **to= res, *to_str= (char*) (res+argc+1);
    for (from=argv ; from != end ;)
    {
      *to++= to_str;
      to_str= strmov(to_str, *from++)+1;
    }
    *to= 0;					// Last ptr should be null
  }
  return res;
}


unknown's avatar
unknown committed
274 275 276
extern "C"
{

277
char **		copy_arguments_ptr= 0; 
unknown's avatar
unknown committed
278

unknown's avatar
unknown committed
279 280 281 282 283 284 285 286 287 288 289 290 291
int STDCALL mysql_server_init(int argc, char **argv, char **groups)
{
  char glob_hostname[FN_REFLEN];

  /* This mess is to allow people to call the init function without
   * having to mess with a fake argv */
  int *argcp;
  char ***argvp;
  int fake_argc = 1;
  char *fake_argv[] = { (char *)"", 0 };
  const char *fake_groups[] = { "server", "embedded", 0 };
  if (argc)
  {
unknown's avatar
unknown committed
292 293
    argcp= &argc;
    argvp= (char***) &argv;
unknown's avatar
unknown committed
294 295 296
  }
  else
  {
unknown's avatar
unknown committed
297 298
    argcp= &fake_argc;
    argvp= (char ***) &fake_argv;
unknown's avatar
unknown committed
299 300
  }
  if (!groups)
unknown's avatar
unknown committed
301
    groups= (char**) fake_groups;
unknown's avatar
unknown committed
302 303 304


  /* Only call MY_INIT() if it hasn't been called before */
unknown's avatar
unknown committed
305
  if (!server_inited)
unknown's avatar
unknown committed
306
  {
unknown's avatar
unknown committed
307
    server_inited=1;
unknown's avatar
unknown committed
308 309 310 311 312 313 314
    org_my_init_done=my_init_done;
  }
  if (!org_my_init_done)
  {
    MY_INIT((char *)"mysql_embedded");	// init my_sys library & pthreads
  }

unknown's avatar
unknown committed
315
  if (init_common_variables("my", *argcp, *argvp, (const char **)groups))
unknown's avatar
unknown committed
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
  {
    mysql_server_end();
    return 1;
  }
    
  /* Get default temporary directory */
  opt_mysql_tmpdir=getenv("TMPDIR");	/* Use this if possible */
#if defined( __WIN__) || defined(OS2)
  if (!opt_mysql_tmpdir)
    opt_mysql_tmpdir=getenv("TEMP");
  if (!opt_mysql_tmpdir)
    opt_mysql_tmpdir=getenv("TMP");
#endif
  if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0])
    opt_mysql_tmpdir=(char*) P_tmpdir;		/* purecov: inspected */

  umask(((~my_umask) & 0666));
  if (init_server_components())
  {
    mysql_server_end();
    return 1;
  }

  error_handler_hook = my_message_sql;

unknown's avatar
unknown committed
341
#ifndef NO_EMBEDDED_ACCESS_CHECKS
unknown's avatar
unknown committed
342
  if (acl_init((THD *)0, opt_noacl))
unknown's avatar
unknown committed
343 344 345 346 347
  {
    mysql_server_end();
    return 1;
  }
  if (!opt_noacl)
unknown's avatar
unknown committed
348
    (void) grant_init((THD *)0);
unknown's avatar
unknown committed
349 350 351

#endif

unknown's avatar
unknown committed
352 353 354 355
  init_max_user_conn();
  init_update_queries();

#ifdef HAVE_DLOPEN
unknown's avatar
unknown committed
356
#ifndef NO_EMBEDDED_ACCESS_CHECKS
unknown's avatar
unknown committed
357
  if (!opt_noacl)
unknown's avatar
unknown committed
358
#endif
unknown's avatar
unknown committed
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
    udf_init();
#endif

  if (opt_bin_log)
  {
    if (!opt_bin_logname)
    {
      char tmp[FN_REFLEN];
      /* TODO: The following should be using fn_format();  We just need to
	 first change fn_format() to cut the file name if it's too long.
      */
      strmake(tmp,glob_hostname,FN_REFLEN-5);
      strmov(strcend(tmp,'.'),"-bin");
      opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
    }
    open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
375
	     opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size);
unknown's avatar
unknown committed
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
    using_update_log=1;
  }

  (void) thr_setconcurrency(concurrency);	// 10 by default

  if (
#ifdef HAVE_BERKELEY_DB
      !berkeley_skip ||
#endif
      (flush_time && flush_time != ~(ulong) 0L))
  {
    pthread_t hThread;
    if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
      sql_print_error("Warning: Can't create thread to manage maintenance");
  }

unknown's avatar
unknown committed
392 393 394 395 396 397 398 399 400
  if (opt_init_file)
  {
    if (read_init_file(opt_init_file))
    {
      mysql_server_end();
      return 1;
    }
  }

unknown's avatar
unknown committed
401 402 403 404 405 406 407 408 409 410 411
  /*
    Update mysqld variables from client variables if set
    The client variables are set also by get_one_option() in mysqld.cc
  */
  if (max_allowed_packet)
    global_system_variables.max_allowed_packet= max_allowed_packet;
  if (net_buffer_length)
    global_system_variables.net_buffer_length= net_buffer_length;
  return 0;
}

412
void STDCALL mysql_server_end()
413
{
unknown's avatar
unknown committed
414 415
  my_free((char*) copy_arguments_ptr, MYF(MY_ALLOW_ZERO_PTR));
  copy_arguments_ptr=0;
unknown's avatar
unknown committed
416 417 418 419 420
  clean_up(0);
#ifdef THREAD
  /* Don't call my_thread_end() if the application is using MY_INIT() */
  if (!org_my_init_done)
    my_thread_end();
421
#endif
422 423 424
  /* If library called my_init(), free memory allocated by it */
  if (!org_my_init_done)
    my_end(0);
unknown's avatar
unknown committed
425 426
}

unknown's avatar
unknown committed
427
} /* extern "C" */
428

429
C_MODE_START
430 431
void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db)
{
432
  THD *thd = (THD *)mysql->thd;
433 434
  thd->mysql= mysql;
}
435

436
void *create_embedded_thd(int client_flag, char *db)
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
{
  THD * thd= new THD;
  thd->thread_id= thread_id++;

  if (thd->store_globals())
  {
    fprintf(stderr,"store_globals failed.\n");
    return NULL;
  }

  thd->mysys_var= my_thread_var;
  thd->dbug_thread_id= my_thread_id();
  thd->thread_stack= (char*) &thd;

  thd->proc_info=0;				// Remove 'login'
  thd->command=COM_SLEEP;
  thd->version=refresh_version;
  thd->set_time();
  init_sql_alloc(&thd->mem_root,8192,8192);
  thd->client_capabilities= client_flag;

  thd->db= db;
unknown's avatar
unknown committed
459
  thd->db_length= db ? strip_sp(db) : 0;
unknown's avatar
unknown committed
460
#ifndef NO_EMBEDDED_ACCESS_CHECKS
461 462
  thd->db_access= DB_ACLS;
  thd->master_access= ~NO_ACCESS;
unknown's avatar
unknown committed
463
#endif
464
  thd->net.query_cache_query= 0;
465

unknown's avatar
SCRUM  
unknown committed
466 467
  thd->data= 0;

468 469
  return thd;
}
470

unknown's avatar
unknown committed
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
#ifndef NO_EMBEDDED_ACCESS_CHECKS
int check_embedded_connection(MYSQL *mysql)
{
  THD *thd= (THD*)mysql->thd;
  int result;
  char scramble_buff[SCRAMBLE_LENGTH];
  int passwd_len;

  thd->host= mysql->options.client_ip ?
    mysql->options.client_ip : (char*)my_localhost;
  thd->ip= thd->host;
  thd->host_or_ip= thd->host;

  if (acl_check_host(thd->host,thd->ip))
  {
    result= ER_HOST_NOT_PRIVILEGED;
    goto err;
  }

  thd->user= mysql->user;
  if (mysql->passwd && mysql->passwd[0])
  {
    memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble
    thd->scramble[SCRAMBLE_LENGTH]= 0;
    scramble(scramble_buff, thd->scramble, mysql->passwd);
    passwd_len= SCRAMBLE_LENGTH;
  }
  else
    passwd_len= 0;

  if((result= check_user(thd, COM_CONNECT, 
			 scramble_buff, passwd_len, thd->db, true)))
     goto err;

  return 0;
err:
  {
    NET *net= &mysql->net;
    memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error));
    memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate));
  }
  return result;
}
#endif

516
C_MODE_END
517

unknown's avatar
unknown committed
518 519 520 521
bool Protocol::send_fields(List<Item> *list, uint flag)
{
  List_iterator_fast<Item> it(*list);
  Item                     *item;
unknown's avatar
SCRUM  
unknown committed
522
  MYSQL_FIELD              *client_field;
unknown's avatar
unknown committed
523
  MYSQL                    *mysql= thd->mysql;
unknown's avatar
SCRUM  
unknown committed
524
  MEM_ROOT                 *field_alloc;
unknown's avatar
unknown committed
525
  
unknown's avatar
SCRUM  
unknown committed
526
  DBUG_ENTER("send_fields");
unknown's avatar
unknown committed
527

unknown's avatar
unknown committed
528 529 530
  if (!mysql)            // bootstrap file handling
    DBUG_RETURN(0);

unknown's avatar
SCRUM  
unknown committed
531
  field_count= list->elements;
unknown's avatar
SCRUM  
unknown committed
532 533 534 535
  field_alloc= &mysql->field_alloc;
  if (!(client_field= thd->mysql->fields= 
	(MYSQL_FIELD *)alloc_root(field_alloc, 
				  sizeof(MYSQL_FIELD) * field_count)))
unknown's avatar
unknown committed
536 537 538 539 540 541 542
    goto err;

  while ((item= it++))
  {
    Send_field server_field;
    item->make_field(&server_field);

unknown's avatar
SCRUM  
unknown committed
543 544 545 546 547
    client_field->db=	  strdup_root(field_alloc, server_field.db_name);
    client_field->table=  strdup_root(field_alloc, server_field.table_name);
    client_field->name=   strdup_root(field_alloc, server_field.col_name);
    client_field->org_table= strdup_root(field_alloc, server_field.org_table_name);
    client_field->org_name=  strdup_root(field_alloc, server_field.org_col_name);
unknown's avatar
unknown committed
548 549 550 551
    client_field->length= server_field.length;
    client_field->type=   server_field.type;
    client_field->flags= server_field.flags;
    client_field->decimals= server_field.decimals;
552 553 554 555 556 557 558
    client_field->db_length=		strlen(client_field->db);
    client_field->table_length=		strlen(client_field->table);
    client_field->name_length=		strlen(client_field->name);
    client_field->org_name_length=	strlen(client_field->org_name);
    client_field->org_table_length=	strlen(client_field->org_table);
    client_field->charsetnr=		server_field.charsetnr;
    
unknown's avatar
unknown committed
559 560 561 562 563 564 565 566 567
    if (INTERNAL_NUM_FIELD(client_field))
      client_field->flags|= NUM_FLAG;

    if (flag & 2)
    {
      char buff[80];
      String tmp(buff, sizeof(buff), default_charset_info), *res;

      if (!(res=item->val_str(&tmp)))
unknown's avatar
SCRUM  
unknown committed
568
	client_field->def= strdup_root(field_alloc, "");
unknown's avatar
unknown committed
569
      else
unknown's avatar
SCRUM  
unknown committed
570
	client_field->def= strdup_root(field_alloc, tmp.ptr());
unknown's avatar
unknown committed
571 572 573 574 575 576
    }
    else
      client_field->def=0;
    client_field->max_length= 0;
    ++client_field;
  }
unknown's avatar
SCRUM  
unknown committed
577
  thd->mysql->field_count= field_count;
unknown's avatar
unknown committed
578

unknown's avatar
SCRUM  
unknown committed
579
  DBUG_RETURN(prepare_for_send(list));
unknown's avatar
unknown committed
580 581
 err:
  send_error(thd, ER_OUT_OF_RESOURCES);	/* purecov: inspected */
unknown's avatar
SCRUM  
unknown committed
582
  DBUG_RETURN(1);				/* purecov: inspected */
unknown's avatar
unknown committed
583 584
}

unknown's avatar
SCRUM  
unknown committed
585
bool Protocol::send_records_num(List<Item> *list, ulonglong records)
unknown's avatar
SCRUM  
unknown committed
586 587 588 589
{
  return false;
}

unknown's avatar
SCRUM  
unknown committed
590
bool Protocol::write()
unknown's avatar
unknown committed
591
{
unknown's avatar
unknown committed
592 593 594
  if (!thd->mysql)            // bootstrap file handling
    return false;

unknown's avatar
SCRUM  
unknown committed
595 596
  *next_field= 0;
  return false;
unknown's avatar
unknown committed
597
}
598

unknown's avatar
unknown committed
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
bool Protocol_prep::write()
{
  MYSQL_ROWS *cur;
  MYSQL_DATA *data= thd->data;

  if (!data)
  {
    if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
					MYF(MY_WME | MY_ZEROFILL))))
      return true;
    
    alloc= &data->alloc;
    init_alloc_root(alloc,8192,0);	/* Assume rowlength < 8192 */
    alloc->min_malloc=sizeof(MYSQL_ROWS);
    data->rows=0;
    data->fields=field_count;
    data->prev_ptr= &data->data;
    thd->data= data;
  }

  data->rows++;
  if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+packet->length())))
  {
    my_error(ER_OUT_OF_RESOURCES,MYF(0));
    return true;
  }
  cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS));
unknown's avatar
SCRUM  
unknown committed
626
  memcpy(cur->data, packet->ptr()+1, packet->length()-1);
unknown's avatar
unknown committed
627 628 629

  *data->prev_ptr= cur;
  data->prev_ptr= &cur->next;
unknown's avatar
SCRUM  
unknown committed
630 631
  cur->next= 0;
  
unknown's avatar
unknown committed
632 633 634
  return false;
}

635
void
636
send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message)
637 638 639
{
  DBUG_ENTER("send_ok");
  MYSQL *mysql= current_thd->mysql;
unknown's avatar
unknown committed
640 641
  if (!mysql)            // bootstrap file handling
    DBUG_VOID_RETURN;
642 643 644
  mysql->affected_rows= affected_rows;
  mysql->insert_id= id;
  if (message)
645
    strmake(thd->net.last_error, message, sizeof(thd->net.last_error)-1);
646 647 648
  DBUG_VOID_RETURN;
}

649 650 651 652 653
void
send_eof(THD *thd, bool no_flush)
{
}

unknown's avatar
SCRUM  
unknown committed
654 655
void Protocol_simple::prepare_for_resend()
{
unknown's avatar
SCRUM  
unknown committed
656 657
  MYSQL_ROWS *cur;
  MYSQL_DATA *data= thd->data;
unknown's avatar
SCRUM  
unknown committed
658 659 660

  DBUG_ENTER("send_data");

unknown's avatar
SCRUM  
unknown committed
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
  if (!data)
  {
    if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
					MYF(MY_WME | MY_ZEROFILL))))
      goto err;
    
    alloc= &data->alloc;
    init_alloc_root(alloc,8192,0);	/* Assume rowlength < 8192 */
    alloc->min_malloc=sizeof(MYSQL_ROWS);
    data->rows=0;
    data->fields=field_count;
    data->prev_ptr= &data->data;
    thd->data= data;
  }

  data->rows++;
unknown's avatar
SCRUM  
unknown committed
677 678 679 680 681 682 683
  if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+(field_count + 1) * sizeof(char *))))
  {
    my_error(ER_OUT_OF_RESOURCES,MYF(0));
    DBUG_VOID_RETURN;
  }
  cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS));

unknown's avatar
SCRUM  
unknown committed
684 685
  *data->prev_ptr= cur;
  data->prev_ptr= &cur->next;
unknown's avatar
SCRUM  
unknown committed
686
  next_field=cur->data;
unknown's avatar
SCRUM  
unknown committed
687 688
  next_mysql_field= thd->mysql->fields;
err:
unknown's avatar
SCRUM  
unknown committed
689 690 691
  DBUG_VOID_RETURN;
}

unknown's avatar
SCRUM  
unknown committed
692 693 694 695 696 697 698
bool Protocol_simple::store_null()
{
  *(next_field++)= NULL;
  ++next_mysql_field;
  return false;
}

unknown's avatar
SCRUM  
unknown committed
699 700
bool Protocol::net_store_data(const char *from, uint length)
{
unknown's avatar
unknown committed
701
  char *field_buf;
unknown's avatar
unknown committed
702 703 704
  if (!thd->mysql)            // bootstrap file handling
    return false;

unknown's avatar
SCRUM  
unknown committed
705
  if (!(field_buf=alloc_root(alloc, length + sizeof(uint) + 1)))
unknown's avatar
SCRUM  
unknown committed
706
    return true;
unknown's avatar
unknown committed
707 708
  *(uint *)field_buf= length;
  *next_field= field_buf + sizeof(uint);
unknown's avatar
SCRUM  
unknown committed
709
  memcpy(*next_field, from, length);
unknown's avatar
SCRUM  
unknown committed
710
  (*next_field)[length]= 0;
unknown's avatar
SCRUM  
unknown committed
711 712 713 714 715 716 717
  if (next_mysql_field->max_length < length)
    next_mysql_field->max_length=length;
  ++next_field;
  ++next_mysql_field;
  return false;
}

unknown's avatar
unknown committed
718
#if 0
unknown's avatar
SCRUM  
unknown committed
719 720 721 722 723 724 725 726 727 728
/* The same as Protocol::net_store_data but does the converstion
*/
bool Protocol::convert_str(const char *from, uint length)
{
  if (!(*next_field=alloc_root(alloc, length + 1)))
    return true;
  convert->store_dest(*next_field, from, length);
  (*next_field)[length]= 0;
  if (next_mysql_field->max_length < length)
    next_mysql_field->max_length=length;
unknown's avatar
SCRUM  
unknown committed
729
  ++next_field;
unknown's avatar
SCRUM  
unknown committed
730 731
  ++next_mysql_field;

unknown's avatar
SCRUM  
unknown committed
732 733
  return false;
}
unknown's avatar
unknown committed
734
#endif
unknown's avatar
unknown committed
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751

bool setup_params_data(st_prep_stmt *stmt)
{                                       
  THD *thd= stmt->thd;
  List<Item> &params= thd->lex.param_list;
  List_iterator<Item> param_iterator(params);
  Item_param *param;
  ulong param_no= 0;
  MYSQL_BIND *client_param= thd->client_params;

  DBUG_ENTER("setup_params_data");

  for (;(param= (Item_param *)param_iterator++); client_param++)
  {       
    setup_param_functions(param, client_param->buffer_type);
    if (!param->long_data_supplied)
    {
unknown's avatar
SCRUM  
unknown committed
752
      if (*client_param->is_null)
unknown's avatar
unknown committed
753 754 755 756 757
        param->maybe_null= param->null_value= 1;
      else
      {
	uchar *buff= (uchar*)client_param->buffer;
        param->maybe_null= param->null_value= 0;
unknown's avatar
unknown committed
758 759 760 761
        param->setup_param_func(param,&buff, 
				client_param->length ? 
				*client_param->length : 
				client_param->buffer_length);
unknown's avatar
unknown committed
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792
      }
    }
    param_no++;
  }
  DBUG_RETURN(0);
}

bool setup_params_data_withlog(st_prep_stmt *stmt)
{                                       
  THD *thd= stmt->thd;
  List<Item> &params= thd->lex.param_list;
  List_iterator<Item> param_iterator(params);
  Item_param *param;
  MYSQL_BIND *client_param= thd->client_params;

  DBUG_ENTER("setup_params_data");

  String str, *res, *query= new String(stmt->query->alloced_length());  
  query->copy(*stmt->query);
  
  ulong param_no= 0;  
  uint32 length= 0;

  for (;(param= (Item_param *)param_iterator++); client_param++)
  {       
    setup_param_functions(param, client_param->buffer_type);
    if (param->long_data_supplied)
      res= param->query_val_str(&str);       
    
    else
    {
unknown's avatar
SCRUM  
unknown committed
793
      if (*client_param->is_null)
unknown's avatar
unknown committed
794 795
      {
        param->maybe_null= param->null_value= 1;
unknown's avatar
unknown committed
796
        res= &my_null_string;
unknown's avatar
unknown committed
797 798 799 800 801
      }
      else
      {
	uchar *buff= (uchar*)client_param->buffer;
        param->maybe_null= param->null_value= 0;
unknown's avatar
unknown committed
802 803 804 805
        param->setup_param_func(param,&buff,
				client_param->length ? 
				*client_param->length : 
				client_param->buffer_length);
unknown's avatar
unknown committed
806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822
        res= param->query_val_str(&str);
      }
    }
    if (query->replace(param->pos_in_query+length, 1, *res))
      DBUG_RETURN(1);
    
    length+= res->length()-1;
    param_no++;
  }
  
  if (alloc_query(stmt->thd, (char *)query->ptr(), query->length()+1))
    DBUG_RETURN(1);
  
  query->free();
  DBUG_RETURN(0);
}