Skip to content

fix(sqleditor): skip read-only columns when saving inserted rows - #10015

Closed
asheshv wants to merge 1 commit into
pgadmin-org:masterfrom
asheshv:fix/query-tool-skip-non-editable-on-insert
Closed

fix(sqleditor): skip read-only columns when saving inserted rows#10015
asheshv wants to merge 1 commit into
pgadmin-org:masterfrom
asheshv:fix/query-tool-skip-non-editable-on-insert

Conversation

@asheshv

@asheshv asheshv commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #9939.

Query Tool result sets can include expression/alias columns (e.g. first_name || ' ' || last_name AS the_name) that don't exist on the underlying table. The editability detection in is_query_resultset_updatable.py already marks them is_editable=False, so the column header correctly shows the lock icon. But when a user adds a new row, the frontend populated every column key on the new row object and shipped the whole thing to /sqleditor/save. save_changed_data accepted those keys verbatim, and the rendered INSERT referenced the alias — Postgres replied with column "the_name" does not exist in relation "some_table".

Filter on both sides:

  • Backendget_columns_types now propagates is_editable into the column metadata stored on the session (is_editable=True defaulted for View Data Tool, where columns are always real table columns).
  • Backendsave_changed_data drops non-editable keys from the added-row data before rendering insert.sql. Defense-in-depth: protects against stale/buggy clients.
  • FrontendResultSet.jsx::triggerSaveData omits cells whose column has can_edit === false from the added-row payload.

Test plan

  • python regression/runtests.py --pkg tools.sqleditor.utils.tests.test_save_changed_data — 13/13 pass, including the new TestSaveAddedRowSkipsNonEditableColumn scenario that runs the issue's exact first_name || ' ' || last_name AS the_name SELECT and verifies the INSERT succeeds.
  • python regression/runtests.py --pkg tools.sqleditor.utils.tests.test_is_query_resultset_updatable — 10/10 pass (3 OID-only scenarios skipped on PG12+, as before).
  • python regression/runtests.py --pkg tools.sqleditor.utils.tests.test_save_changed_uuid_data — 3/3 pass (the other consumer of the changed helpers).
  • make check-pep8, yarn run linter clean.
  • Manual smoke in Query Tool: run the issue's queries, add a row, F5 — INSERT should succeed and only write real columns.

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • SQL Editor now correctly saves newly-added rows when query results include non-editable columns (such as expression or alias columns), preventing save failures and invalid INSERT statements.

Query Tool result sets can include expression or alias columns
(e.g. `first_name || ' ' || last_name AS the_name`) that are not
columns of the underlying table. The editability check correctly
marked them is_editable=False, but the new-row save flow still
sent every column from the row object, so the rendered INSERT
referenced the alias and Postgres rejected the row with
`column "the_name" does not exist`.

Filter on both sides:

- get_columns_types now propagates is_editable into the column
  metadata stored on the session.
- save_changed_data drops non-editable keys from the added-row
  data before rendering insert.sql.
- ResultSet.jsx omits cells whose column has can_edit=false from
  the added-row payload sent to the server.

Adds a regression scenario in test_save_changed_data exercising
the exact concatenation-alias query from the issue report.

Fixes pgadmin-org#9939
@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The PR fixes Query Editor failures when saving new rows in result sets containing non-editable columns (aliases, expressions). The fix filters such columns on both frontend and backend: metadata propagation adds is_editable flags, the frontend filters before sending, the backend filters during INSERT construction, and a regression test validates the scenario.

Changes

Non-editable column filtering in Query Editor saves

Layer / File(s) Summary
Non-editable column metadata propagation
web/pgadmin/tools/sqleditor/utils/get_column_types.py
The get_columns_types function adds an is_editable flag to column type descriptors, extracting it from column metadata and defaulting to True.
Frontend filtering of non-editable columns
web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx
The triggerSaveData function builds a nonEditableKeys set from columns where can_edit === false and omits those keys from each newly-added row's data before sending to the save API.
Backend filtering during insert construction
web/pgadmin/tools/sqleditor/utils/save_changed_data.py
The save_changed_data function filters row data to retain only editable columns from columns_info before rendering INSERT SQL, preventing non-existent table columns from being referenced.
Regression test for non-editable alias columns
web/pgadmin/tools/sqleditor/utils/tests/test_save_changed_data.py
A new test class TestSaveAddedRowSkipsNonEditableColumn validates the insert flow with an aliased expression column (`first_name

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.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 'fix(sqleditor): skip read-only columns when saving inserted rows' is concise, specific, and accurately describes the main change across frontend, backend, and test modifications.
Linked Issues check ✅ Passed The pull request fully addresses issue #9939 by implementing frontend filtering, backend filtering, and metadata propagation to prevent non-editable expression/alias columns from being referenced in INSERT statements.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the objective of skipping non-editable columns during insert operations; no unrelated modifications to unrelated features or infrastructure.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/pgadmin/tools/sqleditor/utils/save_changed_data.py`:
- Around line 121-129: The filtering of incoming row data currently treats
unknown column keys as editable because the predicate uses columns_info.get(k,
{}).get('is_editable', True); change the default to False so unknown keys are
rejected: update the comprehension that builds data (the dict comprehension that
references columns_info and 'is_editable') to use .get('is_editable', False) so
only known editable columns are retained before INSERT rendering.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ce5ec567-c303-4937-8f91-14fa9791425d

📥 Commits

Reviewing files that changed from the base of the PR and between 291a55e and 0f8a14b.

📒 Files selected for processing (4)
  • web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx
  • web/pgadmin/tools/sqleditor/utils/get_column_types.py
  • web/pgadmin/tools/sqleditor/utils/save_changed_data.py
  • web/pgadmin/tools/sqleditor/utils/tests/test_save_changed_data.py

Comment thread web/pgadmin/tools/sqleditor/utils/save_changed_data.py
@dpage

dpage commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Merged to master as f9b9bc9 (squashed, preserving @asheshv as author). I folded in @coderabbitai's suggestion — the added-row filter now requires k in columns_info so unknown client keys are dropped rather than defaulted to editable — and added a release-notes entry for #9939. The squash rewrites the SHA so GitHub won't auto-close this — closing manually. Thanks @asheshv!

@dpage dpage closed this Jun 9, 2026
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@dpage Thanks for merging and for folding in the k in columns_info guard — that extra safety net means the backend will correctly reject any unknown client-supplied keys even if the frontend sends something unexpected in the future. Great work by @asheshv on the fix! 🎉

(ノ◕ヮ◕)ノ*:・゚✧ 🐇

@hiteshjambhale

Copy link
Copy Markdown
Contributor

Hi @asheshv
This is fixed for add rows.

  1. Update rows still fails with same error, We can implement this for update rows as well.
  2. I would suggest resolving this on frontend. The feedback on adding a new row with non editable column is wrong. It initially appeared that the wrong value was inserted(null or added value), and it stays until we re-execute the select query

dpage pushed a commit to kundansable/pgadmin4 that referenced this pull request Aug 18, 2026
The added (INSERT) branch of save_changed_data() already filtered out
columns that aren't backed by a real table column (added for pgadmin-org#9939 /
pgadmin-org#10015), but the updated (UPDATE) branch did not. Editing a row that
includes an aliased/expression column (e.g.
first_name || ' ' || last_name AS the_name) sent that alias into the
generated UPDATE's SET clause, which fails with "column ... does not
exist" even though the grid already marks the column read-only.

Apply the same editable-columns guard to the updated branch, and skip
the row entirely if nothing editable remains after filtering.

Fixes pgadmin-org#10103
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.

Query Editor Cannot Recognize Non-Updatable Fields

3 participants