Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-1096

"You may have observed that in a mixed result, the object always ends up on index 0 of a result row."

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Duplicate
    • Affects Version/s: 2.0.2
    • Fix Version/s: 2.0.4
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      The DQL reference at

      http://www.doctrine-project.org/docs/orm/2.0/en/reference/dql-doctrine-query-language.html

      defines that

      "You may have observed that in a mixed result, the object always ends up on index 0 of a result row."

      I find this too important to state it in such a parenthetic way.

      The reordering is counterintuitive behaviour at its worst, and grossly in violation of the principle of least astonishment. I bet noone would even guess that this could be intended behaviour. I would not consider this a classic bug, as it is documented behaviour, but as a way of deliberately doing it wrong, making mixed results totally counterintuitive to use. From a usability standpoint, this is as bad as it gets.

      I cannot think of any convincing reason why the ORM should decide on its own, and without any notice, to change the explicitly specified ordering from the select list, because it is absolutely confusing and IMO there is no advantage at all in doing so.

      I explicitly told Doctrine 2 to put the entity element on position 3, so why should it end up at position 0 without further notice? If position 0 is a must (which I do not think it should be), then the user should not be able to specify entity elements at any other position than that. As long as other positions are permissible, I would rather have the element stay at the exact position declared, and not be shuffled around.

        Issue Links

          Activity

          Show
          Guilherme Blanco added a comment - Improvement implemented in https://github.com/doctrine/doctrine2/commit/81cc6d9da83d217ea62bd467053fd9885d1083cd
          Hide
          Benjamin Eberlei added a comment -

          Result keys Will be implemented as part of DDC-1424

          Show
          Benjamin Eberlei added a comment - Result keys Will be implemented as part of DDC-1424
          Hide
          Daniel Alvarez Arribas added a comment - - edited

          Sorry for the late update.

          I double checked that the effect is not caused by using the list construct on the result in application code.

          For DQL queries of the following form:

          SELECT someEntityReference.someStringValuedField, someEntityReference
              FROM \SomeEntity someEntityReference
          

          the fields in the result rows will have got shuffled around as soon as the result is returned by Doctrine 2, i. e. before any list() function or the like gets called on it in application code.

          Calling gettype() on the result elements, like:

          $result = $aQueryOfTheFormShownAbove->getResult();
          
          $firstResultElement = reset($result);
          
          foreach ($firstResultElement as $field) {
            
             echo gettype($field) . "\n";
          }
          

          will output:

          object
          string
          

          whereas the DQL query explicitly asked for a result of the form (string, object), not (object, string).

          To my best knowledge, the foreach construct will rely only on the actual positioning regardless of the key values in the input array.

          So the situation is just as I have previously described.

          Show
          Daniel Alvarez Arribas added a comment - - edited Sorry for the late update. I double checked that the effect is not caused by using the list construct on the result in application code. For DQL queries of the following form: SELECT someEntityReference.someStringValuedField, someEntityReference FROM \SomeEntity someEntityReference the fields in the result rows will have got shuffled around as soon as the result is returned by Doctrine 2, i. e. before any list() function or the like gets called on it in application code. Calling gettype() on the result elements, like: $result = $aQueryOfTheFormShownAbove->getResult(); $firstResultElement = reset($result); foreach ($firstResultElement as $field) { echo gettype($field) . "\n" ; } will output: object string whereas the DQL query explicitly asked for a result of the form (string, object), not (object, string). To my best knowledge, the foreach construct will rely only on the actual positioning regardless of the key values in the input array. So the situation is just as I have previously described.
          Hide
          Daniel Alvarez Arribas added a comment - - edited

          Which reminds me... I will have to double-check that it is not the list() calls I do on the result that are screwing things up.

          Show
          Daniel Alvarez Arribas added a comment - - edited Which reminds me... I will have to double-check that it is not the list() calls I do on the result that are screwing things up.
          Hide
          Daniel Alvarez Arribas added a comment - - edited

          Yes, that's exactly what I mean (ignoring the shifting side effect on the result of course).

          It would be:

          $A = reset($result);
          $B = next($result);
          $C = next($result);

          And never, e. g.:

          $C = reset($result);
          $A = next($result);
          $B = next($result);

          If you'd rely on numeric indexes, it would be:

          Basically: SELECT A, B, C -> $A = $result[0], $B = $result[1], $C = $result[2].

          Or: list ($A, $B, $C) = $result;

          And never: SELECT A, B, C -> $A = $result[2], $B = $result[0], $C = $result[1].

          Or: list ($C, $A, $B) = $result;

          Numeric indexing is, though, of course not guaranteed to correctly identify positioning under all circumstances due to the associative-table nature of PHP arrays. E. g. if you populate an array with non-continuous numeric keys, say array (3 = > 'someValue', 5 = 'someOtherValue'), you end up with an array with numeric key 3 at position 0, where the key is clearly not suitable to identify the element's position. But provided you assign numeric keys to the elements in such a way that the numeric keys coincide with the element positions in the array (i. e. the element at position 0 has numeric key 0, and the element at position 1 has numeric key 1), then, of course, you could use numeric keys internally to identify element positions. Then again, you do not need to, the approach of using the de-facto element positions should be more fail-safe.

          Show
          Daniel Alvarez Arribas added a comment - - edited Yes, that's exactly what I mean (ignoring the shifting side effect on the result of course). It would be: $A = reset($result); $B = next($result); $C = next($result); And never, e. g.: $C = reset($result); $A = next($result); $B = next($result); If you'd rely on numeric indexes, it would be: Basically: SELECT A, B, C -> $A = $result [0] , $B = $result [1] , $C = $result [2] . Or: list ($A, $B, $C) = $result; And never: SELECT A, B, C -> $A = $result [2] , $B = $result [0] , $C = $result [1] . Or: list ($C, $A, $B) = $result; Numeric indexing is, though, of course not guaranteed to correctly identify positioning under all circumstances due to the associative-table nature of PHP arrays. E. g. if you populate an array with non-continuous numeric keys, say array (3 = > 'someValue', 5 = 'someOtherValue'), you end up with an array with numeric key 3 at position 0, where the key is clearly not suitable to identify the element's position. But provided you assign numeric keys to the elements in such a way that the numeric keys coincide with the element positions in the array (i. e. the element at position 0 has numeric key 0, and the element at position 1 has numeric key 1), then, of course, you could use numeric keys internally to identify element positions. Then again, you do not need to, the approach of using the de-facto element positions should be more fail-safe.

            People

            • Assignee:
              Guilherme Blanco
              Reporter:
              Daniel Alvarez Arribas
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: