pg: Add query tracing & prepare/execute time measurements

What I'd really like, in addition to this, is a way to extract a query
from an $st object that can be run in the psql CLI. VNDB has a debugging
feature for that, but it's less trivial to make that work with binary
query parameters.
This commit is contained in:
Yorhel 2025-02-22 15:14:51 +01:00
parent a5f9584b02
commit b2d676b1ed
6 changed files with 269 additions and 54 deletions

59
FU.xs
View file

@ -1,5 +1,6 @@
#include <stdio.h>
#include <errno.h>
#include <time.h> /* struct timespec & clock_gettime() */
#include <string.h> /* strerror() */
#include <arpa/inet.h> /* inet_ntop(), inet_ntoa() */
#include <sys/socket.h> /* fd passing */
@ -174,6 +175,12 @@ void _debug_trace(fupg_conn *c, bool on)
else PQuntrace(c->conn);
ST(0) = c->self;
void query_trace(fupg_conn *c, SV *cb)
CODE:
if (c->trace) SvREFCNT_dec(c->trace);
SvGETMAGIC(cb);
c->trace = SvOK(cb) ? SvREFCNT_inc(cb) : NULL;
void status(fupg_conn *c)
CODE:
ST(0) = sv_2mortal(newSVpv(fupg_conn_status(c), 0));
@ -273,16 +280,6 @@ void cache(fupg_st *x, ...)
if (ix == 0 && x->prepared) fu_confess("Invalid attempt to change statement configuration after it has already been prepared or executed");
FUPG_STFLAGS;
void param_types(fupg_st *st)
CODE:
FUPG_ST_COOKIE;
ST(0) = fupg_st_param_types(aTHX_ st);
void columns(fupg_st *st)
CODE:
FUPG_ST_COOKIE;
ST(0) = fupg_st_columns(aTHX_ st);
void exec(fupg_st *st)
CODE:
FUPG_ST_COOKIE;
@ -338,6 +335,48 @@ void kvh(fupg_st *st)
FUPG_ST_COOKIE;
ST(0) = fupg_st_kvh(aTHX_ st);
void param_types(fupg_st *st)
CODE:
FUPG_ST_COOKIE;
ST(0) = fupg_st_param_types(aTHX_ st);
void param_values(fupg_st *st);
CODE:
ST(0) = fupg_st_param_values(aTHX_ st);
void columns(fupg_st *st)
CODE:
FUPG_ST_COOKIE;
ST(0) = fupg_st_columns(aTHX_ st);
void nrows(fupg_st *st)
CODE:
ST(0) = st->result ? fupg_exec_result(aTHX_ st->result) : &PL_sv_undef;
void query(fupg_st *st)
CODE:
ST(0) = newSVpvn_utf8(st->query, strlen(st->query), 1);
void exec_time(fupg_st *st)
CODE:
ST(0) = st->exectime <= 0 ? &PL_sv_undef : sv_2mortal(newSVnv(st->exectime));
void prepare_time(fupg_st *st)
CODE:
ST(0) = !st->prepared ? &PL_sv_undef : sv_2mortal(newSVnv(st->preptime));
void get_cache(fupg_st *st)
CODE:
ST(0) = st->stflags & FUPG_CACHE ? &PL_sv_yes : &PL_sv_no;
void get_text_params(fupg_st *st)
CODE:
ST(0) = st->stflags & FUPG_TEXT_PARAMS ? &PL_sv_yes : &PL_sv_no;
void get_text_results(fupg_st *st)
CODE:
ST(0) = st->stflags & FUPG_TEXT_RESULTS ? &PL_sv_yes : &PL_sv_no;
void DESTROY(fupg_st *st)
CODE:
fupg_st_destroy(aTHX_ st);