MDL-69026 user: Wrap sub-query in brackets
authorAndrew Nicols <andrew@nicols.co.uk>
Fri, 12 Jun 2020 00:46:46 +0000 (08:46 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Fri, 12 Jun 2020 02:03:06 +0000 (10:03 +0800)
commit8bcf74e9bc8cd34780d14e00537ea1cdf0190608
tree8df75055e65eaa8b0e77d1859f201d82141a49e1
parentaa6830ef990a79010810b3b4d83e5a96d0b862bc
MDL-69026 user: Wrap sub-query in brackets

It is perfectly valid to have a query like:

Match None of the following:
- Role is ANY of the following:
-- 'Teacher'
-- 'Editing teacher'
-- 'Manager'; AND
- Keyword is NONE of the following:
-- 'Kevin'

However, due to the way in which the query is constructed, this leads to
a query which includes

    WHERE NOT ef.id IS NOT NULL
    AND NOT
        u.id IN (SELECT userid FROM {role_assignments} WHERE roleid IN (...) AND contextid IN (...))
    AND NOT
        NOT (u.firstname || ' ' || u.lastname LIKE '%Kevin%')

The use of NOT NOT is valid in Postgres, MariaDB, MySQL, and MSSQL, but
not in Oracle.

To counter this when the outer jointype is of type NONE, we must wrap
each of the inner WHERE clauses in a set of brackets, which makes the
query:

    WHERE NOT ef.id IS NOT NULL
    AND NOT
        (u.id IN (SELECT userid FROM {role_assignments} WHERE roleid IN (...) AND contextid IN (...)))
    AND NOT
        (NOT (u.firstname || ' ' || u.lastname LIKE '%Kevin%'))

Whilst Oracle does not support the use of `AND NOT NOT ...`, it does support
`AND NOT (NOT ...)`
user/classes/table/participants_search.php
user/tests/table/participants_search_test.php