Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge pull request #190 from FabioBatSilva/DDC-1978

Fix DDC-1978
  • Loading branch information...
commit 24ec1947a83b82101845889ba4fc7f3cbd0e5a90 2 parents 3965d4f + 331582c
Benjamin Eberlei beberlei authored
103 lib/Doctrine/DBAL/SQLParserUtils.php
@@ -79,43 +79,50 @@ static public function getPlaceholderPositions($statement, $isPositional = true)
79 79 /**
80 80 * For a positional query this method can rewrite the sql statement with regard to array parameters.
81 81 *
82   - * @param string $query
83   - * @param array $params
84   - * @param array $types
  82 + * @param string $query The SQL query to execute.
  83 + * @param array $params The parameters to bind to the query.
  84 + * @param array $types The types the previous parameters are in.
  85 + *
85 86 * @return array
86 87 */
87 88 static public function expandListParameters($query, $params, $types)
88 89 {
89   - $isPositional = is_int(key($params));
  90 + $isPositional = is_int(key($params));
90 91 $arrayPositions = array();
91   - $bindIndex = -1;
  92 + $bindIndex = -1;
  93 +
92 94 foreach ($types as $name => $type) {
93 95 ++$bindIndex;
94   - if ($type === Connection::PARAM_INT_ARRAY || $type === Connection::PARAM_STR_ARRAY) {
95   - if ($isPositional) {
96   - $name = $bindIndex;
97   - }
98 96
99   - $arrayPositions[$name] = false;
  97 + if ($type !== Connection::PARAM_INT_ARRAY && $type !== Connection::PARAM_STR_ARRAY) {
  98 + continue;
  99 + }
  100 +
  101 + if ($isPositional) {
  102 + $name = $bindIndex;
100 103 }
  104 +
  105 + $arrayPositions[$name] = false;
101 106 }
102 107
103   - if ((!$arrayPositions && $isPositional) || (count($params) != count($types))) {
  108 + if (( ! $arrayPositions && $isPositional) || (count($params) != count($types))) {
104 109 return array($query, $params, $types);
105 110 }
106 111
107 112 $paramPos = self::getPlaceholderPositions($query, $isPositional);
  113 +
108 114 if ($isPositional) {
109 115 $paramOffset = 0;
110 116 $queryOffset = 0;
  117 +
111 118 foreach ($paramPos as $needle => $needlePos) {
112   - if (!isset($arrayPositions[$needle])) {
  119 + if ( ! isset($arrayPositions[$needle])) {
113 120 continue;
114 121 }
115 122
116   - $needle += $paramOffset;
  123 + $needle += $paramOffset;
117 124 $needlePos += $queryOffset;
118   - $len = count($params[$needle]);
  125 + $count = count($params[$needle]);
119 126
120 127 $params = array_merge(
121 128 array_slice($params, 0, $needle),
@@ -125,50 +132,52 @@ static public function expandListParameters($query, $params, $types)
125 132
126 133 $types = array_merge(
127 134 array_slice($types, 0, $needle),
128   - array_fill(0, $len, $types[$needle] - Connection::ARRAY_PARAM_OFFSET), // array needles are at PDO::PARAM_* + 100
  135 + array_fill(0, $count, $types[$needle] - Connection::ARRAY_PARAM_OFFSET), // array needles are at PDO::PARAM_* + 100
129 136 array_slice($types, $needle + 1)
130 137 );
131 138
132   - $expandStr = implode(", ", array_fill(0, $len, "?"));
133   - $query = substr($query, 0, $needlePos) . $expandStr . substr($query, $needlePos + 1);
  139 + $expandStr = implode(", ", array_fill(0, $count, "?"));
  140 + $query = substr($query, 0, $needlePos) . $expandStr . substr($query, $needlePos + 1);
134 141
135   - $paramOffset += ($len - 1); // Grows larger by number of parameters minus the replaced needle.
  142 + $paramOffset += ($count - 1); // Grows larger by number of parameters minus the replaced needle.
136 143 $queryOffset += (strlen($expandStr) - 1);
137 144 }
138 145
139   - } else {
140   - $queryOffset= 0;
141   - $typesOrd = array();
142   - $paramsOrd = array();
143   - foreach ($paramPos as $pos => $paramName) {
144   - $paramLen = strlen($paramName) + 1;
145   - $value = $params[$paramName];
146   -
147   - if (!isset($arrayPositions[$paramName])) {
148   - $pos += $queryOffset;
149   - $queryOffset -= ($paramLen - 1);
150   - $paramsOrd[] = $value;
151   - $typesOrd[] = $types[$paramName];
152   - $query = substr($query, 0, $pos) . '?' . substr($query, ($pos + $paramLen));
153   - } else {
154   - $len = count($value);
155   - $expandStr = implode(", ", array_fill(0, $len, "?"));
  146 + return array($query, $params, $types);
  147 + }
156 148
157   - foreach ($value as $val) {
158   - $paramsOrd[] = $val;
159   - $typesOrd[] = $types[$paramName] - Connection::ARRAY_PARAM_OFFSET;
160   - }
161 149
162   - $pos += $queryOffset;
163   - $queryOffset += (strlen($expandStr) - $paramLen);
164   - $query = substr($query, 0, $pos) . $expandStr . substr($query, ($pos + $paramLen));
165   - }
  150 + $queryOffset = 0;
  151 + $typesOrd = array();
  152 + $paramsOrd = array();
  153 +
  154 + foreach ($paramPos as $pos => $paramName) {
  155 + $paramLen = strlen($paramName) + 1;
  156 + $value = $params[$paramName];
  157 +
  158 + if ( ! isset($arrayPositions[$paramName])) {
  159 + $pos += $queryOffset;
  160 + $queryOffset -= ($paramLen - 1);
  161 + $paramsOrd[] = $value;
  162 + $typesOrd[] = $types[$paramName];
  163 + $query = substr($query, 0, $pos) . '?' . substr($query, ($pos + $paramLen));
  164 +
  165 + continue;
  166 + }
  167 +
  168 + $count = count($value);
  169 + $expandStr = $count > 0 ? implode(', ', array_fill(0, $count, '?')) : '?';
  170 +
  171 + foreach ($value as $val) {
  172 + $paramsOrd[] = $val;
  173 + $typesOrd[] = $types[$paramName] - Connection::ARRAY_PARAM_OFFSET;
166 174 }
167 175
168   - $types = $typesOrd;
169   - $params = $paramsOrd;
  176 + $pos += $queryOffset;
  177 + $queryOffset += (strlen($expandStr) - $paramLen);
  178 + $query = substr($query, 0, $pos) . $expandStr . substr($query, ($pos + $paramLen));
170 179 }
171 180
172   - return array($query, $params, $types);
  181 + return array($query, $paramsOrd, $typesOrd);
173 182 }
174   -}
  183 +}
36 tests/Doctrine/Tests/DBAL/SQLParserUtilsTest.php
@@ -98,6 +98,24 @@ static public function dataExpandListParameters()
98 98 array(1, 2, 3, 4, 5),
99 99 array(\PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT)
100 100 ),
  101 + // Positional : Empty "integer" array DDC-1978
  102 + array(
  103 + "SELECT * FROM Foo WHERE foo IN (?)",
  104 + array('foo'=>array()),
  105 + array('foo'=>Connection::PARAM_INT_ARRAY),
  106 + 'SELECT * FROM Foo WHERE foo IN (?)',
  107 + array(),
  108 + array()
  109 + ),
  110 + // Positional : Empty "str" array DDC-1978
  111 + array(
  112 + "SELECT * FROM Foo WHERE foo IN (?)",
  113 + array('foo'=>array()),
  114 + array('foo'=>Connection::PARAM_STR_ARRAY),
  115 + 'SELECT * FROM Foo WHERE foo IN (?)',
  116 + array(),
  117 + array()
  118 + ),
101 119 // Named parameters : Very simple with param int
102 120 array(
103 121 "SELECT * FROM Foo WHERE foo = :foo",
@@ -191,6 +209,24 @@ static public function dataExpandListParameters()
191 209 array(2, 3, 2),
192 210 array(\PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT)
193 211 ),
  212 + // Named parameters : Empty "integer" array DDC-1978
  213 + array(
  214 + "SELECT * FROM Foo WHERE foo IN (:foo)",
  215 + array('foo'=>array()),
  216 + array('foo'=>Connection::PARAM_INT_ARRAY),
  217 + 'SELECT * FROM Foo WHERE foo IN (?)',
  218 + array(),
  219 + array()
  220 + ),
  221 + // Named parameters : Two empty "str" array DDC-1978
  222 + array(
  223 + "SELECT * FROM Foo WHERE foo IN (:foo) OR bar IN (:bar)",
  224 + array('foo'=>array(), 'bar'=>array()),
  225 + array('foo'=>Connection::PARAM_STR_ARRAY, 'bar'=>Connection::PARAM_STR_ARRAY),
  226 + 'SELECT * FROM Foo WHERE foo IN (?) OR bar IN (?)',
  227 + array(),
  228 + array()
  229 + ),
194 230 );
195 231 }
196 232

0 comments on commit 24ec194

Please sign in to comment.
Something went wrong with that request. Please try again.