From 0dca1378fe63223e66e8fa98135b3512eb7d87a7 Mon Sep 17 00:00:00 2001 From: "agentzh (Yichun Zhang)" Date: Wed, 27 Mar 2013 16:57:53 -0700 Subject: [PATCH] bugfix: 64-bit integer values in the MySQL packets (like last insert ids) could not be properly parsed due to the lack of support for 64-bit integers in LuaJIT's BitOp library. thanks Azure Wang for the patch in github pull #6. --- lib/resty/mysql.lua | 10 ++++++-- t/sanity.t | 62 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/lib/resty/mysql.lua b/lib/resty/mysql.lua index 7ac5b7b..9864618 100644 --- a/lib/resty/mysql.lua +++ b/lib/resty/mysql.lua @@ -76,8 +76,14 @@ end local function _get_byte8(data, i) local a, b, c, d, e, f, g, h = strbyte(data, i, i + 7) - return bor(a, lshift(b, 8), lshift(c, 16), lshift(d, 24), lshift(e, 32), - lshift(f, 40), lshift(g, 48), lshift(h, 56)), i + 8 + + -- XXX workaround for the lack of 64-bit support in bitop: + local lo = bor(a, lshift(b, 8), lshift(c, 16), lshift(d, 24)) + local hi = bor(e, lshift(f, 8), lshift(g, 16), lshift(h, 24)) + return lo + hi * 4294967296, i + 8 + + -- return bor(a, lshift(b, 8), lshift(c, 16), lshift(d, 24), lshift(e, 32), + -- lshift(f, 40), lshift(g, 48), lshift(h, 56)), i + 8 end diff --git a/t/sanity.t b/t/sanity.t index 5f25578..d44998f 100644 --- a/t/sanity.t +++ b/t/sanity.t @@ -1186,3 +1186,65 @@ result: \[\{"sum\(id\)":6\}\], err:nil$ qr/lua tcp socket keepalive create connection pool for key "my_pool"/ --- log_level: debug + + +=== TEST 18: large insert_id exceeding a 32-bit integer value +--- http_config eval: $::HttpConfig +--- config + location /t { + content_by_lua ' + local mysql = require("resty.mysql") + local create_sql = [[ + CREATE TABLE `large_t` ( + `id` bigint(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`id`) + ) AUTO_INCREMENT=5000000312; + ]] + local drop_sql = [[ + DROP TABLE IF EXISTS `large_t`; + ]] + local insert_sql = [[ + INSERT INTO `large_t` VALUES(NULL); + ]] + local db, err = mysql:new() + if not db then + ngx.say("failed to instantiate mysql: ", err) + return + end + db:set_timeout(1000) + local ok, err = db:connect{ + host = "$TEST_NGINX_MYSQL_HOST", + port = $TEST_NGINX_MYSQL_PORT, + database="test", + user="root", + password=""} + if not ok then + ngx.say("failed to connect: ", err, ": ", errno, " ", sqlstate) + return + end + local res, err = db:query(drop_sql) + if not res then + ngx.say("drop table error:" .. err) + return + end + local res, err = db:query(create_sql) + if not res then + ngx.say("create table error:" .. err) + return + end + local res, err = db:query(insert_sql) + if not res then + ngx.say("insert table error:" .. err) + return + else + ngx.say(res.insert_id) + end + '; + } +--- request +GET /t +--- response_body +5000000312 +--- no_error_log +[error] +