Doctrine 1
  1. Doctrine 1
  2. DC-754

When using a dot inside a string doctrine throws an exception because it believes what comes before the dot is a class name

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.2.2
    • Fix Version/s: None
    • Component/s: Query
    • Labels:
      None
    • Environment:
      XP Xamp

      Description

      Hi Jon

      I ran into and patched another bug in Doctrine 1.2.2 (The menu in jija shows 1.2.3 as released but I am not seeing it in SVN or on the web site so I can't test the bug in that version).

      When you include a dot in a string in your select statement the function getExpressionOwner in Doctrine_Query fires and considers that the text appearing before the dot in the string is the name of a class. There for it attempts to extract a short alias out of it.

      I made a test case to illustrate this:

      public function testQuoteEncapedDots()
          {
              $q = new Doctrine_Query();
              $q->select("'testing.dots.inquotes' as string, u.name")->from('User u');
      
              $this->assertEqual($q->getSqlQuery(), "SELECT e.id AS e__id, e.name AS e__name, 'testing.dots.inquotes' AS e__0 FROM entity e WHERE (e.type = 0)");
          }
      

      It throws the following exception.

      Unexpected Doctrine_Query_Exception thrown in [Doctrine_Query_ShortAliases_TestC
      ase] with message [Couldn't get short alias for testing] in C:\htdocs\php_librar
      y\Doctrine_1.2_SVN\lib\Doctrine\Query\Abstract.php on line 679
      
      Trace
      -------------
      #0 C:\htdocs\php_library\Doctrine_1.2_SVN\lib\Doctrine\Query.php(641): Doctrine_
      Query_Abstract->getSqlTableAlias('testing')
      #1 C:\htdocs\php_library\Doctrine_1.2_SVN\lib\Doctrine\Query\Select.php(37): Doc
      trine_Query->parseSelect(''testing.dots.i...')
      #2 C:\htdocs\php_library\Doctrine_1.2_SVN\lib\Doctrine\Query\Abstract.php(2083):
       Doctrine_Query_Select->parse(''testing.dots.i...')
      #3 C:\htdocs\php_library\Doctrine_1.2_SVN\lib\Doctrine\Query.php(1168): Doctrine
      _Query_Abstract->_processDqlQueryPart('select', Array)
      #4 C:\htdocs\php_library\Doctrine_1.2_SVN\lib\Doctrine\Query.php(1134): Doctrine
      _Query->buildSqlQuery(true)
      #5 C:\htdocs\php_library\Doctrine_1.2_SVN\tests\Query\ShortAliasesTestCase.php(3
      0): Doctrine_Query->getSqlQuery()
      #6 C:\htdocs\php_library\Doctrine_1.2_SVN\tests\DoctrineTest\UnitTestCase.php(15
      8): Doctrine_Query_ShortAliases_TestCase->testQuoteEncapedDots()
      #7 C:\htdocs\php_library\Doctrine_1.2_SVN\tests\DoctrineTest\GroupTest.php(75):
      UnitTestCase->run()
      #8 C:\htdocs\php_library\Doctrine_1.2_SVN\tests\DoctrineTest.php(183): GroupTest
      ->run(Object(DoctrineTest_Reporter_Cli), Array)
      #9 C:\htdocs\php_library\Doctrine_1.2_SVN\tests\run.php(320): DoctrineTest->run(
      )
      #10 {main}
      

      I patched the bug by doing a preg_replace where all quote encaped strings are removed before looking for the short alias. The getExpressionOwner function now reads as follows in my code:

      public function getExpressionOwner($expr)
          {
              if (strtoupper(substr(trim($expr, '( '), 0, 6)) !== 'SELECT') {
      			$expr = preg_replace('/([\\]*[\'\"])[^\1]*\1/', '', $expr);
                  preg_match_all("/[a-z_][a-z0-9_]*\.[a-z_][a-z0-9_]*[\.[a-z0-9]+]*/i", $expr, $matches);
      
                  $match = current($matches);
      
                  if (isset($match[0])) {
                      $terms = explode('.', $match[0]);
      
                      return $terms[0];
                  }
              }
              return $this->getRootAlias();
      
          }
      

      I am including the patch with this post but I think my version of the code base is starting diverge as I also have a few other things added to mine (as discussed in: DC-701)

      Hope you are well.

      Will Ferrer

      1. 2010-06-21_Doctrine_1.2_SVN.patch
        10 kB
        will ferrer
      2. DC_754_fix.patch
        1 kB
        will ferrer

        Activity

        Hide
        will ferrer added a comment -

        Improved patch to have a more rigorous test case, refined the regex added, and put in a comment referencing this bug.

        Show
        will ferrer added a comment - Improved patch to have a more rigorous test case, refined the regex added, and put in a comment referencing this bug.
        Hide
        Pablo Mateos added a comment -

        Hi, we're having an issue which is related to this post and I'd like to share it with you so maybe it's posible to solve both.

        The situation appears when you need to look for some data that includes a "." inside a string SQL comparison with LIKE operator, here you have an example:

        $this->pager = new sfDoctrinePager('Recurso', sfConfig::get('app_res_pag'));
        $this->pager->getQuery()
        ->select('r.*,
        c.alias as cliente_alias,
        c.nombre as cliente_nombre,
        o.alias as origen_alias,
        o.nombre as origen_nombre,
        GROUP_CONCAT(DISTINCT CONCAT_WS(",", cat.id, e.nombre) ORDER BY cat.id ASC) as elemento_nombre,
        cv.hash as cv_hash')
        ->from('Recurso r')
        ->innerJoin('r.Cliente c')
        ->innerJoin('r.Origen o')
        ->leftJoin('r.RecursoCategoriaItem rci')
        ->leftJoin('rci.CategoriaItem ci')
        ->leftJoin('ci.Categoria cat')
        ->leftJoin('ci.Elemento e')
        ->leftJoin('ci.Nivel n')
        ->leftJoin('r.RecursoCv rcv')
        ->leftJoin('rcv.Cv cv')
        ->leftJoin('cv.Idioma i')
        ->leftJoin('r.RecursoComentario rc')
        ->leftJoin('rc.Comentario comm')
        ->where('r.apellido LIKE "%.net%" OR r.nombre LIKE "%.net%" OR r.numero_doc LIKE "%.net%" OR r.mail LIKE "%.net%" OR o.nombre LIKE "%.net%" OR cat.nombre LIKE "%.net%" OR e.nombre LIKE "%.net%" OR n.nombre LIKE "%.net%" OR c.nombre LIKE "%.net%" OR c.alias LIKE "%.net%" OR r.contenido LIKE "%.net%"')
        ->groupBy('r.id')
        >orderBy('r.' . $orderBy . ' ' . $this>order);
        $this->pager->setPage($page);
        $this->pager->init();

        Look at the "WHERE" line, there is a LIKE ".net".

        So when we execute this code, Doctrine tries to parse the "." in the ".net" like an SQL alias and of course it fails:

        ERROR:

        500 | Internal Server Error | Doctrine_Exception
        Couldn't find class "%

        Do you know some other why to solve this situation ?. In case you need further information about this, just ask me.

        Thank you in advance.

        Pablo Mateos.

        Show
        Pablo Mateos added a comment - Hi, we're having an issue which is related to this post and I'd like to share it with you so maybe it's posible to solve both. The situation appears when you need to look for some data that includes a "." inside a string SQL comparison with LIKE operator, here you have an example: $this->pager = new sfDoctrinePager('Recurso', sfConfig::get('app_res_pag')); $this->pager->getQuery() ->select('r.*, c.alias as cliente_alias, c.nombre as cliente_nombre, o.alias as origen_alias, o.nombre as origen_nombre, GROUP_CONCAT(DISTINCT CONCAT_WS(",", cat.id, e.nombre) ORDER BY cat.id ASC) as elemento_nombre, cv.hash as cv_hash') ->from('Recurso r') ->innerJoin('r.Cliente c') ->innerJoin('r.Origen o') ->leftJoin('r.RecursoCategoriaItem rci') ->leftJoin('rci.CategoriaItem ci') ->leftJoin('ci.Categoria cat') ->leftJoin('ci.Elemento e') ->leftJoin('ci.Nivel n') ->leftJoin('r.RecursoCv rcv') ->leftJoin('rcv.Cv cv') ->leftJoin('cv.Idioma i') ->leftJoin('r.RecursoComentario rc') ->leftJoin('rc.Comentario comm') ->where('r.apellido LIKE "%.net%" OR r.nombre LIKE "%.net%" OR r.numero_doc LIKE "%.net%" OR r.mail LIKE "%.net%" OR o.nombre LIKE "%.net%" OR cat.nombre LIKE "%.net%" OR e.nombre LIKE "%.net%" OR n.nombre LIKE "%.net%" OR c.nombre LIKE "%.net%" OR c.alias LIKE "%.net%" OR r.contenido LIKE "%.net%"') ->groupBy('r.id') >orderBy('r.' . $orderBy . ' ' . $this >order); $this->pager->setPage($page); $this->pager->init(); Look at the "WHERE" line, there is a LIKE ".net". So when we execute this code, Doctrine tries to parse the "." in the ".net" like an SQL alias and of course it fails: ERROR: 500 | Internal Server Error | Doctrine_Exception Couldn't find class "% Do you know some other why to solve this situation ?. In case you need further information about this, just ask me. Thank you in advance. Pablo Mateos.
        Hide
        will ferrer added a comment -

        Hi Pablo

        I think I found a work around for you – I tested this bug out to see if I could recreate and patch it and found that my own system didn't generate the bug. Turns out the difference is my code encapes the strings that go in the query with single quotes and this seems to solve the problem.

        Try the same query you posted above but replace the "%.net%" with '%.net%'.

        I think that should solve it.

        Hope that helps.

        Will

        Show
        will ferrer added a comment - Hi Pablo I think I found a work around for you – I tested this bug out to see if I could recreate and patch it and found that my own system didn't generate the bug. Turns out the difference is my code encapes the strings that go in the query with single quotes and this seems to solve the problem. Try the same query you posted above but replace the "%.net%" with '%.net%'. I think that should solve it. Hope that helps. Will
        Hide
        Pablo Mateos added a comment -

        Hi Will, I tried what you said and it worked !!!!!! . It's great to have so easy solutions for debugging, isn't ?.

        So, anyway do you think this issue should be considered as a bug ?.

        I really appreciate your help.

        Pablo.

        Show
        Pablo Mateos added a comment - Hi Will, I tried what you said and it worked !!!!!! . It's great to have so easy solutions for debugging, isn't ?. So, anyway do you think this issue should be considered as a bug ?. I really appreciate your help. Pablo.
        Hide
        will ferrer added a comment -

        Hi Pablo

        I am glad that worked .

        I do think this is still a bug – I there are some problems with double quotes in dql in general I believe. Then again there may be something in the docs about this being a restriction that I overlooked (not sure).

        But since its solvable with using single quotes I would recommend putting it as a low priority bug – which may mean it won't actually get fixed any time soon. Whether it gets fixed or not though its good to have these kinds of bugs in the system so that there is a record of everything that needs fixing and so other users can find work arounds to there problems by looking through the archive.

        Hope you are well.

        Will

        Show
        will ferrer added a comment - Hi Pablo I am glad that worked . I do think this is still a bug – I there are some problems with double quotes in dql in general I believe. Then again there may be something in the docs about this being a restriction that I overlooked (not sure). But since its solvable with using single quotes I would recommend putting it as a low priority bug – which may mean it won't actually get fixed any time soon. Whether it gets fixed or not though its good to have these kinds of bugs in the system so that there is a record of everything that needs fixing and so other users can find work arounds to there problems by looking through the archive. Hope you are well. Will
        Hide
        Jonathan H. Wage added a comment -
        Show
        Jonathan H. Wage added a comment - Thanks for the issue and patches! Fixed here http://github.com/doctrine/doctrine1/commit/2ad78e62e360133efc04bf6897bf679c7f3d833b
        Hide
        will ferrer added a comment -

        individual patch for this issue with out other features included

        Show
        will ferrer added a comment - individual patch for this issue with out other features included
        Hide
        smash company added a comment -

        I'm curious if this could be the same issue that causes doctrine:build-schema to give either the 'Missing class name' or 'Couldn't find class Content ' error? I am going a little crazy trying to figure out why doctrine:build-schema doesn't work for me. Details here:

        http://www.symfonyexperts.com/question/show/id/156

        Show
        smash company added a comment - I'm curious if this could be the same issue that causes doctrine:build-schema to give either the 'Missing class name' or 'Couldn't find class Content ' error? I am going a little crazy trying to figure out why doctrine:build-schema doesn't work for me. Details here: http://www.symfonyexperts.com/question/show/id/156
        Hide
        will ferrer added a comment -

        Hi Smash

        I did a quick glance at your issue. I have never encountered this error my self and I don't think it is related to my issue.

        When I have a bug like that the first place I start looking is where the exception is being thrown.

        For you its in the Doctrine_Import_Builder class on either line 949 or 995

        You could start by putting some debugging to see what the $definition var is. That may offer some insights. Then if that doesn't clarify whats wrong with your schema you could start back tracking out of the method to see where else things could be screwing up .

        Hope that helps at least alil bit.

        Will Ferrer

        Show
        will ferrer added a comment - Hi Smash I did a quick glance at your issue. I have never encountered this error my self and I don't think it is related to my issue. When I have a bug like that the first place I start looking is where the exception is being thrown. For you its in the Doctrine_Import_Builder class on either line 949 or 995 You could start by putting some debugging to see what the $definition var is. That may offer some insights. Then if that doesn't clarify whats wrong with your schema you could start back tracking out of the method to see where else things could be screwing up . Hope that helps at least alil bit. Will Ferrer

          People

          • Assignee:
            Guilherme Blanco
            Reporter:
            will ferrer
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: