DDC-1213: Make Bit comparsion available #1820

Closed
doctrinebot opened this Issue Jun 17, 2011 · 11 comments

1 participant

@doctrinebot

Jira issue originally created by user scyks:

When you go to compare Bit Values in MySQL Database you can do thiy by "&" or "|" If you do this with Doctrine 2 you got an exception like following:
Message: [Syntax Error] line 0, col 161: Error: Expected =, <, <=, <>, >, >=, != got '&'

So i fixed this problem for me:

Doctrine\ORM\Query\Parser:
Line 2633

    /****
     * ComparisonOperator ::= "=" | "<" | "<=" | "<>" | ">" | ">=" | "!=" | "&" | "|"
     *
     * @return string
     */
    public function ComparisonOperator()
    {
        switch ($this->_lexer->lookahead['value']) {
            case '=':
                $this->match(Lexer::T_EQUALS);

                return '=';

            case '<':
                $this->match(Lexer::T*LOWER*THAN);
                $operator = '<';

                if ($this->*lexer->isNextToken(Lexer::T*EQUALS)) {
                    $this->match(Lexer::T_EQUALS);
                    $operator .= '=';
                } else if ($this->*lexer->isNextToken(Lexer::T_GREATER*THAN)) {
                    $this->match(Lexer::T*GREATER*THAN);
                    $operator .= '>';
                }

                return $operator;

            case '>':
                $this->match(Lexer::T*GREATER*THAN);
                $operator = '>';

                if ($this->*lexer->isNextToken(Lexer::T*EQUALS)) {
                    $this->match(Lexer::T_EQUALS);
                    $operator .= '=';
                }

                return $operator;

            case '!':
                $this->match(Lexer::T_NEGATE);
                $this->match(Lexer::T_EQUALS);

                return '<>';
            /** Changes by SR-RM to make Bit Oprations available **/
            case '&':
                $this->match(LEXER::T*BIT*AND);
                return '&';
            case '|':
                $this->match(LEXER::T*BIT*OR);
                return '|';
            /** Changes by SR-RM End **/
            default:
                $this->syntaxError('=, <, <=, <>, >, >=, !=, &, |');
        }
    }

Doctrine\ORM\Query\Lexer:
Line 53

/** Changes SR-RM to make Bit Oprations available **/
const T*BIT*AND             = 30;
const T*BIT*OR               = 31;
/** Changes by SR-RM End **/

Line 193

/** Changes SR-RM to make Bit Oprations available **/
case '&': return self::T*BIT*AND;
case '|': return self::T*BIT*OR;
/** Changes by SR-RM End **/

So, maybe you gonna ad this in next Release ;)

Thanks or your good Job

@doctrinebot

Comment created by @beberlei:

This issue is referenced in Github Pull-Request GH-230
#230

@doctrinebot

Comment created by @beberlei:

Related Pull Request was closed: #230

@doctrinebot

Comment created by @beberlei:

This issue is referenced in Github Pull-Request GH-231
#231

@doctrinebot

Comment created by @beberlei:

Related Pull Request was closed: #231

@doctrinebot

Comment created by @beberlei:

Fixed

@doctrinebot

Issue was closed with resolution "Fixed"

@doctrinebot

Comment created by historika:

I do miss this patch in the recently checked out 2.2 branch. Is there any reason, it was skipped, even if the fix-version here is still 2.2?
I really miss this feature and was unable to get it to work by applying it manually. The parser seems to have troubles applying my parameters :\

@doctrinebot

Comment created by @FabioBatSilva:

Hi Markus

The bit comparisons was been added as DQL functions,
Can you explain your problem ?

@doctrinebot

Comment created by historika:

Hi Fabio, thank you for the fast reply and the great Doctrine anyway!

My problem is the following:
I have an @Entity called Picture with some columns and the following

    /**** @Column(type = "integer", nullable = false)
     ** @var int **/
    private $visibility;

Now I try to fetch entities from the database that satisfy some special bit mask in this visibility attribute by doing the following:

    /*** @var $query \Doctrine\ORM\Query **/
    $query = $this->entityManager->createQuery('SELECT e FROM Classes\Models\Event e JOIN e.pictures p WHERE p.visibility & :visibility = :visibility ORDER BY p.uploadTime DESC');
    $query->setParameter('visibility', \Classes\Session::instance()->getActualUsersRights());
    return $query->getResult();

The error reported is:

Fatal error:  Uncaught exception 'Doctrine\ORM\Query\QueryException' with message '[Syntax Error] line 0, col 78: Error: Expected end of string, got '='' in ...\Doctrine\ORM\Query\QueryException.php:42
Stack trace:
#0 ...\Doctrine\ORM\Query\Parser.php(380): Doctrine\ORM\Query\QueryException::syntaxError('line 0, col 78:...')
#1 ...\Doctrine\ORM\Query\Parser.php(745): Doctrine\ORM\Query\Parser->syntaxError('end of string')
#2 ...\Doctrine\ORM\Query\Parser.php(213): Doctrine\ORM\Query\Parser->QueryLanguage()
#3 ...\Doctrine\ORM\Query\Parser.php(288): Doctrine\ORM\Query\Parser->getAST()
#4 ...\Doctrine\ORM\Query.php(231): Doctrine\ORM\Query\Parser->parse()
#5 ...\Doctrine\ORM\Query.php(242): Doctrine\ORM\Query->_parse()
#6 in <b>...\Doctrine\ORM\Query\QueryException.php</b> on line <b>42</b><br />

Please note: I applied the above patch by hand to the Doctrine 2.2 code. Before that I got an "expected = got '&'" exception in the query.

Am I wrong, if I look through the code and try to find the suggested lines from Ronald there? They aren't in the downloadable package and even not in the SVN, I checked out this morning from http://svn.github.com/doctrine/doctrine2.git

@doctrinebot

Comment created by @FabioBatSilva:

Hi Markus

The "&" and "|" is not available for database compatibilities
You should use the DQL function BITAND or BITOR

WHERE BIT_AND( p.visibility, :visibility )
@doctrinebot

Comment created by historika:

Thanks a lot Fabio,

stupid me, sorry.

For completeness, I now use:

SELECT e FROM Classes\Models\Event e JOIN e.pictures p WHERE BIT_AND(p.visibility, :visibility) = :visibility ORDER BY p.uploadTime DESC

and seem to get past the critical part.

Now I can go on trying to get the project back to work with the new Doctrine 2.2 ;)
I know its worth the work ;)

@doctrinebot doctrinebot added this to the 2.2 milestone Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment