SQLParserUtilsTest.php 23.5 KB
Newer Older
1 2 3 4 5
<?php

namespace Doctrine\Tests\DBAL;

use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\ParameterType;
7 8 9 10
use Doctrine\DBAL\SQLParserUtils;

/**
 * @group DBAL-78
11
 * @group DDC-1372
12 13 14
 */
class SQLParserUtilsTest extends \Doctrine\Tests\DbalTestCase
{
15
    public function dataGetPlaceholderPositions()
16 17 18 19 20
    {
        return array(
            // none
            array('SELECT * FROM Foo', true, array()),
            array('SELECT * FROM Foo', false, array()),
21

22
            // Positionals
23 24 25
            array('SELECT ?', true, array(7)),
            array('SELECT * FROM Foo WHERE bar IN (?, ?, ?)', true, array(32, 35, 38)),
            array('SELECT ? FROM ?', true, array(7, 14)),
26 27
            array('SELECT "?" FROM foo', true, array()),
            array("SELECT '?' FROM foo", true, array()),
28
            array("SELECT `?` FROM foo", true, array()), // Ticket DBAL-552
29
            array("SELECT [?] FROM foo", true, array()),
30 31 32
            array("SELECT 'Doctrine\DBAL?' FROM foo", true, array()), // Ticket DBAL-558
            array('SELECT "Doctrine\DBAL?" FROM foo', true, array()), // Ticket DBAL-558
            array('SELECT `Doctrine\DBAL?` FROM foo', true, array()), // Ticket DBAL-558
33
            array('SELECT [Doctrine\DBAL?] FROM foo', true, array()), // Ticket DBAL-558
34 35
            array('SELECT "?" FROM foo WHERE bar = ?', true, array(32)),
            array("SELECT '?' FROM foo WHERE bar = ?", true, array(32)),
36
            array("SELECT `?` FROM foo WHERE bar = ?", true, array(32)), // Ticket DBAL-552
37
            array("SELECT [?] FROM foo WHERE bar = ?", true, array(32)),
38
            array('SELECT * FROM foo WHERE jsonb_exists_any(foo.bar, ARRAY[?])', true, array(56)), // Ticket GH-2295
39 40 41
            array("SELECT 'Doctrine\DBAL?' FROM foo WHERE bar = ?", true, array(45)), // Ticket DBAL-558
            array('SELECT "Doctrine\DBAL?" FROM foo WHERE bar = ?', true, array(45)), // Ticket DBAL-558
            array('SELECT `Doctrine\DBAL?` FROM foo WHERE bar = ?', true, array(45)), // Ticket DBAL-558
42
            array('SELECT [Doctrine\DBAL?] FROM foo WHERE bar = ?', true, array(45)), // Ticket DBAL-558
43
            array("SELECT * FROM FOO WHERE bar = 'it\\'s a trap? \\\\' OR bar = ?\nAND baz = \"\\\"quote\\\" me on it? \\\\\" OR baz = ?", true, array(58, 104)),
44
            array('SELECT * FROM foo WHERE foo = ? AND bar = ?', true, array(1 => 42, 0 => 30)), // explicit keys
45

46
            // named
47 48 49 50 51
            array('SELECT :foo FROM :bar', false, array(7 => 'foo', 17 => 'bar')),
            array('SELECT * FROM Foo WHERE bar IN (:name1, :name2)', false, array(32 => 'name1', 40 => 'name2')),
            array('SELECT ":foo" FROM Foo WHERE bar IN (:name1, :name2)', false, array(37 => 'name1', 45 => 'name2')),
            array("SELECT ':foo' FROM Foo WHERE bar IN (:name1, :name2)", false, array(37 => 'name1', 45 => 'name2')),
            array('SELECT :foo_id', false, array(7 => 'foo_id')), // Ticket DBAL-231
52 53
            array('SELECT @rank := 1', false, array()), // Ticket DBAL-398
            array('SELECT @rank := 1 AS rank, :foo AS foo FROM :bar', false, array(27 => 'foo', 44 => 'bar')), // Ticket DBAL-398
54
            array('SELECT * FROM Foo WHERE bar > :start_date AND baz > :start_date', false, array(30 => 'start_date', 52 =>  'start_date')), // Ticket GH-113
55 56
            array('SELECT foo::date as date FROM Foo WHERE bar > :start_date AND baz > :start_date', false, array(46 => 'start_date', 68 =>  'start_date')), // Ticket GH-259
            array('SELECT `d.ns:col_name` FROM my_table d WHERE `d.date` >= :param1', false, array(57 => 'param1')), // Ticket DBAL-552
57
            array('SELECT [d.ns:col_name] FROM my_table d WHERE [d.date] >= :param1', false, array(57 => 'param1')), // Ticket DBAL-552
58
            array('SELECT * FROM foo WHERE jsonb_exists_any(foo.bar, ARRAY[:foo])', false, array(56 => 'foo')), // Ticket GH-2295
59 60 61 62 63 64 65 66
            array(
<<<'SQLDATA'
SELECT * FROM foo WHERE 
bar = ':not_a_param1 ''":not_a_param2"'''
OR bar=:a_param1
OR bar=:a_param2||':not_a_param3'
OR bar=':not_a_param4 '':not_a_param5'' :not_a_param6'
OR bar=''
andreas's avatar
andreas committed
67
OR bar=:a_param3
68
SQLDATA
andreas's avatar
andreas committed
69
                , false, array(74 => 'a_param1', 91 => 'a_param2', 190 => 'a_param3')
70
            ),
71 72 73 74 75
            array("SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data WHERE (data.description LIKE :condition_0 ESCAPE '\\\\') AND (data.description LIKE :condition_1 ESCAPE '\\\\') ORDER BY id ASC", false, array(121 => 'condition_0', 174 => 'condition_1')),
            array('SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data WHERE (data.description LIKE :condition_0 ESCAPE "\\\\") AND (data.description LIKE :condition_1 ESCAPE "\\\\") ORDER BY id ASC', false, array(121 => 'condition_0', 174 => 'condition_1')),
            array('SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data WHERE (data.description LIKE :condition_0 ESCAPE "\\\\") AND (data.description LIKE :condition_1 ESCAPE \'\\\\\') ORDER BY id ASC', false, array(121 => 'condition_0', 174 => 'condition_1')),
            array('SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data WHERE (data.description LIKE :condition_0 ESCAPE `\\\\`) AND (data.description LIKE :condition_1 ESCAPE `\\\\`) ORDER BY id ASC', false, array(121 => 'condition_0', 174 => 'condition_1')),
            array('SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data WHERE (data.description LIKE :condition_0 ESCAPE \'\\\\\') AND (data.description LIKE :condition_1 ESCAPE `\\\\`) ORDER BY id ASC', false, array(121 => 'condition_0', 174 => 'condition_1')),
Luís Cobucci's avatar
Luís Cobucci committed
76

77 78
        );
    }
79

80 81 82 83 84 85
    /**
     * @dataProvider dataGetPlaceholderPositions
     */
    public function testGetPlaceholderPositions($query, $isPositional, $expectedParamPos)
    {
        $actualParamPos = SQLParserUtils::getPlaceholderPositions($query, $isPositional);
86
        self::assertEquals($expectedParamPos, $actualParamPos);
87
    }
88

89
    public function dataExpandListParameters()
90 91 92 93 94
    {
        return array(
            // Positional: Very simple with one needle
            array(
                "SELECT * FROM Foo WHERE foo IN (?)",
95 96
                array(array(1, 2, 3)),
                array(Connection::PARAM_INT_ARRAY),
97
                'SELECT * FROM Foo WHERE foo IN (?, ?, ?)',
98
                array(1, 2, 3),
99
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER)
100 101 102 103
            ),
            // Positional: One non-list before d one after list-needle
            array(
                "SELECT * FROM Foo WHERE foo = ? AND bar IN (?)",
104
                array("string", array(1, 2, 3)),
105
                array(ParameterType::STRING, Connection::PARAM_INT_ARRAY),
106
                'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?)',
107
                array("string", 1, 2, 3),
108
                array(ParameterType::STRING, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER)
109 110 111 112
            ),
            // Positional: One non-list after list-needle
            array(
                "SELECT * FROM Foo WHERE bar IN (?) AND baz = ?",
113
                array(array(1, 2, 3), "foo"),
114
                array(Connection::PARAM_INT_ARRAY, ParameterType::STRING),
115
                'SELECT * FROM Foo WHERE bar IN (?, ?, ?) AND baz = ?',
116
                array(1, 2, 3, "foo"),
117
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING)
118 119 120 121
            ),
            // Positional: One non-list before and one after list-needle
            array(
                "SELECT * FROM Foo WHERE foo = ? AND bar IN (?) AND baz = ?",
122
                array(1, array(1, 2, 3), 4),
123
                array(ParameterType::INTEGER, Connection::PARAM_INT_ARRAY, ParameterType::INTEGER),
124
                'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?) AND baz = ?',
125
                array(1, 1, 2, 3, 4),
126 127 128 129 130 131 132
                array(
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                )
133 134 135 136
            ),
            // Positional: Two lists
            array(
                "SELECT * FROM Foo WHERE foo IN (?, ?)",
137 138
                array(array(1, 2, 3), array(4, 5)),
                array(Connection::PARAM_INT_ARRAY, Connection::PARAM_INT_ARRAY),
139
                'SELECT * FROM Foo WHERE foo IN (?, ?, ?, ?, ?)',
140
                array(1, 2, 3, 4, 5),
141 142 143 144 145 146 147
                array(
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                )
148
            ),
149
            // Positional: Empty "integer" array DDC-1978
Fabio B. Silva's avatar
Fabio B. Silva committed
150 151
            array(
                "SELECT * FROM Foo WHERE foo IN (?)",
152 153 154
                array(array()),
                array(Connection::PARAM_INT_ARRAY),
                'SELECT * FROM Foo WHERE foo IN (NULL)',
Fabio B. Silva's avatar
Fabio B. Silva committed
155 156 157
                array(),
                array()
            ),
158
            // Positional: Empty "str" array DDC-1978
Fabio B. Silva's avatar
Fabio B. Silva committed
159 160
            array(
                "SELECT * FROM Foo WHERE foo IN (?)",
161 162 163
                array(array()),
                array(Connection::PARAM_STR_ARRAY),
                'SELECT * FROM Foo WHERE foo IN (NULL)',
Fabio B. Silva's avatar
Fabio B. Silva committed
164 165 166
                array(),
                array()
            ),
167 168 169 170
            // Positional: explicit keys for params and types
            array(
                "SELECT * FROM Foo WHERE foo = ? AND bar = ? AND baz = ?",
                array(1 => 'bar', 2 => 'baz', 0 => 1),
171
                array(2 => ParameterType::STRING, 1 => ParameterType::STRING),
172 173
                'SELECT * FROM Foo WHERE foo = ? AND bar = ? AND baz = ?',
                array(1 => 'bar', 0 => 1, 2 => 'baz'),
174
                array(1 => ParameterType::STRING, 2 => ParameterType::STRING),
175
            ),
176 177 178 179
            // Positional: explicit keys for array params and array types
            array(
                "SELECT * FROM Foo WHERE foo IN (?) AND bar IN (?) AND baz = ?",
                array(1 => array('bar1', 'bar2'), 2 => true, 0 => array(1, 2, 3)),
180
                array(2 => ParameterType::BOOLEAN, 1 => Connection::PARAM_STR_ARRAY, 0 => Connection::PARAM_INT_ARRAY),
181 182
                'SELECT * FROM Foo WHERE foo IN (?, ?, ?) AND bar IN (?, ?) AND baz = ?',
                array(1, 2, 3, 'bar1', 'bar2', true),
183 184 185 186 187 188 189 190
                array(
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::STRING,
                    ParameterType::STRING,
                    ParameterType::BOOLEAN,
                )
191 192 193 194 195
            ),
            // Positional starts from 1: One non-list before and one after list-needle
            array(
                "SELECT * FROM Foo WHERE foo = ? AND bar IN (?) AND baz = ? AND foo IN (?)",
                array(1 => 1, 2 => array(1, 2, 3), 3 => 4, 4 => array(5, 6)),
196 197 198 199 200 201
                array(
                    1 => ParameterType::INTEGER,
                    2 => Connection::PARAM_INT_ARRAY,
                    3 => ParameterType::INTEGER,
                    4 => Connection::PARAM_INT_ARRAY,
                ),
202 203
                'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?) AND baz = ? AND foo IN (?, ?)',
                array(1, 1, 2, 3, 4, 5, 6),
204 205 206 207 208 209 210 211 212
                array(
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                    ParameterType::INTEGER,
                )
213
            ),
214 215 216 217
            //  Named parameters : Very simple with param int
            array(
                "SELECT * FROM Foo WHERE foo = :foo",
                array('foo'=>1),
218
                array('foo' => ParameterType::INTEGER),
219 220
                'SELECT * FROM Foo WHERE foo = ?',
                array(1),
221
                array(ParameterType::INTEGER),
222
            ),
223

224 225 226 227
             //  Named parameters : Very simple with param int and string
            array(
                "SELECT * FROM Foo WHERE foo = :foo AND bar = :bar",
                array('bar'=>'Some String','foo'=>1),
228
                array('foo' => ParameterType::INTEGER, 'bar' => ParameterType::STRING),
229 230
                'SELECT * FROM Foo WHERE foo = ? AND bar = ?',
                array(1,'Some String'),
231
                array(ParameterType::INTEGER, ParameterType::STRING)
232 233 234 235 236 237 238 239
            ),
            //  Named parameters : Very simple with one needle
            array(
                "SELECT * FROM Foo WHERE foo IN (:foo)",
                array('foo'=>array(1, 2, 3)),
                array('foo'=>Connection::PARAM_INT_ARRAY),
                'SELECT * FROM Foo WHERE foo IN (?, ?, ?)',
                array(1, 2, 3),
240
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER),
241 242 243 244 245
            ),
            // Named parameters: One non-list before d one after list-needle
            array(
                "SELECT * FROM Foo WHERE foo = :foo AND bar IN (:bar)",
                array('foo'=>"string", 'bar'=>array(1, 2, 3)),
246
                array('foo' => ParameterType::STRING, 'bar' => Connection::PARAM_INT_ARRAY),
247 248
                'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?)',
                array("string", 1, 2, 3),
249
                array(ParameterType::STRING, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER)
250 251 252 253 254
            ),
            // Named parameters: One non-list after list-needle
            array(
                "SELECT * FROM Foo WHERE bar IN (:bar) AND baz = :baz",
                array('bar'=>array(1, 2, 3), 'baz'=>"foo"),
255
                array('bar'=>Connection::PARAM_INT_ARRAY, 'baz'=>ParameterType::STRING),
256 257
                'SELECT * FROM Foo WHERE bar IN (?, ?, ?) AND baz = ?',
                array(1, 2, 3, "foo"),
258
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING)
259 260 261 262 263
            ),
            // Named parameters: One non-list before and one after list-needle
            array(
                "SELECT * FROM Foo WHERE foo = :foo AND bar IN (:bar) AND baz = :baz",
                array('bar'=>array(1, 2, 3),'foo'=>1, 'baz'=>4),
264
                array('bar'=>Connection::PARAM_INT_ARRAY, 'foo'=>ParameterType::INTEGER, 'baz'=>ParameterType::INTEGER),
265 266
                'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?) AND baz = ?',
                array(1, 1, 2, 3, 4),
267
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER)
268 269 270 271 272 273 274 275
            ),
            // Named parameters: Two lists
            array(
                "SELECT * FROM Foo WHERE foo IN (:a, :b)",
                array('b'=>array(4, 5),'a'=>array(1, 2, 3)),
                array('a'=>Connection::PARAM_INT_ARRAY, 'b'=>Connection::PARAM_INT_ARRAY),
                'SELECT * FROM Foo WHERE foo IN (?, ?, ?, ?, ?)',
                array(1, 2, 3, 4, 5),
276
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER)
277 278 279 280 281
            ),
            //  Named parameters : With the same name arg type string
            array(
                "SELECT * FROM Foo WHERE foo <> :arg AND bar = :arg",
                array('arg'=>"Some String"),
282
                array('arg'=>ParameterType::STRING),
283 284
                'SELECT * FROM Foo WHERE foo <> ? AND bar = ?',
                array("Some String","Some String"),
285
                array(ParameterType::STRING,ParameterType::STRING,)
286 287 288 289 290 291 292 293
            ),
             //  Named parameters : With the same name arg
            array(
                "SELECT * FROM Foo WHERE foo IN (:arg) AND NOT bar IN (:arg)",
                array('arg'=>array(1, 2, 3)),
                array('arg'=>Connection::PARAM_INT_ARRAY),
                'SELECT * FROM Foo WHERE foo IN (?, ?, ?) AND NOT bar IN (?, ?, ?)',
                array(1, 2, 3, 1, 2, 3),
294
                array(ParameterType::INTEGER,ParameterType::INTEGER, ParameterType::INTEGER,ParameterType::INTEGER,ParameterType::INTEGER, ParameterType::INTEGER)
295
            ),
296 297 298 299 300

             //  Named parameters : Same name, other name in between DBAL-299
            array(
                "SELECT * FROM Foo WHERE (:foo = 2) AND (:bar = 3) AND (:foo = 2)",
                array('foo'=>2,'bar'=>3),
301
                array('foo'=>ParameterType::INTEGER,'bar'=>ParameterType::INTEGER),
302 303
                'SELECT * FROM Foo WHERE (? = 2) AND (? = 3) AND (? = 2)',
                array(2, 3, 2),
304
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER)
305
            ),
Fabio B. Silva's avatar
Fabio B. Silva committed
306 307 308 309 310
             //  Named parameters : Empty "integer" array DDC-1978
            array(
                "SELECT * FROM Foo WHERE foo IN (:foo)",
                array('foo'=>array()),
                array('foo'=>Connection::PARAM_INT_ARRAY),
311
                'SELECT * FROM Foo WHERE foo IN (NULL)',
Fabio B. Silva's avatar
Fabio B. Silva committed
312 313 314 315 316 317 318 319
                array(),
                array()
            ),
             //  Named parameters : Two empty "str" array DDC-1978
            array(
                "SELECT * FROM Foo WHERE foo IN (:foo) OR bar IN (:bar)",
                array('foo'=>array(), 'bar'=>array()),
                array('foo'=>Connection::PARAM_STR_ARRAY, 'bar'=>Connection::PARAM_STR_ARRAY),
320
                'SELECT * FROM Foo WHERE foo IN (NULL) OR bar IN (NULL)',
Fabio B. Silva's avatar
Fabio B. Silva committed
321 322 323
                array(),
                array()
            ),
324 325 326 327 328 329
            array(
                "SELECT * FROM Foo WHERE foo IN (:foo) OR bar = :bar OR baz = :baz",
                array('foo' => array(1, 2), 'bar' => 'bar', 'baz' => 'baz'),
                array('foo' => Connection::PARAM_INT_ARRAY, 'baz' => 'string'),
                'SELECT * FROM Foo WHERE foo IN (?, ?) OR bar = ? OR baz = ?',
                array(1, 2, 'bar', 'baz'),
330
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING, 'string')
331 332 333 334 335 336 337
            ),
            array(
                "SELECT * FROM Foo WHERE foo IN (:foo) OR bar = :bar",
                array('foo' => array(1, 2), 'bar' => 'bar'),
                array('foo' => Connection::PARAM_INT_ARRAY),
                'SELECT * FROM Foo WHERE foo IN (?, ?) OR bar = ?',
                array(1, 2, 'bar'),
338
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING)
339 340 341 342 343
            ),
            // Params/types with colons
            array(
                "SELECT * FROM Foo WHERE foo = :foo OR bar = :bar",
                array(':foo' => 'foo', ':bar' => 'bar'),
344
                array(':foo' => ParameterType::INTEGER),
345 346
                'SELECT * FROM Foo WHERE foo = ? OR bar = ?',
                array('foo', 'bar'),
347
                array(ParameterType::INTEGER, ParameterType::STRING)
348 349 350 351
            ),
            array(
                "SELECT * FROM Foo WHERE foo = :foo OR bar = :bar",
                array(':foo' => 'foo', ':bar' => 'bar'),
352
                array(':foo' => ParameterType::INTEGER, 'bar' => ParameterType::INTEGER),
353 354
                'SELECT * FROM Foo WHERE foo = ? OR bar = ?',
                array('foo', 'bar'),
355
                array(ParameterType::INTEGER, ParameterType::INTEGER)
356 357 358 359 360 361 362
            ),
            array(
                "SELECT * FROM Foo WHERE foo IN (:foo) OR bar = :bar",
                array(':foo' => array(1, 2), ':bar' => 'bar'),
                array('foo' => Connection::PARAM_INT_ARRAY),
                'SELECT * FROM Foo WHERE foo IN (?, ?) OR bar = ?',
                array(1, 2, 'bar'),
363
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING)
364 365 366 367 368 369 370
            ),
            array(
                "SELECT * FROM Foo WHERE foo IN (:foo) OR bar = :bar",
                array('foo' => array(1, 2), 'bar' => 'bar'),
                array(':foo' => Connection::PARAM_INT_ARRAY),
                'SELECT * FROM Foo WHERE foo IN (?, ?) OR bar = ?',
                array(1, 2, 'bar'),
371
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING)
372
            ),
373 374 375 376
            // DBAL-522 - null valued parameters are not considered
            array(
                'INSERT INTO Foo (foo, bar) values (:foo, :bar)',
                array('foo' => 1, 'bar' => null),
377
                array(':foo' => ParameterType::INTEGER, ':bar' => ParameterType::NULL),
378 379
                'INSERT INTO Foo (foo, bar) values (?, ?)',
                array(1, null),
380
                array(ParameterType::INTEGER, ParameterType::NULL)
381 382 383 384
            ),
            array(
                'INSERT INTO Foo (foo, bar) values (?, ?)',
                array(1, null),
385
                array(ParameterType::INTEGER, ParameterType::NULL),
386 387
                'INSERT INTO Foo (foo, bar) values (?, ?)',
                array(1, null),
388
                array(ParameterType::INTEGER, ParameterType::NULL)
389
            ),
390 391 392 393
            // DBAL-1205 - Escaped single quotes SQL- and C-Style
            array(
                "SELECT * FROM Foo WHERE foo = :foo||''':not_a_param''\\'' OR bar = ''':not_a_param''\\'':bar",
                array(':foo' => 1, ':bar' => 2),
394
                array(':foo' => ParameterType::INTEGER, 'bar' => ParameterType::INTEGER),
395 396
                'SELECT * FROM Foo WHERE foo = ?||\'\'\':not_a_param\'\'\\\'\' OR bar = \'\'\':not_a_param\'\'\\\'\'?',
                array(1, 2),
397
                array(ParameterType::INTEGER, ParameterType::INTEGER)
398
            ),
399 400
        );
    }
401

402 403 404 405 406 407
    /**
     * @dataProvider dataExpandListParameters
     */
    public function testExpandListParameters($q, $p, $t, $expectedQuery, $expectedParams, $expectedTypes)
    {
        list($query, $params, $types) = SQLParserUtils::expandListParameters($q, $p, $t);
408

409 410 411
        self::assertEquals($expectedQuery, $query, "Query was not rewritten correctly.");
        self::assertEquals($expectedParams, $params, "Params dont match");
        self::assertEquals($expectedTypes, $types, "Types dont match");
412
    }
413

414
    public function dataQueryWithMissingParameters()
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454
    {
        return array(
            array(
                "SELECT * FROM foo WHERE bar = :param",
                array('other' => 'val'),
                array(),
            ),
            array(
                "SELECT * FROM foo WHERE bar = :param",
                array(),
                array(),
            ),
            array(
                "SELECT * FROM foo WHERE bar = :param",
                array(),
                array('param' => Connection::PARAM_INT_ARRAY),
            ),
            array(
                "SELECT * FROM foo WHERE bar = :param",
                array(),
                array(':param' => Connection::PARAM_INT_ARRAY),
            ),
            array(
                "SELECT * FROM foo WHERE bar = :param",
                array(),
                array('bar' => Connection::PARAM_INT_ARRAY),
            ),
             array(
                "SELECT * FROM foo WHERE bar = :param",
                array('bar' => 'value'),
                array('bar' => Connection::PARAM_INT_ARRAY),
            ),
        );
    }

    /**
     * @dataProvider dataQueryWithMissingParameters
     */
    public function testExceptionIsThrownForMissingParam($query, $params, $types = array())
    {
Luís Cobucci's avatar
Luís Cobucci committed
455
        $this->expectException(
456 457 458 459 460 461
            'Doctrine\DBAL\SQLParserUtilsException',
            'Value for :param not found in params array. Params array key should be "param"'
        );

        SQLParserUtils::expandListParameters($query, $params, $types);
    }
462
}