fix(postgres): read coord_dimension when loading spatial columns - #12749
Conversation
Code Review by Qodo
1. Test added under test/github-issues
|
a56bbd0 to
30b4525
Compare
| `SELECT * FROM (` + | ||
| `SELECT "f_table_schema" "table_schema", "f_table_name" "table_name", ` + | ||
| `"f_${tableColumn.type}_column" "column_name", "srid", "type" ` + | ||
| `"f_${tableColumn.type}_column" "column_name", "srid", "type", "coord_dimension" ` + |
There was a problem hiding this comment.
Could we extend this to CockroachDB? It should be more-or-less compatible with PostGIS, they also support Z/M dimensions: https://docs.cockroachlabs.com/docs/stable/point
Over time, we'd like to extract the common code (like Sqlite), so it's good to have as little variance as possible.
There was a problem hiding this comment.
Done in e4593cc. CockroachDB exposes the same views, so the block is the same shape as the Postgres one, with two differences I could not avoid after probing v25.2 (table in the PR description): coord_dimension comes back as a bigint string, parsed like the existing srid, and CockroachDB drops the M suffix from geometry_columns, which makes PointM indistinguishable from PointZ there. Since the driver already loads crdb_sql_type for every column, the declared feature type is taken from it when present and the coord_dimension logic stays as the shared fallback. The CockroachDB spatial suite gains the same two tests, and both spatial suites pass.
commit: |
CockroachDB exposes the same geometry_columns and geography_columns views as PostGIS, so the dimensional suffix is restored the same way. Two differences are handled: coord_dimension comes back as a bigint string, and geometry_columns drops the M suffix from the type, which makes PointM look like PointZ, so the declared type in crdb_sql_type takes precedence when it carries a feature type.
30b4525 to
e4593cc
Compare
coord_dimension when loading spatial columns
gioboa
left a comment
There was a problem hiding this comment.
Thanks @samuelmbabhazi 👏
Description of change
Fixes #12747
When loading tables, the Postgres driver reads
sridandtypefrom the PostGISgeometry_columnsview but ignorescoord_dimension. PostGIS folds the Z dimension intocoord_dimensionand only keeps the M suffix intype, so ageometry(PointZ)column comes back as feature typePOINT. The loaded table then never matches metadata declaringPointZ, andmigration:generateproduces the same ALTER over and over.Verified against PostGIS 3.6, where the views report:
coord_dimensiontypegeometry(Geometry)GEOMETRYgeometry(GeometryZ)GEOMETRYgeometry(GeometryM)GEOMETRYMgeometry(GeometryZM)GEOMETRYgeography(PointZ)PointZThe query now also selects
coord_dimension, and the loader appends theZorZMsuffix when the dimension calls for it and the suffix is not already present. The guard keepsgeography_columnsworking unchanged, since that view already reports the full suffix intype.SpatialColumnOptions.spatialFeatureTypepreviously only accepted the plain GeoJSON type names, so a dimensional column could not even be declared without a cast. The type now also accepts theZ,MandZMsuffixed forms, and the decorator reference documentation mentions them.The regression test declares geometry
PointZ,PointMandPointZMcolumns plus a geographyPointZcolumn, then asserts both that the loaded table reports the dimensional feature types and that the schema builder reports no pending changes, which is the loop from the issue. Reverting the source changes makes both tests fail. The full spatial test suite passes against the postgres-14 PostGIS image from docker-compose.CockroachDB
As requested in review, the same change is applied to the CockroachDB driver, with the same block shape so the two can be extracted together later. Probed on CockroachDB v25.2, the views match PostGIS except for one case:
coord_dimensiontypetypegeometry(PointZ)POINTPOINTgeometry(PointM)POINTMPOINTgeometry(PointZM)POINTPOINTgeometry(GeometryZM)GEOMETRYGEOMETRYgeography(PointZ)PointZPointZgeography(PointZM)PointZMPointZMCockroachDB drops the M suffix from
geometry_columns, which makesPointMindistinguishable fromPointZthere. The driver already loadscrdb_sql_typefor every column (GEOMETRY(POINTM,4326)), so the declared feature type is taken from it when present and thecoord_dimensionlogic stays as the shared fallback. The only other difference is thatcoord_dimensioncomes back as a bigint string, parsed the same way the existing code parsessrid.The CockroachDB spatial suite gains the same two tests (dimensional feature types loaded, no pending schema changes), and reverting the driver change makes exactly those two fail. Both spatial suites pass: 26 tests across postgres, cockroachdb and mysql.
Pull-Request Checklist
masterbranchFixes #NNNN,Closes #NNNN, orResolves #NNNNtests/**.test.ts)docs/docs/**.md)