Skip to content

Fix: PostGIS identifier length limit - #2

Merged
AlexianMasson merged 2 commits into
mainfrom
fix/postgis-identifier-length-limit
May 19, 2026
Merged

AlexianMasson merged 2 commits into
mainfrom
fix/postgis-identifier-length-limit

Conversation

@AlexianMasson

@AlexianMasson AlexianMasson commented May 18, 2026 •

Copy link
Copy Markdown
Collaborator

Fix: PostGIS table-name length must leave room for auto-created spatial index

Problem

Writing a GeoDataFrame to PostGIS with a long table name failed with:

Error writing data to PostGIS table data.orb003_centroides_within_area_snap_to_network_test_items: Identifier 'idx_orb003_centroides_within_area_snap_to_network_test_items_geom' exceeds maximum length of 63 characters

PostgreSQL caps identifiers at 63 characters. Even when to_postgis(..., index=False) is set, PostGIS still auto-creates a spatial index named idx_<table>_<geom_col>. If the synthesized index name exceeds 63 chars, the write fails mid-operation — after data has been streamed and after the user has already committed to that table name through the UI.

Existing validators (validate_postgres_identifier, validate_table_name) only enforced the raw 63-char limit on the table name itself, so a 60-char table name passed validation and then blew up at write time.

Solution

Enforce the PostGIS-safe length cap up-front, derived from the geometry column convention:

POSTGIS_TABLE_NAME_MAX_LENGTH = 63 − len("idx__") − len(DEFAULT_GEOMETRY_COLUMN) = 54

Non-goals

  • GeoServer workspace / layer naming is unchanged — different identifier rules, no PostGIS index involved. sanitize_name's default cap stays at 63.
  • The cleanup-path validate_table_name (drop-table on rollback) still uses the default 63-char cap so legacy oversized tables remain droppable.

Manual testing

Reproduce the original bug by ingesting a dataset whose sanitised title exceeds 54 characters:

  1. Before this PR: the staging upload succeeds, then the final-write step crashes with the Identifier '...' exceeds maximum length of 63 characters error.
  2. After this PR: the title is truncated to 54 chars during derivation, the PostGIS write succeeds, and idx_<table>_geom fits within the 63-char limit.

If the user bypasses sanitisation (e.g. supplies a pre-validated name via the DB-import flow), the write_data_to_postgis validator now rejects it up-front with a clear message identifying the offending length and the cap.

@AlexianMasson
AlexianMasson requested a review from tonio May 18, 2026 16:16
@AlexianMasson
AlexianMasson force-pushed the fix/postgis-identifier-length-limit branch 3 times, most recently from cc7d88b to b1125b9 Compare May 18, 2026 16:22
@AlexianMasson AlexianMasson changed the title Fix: PostGis identifier length limit Fix: PostGIS identifier length limit May 18, 2026
Pull the 63-char bound out of the identifier regex and expose it as a
max_length parameter on validate_postgres_identifier / validate_table_name,
along with a matching max_length on sanitize_name. The defaults preserve
PostgreSQL's standard 63-char cap so existing callers are unaffected;
downstream callers that need tighter bounds (e.g. PostGIS table names that
must leave room for an auto-created index suffix) can now opt in.

Also removes a stray 'F' character left in validators.py docstring.
…hars

to_postgis silently asks PostgreSQL to create an 'idx_<table>_<geom>' index
even when index=False is set on the write. When the synthesized index name
exceeds PostgreSQL's 63-char identifier limit, the whole write fails with:

  Error writing data to PostGIS table data.<long_name>:
  Identifier 'idx_<long_name>_geom' exceeds maximum length of 63 characters

Enforce the derived 54-char cap (POSTGIS_TABLE_NAME_MAX_LENGTH) up-front:

- write_data_to_postgis validates table_name against the tighter cap, so
  the failure surfaces immediately rather than mid-write.
- get_available_table_name truncates the base name and reserves room for
  its numeric suffix using the same cap (replaces the magic '53').
- The process route runs the title through sanitize_name + validate at
  the PostGIS cap so user-supplied titles get truncated cleanly and an
  oversized name produces HTTP 400 instead of a runtime crash.
@AlexianMasson
AlexianMasson force-pushed the fix/postgis-identifier-length-limit branch from b1125b9 to a8951e7 Compare May 19, 2026 07:29

@tonio tonio left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌🏻

try:
validate_table_name(final_table_name, context="final")
validate_table_name(
final_table_name, context="final", max_length=POSTGIS_TABLE_NAME_MAX_LENGTH

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not having POSTGIS_TABLE_NAME_MAX_LENGTH as the default param ? any other usecase I don't see ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non geo table maybe (-:

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we gonna create idx_<table>_geom spatial index, we should have max_length=PG_IDENTIFIER_MAX_LENGTH (more restrictive case, so the default value).

When not creating spatial index but just reading an existing table, we can have max_length=POSTGIS_TABLE_NAME_MAX_LENGTH.

@AlexianMasson
AlexianMasson merged commit 1729206 into main May 19, 2026
4 checks passed
@f-necas
f-necas deleted the fix/postgis-identifier-length-limit branch May 28, 2026 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants