Skip to content

Feat: Added a Statistics node #2018#9748

Open
mzabuawala wants to merge 1 commit intopgadmin-org:masterfrom
mzabuawala:Feat_STATISTICS
Open

Feat: Added a Statistics node #2018#9748
mzabuawala wants to merge 1 commit intopgadmin-org:masterfrom
mzabuawala:Feat_STATISTICS

Conversation

@mzabuawala
Copy link
Contributor

@mzabuawala mzabuawala commented Mar 16, 2026

Fixes - #2018

Summary by CodeRabbit

  • New Features

    • Added extended-statistics management for PostgreSQL 14+ with a dedicated browser node and UI: create, view, update, delete statistics (column- or expression-based), version-aware SQL generation (14/16/17), schema-diff and dependency support, plus context menus and dialogs for configuration.
  • Tests

    • Added comprehensive integration and regression tests and fixtures covering statistics CRUD, list/delete-multiple, validation and error scenarios.

@coderabbitai
Copy link

coderabbitai bot commented Mar 16, 2026

Walkthrough

Adds a new "Statistics" schema child node with backend REST endpoints, SQL templates for multiple PostgreSQL versions, frontend UI components, tests and test utilities, and integrates the module into the schema module and webpack build.

Changes

Cohort / File(s) Summary
Schema registration
web/pgadmin/browser/server_groups/servers/databases/schemas/__init__.py
Registers the new Statistics blueprint as a schema submodule.
Backend: statistics module & view
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/__init__.py
New StatisticsModule/StatisticsView: REST handlers (list/nodes/properties/create/update/delete/sql/msql/statistics/dependencies/dependents), version gating (PG14+), and SchemaDiff integration.
Frontend: node & UI
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/static/js/statistics.js, .../statistics.ui.js
Adds AMD module registering statistics and coll-statistics nodes, menu actions, AJAX column-loading, and a StatisticsSchema UI definition with validation.
SQL templates — default / PG14+
.../templates/statistics/sql/default/*.sql
Templates for create, update, delete, properties, nodes, count, coll_stats, get_oid, stats, and backend support queries against pg_statistic_ext.
SQL templates — PG16+
.../templates/statistics/sql/16_plus/*.sql
PG16+ create/properties/update templates with conditional name handling and expression support.
SQL templates — PG17+
.../templates/statistics/sql/17_plus/*.sql
PG17+ create/properties/update templates with expression handling and updated conditional clauses.
Tests: fixtures & utilities
.../statistics/tests/statistics_test_data.json, .../statistics/tests/utils.py
New test fixtures and helper functions for API and DB operations (create/verify/drop/get columns).
Tests: test suites
.../statistics/tests/test_statistics_add.py, .../test_statistics_delete*.py, .../test_statistics_get.py, .../test_statistics_put.py
Integration/regression tests covering create, delete (single/multiple), get, and update with positive/negative scenarios and version gating.
Build integration
web/webpack.config.js, web/webpack.shim.js
Adds import and resolve alias for pgadmin.node.statistics so frontend bundle includes the new module.

Sequence Diagram(s)

sequenceDiagram
    participant Browser as Browser (UI)
    participant Server as pgAdmin REST
    participant DB as PostgreSQL

    Browser->>Server: POST /schema/<scid>/statistics (create payload)
    Server->>DB: Execute CREATE STATISTICS (version-specific SQL)
    DB-->>Server: Success + optionally new OID
    Server-->>Browser: 201 Created (node info or success)
    
    Browser->>Server: GET /schema/<scid>/statistics (list)
    Server->>DB: Query pg_statistic_ext (nodes/properties templates)
    DB-->>Server: Rows (statistics metadata)
    Server-->>Browser: 200 OK (list payload)
    
    Browser->>Server: PUT /schema/<scid>/statistics/<stid> (update)
    Server->>DB: Execute ALTER/COMMENT SQL (templated)
    DB-->>Server: Success
    Server-->>Browser: 200 OK (updated node)
    
    Browser->>Server: DELETE /schema/<scid>/statistics/<stid>
    Server->>DB: Execute DROP STATISTICS (cascade/only handling)
    DB-->>Server: Success
    Server-->>Browser: 200 OK
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Suggested reviewers

  • anilsahoo20
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 73.47% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly describes the main change: adding a Statistics node to pgAdmin, which is the primary focus of the entire changeset including the new statistics module, UI components, and test cases.

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

@mzabuawala mzabuawala force-pushed the Feat_STATISTICS branch 8 times, most recently from 0c50973 to ab59af0 Compare March 21, 2026 07:19
@mzabuawala mzabuawala marked this pull request as ready for review March 21, 2026 08:02
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 17

🧹 Nitpick comments (9)
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/update.sql (1)

3-7: Redundant conditional produces identical output.

The {% if %} and {% else %} branches on line 4 emit the same SQL: {{ conn|qtIdent(o_data.schema, o_data.name) }}. The conditional is dead code and can be simplified.

♻️ Proposed simplification
 {### Rename statistics ###}
 {% if data.name and data.name != o_data.name %}
-ALTER STATISTICS {% if data.schema and data.schema != o_data.schema %}{{ conn|qtIdent(o_data.schema, o_data.name) }}{% else %}{{ conn|qtIdent(o_data.schema, o_data.name) }}{% endif %}
+ALTER STATISTICS {{ conn|qtIdent(o_data.schema, o_data.name) }}
 
     RENAME TO {{ conn|qtIdent(data.name) }};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/update.sql`
around lines 3 - 7, The conditional around emitting the identifier in the ALTER
STATISTICS statement is redundant because both branches output {{
conn|qtIdent(o_data.schema, o_data.name) }}; remove the entire {% if data.schema
and data.schema != o_data.schema %} ... {% else %} ... {% endif %} block and
replace it with a single occurrence of {{ conn|qtIdent(o_data.schema,
o_data.name) }} so ALTER STATISTICS always uses that identifier (refer to the
ALTER STATISTICS line and the conn|qtIdent(o_data.schema, o_data.name)
expression).
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/backend_support.sql (1)

1-5: LGTM with a minor optimization suggestion.

The logic correctly detects PostgreSQL 10+ extended statistics support. Using EXISTS would be slightly more efficient as it short-circuits on the first match:

♻️ Optional: Use EXISTS for efficiency
 {### Check if extended statistics are supported (PostgreSQL 10+) ###}
 SELECT
-    CASE WHEN COUNT(*) > 0 THEN TRUE ELSE FALSE END AS has_statistics
-FROM pg_catalog.pg_class
-WHERE relname='pg_statistic_ext'
+    EXISTS (
+        SELECT 1 FROM pg_catalog.pg_class WHERE relname = 'pg_statistic_ext'
+    ) AS has_statistics
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/backend_support.sql`
around lines 1 - 5, Replace the COUNT-based detection of extended statistics
with an EXISTS-based check to short-circuit on the first match: update the query
that produces has_statistics (currently scanning pg_catalog.pg_class with WHERE
relname='pg_statistic_ext') to use an EXISTS subquery so it returns TRUE as soon
as a matching pg_statistic_ext row is found, keeping the same column name
has_statistics and still querying pg_catalog.pg_class with
relname='pg_statistic_ext'.
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/update.sql (1)

3-7: Redundant conditional produces identical output.

Same issue as in the 17_plus template: both branches output {{ conn|qtIdent(o_data.schema, o_data.name) }}.

♻️ Proposed simplification
 {### Rename statistics ###}
 {% if data.name and data.name != o_data.name %}
-ALTER STATISTICS {% if data.schema and data.schema != o_data.schema %}{{ conn|qtIdent(o_data.schema, o_data.name) }}{% else %}{{ conn|qtIdent(o_data.schema, o_data.name) }}{% endif %}
+ALTER STATISTICS {{ conn|qtIdent(o_data.schema, o_data.name) }}
 
     RENAME TO {{ conn|qtIdent(data.name) }};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/update.sql`
around lines 3 - 7, The inner conditional in the update.sql template is
redundant because both branches render {{ conn|qtIdent(o_data.schema,
o_data.name) }}; simplify by removing the conditional and directly use {{
conn|qtIdent(o_data.schema, o_data.name) }} where the ALTER STATISTICS target is
built (keep the outer check {% if data.name and data.name != o_data.name %} ...
RENAME TO {{ conn|qtIdent(data.name) }}; intact); no other logic changes
required.
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/stats.sql (1)

1-1: Misleading version comment for a default template.

The comment states "PostgreSQL 10-11" but this file is in the default folder, which typically serves as the fallback for versions without specific templates. Consider either moving this to a version-specific folder (e.g., 10_plus) or updating the comment to reflect its actual usage scope.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/stats.sql`
at line 1, The comment in the stats.sql default template incorrectly labels the
template as "PostgreSQL 10-11"; either remove or update that version-specific
wording in the stats.sql file (the default template for statistics) to indicate
it is a generic/fallback template, or move this template into a version-specific
directory (e.g., the 10_plus template set) so the comment accurately reflects
its scope; update the header comment in stats.sql (or relocate the file) and
ensure the comment matches the template's actual usage.
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/statistics_test_data.json (1)

232-249: Limited test coverage for update operations.

The statistics_put suite only tests renaming. Consider adding test cases for:

  • Schema change
  • Owner change
  • Comment update
  • Non-existing object (negative test, similar to delete/get suites)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/statistics_test_data.json`
around lines 232 - 249, Add broader update test cases to the statistics_put
suite: keep the existing "Update statistics: Change name." case and add tests
that exercise schema change (set a new "schema" in test_data), owner change (set
an "owner" value), comment update (set a "comment" field), and a negative test
where the object does not exist (use the same "url": "/browser/statistics/obj/"
but set an invalid identifier in inventory_data or test_data and assert a
non-200 status and error_msg). Ensure each new case follows the same shape as
the existing entry (fields: name, url, is_positive_test, inventory_data,
test_data, mocking_required, mock_data, expected_data) and uses unique
descriptive names so they run alongside the current "Update statistics: Change
name." case.
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/create.sql (1)

1-14: Remove duplicate template; 17_plus/create.sql differs from 16_plus/create.sql only in the version comment.

The two templates have identical SQL logic. If PostgreSQL 17 introduced no syntax changes for CREATE STATISTICS, remove the 17_plus template and let template resolution fall back to 16_plus.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/create.sql`
around lines 1 - 14, The 17_plus/create.sql template duplicates the CREATE
STATISTICS logic from 16_plus/create.sql (the CREATE STATISTICS block and
COMMENT ON STATISTICS handling), so delete the redundant 17_plus/create.sql file
and rely on template resolution to fall back to 16_plus/create.sql; ensure no
unique content from 17_plus (e.g., version-only comment) is required elsewhere
and update any references or tests that explicitly point to the 17_plus template
to use the fallback or 16_plus instead.
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/properties.sql (1)

1-1: Minor: Inaccurate comment for the version-specific template.

The comment states "PostgreSQL 14+" but this template is in the 16_plus folder. Consider updating the comment to reflect this is for PostgreSQL 16+.

-{### Query extended statistics properties from pg_statistic_ext (PostgreSQL 14+) ###}
+{### Query extended statistics properties from pg_statistic_ext (PostgreSQL 16+) ###}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/properties.sql`
at line 1, The header comment in the template is inaccurate — update the comment
string "{### Query extended statistics properties from pg_statistic_ext
(PostgreSQL 14+) ###}" to reference PostgreSQL 16+ (e.g. change "PostgreSQL 14+"
to "PostgreSQL 16+") so it correctly reflects the file's 16_plus template;
ensure the modified comment remains the same format and location.
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_add.py (1)

75-75: Unused variable db_user.

The variable db_user is assigned but never used in the method.

     def runTest(self):
         """This function will add statistics under schema node."""
-        db_user = self.server["username"]
         self.data["schema"] = self.schema_name
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_add.py`
at line 75, The assignment to db_user in the test (db_user =
self.server["username"]) is unused; remove this unused variable assignment from
the test in tests/test_statistics_add.py, or if the intent was to reference the
server username later, replace usages to use db_user consistently (e.g., use
db_user where self.server["username"] is currently repeated) so there are no
unused variables.
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/properties.sql (1)

1-1: Minor: Update version comment to match template location.

The comment indicates "PostgreSQL 14+" but this template resides in the 17_plus folder.

-{### Query extended statistics properties from pg_statistic_ext (PostgreSQL 14+) ###}
+{### Query extended statistics properties from pg_statistic_ext (PostgreSQL 17+) ###}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/properties.sql`
at line 1, Update the version comment at the top of the template: replace
"PostgreSQL 14+" with "PostgreSQL 17+" so the header in the statistics SQL
template in the 17_plus folder accurately reflects the template location; ensure
the comment string in the file that currently reads "{### Query extended
statistics properties from pg_statistic_ext (PostgreSQL 14+) ###}" is edited to
say "(PostgreSQL 17+)" to keep versioning consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/__init__.py`:
- Around line 422-435: The current parsing uses split(',') which breaks SQL
expressions with commas; update the parsing in the block that checks
has_expression_list to stop naive comma-splitting: if data['expression_list'] is
provided, first try to json.loads it as an array of expressions and map each
element to {'expression': <elem>}; if json.loads fails, treat the entire
expression_list string as a single expression (wrap it as [{'expression':
expression_list}]) instead of splitting; keep the existing assignment to
data['expressions'] but remove the list comprehension that splits on ',' and add
validation/logging for malformed JSON so callers (UI) are encouraged to send a
structured list.
- Around line 667-677: The function msql() currently assigns the second value
from self.get_SQL(...) to the name "_" which shadows the module-level gettext
alias and causes an UnboundLocalError when _("...") is called during validation;
change the assignment "sql, _ = self.get_SQL(gid, sid, did, data, scid, stid)"
to use a different local name (e.g., "sql, sql_params" or "sql, dummy") and
update any subsequent uses of that second value accordingly so "_" remains the
gettext function and is not shadowed.
- Around line 565-570: The render_template calls that build the DELETE SQL
(using self.template_path and self._DELETE_SQL) do not pass the DB connection
into the template context, but the delete.sql uses {{ conn|qtIdent(schema, name)
}}; update both render_template invocations (the one around the block
referencing res['rows'][0]['name']/['schema'] and the other similar call later)
to include conn=self.conn in their keyword args so the qtIdent filter can access
the connection.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/static/js/statistics.ui.js`:
- Around line 80-127: Add a dependency-driven reset for schema changes: in the
field definition with id 'schema' add a depChange handler that clears 'table'
and 'columns' (e.g., return {table: null, columns: []}) so stale selections
cannot persist when schema changes; also update the 'table' field's options
loader usage (the options or optionsLoaded logic that currently uses
this.fieldOptions.tables / obj.allTablesOptions) so it takes the selected schema
from state (use the same state.schema value or call
obj.getTableOid/state.schema) when fetching tables, and update the table-loader
in statistics.js to request tables scoped to the selected schema rather than a
global list. Ensure references: id 'schema', id 'table', id 'columns',
obj.getTableOid, and obj.fieldOptions.getColumns are used to locate and change
the code.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/update.sql`:
- Line 1: Update the misleading header comment "{### SQL to update extended
statistics object (PostgreSQL 13+) ###}" to reflect the directory name by
changing "PostgreSQL 13+" to "PostgreSQL 16+" so the comment matches the folder
`16_plus`; locate the comment in the template file's top-level SQL header (the
exact string above) and replace the version number accordingly.
- Around line 22-25: Validate and cast data.stattarget to an integer before
rendering this template: ensure wherever request.form/request.json populates
data.stattarget you apply explicit int() casting and/or numeric validation and
reject non-integer input, so the template variable data.stattarget used in the
ALTER STATISTICS ... SET STATISTICS statement is guaranteed to be an integer;
keep the existing use of qtIdent(...) for schema/name but enforce integer
semantics for data.stattarget and return a validation error if casting fails.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/stats.sql`:
- Around line 14-18: The stxkind CASE in the stats.sql template is missing the
mapping for PostgreSQL 15's 'e' kind (expression statistics); update the CASE
that checks "kind" (the stxkind case in the statistics/sql/default/stats.sql
template) to include WHEN 'e' THEN 'expressions' so expression statistics are
returned by the default template fallback used for versions that don't override
this file.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/statistics_test_data.json`:
- Around line 74-77: Update the inaccurate skip message for the inventory_data
test fixture: locate the JSON object named "inventory_data" (which currently
sets "server_min_version": 140000) and change its "skip_msg" to either reflect
that MCV extended statistics were introduced in PostgreSQL 12 (e.g., "MCV
statistics introduced in PG 12") or remove the message entirely if the
server_min_version is intended to indicate a different PG14+ requirement; ensure
the skip_msg matches the actual gating condition tied to server_min_version.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_add.py`:
- Around line 103-106: The test uses eval(self.mock_data["return_value"]) inside
the patch side_effect which is unsafe; replace eval with a safe parser or
factory – e.g., use ast.literal_eval or json.loads on
self.mock_data["return_value"] (or create a centralized factory function that
maps known mock keys to concrete return objects) and pass that parsed value as
the side_effect in the patch for self.mock_data["function_name"], leaving
statistics_utils.api_create(self) call unchanged; ensure tests that set
mock_data return_value produce JSON/text or keys compatible with the chosen
parser/factory and update any test fixtures accordingly.
- Around line 31-33: The setUp method in StatisticsAddTestCase is missing a call
to its parent initializer; update StatisticsAddTestCase.setUp to call
super().setUp() at the start (so BaseTestGenerator and other test setup logic
runs) before assigning self.data = self.test_data, ensuring proper test
initialization.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_delete_multiple.py`:
- Around line 117-120: The test is using an invalid MIME type 'html/json' for
the JSON POST payload; locate the call that passes content_type='html/json' (in
the test in test_statistics_delete_multiple.py where the client request is made
with follow_redirects=True, data=data, content_type=...) and change the
content_type value to 'application/json' so the request uses the correct JSON
Content-Type header.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_delete.py`:
- Around line 129-134: The test currently only verifies deletion of
self.statistics_name but misses verifying self.statistics_name_2 when
self.is_list is true; update the teardown/backend verification in
test_statistics_delete (after calling statistics_utils.verify_statistics) to
also call statistics_utils.verify_statistics(self.server, self.db_name,
self.statistics_name_2) and assert it is None when self.is_list is True (i.e.,
only perform the second check when setUp() created self.statistics_name_2);
ensure both assertions use self.assertIsNone with descriptive messages so a
partial batch-delete (first removed, second present) will fail the test.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_get.py`:
- Around line 134-138: The test uses eval(self.mock_data["return_value"]) which
is unsafe; replace it with a safe parser such as
ast.literal_eval(self.mock_data["return_value"]) after importing ast, or better
yet return a concrete object via a small factory/mapping keyed by
self.mock_data["return_value"] and referenced in the patch call; update the
patch call in test_statistics_get.py (the block using
self.mock_data["function_name"] and statistics_utils.api_get(self)) to use the
safe parsed/constructed object instead of eval and ensure the corresponding
import or factory mapping is added to the test file.
- Around line 58-64: The code reads server_con["data"]["version"] before
verifying the connection succeeded, which can raise a KeyError if connect_server
failed; update the logic in the block that calls
server_utils.connect_server(self, self.server_id) so you first check
server_con.get("info") == "Server connected." (or existence of "data") and only
then read ver = server_con["data"]["version"]; if the check fails, raise the
exception immediately, otherwise compare ver to self.data["server_max_version"]
and call self.skipTest(self.data["skip_msg"]) as before.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_put.py`:
- Around line 112-116: The test uses eval(self.mock_data["return_value"]) inside
the patch side_effect (in test_statistics_put.py) which is a security risk;
replace eval with a safe factory/parser: add a helper like
create_side_effect(config) (or reuse ast.literal_eval if values are simple
literals) that inspects self.mock_data (keys "type"/"value"/"class"/"message" or
"value") and returns either an exception instance or a plain value, then change
the patch to use side_effect=[create_side_effect(self.mock_data)] referencing
the same function name used in the diff instead of eval; ensure the helper
handles exception creation (using getattr on builtins for class names) and
simple value returns to avoid executing arbitrary code.
- Around line 110-120: The test currently only sets response when
self.mocking_required is True, so if self.is_positive_test is False and
self.mocking_required is False response remains undefined; ensure response is
always assigned by calling statistics_utils.api_put(self) in the missing branch
(i.e., add an else branch to the if self.mocking_required block or initialize
response before the conditional) so response is defined before
utils.assert_status_code and utils.assert_error_message; reference: response,
self.mocking_required, self.is_positive_test, and statistics_utils.api_put.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/utils.py`:
- Around line 153-189: The create_statistics() helper opens a DB connection via
test_utils.get_db_connection and currently only commits and returns the
statistics OID on the happy path, leaking connections on errors; update
create_statistics() to ensure connection cleanup by moving
test_utils.set_isolation_level(connection, old_isolation_level),
connection.commit() and connection.close() into a finally block (or closing the
cursor/connection in finally) so the connection is always closed even on
exceptions, and apply the same finally-based cleanup pattern to other helpers
that use test_utils.get_db_connection, pg_cursor, connection, and
test_utils.set_isolation_level.

---

Nitpick comments:
In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/properties.sql`:
- Line 1: The header comment in the template is inaccurate — update the comment
string "{### Query extended statistics properties from pg_statistic_ext
(PostgreSQL 14+) ###}" to reference PostgreSQL 16+ (e.g. change "PostgreSQL 14+"
to "PostgreSQL 16+") so it correctly reflects the file's 16_plus template;
ensure the modified comment remains the same format and location.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/update.sql`:
- Around line 3-7: The inner conditional in the update.sql template is redundant
because both branches render {{ conn|qtIdent(o_data.schema, o_data.name) }};
simplify by removing the conditional and directly use {{
conn|qtIdent(o_data.schema, o_data.name) }} where the ALTER STATISTICS target is
built (keep the outer check {% if data.name and data.name != o_data.name %} ...
RENAME TO {{ conn|qtIdent(data.name) }}; intact); no other logic changes
required.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/create.sql`:
- Around line 1-14: The 17_plus/create.sql template duplicates the CREATE
STATISTICS logic from 16_plus/create.sql (the CREATE STATISTICS block and
COMMENT ON STATISTICS handling), so delete the redundant 17_plus/create.sql file
and rely on template resolution to fall back to 16_plus/create.sql; ensure no
unique content from 17_plus (e.g., version-only comment) is required elsewhere
and update any references or tests that explicitly point to the 17_plus template
to use the fallback or 16_plus instead.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/properties.sql`:
- Line 1: Update the version comment at the top of the template: replace
"PostgreSQL 14+" with "PostgreSQL 17+" so the header in the statistics SQL
template in the 17_plus folder accurately reflects the template location; ensure
the comment string in the file that currently reads "{### Query extended
statistics properties from pg_statistic_ext (PostgreSQL 14+) ###}" is edited to
say "(PostgreSQL 17+)" to keep versioning consistent.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/update.sql`:
- Around line 3-7: The conditional around emitting the identifier in the ALTER
STATISTICS statement is redundant because both branches output {{
conn|qtIdent(o_data.schema, o_data.name) }}; remove the entire {% if data.schema
and data.schema != o_data.schema %} ... {% else %} ... {% endif %} block and
replace it with a single occurrence of {{ conn|qtIdent(o_data.schema,
o_data.name) }} so ALTER STATISTICS always uses that identifier (refer to the
ALTER STATISTICS line and the conn|qtIdent(o_data.schema, o_data.name)
expression).

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/backend_support.sql`:
- Around line 1-5: Replace the COUNT-based detection of extended statistics with
an EXISTS-based check to short-circuit on the first match: update the query that
produces has_statistics (currently scanning pg_catalog.pg_class with WHERE
relname='pg_statistic_ext') to use an EXISTS subquery so it returns TRUE as soon
as a matching pg_statistic_ext row is found, keeping the same column name
has_statistics and still querying pg_catalog.pg_class with
relname='pg_statistic_ext'.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/stats.sql`:
- Line 1: The comment in the stats.sql default template incorrectly labels the
template as "PostgreSQL 10-11"; either remove or update that version-specific
wording in the stats.sql file (the default template for statistics) to indicate
it is a generic/fallback template, or move this template into a version-specific
directory (e.g., the 10_plus template set) so the comment accurately reflects
its scope; update the header comment in stats.sql (or relocate the file) and
ensure the comment matches the template's actual usage.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/statistics_test_data.json`:
- Around line 232-249: Add broader update test cases to the statistics_put
suite: keep the existing "Update statistics: Change name." case and add tests
that exercise schema change (set a new "schema" in test_data), owner change (set
an "owner" value), comment update (set a "comment" field), and a negative test
where the object does not exist (use the same "url": "/browser/statistics/obj/"
but set an invalid identifier in inventory_data or test_data and assert a
non-200 status and error_msg). Ensure each new case follows the same shape as
the existing entry (fields: name, url, is_positive_test, inventory_data,
test_data, mocking_required, mock_data, expected_data) and uses unique
descriptive names so they run alongside the current "Update statistics: Change
name." case.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_add.py`:
- Line 75: The assignment to db_user in the test (db_user =
self.server["username"]) is unused; remove this unused variable assignment from
the test in tests/test_statistics_add.py, or if the intent was to reference the
server username later, replace usages to use db_user consistently (e.g., use
db_user where self.server["username"] is currently repeated) so there are no
unused variables.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9674af98-86d0-4fcb-8398-4e95fbb92be2

📥 Commits

Reviewing files that changed from the base of the PR and between 2576548 and ab59af0.

⛔ Files ignored due to path filters (2)
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/static/img/coll-statistics.svg is excluded by !**/*.svg
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/static/img/statistics.svg is excluded by !**/*.svg
📒 Files selected for processing (32)
  • web/pgadmin/browser/server_groups/servers/databases/schemas/__init__.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/__init__.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/static/js/statistics.js
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/static/js/statistics.ui.js
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/create.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/properties.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/update.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/create.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/properties.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/update.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/backend_support.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/coll_stats.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/count.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/create.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/delete.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/get_oid.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/nodes.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/properties.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/stats.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/update.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/__init__.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/pg/14_plus/__init__.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/pg/__init__.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/statistics_test_data.json
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_add.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_delete.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_delete_multiple.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_get.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_put.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/utils.py
  • web/webpack.config.js
  • web/webpack.shim.js

@mzabuawala mzabuawala force-pushed the Feat_STATISTICS branch 2 times, most recently from a757d95 to fe79b94 Compare March 21, 2026 08:40
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (5)
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_add.py (1)

31-33: ⚠️ Potential issue | 🟠 Major

Call super().setUp() before using BaseTestGenerator state.

This is the only new statistics test that skips the base initializer, so later accesses to scenario/base attributes can run against partially initialized state.

Minimal fix
     def setUp(self):
+        super().setUp()
         # Load test data
         self.data = self.test_data
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_add.py`
around lines 31 - 33, The setUp method in the test (function setUp) uses
BaseTestGenerator state before initializing it; modify setUp to call
super().setUp() as the first action so the base class initializer runs before
accessing self.test_data or other scenario/base attributes (i.e., add a call to
super().setUp() at the top of setUp in the TestStatisticsAdd test file).
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/__init__.py (2)

890-895: ⚠️ Potential issue | 🟠 Major

Pass conn into the schema-diff DROP render.

The target_only diff path still renders delete.sql without conn=self.conn, so qtIdent cannot quote the qualified statistics name there.

Minimal fix
             sql = render_template(
                 "/".join([self.template_path, self._DELETE_SQL]),
                 name=target_params['name'],
                 schema=target_params['schema'],
-                cascade=False
+                cascade=False,
+                conn=self.conn
             )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/__init__.py`
around lines 890 - 895, The target-only diff branch renders the delete.sql
template without the DB connection, so qtIdent cannot properly quote the
qualified statistics name; update the render_template call that builds sql
(using self.template_path and self._DELETE_SQL) to pass conn=self.conn (i.e.,
render_template(..., name=..., schema=..., cascade=False, conn=self.conn)) so
the template can use the connection for quoting.

422-435: ⚠️ Potential issue | 🟠 Major

Stop parsing expressions with split(','), and reuse the same normalizer in preview SQL.

coalesce(a, b) becomes two broken entries here, and msql() renders the same CREATE template without even building data['expressions']. Extract one normalization step and use it for both create and preview paths instead of comma-splitting free text.

Also applies to: 644-679, 728-733

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/__init__.py`
around lines 422 - 435, Replace the ad-hoc comma split logic that builds
data['expressions'] from data['expression_list'] with a shared normalization
helper so complex expressions like "coalesce(a, b)" are preserved; create a
function (e.g. normalize_expressions) that takes the raw expression_list string,
parses/normalizes it into a list of {'expression': ...} entries (preserving
parentheses and function calls, trimming whitespace, and ignoring empty items)
and call this helper wherever the preview/build path currently handles
expression_list (the code that assigns data['expressions'] from
data['expression_list'] and the preview path that uses msql), removing any
split(',') usage and ensuring both creation and preview use the same normalized
output.
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/utils.py (1)

93-133: ⚠️ Potential issue | 🟠 Major

Close these DB helpers in finally.

These helpers only close the connection on the success path. Any exception before connection.close() leaks a backend session, and the helpers that switch isolation level can also skip restoring it. Move cleanup into finally for create_table_for_statistics(), create_statistics(), verify_statistics(), get_statistics_id(), delete_statistics(), and get_statistics_columns().

Also applies to: 153-190, 205-224, 239-259, 275-296, 311-332

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/utils.py`
around lines 93 - 133, The helpers (create_table_for_statistics,
create_statistics, verify_statistics, get_statistics_id, delete_statistics,
get_statistics_columns) currently only close connections on the success path;
move the cleanup into a finally block: ensure any created cursor is closed, the
connection isolation level is restored to old_isolation_level if set, and the
connection is closed in finally even if exceptions occur; also ensure you only
call set_isolation_level and commit/rollback when connection is not None and
handle exceptions during commit by rolling back before closing to avoid leaking
backend sessions.
web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_delete.py (1)

129-134: ⚠️ Potential issue | 🟠 Major

Verify the second statistics object in list-delete mode.

When self.is_list is true, the positive path only checks self.statistics_name. A batch delete that leaves self.statistics_name_2 behind will still pass.

Minimal fix
             statistics_response = statistics_utils.verify_statistics(
                 self.server, self.db_name, self.statistics_name
             )
             self.assertIsNone(statistics_response,
                               "Deleted statistics still present")
+            if self.is_list:
+                statistics_response = statistics_utils.verify_statistics(
+                    self.server, self.db_name, self.statistics_name_2
+                )
+                self.assertIsNone(
+                    statistics_response,
+                    "Second deleted statistics still present"
+                )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_delete.py`
around lines 129 - 134, The test only verifies deletion of self.statistics_name
when self.is_list is True, allowing self.statistics_name_2 to remain; update the
teardown/assertion to also verify that self.statistics_name_2 is deleted in
list-delete mode by calling statistics_utils.verify_statistics for
self.statistics_name_2 (in addition to self.statistics_name) and asserting the
response is None; modify the block that currently calls
statistics_utils.verify_statistics(self.server, self.db_name,
self.statistics_name) to perform the same verification for
self.statistics_name_2 when self.is_list is True.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_delete_multiple.py`:
- Around line 111-121: The test currently only asserts a 200 response after
calling self.tester.delete with data=json.dumps({'ids': self.statistics_ids})
but doesn't verify backend deletion; after the delete request (the call to
self.tester.delete in test_statistics_delete_multiple.py), re-query the two
statistics by their generated names/IDs (referencing self.statistics_ids and any
helper used to fetch statistics in the test class) and assert that neither
exists (e.g., returns None or 404) to ensure both records were removed rather
than relying solely on response.status_code.

---

Duplicate comments:
In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/__init__.py`:
- Around line 890-895: The target-only diff branch renders the delete.sql
template without the DB connection, so qtIdent cannot properly quote the
qualified statistics name; update the render_template call that builds sql
(using self.template_path and self._DELETE_SQL) to pass conn=self.conn (i.e.,
render_template(..., name=..., schema=..., cascade=False, conn=self.conn)) so
the template can use the connection for quoting.
- Around line 422-435: Replace the ad-hoc comma split logic that builds
data['expressions'] from data['expression_list'] with a shared normalization
helper so complex expressions like "coalesce(a, b)" are preserved; create a
function (e.g. normalize_expressions) that takes the raw expression_list string,
parses/normalizes it into a list of {'expression': ...} entries (preserving
parentheses and function calls, trimming whitespace, and ignoring empty items)
and call this helper wherever the preview/build path currently handles
expression_list (the code that assigns data['expressions'] from
data['expression_list'] and the preview path that uses msql), removing any
split(',') usage and ensuring both creation and preview use the same normalized
output.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_add.py`:
- Around line 31-33: The setUp method in the test (function setUp) uses
BaseTestGenerator state before initializing it; modify setUp to call
super().setUp() as the first action so the base class initializer runs before
accessing self.test_data or other scenario/base attributes (i.e., add a call to
super().setUp() at the top of setUp in the TestStatisticsAdd test file).

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_delete.py`:
- Around line 129-134: The test only verifies deletion of self.statistics_name
when self.is_list is True, allowing self.statistics_name_2 to remain; update the
teardown/assertion to also verify that self.statistics_name_2 is deleted in
list-delete mode by calling statistics_utils.verify_statistics for
self.statistics_name_2 (in addition to self.statistics_name) and asserting the
response is None; modify the block that currently calls
statistics_utils.verify_statistics(self.server, self.db_name,
self.statistics_name) to perform the same verification for
self.statistics_name_2 when self.is_list is True.

In
`@web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/utils.py`:
- Around line 93-133: The helpers (create_table_for_statistics,
create_statistics, verify_statistics, get_statistics_id, delete_statistics,
get_statistics_columns) currently only close connections on the success path;
move the cleanup into a finally block: ensure any created cursor is closed, the
connection isolation level is restored to old_isolation_level if set, and the
connection is closed in finally even if exceptions occur; also ensure you only
call set_isolation_level and commit/rollback when connection is not None and
handle exceptions during commit by rolling back before closing to avoid leaking
backend sessions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 559c1b33-8f6b-404a-82fc-f369275fd60b

📥 Commits

Reviewing files that changed from the base of the PR and between ab59af0 and 25bb575.

⛔ Files ignored due to path filters (2)
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/static/img/coll-statistics.svg is excluded by !**/*.svg
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/static/img/statistics.svg is excluded by !**/*.svg
📒 Files selected for processing (32)
  • web/pgadmin/browser/server_groups/servers/databases/schemas/__init__.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/__init__.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/static/js/statistics.js
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/static/js/statistics.ui.js
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/create.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/properties.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/update.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/create.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/properties.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/update.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/backend_support.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/coll_stats.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/count.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/create.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/delete.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/get_oid.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/nodes.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/properties.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/stats.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/update.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/__init__.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/pg/14_plus/__init__.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/pg/__init__.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/statistics_test_data.json
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_add.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_delete.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_delete_multiple.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_get.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/test_statistics_put.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/utils.py
  • web/webpack.config.js
  • web/webpack.shim.js
✅ Files skipped from review due to trivial changes (14)
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/count.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/coll_stats.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/backend_support.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/get_oid.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/nodes.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/stats.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/create.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/create.sql
  • web/webpack.config.js
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/create.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/properties.sql
  • web/webpack.shim.js
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/16_plus/update.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/update.sql
🚧 Files skipped from review as they are similar to previous changes (7)
  • web/pgadmin/browser/server_groups/servers/databases/schemas/init.py
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/delete.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/update.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/default/properties.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/templates/statistics/sql/17_plus/properties.sql
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/static/js/statistics.ui.js
  • web/pgadmin/browser/server_groups/servers/databases/schemas/statistics/tests/statistics_test_data.json

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.

1 participant