Skip to main content

PgSanity

PgSanity checks the syntax of Postgresql SQL files.

It does this by leveraging the ecpg command which is traditionally used for preparing C files with embedded SQL for compilation. However, as part of that preparation, ecpg checks the embedded SQL statements for syntax errors using the exact same parser that is in PostgreSQL.

So the approach that PgSanity takes is to take a file that has a list of bare SQL in it, make that file look like a C file with embedded SQL, run it through ecpg and let ecpg report on the syntax errors of the SQL.

Installation

Dependencies

  • Python >= 3.9
    • May also work with older Pythons >= 3
  • ecpg
    • Ubuntu/Debian: sudo apt-get install libecpg-dev
    • RHEL/CentOS: sudo yum install postgresql-devel
    • Arch: sudo pacman -S postgresql-libs

Getting PgSanity

PgSanity is available in the Python Package Index, so you can install it with pip or uv. Here's PgSanity's page on PyPI.

  • pip install pgsanity or uv pip install pgsanity
    • If you don't have pip you can get it on Ubuntu/Debian by running: sudo apt install python3-pip

It is also available in the FreeBSD ports as databases/pgsanity. You can install it with one of those commands:

  • pkg install py36-pgsanity
  • pkg install py27-pgsanity
  • cd /usr/ports/databases/pgsanity && make install clean

Usage

PgSanity accepts filenames as parameters and it will report SQL syntax errors which exist in those files. PgSanity will exit with a status code of 0 if the syntax of the SQL looks good and a 1 if any errors were found.

$ pgsanity file_with_sql.sql
$ echo $?
0
$ pgsanity good1.sql good2.sql bad.sql
bad.sql: line 1: ERROR: syntax error at or near "bogus_token"
$ echo $?
1

Since pgsanity can handle multiple filenames as parameters it is very comfortable to use with find & xargs.

$ find -name '*.sql' | xargs pgsanity
./sql/bad1.sql: line 59: ERROR: syntax error at or near ";"
./sql/bad2.sql: line 41: ERROR: syntax error at or near "insert"
./sql/bad3.sql: line 57: ERROR: syntax error at or near "update"

Additionally PgSanity will read SQL from stdin if it is not given any parameters. This way it can be used interactively or by piping SQL through it.

$ pgsanity
select column1 alias2 asdf from table3
line 1: ERROR: syntax error at or near "asdf"
$ echo $?
1
$ echo "select mycol from mytable;" | pgsanity
$ echo $?
0

Interpreting The Results

The error messages pretty much come directly from ecpg. Something I have noticed while using pgsanity is that an error message on line X is probably more indicative of the statement right above X. For example:

$ echo "select a from b\ninsert into mytable values (1, 2, 3);" | pgsanity
line 2: ERROR: syntax error at or near "into"

The real problem in that SQL is that there is no semicolon after the 'b' in the select statement. However, the SQL can not be determined to be invalid until the word "into" is encountered in the insert statement. When in doubt, look up to the previous statement.

Another common error message that can be a little weird to interpret is illustrated here:

echo "select a from b" | pgsanity 
line 2: ERROR: syntax error at or near ""

The 'at or near ""' bit is trying to say that we got to the end of the file and no semicolon was found.

pre-commit

This repository is a pre-commit hook.

Usage:

  - repo: https://github.com/markdrago/pgsanity
    rev: v0.3.0
    hooks:
      - id: pgsanity_lint

Reporting Problems

If you encounter any problems with PgSanity, especially any issues where it incorrectly states that invalid SQL is valid or vice versa, please report the issue on PgSanity's github page. Thanks!

Release files for pgsanity 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pgsanity 0.3.0
File Size Uploaded
pgsanity-0.3.0.tar.gz 5.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pgsanity 0.3.0
File Interpreter ABI Platform
pgsanity-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 12.9 kB

Release files / pgsanity-0.3.0.tar.gz

Download URL pgsanity-0.3.0.tar.gz
Size 5.7 kB
Tags Source
SHA-256 checksum
How to use checksums
3e8fc33d0a64e78c3581638bf5a02b37a23c76631beee458c6e44c23a3080ca5
BLAKE2b-256 checksum
How to use checksums
538f0ede629c7aeb587c284a7bb1375424af430bf4af4385036303456430f56c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.19

Release files / pgsanity-0.3.0-py3-none-any.whl

Download URL pgsanity-0.3.0-py3-none-any.whl
Size 7.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
660c60b5993ea7abf3602e25d0b6996277e5cc86964e1a929e5299c8f3bdf40c
BLAKE2b-256 checksum
How to use checksums
89ec50b351aaf396c83e6bc0a3e5548f9c45135aad222b3a31853fa374d8c82c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.19

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.9

1 release file

0.2.8

1 release file

0.2.7

1 release file

0.2.6

1 release file

0.2.5

1 release file

0.2.4

1 release file

0.2.3

1 release file

0.2.2

1 release file

0.2.1

1 release file

0.2

1 release file

0.1.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page