PDOException: SQLSTATE[42000]: [Microsoft][SQL Server Native Client 10.0][SQL Server]Column 'menu_links.link_path' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.: SELECT parent.link_path AS parent_path, parent.menu_name AS menu_name, parent.menu_name AS _field_0 FROM {menu_links} parent INNER JOIN {menu_links} child ON parent.mlid = child.plid WHERE ( ([child].[link_path] = :db_condition_placeholder_0) ) GROUP BY parent.menu_name; Array ( [:db_condition_placeholder_0] => admin/modules ) in menu_CrumbsMultiPlugin_hierarchy->findParent() (line 31 of [...]\sites\all\modules\contrib\crumbs\plugins\crumbs.menu.inc).

Comments

donquixote’s picture

Ok, good luck fixing that :)
(i might look into it another day, but i use mysql, so maybe you want to help)

donquixote’s picture

Here is what the code wants to achieve:
If there are multiple hits, it should just pick the first it can find.
For numeric columnbs I could do a MAX, but for string fields?

Maybe in this case the GROUP BY is not needed at all. Still, some other situations made me paranoid, so I added the GROUP BY to prevent any duplicates.

Any idea?

------

For now I'd say we do it with PHP instead of mysql.
Remove the GROUP BY, and instead use PHP to pick the first element in an array.

Btw, this inspired me to explore some crazy way of picking the first element of an associative array.

    $candidates = array(
      'm1' => array(1 => array('m1a', 'm1b'), 3 => array('m1d', 'm1e')),
      'm2' => array(1 => array('m2a', 'm2b'), 3 => array('m2d', 'm2e')),
    );
    foreach ($candidates as $menu_name => &$menu_candidates) {
      ksort($menu_candidates);
      // pick the first array value, two times.
      foreach ($menu_candidates as $menu_candidates) {break;}
      foreach ($menu_candidates as $menu_candidates) {break;}
    }
    dpm($candidates);

Result:

array('m1' => 'm1a', 'm2' => 'm2a')

Crazy nice, isn't it?

Yes, there are other ways to pick the first element of an associative array. If you have some nice suggestion, let me know.
I just read that reset() is not reliable, http://www.php.net/manual/de/function.reset.php#96090

---------------

Now, applying that to menu_CrumbsMultiPlugin_hierarchy::findParent()

  function findParent($path, $item) {
    $q = db_select('menu_links', 'parent');
    $q->innerJoin('menu_links', 'child', 'parent.mlid = child.plid');
    $q->addExpression('parent.link_path', 'parent_path');
    $q->addExpression('parent.menu_name', 'menu_name');
    $q->addExpression('parent.depth', 'depth');
    $q->condition('child.link_path', $path);
    // If we'd use both GROUP BY and parent.link_path, sqlsrv would complain,
    // because it would not know which row's link path to return in case of
    // duplicate.
    // There is no useful aggregate function for strings, unfortunately.
    // $q->groupBy('parent.menu_name');
    $candidates = array();
    foreach ($q->execute() as $row) {
      $candidates[$row->menu_name][$row->depth][] = $row->parent_path;
    }
    foreach ($candidates as &$menu_candidates) {
      ksort($menu_candidates);
      // pick the first array value, two times.
      // $menu_candidates is already a reference, so here we use it without '&'.
      foreach ($menu_candidates as $menu_candidates) break;
      foreach ($menu_candidates as $menu_candidates) break;
    }
    return $candidates;
  }

Anyone willing to test this?
(not in patch mood today)

donquixote’s picture

Status: Active » Fixed

This should be fixed now.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

donquixote’s picture

Status: Closed (fixed) » Needs work

The "solution" here is ugly and awkward.
Let's do something equivalent to #1788214-4: Crumbs compatibility issue with PostgreSQL instead.

donquixote’s picture

Status: Needs work » Needs review
StatusFileSize
new1.83 KB

Here is a patch to make this look nicer.

bojanz’s picture

Status: Needs review » Reviewed & tested by the community

Looks good.

donquixote’s picture

Status: Reviewed & tested by the community » Fixed

The awkward code is history :)

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.