Skip to content

Commit 7f35015

Browse files
committed
fix #43 fix send_long_data
1 parent aa940ee commit 7f35015

File tree

6 files changed

+275
-7
lines changed

6 files changed

+275
-7
lines changed

hash.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ struct session {
3939

4040
struct session *next;
4141

42-
// char is_stmt;
4342
ulong stmt_id;
43+
char is_long_data; /* if this flag, no parse_param, TODO next version */
4444
int param_count;
4545

4646
/* each param count 2 bytes */
@@ -377,8 +377,13 @@ hash_get_param_count(struct hash *hash,
377377
session->next->lport == lport
378378
) {
379379
if (stmt_id == session->next->stmt_id) {
380-
*param_count = session->next->param_count;
381-
*param_type = session->next->param_type;
380+
/* is_long_data cant valid param_count in COM_EXECUTE */
381+
if ('1' != session->next->is_long_data) {
382+
*param_count = session->next->param_count;
383+
*param_type = session->next->param_type;
384+
} else {
385+
dump(L_ERR, "this stmt_id %lu send_long_data, so cant get_param_count", stmt_id);
386+
}
382387
} else {
383388
/* TODO next version support */
384389
dump(L_ERR, "stmt_id not same %d %d, skip it", stmt_id, session->next->stmt_id);
@@ -390,6 +395,30 @@ hash_get_param_count(struct hash *hash,
390395
return -1;
391396
}
392397

398+
int
399+
hash_set_is_long_data(struct hash *hash,
400+
uint32_t laddr, uint32_t raddr, uint16_t lport, uint16_t rport, ulong stmt_id) {
401+
struct session *session;
402+
unsigned long port;
403+
404+
port = hash_fun(laddr, raddr, lport, rport) % hash->sz;
405+
406+
for (session = hash->sessions + port; session->next; session = session->next) {
407+
if (
408+
session->next->raddr == raddr &&
409+
session->next->laddr == laddr &&
410+
session->next->rport == rport &&
411+
session->next->lport == lport
412+
) {
413+
if (stmt_id == session->next->stmt_id) {
414+
session->next->is_long_data = '1';
415+
return 0;
416+
}
417+
}
418+
}
419+
return -1;
420+
}
421+
393422
/* save stmt_id, param_count */
394423
int
395424
hash_set_sql_len(struct hash *hash,
@@ -443,6 +472,7 @@ hash_set_param_count(struct hash *hash,
443472
/* TODO only support one stmt_id */
444473
session->next->tcp_seq = 0;
445474
session->next->stmt_id = stmt_id;
475+
session->next->is_long_data = '\0';
446476

447477
if (session->next->param_count == param_count)
448478
return 0;

hash.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,17 @@ void hash_stat(struct hash* hash);
7171

7272
int
7373
hash_set_stmt (struct hash *hash,
74-
uint32_t laddr, uint32_t raddr, uint16_t lport, uint16_t rport,
75-
enum SessionStatus status);
74+
uint32_t laddr, uint32_t raddr, uint16_t lport, uint16_t rport,
75+
enum SessionStatus status);
76+
77+
int
78+
hash_set_is_long_data (struct hash *hash,
79+
uint32_t laddr, uint32_t raddr, uint16_t lport, uint16_t rport, ulong stmt_id);
7680

7781
int
7882
hash_set_param_count (struct hash *hash,
79-
uint32_t laddr, uint32_t raddr, uint16_t lport, uint16_t rport,
80-
ulong stmt_id, int param_count);
83+
uint32_t laddr, uint32_t raddr, uint16_t lport, uint16_t rport,
84+
ulong stmt_id, int param_count);
8185

8286
int
8387
hash_set_param (struct hash *hash,

packet.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,12 @@ inbound(MysqlPcap *mp, char* data, uint32 datalen,
633633
dump(L_DEBUG, s);
634634
hash_set(mp->hash, dst, src,
635635
lport, rport, tv, s, cmd, NULL, db, 0, AfterSqlPacket);
636+
} else if (unlikely(cmd == COM_STMT_SEND_LONG_DATA)) {
637+
dump(L_ERR, "COM_STMT_SEND_LONG_DATA");
638+
ASSERT(datalen > 11);
639+
ulong stmt_id = uint4korr(data + 5);
640+
hash_set_is_long_data(mp->hash, dst, src, lport, rport, stmt_id);
641+
return OK;
636642
} else if (likely(cmd > 0)) {
637643
//ASSERT((cmd == COM_QUERY) || (cmd == COM_INIT_DB));
638644
/*

test/p22_blob.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include <stdio.h>
2+
#include <mysql.h>
3+
#include <unistd.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include "c.h"
7+
8+
int main(int argc, char* argv[])
9+
{
10+
MYSQL *mysql,*sock;
11+
MYSQL_ROW row;
12+
MYSQL_RES *result;
13+
14+
mysql = mysql_init(NULL);
15+
if (!(sock = CONN(CLIENT_MULTI_STATEMENTS))) {
16+
fprintf(stderr, "Couldn't connect to engine!\n%s\n\n", mysql_error(mysql));
17+
perror("");
18+
exit(1);
19+
}
20+
21+
// simple
22+
char sql[100] = {};
23+
24+
sprintf(sql, "INSERT INTO blob_test(a, b) VALUE (1, 2)");
25+
26+
mysql_query(sock, sql);
27+
28+
mysql_query(sock, "select * from blob_test");
29+
30+
result = mysql_store_result(mysql);
31+
mysql_free_result(result);
32+
33+
//prepare
34+
35+
MYSQL_STMT *stmt;
36+
MYSQL_BIND bind[2];
37+
my_ulonglong affected_rows;
38+
int param_count;
39+
short small_data;
40+
int int_data;
41+
char str_data[1000];
42+
unsigned long str_length;
43+
my_bool is_null;
44+
45+
stmt = mysql_stmt_init(mysql);
46+
47+
sprintf(sql, "INSERT INTO blob_test(a, b) VALUE (?, ?)");
48+
mysql_stmt_prepare(stmt, sql, strlen(sql));
49+
50+
memset(bind, 0, sizeof(bind));
51+
52+
/* INTEGER PARAM */
53+
/* This is a number type, so there is no need to specify buffer_length */
54+
bind[0].buffer_type= MYSQL_TYPE_LONG;
55+
bind[0].buffer= (char *)&int_data;
56+
bind[0].is_null= 0;
57+
58+
/* STRING PARAM */
59+
my_bool a = 1;
60+
bind[1].buffer_type= MYSQL_TYPE_BLOB;
61+
bind[1].buffer= (char *)str_data;
62+
bind[1].is_null= &a;
63+
bind[1].length= &str_length; //实际大小, bind_
64+
65+
mysql_stmt_bind_param(stmt, bind);
66+
67+
/* Specify the data values for the first row -------------------------------------------------- */
68+
int_data= 10; /* integer */
69+
strncpy(str_data, "MySQL", 1000); /* string */
70+
str_length= strlen(str_data);
71+
72+
mysql_stmt_execute(stmt);
73+
74+
mysql_stmt_close(stmt);
75+
76+
return 0;
77+
}
78+

test/p23_stmt_send_long_data.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#include <stdio.h>
2+
#include <mysql.h>
3+
#include <unistd.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include "c.h"
7+
8+
int main(int argc, char* argv[])
9+
{
10+
MYSQL *mysql,*sock;
11+
MYSQL_ROW row;
12+
MYSQL_RES *result;
13+
14+
mysql = mysql_init(NULL);
15+
if (!(sock = CONN(0))) {
16+
fprintf(stderr, "Couldn't connect to engine!\n%s\n\n", mysql_error(mysql));
17+
perror("");
18+
exit(1);
19+
}
20+
21+
// simple
22+
char sql[100] = {};
23+
24+
sprintf(sql, "INSERT INTO blob_test(a, b) VALUE (1, 2)");
25+
26+
mysql_query(sock, sql);
27+
28+
mysql_query(sock, "select * from blob_test");
29+
30+
result = mysql_store_result(mysql);
31+
mysql_free_result(result);
32+
33+
#define INSERT_QUERY "INSERT INTO blob_test(a, b) VALUES(?,?)"
34+
35+
MYSQL_STMT *stmt;
36+
MYSQL_BIND bind[2];
37+
long length;
38+
int int_data = 10;
39+
char str[100];
40+
int ret;
41+
42+
stmt = mysql_stmt_init(mysql);
43+
44+
mysql_stmt_prepare(stmt, INSERT_QUERY, strlen(INSERT_QUERY));
45+
46+
memset(bind, 0, sizeof(bind));
47+
bind[0].buffer_type= MYSQL_TYPE_LONG;
48+
bind[0].buffer= (char *)&int_data;
49+
bind[0].is_null= 0;
50+
bind[1].buffer_type= MYSQL_TYPE_BLOB;
51+
bind[1].buffer = (char*)&str;
52+
bind[1].is_null= 0;
53+
mysql_stmt_bind_param(stmt, bind);
54+
55+
ret = mysql_stmt_send_long_data(stmt,1,"MySQL",5);
56+
57+
ret = mysql_stmt_send_long_data(stmt,1," - The most popular Open Source database",40);
58+
59+
mysql_stmt_execute(stmt);
60+
61+
return 0;
62+
}
63+

test/p24_stmt_send_long_data2.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#include <stdio.h>
2+
#include <mysql.h>
3+
#include <unistd.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include "c.h"
7+
8+
int main(int argc, char* argv[])
9+
{
10+
MYSQL *mysql,*sock;
11+
MYSQL_ROW row;
12+
MYSQL_RES *result;
13+
14+
mysql = mysql_init(NULL);
15+
if (!(sock = CONN(0))) {
16+
fprintf(stderr, "Couldn't connect to engine!\n%s\n\n", mysql_error(mysql));
17+
perror("");
18+
exit(1);
19+
}
20+
21+
// simple
22+
char sql[100] = {};
23+
24+
sprintf(sql, "INSERT INTO blob_test(a, b) VALUE (1, 2)");
25+
26+
mysql_query(sock, sql);
27+
28+
mysql_query(sock, "select * from blob_test");
29+
30+
result = mysql_store_result(mysql);
31+
mysql_free_result(result);
32+
33+
#define INSERT_QUERY "INSERT INTO blob_test(a, b) VALUES(?,?)"
34+
35+
MYSQL_STMT *stmt;
36+
MYSQL_BIND bind[2];
37+
long length;
38+
int int_data = 10;
39+
char str[100];
40+
int ret;
41+
42+
stmt = mysql_stmt_init(mysql);
43+
44+
mysql_stmt_prepare(stmt, INSERT_QUERY, strlen(INSERT_QUERY));
45+
46+
memset(bind, 0, sizeof(bind));
47+
bind[0].buffer_type= MYSQL_TYPE_LONG;
48+
bind[0].buffer= (char *)&int_data;
49+
bind[0].is_null= 0;
50+
bind[1].buffer_type= MYSQL_TYPE_BLOB;
51+
bind[1].buffer = (char*)&str;
52+
bind[1].is_null= 0;
53+
mysql_stmt_bind_param(stmt, bind);
54+
55+
ret = mysql_stmt_send_long_data(stmt,1,"fails",5);
56+
57+
ret = mysql_stmt_send_long_data(stmt,1," - The most popular Open Source database",40);
58+
59+
mysql_stmt_execute(stmt);
60+
61+
mysql_stmt_close(stmt);
62+
63+
stmt = mysql_stmt_init(mysql);
64+
65+
mysql_stmt_prepare(stmt, INSERT_QUERY, strlen(INSERT_QUERY));
66+
67+
size_t s = sizeof(str);
68+
69+
memset(bind, 0, sizeof(bind));
70+
bind[0].buffer_type= MYSQL_TYPE_LONG;
71+
bind[0].buffer= (char *)&int_data;
72+
bind[0].is_null= 0;
73+
bind[1].buffer_type= MYSQL_TYPE_BLOB;
74+
bind[1].buffer = (char*)&str;
75+
bind[1].is_null= 0;
76+
bind[1].length= (char*)&s;
77+
mysql_stmt_bind_param(stmt, bind);
78+
79+
snprintf(str, sizeof(str), "%s", "this success");
80+
81+
mysql_stmt_execute(stmt);
82+
83+
mysql_stmt_close(stmt);
84+
85+
return 0;
86+
}
87+

0 commit comments

Comments
 (0)