-
-
Notifications
You must be signed in to change notification settings - Fork 278
feat(plugin-postgresql): render PostGIS geometry/geography as EWKT (#1458) #1467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
datlechin
merged 11 commits into
TableProApp:main
from
shubhank-saxena:feat/postgresql-postgis-rendering
May 31, 2026
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
7188ddf
feat(plugin-postgresql): render PostGIS geometry/geography as EWKT (#…
shubhank-saxena 30d0e03
test(plugin-postgresql): cover safe-to-wrap predicate and identifier …
shubhank-saxena 662fac3
docs(postgresql): note PostGIS rendering and changelog entry (#1458)
shubhank-saxena 704439d
fix(plugin-postgresql): skip PostGIS rewrite for queries with side ef…
shubhank-saxena 6d0b144
test(plugin-postgresql): cover side-effect keyword detection
shubhank-saxena af1fe74
fix(plugin-postgresql): block pg_notify and advisory-lock built-ins f…
shubhank-saxena 72fe87b
fix(plugin-postgresql): convert PostGIS values in place instead of re…
shubhank-saxena fe7cb2d
fix(plugin-postgresql): re-probe PostGIS catalogs on reconnect
shubhank-saxena 90f1a8f
test(plugin-postgresql): replace safe-to-wrap tests with value-conver…
shubhank-saxena 8435bf3
refactor(plugin-postgresql): guard PostGIS conversion against clobber…
datlechin a7398dc
Merge branch 'main' into feat/postgresql-postgis-rendering
datlechin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
Plugins/PostgreSQLDriverPlugin/PostGISSpatialRewrite.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| // | ||
| // PostGISSpatialRewrite.swift | ||
| // PostgreSQLDriverPlugin | ||
| // | ||
| // PostGIS rendering support. Geometry and geography values arrive from libpq as | ||
| // raw EWKB hex (e.g. "0101000020E6100000..."). To surface them as readable WKT | ||
| // with SRID, we probe pg_type for the dynamic PostGIS OIDs at connect time and, | ||
| // when a result set contains spatial columns, convert the already-fetched hex | ||
| // values with a separate side-effect-free query. The original user statement is | ||
| // never re-executed: the conversion runs ST_AsEWKT over an array of the fetched | ||
| // values, so it can't double-apply side effects and works the same regardless of | ||
| // whether the query was parameterized. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| enum PostGISSpatialRewrite { | ||
| static let probeQuery = "SELECT oid, typname FROM pg_type WHERE typname IN ('geometry', 'geography')" | ||
|
|
||
| static let geometryConversionQuery = | ||
| "SELECT ST_AsEWKT(t::geometry) FROM unnest($1::text[]) WITH ORDINALITY AS x(t, ord) ORDER BY ord" | ||
| static let geographyConversionQuery = | ||
| "SELECT ST_AsEWKT(t::geography) FROM unnest($1::text[]) WITH ORDINALITY AS x(t, ord) ORDER BY ord" | ||
|
|
||
| static func conversionQuery(forTypeName typeName: String) -> String? { | ||
| switch typeName { | ||
| case "geometry": return geometryConversionQuery | ||
| case "geography": return geographyConversionQuery | ||
| default: return nil | ||
| } | ||
| } | ||
|
|
||
| static func arrayLiteral(from values: [String?]) -> String { | ||
| let elements = values.map { value -> String in | ||
| guard let value else { return "NULL" } | ||
| let escaped = value | ||
| .replacingOccurrences(of: "\\", with: "\\\\") | ||
| .replacingOccurrences(of: "\"", with: "\\\"") | ||
| return "\"\(escaped)\"" | ||
| } | ||
| return "{\(elements.joined(separator: ","))}" | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../../Plugins/PostgreSQLDriverPlugin/PostGISSpatialRewrite.swift |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When PostGIS is installed in a dedicated schema that is not on the session
search_path, the OID probe still enables conversion forpostgis.geometry/postgis.geographycolumns, but these unqualified casts andST_AsEWKTlookups fail with “type/function does not exist”. In that setup a normalSELECT geom FROM ...would return rows, but this conversion path falls back to raw hex and can also leave an explicit transaction aborted after the failed helper query; the probe needs to retain the extension/type namespace and build schema-qualified casts/functions.Useful? React with 👍 / 👎.