diff --git a/async_postgres/pg_client.nim b/async_postgres/pg_client.nim index 23218aa..f3104a9 100644 --- a/async_postgres/pg_client.nim +++ b/async_postgres/pg_client.nim @@ -381,7 +381,6 @@ template queryRecvLoop( cachedColOids: seq[int32], qr: var QueryResult, timeout: Duration = ZeroDuration, - reuseBuffer: bool = true, ) = var queryError: ref PgQueryError @@ -391,19 +390,8 @@ template queryRecvLoop( for i in 0 ..< qr.fields.len: qr.fields[i].formatCode = cachedColFmts[i] if qr.fields.len > 0: - if reuseBuffer: - if conn.rowDataBuf != nil: - conn.rowDataBuf = conn.rowDataBuf.reuseRowData( - int16(qr.fields.len), cachedColFmts, cachedColOids - ) - else: - conn.rowDataBuf = - newRowData(int16(qr.fields.len), cachedColFmts, cachedColOids) - conn.rowDataBuf.fields = qr.fields - qr.data = conn.rowDataBuf - else: - qr.data = newRowData(int16(qr.fields.len), cachedColFmts, cachedColOids) - qr.data.fields = qr.fields + qr.data = newRowData(int16(qr.fields.len), cachedColFmts, cachedColOids) + qr.data.fields = qr.fields block recvLoop: while true: @@ -433,17 +421,8 @@ template queryRecvLoop( cf[i] = resultFormats[i] else: qr.fields = msg.fields - if reuseBuffer: - if conn.rowDataBuf != nil: - conn.rowDataBuf = - conn.rowDataBuf.reuseRowData(int16(qr.fields.len), cf, co) - else: - conn.rowDataBuf = newRowData(int16(qr.fields.len), cf, co) - conn.rowDataBuf.fields = qr.fields - qr.data = conn.rowDataBuf - else: - qr.data = newRowData(int16(qr.fields.len), cf, co) - qr.data.fields = qr.fields + qr.data = newRowData(int16(qr.fields.len), cf, co) + qr.data.fields = qr.fields of bmkNoData: discard of bmkCommandComplete: @@ -530,18 +509,8 @@ proc queryImpl( var qr = QueryResult() queryRecvLoop( - conn, - sql, - effectiveResultFormats, - cacheHit, - cacheMiss, - stmtName, - cachedFields, - cachedColFmts, - cachedColOids, - qr, - timeout, - reuseBuffer = false, + conn, sql, effectiveResultFormats, cacheHit, cacheMiss, stmtName, cachedFields, + cachedColFmts, cachedColOids, qr, timeout, ) return qr @@ -601,18 +570,8 @@ proc queryImpl( var qr = QueryResult() queryRecvLoop( - conn, - sql, - effectiveResultFormats, - cacheHit, - cacheMiss, - stmtName, - cachedFields, - cachedColFmts, - cachedColOids, - qr, - timeout, - reuseBuffer = false, + conn, sql, effectiveResultFormats, cacheHit, cacheMiss, stmtName, cachedFields, + cachedColFmts, cachedColOids, qr, timeout, ) return qr diff --git a/async_postgres/pg_connection.nim b/async_postgres/pg_connection.nim index db75828..e1d4abc 100644 --- a/async_postgres/pg_connection.nim +++ b/async_postgres/pg_connection.nim @@ -167,7 +167,6 @@ type stmtCacheLru: DoublyLinkedList[string] ## LRU order: oldest at head, newest at tail stmtCounter*: int stmtCacheCapacity*: int ## 0=disabled, default 256 - rowDataBuf*: RowData ## Reusable RowData buffer to avoid per-query allocation hstoreOid*: int32 ## Dynamic OID for hstore extension type; 0 if not available tracer*: PgTracer ## Inherited from ConnConfig on connect @@ -1542,7 +1541,6 @@ proc reconnectInPlace(conn: PgConnection) {.async.} = conn.recvBuf.setLen(0) conn.recvBufStart = 0 conn.clearStmtCache() - conn.rowDataBuf = nil conn.state = csConnecting var newConn: PgConnection try: diff --git a/async_postgres/pg_pool.nim b/async_postgres/pg_pool.nim index 1f312c2..fc38f73 100644 --- a/async_postgres/pg_pool.nim +++ b/async_postgres/pg_pool.nim @@ -175,7 +175,6 @@ proc resetSession*(pool: PgPool, conn: PgConnection) {.async.} = try: discard await conn.simpleExec(pool.config.resetQuery) conn.clearStmtCache() - conn.rowDataBuf = nil except CatchableError: try: await conn.close() diff --git a/tests/test_e2e.nim b/tests/test_e2e.nim index d8397b6..91e1990 100644 --- a/tests/test_e2e.nim +++ b/tests/test_e2e.nim @@ -6039,6 +6039,21 @@ suite "E2E: queryDirect / execDirect": waitFor t() + test "queryDirect Row survives subsequent queries (lifetime bug)": + proc t() {.async.} = + let conn = await connect(plainConfig()) + let qr1 = await conn.queryDirect("SELECT $1::text", "x") + let qr2 = await conn.queryDirect("SELECT $1::text", "y") + doAssert qr1.rowCount == 1 + doAssert qr2.rowCount == 1 + let row1 = Row(data: qr1.data, rowIdx: 0) + let row2 = Row(data: qr2.data, rowIdx: 0) + doAssert row1.getStr(0) == "x", "qr1 data was invalidated by qr2" + doAssert row2.getStr(0) == "y" + await conn.close() + + waitFor t() + test "execDirect INSERT and UPDATE": proc t() {.async.} = let conn = await connect(plainConfig())