A Postgres DestReceiver implementation that renders query results in a box format, inspired by DuckDB's box renderer. It is meant to be used under the single-user mode as it writes to stdout.
$ ./install/bin/postgres --single -D data postgres
PostgreSQL stand-alone backend 19devel
backend> SELECT * FROM buzz;
┌─────────────────────┬────────────┐
│ receive_func │ is_it_good │
├─────────────────────┼────────────┤
│ debugtup │ f │
├─────────────────────┼────────────┤
│ box_dr_receive_slot │ t │
├─────────────────────┼────────────┤
│ ??? │ NULL │
└─────────────────────┴────────────┘
Yeah, I know that single-user mode is primarily for debugging, such a tool does
not make too much sense. But right now, that's my main way of running Postgres.
I hack the source code, build it, run it with the --single
option to test my
patch, then keep hacking. Given this niche workflow, the default DestReceiver
is a big no-no for me.
-
Build the project, we need to know the location of Postgres include directory. It is intended to not invoke
pg_config
, in case you have multiple Postgres installed. The build procedure only works on macOS.$ PG_INCLUDE_DIR=<your Postgres include dir> cargo b -r # If you want to use pg_config $ PG_INCLUDE_DIR=$(pg_config --includedir) cargo b -r
Then you will get 2 archive files under
target/release
:$ find target/release -name '*.a' target/release/libstatic_inline_c_funcs.a target/release/libbox_dest_receiver.a
-
Let Postgres link them:
LIBS += box_dest_receiver/target/release/libbox_dest_receiver.a LIBS += box_dest_receiver/target/release/libstatic_inline_c_funcs.a
I believe there are better approaches to do this, but I currently don't know.
-
Use this DestReceiver in Postgres
src/backend/tcop/dest.c
#include "libpq/libpq.h" #include "libpq/pqformat.h" +#include "box_dest_receiver.h" + /* ---------------- * dummy DestReceiver functions @@ -130,7 +132,7 @@ CreateDestReceiver(CommandDest dest) return unconstify(DestReceiver *, &donothingDR); case DestDebug: - return unconstify(DestReceiver *, &debugtupDR); + return box_dr_create(dest); case DestSPI: return unconstify(DestReceiver *, &spi_printtupDR);