After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 740701 - Filter priorities
Filter priorities
Status: RESOLVED FIXED
Product: gom
Classification: Other
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: Gom Maintainers
Gom Maintainers
Depends on:
Blocks:
 
 
Reported: 2014-11-25 17:59 UTC by Mathieu Bridon
Modified: 2014-12-08 18:19 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Respect filter priorities (1014 bytes, patch)
2014-11-25 18:03 UTC, Mathieu Bridon
accepted-commit_now Details | Review
filter: Respect filter priorities (1.25 KB, patch)
2014-12-05 17:23 UTC, Mathieu Bridon
none Details | Review
filter: Respect filter priorities (947 bytes, patch)
2014-12-08 11:21 UTC, Mathieu Bridon
committed Details | Review
tests: Add more data to the DB (2.61 KB, patch)
2014-12-08 17:49 UTC, Mathieu Bridon
committed Details | Review
tests: Ensure filter priority (3.54 KB, patch)
2014-12-08 17:49 UTC, Mathieu Bridon
committed Details | Review

Description Mathieu Bridon 2014-11-25 17:59:38 UTC
I've just spent a while wondering why my query, which is supposed to return
only one entry, was returning instead 22958. (slightly more than expected :P)

Printing the SQL command run by Gom, I see:

  SELECT COUNT('chars'.'id')
  FROM 'chars'
  WHERE 'chars'.'version' == ?
    AND 'chars'.'orientation' != ?
    AND 'chars'.'big5' == ?
     OR 'chars'.'hkscs' == ?
     OR 'chars'.'punctuation' == ?
    AND 'chars'.'code' == ? 

Putting in there the values, this becomes:

  SELECT COUNT('chars'.'id')
  FROM 'chars'
  WHERE 'chars'.'version' == 3
    AND 'chars'.'orientation' != 1
    AND 'chars'.'big5' == 1
     OR 'chars'.'hkscs' == 1
     OR 'chars'.'punctuation' == 1
    AND 'chars'.'code' == 'ddd' 

(as an aside, it would be nice if Gom printed the values in the SQL queries,
not just the '?')

And sure enough, if I run this query in sqlite3, I get:

sqlite> SELECT ...
22958

However, the query I really wanted was:

  SELECT COUNT('chars'.'id')
  FROM 'chars'
  WHERE 'chars'.'version' == 3
    AND 'chars'.'orientation' != 1
    AND ('chars'.'big5' == 1
         OR 'chars'.'hkscs' == 1
         OR 'chars'.'punctuation' == 1)
    AND 'chars'.'code' == 'ddd' 

Notice the parentheses!

Running this new query in sqlite3:

sqlite> SELECT ...
1

That's better.

I'm building the filters as follows (well, slightly simplifying the code
here, this comment is already long enough), and I was expecting it to respect
priorities, that is, to use parentheses:

    v_filter = gom_filter_new_eq (CANGJIE_TYPE_CHAR, "version", &value);
    o_filter = gom_filter_new_neq (CANGJIE_TYPE_CHAR, "orientation", &value);
    v_and_o_filter = gom_filter_new_and (version_filter, orientation_filter);

    b_filter = gom_filter_new_eq (CANGJIE_TYPE_CHAR, "big5", &value);
    h_filter = gom_filter_new_eq (CANGJIE_TYPE_CHAR, "hkscs", &value);
    p_filter = gom_filter_new_eq (CANGJIE_TYPE_CHAR, "punctuation", &value);
    b_or_h_filter = gom_filter_new_or (b_filter, h_filter);
    f_filter = gom_filter_new_or (b_or_h_filter, p_filter);
    
    v_and_o_and_f_filter = gom_filter_new_and (v_and_o_filter, f_filter);
    
    code_filter = gom_filter_new_eq (CANGJIE_TYPE_CHAR, "code", &value);
    final_filter = gom_filter_new_and (v_and_o_and_f_filter, code_filter);
Comment 1 Mathieu Bridon 2014-11-25 18:03:17 UTC
Created attachment 291487 [details] [review]
Respect filter priorities

This adds parentheses everywhere (probably more than strictly
necessary), in order to respect the priorities intended by the user.
Comment 2 Mathieu Bridon 2014-11-25 18:04:38 UTC
Not sure this is the right approach to fixing this, but here's a simple patch that helps in my case.

I'm not excluding the fact that I'm actually doing something wrong with the way I build the filters. :)
Comment 3 Bastien Nocera 2014-11-25 18:05:14 UTC
Review of attachment 291487 [details] [review]:

If the test suite passes, looks good.
Comment 4 Bastien Nocera 2014-11-25 18:16:28 UTC
(In reply to comment #0)
> However, the query I really wanted was:
> 
>   SELECT COUNT('chars'.'id')
>   FROM 'chars'
>   WHERE 'chars'.'version' == 3
>     AND 'chars'.'orientation' != 1
>     AND ('chars'.'big5' == 1
>          OR 'chars'.'hkscs' == 1
>          OR 'chars'.'punctuation' == 1)
>     AND 'chars'.'code' == 'ddd' 
> 
> Notice the parentheses!

This isn't exactly what your code does though.

<snip>
>     v_filter = gom_filter_new_eq (CANGJIE_TYPE_CHAR, "version", &value);
>     o_filter = gom_filter_new_neq (CANGJIE_TYPE_CHAR, "orientation", &value);
>     v_and_o_filter = gom_filter_new_and (version_filter, orientation_filter);
> 
>     b_filter = gom_filter_new_eq (CANGJIE_TYPE_CHAR, "big5", &value);
>     h_filter = gom_filter_new_eq (CANGJIE_TYPE_CHAR, "hkscs", &value);
>     p_filter = gom_filter_new_eq (CANGJIE_TYPE_CHAR, "punctuation", &value);
>     b_or_h_filter = gom_filter_new_or (b_filter, h_filter);
>     f_filter = gom_filter_new_or (b_or_h_filter, p_filter);
> 
>     v_and_o_and_f_filter = gom_filter_new_and (v_and_o_filter, f_filter);
> 
>     code_filter = gom_filter_new_eq (CANGJIE_TYPE_CHAR, "code", &value);
>     final_filter = gom_filter_new_and (v_and_o_and_f_filter, code_filter);

It does:
   SELECT COUNT('chars'.'id')
   FROM 'chars'
   WHERE (('chars'.'version' == 3
     AND 'chars'.'orientation' != 1)
     AND (('chars'.'big5' == 1
          OR 'chars'.'hkscs' == 1)
          OR 'chars'.'punctuation' == 1))
     AND 'chars'.'code' == 'ddd' 

Which might not be really equivalent. Our filters don't handle more than 2 operands right now. But this is likely a separate problem.
Comment 5 Mathieu Bridon 2014-11-28 18:56:30 UTC
I have a new, better patch for this coming, based on top of the ones from bug 740872.

I'll attach it later, once we figure out what to do with the other bug. :)
Comment 6 Mathieu Bridon 2014-12-05 17:23:29 UTC
Created attachment 292207 [details] [review]
filter: Respect filter priorities

This adds parenthesis to the generated SQL queries where appropriate.
Comment 7 Mathieu Bridon 2014-12-08 11:21:46 UTC
Created attachment 292296 [details] [review]
filter: Respect filter priorities

This adds parenthesis to the generated SQL queries where appropriate.
Comment 8 Mathieu Bridon 2014-12-08 11:22:30 UTC
Here's an updated patch after your IRL review from Friday. :)
Comment 9 Bastien Nocera 2014-12-08 11:32:25 UTC
Review of attachment 292296 [details] [review]:

Looks good. Does it fix the original bug as well? Could you make a test case for that as well?

Thinking of what the test set should be will be tricky.
Comment 10 Mathieu Bridon 2014-12-08 17:49:28 UTC
Created attachment 292310 [details] [review]
tests: Add more data to the DB

This will help better ensuring some filter beheviours.
Comment 11 Mathieu Bridon 2014-12-08 17:49:33 UTC
Created attachment 292311 [details] [review]
tests: Ensure filter priority

This runs 2 queries with the same filters, but "grouped" in 2 different
ways, to ensure that we respect filtering priorities (i.e parentheses).
Comment 12 Bastien Nocera 2014-12-08 17:54:33 UTC
Review of attachment 292310 [details] [review]:

Looks good otherwise.

::: tests/test-gom-find-specific.c
@@ +237,3 @@
   g_assert (ret);
 
+  for (i = 0; i < 3; i++) {

i < G_N_ELEMENTS(values);
Comment 13 Bastien Nocera 2014-12-08 17:56:19 UTC
Review of attachment 292311 [details] [review]:

Good stuff!
Comment 14 Mathieu Bridon 2014-12-08 18:12:52 UTC
> Does it fix the original bug as well?

Sure it does.

My new query now looks like:

SELECT COUNT('chars'.'id')
  FROM 'chars'
  WHERE ('chars'.'version' == 3
    AND  'chars'.'orientation' != 1
    AND  ('chars'.'big5' == 1
      OR  'chars'.'hkscs' == 1
      OR  'chars'.'punctuation' == 1))
    AND 'chars'.'code' == 'ddd'

Which, given how I'm constructing the filters, is exactly what I was expecting. :)
Comment 15 Mathieu Bridon 2014-12-08 18:19:27 UTC
Attachment 292296 [details] pushed as ac381b1 - filter: Respect filter priorities
Attachment 292310 [details] pushed as 2d4e1db - tests: Add more data to the DB
Attachment 292311 [details] pushed as 991dcc2 - tests: Ensure filter priority