After installing Permissions Grid, attempting to display the permissions form (/admin/people/permissions) results in this error:

PDOException: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "" LINE 4: WHERE (rid = '') ^: SELECT r.* FROM {role} r WHERE (rid = :db_condition_placeholder_0) ; Array ( [:db_condition_placeholder_0] => ) in user_role_load() (line 2912 of /home/profilees/public_html/modules/user/user.module).

It appears that user_role_load is being called with a $rid of an empty string. PostgreSQL won't do an integer = string comparison. I'm not yet sure where this is coming from.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Ben Coleman’s picture

I've been trying to dig into this. I put a ddebug_backtrace into user_role_load. The results of the backtrace:

18: user_role_load() (Array, 2 elements)
file (String, 29 characters ) modules/user/user.module:2911
args (Array, 1 element)
0 (String, 0 characters )
17: _menu_load_objects() (Array, 2 elements)
file (String, 21 characters ) includes/menu.inc:593
args (Array, 2 elements)
0 (Array, 23 elements)
path (String, 31 characters ) admin/people/permissions/grid/%
load_functions (String, 32 characters ) a:1:{i:4;s:14:"user_role_load";}
to_arg_functions (String, 0 characters )
access_callback (String, 11 characters ) user_access | (Callback) user_access();
access_arguments (String, 40 characters ) a:1:{i:0;s:22:"administer permissions";}
page_callback (String, 15 characters ) drupal_get_form | (Callback) drupal_get_form();
page_arguments (String, 70 characters ) a:2:{i:0;s:44:"permissions_grid_admin_node_perm...
delivery_callback (String, 0 characters )
fit (String, 2 characters ) 30
number_parts (String, 1 characters ) 5
context (String, 1 characters ) 1
tab_parent (String, 29 characters ) admin/people/permissions/grid
tab_root (String, 12 characters ) admin/people
title (String, 16 characters ) Permissions grid
title_callback (String, 1 characters ) t | (Callback) t();
title_arguments (String, 0 characters )
theme_callback (String, 0 characters )
theme_arguments (String, 6 characters ) a:0:{}
type (String, 3 characters ) 132
description (String, 29 characters ) Manage permissions for nodes.
position (String, 0 characters )
weight (String, 2 characters ) -7
include_file (String, 60 characters ) sites/all/modules/permission_grid/permissions_g...
1 (Array, 3 elements)
0 (String, 5 characters ) admin
1 (String, 6 characters ) people
2 (String, 11 characters ) permissions
16: _menu_translate() (Array, 2 elements)
file (String, 21 characters ) includes/menu.inc:761
args (Array, 3 elements)
0 (Array, 24 elements)
∞ (Recursion)
1 (Array, 3 elements)
0 (String, 5 characters ) admin
1 (String, 6 characters ) people
2 (String, 11 characters ) permissions
2 (Boolean) TRUE
15: menu_local_tasks() (Array, 2 elements)
file (String, 22 characters ) includes/menu.inc:1942
args (Array, 0 elements)
14: menu_tab_root_path() (Array, 2 elements)
file (String, 22 characters ) includes/menu.inc:2246
args (Array, 0 elements)
13: menu_get_active_help() (Array, 2 elements)
file (String, 22 characters ) includes/menu.inc:1710
args (Array, 0 elements)
12: system_block_view() (Array, 2 elements)
file (String, 33 characters ) modules/system/system.module:2087
args (Array, 1 element)
0 (String, 4 characters ) help
11: call_user_func_array() (Array, 1 element)
args (Array, 2 elements)
0 (String, 17 characters ) system_block_view | (Callback) system_block_view();
1 (Array, 1 element)
2 (String, 4 characters ) help
10: module_invoke() (Array, 2 elements)
file (String, 23 characters ) includes/module.inc:866
args (Array, 3 elements)
0 (String, 6 characters ) system | (Callback) system();
1 (String, 10 characters ) block_view
2 (String, 4 characters ) help
 9: _block_render_blocks() (Array, 2 elements)
file (String, 30 characters ) modules/block/block.module:881
args (Array, 1 element)
0 (Array, 1 element)
 8: block_list() (Array, 2 elements)
file (String, 30 characters ) modules/block/block.module:674
args (Array, 1 element)
 7: block_get_blocks_by_region() (Array, 2 elements)
file (String, 30 characters ) modules/block/block.module:318
args (Array, 1 element)
 6: block_page_build() (Array, 2 elements)
file (String, 30 characters ) modules/block/block.module:268
args (Array, 1 element)

Looks like the problem is in permissions_grid.admin.inc, but I haven't been able to figure out what yet.

joachim’s picture

I don't see how code in permissions_grid.admin.inc could be breaking the core permissions form. This module doesn't alter that form.

Ben Coleman’s picture

From the backtrace, it doesn't look like it's happening in the form, but in menu code. From what I read of the backtrace, the last 'public' function called is menu_local_tasks (numbered 15 in the backtrace). The internal function _menu_load_object (numbered 17 in the backtrace) is being called with the $item argument an array decidedly pointing to permission_grid (include_file contains 'sites/all/modules/permission_grid/permissions_grid.admin.inc', path contains 'admin/people/permissions/grid/%', you can see plenty more in the traceback above).

For testing purposes, I created a new Drupal site, using PostgreSQL, and added only the Permissions Grid module, everything else just the standard Drupal install. Once that was done, just clicking on the People button in the task bar produced the error in the Issue Summary.

MySQL doesn't produce an error on this, because if you pass compare a string to a numeric field, MySQL will silently convert the string to a number. PostgreSQL and other databases are more picky. If you don't have access to PostgreSQL and want to reproduce the backtrace I have above, add these lines (temporarily, for testing purposes):

  if ($rid == '') {
    ddebug_backtrace();
  }

to the beginning of the user_role_load function in module/user/user.module, and then select the People link in the task bar. You'll get the same backtrace I put in comment #1 (except it will probably be easier to read), you just won't get the error I get on PostgreSQL). I did build a test MySQL-based Drupal site here, with Permissions Menu installed, and I get the backtrace. Note that $rid should be a number (being a Role Id number), so it being equal to an empty string is an error.

Ben Coleman’s picture

Title: Permission Grid trashes Permissions form » Permission Grid Causes People menu and its submenus to error out on PostgreSQL

A bit more digging. This appears to have something to do with the autoloader wildcard %user_role in the second menu entry in permission_grid_menu. Evidently, this gets processed somehow before the form is even called (actually, it gets processed for admin/people/permissions or any submenu, apparently as part of menu handling), even if there is no part of the url corresponding to the wildcard. In the latter case, an empty string is passed as the role id, and PostgreSQL complains. You haven't seen this because MySQL doesn't complain about being handed an empty string for a number.

joachim’s picture

This is because 'admin/people/permissions/grid/%user_role' is correctly having its tab_root set as 'admin/people/permissions'. And when you're there, menu_local_tasks() loads all tabs beneath the current menu item.

This is either:
- a bug in core, because _menu_translate() tries to load menu items it has no map items for
- a bug in core, because user_role_load() should allow for an empty $rid
- a bug in this module because I've misused tabs here (which I have to say is likely!)

While I have a think about this, you can fix the problem by removing the "'type' => MENU_LOCAL_TASK," from the 'admin/people/permissions/grid/%user_role' menu item.

adriancid’s picture

Issue summary: View changes

As @joachim says, it works changing your implementation of hook_menu in permission_grid.module to:

/**
 * Implements hook_menu().
 */
function permission_grid_menu() {
  $items['admin/people/permissions/grid'] = array(
    'title' => 'Permissions grid',
    'description' => 'Manage permissions for nodes.',
    'page callback' => 'permissions_grid_admin_roles',
    'access arguments' => array('administer permissions'),
    'file' => 'permissions_grid.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => -7,
  );
  $items['admin/people/permissions/grid/%user_role'] = array(
    'title' => 'Permissions grid',
    'description' => 'Manage permissions for nodes.',
    'page callback' => 'drupal_get_form',
    // todo calback should have 'form' suffix.
    'page arguments' => array('permissions_grid_admin_node_permissions_form', 4),
    'access arguments' => array('administer permissions'),
    'file' => 'permissions_grid.admin.inc',
    'weight' => -7,
  );

  return $items;
}
adriancid’s picture

Status: Active » Needs work
FileSize
450 bytes

Here is the patch

adriancid’s picture

Status: Needs work » Needs review