Well, this one should be easy to replicate :-) i have checked the queue and nobody seems to have reported this yet, my apologies if there is already an issue open for this.

1) create a CCK text field with a list of "allowed values", where some are just words, but others contain spaces or dashes

2) create a View with an exposed filter on that field, and tell it to do an "is all of" matching.

3) in the view preview, try to match on one or more values that are single words. no problem. now, try matching on one or more where at least one contains a space or dash. you will get an SQL error something like the following:

user warning: 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 '-Dynamics ON node.vid = node_data_field_host_features_Bio-Dynamics.vid AND node_' at line 12 query: SELECT node.nid AS nid, node.title AS node_title, node_data_field_host_picture_1.field_host_picture_1_fid AS node_data_field_host_picture_1_field_host_picture_1_fid, node_data_field_host_picture_1.field_host_picture_1_list AS node_data_field_host_picture_1_field_host_picture_1_list, node_data_field_host_picture_1.field_host_picture_1_data AS node_data_field_host_picture_1_field_host_picture_1_data, node_data_field_host_picture_1.nid AS node_data_field_host_picture_1_nid, node.type AS node_type, node_data_field_host_picture_1.field_host_email_1_value AS node_data_field_host_picture_1_field_host_email_1_value, node.vid AS node_vid, node_data_field_host_picture_1.field_host_website_value AS node_data_field_host_picture_1_field_host_website_value FROM node node INNER JOIN content_field_host_features node_data_field_host_features_Bio-Dynamics ON node.vid = node_data_field_host_features_Bio-Dynamics.vid AND node_data_field_host_features_Bio-Dynamics.field_host_features_value = 'Bio-Dynamics' INNER JOIN content_field_host_features node_data_field_host_features_culinary herbs ON node.vid = node_data_field_host_features_culinary herbs.vid AND node_data_field_host_features_culinary herbs.field_host_features_value = 'culinary herbs' LEFT JOIN content_type_profile_host node_data_field_host_picture_1 ON node.vid = node_data_field_host_picture_1.vid WHERE (node.type in ('profile_host')) AND (node_data_field_host_features_Bio-Dynamics.field_host_features_value = 'Bio-Dynamics' AND node_data_field_host_features_culinary herbs.field_host_features_value = 'culinary herbs') LIMIT 0, 10 in /home/www/wwoof.ca/htdocs/sites/all/modules/views/includes/view.inc on line 723.

seems pretty obvious to me what is happening here... the values "Bio-Dynamics" and "culinary herbs" don't cause problems when they are in single quotes (eg: "field_host_features_value = 'Bio-Dynamics' ") but when they are used to create temporary table aliases (eg: "JOIN content_field_host_features node_data_field_host_features_Bio-Dynamics ON node.vid = node_data_field_host_features_Bio-Dynamics.vid") they should have their spaces, dashes etc. converted to underscores first!

i hope this can be fixed quickly!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

KarenS’s picture

Project: Views (for Drupal 7) » Content Construction Kit (CCK)
Version: 6.x-2.1 » 6.x-2.x-dev
Component: Code » General
Status: Active » Closed (duplicate)

This is a CCK issue which has already been reported multiple times on the CCK issue queue. I can't replicate it the problem, but follow up there, not in Views.

yched’s picture

Component: General » Views Integration
Status: Closed (duplicate) » Active

The duplicate issue is #278832: SQL error on view matching text field whose allowed values includes a blank, marked as closed since then, for lack of information.
Maybe there are others, I can't find then right now. Let's keep this one open - AAMOF I can reproduce.

- setup a text field with allowed values having a space in them
- setup a view with a filter on that text field : 'is one of' + some of the values with a space + check 'Reduce duplicates'

The query contains table aliases based on the selected values, without replacing the spaces.
I'm not sure what happens if the allowed values use non-european characters

Combinations that trigger the bug :
'is one of' + 'Reduce duplicates'
'is all of', with or without 'Reduce duplicates'

Investigating.

yched’s picture

Project: Content Construction Kit (CCK) » Views (for Drupal 7)
Component: Views Integration » Views Data
Status: Active » Needs review
FileSize
871 bytes

Bumping back to Views. CCK has no action on the aliases that get generated from the values in views_many_to_one_helper::ensure_my_table()

Attached patch is a naive fix, that simply handles the case of whitespaces. The actual set of chars to filter is probably much larger, and I'm not sure of the best way to handle this.
- The incoming values can contain virtually any unicode char. They can be non-european chars only.
- we risk generating clashing aliases.

Maybe the aliases should simply be generated with numerical indexes instead of derived from the values strings ?

yched’s picture

"Maybe the aliases should simply be generated with numerical indexes instead of derived from the values strings ?"
New patch does that.

earthangelconsulting’s picture

wow, that was fast! thanks so much yched, i applied the patch from #4, problem solved!

this community rocks!

yched’s picture

Actually, that might not be enough to avoid alias clashes if the view has several instances of the same filter.
Then again, I'm not sure how other handlers take care of this, At any rate, the patch in #4 is better than the current code on this regard.

merlinofchaos’s picture

Status: Needs review » Fixed

I fixed this by running the value through a preg replace which makes sure it contains nothing unsafe. It needs to remain as close to unique as possible so that the same value added later won't pollute the query.

yched’s picture

Status: Fixed » Active

Still broken :
- You probably meant '_' instead of '-', which raises the same errors as before.
- Doesn't work if 2 values are non-az strings of the same length, since they will both generate the same alias and only one instance gets joined. I'm thinking of non-european languages.

merlinofchaos’s picture

I don't think there's a solution for the non-az languages.

Is there any way we can add restrictions to make stuff that's actually meant to be used as database keys sorta database safe?

yched’s picture

Status: Active » Needs review
FileSize
1.43 KB

Merlinofchaos: here's a new attempt at integer-based aliases, persistent across multiple invocations of the filter / argument in the view.
Seems to work alright from my tests, but it's also quite possible that I missed some test cases, and / or that I got your explanations totally wrong...

merlinofchaos’s picture

Status: Needs review » Fixed

Committed. It looks good. Let's see if dev breaks.

Anonymous’s picture

Status: Fixed » Closed (fixed)

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