July 21, 2026 · 8 min read
Six Postgres 19 Features Your Coding Agent Does Not Know About
We used GitHits to explore the Postgres 19 release and surface what changed. Six features came back. A coding agent without GitHits could not reach any of them.
This post did not start with a list of features. It started with a question: ask a coding agent what is new in a database release, and does it actually know?
Postgres 19 reached beta on June 4. We connected GitHits to a coding agent and asked it to work through the release from source, then report on what was new and what it changed for anyone writing queries. The six features below are what came back. We had not picked them in advance.
Then we ran the second half of the test. For each feature we wrote the prompt a developer would plausibly type, and ran it through the same agent twice: once with GitHits enabled, once without. Same model, same prompt, fresh context, one prompt at a time so no answer could lean on another.
Without GitHits, the agent did not reach any of the six. Not partially, not with hedging. In every case it explained that the thing being asked for was not available in core Postgres, and offered the workaround that was correct before this release. Below is each prompt, both answers, and what actually shipped.
Two management hops up an org chart
Start with a graph traversal, the kind of query you would write against an org chart.
Prompt
I have an
employeestable with areports_toself-reference. Using only core Postgres, no extensions and no separate graph database, write a query using graph pattern-matching syntax that finds everyone exactly two management hops above ‘Alice’.
Without GitHits
Not possible in core PostgreSQL. PostgreSQL has recursive CTEs, but no core graph pattern-matching syntax. Use a recursive CTE instead.
With GitHits
CREATE PROPERTY GRAPH employee_graph
VERTEX TABLES (
employees KEY (id)
LABEL employee
PROPERTIES (id, name)
)
EDGE TABLES (
employees AS reports_to_edge
SOURCE KEY (id) REFERENCES employees (id)
DESTINATION KEY (reports_to) REFERENCES employees (id)
LABEL reports_to
);
SELECT manager_name
FROM GRAPH_TABLE (
employee_graph
MATCH (alice IS employee WHERE alice.name = 'Alice')
-[IS reports_to]->()
-[IS reports_to]->(manager IS employee)
COLUMNS (manager.name AS manager_name)
);
The answer without GitHits describes Postgres as it was a year ago, and a year ago it was correct. Postgres 19 adds SQL/PGQ, the SQL:2023 property graph standard, with CREATE PROPERTY GRAPH and GRAPH_TABLE. A recursive CTE still works, but it answers a different question than the one asked. The prompt asked for graph syntax, and that syntax now exists.
The last non-null value in a gappy series
Anyone working with sensor data or event streams has wanted this and hit the same wall.
Prompt
I have
sensor_readings(sensor_id, ts, reading)wherereadingis frequently NULL. For each row, return the most recent non-null reading at or before that row’s timestamp, partitioned by sensor, in one query with no self-joins or lateral workarounds.
Without GitHits
Not possible in core PostgreSQL with those constraints. PostgreSQL does not support
LAST_VALUE(reading) IGNORE NULLS. This needs a workaround such as a self-join, lateral lookup, recursive query, or custom aggregate.
With GitHits
SELECT
sensor_id,
ts,
reading,
last_value(reading) IGNORE NULLS OVER (
PARTITION BY sensor_id
ORDER BY ts
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS latest_non_null_reading
FROM sensor_readings;
For most of Postgres history, “no IGNORE NULLS” was simply true, and the lateral-join workaround is well documented, so the agent reaches for it. This is also a case where web search would not have helped much, since most of what is written on the subject still describes the old behavior. Postgres 19 added IGNORE NULLS and RESPECT NULLS to lead, lag, first_value, last_value, and nth_value. The single line the agent ruled out is the answer.
A random timestamp for test data
A small one, but the kind of thing you write often.
Prompt
Give me a Postgres expression that returns a random
timestamptzbetween two given timestamps, without hand-rolling interval math.
Without GitHits
Not possible with a built-in timestamp-range random function. PostgreSQL has
random(min, max)for numeric types, nottimestamptz. A randomtimestamptzrequires interval or epoch arithmetic.
With GitHits
SELECT random(
'2026-07-10 00:00:00+00'::timestamptz,
'2026-07-11 00:00:00+00'::timestamptz
);
Worth noting how much the agent gets right here. It knows random gained numeric bounds in an earlier release and recalls the old signature correctly. It does not know that 19 added date, timestamp, and timestamptz overloads, so it sends you back to epoch arithmetic you no longer need.
Sequences during a near-zero-downtime upgrade
A question a DBA actually loses sleep over, and one where a stale answer costs you at cutover.
Prompt
I’m setting up logical replication between two Postgres clusters for a near-zero-downtime major upgrade. After cutover, do I have to manually resync sequence values on the subscriber, or is there a setup that keeps sequences in sync automatically? Show the setup.
Without GitHits
In core PostgreSQL logical replication, sequence changes are not kept in sync automatically. Before allowing writes on the upgraded subscriber, resync sequences manually, for example with
setval('public.users_id_seq', (SELECT max(id) FROM public.users), true).
With GitHits
-- publisher
CREATE PUBLICATION upgrade_pub
FOR ALL TABLES, ALL SEQUENCES;
-- subscriber
CREATE SUBSCRIPTION upgrade_sub
CONNECTION 'host=publisher dbname=app user=repl password=...'
PUBLICATION upgrade_pub
WITH (copy_data = true);
-- resync before cutover
ALTER SUBSCRIPTION upgrade_sub REFRESH SEQUENCES;
For years, “logical replication does not carry sequences” was dependable enough to state as a rule, and the agent states it as one. Postgres 19 changed it. Publications can now include sequences with ALL SEQUENCES, and ALTER SUBSCRIPTION ... REFRESH SEQUENCES brings their values across. One detail worth keeping straight: this syncs at subscribe and refresh rather than continuously, which is the shape a cutover needs. Left alone, the agent would have you scripting setval for a problem the release already handles.
Turning on checksums without an outage
The last two are quick, because the shape is familiar by now.
Prompt
My running Postgres cluster has data checksums disabled. How do I enable them without taking the cluster offline or running
pg_checksumsin offline mode?
Without GitHits
You cannot enable data checksums online in core PostgreSQL.
pg_checksums --enablerequires the cluster to be shut down cleanly; there is no online core equivalent.
With GitHits
SELECT pg_enable_data_checksums();
-- optionally throttle the background rewrite
SELECT pg_enable_data_checksums(cost_delay => 10, cost_limit => 1000);
For thirteen years the correct answer was to shut the cluster down. Postgres 19 added pg_enable_data_checksums() and pg_disable_data_checksums(), which flip checksums on a live cluster while a background worker rewrites every page. The agent gave the answer that was true until this release.
URL-safe base64
Prompt
Encode a
byteato a URL-safe base64 string in Postgres, the variant using-and_instead of+and/, with a built-in and not a manualreplace().
Without GitHits
Not possible with a built-in base64url encoder. Core
encode()supportsbase64,hex, andescape, but not URL-safe base64 without post-processing.
With GitHits
SELECT encode('\xdeadbeef'::bytea, 'base64url');
Smaller surface, same result. encode and decode gained base64url and base32hex in 19. The agent listed the old formats as though that list were still complete.
What the six have in common
Two things are worth separating here.
The first is that the agent did not know about these features, which on its own is unremarkable. The second is more useful: it also could not tell that it did not know. Across all six prompts it answered quickly and in the same tone it uses when it is right, and it never flagged that the version might have moved. Each “not possible” meant “not possible in the Postgres I know about,” but nothing in the output marks that distinction. The answers that are wrong read the same as the answers that are right.
None of these features are obscure. All six are in the Postgres 19 release notes, and we traced each one back to the Postgres source before publishing. They are ordinary additions, and they are new.
That is also why GitHits closes the gap without touching the model. Same model, same weights in both runs. Everything the agent needed was public and retrievable, sitting in the source tree the whole time. What it lacked was any reason to go looking, because it did not perceive a gap. GitHits reads the source for the version in question and puts those facts in front of the model before it answers, which accounts for the entire difference between the two answers.
Postgres 19 is a convenient example because the release is recent enough that the misses are easy to check. The same thing happens more quietly with any library, framework, or API that has shipped a version the model does not know about, where the wrong answer arrives just as confidently and you have no release notes open to catch it. The six prompts here are reproducible. Enable GitHits and run them yourself.