Version: nette/database v3.2.8
Bug Description
Nette\Database\Drivers\PgSqlDriver::getColumns() fails during PostgreSQL table structure introspection on PostgreSQL 18.
The problem happens when using Nette\Database\Explorer, for example:
$explorer->table('users')->fetch();
The query itself is not the issue. The exception is thrown before the actual table query is executed, while Nette Database is loading table metadata via Structure / DiscoveredConventions.
The error is:
Nette\Database\DriverException #XX000
SQLSTATE[XX000]: Internal error: 7 ERROR: invalid attnum 10 for relation "pg_attrdef"
The stack trace points to:
Nette\Database\Drivers\PgSqlDriver.php
Nette\Database\Structure.php
Nette\Database\Conventions\DiscoveredConventions.php
Nette\Database\Explorer.php
The issue seems to be caused by this expression in PgSqlDriver::getColumns():
pg_catalog.pg_get_expr(ad.adbin, 'pg_catalog.pg_attrdef'::regclass)::varchar AS default
and also here:
substring(pg_catalog.pg_get_expr(ad.adbin, 'pg_catalog.pg_attrdef'::regclass) from 'nextval[(]''"?([^''"]+)')
With PostgreSQL 18 this fails with invalid attnum ... for relation "pg_attrdef".
Steps To Reproduce
- Use PostgreSQL 18
- Use
nette/database v3.2.8.
- Create a table with default values, for example a typical users table with UUID / timestamp defaults.
- Use
Nette\Database\Explorer and call: $explorer->table('users')->fetch();
- Nette Database tries to introspect table columns and fails with:
SQLSTATE[XX000]: Internal error: 7 ERROR: invalid attnum 10 for relation "pg_attrdef"
In my case this happened in an authentication provider on this line:
$this->databaseExplorer->table('users')->order('created_at ASC')->fetch();
PostgreSQL itself was running correctly. Direct SQL queries against the users table worked. The failure only happened through Nette Database Explorer metadata introspection.
Expected Behavior
Nette\Database\Explorer should be able to introspect PostgreSQL 18 tables without throwing an internal PostgreSQL error.
Possible Solution
In src/Database/Drivers/PgSqlDriver.php, getColumns() should probably use ad.adrelid as the second argument of pg_get_expr() instead of 'pg_catalog.pg_attrdef'::regclass.
This local patch fixed the problem:
- pg_catalog.pg_get_expr(ad.adbin, 'pg_catalog.pg_attrdef'::regclass)::varchar AS default,
+ pg_catalog.pg_get_expr(ad.adbin, ad.adrelid)::varchar AS default,
- substring(pg_catalog.pg_get_expr(ad.adbin, 'pg_catalog.pg_attrdef'::regclass) from 'nextval[(]''"?([^''"]+)')
+ substring(pg_catalog.pg_get_expr(ad.adbin, ad.adrelid) from 'nextval[(]''"?([^''"]+)')
There is already another expression in the same query that uses ad.adrelid:
strpos(pg_catalog.pg_get_expr(ad.adbin, ad.adrelid), 'nextval')
So this change also makes the query internally consistent.
After applying this change locally, Explorer->table('users')->fetch() started working correctly with PostgreSQL 18.
Version: nette/database v3.2.8
Bug Description
Nette\Database\Drivers\PgSqlDriver::getColumns()fails during PostgreSQL table structure introspection on PostgreSQL 18.The problem happens when using
Nette\Database\Explorer, for example:$explorer->table('users')->fetch();
The query itself is not the issue. The exception is thrown before the actual table query is executed, while Nette Database is loading table metadata via
Structure/DiscoveredConventions.The error is:
Nette\Database\DriverException #XX000
SQLSTATE[XX000]: Internal error: 7 ERROR: invalid attnum 10 for relation "pg_attrdef"
The stack trace points to:
Nette\Database\Drivers\PgSqlDriver.php
Nette\Database\Structure.php
Nette\Database\Conventions\DiscoveredConventions.php
Nette\Database\Explorer.php
The issue seems to be caused by this expression in
PgSqlDriver::getColumns():pg_catalog.pg_get_expr(ad.adbin, 'pg_catalog.pg_attrdef'::regclass)::varchar AS default
and also here:
substring(pg_catalog.pg_get_expr(ad.adbin, 'pg_catalog.pg_attrdef'::regclass) from 'nextval[(]''"?([^''"]+)')
With PostgreSQL 18 this fails with
invalid attnum ... for relation "pg_attrdef".Steps To Reproduce
nette/database v3.2.8.Nette\Database\Explorerand call: $explorer->table('users')->fetch();SQLSTATE[XX000]: Internal error: 7 ERROR: invalid attnum 10 for relation "pg_attrdef"
In my case this happened in an authentication provider on this line:
$this->databaseExplorer->table('users')->order('created_at ASC')->fetch();
PostgreSQL itself was running correctly. Direct SQL queries against the
userstable worked. The failure only happened through Nette Database Explorer metadata introspection.Expected Behavior
Nette\Database\Explorershould be able to introspect PostgreSQL 18 tables without throwing an internal PostgreSQL error.Possible Solution
In
src/Database/Drivers/PgSqlDriver.php,getColumns()should probably usead.adrelidas the second argument ofpg_get_expr()instead of'pg_catalog.pg_attrdef'::regclass.This local patch fixed the problem:
There is already another expression in the same query that uses
ad.adrelid:strpos(pg_catalog.pg_get_expr(ad.adbin, ad.adrelid), 'nextval')
So this change also makes the query internally consistent.
After applying this change locally,
Explorer->table('users')->fetch()started working correctly with PostgreSQL 18.