It would be cool if the glossary view would be fixed.

Currently query::build_condition builds the condition. Therefore it uses QueryConditionInterface::condition to add the query.
Sadly this method does not support snippets as field.
Its suggested to use QueryConditionInterface::where

One possible solution would be to use a $operator 'where', or 'snippet' or something similar.

If this operator is set, in build_condition we could check for this operator and look for QueryConditionInterface::where

Any ideas about it?

Comments

dawehner’s picture

Status: Active » Needs review

Here is a first patch. I thought formula would be even better.

I'm not sure whether this is the best way to implement it, but it works at least

dawehner’s picture

StatusFileSize
new3 KB

Ups i forgot the attachment

dawehner’s picture

StatusFileSize
new2.77 KB
-    return "SUBSTR($this->table_alias.$this->real_field, 1, " . intval($this->options['limit']) . ")";
+    return "SUBSTRING($this->table_alias.$this->real_field, 1, " . intval($this->options['limit']) . ")";

I'm not sure about it, but i only found SUBSTRING as example in d7 core, so i guess this could be better.

+        dsm((string) $query);

Rerole

dawehner’s picture

StatusFileSize
new2.77 KB


WHERE (( (SUBSTRING(node.title, 1, 1)= :views_handler_argument_string) ))

This does not look like a good codestyle :)

PS: I'm not sure about the name of the placeholder here

dawehner’s picture

StatusFileSize
new1.82 KB

DamZ suggested to use a field + alias and a simple condition.

I tryed this, but the fieldalias do not to work here

PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'views_handler_argument_string_1' in 'where clause': SELECT COUNT(*) AS expression FROM (SELECT node.title AS node_title, node.nid AS nid, users.name AS users_name, users.uid AS users_uid, node.changed AS node_changed, SUBSTRING(node.title, 1, 1) AS views_handler_argument_string_1 FROM {node} node INNER JOIN {users} users ON node.uid = users.uid WHERE (( (views_handler_argument_string_1 = :db_condition_placeholder_0) )) ORDER BY node_title ASC) subquery; Array ( [:db_condition_placeholder_0] => a )  in views_plugin_pager->execute_count_query()  (line 141 of /var/www/vd7/sites/all/modules/views-DRUPAL-7--3/plugins/views_plugin_pager.inc).

Here is the code for this approach.

dawehner’s picture

Title: Fix glossary view » fix regression for query_default::build_condition

Since #769554: Trivial SQL injection(s) with SelectQuery every complex field, is broken

Examples are

Crell’s picture

For something like a SUBSTRING call, you want to be using ->where(), not ->condition(). That just wasn't properly enforced until the patch mentioned in #6 went in, when it became necessary for security to do so.

->where("SUBSTRING(node.title, :start, :length)", array(':start' => 1, ':length' => 1)) should work. (Or something like that.) Remember the placeholders for proper injection safety.

Also, don't worry about the excessive parentheses. The DB layer is very liberal with parenthesis so as to make sure it doesn't miss any and introduce subtle bugs. It shouldn't hurt anything.

karens’s picture

I've run into this now trying to do complex queries for Date and Calendar, would love to find a solution. The approach in #4 looks logical to me, I don't really understand #5. And I already saw in the dbtng documentation that we need ->where() instead of ->condition(), so I'm glad to see someone working on this solution.

karens’s picture

The patch above worked for me, but I tried to incorporate Crell's comments by making a simple change, which did not work. I just swapped in one more placeholder and added the placeholder to the args() array. This certainly looks like it should work but it blows up completely.

  function get_formula() {
    return "SUBSTRING($this->table_alias.$this->real_field, 1, :length)";
  }
    if ($formula) {
      $field .= ' = :views_handler_argument_string';
      $argument = array(
        ':length' => intval($this->options['limit']),
        ':views_handler_argument_string' => $argument,
      );
      $this->query->add_where(0, $field, $argument, 'formula');
    }
    else {
      $this->query->add_where(0, $field, $argument);
    }

After some analysis I think I see the problem. That formula is used in the WHERE clause but it is also used as a field, and my 'fix' changed a field with no placeholders into a field with placeholders. The current Views code does not know anything about placeholders in fields. The compile_fields() function checks for fields that are formulas and uses addExpression() on them, which is right, but there is no provision for passing placeholders to that function, which is also going to be necessary to support complex queries. I can tell you for sure that Date module has fields which are formulas and I'm sure there are others.

So we need to stretch this patch to provide a way to supply placeholders for formula fields that need them as well as take care of the formula in the WHERE clause.

webchick’s picture

Subscribing for now. Obviously, very interested in helping however I can from the Drupal core side to make Views work in D7. :)

karens’s picture

Title: fix regression for query_default::build_condition » Complex views no longer work
Category: feature » bug
Priority: Normal » Critical

Changing the title and marking this critical, since even some built-in views that used to work are now broken

karens’s picture

Category: bug » feature
Priority: Critical » Normal
StatusFileSize
new4.65 KB

So here's a stab at fixing both problems by using the $params in add_field to add a param for a 'placeholders' array. Then we just add that to ->addExpression(). This patch doesn't work, I get an error 'Unsupported operand types in ...views/plugins/views_plugin_query_default.inc on line 667' that I can't figure out, but I think the approach could work if someone can see what I did wrong.

karens’s picture

Category: feature » bug
Priority: Normal » Critical

Somehow I reverted the status when I added the patch.

dawehner’s picture

StatusFileSize
new5.79 KB

Oh this was a easy problem


+      $this->base_alias = $this->name_alias = $this->query->add_field(NULL, $formula, $this->field . '_truncated', NULL, $params);

This is just one additional parameter.
With this the glossary view works fine again, but the archive still does have problems.

karens’s picture

Yay! Yes, glossary is fixed with that. Now going to see if I can use this change to fix archive and date views.

karens’s picture

StatusFileSize
new5.65 KB

Here's a patch updated with a fix for the archive view. I haven't tried this on the Date module yet, but I think this is looking like a workable system.

karens’s picture

StatusFileSize
new5.67 KB

Actually made one small change, just for clarity in reading the code. When we change the argument to an array of placeholders, I changed the name of the variable to $placeholders rather than $argument.

aschiwi’s picture

Great! I have a working glossary and archive view with this patch. Can't see any errors or anything else that might have been broken along the way. Archive works with both page and block view.

dawehner’s picture

The code looks fine i think i will commit it.

Any reasons against it?

karens’s picture

I was going to be sure it would also work for Date but hopefully if I find other changes are needed you will help me get them committed as follow-on patches. This much at least gets some of the important core views working again and provides a method for other modules to do some more complex queries.

So I would say go ahead and commit it :)

karens’s picture

Status: Needs review » Reviewed & tested by the community

And it also gets rid of the error messages in the Date filter and arguments. They still have other things broken, but getting this much working right is huge. Now I can pass my complex date queries to Views and Views can handle them in a meaningful way.

dawehner’s picture

Status: Reviewed & tested by the community » Fixed

Thanks a million!

I tested it again and commited it

webchick’s picture

YAY!! Thank you so much, all! :D

aschiwi’s picture

I just noticed that comments_recent still seems to be "broken". I'm no good at writing patches for PHP code so here's just a report :)

aschiwi’s picture

Status: Fixed » Needs work

I guess this needs to be "needs work" then.

aschiwi’s picture

Did some more testing. Tracker view is fine, but taxonomy_term is not and I also cannot add a rather simple list of taxonomy terms without the PDOException: SQLSTATE[42S02]: Base table or view not found error message. "backlinks" View as well as "frontpage" seem to work just fine as well.

dawehner’s picture

Perhaps we should create new issues. This one is already quite full.

It's sadly known that taxonomy_term is not working at the moment, but what should i say taxonomy data structure in d7 is not perfect for views.
I don't think i will be able to fix this before drupalcon. I think the days on drupalcon should have 48hours.
#722454: Fix taxonomy integration

The node: status filter is currently broken because views query substitions does not work.
#812970: Get Views Query substitutions working

Did someone claimed that dbtng would help views?

I would suggest to mark this issue as fixed and create new small issues.

karens’s picture

I suspect we haven't uncovered a complete list of all the affected places. We need to start identifying them and then we can fix them. The core fix is still good and at least *some* of the views are working now.

aschiwi’s picture

Status: Needs work » Fixed

Okay, marking this as fixed. The only other thing I found concerned taxonomy and there's already an issue for it. Thanks guys.

Status: Fixed » Closed (fixed)

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