Skip to content

Query Tool result export enhancements (JSON/XML, encoding, BOM, copy-with-headers)#10062

Open
dpage wants to merge 1 commit into
pgadmin-org:masterfrom
dpage:feature/qt-result-export-enhancements
Open

Query Tool result export enhancements (JSON/XML, encoding, BOM, copy-with-headers)#10062
dpage wants to merge 1 commit into
pgadmin-org:masterfrom
dpage:feature/qt-result-export-enhancements

Conversation

@dpage

@dpage dpage commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

A batch of long-standing Query Tool result export/copy enhancements, all in
the results download/copy path.

  • Save results as JSON or XML (in addition to CSV), selectable from a
    drop-down on the Save results to file toolbar button. The download
    generator is now format-aware and streams JSON/XML as well as CSV. JSON/XML
    are always emitted as UTF-8; XML emits column names as escaped name
    attributes so column names that are not valid XML element names are handled
    safely.
  • Output file encoding preference (Query Tool → CSV/TXT Output) controlling
    the character encoding used when saving results; defaults to utf-8, with a
    free-text option for encodings that are not listed.
  • Add byte order mark (BOM)? preference that prepends a UTF BOM to saved
    CSV/TXT files for better interoperability with applications such as Microsoft
    Excel. (Applies to CSV/TXT output only.)
  • Copy with headers? preference that seeds the default state of the results
    grid "Copy with headers" toggle (still toggleable per-copy).

Testing

  • New integration tests exercise the JSON, XML, BOM and non-UTF-encoding
    download paths through the real /query_tool/download/ endpoint; the
    existing CSV scenarios continue to pass, confirming the generator refactor
    is non-regressive.
  • pycodestyle and eslint clean.
  • Preferences and Query Tool toolbar documentation updated, plus release-notes
    entries.

Closes #3205
Closes #4128
Closes #4129
Closes #6695

Summary by CodeRabbit

Release Notes

  • New Features

    • Save Query Tool results in JSON and XML formats (in addition to CSV)
    • Configure character encoding for CSV/TXT output
    • Optional byte order mark (BOM) for UTF-encoded exports
    • Column headers option when copying data from results grid
  • Documentation

    • Updated Query Tool preferences and toolbar documentation with new export format and encoding options
  • Tests

    • Added comprehensive tests for multi-format result exports with encoding support

Several long-standing requests around exporting/copying Query Tool
results, all in the results download/copy path:

- Save results as JSON or XML in addition to CSV, selectable from a
  drop-down on the "Save results to file" toolbar button. The download
  generator is now format-aware and streams JSON/XML as well as CSV.
- New "Output file encoding" preference (CSV/TXT output) controlling
  the character encoding of saved results; defaults to utf-8.
- New "Add byte order mark (BOM)?" preference that prepends a UTF BOM
  to saved CSV/TXT files for better interoperability with applications
  such as Microsoft Excel.
- New "Copy with headers?" preference seeding the default state of the
  results grid "Copy with headers" toggle.

Adds integration tests for the JSON/XML/BOM/encoding download paths and
updates the preferences and Query Tool toolbar documentation.

Closes pgadmin-org#3205
Closes pgadmin-org#4128
Closes pgadmin-org#4129
Closes pgadmin-org#6695
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3193bd2c-d93c-46c7-9499-e21b57e5eb46

📥 Commits

Reviewing files that changed from the base of the PR and between 04fa05c and 54d07e6.

📒 Files selected for processing (9)
  • docs/en_US/preferences.rst
  • docs/en_US/query_tool_toolbar.rst
  • docs/en_US/release_notes_9_16.rst
  • web/pgadmin/tools/sqleditor/__init__.py
  • web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx
  • web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx
  • web/pgadmin/tools/sqleditor/tests/test_download_csv_query_tool.py
  • web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py
  • web/pgadmin/utils/driver/psycopg3/connection.py
👮 Files not reviewed due to content moderation or server errors (4)
  • web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py
  • web/pgadmin/utils/driver/psycopg3/connection.py
  • web/pgadmin/tools/sqleditor/init.py
  • web/pgadmin/tools/sqleditor/tests/test_download_csv_query_tool.py

Walkthrough

Query Tool result export is extended to support JSON and XML formats, configurable output encoding (UTF-8, UTF-16, Windows-1252, etc.), and optional UTF byte order marks. A new preference controls whether column headers are included by default when copying results grid data.

Changes

Query Tool Export Enhancements

Layer / File(s) Summary
Preference Definitions for Export Configuration
web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py
New preferences register CSV output encoding selection (UTF-8, UTF-16, Windows-1252), optional UTF BOM insertion for interoperability, and default behavior for including column headers when copying results grid data.
Database Driver Streaming Helpers
web/pgadmin/utils/driver/psycopg3/connection.py
Module-level _generate_json and _generate_xml helpers stream query results as JSON arrays or XML with configurable null-value replacement. The execute_on_server_as_csv generator accepts a data_format parameter and routes output through the appropriate streaming helper or CSV writer based on format selection.
Download Endpoint Format Routing
web/pgadmin/tools/sqleditor/__init__.py
Download endpoint extracts format parameter from request (csv/json/xml), applies encoding and BOM rules for CSV output, wraps streamed chunks with the selected encoding, and sets HTTP MIME type and filename extension (.csv/.txt/.json/.xml) accordingly.
Download Menu and Format Selection UI
web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx
ResultSetToolbar adds a dropdown menu for CSV/Text, JSON, and XML download options, wires format selection through the downloadResult handler, and seeds the "Copy with headers" toggle default state from user preferences via useEffect.
Result Download Parameter Passing
web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx
ResultSetUtils saveResultsToFile extended to accept dataFormat parameter, selects output MIME type per format, derives file extension (.csv vs .txt based on CSV separator), and includes format in the POST request body to the download endpoint.
Multi-Format Download Test Suite
web/pgadmin/tools/sqleditor/tests/test_download_csv_query_tool.py
New TestDownloadResultFormats test suite validates JSON, XML, and CSV downloads with configurable encoding and BOM options, verifies HTTP response headers (content type with charset, filename in Content-Disposition), confirms BOM presence/absence based on encoding type and configuration, and validates decoded output matches expected format.
User-Facing Documentation Updates
docs/en_US/preferences.rst, docs/en_US/query_tool_toolbar.rst, docs/en_US/release_notes_9_16.rst
Preferences guide documents output encoding dropdown and UTF BOM switch (applied when using UTF encodings, affects CSV/TXT only); toolbar documentation clarifies "Save results to" button behavior with format dropdown and preference reference; release notes announce export format enhancement and new encoding/header preferences.

Sequence Diagram

sequenceDiagram
  participant User
  participant ResultSetToolbar
  participant ResultSet
  participant DownloadEndpoint
  participant DatabaseDriver
  
  User->>ResultSetToolbar: Click "Save as JSON/XML/CSV"
  ResultSetToolbar->>ResultSetToolbar: downloadResult(format)
  ResultSetToolbar->>ResultSet: TRIGGER_SAVE_RESULTS(dataFormat)
  ResultSet->>ResultSet: saveResultsToFile(fileName, progress, dataFormat)
  ResultSet->>DownloadEndpoint: POST with format parameter
  DownloadEndpoint->>DatabaseDriver: execute_on_server_as_csv(data_format)
  DatabaseDriver->>DatabaseDriver: Route to _generate_json/_generate_xml/CSV writer
  DatabaseDriver-->>DownloadEndpoint: Streamed result chunks
  DownloadEndpoint->>DownloadEndpoint: Apply encoding/BOM rules
  DownloadEndpoint->>DownloadEndpoint: Set MIME type & filename extension
  DownloadEndpoint-->>User: Download response (JSON/XML/CSV)
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested Reviewers

  • khushboovashi
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.25% 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 accurately summarizes all main changes in the pull request: Query Tool result export now supports JSON/XML formats, includes encoding preferences, BOM support, and copy-with-headers preference.
Linked Issues check ✅ Passed All linked issue requirements are met: JSON/XML export support [#3205], output file encoding preference [#4128], copy-with-headers preference [#4129], and UTF BOM support [#6695].
Out of Scope Changes check ✅ Passed All changes are directly aligned with the four linked issues and PR objectives. No unrelated modifications were introduced outside the specified scope.

✏️ 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.

@anthonydb

Copy link
Copy Markdown
Contributor

@dpage You appear to be, as they say, on a roll.

Copilot AI 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.

Pull request overview

This PR enhances the pgAdmin Query Tool “save/copy results” path by adding JSON/XML exports, configurable output encoding + optional BOM for CSV/TXT exports, and a preference-seeded “copy with headers” default.

Changes:

  • Add streaming JSON and XML export formats for Query Tool results (alongside existing CSV/TXT).
  • Add Query Tool preferences for output file encoding, optional BOM, and default “copy with headers”.
  • Extend integration tests and update documentation/release notes for the new export/copy behavior.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
web/pgadmin/utils/driver/psycopg3/connection.py Add JSON/XML streaming generators and route export generation by format.
web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py Register new Query Tool preferences for encoding/BOM and copy-with-headers default.
web/pgadmin/tools/sqleditor/tests/test_download_csv_query_tool.py Add integration scenarios covering JSON/XML export + encoding/BOM paths.
web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx Add “Save results” split-button drop-down and seed copy-with-headers from preference.
web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx Send requested export format to backend; map format to MIME type and file extension.
web/pgadmin/tools/sqleditor/init.py Make download endpoint format-aware; apply encoding/BOM for CSV and UTF-8 for JSON/XML.
docs/en_US/release_notes_9_16.rst Add release note entries for the new export/copy features.
docs/en_US/query_tool_toolbar.rst Document the new export format drop-down and encoding/BOM settings.
docs/en_US/preferences.rst Document new CSV/TXT Output and Results Grid preferences.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2182 to +2200
is_utf = output_encoding.lower().replace('-', '').replace(
'_', '').startswith('utf')

str_gen = gen(conn_obj,
trans_obj,
quote=blueprint.csv_quoting.get(),
quote_char=blueprint.csv_quote_char.get(),
field_separator=blueprint.csv_field_separator.get(),
replace_nulls_with=blueprint.replace_nulls_with.get(),
data_format=data_format)

def encoded_gen(text_gen):
is_first_chunk = True
for chunk in text_gen:
if is_first_chunk:
is_first_chunk = False
if add_bom and is_utf:
chunk = '\ufeff' + chunk
yield chunk.encode(output_encoding, errors='replace')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants