Representative Node Views fails due to invalid SQL

Created on 21 November 2014, over 9 years ago
Updated 20 May 2024, about 1 month ago

The Taxonomy and User Representative Node (GroupwiseMax) using a RepresentativeView does not work because the existing code generates SQLSTATE[42000]: Syntax error or access violation and SQLSTATE[HY093]: Invalid parameter number: no parameters were bound.

To reproduce:

  1. Install Drupal 8.
  2. Edit the "People" View.
  3. Add a Representative Node Relationship.
  4. Select content View as the Representative view.
  5. Click Apply (All Displays).
  6. You'll see the error below in the Preview section

Result:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '***CURRENT_USER*** AND ***CURRENT_USER*** <> 0 AND ***VIEW_OWN_UNPUBLISHED_NODES' at line 3: SELECT COUNT(*) AS expression FROM (SELECT 1 AS expression FROM {users_field_data} users_field_data LEFT JOIN {node_field_data} node_field_data_users_field_data ON (SELECT node_field_dataINNER.nid AS nidINNER FROM {node_field_data} node_field_dataINNER INNER JOIN {users_field_data} users_field_data_node_field_dataINNER ON "node_field_dataINNER".uid = "users_field_data_node_field_dataINNER".uid LEFT JOIN {users_field_data} users_field_data_node_field_data_1INNER ON "node_field_dataINNER".uid = "users_field_data_node_field_data_1INNER".uid WHERE (("users_field_data_node_field_data_1INNER".uid = users_field_data.uid )) AND (("node_field_dataINNER".status = "1 OR (node_field_dataINNER".uid = ***CURRENT_USER*** AND ***CURRENT_USER*** <> 0 AND ***VIEW_OWN_UNPUBLISHED_NODES*** = 1) OR ***BYPASS_NODE_ACCESS*** = 1)) ORDER BY node_field_dataINNER.changed DESC LIMIT 1 OFFSET 0) = node_field_data_users_field_data.nid WHERE (users_field_data.default_langcode = :db_condition_placeholder_0) AND (users_field_data.uid != :db_condition_placeholder_1)) subquery; Array ( [:db_condition_placeholder_0] => 1 [:db_condition_placeholder_1] => 0 )

Apply this patch, clear the cache, and refresh the View edit page to see it work. Add a node if you want to see it get data.

Tests are needed for this and it seems GroupwiseMax in general (without the Representative View.) Maybe additional discussion is needed? Maybe there is a better way to replace the **CORRELATED** placeholder? Maybe tests should be a different issue?

This issue also exists in Views for Drupal 7. I created the patch for D7 Views over a year ago here: https://www.drupal.org/node/1417090 β†’ #35 with a recent update in #53. The patch in #35 has ~10 RTBC's.

πŸ› Bug report
Status

Needs work

Version

11.0 πŸ”₯

Component
ViewsΒ  β†’

Last updated 43 minutes ago

Created by

πŸ‡ΊπŸ‡ΈUnited States 13rac1

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

  • VDC

    Related to the Views in Drupal Core initiative.

Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States neclimdul Houston, TX

    blind 10.1 reroll. conflict was just a block in the GroupWiseMax and and it was breaking with the str_contains changes so the patch doesn't have an interdiff because the patch uses preg instead of the str_contains logic.

  • πŸ‡ͺπŸ‡ΈSpain Carlos Romero

    Carlos Romero β†’ made their first commit to this issue’s fork.

  • Pipeline finished with Failed
    5 months ago
    Total: 194s
    #83632
  • Pipeline finished with Failed
    5 months ago
    Total: 296s
    #83645
  • Pipeline finished with Failed
    5 months ago
    Total: 462s
    #83644
  • Pipeline finished with Failed
    5 months ago
    Total: 156s
    #83646
  • Pipeline finished with Failed
    5 months ago
    Total: 240s
    #83649
  • Pipeline finished with Failed
    5 months ago
    Total: 188s
    #83704
  • πŸ‡ΊπŸ‡ΈUnited States euk

    Not entirely sure where the problem stems from, but the latest patch has these lines (line#303 in the file after patching):

    +      // Replace the **CORRELATED** placeholder with the outer field name.
    +      if ($val === '**CORRELATED**') {
    +        $quoted[$key] = $this->definition['outer field'];
    +      }
    

    It appears that the outer field definition is just a plain table name with column, and not a properly aliased reference. This essentially results in an error such as the column is not found. Example (see the line I singled out):

    SELECT "section_association"."id"                            AS "id",
           "users_field_data_section_association__user_id"."uid" AS "users_field_data_section_association__user_id_uid",
           "node_field_data_users_field_data"."nid"              AS "node_field_data_users_field_data_nid"
    FROM section_association "section_association"
    LEFT JOIN section_association__user_id "section_association__user_id"
    ON section_association.id = section_association__user_id.entity_id AND section_association__user_id.deleted = '0'
        INNER JOIN users_field_data "users_field_data_section_association__user_id" ON section_association__user_id.user_id_target_id = users_field_data_section_association__user_id.uid
        INNER JOIN node_field_data "node_field_data_users_field_data" ON (SELECT "node_field_data_reps"."nid" AS "nid_reps"
        FROM
        node_field_data "node_field_data_reps"
        LEFT JOIN users_field_data "users_field_data_node_field_data_reps" ON "node_field_data_reps".uid = "users_field_data_node_field_data_reps".uid
    
        WHERE ("users_field_data_node_field_data_reps".uid = users_field_data.uid)      
                                                                # ^^^, should be "node_field_data_users_field_data"."uid"
    
        ORDER BY "node_field_data_reps"."changed" DESC
        LIMIT 1 OFFSET 0) = node_field_data_users_field_data.nid
    WHERE ("section_association"."access_scheme" IN ('section'))
      AND ("users_field_data_section_association__user_id"."uid"
        > '1')
    

    In the code, replacing $quoted[$key] = $this->definition['outer field']; with $quoted[$key] = $this->relationship . "." . $this->definition['relationship field']; solves the issue.

    Frankly I don't know if that is the proper way of generating the correct aliased reference, and am not sure if there are any implications to this approach. But it solves my issue.

  • πŸ‡ΊπŸ‡ΈUnited States euk

    Adding a patch with the correction from the previous comment

  • last update about 2 months ago
    Custom Commands Failed
  • πŸ‡ΊπŸ‡ΈUnited States Kasey_MK

    The patch in #71 (as well as the diff from MR 6352) both result in a WSOD error for me (Drupal 10.2.6 PHP 8.2.18):

    Drupal\Core\Database\IntegrityConstraintViolationException: SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'tid' in where clause is ambiguous: SELECT "node_field_data_taxonomy_term_field_data"."title" AS "node_field_data_taxonomy_term_field_data_title", "node_field_data_taxonomy_term_field_data"."created" AS "node_field_data_taxonomy_term_field_data_created", "node_field_data_taxonomy_term_field_data"."uid" AS "node_field_data_taxonomy_term_field_data_uid", "taxonomy_term_field_data"."weight" AS "taxonomy_term_field_data_weight", COUNT(field_discussion_taxonomy_term_field_data.nid) AS "field_discussion_taxonomy_term_field_data_nid", SUM(field_discussion_taxonomy_term_field_data__comment_entity_statistics.comment_count) AS "field_discussion_taxonomy_term_field_data__comment_entity_st", MIN(taxonomy_term_field_data.tid) AS "tid", MIN(field_discussion_taxonomy_term_field_data.nid) AS "field_discussion_taxonomy_term_field_data_nid_1", MIN(node_field_data_taxonomy_term_field_data.nid) AS "node_field_data_taxonomy_term_field_data_nid" FROM "taxonomy_term_field_data" "taxonomy_term_field_data" LEFT JOIN "node__field_discussion" "node__field_discussion" ON taxonomy_term_field_data.tid = node__field_discussion.field_discussion_target_id AND node__field_discussion.deleted = :views_join_condition_0 LEFT JOIN "node_field_data" "field_discussion_taxonomy_term_field_data" ON node__field_discussion.entity_id = field_discussion_taxonomy_term_field_data.nid LEFT JOIN "node_field_data" "node_field_data_taxonomy_term_field_data" ON (SELECT "node_field_dataINNER"."nid" AS "nidINNER" FROM "node_field_data" "node_field_dataINNER" LEFT JOIN "taxonomy_index" "taxonomy_indexINNER" ON "node_field_dataINNER".nid = "taxonomy_indexINNER".nid LEFT JOIN "taxonomy_term_field_data" "taxonomy_term_field_data_node_field_dataINNER" ON "taxonomy_indexINNER".tid = "taxonomy_term_field_data_node_field_dataINNER".tid WHERE ("taxonomy_term_field_data_node_field_dataINNER".tid = "".tid) ORDER BY "node_field_dataINNER"."created" DESC LIMIT 1 OFFSET 0) = node_field_data_taxonomy_term_field_data.nid INNER JOIN (SELECT "tn"."nid" AS "nid" FROM "taxonomy_index" "tn" WHERE "tn"."tid" = :db_condition_placeholder_6 UNION SELECT "tn"."nid" AS "nid" FROM "taxonomy_index" "tn" INNER JOIN "taxonomy_term__parent" "th" ON "tn"."tid" = "th"."entity_id" INNER JOIN "taxonomy_term__parent" "th1" ON "th"."parent_target_id" = "th1"."entity_id" WHERE "th1"."entity_id" = :db_condition_placeholder_7) "taxonomy_index_depth" ON field_discussion_taxonomy_term_field_data.nid = taxonomy_index_depth.nid LEFT JOIN "taxonomy_term__field_path_prefix" "taxonomy_term__field_path_prefix" ON taxonomy_term_field_data.tid = taxonomy_term__field_path_prefix.entity_id AND taxonomy_term__field_path_prefix.deleted = :views_join_condition_1 AND (taxonomy_term__field_path_prefix.langcode = taxonomy_term_field_data.langcode OR taxonomy_term__field_path_prefix.bundle = :views_join_condition_3) LEFT JOIN "comment_entity_statistics" "field_discussion_taxonomy_term_field_data__comment_entity_statistics" ON field_discussion_taxonomy_term_field_data.nid = field_discussion_taxonomy_term_field_data__comment_entity_statistics.entity_id AND field_discussion_taxonomy_term_field_data__comment_entity_statistics.entity_type = :views_join_condition_4 WHERE ((field_discussion_taxonomy_term_field_data.status = 1 OR (field_discussion_taxonomy_term_field_data.uid = 20 AND 20 <> 0 AND 1 = 1) OR 1 = 1 OR 1 = 1)) AND ("field_discussion_taxonomy_term_field_data"."type" IN (:db_condition_placeholder_5)) GROUP BY "node_field_data_taxonomy_term_field_data_title", "node_field_data_taxonomy_term_field_data_created", "node_field_data_taxonomy_term_field_data_uid", "taxonomy_term_field_data_weight" ORDER BY "taxonomy_term_field_data_weight" ASC; Array ( [:db_condition_placeholder_5] => post [:views_join_condition_0] => 0 [:db_condition_placeholder_6] => 1083 [:db_condition_placeholder_7] => 1083 [:views_join_condition_1] => 0 [:views_join_condition_3] => brand [:views_join_condition_4] => node ) in Drupal\mysql\Driver\Database\mysql\ExceptionHandler->handleExecutionException() (line 45 of core/modules/mysql/src/Driver/Database/mysql/ExceptionHandler.php).

    The patch in #66 works for me (doesn't result in a WSOD anyway) but gives this warning:
    Deprecated function: Creation of dynamic property Drupal\views\Plugin\views\relationship\GroupwiseMax::$table_aliases is deprecated in Drupal\views\Plugin\views\relationship\GroupwiseMax->leftQuery() (line 253 of core/modules/views/src/Plugin/views/relationship/GroupwiseMax.php).

    This patch is just the one in #66 with this bit added:

    /**
    * The table aliases used by the subquery.
    */
    // phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName
    protected array $table_aliases;

    $tableAliases (as in the patch from #72) also works and meets the camelCase requirement, but for simplicity's sake I wanted to stay as close as possible to the patch that seems to work for us.

Production build 0.69.0 2024