From 3b0acaf5356c581253d48c60bf728565993ee067 Mon Sep 17 00:00:00 2001 From: parihaaraka Date: Wed, 1 Dec 2021 14:19:03 +0300 Subject: [PATCH 1/6] [u]int64_t parameters; decimal->number cast removed in favor of original textual representation --- pg/driver.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/pg/driver.c b/pg/driver.c index 0bc9620..126d5ea 100644 --- a/pg/driver.c +++ b/pg/driver.c @@ -108,8 +108,7 @@ parse_pg_value(struct lua_State *L, PGresult *res, int row, int col) switch (PQftype(res, col)) { case INT2OID: - case INT4OID: - case NUMERICOID: { + case INT4OID: { lua_pushlstring(L, val, len); double v = lua_tonumber(L, -1); lua_pop(L, 1); @@ -127,6 +126,7 @@ parse_pg_value(struct lua_State *L, PGresult *res, int row, int col) else lua_pushboolean(L, 0); break; + //case NUMERICOID: // leave it as is (otherwise cast to decimal) default: lua_pushlstring(L, val, len); } @@ -293,6 +293,27 @@ lua_parse_param(struct lua_State *L, return; } + if (luaL_iscdata(L, idx)) { + uint32_t ctypeid = 0; + void *cdata = luaL_checkcdata(L, idx, &ctypeid); + static char buf[24]; + int len = 0; + if (ctypeid == luaL_ctypeid(L, "int64_t")) { + len = snprintf(buf, sizeof(buf), "%ld", *(int64_t*)cdata); + *type = INT8OID; + } + else if (ctypeid == luaL_ctypeid(L, "uint64_t")) { + len = snprintf(buf, sizeof(buf), "%lu", *(uint64_t*)cdata); + *type = NUMERICOID; + } + + if (len > 0) { + *value = buf; + *length = len; + return; + } + } + // We will pass all other types as strings size_t len; *value = lua_tolstring(L, idx, &len); From 6b93cc8f5a8c22bacc5229c6474ab88317aada2f Mon Sep 17 00:00:00 2001 From: parihaaraka Date: Wed, 30 Mar 2022 16:31:58 +0300 Subject: [PATCH 2/6] new `connection.dec_cast` option ('s' - string, 'n' - number, default is 'n') --- pg/driver.c | 37 +++++++++++++++++++++++++++---------- pg/init.lua | 3 ++- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/pg/driver.c b/pg/driver.c index 126d5ea..9715852 100644 --- a/pg/driver.c +++ b/pg/driver.c @@ -97,7 +97,7 @@ lua_push_error(struct lua_State *L) * Parse pg values to lua */ static int -parse_pg_value(struct lua_State *L, PGresult *res, int row, int col) +parse_pg_value(struct lua_State *L, char dec_cast, PGresult *res, int row, int col) { if (PQgetisnull(res, row, col)) return false; @@ -107,6 +107,14 @@ parse_pg_value(struct lua_State *L, PGresult *res, int row, int col) int len = PQgetlength(res, row, col); switch (PQftype(res, col)) { + case NUMERICOID: { + if (dec_cast == 's') + { + lua_pushlstring(L, val, len); + break; + } + // else fallthrough + } case INT2OID: case INT4OID: { lua_pushlstring(L, val, len); @@ -126,7 +134,6 @@ parse_pg_value(struct lua_State *L, PGresult *res, int row, int col) else lua_pushboolean(L, 0); break; - //case NUMERICOID: // leave it as is (otherwise cast to decimal) default: lua_pushlstring(L, val, len); } @@ -141,6 +148,7 @@ static int safe_pg_parsetuples(struct lua_State *L) { PGresult *res = (PGresult *)lua_topointer(L, 1); + const char dec_cast = (char)lua_tointeger(L, 2); int row, rows = PQntuples(res); int col, cols = PQnfields(res); lua_newtable(L); @@ -148,7 +156,7 @@ safe_pg_parsetuples(struct lua_State *L) lua_pushnumber(L, row + 1); lua_newtable(L); for (col = 0; col < cols; ++col) - parse_pg_value(L, res, row, col); + parse_pg_value(L, dec_cast, res, row, col); lua_settable(L, -3); } return 1; @@ -205,7 +213,7 @@ pg_wait_for_result(PGconn *conn) * Appends result fom postgres to lua table */ static int -pg_resultget(struct lua_State *L, PGconn *conn, int *res_no, int status_ok) +pg_resultget(struct lua_State *L, const char dec_cast, PGconn *conn, int *res_no, int status_ok) { int wait_res = pg_wait_for_result(conn); if (wait_res != 1) @@ -235,7 +243,8 @@ pg_resultget(struct lua_State *L, PGconn *conn, int *res_no, int status_ok) lua_pushinteger(L, (*res_no)++); lua_pushcfunction(L, safe_pg_parsetuples); lua_pushlightuserdata(L, pg_res); - fail = lua_pcall(L, 1, 1, 0); + lua_pushinteger(L, dec_cast); + fail = lua_pcall(L, 2, 1, 0); if (!fail) lua_settable(L, -3); case PGRES_COMMAND_OK: @@ -328,12 +337,20 @@ static int lua_pg_execute(struct lua_State *L) { PGconn *conn = lua_check_pgconn(L, 1); - if (!lua_isstring(L, 2)) { + + char dec_cast = 'n'; + if (lua_isstring(L, 2)) { + const char *tmp = lua_tostring(L, 2); + if (*tmp == 'n' || *tmp == 's') // TODO 'd' - decimal + dec_cast = *tmp; + } + + if (!lua_isstring(L, 3)) { safe_pushstring(L, "Second param should be a sql command"); return lua_push_error(L); } - const char *sql = lua_tostring(L, 2); - int paramCount = lua_gettop(L) - 2; + const char *sql = lua_tostring(L, 3); + int paramCount = lua_gettop(L) - 3; const char **paramValues = NULL; int *paramLengths = NULL; @@ -354,7 +371,7 @@ lua_pg_execute(struct lua_State *L) int idx; for (idx = 0; idx < paramCount; ++idx) { - lua_parse_param(L, idx + 3, paramValues + idx, + lua_parse_param(L, idx + 4, paramValues + idx, paramLengths + idx, paramTypes + idx); } res = PQsendQueryParams(conn, sql, paramCount, paramTypes, @@ -373,7 +390,7 @@ lua_pg_execute(struct lua_State *L) int res_no = 1; int status_ok = 1; - while ((status_ok = pg_resultget(L, conn, &res_no, status_ok))); + while ((status_ok = pg_resultget(L, dec_cast, conn, &res_no, status_ok))); return 2; } diff --git a/pg/init.lua b/pg/init.lua index b1000d6..d95e84b 100644 --- a/pg/init.lua +++ b/pg/init.lua @@ -15,6 +15,7 @@ local function conn_create(pg_conn) usable = true, conn = pg_conn, queue = queue, + dec_cast = 'n' -- 'n' - number, 's' - string }, conn_mt) return conn @@ -60,7 +61,7 @@ conn_mt = { self.queue:put(false) return get_error(self.raise.pool, 'Connection is broken') end - local status, datas = self.conn:execute(sql, ...) + local status, datas = self.conn:execute(self.dec_cast, sql, ...) if status ~= 0 then self.queue:put(status > 0) return error(datas) From 6b7de5657748e4757e1a926df95d7bcfc9339e51 Mon Sep 17 00:00:00 2001 From: parihaaraka Date: Thu, 31 Mar 2022 13:31:56 +0300 Subject: [PATCH 3/6] optional pg decimal to tnt decimal cast --- pg/driver.c | 56 +++++++++++++++++++++++++++++++++++++++-------------- pg/init.lua | 12 ++++++++++-- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/pg/driver.c b/pg/driver.c index 9715852..8ad8376 100644 --- a/pg/driver.c +++ b/pg/driver.c @@ -49,6 +49,12 @@ #undef PACKAGE_VERSION #include +struct dec_opt { + char cast; + int dnew_index; +}; +typedef struct dec_opt dec_opt_t; + /** * Infinity timeout from tarantool_ev.c. I mean, this should be in * a module.h file. @@ -97,7 +103,7 @@ lua_push_error(struct lua_State *L) * Parse pg values to lua */ static int -parse_pg_value(struct lua_State *L, char dec_cast, PGresult *res, int row, int col) +parse_pg_value(struct lua_State *L, dec_opt_t *dopt, PGresult *res, int row, int col) { if (PQgetisnull(res, row, col)) return false; @@ -108,9 +114,18 @@ parse_pg_value(struct lua_State *L, char dec_cast, PGresult *res, int row, int c switch (PQftype(res, col)) { case NUMERICOID: { - if (dec_cast == 's') - { + if (dopt->cast == 's') { + lua_pushlstring(L, val, len); + break; + } + else if (dopt->cast == 'd' && dopt->dnew_index != -1) { + lua_rawgeti(L, LUA_REGISTRYINDEX, dopt->dnew_index); lua_pushlstring(L, val, len); + int fail = lua_pcall(L, 1, 1, 0); + if (fail) { + lua_pop(L, 2); + return false; + } break; } // else fallthrough @@ -148,7 +163,7 @@ static int safe_pg_parsetuples(struct lua_State *L) { PGresult *res = (PGresult *)lua_topointer(L, 1); - const char dec_cast = (char)lua_tointeger(L, 2); + dec_opt_t *dopt = (dec_opt_t *)lua_topointer(L, 2); int row, rows = PQntuples(res); int col, cols = PQnfields(res); lua_newtable(L); @@ -156,7 +171,7 @@ safe_pg_parsetuples(struct lua_State *L) lua_pushnumber(L, row + 1); lua_newtable(L); for (col = 0; col < cols; ++col) - parse_pg_value(L, dec_cast, res, row, col); + parse_pg_value(L, dopt, res, row, col); lua_settable(L, -3); } return 1; @@ -213,7 +228,7 @@ pg_wait_for_result(PGconn *conn) * Appends result fom postgres to lua table */ static int -pg_resultget(struct lua_State *L, const char dec_cast, PGconn *conn, int *res_no, int status_ok) +pg_resultget(struct lua_State *L, dec_opt_t *dopt, PGconn *conn, int *res_no, int status_ok) { int wait_res = pg_wait_for_result(conn); if (wait_res != 1) @@ -243,7 +258,7 @@ pg_resultget(struct lua_State *L, const char dec_cast, PGconn *conn, int *res_no lua_pushinteger(L, (*res_no)++); lua_pushcfunction(L, safe_pg_parsetuples); lua_pushlightuserdata(L, pg_res); - lua_pushinteger(L, dec_cast); + lua_pushlightuserdata(L, dopt); fail = lua_pcall(L, 2, 1, 0); if (!fail) lua_settable(L, -3); @@ -338,19 +353,25 @@ lua_pg_execute(struct lua_State *L) { PGconn *conn = lua_check_pgconn(L, 1); - char dec_cast = 'n'; + dec_opt_t dopt = {'n', -1}; if (lua_isstring(L, 2)) { const char *tmp = lua_tostring(L, 2); - if (*tmp == 'n' || *tmp == 's') // TODO 'd' - decimal - dec_cast = *tmp; + if (*tmp == 'n' || *tmp == 's' || *tmp == 'd') + dopt.cast = *tmp; } - if (!lua_isstring(L, 3)) { + if (!lua_isstring(L, 4)) { safe_pushstring(L, "Second param should be a sql command"); return lua_push_error(L); } - const char *sql = lua_tostring(L, 3); - int paramCount = lua_gettop(L) - 3; + + if (lua_isfunction(L, 3)) { + lua_pushvalue(L, 3); + dopt.dnew_index = luaL_ref(L, LUA_REGISTRYINDEX); + } + + const char *sql = lua_tostring(L, 4); + int paramCount = lua_gettop(L) - 4; const char **paramValues = NULL; int *paramLengths = NULL; @@ -371,7 +392,7 @@ lua_pg_execute(struct lua_State *L) int idx; for (idx = 0; idx < paramCount; ++idx) { - lua_parse_param(L, idx + 4, paramValues + idx, + lua_parse_param(L, idx + 5, paramValues + idx, paramLengths + idx, paramTypes + idx); } res = PQsendQueryParams(conn, sql, paramCount, paramTypes, @@ -383,6 +404,8 @@ lua_pg_execute(struct lua_State *L) if (res == -1) { lua_pushinteger(L, PQstatus(conn) == CONNECTION_BAD ? -1: 0); lua_pushstring(L, PQerrorMessage(conn)); + if (dopt.dnew_index != -1) + luaL_unref(L, LUA_REGISTRYINDEX, dopt.dnew_index); return 2; } lua_pushinteger(L, 0); @@ -390,7 +413,10 @@ lua_pg_execute(struct lua_State *L) int res_no = 1; int status_ok = 1; - while ((status_ok = pg_resultget(L, dec_cast, conn, &res_no, status_ok))); + while ((status_ok = pg_resultget(L, &dopt, conn, &res_no, status_ok))); + + if (dopt.dnew_index != -1) + luaL_unref(L, LUA_REGISTRYINDEX, dopt.dnew_index); return 2; } diff --git a/pg/init.lua b/pg/init.lua index d95e84b..686f426 100644 --- a/pg/init.lua +++ b/pg/init.lua @@ -4,6 +4,14 @@ local fiber = require('fiber') local driver = require('pg.driver') local ffi = require('ffi') +local dnew +do + local ok, dec = pcall(require, "decimal") + if ok then + dnew = dec.new + end +end + local pool_mt local conn_mt @@ -15,7 +23,7 @@ local function conn_create(pg_conn) usable = true, conn = pg_conn, queue = queue, - dec_cast = 'n' -- 'n' - number, 's' - string + dec_cast = 'n' -- 'n' - number, 's' - string, 'd' - decimal }, conn_mt) return conn @@ -61,7 +69,7 @@ conn_mt = { self.queue:put(false) return get_error(self.raise.pool, 'Connection is broken') end - local status, datas = self.conn:execute(self.dec_cast, sql, ...) + local status, datas = self.conn:execute(self.dec_cast, dnew, sql, ...) if status ~= 0 then self.queue:put(status > 0) return error(datas) From 9ed329115bf66d4d48771b109eefc072ccf20f96 Mon Sep 17 00:00:00 2001 From: parihaaraka Date: Thu, 31 Mar 2022 21:52:06 +0300 Subject: [PATCH 4/6] multiple [u]int64_t parameters usage fix --- pg/driver.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/pg/driver.c b/pg/driver.c index 8ad8376..b4f6aa6 100644 --- a/pg/driver.c +++ b/pg/driver.c @@ -293,6 +293,13 @@ static void lua_parse_param(struct lua_State *L, int idx, const char **value, int *length, Oid *type) { + static char buf[512]; // buffer for serialized [u]int64_t + static char *pos; + if (idx == 5) { // lua_parse_param(L, idx + 5, ... + *buf = '\0'; + pos = buf; + } + if (lua_isnil(L, idx)) { *value = NULL; *length = 0; @@ -320,20 +327,20 @@ lua_parse_param(struct lua_State *L, if (luaL_iscdata(L, idx)) { uint32_t ctypeid = 0; void *cdata = luaL_checkcdata(L, idx, &ctypeid); - static char buf[24]; int len = 0; if (ctypeid == luaL_ctypeid(L, "int64_t")) { - len = snprintf(buf, sizeof(buf), "%ld", *(int64_t*)cdata); + len = snprintf(pos, sizeof(buf) - (pos - buf), "%ld", *(int64_t*)cdata); *type = INT8OID; } else if (ctypeid == luaL_ctypeid(L, "uint64_t")) { - len = snprintf(buf, sizeof(buf), "%lu", *(uint64_t*)cdata); + len = snprintf(pos, sizeof(buf) - (pos - buf), "%lu", *(uint64_t*)cdata); *type = NUMERICOID; } if (len > 0) { - *value = buf; + *value = pos; *length = len; + pos += len + 1; return; } } From 66477ca34f2d04e789be457ede12824683ed29ef Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Wed, 13 Jul 2022 19:01:20 +0300 Subject: [PATCH 5/6] Set a type for PostreSQL decimal numbers [TO SQUASH] [REMOVE BEFORE MERGE] Changes proposed in fixup commit: documentation, regression tests, code style. Patch adds support of PostgreSQL decimal numbers - it is possible to choose a Lua/Tarantool type that will be used for casting values with NUMERIC type [1]. By default Lua "number" type is used, the same behaviour was used before changes. Additionally user could choose two other types: Lua "string" and Tarantool's decimal type [2], [3]. Fixes #26 Fixes #25 1. https://www.postgresql.org/docs/current/datatype-oid.html 2. https://www.tarantool.io/en/doc/latest/reference/reference_lua/decimal/ 3. https://www.tarantool.io/en/doc/latest/book/box/data_model/#data-types Co-authored-by: Sergey Bronnikov --- README.md | 2 ++ pg/driver.c | 46 +++++++++++++++++++++++++++++++++++----------- pg/init.lua | 14 +++++++------- test/pg.test.lua | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 8a063a6..203bd15 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,8 @@ Connect to a database. - `db` - a database name - `conn_string` (mutual exclusive with host, port, user, pass, db) - PostgreSQL [connection string][PQconnstring] + - `dec_cast` - an option that switches casting types for `NUMERIC` PostgreSQL + type. Possible values: `n` (`number`), `s` (`string`), `d` (`decimal`). *Returns*: diff --git a/pg/driver.c b/pg/driver.c index b4f6aa6..6ce6c5d 100644 --- a/pg/driver.c +++ b/pg/driver.c @@ -49,6 +49,25 @@ #undef PACKAGE_VERSION #include +/** + * The fallthrough attribute with a null statement serves as a fallthrough + * statement. It hints to the compiler that a statement that falls through + * to another case label, or user-defined label in a switch statement is + * intentional and thus the -Wimplicit-fallthrough warning must not trigger. + * The fallthrough attribute may appear at most once in each attribute list, + * and may not be mixed with other attributes. It can only be used in a switch + * statement (the compiler will issue an error otherwise), after a preceding + * statement and before a logically succeeding case label, or user-defined + * label. + */ +#if defined(__cplusplus) && __has_cpp_attribute(fallthrough) +# define FALLTHROUGH [[fallthrough]] +#elif __has_attribute(fallthrough) || (defined(__GNUC__) && __GNUC__ >= 7) +# define FALLTHROUGH __attribute__((fallthrough)) +#else +# define FALLTHROUGH +#endif + struct dec_opt { char cast; int dnew_index; @@ -103,7 +122,7 @@ lua_push_error(struct lua_State *L) * Parse pg values to lua */ static int -parse_pg_value(struct lua_State *L, dec_opt_t *dopt, PGresult *res, int row, int col) +parse_pg_value(struct lua_State *L, PGresult *res, int row, int col, dec_opt_t *dopt) { if (PQgetisnull(res, row, col)) return false; @@ -128,7 +147,8 @@ parse_pg_value(struct lua_State *L, dec_opt_t *dopt, PGresult *res, int row, int } break; } - // else fallthrough + /* 'n': fallthrough */ + FALLTHROUGH; } case INT2OID: case INT4OID: { @@ -171,7 +191,7 @@ safe_pg_parsetuples(struct lua_State *L) lua_pushnumber(L, row + 1); lua_newtable(L); for (col = 0; col < cols; ++col) - parse_pg_value(L, dopt, res, row, col); + parse_pg_value(L, res, row, col, dopt); lua_settable(L, -3); } return 1; @@ -228,7 +248,7 @@ pg_wait_for_result(PGconn *conn) * Appends result fom postgres to lua table */ static int -pg_resultget(struct lua_State *L, dec_opt_t *dopt, PGconn *conn, int *res_no, int status_ok) +pg_resultget(struct lua_State *L, PGconn *conn, int *res_no, int status_ok, dec_opt_t *dopt) { int wait_res = pg_wait_for_result(conn); if (wait_res != 1) @@ -293,9 +313,11 @@ static void lua_parse_param(struct lua_State *L, int idx, const char **value, int *length, Oid *type) { - static char buf[512]; // buffer for serialized [u]int64_t - static char *pos; - if (idx == 5) { // lua_parse_param(L, idx + 5, ... + /* Serialized [u]int64_t */ + static char buf[512]; + static char *pos = NULL; + /* lua_parse_param(L, idx + 5, ...) */ + if (idx == 5) { *buf = '\0'; pos = buf; } @@ -362,9 +384,11 @@ lua_pg_execute(struct lua_State *L) dec_opt_t dopt = {'n', -1}; if (lua_isstring(L, 2)) { - const char *tmp = lua_tostring(L, 2); - if (*tmp == 'n' || *tmp == 's' || *tmp == 'd') - dopt.cast = *tmp; + const char *dec_cast_type = lua_tostring(L, 2); + if (*dec_cast_type == 'n' || + *dec_cast_type == 's' || + *dec_cast_type == 'd') + dopt.cast = *dec_cast_type; } if (!lua_isstring(L, 4)) { @@ -420,7 +444,7 @@ lua_pg_execute(struct lua_State *L) int res_no = 1; int status_ok = 1; - while ((status_ok = pg_resultget(L, &dopt, conn, &res_no, status_ok))); + while ((status_ok = pg_resultget(L, conn, &res_no, status_ok, &dopt))); if (dopt.dnew_index != -1) luaL_unref(L, LUA_REGISTRYINDEX, dopt.dnew_index); diff --git a/pg/init.lua b/pg/init.lua index 686f426..91ff0ea 100644 --- a/pg/init.lua +++ b/pg/init.lua @@ -4,12 +4,9 @@ local fiber = require('fiber') local driver = require('pg.driver') local ffi = require('ffi') -local dnew -do - local ok, dec = pcall(require, "decimal") - if ok then - dnew = dec.new - end +local has_decimal, dec = pcall(require, 'decimal') +if has_decimal then + dnew = dec.new end local pool_mt @@ -23,7 +20,10 @@ local function conn_create(pg_conn) usable = true, conn = pg_conn, queue = queue, - dec_cast = 'n' -- 'n' - number, 's' - string, 'd' - decimal + dec_cast = 'n' -- Defined in pg/driver.c: + -- 'n' - number, + -- 's' - string, + -- 'd' - decimal. }, conn_mt) return conn diff --git a/test/pg.test.lua b/test/pg.test.lua index 144ceea..871f395 100755 --- a/test/pg.test.lua +++ b/test/pg.test.lua @@ -129,6 +129,41 @@ function test_pg_int64(t, p) p:put(conn) end +function test_pg_decimal(t, p) + t:plan(8) + + -- Setup + conn = p:get() + t:isnt(conn, nil, 'connection is established') + local num = 4500 + conn:execute('CREATE TABLE dectest (num NUMERIC(7,2))') + conn:execute(('INSERT INTO dectest VALUES(%d)'):format(num)) + + local res, r, _ + -- dec_cast is 'n' + t:is(conn.dec_cast, 'n', 'decimal casting type is "n" by default') + r, _ = conn:execute('SELECT num FROM dectest') + res = r[1][1]['num'] + t:is(type(res), 'number', 'type is "number"') + t:is(res, num, 'decimal number is correct') + -- dec_cast is 's' + conn.dec_cast = 's' + r, _ = conn:execute('SELECT num FROM dectest') + res = r[1][1]['num'] + t:is(type(res), 'string', 'type is "string"') + t:is(res, '4500.00', 'decimal number is correct') + -- dec_cast is 'd' + conn.dec_cast = 'd' + r, _ = conn:execute('SELECT num FROM dectest') + res = r[1][1]['num'] + t:is(type(res), 'cdata', 'type is "decimal"') + t:is(res, num, 'decimal number is correct') + + -- Teardown + conn:execute('DROP TABLE dectest') + p:put(conn) +end + tap.test('connection old api', test_old_api, conn) local pool_conn = p:get() tap.test('connection old api via pool', test_old_api, pool_conn) @@ -136,4 +171,5 @@ p:put(pool_conn) tap.test('test collection connections', test_gc, p) tap.test('connection concurrent', test_conn_concurrent, p) tap.test('int64', test_pg_int64, p) +tap.test('decimal', test_pg_decimal, p) p:close() From b6212637641281d7b43474585051da072464cf0c Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Mon, 18 Jul 2022 17:24:52 +0300 Subject: [PATCH 6/6] Fix fallthrough compiler warnings 1. https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wimplicit-fallthrough --- pg/driver.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pg/driver.c b/pg/driver.c index 6ce6c5d..1fba631 100644 --- a/pg/driver.c +++ b/pg/driver.c @@ -280,8 +280,11 @@ pg_resultget(struct lua_State *L, PGconn *conn, int *res_no, int status_ok, dec_ lua_pushlightuserdata(L, pg_res); lua_pushlightuserdata(L, dopt); fail = lua_pcall(L, 2, 1, 0); - if (!fail) + if (!fail) { lua_settable(L, -3); + break; + } + break; case PGRES_COMMAND_OK: res = 1; break;