Commands

# build the PostgreSQL extension (default)
make

# installation
make install

# cleanup object files and shared libararies generated by the build command:
make clean

# regresssion testing (with pg_regress)
make installcheck

Current Debugging approach

For C implementations, I am directly testing by creating a ‘testable’ makefile target. For PostgreSQL wrapper functions, I am testing them directly on the Database as of now.

This way, the log/print statements for C implementations and wrapper functions won’t get mixed up. After completely testing and making sure that the C implementations are correct, we can then test the wrapper functions using PostgreSQL debug functions. This way, since C implementations will already have been tested, we won’t need to add PostgreSQL debug function calls in there.

Testing the C implementations

make testable

This generates a binary named testable that can be used to test the C implementations. However, this does not include PostgreSQl wrapper implementation C files. For wrapper files, I am currently testing on the database itself for the sake of simplicity.

Debugging tips for the PostgreSQL wrapper functions

  • Make sure to restart the PostgreSQL service after making changes to the source code and building the extension.

  • Write log statements like the following:

ereport(LOG, (errmsg("DEBUG: raw DateADT value = %d", adDate)));
ereport(LOG, (errmsg("DEBUG: After j2date -> %d-%d-%d", year, month, day)));
  • Make sure that the following are set in your ‘postgresq.conf’ file:
  log_min_messages = LOG
  log_statement = 'all'
  • Check for logs in the PostgreSQl log file:
tail -f /path/to/postgresq/log/file
[/opt/homebrew/var/log/postgresql@18.log] (Apple Silicon Homebrew installation)

NOTES ON POSGRESQL FUNCTIONS

Log levels and their impact

  • ERROR: Aborts the current transaction and exits the function early. (useful for validation failures.)
  • FATAL: Terminates the current session/connection.
  • PANIC: Shuts down the entire database cluster.
  • WARNING / NOTICE / LOG: Prints a message but continues execution of the function.

ereport(ERROR, …)

Unlike exit(1), which kills the entire process, ereport(ERROR, ...) tells PostgreSQL to abort the current transaction, roll back any changes, and return a clean error message to the client.