Skip to content

Fix index/constraint column not shown when its name requires quoting (#6481) - #10039

Open
dpage wants to merge 2 commits into
pgadmin-org:masterfrom
dpage:fix-6481-index-quoted-col
Open

Fix index/constraint column not shown when its name requires quoting (#6481)#10039
dpage wants to merge 2 commits into
pgadmin-org:masterfrom
dpage:fix-6481-index-quoted-col

Conversation

@dpage

@dpage dpage commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #6481.

When an index (or exclusion constraint) column name requires quoting — e.g. it contains a double quote or other special characters — the column was not shown in the Properties panel, and editing reported it as empty.

Root cause: the is_exp (expression) flag is computed as pg_get_indexdef(...) = a.attname. pg_get_indexdef() returns the SQL-quoted identifier (e.g. "col""x") while a.attname is the raw name (col"x). For any name needing quoting these never match, so a plain column was misclassified as an expression and dropped.

Fix: compare against pg_catalog.quote_ident(a.attname), which yields the same quoted form as pg_get_indexdef() for both normal and special names. Real expression indexes (where attname is NULL) still evaluate as expressions.

Changes

  • indexes/sql/11_plus/column_details.sql, indexes/sql/default/column_details.sql, exclusion_constraint/sql/default/get_constraint_cols.sql
  • Release note (9.16)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of quoted database identifiers across indexes and constraints.
    • Correctly preserves mixed-case names, reserved words, and identifiers containing double quotes.
    • More accurately distinguishes indexed columns from expressions.
  • Tests

    • Added coverage for quoted column names and identifier parsing, including edge cases.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

An error occurred during the review process. Please try again later.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d02ee2c0-5bbf-4bbe-a347-6d06e4cb670e

📥 Commits

Reviewing files that changed from the base of the PR and between c2398d5 and 9adc76c.

📒 Files selected for processing (10)
  • web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/utils.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/utils.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/utils.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/test_indexes_quoted_column.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/utils.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/exclusion_constraint/sql/default/get_constraint_cols.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/column_details.sql
  • web/pgadmin/utils/__init__.py
  • web/pgadmin/utils/tests/test_unquote_ident.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/indexes/sql/default/column_details.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/exclusion_constraint/sql/default/get_constraint_cols.sql

Included review availability: Your plan includes up to 8 reviews per rolling hour; 4 remain after this review.


Walkthrough

The change adds unquote_ident, applies it to index and constraint column handling, updates SQL identifier comparisons, and adds tests for quoted column names, including embedded double quotes.

Changes

Quoted Identifier Handling

Layer / File(s) Summary
Identifier unquoting utility
web/pgadmin/utils/__init__.py, web/pgadmin/utils/tests/test_unquote_ident.py
Adds unquote_ident and tests quoted identifiers, embedded doubled quotes, expressions, malformed values, empty strings, and None.
Index and constraint column normalization
web/pgadmin/browser/server_groups/servers/databases/schemas/tables/{indexes, constraints}/...
Uses unquote_ident when normalizing column names in index, exclusion-constraint, foreign-key, and index-constraint code.
SQL template fixes for quoted identifier comparison
web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/{indexes,exclusion_constraint}/sql/default/*.sql
Compares index definitions with quoted attribute names when computing is_exp.
Quoted-column index regression coverage
web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/tests/test_indexes_quoted_column.py
Creates indexes on mixed-case, reserved, and embedded-quote column names, then verifies the returned column name and is_exp value.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 9adc7

This change corrects display and editing of index or constraint columns with quoted names, with focused coverage added; no actionable merge-blocking risk remains beyond normal checks and review.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the fix for index and constraint columns that require SQL quoting.
Linked Issues check ✅ Passed The changes address issue [#6481] by preserving quoted column names and adding regression coverage for index metadata.
Out of Scope Changes check ✅ Passed The SQL, utility, and test changes support quoted identifier handling for indexes and constraints within the stated objectives.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@dpage
dpage force-pushed the fix-6481-index-quoted-col branch 3 times, most recently from ea60e15 to 464cc15 Compare June 9, 2026 11:37

@asheshv asheshv 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.

The SQL fix (comparing against quote_ident(a.attname) instead of a.attname) is correct — is_exp will now classify properly. But the Python side that displays the column name is still broken for the exact category the PR claims to fix.

web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/utils.py:123 uses attdef.strip('"'). str.strip('"') strips outer quotes but doesn't unescape doubled inner quotes. For a column named col"x, pg_get_indexdef returns "col""x"; .strip('"') yields col""x, not col"x. So the properties panel still displays the wrong name for any identifier containing a literal ".

Pull this into a tiny helper:

def unquote_ident(s):
    if s.startswith('"') and s.endswith('"'):
        return s[1:-1].replace('""', '"')
    return s

Tests gap: no scenarios for quoted-identifier column names (uppercase, spaces, reserved words, embedded "). The regression that caused #6481 wouldn't have been caught by existing tests, and this PR doesn't add coverage for it.

@dpage
dpage force-pushed the fix-6481-index-quoted-col branch from 464cc15 to 9adc76c Compare August 17, 2026 12:16
@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

dpage and others added 2 commits August 17, 2026 15:53
…g#6481

The is_exp flag compared pg_get_indexdef() (which returns the SQL-quoted
identifier) directly against a.attname (the raw name). For any column
name needing quoting these differ, so a plain column was wrongly treated
as an expression and not rendered, and validation reported it empty.
Compare against pg_catalog.quote_ident(a.attname) instead, which matches
pg_get_indexdef()'s output for both normal and quoted names; real
expressions (attname NULL) still evaluate as expressions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The SQL fix classifies the column correctly, but the Python that displays
it still used str.strip('"'), which removes the outer quotes without
unescaping the doubled inner ones, so a column named col"x came back as
col""x and the properties panel showed the wrong name. Worse, the create
templates re-quote that value with qtIdent(), turning it into
"col""""x" in generated DDL.

unquote_ident() in pgadmin.utils reverses quote_ident() properly: it
unescapes doubled quotes, and because it only matches a string that is
entirely one quoted identifier it leaves expressions such as "a" || "b"
alone, which strip() mangled. The same pattern appeared in the index,
exclusion, index and foreign key constraint code, so all five call sites
now share the helper.

Tests cover the helper directly, and a new index test asserts the
Properties panel reports the right column for a mixed case name, a
reserved word and a name containing a literal double quote, none of which
had any coverage.

The 11_plus index template hunk from the original commit is dropped: that
bucket no longer exists on master.
@dpage
dpage force-pushed the fix-6481-index-quoted-col branch from 9adc76c to 067830a Compare August 17, 2026 14:54
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.

The index column is not shown in the Properties dialogue if the column name contains double quotes *

2 participants