Skip to content

Comments: Allow WP_Comment_Query fields to project arbitrary columns#203

Closed
dd32 wants to merge 1 commit into
trunkfrom
65313-comment-query-fields-projections
Closed

Comments: Allow WP_Comment_Query fields to project arbitrary columns#203
dd32 wants to merge 1 commit into
trunkfrom
65313-comment-query-fields-projections

Conversation

@dd32
Copy link
Copy Markdown
Owner

@dd32 dd32 commented May 22, 2026

Summary

  • Extends WP_Comment_Query's fields argument to accept any column of $wpdb->comments (single string) or an array of columns, mirroring the flexibility of WP_User_Query.
  • Projections apply DISTINCT so the common array_unique( wp_list_pluck( ... ) ) pattern collapses to a single 'fields' => 'comment_post_ID' query.
  • 'ids' and '' (default) keep their existing semantics — the change is purely additive.

Implements Trac #65313.

Why

Plugins that want "give me the distinct comment_post_IDs matching X" currently have three options, none good:

  1. fields => '' + array_column( $q->comments, 'comment_post_ID' ) — hydrates every comment object just to throw all but one field away.
  2. fields => 'ids' + get_comment( $id )->comment_post_ID in a loop — N+1 cache lookups.
  3. Drop to raw SQL — bypasses filters, caching, and meta-query.

In the gp-translation-helpers reference case, hydrating ~32K comments to extract distinct post IDs took ~6.6s; the equivalent raw SQL returned the same 25,694 IDs in ~610ms (~11× speedup, all of it from skipping hydration).

API

// Returns an array of distinct post IDs (no array_unique needed):
$post_ids = ( new WP_Comment_Query() )->query( array(
    'meta_key'   => 'locale',
    'meta_value' => 'nl',
    'user_id'    => 42,
    'fields'     => 'comment_post_ID',
) );

// Multi-column projection returns an array of stdClass rows:
$rows = ( new WP_Comment_Query() )->query( array(
    'fields' => array( 'comment_ID', 'comment_post_ID', 'comment_date' ),
) );

Column names must be passed in exact case. The only exception is the ID segment of comment_ID / comment_post_ID, which accepts any case (comment_id, comment_Id, comment_ID).

Unknown column names fall through silently to the default behaviour (WP_Comment objects), to keep the path forward-compatible.

Test plan

  • npm run test:php -- tests/phpunit/tests/comment/query.php — 165 tests / 487 assertions pass (no regressions).
  • npm run test:php -- --group comment — 539 tests / 1365 assertions pass.
  • New tests in tests/phpunit/tests/comment/query.php cover:
    • Single-column projection returns distinct values
    • Single-column projection with a custom column + filters
    • Case-flexibility of the ID suffix; strict case for non-ID columns
    • Multi-column projection returns stdClass[] with DISTINCT applied
    • Unknown column falls back to full WP_Comment objects
    • 'ids' semantics unchanged (still returns int[])
    • Empty result sets return array() without a follow-up query

🤖 Generated with Claude Code

@github-actions
Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props dd32.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Extends the `fields` argument of `WP_Comment_Query` to accept:

  - a column name from the `$wpdb->comments` table (e.g.
    `'comment_post_ID'`) — returns a flat array of distinct values for
    that column.
  - a `'col_a=>col_b'` pair (e.g. `'comment_ID=>comment_post_ID'`) —
    returns an associative array keyed by col_a's value with col_b's
    value as the entry, mirroring `WP_Query` / `WP_Term_Query`'s
    `'id=>parent'` idiom.

The motivation is to avoid hydrating full `WP_Comment` objects when the
caller only needs one column. In one reference case (gp-translation-
helpers), hydrating ~32K comments to extract distinct post IDs took
~6.6s; the equivalent raw SQL took ~610ms (~11x), all of it from
skipping hydration.

Single-column results apply `DISTINCT` so callers can drop the common
`array_unique( wp_list_pluck( ... ) )` wrapping.

Column names must be passed in their exact case; the only exception is
the `ID` suffix of `comment_ID` / `comment_post_ID`, which is accepted
in any case (e.g. `'comment_post_id'`).

`'ids'` and `''` retain their existing meaning; the new behaviour is
purely additive.

Props dd32.
See #65313.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dd32
Copy link
Copy Markdown
Owner Author

dd32 commented May 22, 2026

Re-filing on WordPress/wordpress-develop per ticket workflow. See follow-up PR.

@dd32 dd32 force-pushed the 65313-comment-query-fields-projections branch from 087c972 to 9115f83 Compare May 22, 2026 05:44
@dd32 dd32 closed this May 22, 2026
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