I can think of plenty of cases where the only significant characters in comparing two values are alphanumeric ones. Phone and credit card numbers, which can be embellished with optional brackets, dashes, and spaces, etc., are obvious examples.
Unfortunately MySQL (and I'm sure most other databases) don't have the regexp grunt to do those sorts of comparisons, so we will have to store our own converted values for any fields on which we want alphanumeric-only comparison, which will require our own table. This is overhead that has been so far avoided, but may help solve some other problems (eg. #333137: Case sensitivity (uppercase and lowercase should not be considered unique)), so isn't a wholly bad thing.
Also I think leveraging Transliteration module will make this (and possibly other) functionality more locale-tolerant, so I don't think it's a problematic (possibly optional) dependency for this feature.
Hope to get a working patch posted shortly. If anybody wants to chip in sooner, let me know and I'll set up a public git repo. I need this feature for a D6 site, but happy to provide a D7 patch if the maintainer agrees to commit.
Comments
Comment #1
Matthew Davidson commentedAs with case-sensitivity, it seems that treatment of accented characters is server-specific (at least with MySQL). With my server locale set to en_AU, MySQL considers 'cafe' equivalent to 'café'. Presumably if my server locale was set to French, this would not be the case, so although in my case the behaviour is as desired, it would be best to be explicit.
You can do a strict comparison on a per-query basis by adding 'collate utf8_bin' to the end of your SELECT query, but I don't know whether this works the same in PostgreSQL. If somebody can check this out for me, I'd be much obliged. In the meantime I'll make this functionality dependent on MySQL.
Comment #2
Matthew Davidson commentedOkay, so this has turned out to be a hairier yak than I originally thought.
It occurred to me that the most flexible way to tackle this would be to leverage filter formats. So we associate each unique field with a filter format (a default one is provided), which will - usually - be different to the one (if any) used to display the value of the field. This is configured in the CCK global field settings form fieldset (admin/content/node-type/[content_type]/fields/[field_type] - I just couldn't figure out the best place to put this for the node title field, so for the moment title values are stuck on the default unique field filter format). When the test for matching values is done we compare the new value as run through the filter format against our own stored values which have already been filtered.
I do not know how PostgreSQL works with unicode, so for the moment I've set this to only work with MySQL. I'd really appreciate input from PostgreSQL people.
This works far less efficiently than it might, often just dumping and recreating whole tables on configuration changes where it might in theory be possible to update some subset of the records. This may cause unnecessary problems with really big datasets; I don't know. I wanted to get some feedback as to whether this is a useful direction to pursue before putting a lot of effort into performance optimisation.
The default unique field filter provided converts all values to lower case, to in effect retain the existing (depending on your database collation configuration) behaviour. You can remove that filter from the default format (or create another format without that filter and set your desired field to use that) to get case-sensitivity. You could also install the Filter Transliteration module and enable that filter if you want 'cafe' to match 'café'. Go crazy. There are lots of modules that provide filters out there, and writing your own is pretty trivial.
Please test away. The patch below is against the latest commit on the 6.x-1.x branch.
Comment #3
Matthew Davidson commentedDamn, needs some code in the update hook to generate the db tables. In the meantime, disabling and re-enabling the module will have the same effect.
Comment #4
Matthew Davidson commentedAnd it spits the dummy when trying to create tables for email fields.
Comment #5
Matthew Davidson commentedThis patch appears to fix the issues above. Review appreciated.
Comment #6
Matthew Davidson commentedRerolled to fix a minor bug and add needed database table creation code in upgrade function.
Comment #7
Matthew Davidson commentedYet another minor modification to refresh stored values when field filter configuration is changed.
Comment #8
Matthew Davidson commentedNode titles are 255 bytes long, not 12. D'oh!
Comment #9
astonvictor commentedI'm closing it because the issue was created a long time ago without any further steps.
if you still need it then raise a new one.
thanks