HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
pganalyze
libpg_query
C2017–2026
pganalyze / libpg_query

libpg_query

C library for accessing the PostgreSQL parser outside of the server environment

17Distinct people
24Mentions
0Explicit recommenders
1.5KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

C library for accessing the PostgreSQL parser outside of the server environment

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year24 dated mentions

Observed mentions: 2017-07-24 01:12:45 UTC to 2026-09-18 15:13:18 UTC.

0369122017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20172018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments20212022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 11 mentions; 0 submissions, 11 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC101
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC101
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC110
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC101
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC000
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC101
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC11011
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC202
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC404
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC211

What Hacker News says

24 sources
levkk·Sep 18, 2026Submission

Show HN: pg_raw_parse - parse PgSQL in Rust

Hey HN! We built a wrapper on top of the Postgres native SQL parser to allow us to parse and manipulate SQL in Rust. Our library forks libpg_query [1] and its original Rust bindings, pg_query.rs [2]. By not using Protobuf and mapping our structs directly on top of the Postgres arena allocator, we are able to achieve a pretty massive speedup: - 20-60x parse/deparse, depending on query size - 90% memory utilization decrease vs pg_query.rs This library is used in production in PgDog [3], but has no dependencies to it, so you can use it in your Rust apps without issues. It also provides access to Postgres internals used to walk and transform query ASTs. Those are actually really cool. Check out the README for details, but we basically use a bunch of Rust macros to generate 100% compatible Rust structs directly from C headers. This makes it re
Read the rest
ally easy to upgrade major versions, i.e., we just bump the submodules and re-compile. Let us know what you think! - PgDog team [1]: https://github.com/pganalyze/libpg_query [2]: https://github.com/pganalyze/pg_query.rs [3]: https://github.com/pgdogdev/pgdog
4 points · Open discussion
Since there seems to be some confusion in the comments about why pg_query chose Protobufs in the first place, let me add some context as the original author of pg_query (but not involved with PgDog, though Lev has shared this work by email beforehand). The initial motivation for developing pg_query was for pganalyze, where we use it to parse queries extracted from Postgres, to find the referenced tables, and these days also rewrite and format queries. That use case runs in the background, and as such is much less performance critical. pg_query actually initially used a JSON format for the parse output (AST), but we changed that to Protobuf a few major releases ago, because Protobuf makes it easy to have typed bindings in the different languages we support (Ruby, Go, Rust, Python, etc). Alternatives (e.g. using FFI directly) make sense for
Read the rest
Rust, but would require a lot of maintained glue code for other languages. All that said, I'm supportive of Lev's effort here, and we'll add some additional functions (see [0]) in the libpg_query library to make using it directly (i.e. via FFI) easier. But I don't see Protobuf going away, because in non-performance critical cases, it is more ergonomic across the different bindings. [0]: https://github.com/pganalyze/libpg_query/pull/321
In Replacing Protobuf with Rust
Yeah, as one of the main authors of libpg_query, I think the primary things that make this easier is that Postgres has good abstractions internally, and the parser works independently from other parts (e.g. the community discourages adding settings that affect parser behavior). Over the years we've only had to maintain a small set of patches on top of the Postgres source [0], together with some mocks and our libclang-based extraction logic [1]. Of course it would be nice if Postgres just packaged this directly like it packages the client libraries, but there is non-trivial effort involved to do that. From what I recall, the main issue is that error handling and memory allocations work differently in the client-side libraries (and so that would have to either also be moved out of the backend source, or use some other abstraction). [0]: htt
Read the rest
In Hacking the Postgres wire protocol
Yes, the same way. It's all based on the extremely useful `https://github.com/pganalyze/libpg_query` project, which is where the "extracted the parser from Postgres" part comes in. Supabase's LSP also uses tree-sitter for corrections and autocomplete, because one drawback of using the server's source is that pg_query only works on well-formed/executable SQL - when it detects a malformed query, it formulates an error and exits, since that's what you want in an SQL server. So for partially-correct syntax and fill-forward, tree-sitter covers the gaps.
In Hacking the Postgres wire protocol
Tends to be a matter of opinion. Postgres does not expose the relevant functions, so https://github.com/pganalyze/libpg_query has to do some heavy lifting to convert their source code into a nice library. Conversely, Postgres is very well written code, in an extremely common language, with a stable release cadence, and such a long track record it is seen as the reference implementation for correctly parsing SQL.
In Hacking the Postgres wire protocol
libpg_query is a good library! "C library for accessing the PostgreSQL parser outside of the server environment" https://github.com/pganalyze/libpg_query?tab=readme-ov-file#... pg_query wrappers in other languages: - Ruby: pg_query - Go: pg_query_go - Javascript (Node): pgsql-parser - Javascript (Browser): pg-query-emscripten - Python: psqlparse, pglast, psqlparse2 - OCaml: pg_query-ocaml - Rust: pg_query.rs
In Show HN: Parse your Postgres queries into a fully-typed AST in TypeScript
We're going through the same search right now. I haven't found anything that would suit our ideal use-case (which would be a kind of "collaboratively-editable web Jupyter-notebook server for psql DDL maintenance sessions" — but without the edit-and-replay-in-the-same-cell part, because it should also be its own audit log; and with an "each psql session runs indefinitely and streams output back to the output cell" property that Jupyter doesn't have. Or basically, "something that is to a shared tmux session as Slack is to IRC.") I'm half motivated to just build this myself, since everything about it is a constant need. Less ideal, but still nice, would be a proxy that creates an SQL statement audit log for all statements executed through it (where you'd then make it so that your devs can only connect through it.) I believe the pgpool proxy
Read the rest
can do this — see https://www.pgpool.net/docs/latest/en/html/runtime-config-lo.... > Company policy puts all kinds of restrictions on desktop connections to DBs Presuming these restrictions exist in your company only to ensure that developers' more casually-guarded security credentials aren't exfiltrated from their machines by a virus or a phishing attack and used to attach to your servers from some external IP: consider putting your developer workstations and your DB servers together onto an enterprise-managed Tailscale overlay-network, and then putting a line in pg_hba.conf such that DB users in the "developers" DB group can only connect from the overlay-network's IP range. (AFAIK it's very hard to exfiltrate a logged-in Tailscale session and reuse it elsewhere.) However, presuming you care more about this: > The objective is mostly logging DDL actions and limiting certain DDL operations. One "hack" approach that will get you just these two properties, but otherwise keep things to what you're already doing, is a pretty old-school one: command-line-specific /etc/sudoers lines. Specifically, you would: 1. Make a DB user called ddl_maintenance; make this DB user, and only this DB user, a pseudo-superuser capable of executing DDL statements. Your developer DB users should not have this privilege. 2. On the jump box, create a ddl_maintenance OS user, with /sbin/nologin as their login shell. 3. Also give the ddl_maintenance user a ~/.pgpass file, containing their DB credentials (so that psql can connect automatically when run as this user). chmod it 400, so that other users won't learn these credentials. 4. Write a policy-enforcer program, that parses a .sql file, and exits 0 if every statement in that file is safe to run per your company policy — or with some other exit code if it's not. (Use https://github.com/pganalyze/libpg_query, or one of its HLL bindings. I'd probably recommend the Golang one for simplest deployment.) 5. Write a glue script that receives a path to a .sql file as $1 (and/or a stream of SQL on stdin); buffers it to a spool dir, so that it can be streamed more than once; tests it for conformance with your policy-checker program from #4; and if it passes, executes it with psql. (Don't pass on arbitrary flags to psql — you want to force your devs to use psql a specific, auditable way.) You want something that looks like this: if ddl-looks-good "${sql_in_spool}"; then psql -a -f "${sql_in_spool}" | tee -a "/var/log/ddl_maintenance.log" fi 6. Add a line to /etc/sudoers, that allows users to sudo as ddl_maintenance without a password, but only to execute this glue script using sudo -c. 7. (optional) wrap the required sudo incantation in a friendly wrapper script, so the devs don't have to learn Weird Sudo Tricks to get their job done. Document this final wrapper script; treat everything else as implementation details. --- All that being said, if you have a whitelist of DDL commands you want your devs to run... just make some SECURITY DEFINER stored procedures that do those things (and which audit-log into one or more tables or THROW NOTICEs into the PG log), and grant your DB "developers" group EXECUTE privilege on those sprocs. Problem solved :)
In Show HN: I've built a MySQL proxy that supports online DDL
hey, author here. Thanks for posting it! A bit of background: a few months ago we announced a Postgres language server[0]. A language server adds features like syntax error diagnostic and autocomplete to your editor (vscode, neovim, etc). We have iterated a lot on the parser over the past few months and want to share an update today. the parser is a core piece of any language server that constructs syntax trees from the raw input string. Usually first an untyped concrete syntax tree (cst) that represents the syntactic structure of the input, and subsequently a typed abstract syntax tree (ast) containing the meaning of the source. In our implementation, we leverage the actual Postgres parser to-do the heavy lifting. However, the parser is designed to parse executable SQL — not to provide language intelligence. For example, it does not hand
Read the rest
le incomplete inputs, and outputs just the ast, not the cst. To use it for a language server we had to work around these limitations as good as possible. While we leverage procedural macros in rust to generate a lot of the repetitive parser code, there remains a portion that requires a bit of manual work. But the groundwork is completed, and we can finally start working on the data model and the actual server next. Our aim is to bring this to a usable state as swiftly as possible. Huge shout-out to pg_analyze for creating and maintaining libpg_query[1], without which this project would not be possible! [0] https://news.ycombinator.com/item?id=37020610 [1] https://github.com/pganalyze/libpg_query
In Postgres Language Server: Implementing the Parser
Author here - what we call "pg_plan" internally, is essentially very similar in spirit to what we do with pg_query [0], but the difference is that we pull in a lot more code from Postgres, and have more overrides in places that are not needed for the use case (e.g. MVCC handling, etc). My gut feeling tells me that the chances of having an upstream library that contains the parser/parse analysis/planner are slim. Mainly from there being a lot of entanglement with reading files on disk, memory management, etc - I suspect one of the pushbacks would be it would complicate development work for Postgres itself, to the point its not worth the benefits. For the pg_query library on the other hand I have hopes that we can upstream this eventually - there are enough third-party users out there to clearly show the need, and its much more contained (i
Read the rest
.e. raw parser + AST structs). Hopefully something we can spend a bit of time on next year. [0]: https://github.com/pganalyze/libpg_query
In An automatic indexing system for Postgres
Couple of points in this post, so will address a few of them: "(Paraphrased) C is bad, and it takes forever to pick up the PG-specific C idioms" There's probably not a productive conversation to be had about C as a language. I will say that as of C23, the language is not quite as barebones as it used to be and incorporates a lot of modern improvements. On the topic of PG-specific C -- there are a handful of replacements for common operations that you use in PG. Things like "palloc/pfree", and the built-in macros for error and warning logging, etc. I genuinely don't think it would take a motivated party more than a day or two to pick all of these up -- there aren't that many of them and they tend to map to things you're already used to. "I wanted to reuse builtin pg code to parse the printed statements from logs - I ended up writing a
Read the rest
parser (in a non-C language) myself which was faster." It's true that the core PG code isn't written in a modular way that's friendly to integration piecemeal in other projects (outside of libpq). For THIS PARTICULAR case, the pganalyze team has actually extracted out the parser of PG for including in your own projects: https://github.com/pganalyze/libpg_query
In Postgres: The next generation
#. SQLite WAL mode From https://www.sqlite.org/isolation.html https://news.ycombinator.com/item?id=32247085 : > [sqlite] WAL mode permits simultaneous readers and writers. It can do this because changes do not overwrite the original database file, but rather go into the separate write-ahead log file. That means that readers can continue to read the old, original, unaltered content from the original database file at the same time that the writer is appending to the write-ahead log #. superfly/litefs: a FUSE-based file system for replicating SQLite https://github.com/superfly/litefs #. sqldiff: https://www.sqlite.org/sqldiff.html https://news.ycombinator.com/item?id=31265005 #. dolthub/dolt: https://github.com/dolthub/dolt : > Dolt is a SQL database that you can fork, clone, branch, merge, push and pull just like a Git repository. [...] > D
Read the rest
olt can be set up as a replica of your existing MySQL or MariaDB database using standard MySQL binlog replication. Every write becomes a Dolt commit. This is a great way to get the version control benefits of Dolt and keep an existing MySQL or MariaDB database. #. github/gh-ost: https://github.com/github/gh-ost : > Instead, gh-ost uses the binary log stream to capture table changes, and asynchronously applies them onto the ghost table. gh-ost takes upon itself some tasks that other tools leave for the database to perform. As result, gh-ost has greater control over the migration process; can truly suspend it; can truly decouple the migration's write load from the master's workload. #. vlcn-io/cr-sqlite: https://github.com/vlcn-io/cr-sqlite : > Convergent, Replicated SQLite. Multi-writer and CRDT support for SQLite > CR-SQLite is a run-time loadable extension for SQLite and libSQL. It allows merging different SQLite databases together that have taken independent writes. > In other words, you can write to your SQLite database while offline. I can write to mine while offline. We can then both come online and merge our databases together, without conflict. > In technical terms: cr-sqlite adds multi-master replication and partition tolerance to SQLite via conflict free replicated data types (CRDTs) and/or causally ordered event logs. yjs also does CRDTs (Jupyter RTC,) #. pganalyze/libpg_query: https://github.com/pganalyze/libpg_query : > C library for accessing the PostgreSQL parser outside of the server environment #. Ibis + Substrait [ + DuckDB ] https://ibis-project.org/blog/ibis_substrait_to_duckdb/ : > ibis strives to provide a consistent interface for interacting with a multitude of different analytical execution engines, most of which (but not all) speak some dialect of SQL. > Today, Ibis accomplishes this with a lot of help from `sqlalchemy` and `sqlglot` to handle differences in dialect, or we interact directly with available Python bindings (for instance with the pandas, datafusion, and polars backends). > [...] `Substrait` is a new cross-language serialization format for communicating (among other things) query plans. It's still in its early days, but there is already nascent support for Substrait in Apache Arrow, DuckDB, and Velox. #. ibis-project/ibis-substrait: https://github.com/ibis-project/ibis-substrait #. tobymao/sqlglot: https://github.com/tobymao/sqlglot : > SQLGlot is a no-dependency SQL parser, transpiler, optimizer, and engine. It can be used to format SQL or translate between 19 different dialects like DuckDB, Presto, Spark, Snowflake, and BigQuery. It aims to read a wide variety of SQL inputs and output syntactically and semantically correct SQL in the targeted dialects. > It is a very comprehensive generic SQL parser with a robust test suite. It is also quite performant, while being written purely in Python. > You can easily customize the parser, analyze queries, traverse expression trees, and programmatically build SQL. > Syntax errors are highlighted and dialect incompatibilities can warn or raise depending on configurations. However, it should be noted that SQL validation is not SQLGlot’s goal, so some syntax errors may go unnoticed. #. benbjohnson/postlite: https://github.com/benbjohnson/postlite : > postlite is a network proxy to allow access to remote SQLite databases over the Postgres wire protocol. This allows GUI tools to be used on remote SQLite databases which can make administration easier. > The proxy works by translating Postgres frontend wire messages into SQLite transactions and converting results back into Postgres response wire messages. Many Postgres clients also inspect the pg_catalog to determine system information so Postlite mirrors this catalog by using an attached in-memory database with virtual tables. The proxy also performs minor rewriting on these system queries to convert them to usable SQLite syntax. > Note: This software is in alpha. Please report bugs. Postlite doesn't alter your database unless you issue INSERT, UPDATE, DELETE commands so it's probably safe. If anything, the Postlite process may die but it shouldn't affect your database. #. > "Hosting SQLite Databases on GitHub Pages" (2021) re: sql.js-httpvfs, DuckDB https://news.ycombinator.com/item?id=28021766 #. >> - bittorrent/sqltorrent https://github.com/bittorrent/sqltorrent >> Sqltorrent is a custom VFS for sqlite which allows applications to query an sqlite database contained within a torrent. Queries can be processed immediately after the database has been opened, even though the database file is still being downloaded. Pieces of the file which are required to complete a query are prioritized so that queries complete reasonably quickly even if only a small fraction of the whole database has been downloaded. #. simonw/datasette-lite: https://github.com/simonw/datasette-lite datasette, *-to-sqlite, dogsheep "Loading SQLite databases" [w/ datasette] https://github.com/simonw/datasette-lite#loading-sqlite-data... #. awesome-db-tools: https://github.com/mgramin/awesome-db-tools Lots of neat SQLite/vtable/pg/replication things
In SQLedge: Replicate Postgres to SQLite on the Edge
Generally I agree that this would be great to have, and Postgres does have a set of libraries it already maintains as part of the main source tree (i.e. libpq, etc), and there is a shared set of code between the backend and the "frontend" (https://github.com/postgres/postgres/tree/master/src/common). So theoretically you could imagine the parser moving into that shared code portion, sharing code but not necessarily requiring linking to a library from the backend. However, the challenge from what I've understood from past conversations with some folks working on Postgres core is that the parser is currently heavily tied into the backend - note the parser isn't just the scan.l/gram.y file, but also the raw parse node structs that it outputs. You can see how many files we pull in from the main tree that are prefixed with "src_backend": https
Read the rest
://github.com/pganalyze/libpg_query/tree/15-latest/src/... Further, there isn't a canonical way to output node trees into a text format today in core, besides the rather hard to work with output of debug_print_parse - there have been discussions on -hackers to potentially utilize JSON here, which may make this a bit easier. Note that in libpg_query we currently use Protobuf (but used to use JSON), which does have the benefit of getting auto-generated structs in the language bindings - but Protobuf is not used in core Postgres at all today. All in all, I think there is some upstream interest, but its not clear that this is a good idea from a maintainability perspective.
In Postgres Language Server
Excited to see this - and excellent use case for libpg_query (I'm the original author and still help maintain it together with the rest of the team) and appreciate the shout out to pganalyze! If anyone else has a use case for using the Postgres parser outside the server, we have a healthy ecosystem of libraries that build on the core C library (we maintain bindings for Ruby, Go and Rust ourselves), as well as various projects using it (e.g. sqlc uses it for a type-safe way for using hand-written SQL in Go): https://github.com/pganalyze/libpg_query#resources
In Postgres Language Server

Showing the 15 most recent of 24 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.