Failed Conditions
Pull Request — master (#2617)
by Walt
34:21
created

expectCteWithMaxRowNum()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 3
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Platforms;
4
5
use Doctrine\DBAL\Schema\Column;
6
use Doctrine\DBAL\Schema\ColumnDiff;
7
use Doctrine\DBAL\Schema\Table;
8
use Doctrine\DBAL\Schema\TableDiff;
9
use Doctrine\DBAL\TransactionIsolationLevel;
10
use Doctrine\DBAL\Types\Type;
11
use function sprintf;
12
13
abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCase
14
{
15
    public function getGenerateTableSql()
16
    {
17
        return 'CREATE TABLE test (id INT IDENTITY NOT NULL, test NVARCHAR(255), PRIMARY KEY (id))';
18
    }
19
20
    public function getGenerateTableWithMultiColumnUniqueIndexSql()
21
    {
22
        return array(
23
            'CREATE TABLE test (foo NVARCHAR(255), bar NVARCHAR(255))',
24
            'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar) WHERE foo IS NOT NULL AND bar IS NOT NULL'
25
        );
26
    }
27
28
    public function getGenerateAlterTableSql()
29
    {
30
        return array(
31
            'ALTER TABLE mytable ADD quota INT',
32
            'ALTER TABLE mytable DROP COLUMN foo',
33
            'ALTER TABLE mytable ALTER COLUMN baz NVARCHAR(255) NOT NULL',
34
            "ALTER TABLE mytable ADD CONSTRAINT DF_6B2BD609_78240498 DEFAULT 'def' FOR baz",
35
            'ALTER TABLE mytable ALTER COLUMN bloo BIT NOT NULL',
36
            "ALTER TABLE mytable ADD CONSTRAINT DF_6B2BD609_CECED971 DEFAULT '0' FOR bloo",
37
            "sp_RENAME 'mytable', 'userlist'",
38
            "DECLARE @sql NVARCHAR(MAX) = N''; " .
39
            "SELECT @sql += N'EXEC sp_rename N''' + dc.name + ''', N''' " .
40
            "+ REPLACE(dc.name, '6B2BD609', 'E2B58069') + ''', ''OBJECT'';' " .
41
            "FROM sys.default_constraints dc " .
42
            "JOIN sys.tables tbl ON dc.parent_object_id = tbl.object_id " .
43
            "WHERE tbl.name = 'userlist';" .
44
            "EXEC sp_executesql @sql"
45
        );
46
    }
47
48
    /**
49
     * @expectedException \Doctrine\DBAL\DBALException
50
     */
51
    public function testDoesNotSupportRegexp()
52
    {
53
        $this->_platform->getRegexpExpression();
54
    }
55
56
    public function testGeneratesSqlSnippets()
57
    {
58
        self::assertEquals('CONVERT(date, GETDATE())', $this->_platform->getCurrentDateSQL());
59
        self::assertEquals('CONVERT(time, GETDATE())', $this->_platform->getCurrentTimeSQL());
60
        self::assertEquals('CURRENT_TIMESTAMP', $this->_platform->getCurrentTimestampSQL());
61
        self::assertEquals('"', $this->_platform->getIdentifierQuoteCharacter(), 'Identifier quote character is not correct');
62
        self::assertEquals('(column1 + column2 + column3)', $this->_platform->getConcatExpression('column1', 'column2', 'column3'), 'Concatenation expression is not correct');
63
    }
64
65
    public function testGeneratesTransactionsCommands()
66
    {
67
        self::assertEquals(
68
            'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED',
69
            $this->_platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_UNCOMMITTED)
70
        );
71
        self::assertEquals(
72
            'SET TRANSACTION ISOLATION LEVEL READ COMMITTED',
73
            $this->_platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_COMMITTED)
74
        );
75
        self::assertEquals(
76
            'SET TRANSACTION ISOLATION LEVEL REPEATABLE READ',
77
            $this->_platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::REPEATABLE_READ)
78
        );
79
        self::assertEquals(
80
            'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE',
81
            $this->_platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::SERIALIZABLE)
82
        );
83
    }
84
85
    public function testGeneratesDDLSnippets()
86
    {
87
        $dropDatabaseExpectation = 'DROP DATABASE foobar';
88
89
        self::assertEquals('SELECT * FROM sys.databases', $this->_platform->getListDatabasesSQL());
90
        self::assertEquals('CREATE DATABASE foobar', $this->_platform->getCreateDatabaseSQL('foobar'));
91
        self::assertEquals($dropDatabaseExpectation, $this->_platform->getDropDatabaseSQL('foobar'));
92
        self::assertEquals('DROP TABLE foobar', $this->_platform->getDropTableSQL('foobar'));
93
    }
94
95
    public function testGeneratesTypeDeclarationForIntegers()
96
    {
97
        self::assertEquals(
98
                'INT',
99
                $this->_platform->getIntegerTypeDeclarationSQL(array())
100
        );
101
        self::assertEquals(
102
                'INT IDENTITY',
103
                $this->_platform->getIntegerTypeDeclarationSQL(array('autoincrement' => true)
104
        ));
105
        self::assertEquals(
106
                'INT IDENTITY',
107
                $this->_platform->getIntegerTypeDeclarationSQL(
108
                        array('autoincrement' => true, 'primary' => true)
109
        ));
110
    }
111
112
    public function testGeneratesTypeDeclarationsForStrings()
113
    {
114
        self::assertEquals(
115
                'NCHAR(10)',
116
                $this->_platform->getVarcharTypeDeclarationSQL(
117
                        array('length' => 10, 'fixed' => true)
118
        ));
119
        self::assertEquals(
120
                'NVARCHAR(50)',
121
                $this->_platform->getVarcharTypeDeclarationSQL(array('length' => 50)),
122
                'Variable string declaration is not correct'
123
        );
124
        self::assertEquals(
125
                'NVARCHAR(255)',
126
                $this->_platform->getVarcharTypeDeclarationSQL(array()),
127
                'Long string declaration is not correct'
128
        );
129
        self::assertSame('VARCHAR(MAX)', $this->_platform->getClobTypeDeclarationSQL(array()));
130
        self::assertSame(
131
            'VARCHAR(MAX)',
132
            $this->_platform->getClobTypeDeclarationSQL(array('length' => 5, 'fixed' => true))
133
        );
134
    }
135
136
    public function testPrefersIdentityColumns()
137
    {
138
        self::assertTrue($this->_platform->prefersIdentityColumns());
139
    }
140
141
    public function testSupportsIdentityColumns()
142
    {
143
        self::assertTrue($this->_platform->supportsIdentityColumns());
144
    }
145
146
    public function testSupportsCreateDropDatabase()
147
    {
148
        self::assertTrue($this->_platform->supportsCreateDropDatabase());
149
    }
150
151
    public function testSupportsSchemas()
152
    {
153
        self::assertTrue($this->_platform->supportsSchemas());
154
    }
155
156
    public function testDoesNotSupportSavePoints()
157
    {
158
        self::assertTrue($this->_platform->supportsSavepoints());
159
    }
160
161
    public function getGenerateIndexSql()
162
    {
163
        return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
164
    }
165
166
    public function getGenerateUniqueIndexSql()
167
    {
168
        return 'CREATE UNIQUE INDEX index_name ON test (test, test2) WHERE test IS NOT NULL AND test2 IS NOT NULL';
169
    }
170
171
    public function getGenerateForeignKeySql()
172
    {
173
        return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
174
    }
175
176
    public function testModifyLimitQuery()
177
    {
178
        $querySql = 'SELECT * FROM user';
179
        $alteredSql = 'SELECT TOP 10 * FROM user';
180
        $sql = $this->_platform->modifyLimitQuery($querySql, 10, 0);
181
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
182
    }
183
184
    public function testModifyLimitQueryWithEmptyOffset()
185
    {
186
        $querySql = 'SELECT * FROM user';
187
        $alteredSql = 'SELECT TOP 10 * FROM user';
188
        $sql = $this->_platform->modifyLimitQuery($querySql, 10);
189
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
190
    }
191
192
    public function testModifyLimitQueryWithOffset()
193
    {
194
        if ( ! $this->_platform->supportsLimitOffset()) {
195
            $this->markTestSkipped(sprintf('Platform "%s" does not support offsets in result limiting.', $this->_platform->getName()));
196
        }
197
198
        $querySql = 'SELECT * FROM user ORDER BY username DESC';
199
        $alteredSql = 'SELECT TOP 15 * FROM user ORDER BY username DESC';
200
        $sql = $this->_platform->modifyLimitQuery($querySql, 10, 5);
201
202
        $this->expectCteWithMinAndMaxRowNums($alteredSql, 6, 15, $sql);
203
    }
204
205
    public function testModifyLimitQueryWithAscOrderBy()
206
    {
207
        $querySql = 'SELECT * FROM user ORDER BY username ASC';
208
        $alteredSql = 'SELECT TOP 10 * FROM user ORDER BY username ASC';
209
        $sql = $this->_platform->modifyLimitQuery($querySql, 10);
210
211
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
212
    }
213
214
    public function testModifyLimitQueryWithLowercaseOrderBy()
215
    {
216
        $querySql = 'SELECT * FROM user order by username';
217
        $alteredSql = 'SELECT TOP 10 * FROM user order by username';
218
        $sql = $this->_platform->modifyLimitQuery($querySql, 10);
219
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
220
    }
221
222
    public function testModifyLimitQueryWithDescOrderBy()
223
    {
224
        $querySql = 'SELECT * FROM user ORDER BY username DESC';
225
        $alteredSql = 'SELECT TOP 10 * FROM user ORDER BY username DESC';
226
        $sql = $this->_platform->modifyLimitQuery($querySql, 10);
227
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
228
    }
229
230
    public function testModifyLimitQueryWithMultipleOrderBy()
231
    {
232
        $querySql = 'SELECT * FROM user ORDER BY username DESC, usereamil ASC';
233
        $alteredSql = 'SELECT TOP 10 * FROM user ORDER BY username DESC, usereamil ASC';
234
        $sql = $this->_platform->modifyLimitQuery($querySql, 10);
235
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
236
    }
237
238
    public function testModifyLimitQueryWithSubSelect()
239
    {
240
        $querySql = 'SELECT * FROM (SELECT u.id as uid, u.name as uname) dctrn_result';
241
        $alteredSql = 'SELECT TOP 10 * FROM (SELECT u.id as uid, u.name as uname) dctrn_result';
242
        $sql = $this->_platform->modifyLimitQuery($querySql, 10);
243
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
244
    }
245
246
    public function testModifyLimitQueryWithSubSelectAndOrder()
247
    {
248
        $querySql = 'SELECT * FROM (SELECT u.id as uid, u.name as uname ORDER BY u.name DESC) dctrn_result';
249
        $alteredSql = 'SELECT TOP 10 * FROM (SELECT u.id as uid, u.name as uname) dctrn_result';
250
        $sql = $this->_platform->modifyLimitQuery($querySql, 10);
251
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
252
253
        $querySql = 'SELECT * FROM (SELECT u.id, u.name ORDER BY u.name DESC) dctrn_result';
254
        $alteredSql = 'SELECT TOP 10 * FROM (SELECT u.id, u.name) dctrn_result';
255
        $sql = $this->_platform->modifyLimitQuery($querySql, 10);
256
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
257
    }
258
259
    public function testModifyLimitQueryWithSubSelectAndMultipleOrder()
260
    {
261
        if ( ! $this->_platform->supportsLimitOffset()) {
262
            $this->markTestSkipped(sprintf('Platform "%s" does not support offsets in result limiting.', $this->_platform->getName()));
263
        }
264
265
        $querySql = 'SELECT * FROM (SELECT u.id as uid, u.name as uname ORDER BY u.name DESC, id ASC) dctrn_result';
266
        $alteredSql = 'SELECT TOP 15 * FROM (SELECT u.id as uid, u.name as uname) dctrn_result';
267
        $sql = $this->_platform->modifyLimitQuery($querySql, 10, 5);
268
        $this->expectCteWithMinAndMaxRowNums($alteredSql, 6, 15, $sql);
269
270
        $querySql = 'SELECT * FROM (SELECT u.id uid, u.name uname ORDER BY u.name DESC, id ASC) dctrn_result';
271
        $alteredSql = 'SELECT TOP 15 * FROM (SELECT u.id uid, u.name uname) dctrn_result';
272
        $sql = $this->_platform->modifyLimitQuery($querySql, 10, 5);
273
        $this->expectCteWithMinAndMaxRowNums($alteredSql, 6, 15, $sql);
274
275
        $querySql = 'SELECT * FROM (SELECT u.id, u.name ORDER BY u.name DESC, id ASC) dctrn_result';
276
        $alteredSql = 'SELECT TOP 15 * FROM (SELECT u.id, u.name) dctrn_result';
277
        $sql = $this->_platform->modifyLimitQuery($querySql, 10, 5);
278
        $this->expectCteWithMinAndMaxRowNums($alteredSql, 6, 15, $sql);
279
    }
280
281
    public function testModifyLimitQueryWithFromColumnNames()
282
    {
283
        $querySql = 'SELECT a.fromFoo, fromBar FROM foo';
284
        $alteredSql = 'SELECT TOP 10 a.fromFoo, fromBar FROM foo';
285
        $sql = $this->_platform->modifyLimitQuery($querySql, 10);
286
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
287
    }
288
289
    /**
290
     * @group DBAL-927
291
     */
292
    public function testModifyLimitQueryWithExtraLongQuery()
293
    {
294
        $query = 'SELECT table1.column1, table2.column2, table3.column3, table4.column4, table5.column5, table6.column6, table7.column7, table8.column8 FROM table1, table2, table3, table4, table5, table6, table7, table8 ';
295
        $query.= 'WHERE (table1.column1 = table2.column2) AND (table1.column1 = table3.column3) AND (table1.column1 = table4.column4) AND (table1.column1 = table5.column5) AND (table1.column1 = table6.column6) AND (table1.column1 = table7.column7) AND (table1.column1 = table8.column8) AND (table2.column2 = table3.column3) AND (table2.column2 = table4.column4) AND (table2.column2 = table5.column5) AND (table2.column2 = table6.column6) ';
296
        $query.= 'AND (table2.column2 = table7.column7) AND (table2.column2 = table8.column8) AND (table3.column3 = table4.column4) AND (table3.column3 = table5.column5) AND (table3.column3 = table6.column6) AND (table3.column3 = table7.column7) AND (table3.column3 = table8.column8) AND (table4.column4 = table5.column5) AND (table4.column4 = table6.column6) AND (table4.column4 = table7.column7) AND (table4.column4 = table8.column8) ';
297
        $query.= 'AND (table5.column5 = table6.column6) AND (table5.column5 = table7.column7) AND (table5.column5 = table8.column8) AND (table6.column6 = table7.column7) AND (table6.column6 = table8.column8) AND (table7.column7 = table8.column8)';
298
299
        $alteredSql = 'SELECT TOP 10 table1.column1, table2.column2, table3.column3, table4.column4, table5.column5, table6.column6, table7.column7, table8.column8 FROM table1, table2, table3, table4, table5, table6, table7, table8 ';
300
        $alteredSql.= 'WHERE (table1.column1 = table2.column2) AND (table1.column1 = table3.column3) AND (table1.column1 = table4.column4) AND (table1.column1 = table5.column5) AND (table1.column1 = table6.column6) AND (table1.column1 = table7.column7) AND (table1.column1 = table8.column8) AND (table2.column2 = table3.column3) AND (table2.column2 = table4.column4) AND (table2.column2 = table5.column5) AND (table2.column2 = table6.column6) ';
301
        $alteredSql.= 'AND (table2.column2 = table7.column7) AND (table2.column2 = table8.column8) AND (table3.column3 = table4.column4) AND (table3.column3 = table5.column5) AND (table3.column3 = table6.column6) AND (table3.column3 = table7.column7) AND (table3.column3 = table8.column8) AND (table4.column4 = table5.column5) AND (table4.column4 = table6.column6) AND (table4.column4 = table7.column7) AND (table4.column4 = table8.column8) ';
302
        $alteredSql.= 'AND (table5.column5 = table6.column6) AND (table5.column5 = table7.column7) AND (table5.column5 = table8.column8) AND (table6.column6 = table7.column7) AND (table6.column6 = table8.column8) AND (table7.column7 = table8.column8)';
303
304
        $sql = $this->_platform->modifyLimitQuery($query, 10);
305
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
306
    }
307
308
    /**
309
     * @group DDC-2470
310
     */
311
    public function testModifyLimitQueryWithOrderByClause()
312
    {
313
        if ( ! $this->_platform->supportsLimitOffset()) {
314
            $this->markTestSkipped(sprintf('Platform "%s" does not support offsets in result limiting.', $this->_platform->getName()));
315
        }
316
317
        $sql        = 'SELECT m0_.NOMBRE AS NOMBRE0, m0_.FECHAINICIO AS FECHAINICIO1, m0_.FECHAFIN AS FECHAFIN2 FROM MEDICION m0_ WITH (NOLOCK) INNER JOIN ESTUDIO e1_ ON m0_.ESTUDIO_ID = e1_.ID INNER JOIN CLIENTE c2_ ON e1_.CLIENTE_ID = c2_.ID INNER JOIN USUARIO u3_ ON c2_.ID = u3_.CLIENTE_ID WHERE u3_.ID = ? ORDER BY m0_.FECHAINICIO DESC';
318
        $alteredSql = 'SELECT TOP 15 m0_.NOMBRE AS NOMBRE0, m0_.FECHAINICIO AS FECHAINICIO1, m0_.FECHAFIN AS FECHAFIN2 FROM MEDICION m0_ WITH (NOLOCK) INNER JOIN ESTUDIO e1_ ON m0_.ESTUDIO_ID = e1_.ID INNER JOIN CLIENTE c2_ ON e1_.CLIENTE_ID = c2_.ID INNER JOIN USUARIO u3_ ON c2_.ID = u3_.CLIENTE_ID WHERE u3_.ID = ? ORDER BY m0_.FECHAINICIO DESC';
319
        $actual     = $this->_platform->modifyLimitQuery($sql, 10, 5);
320
321
        $this->expectCteWithMinAndMaxRowNums($alteredSql, 6, 15, $actual);
322
    }
323
324
    /**
325
     * @group DBAL-713
326
     */
327
    public function testModifyLimitQueryWithSubSelectInSelectList()
328
    {
329
        $querySql = "SELECT " .
330
            "u.id, " .
331
            "(u.foo/2) foodiv, " .
332
            "CONCAT(u.bar, u.baz) barbaz, " .
333
            "(SELECT (SELECT COUNT(*) FROM login l WHERE l.profile_id = p.id) FROM profile p WHERE p.user_id = u.id) login_count " .
334
            "FROM user u " .
335
            "WHERE u.status = 'disabled'";
336
        $alteredSql = "SELECT TOP 10 " .
337
            "u.id, " .
338
            "(u.foo/2) foodiv, " .
339
            "CONCAT(u.bar, u.baz) barbaz, " .
340
            "(SELECT (SELECT COUNT(*) FROM login l WHERE l.profile_id = p.id) FROM profile p WHERE p.user_id = u.id) login_count " .
341
            "FROM user u " .
342
            "WHERE u.status = 'disabled'";
343
        $sql = $this->_platform->modifyLimitQuery($querySql, 10);
344
345
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
346
    }
347
348
    /**
349
     * @group DBAL-713
350
     */
351
    public function testModifyLimitQueryWithSubSelectInSelectListAndOrderByClause()
352
    {
353
        if ( ! $this->_platform->supportsLimitOffset()) {
354
            $this->markTestSkipped(sprintf('Platform "%s" does not support offsets in result limiting.', $this->_platform->getName()));
355
        }
356
357
        $querySql = "SELECT " .
358
            "u.id, " .
359
            "(u.foo/2) foodiv, " .
360
            "CONCAT(u.bar, u.baz) barbaz, " .
361
            "(SELECT (SELECT COUNT(*) FROM login l WHERE l.profile_id = p.id) FROM profile p WHERE p.user_id = u.id) login_count " .
362
            "FROM user u " .
363
            "WHERE u.status = 'disabled' " .
364
            "ORDER BY u.username DESC";
365
        $alteredSql = "SELECT TOP 15 " .
366
            "u.id, " .
367
            "(u.foo/2) foodiv, " .
368
            "CONCAT(u.bar, u.baz) barbaz, " .
369
            "(SELECT (SELECT COUNT(*) FROM login l WHERE l.profile_id = p.id) FROM profile p WHERE p.user_id = u.id) login_count " .
370
            "FROM user u " .
371
            "WHERE u.status = 'disabled' " .
372
            "ORDER BY u.username DESC";
373
        $sql = $this->_platform->modifyLimitQuery($querySql, 10, 5);
374
        $this->expectCteWithMinAndMaxRowNums($alteredSql, 6, 15, $sql);
375
    }
376
377
    /**
378
     * @group DBAL-834
379
     */
380
    public function testModifyLimitQueryWithAggregateFunctionInOrderByClause()
381
    {
382
        $querySql = "SELECT " .
383
            "MAX(heading_id) aliased, " .
384
            "code " .
385
            "FROM operator_model_operator " .
386
            "GROUP BY code " .
387
            "ORDER BY MAX(heading_id) DESC";
388
        $alteredSql = "SELECT TOP 1 " .
389
            "MAX(heading_id) aliased, " .
390
            "code " .
391
            "FROM operator_model_operator " .
392
            "GROUP BY code " .
393
            "ORDER BY MAX(heading_id) DESC";
394
        $sql = $this->_platform->modifyLimitQuery($querySql, 1, 0);
395
        $this->expectCteWithMaxRowNum($alteredSql, 1, $sql);
396
    }
397
398
    /**
399
     * @throws \Doctrine\DBAL\DBALException
400
     */
401
    public function testModifyLimitSubqueryWithJoinAndSubqueryOrderedByColumnFromBaseTable()
402
    {
403
        $querySql = "SELECT DISTINCT id_0, name_1 "
404
            . "FROM ("
405
            . "SELECT t1.id AS id_0, t2.name AS name_1 "
406
            . "FROM table_parent t1 "
407
            . "LEFT JOIN join_table t2 ON t1.id = t2.table_id "
408
            . "ORDER BY t1.id ASC"
409
            . ") dctrn_result "
410
            . "ORDER BY id_0 ASC";
411
        $alteredSql = "SELECT DISTINCT TOP 5 id_0, name_1 "
412
            . "FROM ("
413
            . "SELECT t1.id AS id_0, t2.name AS name_1 "
414
            . "FROM table_parent t1 "
415
            . "LEFT JOIN join_table t2 ON t1.id = t2.table_id"
416
            . ") dctrn_result "
417
            . "ORDER BY id_0 ASC";
418
        $sql = $this->_platform->modifyLimitQuery($querySql, 5);
419
        $this->expectCteWithMaxRowNum($alteredSql, 5, $sql);
420
    }
421
422
    /**
423
     * @throws \Doctrine\DBAL\DBALException
424
     */
425
    public function testModifyLimitSubqueryWithJoinAndSubqueryOrderedByColumnFromJoinTable()
426
    {
427
        $querySql = "SELECT DISTINCT id_0, name_1 "
428
            . "FROM ("
429
            . "SELECT t1.id AS id_0, t2.name AS name_1 "
430
            . "FROM table_parent t1 "
431
            . "LEFT JOIN join_table t2 ON t1.id = t2.table_id "
432
            . "ORDER BY t2.name ASC"
433
            . ") dctrn_result "
434
            . "ORDER BY name_1 ASC";
435
        $alteredSql = "SELECT DISTINCT TOP 5 id_0, name_1 "
436
            . "FROM ("
437
            . "SELECT t1.id AS id_0, t2.name AS name_1 "
438
            . "FROM table_parent t1 "
439
            . "LEFT JOIN join_table t2 ON t1.id = t2.table_id"
440
            . ") dctrn_result "
441
            . "ORDER BY name_1 ASC";
442
        $sql = $this->_platform->modifyLimitQuery($querySql, 5);
443
        $this->expectCteWithMaxRowNum($alteredSql, 5, $sql);
444
    }
445
446
    /**
447
     * @throws \Doctrine\DBAL\DBALException
448
     */
449
    public function testModifyLimitSubqueryWithJoinAndSubqueryOrderedByColumnsFromBothTables()
450
    {
451
        $querySql = "SELECT DISTINCT id_0, name_1, foo_2 "
452
            . "FROM ("
453
            . "SELECT t1.id AS id_0, t2.name AS name_1, t2.foo AS foo_2 "
454
            . "FROM table_parent t1 "
455
            . "LEFT JOIN join_table t2 ON t1.id = t2.table_id "
456
            . "ORDER BY t2.name ASC, t2.foo DESC"
457
            . ") dctrn_result "
458
            . "ORDER BY name_1 ASC, foo_2 DESC";
459
        $alteredSql = "SELECT DISTINCT TOP 5 id_0, name_1, foo_2 "
460
            . "FROM ("
461
            . "SELECT t1.id AS id_0, t2.name AS name_1, t2.foo AS foo_2 "
462
            . "FROM table_parent t1 "
463
            . "LEFT JOIN join_table t2 ON t1.id = t2.table_id"
464
            . ") dctrn_result "
465
            . "ORDER BY name_1 ASC, foo_2 DESC";
466
        $sql = $this->_platform->modifyLimitQuery($querySql, 5);
467
        $this->expectCteWithMaxRowNum($alteredSql, 5, $sql);
468
    }
469
470
    public function testModifyLimitSubquerySimple()
471
    {
472
        $querySql = "SELECT DISTINCT id_0 FROM "
473
            . "(SELECT k0_.id AS id_0, k0_.field AS field_1 "
474
            . "FROM key_table k0_ WHERE (k0_.where_field IN (1))) dctrn_result";
475
        $alteredSql = "SELECT DISTINCT TOP 20 id_0 FROM (SELECT k0_.id AS id_0, k0_.field AS field_1 "
476
            . "FROM key_table k0_ WHERE (k0_.where_field IN (1))) dctrn_result";
477
        $sql = $this->_platform->modifyLimitQuery($querySql, 20);
478
        $this->expectCteWithMaxRowNum($alteredSql, 20, $sql);
479
    }
480
481
    /**
482
     * @group DDC-1360
483
     */
484
    public function testQuoteIdentifier()
485
    {
486
        self::assertEquals('[fo][o]', $this->_platform->quoteIdentifier('fo]o'));
487
        self::assertEquals('[test]', $this->_platform->quoteIdentifier('test'));
488
        self::assertEquals('[test].[test]', $this->_platform->quoteIdentifier('test.test'));
489
    }
490
491
    /**
492
     * @group DDC-1360
493
     */
494
    public function testQuoteSingleIdentifier()
495
    {
496
        self::assertEquals('[fo][o]', $this->_platform->quoteSingleIdentifier('fo]o'));
497
        self::assertEquals('[test]', $this->_platform->quoteSingleIdentifier('test'));
498
        self::assertEquals('[test.test]', $this->_platform->quoteSingleIdentifier('test.test'));
499
    }
500
501
    /**
502
     * @group DBAL-220
503
     */
504
    public function testCreateClusteredIndex()
505
    {
506
        $idx = new \Doctrine\DBAL\Schema\Index('idx', array('id'));
507
        $idx->addFlag('clustered');
508
        self::assertEquals('CREATE CLUSTERED INDEX idx ON tbl (id)', $this->_platform->getCreateIndexSQL($idx, 'tbl'));
509
    }
510
511
    /**
512
     * @group DBAL-220
513
     */
514
    public function testCreateNonClusteredPrimaryKeyInTable()
515
    {
516
        $table = new \Doctrine\DBAL\Schema\Table("tbl");
517
        $table->addColumn("id", "integer");
518
        $table->setPrimaryKey(Array("id"));
519
        $table->getIndex('primary')->addFlag('nonclustered');
520
521
        self::assertEquals(array('CREATE TABLE tbl (id INT NOT NULL, PRIMARY KEY NONCLUSTERED (id))'), $this->_platform->getCreateTableSQL($table));
522
    }
523
524
    /**
525
     * @group DBAL-220
526
     */
527
    public function testCreateNonClusteredPrimaryKey()
528
    {
529
        $idx = new \Doctrine\DBAL\Schema\Index('idx', array('id'), false, true);
530
        $idx->addFlag('nonclustered');
531
        self::assertEquals('ALTER TABLE tbl ADD PRIMARY KEY NONCLUSTERED (id)', $this->_platform->getCreatePrimaryKeySQL($idx, 'tbl'));
532
    }
533
534
    public function testAlterAddPrimaryKey()
535
    {
536
        $idx = new \Doctrine\DBAL\Schema\Index('idx', array('id'), false, true);
537
        self::assertEquals('ALTER TABLE tbl ADD PRIMARY KEY (id)', $this->_platform->getCreateIndexSQL($idx, 'tbl'));
538
    }
539
540
    protected function getQuotedColumnInPrimaryKeySQL()
541
    {
542
        return array(
543
            'CREATE TABLE [quoted] ([create] NVARCHAR(255) NOT NULL, PRIMARY KEY ([create]))',
544
        );
545
    }
546
547
    protected function getQuotedColumnInIndexSQL()
548
    {
549
        return array(
550
            'CREATE TABLE [quoted] ([create] NVARCHAR(255) NOT NULL)',
551
            'CREATE INDEX IDX_22660D028FD6E0FB ON [quoted] ([create])',
552
        );
553
    }
554
555
    protected function getQuotedNameInIndexSQL()
556
    {
557
        return array(
558
            'CREATE TABLE test (column1 NVARCHAR(255) NOT NULL)',
559
            'CREATE INDEX [key] ON test (column1)',
560
        );
561
    }
562
563
    protected function getQuotedColumnInForeignKeySQL()
564
    {
565
        return array(
566
            'CREATE TABLE [quoted] ([create] NVARCHAR(255) NOT NULL, foo NVARCHAR(255) NOT NULL, [bar] NVARCHAR(255) NOT NULL)',
567
            'ALTER TABLE [quoted] ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ([create], foo, [bar]) REFERENCES [foreign] ([create], bar, [foo-bar])',
568
            'ALTER TABLE [quoted] ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ([create], foo, [bar]) REFERENCES foo ([create], bar, [foo-bar])',
569
            'ALTER TABLE [quoted] ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ([create], foo, [bar]) REFERENCES [foo-bar] ([create], bar, [foo-bar])',
570
        );
571
    }
572
573
    public function testGetCreateSchemaSQL()
574
    {
575
        $schemaName = 'schema';
576
        $sql = $this->_platform->getCreateSchemaSQL($schemaName);
577
        self::assertEquals('CREATE SCHEMA ' . $schemaName, $sql);
578
    }
579
580
    /**
581
     * @group DBAL-543
582
     */
583
    public function getCreateTableColumnCommentsSQL()
584
    {
585
        return array(
586
            "CREATE TABLE test (id INT NOT NULL, PRIMARY KEY (id))",
587
            "EXEC sp_addextendedproperty N'MS_Description', N'This is a comment', N'SCHEMA', dbo, N'TABLE', test, N'COLUMN', id",
588
        );
589
    }
590
591
    /**
592
     * @group DBAL-543
593
     */
594
    public function getAlterTableColumnCommentsSQL()
595
    {
596
        return array(
597
            "ALTER TABLE mytable ADD quota INT NOT NULL",
598
            "EXEC sp_addextendedproperty N'MS_Description', N'A comment', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', quota",
599
            // todo
600
            //"EXEC sp_addextendedproperty N'MS_Description', N'B comment', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', baz",
601
        );
602
    }
603
604
    /**
605
     * @group DBAL-543
606
     */
607
    public function getCreateTableColumnTypeCommentsSQL()
608
    {
609
        return array(
610
            "CREATE TABLE test (id INT NOT NULL, data VARCHAR(MAX) NOT NULL, PRIMARY KEY (id))",
611
            "EXEC sp_addextendedproperty N'MS_Description', N'(DC2Type:array)', N'SCHEMA', dbo, N'TABLE', test, N'COLUMN', data",
612
        );
613
    }
614
615
    /**
616
     * @group DBAL-543
617
     */
618
    public function testGeneratesCreateTableSQLWithColumnComments()
619
    {
620
        $table = new Table('mytable');
621
        $table->addColumn('id', 'integer', array('autoincrement' => true));
622
        $table->addColumn('comment_null', 'integer', array('comment' => null));
623
        $table->addColumn('comment_false', 'integer', array('comment' => false));
624
        $table->addColumn('comment_empty_string', 'integer', array('comment' => ''));
625
        $table->addColumn('comment_integer_0', 'integer', array('comment' => 0));
626
        $table->addColumn('comment_float_0', 'integer', array('comment' => 0.0));
627
        $table->addColumn('comment_string_0', 'integer', array('comment' => '0'));
628
        $table->addColumn('comment', 'integer', array('comment' => 'Doctrine 0wnz you!'));
629
        $table->addColumn('`comment_quoted`', 'integer', array('comment' => 'Doctrine 0wnz comments for explicitly quoted columns!'));
630
        $table->addColumn('create', 'integer', array('comment' => 'Doctrine 0wnz comments for reserved keyword columns!'));
631
        $table->addColumn('commented_type', 'object');
632
        $table->addColumn('commented_type_with_comment', 'array', array('comment' => 'Doctrine array type.'));
633
        $table->addColumn('comment_with_string_literal_char', 'string', array('comment' => "O'Reilly"));
634
        $table->setPrimaryKey(array('id'));
635
636
        self::assertEquals(
637
            array(
638
                "CREATE TABLE mytable (id INT IDENTITY NOT NULL, comment_null INT NOT NULL, comment_false INT NOT NULL, comment_empty_string INT NOT NULL, comment_integer_0 INT NOT NULL, comment_float_0 INT NOT NULL, comment_string_0 INT NOT NULL, comment INT NOT NULL, [comment_quoted] INT NOT NULL, [create] INT NOT NULL, commented_type VARCHAR(MAX) NOT NULL, commented_type_with_comment VARCHAR(MAX) NOT NULL, comment_with_string_literal_char NVARCHAR(255) NOT NULL, PRIMARY KEY (id))",
639
                "EXEC sp_addextendedproperty N'MS_Description', N'0', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_integer_0",
640
                "EXEC sp_addextendedproperty N'MS_Description', N'0', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_float_0",
641
                "EXEC sp_addextendedproperty N'MS_Description', N'0', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_string_0",
642
                "EXEC sp_addextendedproperty N'MS_Description', N'Doctrine 0wnz you!', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment",
643
                "EXEC sp_addextendedproperty N'MS_Description', N'Doctrine 0wnz comments for explicitly quoted columns!', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', [comment_quoted]",
644
                "EXEC sp_addextendedproperty N'MS_Description', N'Doctrine 0wnz comments for reserved keyword columns!', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', [create]",
645
                "EXEC sp_addextendedproperty N'MS_Description', N'(DC2Type:object)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', commented_type",
646
                "EXEC sp_addextendedproperty N'MS_Description', N'Doctrine array type.(DC2Type:array)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', commented_type_with_comment",
647
                "EXEC sp_addextendedproperty N'MS_Description', N'O''Reilly', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_with_string_literal_char",
648
            ),
649
            $this->_platform->getCreateTableSQL($table)
650
        );
651
    }
652
653
    /**
654
     * @group DBAL-543
655
     * @group DBAL-1011
656
     */
657
    public function testGeneratesAlterTableSQLWithColumnComments()
658
    {
659
        $table = new Table('mytable');
660
        $table->addColumn('id', 'integer', array('autoincrement' => true));
661
        $table->addColumn('comment_null', 'integer', array('comment' => null));
662
        $table->addColumn('comment_false', 'integer', array('comment' => false));
663
        $table->addColumn('comment_empty_string', 'integer', array('comment' => ''));
664
        $table->addColumn('comment_integer_0', 'integer', array('comment' => 0));
665
        $table->addColumn('comment_float_0', 'integer', array('comment' => 0.0));
666
        $table->addColumn('comment_string_0', 'integer', array('comment' => '0'));
667
        $table->addColumn('comment', 'integer', array('comment' => 'Doctrine 0wnz you!'));
668
        $table->addColumn('`comment_quoted`', 'integer', array('comment' => 'Doctrine 0wnz comments for explicitly quoted columns!'));
669
        $table->addColumn('create', 'integer', array('comment' => 'Doctrine 0wnz comments for reserved keyword columns!'));
670
        $table->addColumn('commented_type', 'object');
671
        $table->addColumn('commented_type_with_comment', 'array', array('comment' => 'Doctrine array type.'));
672
        $table->addColumn('comment_with_string_literal_quote_char', 'array', array('comment' => "O'Reilly"));
673
        $table->setPrimaryKey(array('id'));
674
675
        $tableDiff = new TableDiff('mytable');
676
        $tableDiff->fromTable = $table;
677
        $tableDiff->addedColumns['added_comment_none'] = new Column('added_comment_none', Type::getType('integer'));
678
        $tableDiff->addedColumns['added_comment_null'] = new Column('added_comment_null', Type::getType('integer'), array('comment' => null));
679
        $tableDiff->addedColumns['added_comment_false'] = new Column('added_comment_false', Type::getType('integer'), array('comment' => false));
680
        $tableDiff->addedColumns['added_comment_empty_string'] = new Column('added_comment_empty_string', Type::getType('integer'), array('comment' => ''));
681
        $tableDiff->addedColumns['added_comment_integer_0'] = new Column('added_comment_integer_0', Type::getType('integer'), array('comment' => 0));
682
        $tableDiff->addedColumns['added_comment_float_0'] = new Column('added_comment_float_0', Type::getType('integer'), array('comment' => 0.0));
683
        $tableDiff->addedColumns['added_comment_string_0'] = new Column('added_comment_string_0', Type::getType('integer'), array('comment' => '0'));
684
        $tableDiff->addedColumns['added_comment'] = new Column('added_comment', Type::getType('integer'), array('comment' => 'Doctrine'));
685
        $tableDiff->addedColumns['`added_comment_quoted`'] = new Column('`added_comment_quoted`', Type::getType('integer'), array('comment' => 'rulez'));
686
        $tableDiff->addedColumns['select'] = new Column('select', Type::getType('integer'), array('comment' => '666'));
687
        $tableDiff->addedColumns['added_commented_type'] = new Column('added_commented_type', Type::getType('object'));
688
        $tableDiff->addedColumns['added_commented_type_with_comment'] = new Column('added_commented_type_with_comment', Type::getType('array'), array('comment' => '666'));
689
        $tableDiff->addedColumns['added_comment_with_string_literal_char'] = new Column('added_comment_with_string_literal_char', Type::getType('string'), array('comment' => "''"));
690
691
        $tableDiff->renamedColumns['comment_float_0'] = new Column('comment_double_0', Type::getType('decimal'), array('comment' => 'Double for real!'));
692
693
        // Add comment to non-commented column.
694
        $tableDiff->changedColumns['id'] = new ColumnDiff(
695
            'id',
696
            new Column('id', Type::getType('integer'), array('autoincrement' => true, 'comment' => 'primary')),
697
            array('comment'),
698
            new Column('id', Type::getType('integer'), array('autoincrement' => true))
699
        );
700
701
        // Remove comment from null-commented column.
702
        $tableDiff->changedColumns['comment_null'] = new ColumnDiff(
703
            'comment_null',
704
            new Column('comment_null', Type::getType('string')),
705
            array('type'),
706
            new Column('comment_null', Type::getType('integer'), array('comment' => null))
707
        );
708
709
        // Add comment to false-commented column.
710
        $tableDiff->changedColumns['comment_false'] = new ColumnDiff(
711
            'comment_false',
712
            new Column('comment_false', Type::getType('integer'), array('comment' => 'false')),
713
            array('comment'),
714
            new Column('comment_false', Type::getType('integer'), array('comment' => false))
715
        );
716
717
        // Change type to custom type from empty string commented column.
718
        $tableDiff->changedColumns['comment_empty_string'] = new ColumnDiff(
719
            'comment_empty_string',
720
            new Column('comment_empty_string', Type::getType('object')),
721
            array('type'),
722
            new Column('comment_empty_string', Type::getType('integer'), array('comment' => ''))
723
        );
724
725
        // Change comment to false-comment from zero-string commented column.
726
        $tableDiff->changedColumns['comment_string_0'] = new ColumnDiff(
727
            'comment_string_0',
728
            new Column('comment_string_0', Type::getType('integer'), array('comment' => false)),
729
            array('comment'),
730
            new Column('comment_string_0', Type::getType('integer'), array('comment' => '0'))
731
        );
732
733
        // Remove comment from regular commented column.
734
        $tableDiff->changedColumns['comment'] = new ColumnDiff(
735
            'comment',
736
            new Column('comment', Type::getType('integer')),
737
            array('comment'),
738
            new Column('comment', Type::getType('integer'), array('comment' => 'Doctrine 0wnz you!'))
739
        );
740
741
        // Change comment and change type to custom type from regular commented column.
742
        $tableDiff->changedColumns['`comment_quoted`'] = new ColumnDiff(
743
            '`comment_quoted`',
744
            new Column('`comment_quoted`', Type::getType('array'), array('comment' => 'Doctrine array.')),
745
            array('comment', 'type'),
746
            new Column('`comment_quoted`', Type::getType('integer'), array('comment' => 'Doctrine 0wnz you!'))
747
        );
748
749
        // Remove comment and change type to custom type from regular commented column.
750
        $tableDiff->changedColumns['create'] = new ColumnDiff(
751
            'create',
752
            new Column('create', Type::getType('object')),
753
            array('comment', 'type'),
754
            new Column('create', Type::getType('integer'), array('comment' => 'Doctrine 0wnz comments for reserved keyword columns!'))
755
        );
756
757
        // Add comment and change custom type to regular type from non-commented column.
758
        $tableDiff->changedColumns['commented_type'] = new ColumnDiff(
759
            'commented_type',
760
            new Column('commented_type', Type::getType('integer'), array('comment' => 'foo')),
761
            array('comment', 'type'),
762
            new Column('commented_type', Type::getType('object'))
763
        );
764
765
        // Remove comment from commented custom type column.
766
        $tableDiff->changedColumns['commented_type_with_comment'] = new ColumnDiff(
767
            'commented_type_with_comment',
768
            new Column('commented_type_with_comment', Type::getType('array')),
769
            array('comment'),
770
            new Column('commented_type_with_comment', Type::getType('array'), array('comment' => 'Doctrine array type.'))
771
        );
772
773
        // Change comment from comment with string literal char column.
774
        $tableDiff->changedColumns['comment_with_string_literal_char'] = new ColumnDiff(
775
            'comment_with_string_literal_char',
776
            new Column('comment_with_string_literal_char', Type::getType('string'), array('comment' => "'")),
777
            array('comment'),
778
            new Column('comment_with_string_literal_char', Type::getType('array'), array('comment' => "O'Reilly"))
779
        );
780
781
        $tableDiff->removedColumns['comment_integer_0'] = new Column('comment_integer_0', Type::getType('integer'), array('comment' => 0));
782
783
        self::assertEquals(
784
            array(
785
                // Renamed columns.
786
                "sp_RENAME 'mytable.comment_float_0', 'comment_double_0', 'COLUMN'",
787
788
                // Added columns.
789
                "ALTER TABLE mytable ADD added_comment_none INT NOT NULL",
790
                "ALTER TABLE mytable ADD added_comment_null INT NOT NULL",
791
                "ALTER TABLE mytable ADD added_comment_false INT NOT NULL",
792
                "ALTER TABLE mytable ADD added_comment_empty_string INT NOT NULL",
793
                "ALTER TABLE mytable ADD added_comment_integer_0 INT NOT NULL",
794
                "ALTER TABLE mytable ADD added_comment_float_0 INT NOT NULL",
795
                "ALTER TABLE mytable ADD added_comment_string_0 INT NOT NULL",
796
                "ALTER TABLE mytable ADD added_comment INT NOT NULL",
797
                "ALTER TABLE mytable ADD [added_comment_quoted] INT NOT NULL",
798
                "ALTER TABLE mytable ADD [select] INT NOT NULL",
799
                "ALTER TABLE mytable ADD added_commented_type VARCHAR(MAX) NOT NULL",
800
                "ALTER TABLE mytable ADD added_commented_type_with_comment VARCHAR(MAX) NOT NULL",
801
                "ALTER TABLE mytable ADD added_comment_with_string_literal_char NVARCHAR(255) NOT NULL",
802
                "ALTER TABLE mytable DROP COLUMN comment_integer_0",
803
                "ALTER TABLE mytable ALTER COLUMN comment_null NVARCHAR(255) NOT NULL",
804
                "ALTER TABLE mytable ALTER COLUMN comment_empty_string VARCHAR(MAX) NOT NULL",
805
                "ALTER TABLE mytable ALTER COLUMN [comment_quoted] VARCHAR(MAX) NOT NULL",
806
                "ALTER TABLE mytable ALTER COLUMN [create] VARCHAR(MAX) NOT NULL",
807
                "ALTER TABLE mytable ALTER COLUMN commented_type INT NOT NULL",
808
809
                // Added columns.
810
                "EXEC sp_addextendedproperty N'MS_Description', N'0', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', added_comment_integer_0",
811
                "EXEC sp_addextendedproperty N'MS_Description', N'0', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', added_comment_float_0",
812
                "EXEC sp_addextendedproperty N'MS_Description', N'0', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', added_comment_string_0",
813
                "EXEC sp_addextendedproperty N'MS_Description', N'Doctrine', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', added_comment",
814
                "EXEC sp_addextendedproperty N'MS_Description', N'rulez', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', [added_comment_quoted]",
815
                "EXEC sp_addextendedproperty N'MS_Description', N'666', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', [select]",
816
                "EXEC sp_addextendedproperty N'MS_Description', N'(DC2Type:object)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', added_commented_type",
817
                "EXEC sp_addextendedproperty N'MS_Description', N'666(DC2Type:array)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', added_commented_type_with_comment",
818
                "EXEC sp_addextendedproperty N'MS_Description', N'''''', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', added_comment_with_string_literal_char",
819
820
                // Changed columns.
821
                "EXEC sp_addextendedproperty N'MS_Description', N'primary', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', id",
822
                "EXEC sp_addextendedproperty N'MS_Description', N'false', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_false",
823
                "EXEC sp_addextendedproperty N'MS_Description', N'(DC2Type:object)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_empty_string",
824
                "EXEC sp_dropextendedproperty N'MS_Description', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_string_0",
825
                "EXEC sp_dropextendedproperty N'MS_Description', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment",
826
                "EXEC sp_updateextendedproperty N'MS_Description', N'Doctrine array.(DC2Type:array)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', [comment_quoted]",
827
                "EXEC sp_updateextendedproperty N'MS_Description', N'(DC2Type:object)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', [create]",
828
                "EXEC sp_updateextendedproperty N'MS_Description', N'foo', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', commented_type",
829
                "EXEC sp_updateextendedproperty N'MS_Description', N'(DC2Type:array)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', commented_type_with_comment",
830
                "EXEC sp_updateextendedproperty N'MS_Description', N'''', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_with_string_literal_char",
831
            ),
832
            $this->_platform->getAlterTableSQL($tableDiff)
833
        );
834
    }
835
836
    /**
837
     * @group DBAL-122
838
     */
839
    public function testInitializesDoctrineTypeMappings()
840
    {
841
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('bigint'));
842
        self::assertSame('bigint', $this->_platform->getDoctrineTypeMapping('bigint'));
843
844
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('numeric'));
845
        self::assertSame('decimal', $this->_platform->getDoctrineTypeMapping('numeric'));
846
847
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('bit'));
848
        self::assertSame('boolean', $this->_platform->getDoctrineTypeMapping('bit'));
849
850
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('smallint'));
851
        self::assertSame('smallint', $this->_platform->getDoctrineTypeMapping('smallint'));
852
853
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('decimal'));
854
        self::assertSame('decimal', $this->_platform->getDoctrineTypeMapping('decimal'));
855
856
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('smallmoney'));
857
        self::assertSame('integer', $this->_platform->getDoctrineTypeMapping('smallmoney'));
858
859
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('int'));
860
        self::assertSame('integer', $this->_platform->getDoctrineTypeMapping('int'));
861
862
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('tinyint'));
863
        self::assertSame('smallint', $this->_platform->getDoctrineTypeMapping('tinyint'));
864
865
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('money'));
866
        self::assertSame('integer', $this->_platform->getDoctrineTypeMapping('money'));
867
868
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('float'));
869
        self::assertSame('float', $this->_platform->getDoctrineTypeMapping('float'));
870
871
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('real'));
872
        self::assertSame('float', $this->_platform->getDoctrineTypeMapping('real'));
873
874
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('double'));
875
        self::assertSame('float', $this->_platform->getDoctrineTypeMapping('double'));
876
877
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('double precision'));
878
        self::assertSame('float', $this->_platform->getDoctrineTypeMapping('double precision'));
879
880
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('smalldatetime'));
881
        self::assertSame('datetime', $this->_platform->getDoctrineTypeMapping('smalldatetime'));
882
883
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('datetime'));
884
        self::assertSame('datetime', $this->_platform->getDoctrineTypeMapping('datetime'));
885
886
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('char'));
887
        self::assertSame('string', $this->_platform->getDoctrineTypeMapping('char'));
888
889
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('varchar'));
890
        self::assertSame('string', $this->_platform->getDoctrineTypeMapping('varchar'));
891
892
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('text'));
893
        self::assertSame('text', $this->_platform->getDoctrineTypeMapping('text'));
894
895
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('nchar'));
896
        self::assertSame('string', $this->_platform->getDoctrineTypeMapping('nchar'));
897
898
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('nvarchar'));
899
        self::assertSame('string', $this->_platform->getDoctrineTypeMapping('nvarchar'));
900
901
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('ntext'));
902
        self::assertSame('text', $this->_platform->getDoctrineTypeMapping('ntext'));
903
904
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('binary'));
905
        self::assertSame('binary', $this->_platform->getDoctrineTypeMapping('binary'));
906
907
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('varbinary'));
908
        self::assertSame('binary', $this->_platform->getDoctrineTypeMapping('varbinary'));
909
910
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('image'));
911
        self::assertSame('blob', $this->_platform->getDoctrineTypeMapping('image'));
912
913
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('uniqueidentifier'));
914
        self::assertSame('guid', $this->_platform->getDoctrineTypeMapping('uniqueidentifier'));
915
    }
916
917
    protected function getBinaryMaxLength()
918
    {
919
        return 8000;
920
    }
921
922
    public function testReturnsBinaryTypeDeclarationSQL()
923
    {
924
        self::assertSame('VARBINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array()));
925
        self::assertSame('VARBINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 0)));
926
        self::assertSame('VARBINARY(8000)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 8000)));
927
        self::assertSame('VARBINARY(MAX)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 8001)));
928
929
        self::assertSame('BINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true)));
930
        self::assertSame('BINARY(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 0)));
931
        self::assertSame('BINARY(8000)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 8000)));
932
        self::assertSame('VARBINARY(MAX)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 8001)));
933
    }
934
935
    /**
936
     * @group DBAL-234
937
     */
938
    protected function getAlterTableRenameIndexSQL()
939
    {
940
        return array(
941
            "EXEC sp_RENAME N'mytable.idx_foo', N'idx_bar', N'INDEX'",
942
        );
943
    }
944
945
    /**
946
     * @group DBAL-234
947
     */
948
    protected function getQuotedAlterTableRenameIndexSQL()
949
    {
950
        return array(
951
            "EXEC sp_RENAME N'[table].[create]', N'[select]', N'INDEX'",
952
            "EXEC sp_RENAME N'[table].[foo]', N'[bar]', N'INDEX'",
953
        );
954
    }
955
956
    /**
957
     * @group DBAL-825
958
     */
959
    public function testChangeColumnsTypeWithDefaultValue()
960
    {
961
        $tableName = 'column_def_change_type';
962
        $table     = new Table($tableName);
963
964
        $table->addColumn('col_int', 'smallint', array('default' => 666));
965
        $table->addColumn('col_string', 'string', array('default' => 'foo'));
966
967
        $tableDiff = new TableDiff($tableName);
968
        $tableDiff->fromTable = $table;
969
        $tableDiff->changedColumns['col_int'] = new ColumnDiff(
970
            'col_int',
971
            new Column('col_int', Type::getType('integer'), array('default' => 666)),
972
            array('type'),
973
            new Column('col_int', Type::getType('smallint'), array('default' => 666))
974
        );
975
976
        $tableDiff->changedColumns['col_string'] = new ColumnDiff(
977
            'col_string',
978
            new Column('col_string', Type::getType('string'), array('default' => 666, 'fixed' => true)),
979
            array('fixed'),
980
            new Column('col_string', Type::getType('string'), array('default' => 666))
981
        );
982
983
        $expected = $this->_platform->getAlterTableSQL($tableDiff);
984
985
        self::assertSame(
986
            $expected,
987
            array(
988
                'ALTER TABLE column_def_change_type DROP CONSTRAINT DF_829302E0_FA2CB292',
989
                'ALTER TABLE column_def_change_type ALTER COLUMN col_int INT NOT NULL',
990
                'ALTER TABLE column_def_change_type ADD CONSTRAINT DF_829302E0_FA2CB292 DEFAULT 666 FOR col_int',
991
                'ALTER TABLE column_def_change_type DROP CONSTRAINT DF_829302E0_2725A6D0',
992
                'ALTER TABLE column_def_change_type ALTER COLUMN col_string NCHAR(255) NOT NULL',
993
                "ALTER TABLE column_def_change_type ADD CONSTRAINT DF_829302E0_2725A6D0 DEFAULT '666' FOR col_string",
994
            )
995
        );
996
    }
997
998
    /**
999
     * {@inheritdoc}
1000
     */
1001
    protected function getQuotedAlterTableRenameColumnSQL()
1002
    {
1003
        return array(
1004
            "sp_RENAME 'mytable.unquoted1', 'unquoted', 'COLUMN'",
1005
            "sp_RENAME 'mytable.unquoted2', '[where]', 'COLUMN'",
1006
            "sp_RENAME 'mytable.unquoted3', '[foo]', 'COLUMN'",
1007
            "sp_RENAME 'mytable.[create]', 'reserved_keyword', 'COLUMN'",
1008
            "sp_RENAME 'mytable.[table]', '[from]', 'COLUMN'",
1009
            "sp_RENAME 'mytable.[select]', '[bar]', 'COLUMN'",
1010
            "sp_RENAME 'mytable.quoted1', 'quoted', 'COLUMN'",
1011
            "sp_RENAME 'mytable.quoted2', '[and]', 'COLUMN'",
1012
            "sp_RENAME 'mytable.quoted3', '[baz]', 'COLUMN'",
1013
        );
1014
    }
1015
1016
    /**
1017
     * {@inheritdoc}
1018
     */
1019
    protected function getQuotedAlterTableChangeColumnLengthSQL()
1020
    {
1021
        $this->markTestIncomplete('Not implemented yet');
1022
    }
1023
1024
    /**
1025
     * @group DBAL-807
1026
     */
1027
    protected function getAlterTableRenameIndexInSchemaSQL()
1028
    {
1029
        return array(
1030
            "EXEC sp_RENAME N'myschema.mytable.idx_foo', N'idx_bar', N'INDEX'",
1031
        );
1032
    }
1033
1034
    /**
1035
     * @group DBAL-807
1036
     */
1037
    protected function getQuotedAlterTableRenameIndexInSchemaSQL()
1038
    {
1039
        return array(
1040
            "EXEC sp_RENAME N'[schema].[table].[create]', N'[select]', N'INDEX'",
1041
            "EXEC sp_RENAME N'[schema].[table].[foo]', N'[bar]', N'INDEX'",
1042
        );
1043
    }
1044
1045
    protected function getQuotesDropForeignKeySQL()
1046
    {
1047
        return 'ALTER TABLE [table] DROP CONSTRAINT [select]';
1048
    }
1049
1050
    protected function getQuotesDropConstraintSQL()
1051
    {
1052
        return 'ALTER TABLE [table] DROP CONSTRAINT [select]';
1053
    }
1054
1055
    /**
1056
     * @dataProvider getGeneratesIdentifierNamesInDefaultConstraintDeclarationSQL
1057
     * @group DBAL-830
1058
     */
1059
    public function testGeneratesIdentifierNamesInDefaultConstraintDeclarationSQL($table, $column, $expectedSql)
1060
    {
1061
        self::assertSame($expectedSql, $this->_platform->getDefaultConstraintDeclarationSQL($table, $column));
0 ignored issues
show
Bug introduced by
The method getDefaultConstraintDeclarationSQL() does not exist on Doctrine\DBAL\Platforms\AbstractPlatform. It seems like you code against a sub-type of Doctrine\DBAL\Platforms\AbstractPlatform such as Doctrine\DBAL\Platforms\SQLServerPlatform. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1061
        self::assertSame($expectedSql, $this->_platform->/** @scrutinizer ignore-call */ getDefaultConstraintDeclarationSQL($table, $column));
Loading history...
1062
    }
1063
1064
    public function getGeneratesIdentifierNamesInDefaultConstraintDeclarationSQL()
1065
    {
1066
        return array(
1067
            // Unquoted identifiers non-reserved keywords.
1068
            array('mytable', array('name' => 'mycolumn', 'default' => 'foo'), " CONSTRAINT DF_6B2BD609_9BADD926 DEFAULT 'foo' FOR mycolumn"),
1069
            // Quoted identifiers non-reserved keywords.
1070
            array('`mytable`', array('name' => '`mycolumn`', 'default' => 'foo'), " CONSTRAINT DF_6B2BD609_9BADD926 DEFAULT 'foo' FOR [mycolumn]"),
1071
            // Unquoted identifiers reserved keywords.
1072
            array('table', array('name' => 'select', 'default' => 'foo'), " CONSTRAINT DF_F6298F46_4BF2EAC0 DEFAULT 'foo' FOR [select]"),
1073
            // Quoted identifiers reserved keywords.
1074
            array('`table`', array('name' => '`select`', 'default' => 'foo'), " CONSTRAINT DF_F6298F46_4BF2EAC0 DEFAULT 'foo' FOR [select]"),
1075
        );
1076
    }
1077
1078
    /**
1079
     * @dataProvider getGeneratesIdentifierNamesInCreateTableSQL
1080
     * @group DBAL-830
1081
     */
1082
    public function testGeneratesIdentifierNamesInCreateTableSQL($table, $expectedSql)
1083
    {
1084
        self::assertSame($expectedSql, $this->_platform->getCreateTableSQL($table));
1085
    }
1086
1087
    public function getGeneratesIdentifierNamesInCreateTableSQL()
1088
    {
1089
        return array(
1090
            // Unquoted identifiers non-reserved keywords.
1091
            array(
1092
                new Table('mytable', array(new Column('mycolumn', Type::getType('string'), array('default' => 'foo')))),
1093
                array(
1094
                    'CREATE TABLE mytable (mycolumn NVARCHAR(255) NOT NULL)',
1095
                    "ALTER TABLE mytable ADD CONSTRAINT DF_6B2BD609_9BADD926 DEFAULT 'foo' FOR mycolumn"
1096
                )
1097
            ),
1098
            // Quoted identifiers reserved keywords.
1099
            array(
1100
                new Table('`mytable`', array(new Column('`mycolumn`', Type::getType('string'), array('default' => 'foo')))),
1101
                array(
1102
                    'CREATE TABLE [mytable] ([mycolumn] NVARCHAR(255) NOT NULL)',
1103
                    "ALTER TABLE [mytable] ADD CONSTRAINT DF_6B2BD609_9BADD926 DEFAULT 'foo' FOR [mycolumn]"
1104
                )
1105
            ),
1106
            // Unquoted identifiers reserved keywords.
1107
            array(
1108
                new Table('table', array(new Column('select', Type::getType('string'), array('default' => 'foo')))),
1109
                array(
1110
                    'CREATE TABLE [table] ([select] NVARCHAR(255) NOT NULL)',
1111
                    "ALTER TABLE [table] ADD CONSTRAINT DF_F6298F46_4BF2EAC0 DEFAULT 'foo' FOR [select]"
1112
                )
1113
            ),
1114
            // Quoted identifiers reserved keywords.
1115
            array(
1116
                new Table('`table`', array(new Column('`select`', Type::getType('string'), array('default' => 'foo')))),
1117
                array(
1118
                    'CREATE TABLE [table] ([select] NVARCHAR(255) NOT NULL)',
1119
                    "ALTER TABLE [table] ADD CONSTRAINT DF_F6298F46_4BF2EAC0 DEFAULT 'foo' FOR [select]"
1120
                )
1121
            ),
1122
        );
1123
    }
1124
1125
    /**
1126
     * @dataProvider getGeneratesIdentifierNamesInAlterTableSQL
1127
     * @group DBAL-830
1128
     */
1129
    public function testGeneratesIdentifierNamesInAlterTableSQL($tableDiff, $expectedSql)
1130
    {
1131
        self::assertSame($expectedSql, $this->_platform->getAlterTableSQL($tableDiff));
1132
    }
1133
1134
    public function getGeneratesIdentifierNamesInAlterTableSQL()
1135
    {
1136
        return array(
1137
            // Unquoted identifiers non-reserved keywords.
1138
            array(
1139
                new TableDiff(
1140
                    'mytable',
1141
                    array(new Column('addcolumn', Type::getType('string'), array('default' => 'foo'))),
1142
                    array(
1143
                        'mycolumn' => new ColumnDiff(
1144
                            'mycolumn',
1145
                            new Column('mycolumn', Type::getType('string'), array('default' => 'bar')),
1146
                            array('default'),
1147
                            new Column('mycolumn', Type::getType('string'), array('default' => 'foo'))
1148
                        )
1149
                    ),
1150
                    array(new Column('removecolumn', Type::getType('string'), array('default' => 'foo')))
1151
                ),
1152
                array(
1153
                    'ALTER TABLE mytable ADD addcolumn NVARCHAR(255) NOT NULL',
1154
                    "ALTER TABLE mytable ADD CONSTRAINT DF_6B2BD609_4AD86123 DEFAULT 'foo' FOR addcolumn",
1155
                    'ALTER TABLE mytable DROP COLUMN removecolumn',
1156
                    'ALTER TABLE mytable DROP CONSTRAINT DF_6B2BD609_9BADD926',
1157
                    'ALTER TABLE mytable ALTER COLUMN mycolumn NVARCHAR(255) NOT NULL',
1158
                    "ALTER TABLE mytable ADD CONSTRAINT DF_6B2BD609_9BADD926 DEFAULT 'bar' FOR mycolumn"
1159
                )
1160
            ),
1161
            // Quoted identifiers non-reserved keywords.
1162
            array(
1163
                new TableDiff(
1164
                    '`mytable`',
1165
                    array(new Column('`addcolumn`', Type::getType('string'), array('default' => 'foo'))),
1166
                    array(
1167
                        'mycolumn' => new ColumnDiff(
1168
                            '`mycolumn`',
1169
                            new Column('`mycolumn`', Type::getType('string'), array('default' => 'bar')),
1170
                            array('default'),
1171
                            new Column('`mycolumn`', Type::getType('string'), array('default' => 'foo'))
1172
                        )
1173
                    ),
1174
                    array(new Column('`removecolumn`', Type::getType('string'), array('default' => 'foo')))
1175
                ),
1176
                array(
1177
                    'ALTER TABLE [mytable] ADD [addcolumn] NVARCHAR(255) NOT NULL',
1178
                    "ALTER TABLE [mytable] ADD CONSTRAINT DF_6B2BD609_4AD86123 DEFAULT 'foo' FOR [addcolumn]",
1179
                    'ALTER TABLE [mytable] DROP COLUMN [removecolumn]',
1180
                    'ALTER TABLE [mytable] DROP CONSTRAINT DF_6B2BD609_9BADD926',
1181
                    'ALTER TABLE [mytable] ALTER COLUMN [mycolumn] NVARCHAR(255) NOT NULL',
1182
                    "ALTER TABLE [mytable] ADD CONSTRAINT DF_6B2BD609_9BADD926 DEFAULT 'bar' FOR [mycolumn]"
1183
                )
1184
            ),
1185
            // Unquoted identifiers reserved keywords.
1186
            array(
1187
                new TableDiff(
1188
                    'table',
1189
                    array(new Column('add', Type::getType('string'), array('default' => 'foo'))),
1190
                    array(
1191
                        'select' => new ColumnDiff(
1192
                            'select',
1193
                            new Column('select', Type::getType('string'), array('default' => 'bar')),
1194
                            array('default'),
1195
                            new Column('select', Type::getType('string'), array('default' => 'foo'))
1196
                        )
1197
                    ),
1198
                    array(new Column('drop', Type::getType('string'), array('default' => 'foo')))
1199
                ),
1200
                array(
1201
                    'ALTER TABLE [table] ADD [add] NVARCHAR(255) NOT NULL',
1202
                    "ALTER TABLE [table] ADD CONSTRAINT DF_F6298F46_FD1A73E7 DEFAULT 'foo' FOR [add]",
1203
                    'ALTER TABLE [table] DROP COLUMN [drop]',
1204
                    'ALTER TABLE [table] DROP CONSTRAINT DF_F6298F46_4BF2EAC0',
1205
                    'ALTER TABLE [table] ALTER COLUMN [select] NVARCHAR(255) NOT NULL',
1206
                    "ALTER TABLE [table] ADD CONSTRAINT DF_F6298F46_4BF2EAC0 DEFAULT 'bar' FOR [select]"
1207
                )
1208
            ),
1209
            // Quoted identifiers reserved keywords.
1210
            array(
1211
                new TableDiff(
1212
                    '`table`',
1213
                    array(new Column('`add`', Type::getType('string'), array('default' => 'foo'))),
1214
                    array(
1215
                        'select' => new ColumnDiff(
1216
                            '`select`',
1217
                            new Column('`select`', Type::getType('string'), array('default' => 'bar')),
1218
                            array('default'),
1219
                            new Column('`select`', Type::getType('string'), array('default' => 'foo'))
1220
                        )
1221
                    ),
1222
                    array(new Column('`drop`', Type::getType('string'), array('default' => 'foo')))
1223
                ),
1224
                array(
1225
                    'ALTER TABLE [table] ADD [add] NVARCHAR(255) NOT NULL',
1226
                    "ALTER TABLE [table] ADD CONSTRAINT DF_F6298F46_FD1A73E7 DEFAULT 'foo' FOR [add]",
1227
                    'ALTER TABLE [table] DROP COLUMN [drop]',
1228
                    'ALTER TABLE [table] DROP CONSTRAINT DF_F6298F46_4BF2EAC0',
1229
                    'ALTER TABLE [table] ALTER COLUMN [select] NVARCHAR(255) NOT NULL',
1230
                    "ALTER TABLE [table] ADD CONSTRAINT DF_F6298F46_4BF2EAC0 DEFAULT 'bar' FOR [select]"
1231
                )
1232
            ),
1233
        );
1234
    }
1235
1236
    /**
1237
     * @group DBAL-423
1238
     */
1239
    public function testReturnsGuidTypeDeclarationSQL()
1240
    {
1241
        self::assertSame('UNIQUEIDENTIFIER', $this->_platform->getGuidTypeDeclarationSQL(array()));
1242
    }
1243
1244
    /**
1245
     * {@inheritdoc}
1246
     */
1247
    public function getAlterTableRenameColumnSQL()
1248
    {
1249
        return array(
1250
            "sp_RENAME 'foo.bar', 'baz', 'COLUMN'",
1251
            'ALTER TABLE foo DROP CONSTRAINT DF_8C736521_76FF8CAA',
1252
            'ALTER TABLE foo ADD CONSTRAINT DF_8C736521_78240498 DEFAULT 666 FOR baz',
1253
        );
1254
    }
1255
1256
    /**
1257
     * {@inheritdoc}
1258
     */
1259
    protected function getQuotesTableIdentifiersInAlterTableSQL()
1260
    {
1261
        return array(
1262
            'ALTER TABLE [foo] DROP CONSTRAINT fk1',
1263
            'ALTER TABLE [foo] DROP CONSTRAINT fk2',
1264
            "sp_RENAME '[foo].id', 'war', 'COLUMN'",
1265
            'ALTER TABLE [foo] ADD bloo INT NOT NULL',
1266
            'ALTER TABLE [foo] DROP COLUMN baz',
1267
            'ALTER TABLE [foo] ALTER COLUMN bar INT',
1268
            "sp_RENAME '[foo]', 'table'",
1269
            "DECLARE @sql NVARCHAR(MAX) = N''; " .
1270
            "SELECT @sql += N'EXEC sp_rename N''' + dc.name + ''', N''' + REPLACE(dc.name, '8C736521', 'F6298F46') + ''', " .
1271
            "''OBJECT'';' FROM sys.default_constraints dc JOIN sys.tables tbl ON dc.parent_object_id = tbl.object_id " .
1272
            "WHERE tbl.name = 'table';EXEC sp_executesql @sql",
1273
            'ALTER TABLE [table] ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
1274
            'ALTER TABLE [table] ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
1275
        );
1276
    }
1277
1278
    /**
1279
     * {@inheritdoc}
1280
     */
1281
    protected function getCommentOnColumnSQL()
1282
    {
1283
        return array(
1284
            "COMMENT ON COLUMN foo.bar IS 'comment'",
1285
            "COMMENT ON COLUMN [Foo].[BAR] IS 'comment'",
1286
            "COMMENT ON COLUMN [select].[from] IS 'comment'",
1287
        );
1288
    }
1289
1290
    /**
1291
     * {@inheritdoc}
1292
     */
1293
    public function getReturnsForeignKeyReferentialActionSQL()
1294
    {
1295
        return array(
1296
            array('CASCADE', 'CASCADE'),
1297
            array('SET NULL', 'SET NULL'),
1298
            array('NO ACTION', 'NO ACTION'),
1299
            array('RESTRICT', 'NO ACTION'),
1300
            array('SET DEFAULT', 'SET DEFAULT'),
1301
            array('CaScAdE', 'CASCADE'),
1302
        );
1303
    }
1304
1305
    /**
1306
     * {@inheritdoc}
1307
     */
1308
    protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL()
1309
    {
1310
        return 'CONSTRAINT [select] UNIQUE (foo) WHERE foo IS NOT NULL';
1311
    }
1312
1313
    /**
1314
     * {@inheritdoc}
1315
     */
1316
    protected function getQuotesReservedKeywordInIndexDeclarationSQL()
1317
    {
1318
        return 'INDEX [select] (foo)';
1319
    }
1320
1321
    /**
1322
     * {@inheritdoc}
1323
     */
1324
    protected function getQuotesReservedKeywordInTruncateTableSQL()
1325
    {
1326
        return 'TRUNCATE TABLE [select]';
1327
    }
1328
1329
    /**
1330
     * {@inheritdoc}
1331
     */
1332
    protected function getAlterStringToFixedStringSQL()
1333
    {
1334
        return array(
1335
            'ALTER TABLE mytable ALTER COLUMN name NCHAR(2) NOT NULL',
1336
        );
1337
    }
1338
1339
    /**
1340
     * {@inheritdoc}
1341
     */
1342
    protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL()
1343
    {
1344
        return array(
1345
            "EXEC sp_RENAME N'mytable.idx_foo', N'idx_foo_renamed', N'INDEX'",
1346
        );
1347
    }
1348
1349
    public function testModifyLimitQueryWithTopNSubQueryWithOrderBy()
1350
    {
1351
        $querySql = 'SELECT * FROM test t WHERE t.id = (SELECT TOP 1 t2.id FROM test t2 ORDER BY t2.data DESC)';
1352
        $alteredSql = 'SELECT TOP 10 * FROM test t WHERE t.id = (SELECT TOP 1 t2.id FROM test t2 ORDER BY t2.data DESC)';
1353
        $sql = $this->_platform->modifyLimitQuery($querySql, 10);
1354
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
1355
1356
        $querySql = 'SELECT * FROM test t WHERE t.id = (SELECT TOP 1 t2.id FROM test t2 ORDER BY t2.data DESC) ORDER BY t.data2 DESC';
1357
        $alteredSql = 'SELECT TOP 10 * FROM test t WHERE t.id = (SELECT TOP 1 t2.id FROM test t2 ORDER BY t2.data DESC) ORDER BY t.data2 DESC';
1358
        $sql = $this->_platform->modifyLimitQuery($querySql, 10);
1359
        $this->expectCteWithMaxRowNum($alteredSql, 10, $sql);
1360
    }
1361
1362
    /**
1363
     * @group DBAL-2436
1364
     */
1365
    public function testQuotesTableNameInListTableColumnsSQL()
1366
    {
1367
        self::assertContains("'Foo''Bar\\'", $this->_platform->getListTableColumnsSQL("Foo'Bar\\"), '', true);
1368
    }
1369
1370
    /**
1371
     * @group DBAL-2436
1372
     */
1373
    public function testQuotesSchemaNameInListTableColumnsSQL()
1374
    {
1375
        self::assertContains(
1376
            "'Foo''Bar\\'",
1377
            $this->_platform->getListTableColumnsSQL("Foo'Bar\\.baz_table"),
1378
            '',
1379
            true
1380
        );
1381
    }
1382
1383
    /**
1384
     * @group DBAL-2436
1385
     */
1386
    public function testQuotesTableNameInListTableForeignKeysSQL()
1387
    {
1388
        self::assertContains("'Foo''Bar\\'", $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\"), '', true);
1389
    }
1390
1391
    /**
1392
     * @group DBAL-2436
1393
     */
1394
    public function testQuotesSchemaNameInListTableForeignKeysSQL()
1395
    {
1396
        self::assertContains(
1397
            "'Foo''Bar\\'",
1398
            $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\.baz_table"),
1399
            '',
1400
            true
1401
        );
1402
    }
1403
1404
    /**
1405
     * @group DBAL-2436
1406
     */
1407
    public function testQuotesTableNameInListTableIndexesSQL()
1408
    {
1409
        self::assertContains("'Foo''Bar\\'", $this->_platform->getListTableIndexesSQL("Foo'Bar\\"), '', true);
1410
    }
1411
1412
    /**
1413
     * @group DBAL-2436
1414
     */
1415
    public function testQuotesSchemaNameInListTableIndexesSQL()
1416
    {
1417
        self::assertContains(
1418
            "'Foo''Bar\\'",
1419
            $this->_platform->getListTableIndexesSQL("Foo'Bar\\.baz_table"),
1420
            '',
1421
            true
1422
        );
1423
    }
1424
1425
    /**
1426
     * @group 2859
1427
     */
1428
    public function testGetDefaultValueDeclarationSQLForDateType() : void
1429
    {
1430
        $currentDateSql = $this->_platform->getCurrentDateSQL();
1431
        foreach (['date', 'date_immutable'] as $type) {
1432
            $field = [
1433
                'type'    => Type::getType($type),
1434
                'default' => $currentDateSql,
1435
            ];
1436
1437
            self::assertSame(
1438
                " DEFAULT '" . $currentDateSql . "'",
1439
                $this->_platform->getDefaultValueDeclarationSQL($field)
1440
            );
1441
        }
1442
    }
1443
1444
    private function expectCteWithMaxRowNum(string $expectedSql, int $expectedMax, string $sql) : void
1445
    {
1446
        $pattern = 'WITH dctrn_cte AS (%s) SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte) AS doctrine_tbl WHERE doctrine_rownum <= %d ORDER BY doctrine_rownum ASC';
1447
        self::assertEquals(sprintf($pattern, $expectedSql, $expectedMax), $sql);
1448
    }
1449
1450
    private function expectCteWithMinAndMaxRowNums(string $expectedSql, int $expectedMin, int $expectedMax, string $sql) : void
1451
    {
1452
        $pattern = 'WITH dctrn_cte AS (%s) SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte) AS doctrine_tbl WHERE doctrine_rownum >= %d AND doctrine_rownum <= %d ORDER BY doctrine_rownum ASC';
1453
        self::assertEquals(sprintf($pattern, $expectedSql, $expectedMin, $expectedMax), $sql);
1454
    }
1455
}
1456