lib_sql.cc 18.7 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

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
void embedded_get_error(MYSQL *mysql)
{
  THD *thd=(THD *) mysql->thd;
  NET *net= &mysql->net;
  if ((net->last_errno= thd->net.last_errno))
  {
    memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error));
    memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate));
  }
  else
  {
    net->last_error[0]= 0;
    strmov(net->sqlstate, not_error_sqlstate);
  }
}

unknown's avatar
unknown committed
61
static my_bool
unknown's avatar
SCRUM  
unknown committed
62 63 64
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)
65
{
66
  my_bool result= 1;
67
  THD *thd=(THD *) mysql->thd;
unknown's avatar
unknown committed
68
  NET *net= &mysql->net;
69 70 71 72

  /* Check that we are calling the client functions in right order */
  if (mysql->status != MYSQL_STATUS_READY)
  {
unknown's avatar
unknown committed
73 74
    strmov(net->last_error,
	   ER(net->last_errno=CR_COMMANDS_OUT_OF_SYNC));
75 76 77 78
    return 1;
  }

  /* Clear result variables */
unknown's avatar
unknown committed
79
  thd->clear_error();
80
  mysql->affected_rows= ~(my_ulonglong) 0;
unknown's avatar
SCRUM  
unknown committed
81
  mysql->field_count= 0;
82

83
  thd->store_globals();				// Fix if more than one connect
unknown's avatar
unknown committed
84 85 86 87 88 89
  /* 
     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
90
  free_old_query(mysql);
unknown's avatar
unknown committed
91 92 93 94

  thd->extra_length= arg_length;
  thd->extra_data= (char *)arg;
  if (header)
unknown's avatar
SCRUM  
unknown committed
95 96 97 98 99
  {
    arg= header;
    arg_length= header_length;
  }

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

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

105
  embedded_get_error(mysql);
unknown's avatar
unknown committed
106
  mysql->server_status= thd->server_status;
unknown's avatar
SCRUM  
unknown committed
107
  mysql->warning_count= ((THD*)mysql->thd)->total_warn_count;
108
  return result;
109 110
}

unknown's avatar
unknown committed
111
static MYSQL_DATA *
unknown's avatar
SCRUM  
unknown committed
112
emb_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)),
unknown's avatar
SCRUM  
unknown committed
113
	      unsigned int fields __attribute__((unused)))
unknown's avatar
SCRUM  
unknown committed
114 115 116
{
  MYSQL_DATA *result= ((THD*)mysql->thd)->data;
  if (!result)
unknown's avatar
SCRUM  
unknown committed
117 118 119 120 121 122 123 124 125 126 127 128
  {
    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
129 130 131 132 133
  *result->prev_ptr= NULL;
  ((THD*)mysql->thd)->data= NULL;
  return result;
}

unknown's avatar
unknown committed
134
static MYSQL_FIELD *emb_list_fields(MYSQL *mysql)
unknown's avatar
SCRUM  
unknown committed
135 136 137 138
{
  return mysql->fields;
}

unknown's avatar
unknown committed
139
static my_bool emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
unknown's avatar
SCRUM  
unknown committed
140 141
{
  THD *thd= (THD*)mysql->thd;
unknown's avatar
unknown committed
142 143
  if (mysql->net.last_errno)
    return 1;
unknown's avatar
SCRUM  
unknown committed
144 145 146 147 148 149 150 151 152 153 154
  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
155
    mysql->fields= NULL;
unknown's avatar
SCRUM  
unknown committed
156
  }
unknown's avatar
SCRUM  
unknown committed
157

unknown's avatar
SCRUM  
unknown committed
158 159 160 161 162 163 164 165 166
  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
unknown committed
167 168
static void emb_fetch_lengths(ulong *to, MYSQL_ROW column,
			      unsigned int field_count)
unknown's avatar
SCRUM  
unknown committed
169 170 171 172 173 174 175
{ 
  MYSQL_ROW end;

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

unknown's avatar
unknown committed
176
static my_bool emb_mysql_read_query_result(MYSQL *mysql)
unknown's avatar
SCRUM  
unknown committed
177 178 179 180 181 182 183 184 185 186
{
  if (mysql->net.last_errno)
    return -1;

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

  return 0;
}

unknown's avatar
unknown committed
187
static int emb_stmt_execute(MYSQL_STMT *stmt)
unknown's avatar
SCRUM  
unknown committed
188 189 190 191
{
  DBUG_ENTER("emb_stmt_execute");
  THD *thd= (THD*)stmt->mysql->thd;
  thd->client_param_count= stmt->param_count;
unknown's avatar
unknown committed
192
  thd->client_params= stmt->params;
unknown's avatar
unknown committed
193 194 195 196 197
  if (thd->data)
  {
    free_rows(thd->data);
    thd->data= 0;
  }
unknown's avatar
SCRUM  
unknown committed
198
  if (emb_advanced_command(stmt->mysql, COM_EXECUTE,0,0,
199 200 201
			   (const char*)&stmt->stmt_id,sizeof(stmt->stmt_id),
			   1) ||
      emb_mysql_read_query_result(stmt->mysql))
unknown's avatar
SCRUM  
unknown committed
202 203 204 205 206
  {
    NET *net= &stmt->mysql->net;
    set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
    DBUG_RETURN(1);
  }
207 208
  stmt->affected_rows= stmt->mysql->affected_rows;
  stmt->insert_id= stmt->mysql->insert_id;
unknown's avatar
SCRUM  
unknown committed
209 210 211
  DBUG_RETURN(0);
}

212
int emb_read_binary_rows(MYSQL_STMT *stmt)
unknown's avatar
unknown committed
213
{
214 215 216 217 218 219
  MYSQL_DATA *data;
  if (!(data= emb_read_rows(stmt->mysql, 0, 0)))
    return 1;
  stmt->result= *data;
  my_free((char *) data, MYF(0));
  return 0;
unknown's avatar
unknown committed
220 221
}

unknown's avatar
unknown committed
222
int emb_unbuffered_fetch(MYSQL *mysql, char **row)
unknown's avatar
SCRUM  
unknown committed
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
{
  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
unknown committed
242
static void emb_free_embedded_thd(MYSQL *mysql)
unknown's avatar
SCRUM  
unknown committed
243 244 245 246
{
  THD *thd= (THD*)mysql->thd;
  if (thd->data)
    free_rows(thd->data);
unknown's avatar
unknown committed
247
  thread_count--;
unknown's avatar
SCRUM  
unknown committed
248
  delete thd;
249
  mysql->thd=0;
unknown's avatar
SCRUM  
unknown committed
250 251
}

unknown's avatar
unknown committed
252
static const char * emb_read_statistics(MYSQL *mysql)
unknown's avatar
unknown committed
253 254 255 256 257
{
  THD *thd= (THD*)mysql->thd;
  return thd->net.last_error;
}

unknown's avatar
unknown committed
258 259 260 261 262 263

static MYSQL_RES * emb_mysql_store_result(MYSQL *mysql)
{
  return mysql_store_result(mysql);
}

unknown's avatar
unknown committed
264
my_bool emb_next_result(MYSQL *mysql)
265 266 267 268 269
{
  THD *thd= (THD*)mysql->thd;
  DBUG_ENTER("emb_next_result");

  if (emb_advanced_command(mysql, COM_QUERY,0,0,
270 271
			   thd->query_rest.ptr(),thd->query_rest.length(),1) ||
      emb_mysql_read_query_result(mysql))
272 273 274 275
    DBUG_RETURN(1);

  DBUG_RETURN(0);				/* No more results */
}
unknown's avatar
unknown committed
276

277 278 279 280 281 282 283
int emb_read_change_user_result(MYSQL *mysql, 
				char *buff __attribute__((unused)),
				const char *passwd __attribute__((unused)))
{
  return mysql_errno(mysql);
}

unknown's avatar
SCRUM  
unknown committed
284 285 286 287 288
MYSQL_METHODS embedded_methods= 
{
  emb_mysql_read_query_result,
  emb_advanced_command,
  emb_read_rows,
unknown's avatar
unknown committed
289
  emb_mysql_store_result,
unknown's avatar
SCRUM  
unknown committed
290 291
  emb_fetch_lengths, 
  emb_list_fields,
unknown's avatar
SCRUM  
unknown committed
292
  emb_read_prepare_result,
unknown's avatar
unknown committed
293
  emb_stmt_execute,
unknown's avatar
SCRUM  
unknown committed
294
  emb_read_binary_rows,
unknown's avatar
SCRUM  
unknown committed
295
  emb_unbuffered_fetch,
unknown's avatar
unknown committed
296
  emb_free_embedded_thd,
unknown's avatar
unknown committed
297
  emb_read_statistics,
298 299
  emb_next_result,
  emb_read_change_user_result
unknown's avatar
SCRUM  
unknown committed
300 301
};

unknown's avatar
unknown committed
302
C_MODE_END
303

304
void THD::clear_error()
305
{
306 307 308
  net.last_error[0]= 0;
  net.last_errno= 0;
  net.report_error= 0;
309 310
}

311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
/*
  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
338 339 340
extern "C"
{

341
char **		copy_arguments_ptr= 0; 
unknown's avatar
unknown committed
342

343
int init_embedded_server(int argc, char **argv, char **groups)
unknown's avatar
unknown committed
344
{
unknown's avatar
unknown committed
345 346 347 348
  /*
    This mess is to allow people to call the init function without
    having to mess with a fake argv
   */
unknown's avatar
unknown committed
349 350 351 352 353 354 355
  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
356 357
    argcp= &argc;
    argvp= (char***) &argv;
unknown's avatar
unknown committed
358 359 360
  }
  else
  {
unknown's avatar
unknown committed
361 362
    argcp= &fake_argc;
    argvp= (char ***) &fake_argv;
unknown's avatar
unknown committed
363 364
  }
  if (!groups)
unknown's avatar
unknown committed
365
    groups= (char**) fake_groups;
unknown's avatar
unknown committed
366

367
  my_progname= (char *)"mysql_embedded";
unknown's avatar
unknown committed
368

unknown's avatar
unknown committed
369
  if (init_common_variables("my", *argcp, *argvp, (const char **)groups))
unknown's avatar
unknown committed
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
  {
    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
395
#ifndef NO_EMBEDDED_ACCESS_CHECKS
unknown's avatar
unknown committed
396
  if (acl_init((THD *)0, opt_noacl))
unknown's avatar
unknown committed
397 398 399 400 401
  {
    mysql_server_end();
    return 1;
  }
  if (!opt_noacl)
unknown's avatar
unknown committed
402
    (void) grant_init((THD *)0);
unknown's avatar
unknown committed
403 404 405

#endif

unknown's avatar
unknown committed
406 407 408 409
  init_max_user_conn();
  init_update_queries();

#ifdef HAVE_DLOPEN
unknown's avatar
unknown committed
410
#ifndef NO_EMBEDDED_ACCESS_CHECKS
unknown's avatar
unknown committed
411
  if (!opt_noacl)
unknown's avatar
unknown committed
412
#endif
unknown's avatar
unknown committed
413 414 415 416 417 418 419
    udf_init();
#endif

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

  if (
#ifdef HAVE_BERKELEY_DB
420
      (have_berkeley_db == SHOW_OPTION_YES) ||
unknown's avatar
unknown committed
421 422 423 424 425 426 427 428
#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
429 430 431 432 433 434 435 436 437
  if (opt_init_file)
  {
    if (read_init_file(opt_init_file))
    {
      mysql_server_end();
      return 1;
    }
  }

unknown's avatar
unknown committed
438 439 440 441 442 443 444 445 446 447 448
  /*
    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;
}

449
void end_embedded_server()
450
{
unknown's avatar
unknown committed
451 452
  my_free((char*) copy_arguments_ptr, MYF(MY_ALLOW_ZERO_PTR));
  copy_arguments_ptr=0;
unknown's avatar
unknown committed
453
  clean_up(0);
unknown's avatar
unknown committed
454 455
}

unknown's avatar
unknown committed
456
} /* extern "C" */
457

458
C_MODE_START
459 460
void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db)
{
461
  THD *thd = (THD *)mysql->thd;
462
  thd->mysql= mysql;
unknown's avatar
unknown committed
463
  mysql->server_version= server_version;
464
}
465

466
void *create_embedded_thd(int client_flag, char *db)
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
{
  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
489
  thd->db_length= db ? strip_sp(db) : 0;
unknown's avatar
unknown committed
490
#ifndef NO_EMBEDDED_ACCESS_CHECKS
491 492
  thd->db_access= DB_ACLS;
  thd->master_access= ~NO_ACCESS;
unknown's avatar
unknown committed
493
#endif
494
  thd->net.query_cache_query= 0;
495

unknown's avatar
SCRUM  
unknown committed
496 497
  thd->data= 0;

unknown's avatar
unknown committed
498
  thread_count++;
499 500
  return thd;
}
501

502 503 504 505 506 507
#ifdef NO_EMBEDDED_ACCESS_CHECKS
int check_embedded_connection(MYSQL *mysql)
{
  THD *thd= (THD*)mysql->thd;
  thd->host= (char*)my_localhost;
  thd->host_or_ip= thd->host;
unknown's avatar
unknown committed
508
  thd->user= my_strdup(mysql->user, MYF(0));
509
  return check_user(thd, COM_CONNECT, NULL, 0, thd->db, true);
510 511 512
}

#else
unknown's avatar
unknown committed
513 514 515 516 517 518 519
int check_embedded_connection(MYSQL *mysql)
{
  THD *thd= (THD*)mysql->thd;
  int result;
  char scramble_buff[SCRAMBLE_LENGTH];
  int passwd_len;

520 521
  if (mysql->options.client_ip)
  {
unknown's avatar
unknown committed
522 523
    thd->host= my_strdup(mysql->options.client_ip, MYF(0));
    thd->ip= my_strdup(thd->host, MYF(0));
524 525 526
  }
  else
    thd->host= (char*)my_localhost;
unknown's avatar
unknown committed
527 528 529 530 531 532 533 534
  thd->host_or_ip= thd->host;

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

unknown's avatar
unknown committed
535
  thd->user= my_strdup(mysql->user, MYF(0));
unknown's avatar
unknown committed
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
  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

561
C_MODE_END
562

unknown's avatar
unknown committed
563 564 565 566
bool Protocol::send_fields(List<Item> *list, uint flag)
{
  List_iterator_fast<Item> it(*list);
  Item                     *item;
unknown's avatar
SCRUM  
unknown committed
567
  MYSQL_FIELD              *client_field;
unknown's avatar
unknown committed
568
  MYSQL                    *mysql= thd->mysql;
unknown's avatar
SCRUM  
unknown committed
569
  MEM_ROOT                 *field_alloc;
unknown's avatar
unknown committed
570
  
unknown's avatar
SCRUM  
unknown committed
571
  DBUG_ENTER("send_fields");
unknown's avatar
unknown committed
572

unknown's avatar
unknown committed
573 574 575
  if (!mysql)            // bootstrap file handling
    DBUG_RETURN(0);

unknown's avatar
SCRUM  
unknown committed
576
  field_count= list->elements;
unknown's avatar
SCRUM  
unknown committed
577 578 579 580
  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
581 582 583 584 585 586 587
    goto err;

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

unknown's avatar
SCRUM  
unknown committed
588 589 590 591 592
    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
593 594 595 596
    client_field->length= server_field.length;
    client_field->type=   server_field.type;
    client_field->flags= server_field.flags;
    client_field->decimals= server_field.decimals;
597 598 599 600 601 602
    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
SCRUM  
unknown committed
603 604 605

    client_field->catalog= strdup_root(field_alloc, "std");
    client_field->catalog_length= 3;
606
    
unknown's avatar
unknown committed
607 608 609 610 611 612 613 614 615
    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
616 617
      {
	client_field->def_length= 0;
618
	client_field->def= strmake_root(field_alloc, "",0);
unknown's avatar
SCRUM  
unknown committed
619
      }
unknown's avatar
unknown committed
620
      else
unknown's avatar
SCRUM  
unknown committed
621
      {
622
	client_field->def_length= res->length();
623 624
	client_field->def= strmake_root(field_alloc, res->ptr(),
					client_field->def_length);
unknown's avatar
SCRUM  
unknown committed
625
      }
unknown's avatar
unknown committed
626 627 628 629 630 631
    }
    else
      client_field->def=0;
    client_field->max_length= 0;
    ++client_field;
  }
unknown's avatar
SCRUM  
unknown committed
632
  thd->mysql->field_count= field_count;
unknown's avatar
unknown committed
633

unknown's avatar
SCRUM  
unknown committed
634
  DBUG_RETURN(prepare_for_send(list));
unknown's avatar
unknown committed
635 636
 err:
  send_error(thd, ER_OUT_OF_RESOURCES);	/* purecov: inspected */
unknown's avatar
SCRUM  
unknown committed
637
  DBUG_RETURN(1);				/* purecov: inspected */
unknown's avatar
unknown committed
638 639
}

unknown's avatar
SCRUM  
unknown committed
640
bool Protocol::send_records_num(List<Item> *list, ulonglong records)
unknown's avatar
SCRUM  
unknown committed
641 642 643 644
{
  return false;
}

unknown's avatar
SCRUM  
unknown committed
645
bool Protocol::write()
unknown's avatar
unknown committed
646
{
unknown's avatar
unknown committed
647 648 649
  if (!thd->mysql)            // bootstrap file handling
    return false;

unknown's avatar
SCRUM  
unknown committed
650 651
  *next_field= 0;
  return false;
unknown's avatar
unknown committed
652
}
653

unknown's avatar
unknown committed
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
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
681
  memcpy(cur->data, packet->ptr()+1, packet->length()-1);
unknown's avatar
unknown committed
682 683 684

  *data->prev_ptr= cur;
  data->prev_ptr= &cur->next;
unknown's avatar
SCRUM  
unknown committed
685 686
  cur->next= 0;
  
unknown's avatar
unknown committed
687 688 689
  return false;
}

690
void
691
send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message)
692 693 694
{
  DBUG_ENTER("send_ok");
  MYSQL *mysql= current_thd->mysql;
unknown's avatar
unknown committed
695 696
  if (!mysql)            // bootstrap file handling
    DBUG_VOID_RETURN;
697 698 699
  mysql->affected_rows= affected_rows;
  mysql->insert_id= id;
  if (message)
700
  {
701
    strmake(thd->net.last_error, message, sizeof(thd->net.last_error)-1);
702 703
    mysql->info= thd->net.last_error;
  }
704 705 706
  DBUG_VOID_RETURN;
}

707 708 709 710 711
void
send_eof(THD *thd, bool no_flush)
{
}

unknown's avatar
SCRUM  
unknown committed
712 713
void Protocol_simple::prepare_for_resend()
{
unknown's avatar
SCRUM  
unknown committed
714 715
  MYSQL_ROWS *cur;
  MYSQL_DATA *data= thd->data;
unknown's avatar
SCRUM  
unknown committed
716 717 718

  DBUG_ENTER("send_data");

unknown's avatar
SCRUM  
unknown committed
719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
  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
735 736 737 738 739 740 741
  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
742 743
  *data->prev_ptr= cur;
  data->prev_ptr= &cur->next;
unknown's avatar
SCRUM  
unknown committed
744
  next_field=cur->data;
unknown's avatar
SCRUM  
unknown committed
745 746
  next_mysql_field= thd->mysql->fields;
err:
unknown's avatar
SCRUM  
unknown committed
747 748 749
  DBUG_VOID_RETURN;
}

unknown's avatar
SCRUM  
unknown committed
750 751 752 753 754 755 756
bool Protocol_simple::store_null()
{
  *(next_field++)= NULL;
  ++next_mysql_field;
  return false;
}

unknown's avatar
SCRUM  
unknown committed
757 758
bool Protocol::net_store_data(const char *from, uint length)
{
unknown's avatar
unknown committed
759
  char *field_buf;
unknown's avatar
unknown committed
760 761 762
  if (!thd->mysql)            // bootstrap file handling
    return false;

unknown's avatar
SCRUM  
unknown committed
763
  if (!(field_buf=alloc_root(alloc, length + sizeof(uint) + 1)))
unknown's avatar
SCRUM  
unknown committed
764
    return true;
unknown's avatar
unknown committed
765 766
  *(uint *)field_buf= length;
  *next_field= field_buf + sizeof(uint);
unknown's avatar
SCRUM  
unknown committed
767
  memcpy(*next_field, from, length);
unknown's avatar
SCRUM  
unknown committed
768
  (*next_field)[length]= 0;
unknown's avatar
SCRUM  
unknown committed
769 770 771 772 773 774 775
  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
776
#if 0
unknown's avatar
SCRUM  
unknown committed
777 778 779 780 781 782 783 784 785 786
/* 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
787
  ++next_field;
unknown's avatar
SCRUM  
unknown committed
788 789
  ++next_mysql_field;

unknown's avatar
SCRUM  
unknown committed
790 791
  return false;
}
unknown's avatar
unknown committed
792
#endif
unknown's avatar
unknown committed
793