Ticket #496 (closed defect: fixed)

Opened 21 months ago

Last modified 16 months ago

NOT operator doesn't work well in DQL

Reported by: jonathan.ding Owned by: jepso
Priority: critical Milestone: 2.0.0 (OLD)
Component: Query/Hydration Version: 1.0.0
Severity: Keywords:
Cc: Has Test:
Status: Has Patch:

Description

Considering below DQL:

<?php
$q1->parseQuery('SELECT c.id FROM Content c WHERE NOT (c.id=3)');
$q2->parseQuery('SELECT c.id FROM Content c WHERE NOT c.id=3');
echo $q1->getSql();
echo $q2->getSql();

The first one returns wrong Sql

SELECT c.id AS c__id FROM content c

And the second one raised exception.

Looks like the 'NOT' is not well parsed. Or my usage is wrong? Oringinally I'm have a complicated DQL like

  SELECT ... FROM ... WHERE condition1 AND NOT condition2 AND condition3 OR NOT condition4 ...

Change History

Changed 21 months ago by jonathan.ding

Hi, is there any update for this entry? thanks a lot!

Changed 21 months ago by zYne

WHERE c.id != 3

Changed 21 months ago by zYne

  • status changed from new to assigned
  • owner changed from somebody to zYne

Changed 21 months ago by jonathan.ding

:) For sure I could make it "c.id!=3' in this simple example to reproduce the bug. But how about if the condition for 'NOT' operation is a complicated expression, or you want to NOT on a totally dynamic generated on? for example

<?php
$op = a_complicated_func() ? 'NOT ' : '';
$DQL = 'SELECT * FROM Content c WHERE '.$op.a_complicated_func_to_generate_dql_part();

I can not believe we only handle binary logic operation like 'AND' and 'OR', and won't support the unitary 'NOT'.
As I have to wait serveral days to get the response, I gave a quick fix on this without much testing, and it's just for your reference and I hope to get an official patch as soon as possible.
Add the processing of 'NOT' on Query/Condition.php. Below are the code from line 66 after my fix.

<?php
                if (substr($parts[0],0,1) == '(' && substr($parts[0], -1) == ')') {
                    return $this->parse(substr($parts[0], 1, -1));
                } else {
                    // Processing NOT here
                    if (strtoupper(substr($parts[0], 0, 4)) === 'NOT ') {
                        $r = 'NOT ('.$this->parse(substr($parts[0], 4)).')';
                    } else {
                        return $this->load($parts[0]);
                    }
                }

Changed 20 months ago by jwage

  • owner changed from zYne to jonathan.ding
  • status changed from assigned to new

Great, apply your patch to your local development copy of Doctrine and run the tests to ensure it does not break anything and attach the patch here and we can apply it or if you have svn commit access you can commit it. If you commit the patch, in the commit message put "fixes #496" and it will close the ticket here and update it.

Changed 19 months ago by romanb

  • milestone changed from 1.0 to beta3

Changed 18 months ago by jwage

  • owner changed from jonathan.ding to jepso
  • milestone changed from beta3 to 1.0

Changed 17 months ago by romanb

  • component changed from general to Query/Hydration

Changed 17 months ago by guilhermeblanco

  • status changed from new to closed
  • resolution set to fixed

(In [3783]) Added NOT operator recognition in DQL (fixes #496)

Changed 16 months ago by anonymous

  • milestone 1.0 deleted

Milestone 1.0 deleted

Note: See TracTickets for help on using tickets.