Search using "special" characters

I just noticed that in Lighttable - Collection filters - Search the “_” (underscore) character, when standing at the beginning or the end of the search text, is ignored.
Example: Searching for a sequence number “_3381” (without the double quotes) yields the same result as “3381”.

Is there anything known about this behaviour? Are there also some other “special” characters (apart from “%” wildcard character) behaving differently than normal search text?

I’m using darktable 4.4.2 under Windows 11 …

Hi @JankoK , most probably it is because in sqlite argot, underscore symbol is a wildcard character and means any single character.

I guess default escape character may be “\” then your search should be: “\_3381”

Regards!

Ji @rgo, thank you for your response. I was thinking along the same line, but unfortunately “\_3381” search is empty (i. e. nothing found) …
There must be either a different escape character or some other mechanism is at play, especially since the underscore character in the middle of the search string is accepted as a valid one …

I’m re-visiting this topic, as the behaviour of the search function is the same in darktable 5.01, running either under Windows 11 or Linux (I tested Mint Cinnamon 22.1)
Is there anything new known in this regard?
Is this normal behaviour? If yes, what is the logic behind it?

This behaviour is namely a bit awkward, when filtering file names, as the ‘_’ character is quite often used in many file names and paths. Is there a suitable workaround known?

I guess the usage of \_ does not work because the generated query does not have the optional clause ESCAPE.

Example of query generated after looking for \_DSC3138:

SELECT          Count(DISTINCT sel.id)
FROM            (
                       SELECT mi.id,
                              filename,
                              version,
                              datetime_taken
                       FROM   main.images AS mi
                       WHERE  (
                                     flags & 256) != 256
                       AND    (( (
                                                   film_id IN
                                                   (
                                                          SELECT id
                                                          FROM   main.film_rolls
                                                          WHERE  folder LIKE '/home/foobar')))
                              AND    ( (
                                                   1=1)
                                     AND    (
                                                   flags & 8 == 0
                                            AND    flags & 7 >= 1)
                                     AND    (
                                                   mi.id IN
                                                   (
                                                          SELECT id
                                                          FROM   main.meta_data
                                                          WHERE  value LIKE '%\_DSC3138%'
                                                          UNION
                                                          SELECT imgid              AS id
                                                          FROM   main.tagged_images AS ti,
                                                                 data.tags          AS t
                                                          WHERE  t.id=ti.tagid
                                                          AND    (
                                                                        t.NAME LIKE '%\_DSC3138%'
                                                                 OR     t.synonyms LIKE '%\_DSC3138%')
                                                          UNION
                                                          SELECT miu.id
                                                          FROM   main.images AS miu,
                                                                 main.makers AS mk,
                                                                 main.models AS md
                                                          WHERE  miu.maker_id = mk.id
                                                          AND    miu.model_id = md.id
                                                          AND    (
                                                                        filename LIKE '%\_DSC3138%'
                                                                 OR     mk.NAME LIKE '%\_DSC3138%'
                                                                 OR     md.NAME LIKE '%\_DSC3138%')
                                                          UNION
                                                          SELECT i.id
                                                          FROM   main.images     AS i,
                                                                 main.film_rolls AS fr
                                                          WHERE  fr.id=i.film_id
                                                          AND    fr.folder LIKE '%\_DSC3138%'))))) AS sel
LEFT OUTER JOIN main.color_labels                                                                  AS b
ON              sel.id = b.imgid
ORDER BY        color DESC,
                datetime_taken,
                filename,
                version ASC limit ?1,
                ?2

If I have time this weekend I will try to test if it works with the ESCAPE '\'.

Regards

I made four files named _.jpg _1.jpg t.jpg and tt.jpg
when search for _1 correctly finds only " _1.jpg" as it should. If search for 1.jpg only it does not find any. However, if search for tt, it works correctly. If search for just t it does not find any. It seems to me when file name is a single character regardless of being _ or any other character it does fail to search. search bar overlay text says " by default start and end wildcard are auto-supplied." Maybe because of this default behavior just one character image name is ignored.

underscore works as “any single character”.

For example, if you try to search: t_.jpg
It will find tt.jpg.

But also it is true that the search terms are wrapped between % which works as “anything”.

True. What I was trying to say if your search is limited to a single character then search will not work. Which is fine with me I was trying to find out why _ does not produce any result and did found out it is not limited to _ but any single character filename will fails the search and that maybe is because of wrapping between %.

1 Like

I have done a quick test and ESCAPE works as expected:

--- underscore with backslash (as darktable pass the search terms)
--- does not find anything
sqlite> SELECT id, filename from images WHERE filename LIKE '%\_DSC3138%';

--- underscore with backslash and ESCAPE clause
--- finds the image
sqlite> SELECT id, filename from images WHERE filename LIKE '%\_DSC3138%' ESCAPE '\';
id|filename
63158|_DSC3138.nef

--- underscore as any character and ESCAPE clause
--- finds the file
sqlite> SELECT id, filename from images WHERE filename LIKE '%_DSC3138%'  ESCAPE '\';
id|filename
63158|_DSC3138.nef

On Sunday I can try to send a feature request to include the ESCAPE in this query and maybe others (I need to check this file more deeply darktable/src/common/collection.c at master · darktable-org/darktable · GitHub).

Thank you for your responses!
Your explanation seems to be spot on. After playing some more with different search combinations, everything confirms your findings.

I have one question though: If the escape character ‘' is included, will the double backslash (’\') find the actual backslash character (as in searching for a certain file path)?

Good point! In that case you need to escape the escape character(‘\’).

When I try to do the changes, I’ll check for alternatives or how much can affect common searches.

1 Like

Finally, I’m having some time to check this.

When you search for files in “collection filters” module, you mean by adding a new filename rule, right (check below image)?

Or do you mean “collections” module, filtering by film roll (another image below):

Mentioning “collections” module because it does not use sqlite to filter.
% symbol handling has been implemented in code to simulate sqlite % symbol behaviour but not for _ symbol.

Thanks

Thank you for your response!

Yes, I mean “collection filters” (not “collections” module) as stated in my original post.
But it is good to know, that the “collections” module does not use sqlite for filtering.