Passed
Pull Request — master (#3120)
by Sergei
12:25
created

SQLParserUtilsTest::dataExpandListParameters()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 309
Code Lines 245

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 309
rs 8.2857
c 0
b 0
f 0
cc 1
eloc 245
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Doctrine\Tests\DBAL;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\ParameterType;
7
use Doctrine\DBAL\SQLParserUtils;
8
9
/**
10
 * @group DBAL-78
11
 * @group DDC-1372
12
 */
13
class SQLParserUtilsTest extends \Doctrine\Tests\DbalTestCase
14
{
15
    public function dataGetPlaceholderPositions()
16
    {
17
        return array(
18
            // none
19
            array('SELECT * FROM Foo', true, array()),
20
            array('SELECT * FROM Foo', false, array()),
21
22
            // Positionals
23
            array('SELECT ?', true, array(7)),
24
            array('SELECT * FROM Foo WHERE bar IN (?, ?, ?)', true, array(32, 35, 38)),
25
            array('SELECT ? FROM ?', true, array(7, 14)),
26
            array('SELECT "?" FROM foo', true, array()),
27
            array("SELECT '?' FROM foo", true, array()),
28
            array("SELECT `?` FROM foo", true, array()), // Ticket DBAL-552
29
            array("SELECT [?] FROM foo", true, array()),
30
            array("SELECT 'Doctrine\DBAL?' FROM foo", true, array()), // Ticket DBAL-558
31
            array('SELECT "Doctrine\DBAL?" FROM foo', true, array()), // Ticket DBAL-558
32
            array('SELECT `Doctrine\DBAL?` FROM foo', true, array()), // Ticket DBAL-558
33
            array('SELECT [Doctrine\DBAL?] FROM foo', true, array()), // Ticket DBAL-558
34
            array('SELECT "?" FROM foo WHERE bar = ?', true, array(32)),
35
            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
            array("SELECT 'Doctrine\DBAL?' FROM foo WHERE bar = ?", true, array(45)), // Ticket DBAL-558
40
            array('SELECT "Doctrine\DBAL?" FROM foo WHERE bar = ?', true, array(45)), // Ticket DBAL-558
41
            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
            array('SELECT :foo FROM :bar', false, array(7 => 'foo', 17 => 'bar')),
48
            array('SELECT * FROM Foo WHERE bar IN (:name1, :name2)', false, array(32 => 'name1', 40 => 'name2')),
49
            array('SELECT ":foo" FROM Foo WHERE bar IN (:name1, :name2)', false, array(37 => 'name1', 45 => 'name2')),
50
            array("SELECT ':foo' FROM Foo WHERE bar IN (:name1, :name2)", false, array(37 => 'name1', 45 => 'name2')),
51
            array('SELECT :foo_id', false, array(7 => 'foo_id')), // Ticket DBAL-231
52
            array('SELECT @rank := 1', false, array()), // Ticket DBAL-398
53
            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
            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
56
            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
            array(
60
<<<'SQLDATA'
61
SELECT * FROM foo WHERE 
62
bar = ':not_a_param1 ''":not_a_param2"'''
63
OR bar=:a_param1
64
OR bar=:a_param2||':not_a_param3'
65
OR bar=':not_a_param4 '':not_a_param5'' :not_a_param6'
66
OR bar=''
67
OR bar=:a_param3
68
SQLDATA
69
                , false, array(74 => 'a_param1', 91 => 'a_param2', 190 => 'a_param3')
70
            ),
71
            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')),
72
            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')),
73
            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')),
74
            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')),
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')),
76
77
        );
78
    }
79
80
    /**
81
     * @dataProvider dataGetPlaceholderPositions
82
     */
83
    public function testGetPlaceholderPositions($query, $isPositional, $expectedParamPos)
84
    {
85
        $actualParamPos = SQLParserUtils::getPlaceholderPositions($query, $isPositional);
86
        self::assertEquals($expectedParamPos, $actualParamPos);
87
    }
88
89
    public function dataExpandListParameters()
90
    {
91
        return array(
92
            // Positional: Very simple with one needle
93
            array(
94
                "SELECT * FROM Foo WHERE foo IN (?)",
95
                array(array(1, 2, 3)),
96
                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
            // Positional: One non-list before d one after list-needle
102
            array(
103
                "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
            // Positional: One non-list after list-needle
111
            array(
112
                "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
            // Positional: One non-list before and one after list-needle
120
            array(
121
                "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
                array(
127
                    ParameterType::INTEGER,
128
                    ParameterType::INTEGER,
129
                    ParameterType::INTEGER,
130
                    ParameterType::INTEGER,
131
                    ParameterType::INTEGER,
132
                )
133
            ),
134
            // Positional: Two lists
135
            array(
136
                "SELECT * FROM Foo WHERE foo IN (?, ?)",
137
                array(array(1, 2, 3), array(4, 5)),
138
                array(Connection::PARAM_INT_ARRAY, Connection::PARAM_INT_ARRAY),
139
                'SELECT * FROM Foo WHERE foo IN (?, ?, ?, ?, ?)',
140
                array(1, 2, 3, 4, 5),
141
                array(
142
                    ParameterType::INTEGER,
143
                    ParameterType::INTEGER,
144
                    ParameterType::INTEGER,
145
                    ParameterType::INTEGER,
146
                    ParameterType::INTEGER,
147
                )
148
            ),
149
            // Positional: Empty "integer" array DDC-1978
150
            array(
151
                "SELECT * FROM Foo WHERE foo IN (?)",
152
                array(array()),
153
                array(Connection::PARAM_INT_ARRAY),
154
                'SELECT * FROM Foo WHERE foo IN (NULL)',
155
                array(),
156
                array()
157
            ),
158
            // Positional: Empty "str" array DDC-1978
159
            array(
160
                "SELECT * FROM Foo WHERE foo IN (?)",
161
                array(array()),
162
                array(Connection::PARAM_STR_ARRAY),
163
                'SELECT * FROM Foo WHERE foo IN (NULL)',
164
                array(),
165
                array()
166
            ),
167
            // Positional: explicit keys for params and types
168
            array(
169
                "SELECT * FROM Foo WHERE foo = ? AND bar = ? AND baz = ?",
170
                array(1 => 'bar', 2 => 'baz', 0 => 1),
171
                array(2 => ParameterType::STRING, 1 => ParameterType::STRING),
172
                'SELECT * FROM Foo WHERE foo = ? AND bar = ? AND baz = ?',
173
                array(1 => 'bar', 0 => 1, 2 => 'baz'),
174
                array(1 => ParameterType::STRING, 2 => ParameterType::STRING),
175
            ),
176
            // Positional: explicit keys for array params and array types
177
            array(
178
                "SELECT * FROM Foo WHERE foo IN (?) AND bar IN (?) AND baz = ?",
179
                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
                'SELECT * FROM Foo WHERE foo IN (?, ?, ?) AND bar IN (?, ?) AND baz = ?',
182
                array(1, 2, 3, 'bar1', 'bar2', true),
183
                array(
184
                    ParameterType::INTEGER,
185
                    ParameterType::INTEGER,
186
                    ParameterType::INTEGER,
187
                    ParameterType::STRING,
188
                    ParameterType::STRING,
189
                    ParameterType::BOOLEAN,
190
                )
191
            ),
192
            // Positional starts from 1: One non-list before and one after list-needle
193
            array(
194
                "SELECT * FROM Foo WHERE foo = ? AND bar IN (?) AND baz = ? AND foo IN (?)",
195
                array(1 => 1, 2 => array(1, 2, 3), 3 => 4, 4 => array(5, 6)),
196
                array(
197
                    1 => ParameterType::INTEGER,
198
                    2 => Connection::PARAM_INT_ARRAY,
199
                    3 => ParameterType::INTEGER,
200
                    4 => Connection::PARAM_INT_ARRAY,
201
                ),
202
                'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?) AND baz = ? AND foo IN (?, ?)',
203
                array(1, 1, 2, 3, 4, 5, 6),
204
                array(
205
                    ParameterType::INTEGER,
206
                    ParameterType::INTEGER,
207
                    ParameterType::INTEGER,
208
                    ParameterType::INTEGER,
209
                    ParameterType::INTEGER,
210
                    ParameterType::INTEGER,
211
                    ParameterType::INTEGER,
212
                )
213
            ),
214
            //  Named parameters : Very simple with param int
215
            array(
216
                "SELECT * FROM Foo WHERE foo = :foo",
217
                array('foo'=>1),
218
                array('foo' => ParameterType::INTEGER),
219
                'SELECT * FROM Foo WHERE foo = ?',
220
                array(1),
221
                array(ParameterType::INTEGER),
222
            ),
223
224
             //  Named parameters : Very simple with param int and string
225
            array(
226
                "SELECT * FROM Foo WHERE foo = :foo AND bar = :bar",
227
                array('bar'=>'Some String','foo'=>1),
228
                array('foo' => ParameterType::INTEGER, 'bar' => ParameterType::STRING),
229
                'SELECT * FROM Foo WHERE foo = ? AND bar = ?',
230
                array(1,'Some String'),
231
                array(ParameterType::INTEGER, ParameterType::STRING)
232
            ),
233
            //  Named parameters : Very simple with one needle
234
            array(
235
                "SELECT * FROM Foo WHERE foo IN (:foo)",
236
                array('foo'=>array(1, 2, 3)),
237
                array('foo'=>Connection::PARAM_INT_ARRAY),
238
                'SELECT * FROM Foo WHERE foo IN (?, ?, ?)',
239
                array(1, 2, 3),
240
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER),
241
            ),
242
            // Named parameters: One non-list before d one after list-needle
243
            array(
244
                "SELECT * FROM Foo WHERE foo = :foo AND bar IN (:bar)",
245
                array('foo'=>"string", 'bar'=>array(1, 2, 3)),
246
                array('foo' => ParameterType::STRING, 'bar' => Connection::PARAM_INT_ARRAY),
247
                'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?)',
248
                array("string", 1, 2, 3),
249
                array(ParameterType::STRING, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER)
250
            ),
251
            // Named parameters: One non-list after list-needle
252
            array(
253
                "SELECT * FROM Foo WHERE bar IN (:bar) AND baz = :baz",
254
                array('bar'=>array(1, 2, 3), 'baz'=>"foo"),
255
                array('bar'=>Connection::PARAM_INT_ARRAY, 'baz'=>ParameterType::STRING),
256
                'SELECT * FROM Foo WHERE bar IN (?, ?, ?) AND baz = ?',
257
                array(1, 2, 3, "foo"),
258
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING)
259
            ),
260
            // Named parameters: One non-list before and one after list-needle
261
            array(
262
                "SELECT * FROM Foo WHERE foo = :foo AND bar IN (:bar) AND baz = :baz",
263
                array('bar'=>array(1, 2, 3),'foo'=>1, 'baz'=>4),
264
                array('bar'=>Connection::PARAM_INT_ARRAY, 'foo'=>ParameterType::INTEGER, 'baz'=>ParameterType::INTEGER),
265
                'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?) AND baz = ?',
266
                array(1, 1, 2, 3, 4),
267
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER)
268
            ),
269
            // Named parameters: Two lists
270
            array(
271
                "SELECT * FROM Foo WHERE foo IN (:a, :b)",
272
                array('b'=>array(4, 5),'a'=>array(1, 2, 3)),
273
                array('a'=>Connection::PARAM_INT_ARRAY, 'b'=>Connection::PARAM_INT_ARRAY),
274
                'SELECT * FROM Foo WHERE foo IN (?, ?, ?, ?, ?)',
275
                array(1, 2, 3, 4, 5),
276
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER)
277
            ),
278
            //  Named parameters : With the same name arg type string
279
            array(
280
                "SELECT * FROM Foo WHERE foo <> :arg AND bar = :arg",
281
                array('arg'=>"Some String"),
282
                array('arg'=>ParameterType::STRING),
283
                'SELECT * FROM Foo WHERE foo <> ? AND bar = ?',
284
                array("Some String","Some String"),
285
                array(ParameterType::STRING,ParameterType::STRING,)
286
            ),
287
             //  Named parameters : With the same name arg
288
            array(
289
                "SELECT * FROM Foo WHERE foo IN (:arg) AND NOT bar IN (:arg)",
290
                array('arg'=>array(1, 2, 3)),
291
                array('arg'=>Connection::PARAM_INT_ARRAY),
292
                'SELECT * FROM Foo WHERE foo IN (?, ?, ?) AND NOT bar IN (?, ?, ?)',
293
                array(1, 2, 3, 1, 2, 3),
294
                array(ParameterType::INTEGER,ParameterType::INTEGER, ParameterType::INTEGER,ParameterType::INTEGER,ParameterType::INTEGER, ParameterType::INTEGER)
295
            ),
296
297
             //  Named parameters : Same name, other name in between DBAL-299
298
            array(
299
                "SELECT * FROM Foo WHERE (:foo = 2) AND (:bar = 3) AND (:foo = 2)",
300
                array('foo'=>2,'bar'=>3),
301
                array('foo'=>ParameterType::INTEGER,'bar'=>ParameterType::INTEGER),
302
                'SELECT * FROM Foo WHERE (? = 2) AND (? = 3) AND (? = 2)',
303
                array(2, 3, 2),
304
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER)
305
            ),
306
             //  Named parameters : Empty "integer" array DDC-1978
307
            array(
308
                "SELECT * FROM Foo WHERE foo IN (:foo)",
309
                array('foo'=>array()),
310
                array('foo'=>Connection::PARAM_INT_ARRAY),
311
                'SELECT * FROM Foo WHERE foo IN (NULL)',
312
                array(),
313
                array()
314
            ),
315
             //  Named parameters : Two empty "str" array DDC-1978
316
            array(
317
                "SELECT * FROM Foo WHERE foo IN (:foo) OR bar IN (:bar)",
318
                array('foo'=>array(), 'bar'=>array()),
319
                array('foo'=>Connection::PARAM_STR_ARRAY, 'bar'=>Connection::PARAM_STR_ARRAY),
320
                'SELECT * FROM Foo WHERE foo IN (NULL) OR bar IN (NULL)',
321
                array(),
322
                array()
323
            ),
324
            array(
325
                "SELECT * FROM Foo WHERE foo IN (:foo) OR bar = :bar OR baz = :baz",
326
                array('foo' => array(1, 2), 'bar' => 'bar', 'baz' => 'baz'),
327
                array('foo' => Connection::PARAM_INT_ARRAY, 'baz' => 'string'),
328
                'SELECT * FROM Foo WHERE foo IN (?, ?) OR bar = ? OR baz = ?',
329
                array(1, 2, 'bar', 'baz'),
330
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING, 'string')
331
            ),
332
            array(
333
                "SELECT * FROM Foo WHERE foo IN (:foo) OR bar = :bar",
334
                array('foo' => array(1, 2), 'bar' => 'bar'),
335
                array('foo' => Connection::PARAM_INT_ARRAY),
336
                'SELECT * FROM Foo WHERE foo IN (?, ?) OR bar = ?',
337
                array(1, 2, 'bar'),
338
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING)
339
            ),
340
            // Params/types with colons
341
            array(
342
                "SELECT * FROM Foo WHERE foo = :foo OR bar = :bar",
343
                array(':foo' => 'foo', ':bar' => 'bar'),
344
                array(':foo' => ParameterType::INTEGER),
345
                'SELECT * FROM Foo WHERE foo = ? OR bar = ?',
346
                array('foo', 'bar'),
347
                array(ParameterType::INTEGER, ParameterType::STRING)
348
            ),
349
            array(
350
                "SELECT * FROM Foo WHERE foo = :foo OR bar = :bar",
351
                array(':foo' => 'foo', ':bar' => 'bar'),
352
                array(':foo' => ParameterType::INTEGER, 'bar' => ParameterType::INTEGER),
353
                'SELECT * FROM Foo WHERE foo = ? OR bar = ?',
354
                array('foo', 'bar'),
355
                array(ParameterType::INTEGER, ParameterType::INTEGER)
356
            ),
357
            array(
358
                "SELECT * FROM Foo WHERE foo IN (:foo) OR bar = :bar",
359
                array(':foo' => array(1, 2), ':bar' => 'bar'),
360
                array('foo' => Connection::PARAM_INT_ARRAY),
361
                'SELECT * FROM Foo WHERE foo IN (?, ?) OR bar = ?',
362
                array(1, 2, 'bar'),
363
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING)
364
            ),
365
            array(
366
                "SELECT * FROM Foo WHERE foo IN (:foo) OR bar = :bar",
367
                array('foo' => array(1, 2), 'bar' => 'bar'),
368
                array(':foo' => Connection::PARAM_INT_ARRAY),
369
                'SELECT * FROM Foo WHERE foo IN (?, ?) OR bar = ?',
370
                array(1, 2, 'bar'),
371
                array(ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING)
372
            ),
373
            // DBAL-522 - null valued parameters are not considered
374
            array(
375
                'INSERT INTO Foo (foo, bar) values (:foo, :bar)',
376
                array('foo' => 1, 'bar' => null),
377
                array(':foo' => ParameterType::INTEGER, ':bar' => ParameterType::NULL),
378
                'INSERT INTO Foo (foo, bar) values (?, ?)',
379
                array(1, null),
380
                array(ParameterType::INTEGER, ParameterType::NULL)
381
            ),
382
            array(
383
                'INSERT INTO Foo (foo, bar) values (?, ?)',
384
                array(1, null),
385
                array(ParameterType::INTEGER, ParameterType::NULL),
386
                'INSERT INTO Foo (foo, bar) values (?, ?)',
387
                array(1, null),
388
                array(ParameterType::INTEGER, ParameterType::NULL)
389
            ),
390
            // DBAL-1205 - Escaped single quotes SQL- and C-Style
391
            array(
392
                "SELECT * FROM Foo WHERE foo = :foo||''':not_a_param''\\'' OR bar = ''':not_a_param''\\'':bar",
393
                array(':foo' => 1, ':bar' => 2),
394
                array(':foo' => ParameterType::INTEGER, 'bar' => ParameterType::INTEGER),
395
                'SELECT * FROM Foo WHERE foo = ?||\'\'\':not_a_param\'\'\\\'\' OR bar = \'\'\':not_a_param\'\'\\\'\'?',
396
                array(1, 2),
397
                array(ParameterType::INTEGER, ParameterType::INTEGER)
398
            ),
399
        );
400
    }
401
402
    /**
403
     * @dataProvider dataExpandListParameters
404
     */
405
    public function testExpandListParameters($q, $p, $t, $expectedQuery, $expectedParams, $expectedTypes)
406
    {
407
        list($query, $params, $types) = SQLParserUtils::expandListParameters($q, $p, $t);
408
409
        self::assertEquals($expectedQuery, $query, "Query was not rewritten correctly.");
410
        self::assertEquals($expectedParams, $params, "Params dont match");
411
        self::assertEquals($expectedTypes, $types, "Types dont match");
412
    }
413
414
    public function dataQueryWithMissingParameters()
415
    {
416
        return array(
417
            array(
418
                "SELECT * FROM foo WHERE bar = :param",
419
                array('other' => 'val'),
420
                array(),
421
            ),
422
            array(
423
                "SELECT * FROM foo WHERE bar = :param",
424
                array(),
425
                array(),
426
            ),
427
            array(
428
                "SELECT * FROM foo WHERE bar = :param",
429
                array(),
430
                array('param' => Connection::PARAM_INT_ARRAY),
431
            ),
432
            array(
433
                "SELECT * FROM foo WHERE bar = :param",
434
                array(),
435
                array(':param' => Connection::PARAM_INT_ARRAY),
436
            ),
437
            array(
438
                "SELECT * FROM foo WHERE bar = :param",
439
                array(),
440
                array('bar' => Connection::PARAM_INT_ARRAY),
441
            ),
442
             array(
443
                "SELECT * FROM foo WHERE bar = :param",
444
                array('bar' => 'value'),
445
                array('bar' => Connection::PARAM_INT_ARRAY),
446
            ),
447
        );
448
    }
449
450
    /**
451
     * @dataProvider dataQueryWithMissingParameters
452
     */
453
    public function testExceptionIsThrownForMissingParam($query, $params, $types = array())
454
    {
455
        $this->expectException(
456
            'Doctrine\DBAL\SQLParserUtilsException',
457
            'Value for :param not found in params array. Params array key should be "param"'
458
        );
459
460
        SQLParserUtils::expandListParameters($query, $params, $types);
461
    }
462
}
463