Don't seem to be able to set Inner Join in hook_views_data

New Zeal - November 6, 2009 - 06:57
Project:Views
Version:6.x-2.7
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:won't fix
Description

Hi,

I know that user.views.inc and other modules use format such as this

    'node' => array(
      'left_field' => 'uid',
      'field' => 'uid',
      'type' => 'INNER', // all nodes have an author.
    ),

I tried the same format for a privatemsg filter:

    'pm_node' => array(
      'left_field' => 'thread_id',
      'field' => 'thread_id',
  'type' => 'INNER',
    ),
    'node' => array(
      'left_table' => 'pm_node',
      'left_field' => 'thread_id',
      'field' => 'thread_id',
  'type' => 'INNER',
    ),

but the join consistently remained LEFT JOIN. I did some debug messages and in the join() function (line 1237 of handlers.inc) the join object is as follows:
    [join] => views_join Object
        (
            [definition] => Array
                (
                    [left_field] => nid
                    [field] => nid
                    [type] => INNER
                    [table] => pm_node
                    [left_table] => node
                )

            [extra_type] => AND
            [table] => pm_node
            [left_table] => node
            [left_field] => nid
            [field] => nid
            [type] => LEFT
            [adjusted] => 1
        )

As you can see the definition array has type = INNER while at the next level type = LEFT. In order to achieve our immediate needs I have hacked the join function with a line at the start of the function (line 1238):
if(isset($table['join']->definition['type'])) $this->type = $table['join']->definition['type'];

I can only assume I am doing something wrong in the construction of hook_views_data(), otherwise there might be some bug in this part of Views in some use cases.

#1

dereine - November 6, 2009 - 07:43

Wow someone with a really good question :) Thx.

Could you upload or link the code, so it is easier to find out whether you are doing something wrong, or find out the bug. Sry which file did you hacked :)

    'pm_node' => array(
      'left_field' => 'thread_id',
      'field' => 'thread_id',
      'type' => 'INNER',
    ),
    // you define the same join twice? Why not use just the first one.
    'node' => array(
      'left_table' => 'pm_node',
      'left_field' => 'thread_id',
      'field' => 'thread_id',
      'type' => 'INNER',
    ),

See my inline comment

#2

New Zeal - November 6, 2009 - 21:14

Hi,

Thanks for the quick response. Attached is the .views.inc file (renamed .views.txt).

I note your comment, but we are joining two tables so we need two inner joins. I should have included more code. The attached file will make that clearer.

AttachmentSize
webble.views_.txt 3.51 KB

#3

merlinofchaos - November 6, 2009 - 21:29

Are you sure you marked the correct version? You mention that the join() function is at line 1237 of handlers.inc but in 2.7 it is at line 1242 -- that 5 line discrepancy could be nothing, or it could be important.

Also, in the construct method of the views_join object:

<?php
      $this
->type = !empty($this->definition['type']) ? strtoupper($this->definition['type']) : 'LEFT';
?>

I see absolutely no reason that line of code would not be triggered. You should try to debug that and see if you can tell why it is not happening.

#4

merlinofchaos - November 6, 2009 - 21:34

A couple of additional comments about this .views.inc file:

<?php
   
'pm_node' => array(
     
'left_field' => 'thread_id',
     
'field' => 'thread_id',
     
'type' => 'INNER',
    ),

?>

You define joins to the pm_node table as though pm_node were a base table. Unless you want to do interesting things with relationships, this is unnecessary. I would recommend removing this code unless you're sure you want it.

<?php
  $data
['node']['uid_quote'] = array(
   
'real field' => 'uid',
   
'title' => t('Current User Quotes'),
   
'help' => t('Filter the view to the currently logged in user\'s quotes.'),
   
'filter' => array(
     
'handler' => 'webble_handler_filter_quote',
     
'type' => 'yes-no',
    ),
   
/*
    'sort' => array(
      'handler' => 'webble_handler_sort_quote',
      */
   
);
?>

This won't work. YOu cannot modify existing tables via hook_views_data(), which is only for adding tables that your module owns. Instead, use hook_views_data_alter() to modify tables defined by other modules.

#5

New Zeal - November 6, 2009 - 22:07

Thanks merlinofchaos,

This is definitely 2.7. I downloaded it yesterday and I keep all versions in their original directories.

I tested this line of code and it is triggered and $this->type correctly takes the value 'INNER'

    $this->type = !empty($this->definition['type']) ? strtoupper($this->definition['type']) : 'LEFT';

#6

merlinofchaos - November 6, 2009 - 22:11

So that means that somewhere *between* $this->type being correctly set to "INNER" and ::join() being invoked, it is getting overwritten, it sounds like. I'm not even sure what to suggest next.

#7

New Zeal - November 6, 2009 - 22:50

Thanks, again, merlinofchaos,

My mistake. Yes, this is all that is needed. Tested and still doing the same thing.

$data['pm_index']['table']['join'] = array(
    'node' => array(
      'left_table' => 'pm_node',
      'left_field' => 'thread_id',
      'field' => 'thread_id',
     'type' => 'INNER',
    ),
  );

Regarding $data['node']['uid_quote']: That does actually work, but I have taken your suggestion and turned it into a hook_views_data_alter

So, anyway, at the end of the construct() function $this->type correctly has the value 'INNER', but somewhere it is being overwritten. I'll just keep the hack in place and keep a note of it. It is certainly obvious when it is not working.

#8

New Zeal - November 8, 2009 - 22:42
Status:active» won't fix

My apologies, I should have clicked onto this sooner: I am using one other Views Module: Views Or, and as you would guess, this is the module that is changing the Join back to Left. I have posted an issue on that module page and maybe eventually we will have a solution.

Meantime thank-you very much for your time and all the best.

I've changed the status of this thread to won't fix to get it out of your way. I hope that's the right choice.

#9

merlinofchaos - November 9, 2009 - 20:26

Just letting you know that won't fix, fixed or closed all would work just fine.

 
 

Drupal is a registered trademark of Dries Buytaert.