17
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#include <drizzled/global.h>
21
#include <drizzled/common.h>
22
#include <libdrizzle/drizzle_com.h>
23
#include <libdrizzle/libdrizzle.h>
24
#include <libdrizzle/errmsg.h>
25
#include <libdrizzle/drizzle.h>
26
#include <libdrizzle/gettext.h>
27
#include <libdrizzle/net_serv.h>
28
#include <libdrizzle/drizzle_data.h>
29
#include <libdrizzle/local_infile.h>
23
31
#include "libdrizzle_priv.h"
25
#include "libdrizzle.h"
30
#include "drizzle_data.h"
33
#include <vio/violite.h>
32
#include <drizzled/gettext.h>
35
#include <drizzled/version.h>
35
38
#include <stdlib.h>
49
50
unsigned int drizzle_server_last_errno;
51
52
/* Server error code and message */
52
char drizzle_server_last_error[LIBDRIZZLE_ERRMSG_SIZE];
53
char drizzle_server_last_error[DRIZZLE_ERRMSG_SIZE];
55
56
Note that the drizzle argument must be initialized with drizzle_init()
56
before calling drizzleclient_connect !
57
before calling drizzle_connect !
61
62
static DRIZZLE_METHODS client_methods=
63
drizzleclient_cli_read_query_result, /* read_query_result */
64
drizzleclient_cli_advanced_command, /* advanced_command */
65
drizzleclient_cli_read_rows, /* read_rows */
66
drizzleclient_cli_use_result, /* use_result */
67
drizzleclient_cli_fetch_lengths, /* fetch_lengths */
68
drizzleclient_cli_flush_use_result, /* flush_use_result */
69
drizzleclient_cli_list_fields, /* list_fields */
70
drizzleclient_cli_unbuffered_fetch, /* unbuffered_fetch */
71
drizzleclient_cli_read_statistics, /* read_statistics */
72
drizzleclient_cli_read_query_result, /* next_result */
64
cli_read_query_result, /* read_query_result */
65
cli_advanced_command, /* advanced_command */
66
cli_read_rows, /* read_rows */
67
cli_use_result, /* use_result */
68
cli_fetch_lengths, /* fetch_lengths */
69
cli_flush_use_result, /* flush_use_result */
70
cli_list_fields, /* list_fields */
71
cli_unbuffered_fetch, /* unbuffered_fetch */
72
cli_read_statistics, /* read_statistics */
73
cli_read_query_result, /* next_result */
74
cli_read_change_user_result, /* read_change_user_result */
79
81
****************************************************************************/
82
drizzleclient_create(DRIZZLE *ptr)
84
drizzle_create(DRIZZLE *ptr)
85
87
if (!drizzle_client_init)
87
89
drizzle_client_init=true;
89
if (!drizzleclient_get_default_port())
91
if (!drizzle_get_default_port())
91
drizzleclient_set_default_port(DRIZZLE_PORT);
93
drizzle_set_default_port(DRIZZLE_PORT);
93
95
struct servent *serv_ptr;
106
108
#if DRIZZLE_PORT_DEFAULT == 0
107
109
if ((serv_ptr = getservbyname("drizzle", "tcp")))
108
drizzleclient_set_default_port((uint32_t) ntohs((uint16_t) serv_ptr->s_port));
110
drizzle_set_default_port((uint32_t) ntohs((uint16_t) serv_ptr->s_port));
110
112
if ((env = getenv("DRIZZLE_TCP_PORT")))
111
drizzleclient_set_default_port((uint32_t) atoi(env));
113
drizzle_set_default_port((uint32_t) atoi(env));
114
116
#if defined(SIGPIPE)
125
drizzleclient_set_error(NULL, CR_OUT_OF_MEMORY, drizzleclient_sqlstate_get_unknown());
127
drizzle_set_error(NULL, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
128
130
memset(ptr, 0, sizeof(DRIZZLE));
136
138
ptr->options.connect_timeout= CONNECT_TIMEOUT;
137
strcpy(ptr->net.sqlstate, drizzleclient_sqlstate_get_not_error());
139
strcpy(ptr->net.sqlstate, sqlstate_get_not_error());
140
142
Only enable LOAD DATA INFILE by default if configured with
152
154
By default we don't reconnect because it could silently corrupt data (after
153
155
reconnection you potentially lose table locks, user variables, session
154
156
variables (transactions but they are specifically dealt with in
155
drizzleclient_reconnect()).
157
drizzle_reconnect()).
156
158
This is a change: < 5.0.3 drizzle->reconnect was set to 1 by default.
157
159
How this change impacts existing apps:
158
160
- existing apps which relyed on the default will see a behaviour change;
159
they will have to set reconnect=1 after drizzleclient_connect().
161
they will have to set reconnect=1 after drizzle_connect().
160
162
- existing apps which explicitely asked for reconnection (the only way they
161
could do it was by setting drizzle.reconnect to 1 after drizzleclient_connect())
163
could do it was by setting drizzle.reconnect to 1 after drizzle_connect())
162
164
will not see a behaviour change.
163
165
- existing apps which explicitely asked for no reconnection
164
166
(drizzle.reconnect=0) will not see a behaviour change.
200
drizzleclient_connect(DRIZZLE *drizzle,const char *host, const char *user,
202
drizzle_connect(DRIZZLE *drizzle,const char *host, const char *user,
201
203
const char *passwd, const char *db,
203
const char * unix_port,
205
const char * unix_port __attribute__((__unused__)),
204
206
uint32_t client_flag)
207
208
char buff[NAME_LEN+USERNAME_LENGTH+100];
208
209
char *end,*host_info=NULL;
209
210
uint32_t pkt_length;
261
262
if (gai_errno != 0)
263
drizzleclient_set_extended_error(drizzle, CR_UNKNOWN_HOST, drizzleclient_sqlstate_get_unknown(),
264
drizzle_set_extended_error(drizzle, CR_UNKNOWN_HOST, sqlstate_get_unknown(),
264
265
ER(CR_UNKNOWN_HOST), host, errno);
276
net->vio= drizzleclient_vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
277
net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
283
if (drizzleclient_connect_with_timeout(sock, t_res->ai_addr, t_res->ai_addrlen, drizzle->options.connect_timeout))
284
if (connect_with_timeout(sock, t_res->ai_addr, t_res->ai_addrlen, drizzle->options.connect_timeout))
285
drizzleclient_vio_delete(net->vio);
286
vio_delete(net->vio);
297
drizzleclient_set_extended_error(drizzle, CR_CONN_HOST_ERROR, drizzleclient_sqlstate_get_unknown(),
298
drizzle_set_extended_error(drizzle, CR_CONN_HOST_ERROR, sqlstate_get_unknown(),
298
299
ER(CR_CONN_HOST_ERROR), host, errno);
302
if (drizzleclient_net_init(net, net->vio))
303
if (my_net_init(net, net->vio))
304
drizzleclient_vio_delete(net->vio);
305
vio_delete(net->vio);
306
drizzleclient_set_error(drizzle, CR_OUT_OF_MEMORY, drizzleclient_sqlstate_get_unknown());
307
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
309
drizzleclient_vio_keepalive(net->vio,true);
310
vio_keepalive(net->vio,true);
311
312
/* If user set read_timeout, let it override the default */
312
313
if (drizzle->options.read_timeout)
313
drizzleclient_net_set_read_timeout(net, drizzle->options.read_timeout);
314
my_net_set_read_timeout(net, drizzle->options.read_timeout);
315
316
/* If user set write_timeout, let it override the default */
316
317
if (drizzle->options.write_timeout)
317
drizzleclient_net_set_write_timeout(net, drizzle->options.write_timeout);
318
my_net_set_write_timeout(net, drizzle->options.write_timeout);
319
320
if (drizzle->options.max_allowed_packet)
320
321
net->max_packet_size= drizzle->options.max_allowed_packet;
322
323
/* Get version info */
323
324
drizzle->protocol_version= PROTOCOL_VERSION; /* Assume this */
324
325
if (drizzle->options.connect_timeout &&
325
drizzleclient_vio_poll_read(net->vio, drizzle->options.connect_timeout))
326
vio_poll_read(net->vio, drizzle->options.connect_timeout))
327
drizzleclient_set_extended_error(drizzle, CR_SERVER_LOST, drizzleclient_sqlstate_get_unknown(),
328
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
328
329
ER(CR_SERVER_LOST_INITIAL_COMM_WAIT),
334
335
Part 1: Connection established, read and parse first packet
337
if ((pkt_length=drizzleclient_cli_safe_read(drizzle)) == packet_error)
338
if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
339
340
if (drizzle->net.last_errno == CR_SERVER_LOST)
340
drizzleclient_set_extended_error(drizzle, CR_SERVER_LOST, drizzleclient_sqlstate_get_unknown(),
341
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
341
342
ER(CR_SERVER_LOST_INITIAL_COMM_READ),
347
348
drizzle->protocol_version= net->read_pos[0];
348
349
if (drizzle->protocol_version != PROTOCOL_VERSION)
350
drizzleclient_set_extended_error(drizzle, CR_VERSION_ERROR, drizzleclient_sqlstate_get_unknown(),
351
drizzle_set_extended_error(drizzle, CR_VERSION_ERROR, sqlstate_get_unknown(),
351
352
ER(CR_VERSION_ERROR), drizzle->protocol_version,
352
353
PROTOCOL_VERSION);
381
382
if (drizzle->options.secure_auth && passwd[0] &&
382
383
!(drizzle->server_capabilities & CLIENT_SECURE_CONNECTION))
384
drizzleclient_set_error(drizzle, CR_SECURE_AUTH, drizzleclient_sqlstate_get_unknown());
385
drizzle_set_error(drizzle, CR_SECURE_AUTH, sqlstate_get_unknown());
391
392
!(drizzle->user=strdup(user)) ||
392
393
!(drizzle->passwd=strdup(passwd)))
394
drizzleclient_set_error(drizzle, CR_OUT_OF_MEMORY, drizzleclient_sqlstate_get_unknown());
395
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
397
398
drizzle->host= drizzle->host_info+strlen(host_info)+1;
450
451
/* Add database if needed */
451
452
if (db && (drizzle->server_capabilities & CLIENT_CONNECT_WITH_DB))
453
size_t db_len= strlen(db);
455
if (db_len >= NAME_LEN)
456
db_len= NAME_LEN - 1;
457
end= memcpy(end, db, db_len);
454
end= strncpy(end, db, NAME_LEN) + NAME_LEN + 1;
461
455
drizzle->db= strdup(db);
464
458
/* Write authentication package */
465
if (drizzleclient_net_write(net, (unsigned char*) buff, (size_t) (end-buff)) || drizzleclient_net_flush(net))
459
if (my_net_write(net, (unsigned char*) buff, (size_t) (end-buff)) || net_flush(net))
467
drizzleclient_set_extended_error(drizzle, CR_SERVER_LOST, drizzleclient_sqlstate_get_unknown(),
461
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
468
462
ER(CR_SERVER_LOST_SEND_AUTH),
475
469
OK-packet, or re-request scrambled password.
478
if ((pkt_length=drizzleclient_cli_safe_read(drizzle)) == packet_error)
472
if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
480
474
if (drizzle->net.last_errno == CR_SERVER_LOST)
481
drizzleclient_set_extended_error(drizzle, CR_SERVER_LOST, drizzleclient_sqlstate_get_unknown(),
475
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
482
476
ER(CR_SERVER_LOST_READ_AUTH),
491
if (db && drizzleclient_select_db(drizzle, db))
485
if (db && drizzle_select_db(drizzle, db))
493
487
if (drizzle->net.last_errno == CR_SERVER_LOST)
494
drizzleclient_set_extended_error(drizzle, CR_SERVER_LOST, drizzleclient_sqlstate_get_unknown(),
488
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
495
489
ER(CR_SERVER_LOST_SETTING_DB),
505
499
/* Free alloced memory */
506
drizzleclient_disconnect(drizzle);
507
drizzleclient_close_free(drizzle);
500
drizzle_disconnect(drizzle);
501
drizzle_close_free(drizzle);
508
502
if (!(((uint32_t) client_flag) & CLIENT_REMEMBER_OPTIONS))
509
drizzleclient_close_free_options(drizzle);
503
drizzle_close_free_options(drizzle);
543
537
/* Allow reconnect next time */
544
538
drizzle->server_status&= ~SERVER_STATUS_IN_TRANS;
545
drizzleclient_set_error(drizzle, CR_SERVER_GONE_ERROR, drizzleclient_sqlstate_get_unknown());
539
drizzle_set_error(drizzle, CR_SERVER_GONE_ERROR, sqlstate_get_unknown());
548
drizzleclient_create(&tmp_drizzle);
542
drizzle_create(&tmp_drizzle);
549
543
tmp_drizzle.options= drizzle->options;
550
544
tmp_drizzle.options.my_cnf_file= tmp_drizzle.options.my_cnf_group= 0;
552
if (!drizzleclient_connect(&tmp_drizzle,drizzle->host,drizzle->user,drizzle->passwd,
546
if (!drizzle_connect(&tmp_drizzle,drizzle->host,drizzle->user,drizzle->passwd,
553
547
drizzle->db, drizzle->port, 0,
554
548
drizzle->client_flag | CLIENT_REMEMBER_OPTIONS))
565
559
/* Don't free options as these are now used in tmp_drizzle */
566
560
memset(&drizzle->options, 0, sizeof(drizzle->options));
567
561
drizzle->free_me=0;
568
drizzleclient_close(drizzle);
562
drizzle_close(drizzle);
569
563
*drizzle=tmp_drizzle;
570
drizzleclient_net_clear(&drizzle->net, 1);
564
net_clear(&drizzle->net, 1);
571
565
drizzle->affected_rows= ~(uint64_t) 0;
576
570
Shut down connection
577
571
**************************************************************************/
579
void drizzleclient_disconnect(DRIZZLE *drizzle)
573
void drizzle_disconnect(DRIZZLE *drizzle)
581
575
int save_errno= errno;
582
576
if (drizzle->net.vio != 0)
584
drizzleclient_vio_delete(drizzle->net.vio);
578
vio_delete(drizzle->net.vio);
585
579
drizzle->net.vio= 0; /* Marker */
587
drizzleclient_net_end(&drizzle->net);
588
drizzleclient_free_old_query(drizzle);
581
net_end(&drizzle->net);
582
free_old_query(drizzle);
589
583
errno= save_errno;
595
589
If handle is alloced by DRIZZLE connect free it.
596
590
*************************************************************************/
598
void drizzleclient_close_free_options(DRIZZLE *drizzle)
592
void drizzle_close_free_options(DRIZZLE *drizzle)
600
594
if (drizzle->options.user != NULL)
601
595
free(drizzle->options.user);
638
void drizzleclient_close(DRIZZLE *drizzle)
632
void drizzle_close(DRIZZLE *drizzle)
640
634
if (drizzle) /* Some simple safety */
642
636
/* If connection is still up, send a QUIT message */
643
637
if (drizzle->net.vio != 0)
645
drizzleclient_free_old_query(drizzle);
639
free_old_query(drizzle);
646
640
drizzle->status=DRIZZLE_STATUS_READY; /* Force command */
647
641
drizzle->reconnect=0;
648
642
simple_command(drizzle,COM_QUIT,(unsigned char*) 0,0,1);
649
drizzleclient_disconnect(drizzle); /* Sets drizzle->net.vio= 0 */
643
drizzle_disconnect(drizzle); /* Sets drizzle->net.vio= 0 */
651
drizzleclient_close_free_options(drizzle);
652
drizzleclient_close_free(drizzle);
645
drizzle_close_free_options(drizzle);
646
drizzle_close_free(drizzle);
653
647
if (drizzle->free_me)
654
648
free((unsigned char*) drizzle);
660
bool drizzleclient_cli_read_query_result(DRIZZLE *drizzle)
654
bool cli_read_query_result(DRIZZLE *drizzle)
662
656
unsigned char *pos;
663
657
uint32_t field_count;
664
658
DRIZZLE_DATA *fields;
667
if ((length = drizzleclient_cli_safe_read(drizzle)) == packet_error)
661
if ((length = cli_safe_read(drizzle)) == packet_error)
669
drizzleclient_free_old_query(drizzle); /* Free old result */
663
free_old_query(drizzle); /* Free old result */
671
665
pos=(unsigned char*) drizzle->net.read_pos;
672
if ((field_count= drizzleclient_net_field_length(&pos)) == 0)
666
if ((field_count= net_field_length(&pos)) == 0)
674
drizzle->affected_rows= drizzleclient_drizzleclient_net_field_length_ll(&pos);
675
drizzle->insert_id= drizzleclient_drizzleclient_net_field_length_ll(&pos);
668
drizzle->affected_rows= net_field_length_ll(&pos);
669
drizzle->insert_id= net_field_length_ll(&pos);
677
671
drizzle->server_status= uint2korr(pos); pos+=2;
678
672
drizzle->warning_count= uint2korr(pos); pos+=2;
680
if (pos < drizzle->net.read_pos+length && drizzleclient_net_field_length(&pos))
674
if (pos < drizzle->net.read_pos+length && net_field_length(&pos))
681
675
drizzle->info=(char*) pos;
684
678
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
686
drizzleclient_set_error(drizzle, CR_MALFORMED_PACKET, drizzleclient_sqlstate_get_unknown());
682
if (!(drizzle->options.client_flag & CLIENT_LOCAL_FILES))
684
drizzle_set_error(drizzle, CR_MALFORMED_PACKET, sqlstate_get_unknown());
688
error= handle_local_infile(drizzle,(char*) pos);
689
if ((length= cli_safe_read(drizzle)) == packet_error || error)
691
goto get_info; /* Get info packet */
690
693
if (!(drizzle->server_status & SERVER_STATUS_AUTOCOMMIT))
691
694
drizzle->server_status|= SERVER_STATUS_IN_TRANS;
693
if (!(fields=drizzleclient_cli_read_rows(drizzle,(DRIZZLE_FIELD*)0, 7)))
696
if (!(fields=cli_read_rows(drizzle,(DRIZZLE_FIELD*)0, 7)))
695
if (!(drizzle->fields= drizzleclient_unpack_fields(fields, (uint32_t) field_count, 0)))
698
if (!(drizzle->fields= unpack_fields(fields, (uint32_t) field_count, 0)))
697
700
drizzle->status= DRIZZLE_STATUS_GET_RESULT;
698
701
drizzle->field_count= (uint32_t) field_count;
704
707
Send the query and return so we can do something else.
705
Needs to be followed by drizzleclient_read_query_result() when we want to
708
Needs to be followed by drizzle_read_query_result() when we want to
706
709
finish processing it.
710
drizzleclient_send_query(DRIZZLE *drizzle, const char* query, uint32_t length)
713
drizzle_send_query(DRIZZLE *drizzle, const char* query, uint32_t length)
712
715
return(simple_command(drizzle, COM_QUERY, (unsigned char*) query, length, 1));
717
drizzleclient_real_query(DRIZZLE *drizzle, const char *query, uint32_t length)
720
drizzle_real_query(DRIZZLE *drizzle, const char *query, uint32_t length)
719
if (drizzleclient_send_query(drizzle,query,length))
722
if (drizzle_send_query(drizzle,query,length))
721
724
return((int) (*drizzle->methods->read_query_result)(drizzle));
725
728
/**************************************************************************
726
729
Alloc result struct for buffered results. All rows are read to buffer.
727
drizzleclient_data_seek may be used.
730
drizzle_data_seek may be used.
728
731
**************************************************************************/
730
DRIZZLE_RES * drizzleclient_store_result(DRIZZLE *drizzle)
733
DRIZZLE_RES * drizzle_store_result(DRIZZLE *drizzle)
732
735
DRIZZLE_RES *result;
736
739
if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
738
drizzleclient_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, drizzleclient_sqlstate_get_unknown());
741
drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, sqlstate_get_unknown());
741
744
drizzle->status=DRIZZLE_STATUS_READY; /* server is ready */
743
746
sizeof(uint32_t) *
744
747
drizzle->field_count))))
746
drizzleclient_set_error(drizzle, CR_OUT_OF_MEMORY, drizzleclient_sqlstate_get_unknown());
749
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
749
752
memset(result, 0,(sizeof(DRIZZLE_RES)+ sizeof(uint32_t) *
772
775
/**************************************************************************
773
776
Alloc struct for use with unbuffered reads. Data is fetched by domand
774
when calling to drizzleclient_fetch_row.
777
when calling to drizzle_fetch_row.
775
778
DRIZZLE_DATA_seek is a noop.
777
780
No other queries may be specified with the same DRIZZLE handle.
788
791
if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
790
drizzleclient_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, drizzleclient_sqlstate_get_unknown());
793
drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, sqlstate_get_unknown());
793
796
if (!(result=(DRIZZLE_RES*) malloc(sizeof(*result)+
824
827
@parma sqlstate SQL standard sqlstate
827
void drizzleclient_set_error(DRIZZLE *drizzle, int errcode, const char *sqlstate)
830
void drizzle_set_error(DRIZZLE *drizzle, int errcode, const char *sqlstate)
830
833
assert(drizzle != 0);
848
unsigned int drizzleclient_errno(const DRIZZLE *drizzle)
851
unsigned int drizzle_errno(const DRIZZLE *drizzle)
850
853
return drizzle ? drizzle->net.last_errno : drizzle_server_last_errno;
854
const char * drizzleclient_error(const DRIZZLE *drizzle)
857
const char * drizzle_error(const DRIZZLE *drizzle)
856
859
return drizzle ? _(drizzle->net.last_error) : _(drizzle_server_last_error);
862
865
@param drizzle connection handle
863
866
@param errcode CR_* errcode, for client errors
864
@param sqlstate SQL standard sql state, drizzleclient_sqlstate_get_unknown() for the
867
@param sqlstate SQL standard sql state, sqlstate_get_unknown() for the
865
868
majority of client errors.
866
869
@param format error message template, in sprintf format
867
870
@param ... variable number of arguments
870
void drizzleclient_set_extended_error(DRIZZLE *drizzle, int errcode,
873
void drizzle_set_extended_error(DRIZZLE *drizzle, int errcode,
871
874
const char *sqlstate,
872
875
const char *format, ...)
892
895
Flush result set sent from server
895
void drizzleclient_cli_flush_use_result(DRIZZLE *drizzle)
898
void cli_flush_use_result(DRIZZLE *drizzle)
897
900
/* Clear the current execution status */
900
903
uint32_t pkt_len;
901
if ((pkt_len=drizzleclient_cli_safe_read(drizzle)) == packet_error)
904
if ((pkt_len=cli_safe_read(drizzle)) == packet_error)
903
906
if (pkt_len <= 8 && drizzle->net.read_pos[0] == DRIZZLE_PROTOCOL_NO_MORE_DATA)
915
918
/**************************************************************************
916
919
Get column lengths of the current row
917
If one uses drizzleclient_use_result, res->lengths contains the length information,
920
If one uses drizzle_use_result, res->lengths contains the length information,
918
921
else the lengths are calculated from the offset between pointers.
919
922
**************************************************************************/
921
void drizzleclient_cli_fetch_lengths(uint32_t *to, DRIZZLE_ROW column, uint32_t field_count)
924
void cli_fetch_lengths(uint32_t *to, DRIZZLE_ROW column, uint32_t field_count)
923
926
uint32_t *prev_length;