diff --git a/include/ma_pvio.h b/include/ma_pvio.h index d98fa6c4..2e22bc4a 100644 --- a/include/ma_pvio.h +++ b/include/ma_pvio.h @@ -55,6 +55,8 @@ enum enum_pvio_operation { PVIO_WRITE=1 }; +#define SHM_DEFAULT_NAME "MYSQL" + struct st_pvio_callback; typedef struct st_pvio_callback { diff --git a/libmariadb/ma_pvio.c b/libmariadb/ma_pvio.c index 77208b4a..dc74d08e 100644 --- a/libmariadb/ma_pvio.c +++ b/libmariadb/ma_pvio.c @@ -139,9 +139,11 @@ MARIADB_PVIO *ma_pvio_init(MA_PVIO_CINFO *cinfo) /* {{{ my_bool ma_pvio_is_alive */ my_bool ma_pvio_is_alive(MARIADB_PVIO *pvio) { + if (!pvio) + return FALSE; if (pvio->methods->is_alive) return pvio->methods->is_alive(pvio); - return FALSE; + return TRUE; } /* }}} */ diff --git a/libmariadb/ma_stmt_codec.c b/libmariadb/ma_stmt_codec.c index 29f6b105..c8a53966 100644 --- a/libmariadb/ma_stmt_codec.c +++ b/libmariadb/ma_stmt_codec.c @@ -921,47 +921,28 @@ static void ps_fetch_bin(MYSQL_BIND *r_param, const MYSQL_FIELD *field, unsigned char **row) { - /* If r_praram->buffer_type is not a binary type or binary_flag isn't set, - we do conversion from string */ - if (!(field->flags & BINARY_FLAG) || - (r_param->buffer_type != MYSQL_TYPE_NEWDECIMAL && - r_param->buffer_type != MYSQL_TYPE_DECIMAL && - r_param->buffer_type != MYSQL_TYPE_GEOMETRY && - r_param->buffer_type != MYSQL_TYPE_ENUM && - r_param->buffer_type != MYSQL_TYPE_SET && - r_param->buffer_type != MYSQL_TYPE_TINY_BLOB && - r_param->buffer_type != MYSQL_TYPE_MEDIUM_BLOB && - r_param->buffer_type != MYSQL_TYPE_LONG_BLOB && - r_param->buffer_type != MYSQL_TYPE_BLOB)) - { - ps_fetch_string(r_param, field, row); - return; - } - else - { - ulong field_length= *r_param->length= net_field_length(row); - uchar *current_pos= (*row) + r_param->offset, - *end= (*row) + field_length; - size_t copylen= 0; + ulong field_length= *r_param->length= net_field_length(row); + uchar *current_pos= (*row) + r_param->offset, + *end= (*row) + field_length; + size_t copylen= 0; - if (current_pos < end) + if (current_pos < end) + { + copylen= end - current_pos; + if (r_param->buffer_length) { - copylen= end - current_pos; - if (r_param->buffer_length) - { - memcpy(r_param->buffer, current_pos, MIN(copylen, r_param->buffer_length)); - if (copylen < r_param->buffer_length && - r_param->buffer_type == MYSQL_TYPE_STRING) - ((char *)r_param->buffer)[copylen]= 0; - } + memcpy(r_param->buffer, current_pos, MIN(copylen, r_param->buffer_length)); + if (copylen < r_param->buffer_length && + r_param->buffer_type == MYSQL_TYPE_STRING) + ((char *)r_param->buffer)[copylen]= 0; } - *r_param->error= copylen > r_param->buffer_length; - /* don't count trailing zero if we fetch into string */ - if (r_param->buffer_type == MYSQL_TYPE_STRING && - !*r_param->error) - field_length--; - (*row)+= field_length; } + *r_param->error= copylen > r_param->buffer_length; + /* don't count trailing zero if we fetch into string */ + if (r_param->buffer_type == MYSQL_TYPE_STRING && + !*r_param->error) + field_length--; + (*row)+= field_length; } /* }}} */ diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index aa5e11cd..9eb44b2f 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -1221,8 +1221,15 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user, else #endif #else + if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY || + mysql->options.shared_memory_base_name) + { + cinfo.host= mysql->options.shared_memory_base_name; + cinfo.type= PVIO_TYPE_SHAREDMEM; + sprintf(host_info=buff,ER(CR_SHARED_MEMORY_CONNECTION), cinfo.host ? cinfo.host : SHM_DEFAULT_NAME); + } /* named pipe */ - if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE || + else if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE || (host && strcmp(host,LOCAL_HOST_NAMEDPIPE) == 0)) { cinfo.type= PVIO_TYPE_NAMEDPIPE; @@ -2621,6 +2628,11 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...) case MYSQL_OPT_PROTOCOL: mysql->options.protocol= *((uint *)arg1); break; +#ifdef _WIN32 + case MYSQL_SHARED_MEMORY_BASE_NAME: + OPT_SET_VALUE_STR(&mysql->options, shared_memory_base_name, arg1); + break; +#endif case MYSQL_OPT_READ_TIMEOUT: mysql->options.read_timeout= *(uint *)arg1; break; diff --git a/plugins/pvio/pvio_npipe.c b/plugins/pvio/pvio_npipe.c index 2dfa7535..2deadee7 100644 --- a/plugins/pvio/pvio_npipe.c +++ b/plugins/pvio/pvio_npipe.c @@ -46,6 +46,7 @@ int pvio_npipe_keepalive(MARIADB_PVIO *pvio); my_bool pvio_npipe_get_handle(MARIADB_PVIO *pvio, void *handle); my_bool pvio_npipe_is_blocking(MARIADB_PVIO *pvio); int pvio_npipe_shutdown(MARIADB_PVIO *pvio); +my_bool pvio_npipe_is_alive(MARIADB_PVIO *pvio); struct st_ma_pvio_methods pvio_npipe_methods= { pvio_npipe_set_timeout, @@ -62,7 +63,7 @@ struct st_ma_pvio_methods pvio_npipe_methods= { pvio_npipe_keepalive, pvio_npipe_get_handle, pvio_npipe_is_blocking, - NULL, + pvio_npipe_is_alive, NULL, pvio_npipe_shutdown }; @@ -367,4 +368,16 @@ int pvio_npipe_shutdown(MARIADB_PVIO *pvio) } return 1; } + +my_bool pvio_npipe_is_alive(MARIADB_PVIO *pvio) +{ + HANDLE handle; + if (!pvio || !pvio->data) + return FALSE; + handle= ((struct st_pvio_npipe *)pvio->data)->pipe; + /* Copy data fron named pipe without removing it */ + if (PeekNamedPipe(handle, NULL, 0, NULL, NULL, NULL)) + return TRUE; + return test(GetLastError() != ERROR_BROKEN_PIPE); +} #endif diff --git a/plugins/pvio/pvio_shmem.c b/plugins/pvio/pvio_shmem.c index 4d8ef572..1c39cbf4 100644 --- a/plugins/pvio/pvio_shmem.c +++ b/plugins/pvio/pvio_shmem.c @@ -29,7 +29,6 @@ #include #include -#define SHM_DEFAULT_NAME "MYSQL" #define PVIO_SHM_BUFFER_SIZE 16000 + 4 my_bool pvio_shm_set_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type, int timeout); @@ -41,6 +40,8 @@ my_bool pvio_shm_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value) my_bool pvio_shm_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo); my_bool pvio_shm_close(MARIADB_PVIO *pvio); int pvio_shm_shutdown(MARIADB_PVIO *pvio); +my_bool pvio_shm_is_alive(MARIADB_PVIO *pvio); +my_bool pvio_shm_get_handle(MARIADB_PVIO *pvio, void *handle); struct st_ma_pvio_methods pvio_shm_methods= { pvio_shm_set_timeout, @@ -55,9 +56,9 @@ struct st_ma_pvio_methods pvio_shm_methods= { pvio_shm_close, NULL, NULL, + pvio_shm_get_handle, NULL, - NULL, - NULL, + pvio_shm_is_alive, NULL, pvio_shm_shutdown }; @@ -262,9 +263,7 @@ my_bool pvio_shm_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo) */ - base_memory_name= (cinfo->mysql->options.shared_memory_base_name) ? - cinfo->mysql->options.shared_memory_base_name : SHM_DEFAULT_NAME; - + base_memory_name= (cinfo->host) ? cinfo->host : SHM_DEFAULT_NAME; if (!(shm_name= (char *)LocalAlloc(LMEM_ZEROINIT, strlen(base_memory_name) + 40))) { @@ -447,5 +446,24 @@ int pvio_shm_shutdown(MARIADB_PVIO *pvio) return (SetEvent(pvio_shm->event[PVIO_SHM_CONNECTION_CLOSED]) ? 0 : 1); return 1; } + +my_bool pvio_shm_is_alive(MARIADB_PVIO *pvio) +{ + PVIO_SHM *pvio_shm; + if (!pvio || !pvio->data) + return FALSE; + pvio_shm= (PVIO_SHM *)pvio->data; + return WaitForSingleObject(pvio_shm->event[PVIO_SHM_CONNECTION_CLOSED], 0); +} + +my_bool pvio_shm_get_handle(MARIADB_PVIO *pvio, void *handle) +{ + PVIO_SHM *pvio_shm; + *(HANDLE **)handle= 0; + if (!pvio || !pvio->data) + return FALSE; + *(HANDLE **)handle= (HANDLE **)((PVIO_SHM*)pvio->data)->event; + return TRUE; +} #endif diff --git a/unittest/libmariadb/my_test.h b/unittest/libmariadb/my_test.h index c1acf256..771af6f8 100644 --- a/unittest/libmariadb/my_test.h +++ b/unittest/libmariadb/my_test.h @@ -122,6 +122,9 @@ static char *password = 0; static unsigned int port = 0; static char *socketname = 0; static char *username = 0; +#ifdef _WIN32 +static int protocol= 0; +#endif /* static struct my_option test_options[] = { @@ -312,19 +315,24 @@ static void usage() printf("-d database\n"); printf("-S socketname\n"); printf("-P port number\n"); + printf("-w protocol mode (windows only: 1= named pipe, 2= shared memory)"); printf("? displays this help and exits\n"); -} void get_options(int argc, char **argv) { int c= 0; - while ((c=getopt(argc,argv, "h:u:p:d:P:S:?")) >= 0) + while ((c=getopt(argc,argv, "h:u:p:d:w:P:S:?")) >= 0) { switch(c) { case 'h': hostname= optarg; break; + case 'w': +#ifdef _WIN32 + protocol= atoi(optarg); +#endif + break; case 'u': username= optarg; break; @@ -388,7 +396,12 @@ MYSQL *test_connect(struct my_tests_st *test) { diag("%s", "mysql_init failed - exiting"); return(NULL); } - +#ifdef _WIN32 + switch (protocol) { + case 1: /* named pipe */ + case 2: /* shared memory */ + } +#endif mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, &truncation_report); mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, &timeout); @@ -414,6 +427,7 @@ MYSQL *test_connect(struct my_tests_st *test) { mysql_close(mysql); return(NULL); } + printf("Connection: %s\n", mysql->host_info); return(mysql); } diff --git a/unittest/libmariadb/ps.c b/unittest/libmariadb/ps.c index f66e2cd7..25ec9013 100644 --- a/unittest/libmariadb/ps.c +++ b/unittest/libmariadb/ps.c @@ -4857,7 +4857,53 @@ int test_notrunc(MYSQL *mysql) return OK; } +static int test_bit2tiny(MYSQL *mysql) +{ + MYSQL_BIND bind[2]; + char data[11]; + unsigned long length[2]; + my_bool is_null[2], error[2]; + char *query = "SELECT val FROM justbit"; + MYSQL_STMT *stmt; + int rc; + + mysql_query(mysql, "DROP TABLE IF EXISTS justbit"); + mysql_query(mysql, "CREATE TABLE justbit(val bit(1) not null)"); + mysql_query(mysql, "INSERT INTO justbit values (1)"); + + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_stmt_rc(rc, stmt); + + memset(bind, '\0', sizeof(bind)); + + bind[0].buffer_type= MYSQL_TYPE_TINY; + bind[0].buffer= &data[0]; + bind[0].buffer_length= 1; + bind[0].is_null= &is_null[0]; + bind[0].length= &length[0]; + bind[0].error= &error[0]; + + rc= mysql_stmt_execute(stmt); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_bind_result(stmt, bind); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_store_result(stmt); + check_stmt_rc(rc, stmt); + + mysql_stmt_fetch(stmt); + + FAIL_IF(data[0] != 1, "Value should be 1"); + + mysql_stmt_free_result(stmt); + mysql_stmt_close(stmt); + return OK; +} + struct my_tests_st my_tests[] = { + {"test_bit2tiny", test_bit2tiny, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_conc97", test_conc97, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_conc83", test_conc83, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"test_conc60", test_conc60, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},