Skip to content

Commit 6141671

Browse files
committed
1 parent 9ed3291 commit 6141671

File tree

4 files changed

+55
-14
lines changed

4 files changed

+55
-14
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ Connect to a database.
5454
- `db` - a database name
5555
- `conn_string` (mutual exclusive with host, port, user, pass, db) - PostgreSQL
5656
[connection string][PQconnstring]
57+
- `dec_cast` - an option that switches casting types for `NUMERIC` PostgreSQL
58+
type. Possible values: `n` (`number`), `s` (`string`), `d` (`decimal`).
5759

5860
*Returns*:
5961

pg/driver.c

+11-7
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ parse_pg_value(struct lua_State *L, dec_opt_t *dopt, PGresult *res, int row, int
128128
}
129129
break;
130130
}
131-
// else fallthrough
131+
/* 'n': fallthrough */
132132
}
133133
case INT2OID:
134134
case INT4OID: {
@@ -293,9 +293,11 @@ static void
293293
lua_parse_param(struct lua_State *L,
294294
int idx, const char **value, int *length, Oid *type)
295295
{
296-
static char buf[512]; // buffer for serialized [u]int64_t
297-
static char *pos;
298-
if (idx == 5) { // lua_parse_param(L, idx + 5, ...
296+
/* Serialized [u]int64_t */
297+
static char buf[512];
298+
static char *pos = NULL;
299+
/* lua_parse_param(L, idx + 5, ...) */
300+
if (idx == 5) {
299301
*buf = '\0';
300302
pos = buf;
301303
}
@@ -362,9 +364,11 @@ lua_pg_execute(struct lua_State *L)
362364

363365
dec_opt_t dopt = {'n', -1};
364366
if (lua_isstring(L, 2)) {
365-
const char *tmp = lua_tostring(L, 2);
366-
if (*tmp == 'n' || *tmp == 's' || *tmp == 'd')
367-
dopt.cast = *tmp;
367+
const char *dec_cast_type = lua_tostring(L, 2);
368+
if (*dec_cast_type == 'n' ||
369+
*dec_cast_type == 's' ||
370+
*dec_cast_type == 'd')
371+
dopt.cast = *dec_cast_type;
368372
}
369373

370374
if (!lua_isstring(L, 4)) {

pg/init.lua

+7-7
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@ local fiber = require('fiber')
44
local driver = require('pg.driver')
55
local ffi = require('ffi')
66

7-
local dnew
8-
do
9-
local ok, dec = pcall(require, "decimal")
10-
if ok then
11-
dnew = dec.new
12-
end
7+
local has_decimal, dec = pcall(require, 'decimal')
8+
if has_decimal then
9+
dnew = dec.new
1310
end
1411

1512
local pool_mt
@@ -23,7 +20,10 @@ local function conn_create(pg_conn)
2320
usable = true,
2421
conn = pg_conn,
2522
queue = queue,
26-
dec_cast = 'n' -- 'n' - number, 's' - string, 'd' - decimal
23+
dec_cast = 'n' -- Defined in pg/driver.c:
24+
-- 'n' - number,
25+
-- 's' - string,
26+
-- 'd' - decimal.
2727
}, conn_mt)
2828

2929
return conn

test/pg.test.lua

+35
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,46 @@ function test_pg_int64(t, p)
129129
p:put(conn)
130130
end
131131

132+
function test_pg_decimal(t, p)
133+
t:plan(8)
134+
135+
-- Setup
136+
conn = p:get()
137+
t:isnt(conn, nil, 'connection is established')
138+
local num = 4500
139+
conn:execute('CREATE TABLE dectest (num NUMERIC(7,2))')
140+
conn:execute(('INSERT INTO dectest VALUES(%d)'):format(num))
141+
142+
-- dec_cast is 'n'
143+
t:is(conn.dec_cast, 'n', 'decimal casting type is "n" by default')
144+
local r, m = conn:execute('SELECT num FROM dectest')
145+
local res = r[1][1]['num']
146+
t:is(type(res), 'number', 'type is "number"')
147+
t:is(res, num, 'decimal number is correct')
148+
-- dec_cast is 's'
149+
conn.dec_cast = 's'
150+
local r, m = conn:execute('SELECT num FROM dectest')
151+
local res = r[1][1]['num']
152+
t:is(type(res), 'string', 'type is "string"')
153+
t:is(res, '4500.00', 'decimal number is correct')
154+
-- dec_cast is 'd'
155+
conn.dec_cast = 'd'
156+
local r, m = conn:execute('SELECT num FROM dectest')
157+
local res = r[1][1]['num']
158+
t:is(type(res), 'cdata', 'type is "decimal"')
159+
t:is(res, num, 'decimal number is correct')
160+
161+
-- Teardown
162+
conn:execute('DROP TABLE dectest')
163+
p:put(conn)
164+
end
165+
132166
tap.test('connection old api', test_old_api, conn)
133167
local pool_conn = p:get()
134168
tap.test('connection old api via pool', test_old_api, pool_conn)
135169
p:put(pool_conn)
136170
tap.test('test collection connections', test_gc, p)
137171
tap.test('connection concurrent', test_conn_concurrent, p)
138172
tap.test('int64', test_pg_int64, p)
173+
tap.test('decimal', test_pg_decimal, p)
139174
p:close()

0 commit comments

Comments
 (0)