From 486d1901a96021890936273b470e37013f215490 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Fri, 4 Oct 2019 08:22:29 +0300 Subject: [PATCH 01/27] Add remote FakeTable for remote synonyms functionality --- Source/BuildOrder.txt | 8 +++ Source/tSQLt.FakeTable.ssp.sql | 45 ++++++++++++---- ...Lt.Private_AlterSysObjectForRemote.ssp.sql | 26 ++++++++++ .../tSQLt.Private_CreateFakeOfTable.ssp.sql | 7 +-- ...QLt.Private_CreateRemoteSysObjects.ssp.sql | 51 +++++++++++++++++++ ...DataTypeOrComputedColumnDefinition.sfn.sql | 2 +- ...ate_GetDefaultConstraintDefinition.sfn.sql | 2 +- ...SQLt.Private_GetIdentityDefinition.sfn.sql | 2 +- .../tSQLt.Private_GetRemoteObjectId.ssp.sql | 29 +++++++++++ Source/tSQLt.Private_SysColumns.svw.sql | 8 +++ .../tSQLt.Private_SysComputedColumns.svw.sql | 8 +++ ...SQLt.Private_SysDefaultConstraints.svw.sql | 8 +++ .../tSQLt.Private_SysIdentityColumns.svw.sql | 8 +++ Source/tSQLt.Private_SysObjects.svw.sql | 8 +++ 14 files changed, 197 insertions(+), 15 deletions(-) create mode 100644 Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql create mode 100644 Source/tSQLt.Private_CreateRemoteSysObjects.ssp.sql create mode 100644 Source/tSQLt.Private_GetRemoteObjectId.ssp.sql create mode 100644 Source/tSQLt.Private_SysColumns.svw.sql create mode 100644 Source/tSQLt.Private_SysComputedColumns.svw.sql create mode 100644 Source/tSQLt.Private_SysDefaultConstraints.svw.sql create mode 100644 Source/tSQLt.Private_SysIdentityColumns.svw.sql create mode 100644 Source/tSQLt.Private_SysObjects.svw.sql diff --git a/Source/BuildOrder.txt b/Source/BuildOrder.txt index fb97a1066..17a953744 100644 --- a/Source/BuildOrder.txt +++ b/Source/BuildOrder.txt @@ -4,8 +4,16 @@ tSQLt.Private_Bin2Hex.sfn.sql tSQLt.Private_NewTestClassList.tbl.sql tSQLt.Private_ResetNewTestClassList.ssp.sql tSQLt.Private_SysTypes.svw.sql +tSQLt.Private_SysColumns.svw.sql +tSQLt.Private_SysComputedColumns.svw.sql +tSQLt.Private_SysDefaultConstraints.svw.sql +tSQLt.Private_SysIdentityColumns.svw.sql +tSQLt.Private_SysObjects.svw.sql tSQLt.Private_GetFullTypeName.sfn.sql tSQLt.Private_DisallowOverwritingNonTestSchema.ssp.sql +tSQLt.Private_GetRemoteObjectId.ssp.sql +tSQLt.Private_AlterSysObjectForRemote.ssp.sql +tSQLt.Private_CreateRemoteSysObjects.ssp.sql tSQLt.Private_QuoteClassNameForNewTestClass.sfn.sql tSQLt.Private_MarkSchemaAsTestClass.ssp.sql tSQLt.NewTestClass.ssp.sql diff --git a/Source/tSQLt.FakeTable.ssp.sql b/Source/tSQLt.FakeTable.ssp.sql index a2635edba..fda84bfeb 100644 --- a/Source/tSQLt.FakeTable.ssp.sql +++ b/Source/tSQLt.FakeTable.ssp.sql @@ -13,7 +13,8 @@ BEGIN DECLARE @OrigTableName NVARCHAR(MAX); DECLARE @NewNameOfOriginalTable NVARCHAR(4000); DECLARE @OrigTableFullName NVARCHAR(MAX); SET @OrigTableFullName = NULL; - + DECLARE @RemoteObjectID INT; + SELECT @OrigSchemaName = @SchemaName, @OrigTableName = @TableName @@ -35,21 +36,47 @@ BEGIN FROM sys.synonyms AS S WHERE S.object_id = OBJECT_ID(@SchemaName + '.' + @NewNameOfOriginalTable); - IF(@OrigTableFullName IS NOT NULL) - BEGIN - IF(COALESCE(OBJECT_ID(@OrigTableFullName,'U'),OBJECT_ID(@OrigTableFullName,'V')) IS NULL) - BEGIN - RAISERROR('Cannot fake synonym %s.%s as it is pointing to %s, which is not a table or view!',16,10,@SchemaName,@TableName,@OrigTableFullName); - END; - END; + IF ( @OrigTableFullName IS NOT NULL ) + BEGIN + IF ( PARSENAME(@OrigTableFullName, 3) IS NOT NULL ) + BEGIN + + DECLARE @Cmd NVARCHAR(MAX); + DECLARE @params NVARCHAR(MAX); SET @params = '@RemoteObjectID INT OUT, @OrigTableFullName NVARCHAR(MAX)'; + + EXEC tSQLt.Private_GetRemoteObjectId @OrigTableFullName = @OrigTableFullName , + @RemoteObjectId = @RemoteObjectID OUTPUT + END; + + IF ( COALESCE(OBJECT_ID(@OrigTableFullName, 'U'), + OBJECT_ID(@OrigTableFullName, 'V'), + @RemoteObjectID) IS NULL ) + BEGIN + RAISERROR('Cannot fake synonym %s.%s as it is pointing to %s, which is not a table or view!',16,10,@SchemaName,@TableName,@OrigTableFullName); + END; + ELSE + BEGIN + + DECLARE @Database NVARCHAR(MAX); SET @Database = PARSENAME(@OrigTableFullName, 3); + DECLARE @Instance NVARCHAR(MAX); SET @Instance = PARSENAME(@OrigTableFullName, 4); + + EXEC tSQLt.Private_CreateRemoteSysObjects @Instance = @Instance, @Database = @Database; + END + END; ELSE BEGIN SET @OrigTableFullName = @SchemaName + '.' + @NewNameOfOriginalTable; END; - EXEC tSQLt.Private_CreateFakeOfTable @SchemaName, @TableName, @OrigTableFullName, @Identity, @ComputedColumns, @Defaults; + EXEC tSQLt.Private_CreateFakeOfTable @SchemaName, @TableName, @OrigTableFullName, @Identity, @ComputedColumns, @Defaults, @RemoteObjectID; EXEC tSQLt.Private_MarkFakeTable @SchemaName, @TableName, @NewNameOfOriginalTable; + + IF (@RemoteObjectID IS NOT NULL) + BEGIN + EXEC tSQLt.Private_CreateRemoteSysObjects @Instance = NULL, @Database = NULL; + END + END ---Build- GO diff --git a/Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql b/Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql new file mode 100644 index 000000000..0779666bf --- /dev/null +++ b/Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql @@ -0,0 +1,26 @@ +IF OBJECT_ID('tSQLt.Private_AlterSysObjectForRemote') IS NOT NULL + DROP PROCEDURE tSQLt.Private_AlterSysObjectForRemote; +GO +---Build+ +CREATE PROCEDURE tSQLt.Private_AlterSysObjectForRemote + @Instance NVARCHAR(MAX) , + @Database NVARCHAR(MAX) , + @SysObject NVARCHAR(MAX) , + @PrivateViewName NVARCHAR(MAX) +AS + BEGIN + DECLARE @sql NVARCHAR(MAX); + SET @sql = 'ALTER VIEW tSQLt.' + @PrivateViewName + ' AS + SELECT * ' + + CASE WHEN CAST(SERVERPROPERTY('ProductVersion') AS VARCHAR(MAX)) LIKE '9.%' + AND @SysObject = 'types' THEN ',0 is_table_type' + ELSE '' + END + ' FROM ' + COALESCE(QUOTENAME(@Instance) + '.', '') + + COALESCE(QUOTENAME(@Database) + '.', '') + 'sys.' + @SysObject + + ';'; + EXEC (@sql); + + RETURN 0; + END; +---Build- +GO \ No newline at end of file diff --git a/Source/tSQLt.Private_CreateFakeOfTable.ssp.sql b/Source/tSQLt.Private_CreateFakeOfTable.ssp.sql index af732fd63..6871a22db 100644 --- a/Source/tSQLt.Private_CreateFakeOfTable.ssp.sql +++ b/Source/tSQLt.Private_CreateFakeOfTable.ssp.sql @@ -7,7 +7,8 @@ CREATE PROCEDURE tSQLt.Private_CreateFakeOfTable @OrigTableFullName NVARCHAR(MAX), @Identity BIT, @ComputedColumns BIT, - @Defaults BIT + @Defaults BIT, + @RemoteObjectID INT AS BEGIN DECLARE @Cmd NVARCHAR(MAX); @@ -25,11 +26,11 @@ BEGIN THEN '' ELSE ' NULL' END - FROM sys.columns c + FROM tSQLt.Private_SysColumns c CROSS APPLY tSQLt.Private_GetDataTypeOrComputedColumnDefinition(c.user_type_id, c.max_length, c.precision, c.scale, c.collation_name, c.object_id, c.column_id, @ComputedColumns) cc CROSS APPLY tSQLt.Private_GetDefaultConstraintDefinition(c.object_id, c.column_id, @Defaults) AS dc CROSS APPLY tSQLt.Private_GetIdentityDefinition(c.object_id, c.column_id, @Identity) AS id - WHERE object_id = OBJECT_ID(@OrigTableFullName) + WHERE object_id = COALESCE(@RemoteObjectID, OBJECT_ID(@OrigTableFullName)) ORDER BY column_id FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'); diff --git a/Source/tSQLt.Private_CreateRemoteSysObjects.ssp.sql b/Source/tSQLt.Private_CreateRemoteSysObjects.ssp.sql new file mode 100644 index 000000000..8fbb3de7c --- /dev/null +++ b/Source/tSQLt.Private_CreateRemoteSysObjects.ssp.sql @@ -0,0 +1,51 @@ +IF OBJECT_ID('tSQLt.Private_CreateRemoteSysObjects') IS NOT NULL + DROP PROCEDURE tSQLt.Private_CreateRemoteSysObjects; +GO +---Build+ +CREATE PROCEDURE tSQLt.Private_CreateRemoteSysObjects + @Instance NVARCHAR(MAX) , + @Database NVARCHAR(MAX) +AS + BEGIN + DECLARE @SysObject NVARCHAR(MAX); + DECLARE @ViewName NVARCHAR(MAX); + + + DECLARE @SysObjects AS TABLE + ( + SysObject NVARCHAR(MAX) , + ViewName NVARCHAR(MAX) + ); + INSERT INTO @SysObjects + VALUES ( 'types', 'Private_SysTypes' ), + ( 'computed_columns', 'Private_SysComputedColumns' ), + ( 'default_constraints', 'Private_SysDefaultConstraints' ), + ( 'identity_columns', 'Private_SysIdentityColumns' ), + ( 'columns', 'Private_SysColumns' ), + ( 'objects', 'Private_SysObjects' ); + + DECLARE @cursor AS CURSOR; + + SET @cursor = CURSOR FOR +SELECT SysObject, ViewName + FROM @SysObjects; + + OPEN @cursor; + FETCH NEXT FROM @cursor INTO @SysObject, @ViewName; + + WHILE @@FETCH_STATUS = 0 + BEGIN + EXEC tSQLt.Private_AlterSysObjectForRemote @Instance = @Instance, + @Database = @Database, @SysObject = @SysObject, + @PrivateViewName = @ViewName; + + FETCH NEXT FROM @cursor INTO @SysObject, @ViewName; + END; + + CLOSE @cursor; + DEALLOCATE @cursor; + + RETURN 0; + END; +---Build- +GO diff --git a/Source/tSQLt.Private_GetDataTypeOrComputedColumnDefinition.sfn.sql b/Source/tSQLt.Private_GetDataTypeOrComputedColumnDefinition.sfn.sql index 50a397bb1..e06e9b50e 100644 --- a/Source/tSQLt.Private_GetDataTypeOrComputedColumnDefinition.sfn.sql +++ b/Source/tSQLt.Private_GetDataTypeOrComputedColumnDefinition.sfn.sql @@ -14,7 +14,7 @@ RETURN SELECT ' AS '+ cci.definition + CASE WHEN cci.is_persisted = 1 THEN ' PERSISTED' ELSE '' END AS ComputedColumnDefinition, cci.object_id, cci.column_id - FROM sys.computed_columns cci + FROM tSQLt.Private_SysComputedColumns cci )cc ON cc.object_id = V.ObjectId AND cc.column_id = V.ColumnId diff --git a/Source/tSQLt.Private_GetDefaultConstraintDefinition.sfn.sql b/Source/tSQLt.Private_GetDefaultConstraintDefinition.sfn.sql index 9c759c7a0..9ec2f30ff 100644 --- a/Source/tSQLt.Private_GetDefaultConstraintDefinition.sfn.sql +++ b/Source/tSQLt.Private_GetDefaultConstraintDefinition.sfn.sql @@ -9,7 +9,7 @@ RETURN SELECT COALESCE(DefaultDefinition, '') AS DefaultDefinition FROM (SELECT 1) X(X) LEFT JOIN (SELECT 1 AS IsDefault,' DEFAULT '+ definition AS DefaultDefinition,parent_object_id,parent_column_id - FROM sys.default_constraints + FROM tSQLt.Private_SysDefaultConstraints )dc ON dc.parent_object_id = @ObjectId AND dc.parent_column_id = @ColumnId diff --git a/Source/tSQLt.Private_GetIdentityDefinition.sfn.sql b/Source/tSQLt.Private_GetIdentityDefinition.sfn.sql index 05cbf178e..5ec9831ff 100644 --- a/Source/tSQLt.Private_GetIdentityDefinition.sfn.sql +++ b/Source/tSQLt.Private_GetIdentityDefinition.sfn.sql @@ -12,7 +12,7 @@ RETURN SELECT ' IDENTITY(' + CAST(seed_value AS NVARCHAR(MAX)) + ',' + CAST(increment_value AS NVARCHAR(MAX)) + ')' AS IdentityDefinition, object_id, column_id - FROM sys.identity_columns + FROM tSQLt.Private_SysIdentityColumns ) AS id ON id.object_id = @ObjectId AND id.column_id = @ColumnId diff --git a/Source/tSQLt.Private_GetRemoteObjectId.ssp.sql b/Source/tSQLt.Private_GetRemoteObjectId.ssp.sql new file mode 100644 index 000000000..9017e57ec --- /dev/null +++ b/Source/tSQLt.Private_GetRemoteObjectId.ssp.sql @@ -0,0 +1,29 @@ +IF OBJECT_ID('tSQLt.Private_GetRemoteObjectId') IS NOT NULL + DROP PROCEDURE tSQLt.Private_GetRemoteObjectId; +GO +---Build+ +GO +CREATE PROCEDURE tSQLt.Private_GetRemoteObjectId + @OrigTableFullName NVARCHAR(MAX) , + @RemoteObjectId INT OUTPUT +AS + BEGIN + DECLARE @RemotePath NVARCHAR(MAX) = COALESCE(QUOTENAME(PARSENAME(@OrigTableFullName, 4))+ '.', '') + + QUOTENAME(PARSENAME(@OrigTableFullName, 3)); + DECLARE @Cmd NVARCHAR(MAX); + DECLARE @params NVARCHAR(MAX) = '@RemoteObjectID INT OUT, @OrigTableFullName NVARCHAR(MAX)'; + SET @Cmd = ' + SELECT @RemoteObjectID = o.object_id + FROM ' + @RemotePath + '.sys.objects o + JOIN ' + @RemotePath + + '.sys.schemas s ON s.schema_id = o.schema_id + WHERE s.name = PARSENAME(@OrigTableFullName, 2) + AND o.name = PARSENAME(@OrigTableFullName, 1) + AND o.type IN ( ''U'', ''V'' );'; + + EXEC sp_executesql @Cmd, @params, @RemoteObjectID OUT, + @OrigTableFullName; + END; +GO +---Build- +GO diff --git a/Source/tSQLt.Private_SysColumns.svw.sql b/Source/tSQLt.Private_SysColumns.svw.sql new file mode 100644 index 000000000..e594f34bd --- /dev/null +++ b/Source/tSQLt.Private_SysColumns.svw.sql @@ -0,0 +1,8 @@ +IF OBJECT_ID('tSQLt.Private_SysColumns') IS NOT NULL DROP VIEW tSQLt.Private_SysColumns; +GO +---Build+ +GO +CREATE VIEW tSQLt.Private_SysColumns AS SELECT * FROM sys.columns AS cc; +GO +---Build- +GO diff --git a/Source/tSQLt.Private_SysComputedColumns.svw.sql b/Source/tSQLt.Private_SysComputedColumns.svw.sql new file mode 100644 index 000000000..13414a842 --- /dev/null +++ b/Source/tSQLt.Private_SysComputedColumns.svw.sql @@ -0,0 +1,8 @@ +IF OBJECT_ID('tSQLt.Private_SysComputedColumns') IS NOT NULL DROP VIEW tSQLt.Private_SysComputedColumns; +GO +---Build+ +GO +CREATE VIEW tSQLt.Private_SysComputedColumns AS SELECT * FROM sys.computed_columns AS cc; +GO +---Build- +GO diff --git a/Source/tSQLt.Private_SysDefaultConstraints.svw.sql b/Source/tSQLt.Private_SysDefaultConstraints.svw.sql new file mode 100644 index 000000000..e6250e2bc --- /dev/null +++ b/Source/tSQLt.Private_SysDefaultConstraints.svw.sql @@ -0,0 +1,8 @@ +IF OBJECT_ID('tSQLt.Private_SysDefaultConstraints') IS NOT NULL DROP VIEW tSQLt.Private_SysDefaultConstraints; +GO +---Build+ +GO +CREATE VIEW tSQLt.Private_SysDefaultConstraints AS SELECT * FROM sys.default_constraints AS cc; +GO +---Build- +GO diff --git a/Source/tSQLt.Private_SysIdentityColumns.svw.sql b/Source/tSQLt.Private_SysIdentityColumns.svw.sql new file mode 100644 index 000000000..202df612e --- /dev/null +++ b/Source/tSQLt.Private_SysIdentityColumns.svw.sql @@ -0,0 +1,8 @@ +IF OBJECT_ID('tSQLt.Private_SysIdentityColumns') IS NOT NULL DROP VIEW tSQLt.Private_SysIdentityColumns; +GO +---Build+ +GO +CREATE VIEW tSQLt.Private_SysIdentityColumns AS SELECT * FROM sys.identity_columns AS cc; +GO +---Build- +GO diff --git a/Source/tSQLt.Private_SysObjects.svw.sql b/Source/tSQLt.Private_SysObjects.svw.sql new file mode 100644 index 000000000..7a8240f2f --- /dev/null +++ b/Source/tSQLt.Private_SysObjects.svw.sql @@ -0,0 +1,8 @@ +IF OBJECT_ID('tSQLt.Private_SysObjects') IS NOT NULL DROP VIEW tSQLt.Private_SysObjects; +GO +---Build+ +GO +CREATE VIEW tSQLt.Private_SysObjects AS SELECT * FROM sys.objects AS cc; +GO +---Build- +GO From 7001123a29413d6c7a2bde879f294aa880c1fbf1 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Tue, 22 Oct 2019 09:04:05 +0300 Subject: [PATCH 02/27] Add creation of tSQLt_RemoteSynonymsTestDatabase database and needed for testing objects --- .../tSQLt_RemoteSynonymsTestDatabase.db.sql | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql diff --git a/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql b/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql new file mode 100644 index 000000000..041d479ee --- /dev/null +++ b/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql @@ -0,0 +1,96 @@ +IF NOT EXISTS ( SELECT * + FROM sys.databases + WHERE name = 'tSQLt_RemoteSynonymsTestDatabase' ) + BEGIN + CREATE DATABASE tSQLt_RemoteSynonymsTestDatabase; + END; +GO +USE tSQLt_RemoteSynonymsTestDatabase +GO + +IF EXISTS ( SELECT * + FROM sys.tables t + JOIN sys.schemas s ON s.schema_id = t.schema_id + WHERE t.name = 'tbl' + AND s.name = 'MyTestClass' ) + BEGIN + DROP TABLE MyTestClass.tbl; + END; +GO + +IF EXISTS ( SELECT * + FROM sys.types t + JOIN sys.schemas s ON s.schema_id = t.schema_id + WHERE t.name = 'UDT' + AND s.name = 'MyTestClass' ) + BEGIN + DROP TYPE MyTestClass.UDT; + END; +GO + +IF EXISTS ( SELECT * + FROM sys.schemas + WHERE name = 'MyTestClass' ) + BEGIN + DROP SCHEMA MyTestClass; + END; +GO + +IF EXISTS ( SELECT * + FROM sys.objects o + JOIN sys.schemas s ON s.schema_id = o.schema_id + WHERE o.name = 'TestView' + AND s.name = 'dbo' ) + BEGIN + DROP VIEW dbo.TestView; + END; + + +IF EXISTS ( SELECT * + FROM sys.tables t + JOIN sys.schemas s ON s.schema_id = t.schema_id + WHERE t.name = 'TestTable' + AND s.name = 'dbo' ) + BEGIN + DROP TABLE dbo.TestTable; + END; +GO + +IF EXISTS ( SELECT * + FROM sys.objects o + JOIN sys.schemas s ON s.schema_id = o.schema_id + WHERE o.name = 'NotATable' + AND s.name = 'dbo' ) + BEGIN + DROP PROCEDURE dbo.NotATable; + END; +GO + +CREATE TABLE dbo.TestTable + ( + c1 INT NULL , + c2 BIGINT NULL , + c3 VARCHAR(MAX) NULL + ); +GO +CREATE VIEW dbo.TestView +AS + SELECT * + FROM dbo.TestTable;; +GO + +CREATE PROCEDURE dbo.NotATable +AS + RETURN; +GO + +CREATE SCHEMA MyTestClass; +GO + +CREATE TYPE MyTestClass.UDT FROM NVARCHAR(20); +GO + +CREATE TABLE MyTestClass.tbl(i MyTestClass.UDT) +GO +USE $(NewDbName) +GO \ No newline at end of file From 8bcb40ecc2310afdd382d667903dbe69db041fb3 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Tue, 22 Oct 2019 09:04:22 +0300 Subject: [PATCH 03/27] Add bunch of remote FakeTable tests --- Tests/FakeTableTests.class.sql | 480 +++++++++++++++++++++++++++++++++ 1 file changed, 480 insertions(+) diff --git a/Tests/FakeTableTests.class.sql b/Tests/FakeTableTests.class.sql index 2b6c1c3d7..41be6f6c2 100644 --- a/Tests/FakeTableTests.class.sql +++ b/Tests/FakeTableTests.class.sql @@ -190,6 +190,18 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test FakeTable works with remote 2 part names in first parameter] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + + EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; + + EXEC FakeTableTests.AssertTableIsNewObjectThatHasNoConstraints 'FakeTableTests.TempTable1'; +END; +GO + CREATE PROC FakeTableTests.[test a faked table has no check constraints] AS BEGIN @@ -202,6 +214,19 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test a faked remote table has no check constraints] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT CHECK(i > 5)); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + + EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; + + EXEC FakeTableTests.AssertTableIsNewObjectThatHasNoConstraints 'FakeTableTests.TempTable1'; + INSERT INTO FakeTableTests.TempTable1 (i) VALUES (5); +END; +GO + CREATE PROC FakeTableTests.[test a faked table has no foreign keys] AS BEGIN @@ -215,6 +240,22 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test a faked remote table has no foreign keys] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable0(i INT PRIMARY KEY); + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT REFERENCES tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable0(i)); + + CREATE SYNONYM FakeTableTests.TempTable0 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable0; + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + + EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; + + EXEC FakeTableTests.AssertTableIsNewObjectThatHasNoConstraints 'FakeTableTests.TempTable1'; + INSERT INTO FakeTableTests.TempTable1 (i) VALUES (5); +END; +GO + CREATE PROC FakeTableTests.[test FakeTable: a faked table has any defaults removed] AS BEGIN @@ -233,6 +274,25 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable: a faked table has any defaults removed] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT DEFAULT(77)); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + + EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; + + EXEC FakeTableTests.AssertTableIsNewObjectThatHasNoConstraints 'FakeTableTests.TempTable1'; + INSERT INTO FakeTableTests.TempTable1 (i) DEFAULT VALUES; + + DECLARE @value INT; + SELECT @value = i + FROM FakeTableTests.TempTable1; + + EXEC tSQLt.AssertEquals NULL, @value; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable: a faked table has any unique constraints removed] AS BEGIN @@ -246,6 +306,20 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable: a faked table has any unique constraints removed] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT UNIQUE); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + + EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; + + EXEC FakeTableTests.AssertTableIsNewObjectThatHasNoConstraints 'FakeTableTests.TempTable1'; + INSERT INTO FakeTableTests.TempTable1 (i) VALUES (1); + INSERT INTO FakeTableTests.TempTable1 (i) VALUES (1); +END; +GO + CREATE PROC FakeTableTests.[test FakeTable: a faked table has any unique indexes removed] AS BEGIN @@ -260,6 +334,21 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable: a faked table has any unique indexes removed] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT); + CREATE UNIQUE INDEX UQ_tSQLt_test_TempTable1_i ON tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + + EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; + + EXEC FakeTableTests.AssertTableIsNewObjectThatHasNoConstraints 'FakeTableTests.TempTable1'; + INSERT INTO FakeTableTests.TempTable1 (i) VALUES (1); + INSERT INTO FakeTableTests.TempTable1 (i) VALUES (1); +END; +GO + CREATE PROC FakeTableTests.[test FakeTable: a faked table has any not null constraints removed] AS BEGIN @@ -272,6 +361,19 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable: a faked table has any not null constraints removed] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT NOT NULL); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + + EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; + + EXEC FakeTableTests.AssertTableIsNewObjectThatHasNoConstraints 'FakeTableTests.TempTable1'; + INSERT INTO FakeTableTests.TempTable1 (i) VALUES (NULL); +END; +GO + CREATE PROC FakeTableTests.[test FakeTable works on referencedTo tables] AS BEGIN @@ -293,6 +395,27 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable works on referencedTo tables] +AS +BEGIN + + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(i INT PRIMARY KEY); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst2(i INT PRIMARY KEY, tst1i INT REFERENCES tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(i)); + + BEGIN TRY + EXEC tSQLt.FakeTable 'FakeTableTests.tst1'; + END TRY + BEGIN CATCH + DECLARE @ErrorMessage NVARCHAR(MAX); + SELECT @ErrorMessage = ERROR_MESSAGE()+'{'+ISNULL(ERROR_PROCEDURE(),'NULL')+','+ISNULL(CAST(ERROR_LINE() AS VARCHAR),'NULL')+'}'; + + EXEC tSQLt.Fail 'FakeTable threw unexpected error:', @ErrorMessage; + END CATCH; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable doesn't produce output] AS BEGIN @@ -314,6 +437,28 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable doesn't produce output] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst(i INT); + CREATE SYNONYM FakeTableTests.tst FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst; + + EXEC tSQLt.CaptureOutput 'EXEC tSQLt.FakeTable ''FakeTableTests.tst'''; + + SELECT OutputText + INTO #actual + FROM tSQLt.CaptureOutputLog; + + SELECT TOP(0) * + INTO #expected + FROM #actual; + + INSERT INTO #expected(OutputText)VALUES(NULL); + + EXEC tSQLt.AssertEqualsTable '#expected','#actual'; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable doesn't preserve identity if @Identity parameter is not specified] AS BEGIN @@ -330,6 +475,21 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable doesn't preserve identity if @Identity parameter is not specified] +AS +BEGIN + + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(i INT IDENTITY(1,1)); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + + EXEC tSQLt.FakeTable 'FakeTableTests.tst1'; + + EXEC('INSERT INTO FakeTableTests.tst1(i) VALUES(1)'); + +END; +GO + CREATE PROC FakeTableTests.[test FakeTable doesn't preserve identity if @identity parameter is 0] AS BEGIN @@ -346,6 +506,19 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable doesn't preserve identity if @identity parameter is 0] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(i INT IDENTITY(1,1)); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + EXEC tSQLt.FakeTable 'FakeTableTests.tst1',@Identity=0; + + EXEC('INSERT INTO FakeTableTests.tst1(i) VALUES(1)'); + +END; +GO + CREATE PROC FakeTableTests.[test FakeTable preserves identity if @identity parameter is 1] AS BEGIN @@ -362,6 +535,27 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves identity if @identity parameter is 1] +AS +BEGIN + + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 ( i INT IDENTITY(1, 1) ); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + + EXEC tSQLt.FakeTable 'FakeTableTests.tst1', @Identity = 1; + BEGIN TRY + EXEC('INSERT INTO FakeTableTests.tst1(i) VALUES(1)'); + EXEC tSQLt.Fail @Message0 = N'Fake table has no identity column!'; + END TRY + BEGIN CATCH + DECLARE @ErrorMessage NVARCHAR(4000); + SET @ErrorMessage = ERROR_MESSAGE(); + EXEC tSQLt.AssertEquals @Expected = 'Cannot insert explicit value for identity column in table ''tst1'' when IDENTITY_INSERT is set to OFF.', + @Actual = @ErrorMessage; + END CATCH +END; +GO CREATE PROC FakeTableTests.[test FakeTable works with more than one column] AS @@ -386,6 +580,37 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable works with more than one column] +AS +BEGIN + + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(i1 INT,i2 INT,i3 INT,i4 INT,i5 INT,i6 INT,i7 INT,i8 INT); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + CREATE TABLE #Actual (column_id INT, [name] NVARCHAR(500)); + CREATE TABLE #Expected (column_id INT, [name] NVARCHAR(500)); + + INSERT INTO #Expected + SELECT column_id , + c.name + FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns c + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables t ON t.object_id = c.object_id + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas s ON s.schema_id = t.schema_id + WHERE t.name = 'tst1' + AND s.name = 'dbo'; + + EXEC tSQLt.FakeTable 'FakeTableTests.tst1'; + + INSERT INTO #Actual + SELECT column_id , + name + FROM sys.columns + WHERE object_id = OBJECT_ID('FakeTableTests.tst1'); + + EXEC tSQLt.AssertEqualsTable '#Expected', '#Actual'; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable works with ugly column and table names] AS BEGIN @@ -408,6 +633,37 @@ BEGIN EXEC tSQLt.AssertEqualsTable '#Expected','#Actual'; END; GO + +CREATE PROC FakeTableTests.[test remote FakeTable works with ugly column and table names] +AS +BEGIN + + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.[tst!@#$%^&*()_+ 1]([col!@#$%^&*()_+ 1] INT); + CREATE SYNONYM FakeTableTests.[tst!@#$%^&*()_+ 1] FOR tSQLt_RemoteSynonymsTestDatabase.dbo.[tst!@#$%^&*()_+ 1]; + + CREATE TABLE #Actual (column_id INT, [name] NVARCHAR(500)); + CREATE TABLE #Expected (column_id INT, [name] NVARCHAR(500)); + + INSERT INTO #Expected + SELECT column_id , + c.name + FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns c + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables t ON t.object_id = c.object_id + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas s ON s.schema_id = t.schema_id + WHERE t.name = 'tst!@#$%^&*()_+ 1' + AND s.name = 'dbo'; + + EXEC tSQLt.FakeTable 'FakeTableTests.[tst!@#$%^&*()_+ 1]'; + + INSERT INTO #Actual + SELECT column_id , + name + FROM sys.columns + WHERE object_id = OBJECT_ID('FakeTableTests.[tst!@#$%^&*()_+ 1]'); + + EXEC tSQLt.AssertEqualsTable '#Expected', '#Actual'; +END; +GO CREATE PROC FakeTableTests.[test FakeTable preserves identity base and step-size] AS @@ -432,6 +688,29 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves identity base and step-size] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (i INT IDENTITY(42,13)); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + INSERT INTO FakeTableTests.tst1 DEFAULT VALUES; + INSERT INTO FakeTableTests.tst1 DEFAULT VALUES; + + SELECT i + INTO #Expected + FROM FakeTableTests.tst1; + + EXEC tSQLt.FakeTable 'FakeTableTests.tst1',@Identity=1; + + INSERT INTO FakeTableTests.tst1 DEFAULT VALUES; + INSERT INTO FakeTableTests.tst1 DEFAULT VALUES; + + EXEC tSQLt.AssertEqualsTable '#Expected', 'FakeTableTests.tst1'; + +END; +GO + CREATE PROC FakeTableTests.[test FakeTable preserves data type of identity column with @Identity=0] AS BEGIN @@ -456,6 +735,36 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves data type of identity column with @Identity=0] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 ( i INT ); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + CREATE TABLE #Expected(type_name NVARCHAR(500)); + CREATE TABLE #Actual (type_name NVARCHAR(500)); + + INSERT INTO #Expected + SELECT tp.name type_name + FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns c + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.types tp ON tp.user_type_id = c.user_type_id + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables t ON t.object_id = c.object_id + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas s ON s.schema_id = t.schema_id + WHERE t.name = 'tst1' + AND s.name = 'dbo'; + + EXEC tSQLt.FakeTable 'FakeTableTests.tst1', @Identity = 0; + + INSERT INTO #Actual + SELECT TYPE_NAME(user_type_id) type_name + FROM sys.columns + WHERE object_id = OBJECT_ID('FakeTableTests.tst1'); + + EXEC tSQLt.AssertEqualsTable '#Expected','#Actual' + +END; +GO + CREATE PROC FakeTableTests.[test FakeTable preserves data type of identity column with @Identity=1] AS BEGIN @@ -480,6 +789,37 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves data type of identity column with @Identity=1] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 ( i [DECIMAL](4) IDENTITY(1,1) ); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + CREATE TABLE #Expected(type_name NVARCHAR(500), max_length INT, precision INT, scale INT); + CREATE TABLE #Actual(type_name NVARCHAR(500), max_length INT, precision INT, scale INT); + + INSERT INTO #Expected + SELECT tp.name type_name, c.max_length, c.precision, c.scale + FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns c + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.types tp ON tp.user_type_id = c.user_type_id + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables t ON t.object_id = c.object_id + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas s ON s.schema_id = t.schema_id + WHERE t.name = 'tst1' + AND s.name = 'dbo'; + + + EXEC tSQLt.FakeTable 'FakeTableTests.tst1',@Identity = 1; + + INSERT INTO #Actual + SELECT TYPE_NAME(user_type_id) type_name,max_length,precision,scale + FROM sys.columns + WHERE object_id = OBJECT_ID('FakeTableTests.tst1'); + + EXEC tSQLt.AssertEqualsTable '#Expected','#Actual'; + +END; +GO + CREATE PROC FakeTableTests.[test FakeTable works if IDENTITYCOL is not the first column (with @Identity=1)] AS BEGIN @@ -504,6 +844,42 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable works if IDENTITYCOL is not the first column (with @Identity=1)] +AS +BEGIN + + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(x INT, i INT IDENTITY(1,1), y VARCHAR(30)); + CREATE TABLE #Actual + ( + name VARCHAR(500) , + is_identity BIT + ); + CREATE TABLE #Expected + ( + name VARCHAR(500) , + is_identity BIT + ); + INSERT INTO #Expected + SELECT c.name, is_identity + FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns c + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables t ON t.object_id = c.object_id + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas s ON s.schema_id = t.schema_id + WHERE t.name = 'tst1' AND s.name = 'dbo'; + + CREATE SYNONYM dbo.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + EXEC tSQLt.FakeTable 'dbo.tst1',@Identity = 1; + + INSERT INTO #Actual + SELECT name, is_identity + FROM sys.columns + WHERE object_id = OBJECT_ID('dbo.tst1'); + + EXEC tSQLt.AssertEqualsTable '#Expected','#Actual'; + +END; +GO + CREATE PROC FakeTableTests.[test FakeTable works if there is no IDENTITYCOL and @Identity = 1] AS BEGIN @@ -528,6 +904,42 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable works if there is no IDENTITYCOL and @Identity = 1] +AS +BEGIN + + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(x INT, y VARCHAR(30)); + CREATE SYNONYM dbo.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + CREATE TABLE #Actual + ( + name VARCHAR(500) , + is_identity BIT + ); + CREATE TABLE #Expected + ( + name VARCHAR(500) , + is_identity BIT + ); + INSERT INTO #Expected + SELECT c.name, is_identity + FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns c + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables t ON t.object_id = c.object_id + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas s ON s.schema_id = t.schema_id + WHERE t.name = 'tst1' AND s.name = 'dbo'; + + EXEC tSQLt.FakeTable 'dbo.tst1',@Identity = 1; + + INSERT INTO #Actual + SELECT name, is_identity + FROM sys.columns + WHERE object_id = OBJECT_ID('dbo.tst1'); + + EXEC tSQLt.AssertEqualsTable '#Expected','#Actual'; + +END; +GO + CREATE PROC FakeTableTests.AssertTableStructureBeforeAndAfterCommandForComputedCols @TableName NVARCHAR(MAX), @Cmd NVARCHAR(MAX), @@ -892,6 +1304,24 @@ BEGIN END; GO +CREATE PROCEDURE FakeTableTests.[test Private_ResolveFakeTableNamesForBackwardCompatibility accepts parms in wrong order] +AS +BEGIN + EXEC ('CREATE SCHEMA MySchema'); + EXEC ('CREATE TABLE MySchema.MyTable (i INT)'); + + SELECT CleanSchemaName, CleanTableName + INTO #actual + FROM tSQLt.Private_ResolveFakeTableNamesForBackwardCompatibility('MySchema','MyTable'); + + SELECT TOP(0) * INTO #expected FROM #actual; + + INSERT INTO #expected (CleanSchemaName, CleanTableName) VALUES ('[MySchema]', '[MyTable]'); + + EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable preserves UDTd] AS BEGIN @@ -960,6 +1390,17 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test raises appropriate error if synonym is remote but not of a table] +AS +BEGIN + CREATE SYNONYM FakeTableTests.TempSynonym1 FOR tSQLt_RemoteSynonymsTestDatabase.FakeTableTests.NotATable; + + EXEC tSQLt.ExpectException @ExpectedMessage = 'Cannot fake synonym [FakeTableTests].[TempSynonym1] as it is pointing to [tSQLt_RemoteSynonymsTestDatabase].[FakeTableTests].[NotATable], which is not a table or view!'; + EXEC tSQLt.FakeTable 'FakeTableTests.TempSynonym1'; + +END; +GO + CREATE PROC FakeTableTests.[test can fake view] AS BEGIN @@ -972,6 +1413,20 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test can fake view to remote table] +AS +BEGIN + + SELECT TOP(0) * INTO #actual FROM tSQLt_RemoteSynonymsTestDatabase.dbo.TestTable; + + EXEC('CREATE VIEW FakeTableTests.TempView1 AS SELECT * FROM tSQLt_RemoteSynonymsTestDatabase.dbo.TestTable;'); + + EXEC tSQLt.FakeTable 'FakeTableTests.TempView1'; + + EXEC tSQLt.AssertEqualsTableSchema @Expected = 'FakeTableTests.TempTable1', @Actual = #actual; +END; +GO + CREATE PROC FakeTableTests.[test can fake local synonym of view] AS BEGIN @@ -985,6 +1440,18 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test can fake remote synonym of view] +AS +BEGIN + + CREATE SYNONYM FakeTableTests.TempSynonym1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TestView; + + EXEC tSQLt.FakeTable 'FakeTableTests.TempSynonym1'; + + EXEC('INSERT INTO FakeTableTests.TempSynonym1 VALUES (1,2,NULL)'); +END; +GO + CREATE PROC FakeTableTests.[test raises error if @TableName is multi-part and @SchemaName is not NULL] AS BEGIN @@ -1017,6 +1484,19 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable works with two parameters, if they are quoted] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1 ( i INT NOT NULL ); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + + EXEC tSQLt.FakeTable '[FakeTableTests]','[TempTable1]'; + + EXEC FakeTableTests.AssertTableIsNewObjectThatHasNoConstraints 'FakeTableTests.TempTable1'; + +END; +GO + --CREATE PROC FakeTableTests.[test FakeTable works with cross database synonym] --AS --BEGIN From 7c4b997a36553072e7467f37d0ea47dd55d0f844 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Fri, 25 Oct 2019 08:56:56 +0300 Subject: [PATCH 04/27] Add UDDT support + finish all FakeTable tests for Remote synonyms --- Source/BuildOrder.txt | 2 + ...Lt.Private_AlterSysObjectForRemote.ssp.sql | 25 +- .../tSQLt.Private_CreateFakeOfTable.ssp.sql | 5 + ...QLt.Private_CreateRemoteSysObjects.ssp.sql | 3 +- ...e_CreateRemoteUserDefinedDataTypes.ssp.sql | 58 ++++ Source/tSQLt.Private_SysSchemas.svw.sql | 8 + TestUtil/BuildOrder.txt | 1 + .../tSQLt_RemoteSynonymsTestDatabase.db.sql | 27 ++ Tests/FakeTableTests.class.sql | 282 ++++++++++++++++-- 9 files changed, 377 insertions(+), 34 deletions(-) create mode 100644 Source/tSQLt.Private_CreateRemoteUserDefinedDataTypes.ssp.sql create mode 100644 Source/tSQLt.Private_SysSchemas.svw.sql diff --git a/Source/BuildOrder.txt b/Source/BuildOrder.txt index 17a953744..e3b2f3974 100644 --- a/Source/BuildOrder.txt +++ b/Source/BuildOrder.txt @@ -9,6 +9,7 @@ tSQLt.Private_SysComputedColumns.svw.sql tSQLt.Private_SysDefaultConstraints.svw.sql tSQLt.Private_SysIdentityColumns.svw.sql tSQLt.Private_SysObjects.svw.sql +tSQLt.Private_SysSchemas.svw.sql tSQLt.Private_GetFullTypeName.sfn.sql tSQLt.Private_DisallowOverwritingNonTestSchema.ssp.sql tSQLt.Private_GetRemoteObjectId.ssp.sql @@ -56,6 +57,7 @@ tSQLt.Private_GetDataTypeOrComputedColumnDefinition.sfn.sql tSQLt.Private_GetIdentityDefinition.sfn.sql tSQLt.Private_GetDefaultConstraintDefinition.sfn.sql tSQLt.Private_GetUniqueConstraintDefinition.sfn.sql +tSQLt.Private_CreateRemoteUserDefinedDataTypes.ssp.sql tSQLt.Private_CreateFakeOfTable.ssp.sql tSQLt.Private_MarkFakeTable.ssp.sql tSQLt.FakeTable.ssp.sql diff --git a/Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql b/Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql index 0779666bf..3f966576e 100644 --- a/Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql +++ b/Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql @@ -11,13 +11,36 @@ AS BEGIN DECLARE @sql NVARCHAR(MAX); SET @sql = 'ALTER VIEW tSQLt.' + @PrivateViewName + ' AS - SELECT * ' + SELECT ' + + CASE WHEN @SysObject = 'types' THEN ' + name , + system_type_id , + user_type_id , + CASE WHEN is_user_defined = 1 THEN 1 + ELSE schema_id + END AS schema_id , + principal_id , + max_length , + precision , + scale , + collation_name , + is_nullable , + is_user_defined , + is_assembly_type , + default_object_id , + rule_object_id , + is_table_type + ' ELSE '* ' END + CASE WHEN CAST(SERVERPROPERTY('ProductVersion') AS VARCHAR(MAX)) LIKE '9.%' AND @SysObject = 'types' THEN ',0 is_table_type' ELSE '' END + ' FROM ' + COALESCE(QUOTENAME(@Instance) + '.', '') + COALESCE(QUOTENAME(@Database) + '.', '') + 'sys.' + @SysObject + ';'; + + + + EXEC (@sql); RETURN 0; diff --git a/Source/tSQLt.Private_CreateFakeOfTable.ssp.sql b/Source/tSQLt.Private_CreateFakeOfTable.ssp.sql index 6871a22db..3039ccbd4 100644 --- a/Source/tSQLt.Private_CreateFakeOfTable.ssp.sql +++ b/Source/tSQLt.Private_CreateFakeOfTable.ssp.sql @@ -13,6 +13,11 @@ AS BEGIN DECLARE @Cmd NVARCHAR(MAX); DECLARE @Cols NVARCHAR(MAX); + + IF (@RemoteObjectID IS NOT NULL) + BEGIN + EXEC tSQLt.Private_CreateRemoteUserDefinedDataTypes @RemoteObjectID = @RemoteObjectID + END SELECT @Cols = ( diff --git a/Source/tSQLt.Private_CreateRemoteSysObjects.ssp.sql b/Source/tSQLt.Private_CreateRemoteSysObjects.ssp.sql index 8fbb3de7c..8cbb84a6d 100644 --- a/Source/tSQLt.Private_CreateRemoteSysObjects.ssp.sql +++ b/Source/tSQLt.Private_CreateRemoteSysObjects.ssp.sql @@ -22,7 +22,8 @@ AS ( 'default_constraints', 'Private_SysDefaultConstraints' ), ( 'identity_columns', 'Private_SysIdentityColumns' ), ( 'columns', 'Private_SysColumns' ), - ( 'objects', 'Private_SysObjects' ); + ( 'objects', 'Private_SysObjects' ), + ( 'schemas', 'Private_SysSchemas' ); DECLARE @cursor AS CURSOR; diff --git a/Source/tSQLt.Private_CreateRemoteUserDefinedDataTypes.ssp.sql b/Source/tSQLt.Private_CreateRemoteUserDefinedDataTypes.ssp.sql new file mode 100644 index 000000000..ec805c1b5 --- /dev/null +++ b/Source/tSQLt.Private_CreateRemoteUserDefinedDataTypes.ssp.sql @@ -0,0 +1,58 @@ +IF OBJECT_ID('tSQLt.Private_CreateRemoteUserDefinedDataTypes') IS NOT NULL + DROP PROCEDURE tSQLt.Private_CreateRemoteUserDefinedDataTypes; +GO +---Build+ +CREATE PROCEDURE tSQLt.Private_CreateRemoteUserDefinedDataTypes @RemoteObjectID INT +AS + BEGIN + + DECLARE @UDDTs NVARCHAR(MAX) = ''; + + SELECT @UDDTs = @UDDTs + N'CREATE TYPE ' + QUOTENAME(sch.[name]) + + N'.' + QUOTENAME(typ.[name]) + N' FROM ' + styp.[name] + + CASE WHEN typ.[system_type_id] IN ( 41, 42, 43, 106, 108, + 165, 167, 173, 175, 231, + 239 ) + THEN N'(' + + CASE WHEN typ.[max_length] = -1 -- for: VARCHAR, NVARCHAR, VARBINARY + THEN N'MAX' + WHEN typ.[system_type_id] IN ( 165, 167, + 173, 175 ) + -- VARBINARY, VARCHAR, BINARY, CHAR + THEN CONVERT(NVARCHAR(5), typ.[max_length]) + WHEN typ.[system_type_id] IN ( 231, 239 ) -- NVARCHAR, NCHAR + THEN CONVERT(NVARCHAR(5), ( typ.[max_length] + / 2 )) + WHEN typ.[system_type_id] IN ( 41, 42, 43 ) + -- TIME, DATETIME2, DATETIMEOFFSET + THEN CONVERT(NVARCHAR(5), typ.[scale]) + WHEN typ.[system_type_id] IN ( 106, 108 ) -- DECIMAL, NUMERIC + THEN CONVERT(NVARCHAR(5), typ.[precision]) + + N', ' + + CONVERT(NVARCHAR(5), typ.[scale]) + END + N')' + ELSE N'' + END + CASE typ.[is_nullable] + WHEN 1 THEN N' NULL' + ELSE ' NOT NULL' + END + N';' + FROM tSQLt.Private_SysTypes typ + INNER JOIN tSQLt.Private_SysSchemas sch ON sch.[schema_id] = typ.[schema_id] + INNER JOIN tSQLt.Private_SysTypes styp ON styp.[user_type_id] = typ.[system_type_id] + JOIN tSQLt.Private_SysColumns AS c ON c.user_type_id = typ.user_type_id + JOIN tSQLt.Private_SysObjects t ON t.object_id = c.object_id + WHERE typ.[is_user_defined] = 1 + AND typ.[is_assembly_type] = 0 + AND typ.[is_table_type] = 0 + AND t.object_id = @RemoteObjectID + AND NOT EXISTS ( SELECT 1 + FROM sys.types t + JOIN sys.schemas s ON s.schema_id = t.schema_id + AND t.[name] COLLATE SQL_Latin1_General_CP1_CI_AS = typ.[name] COLLATE SQL_Latin1_General_CP1_CI_AS + AND s.[name] COLLATE SQL_Latin1_General_CP1_CI_AS = sch.[name] COLLATE SQL_Latin1_General_CP1_CI_AS ); + + EXEC (@UDDTs); + + END; +---Build- +GO diff --git a/Source/tSQLt.Private_SysSchemas.svw.sql b/Source/tSQLt.Private_SysSchemas.svw.sql new file mode 100644 index 000000000..2ef39844a --- /dev/null +++ b/Source/tSQLt.Private_SysSchemas.svw.sql @@ -0,0 +1,8 @@ +IF OBJECT_ID('tSQLt.Private_SysSchemas') IS NOT NULL DROP VIEW tSQLt.Private_SysSchemas; +GO +---Build+ +GO +CREATE VIEW tSQLt.Private_SysSchemas AS SELECT * FROM sys.schemas AS cc; +GO +---Build- +GO diff --git a/TestUtil/BuildOrder.txt b/TestUtil/BuildOrder.txt index 161d9d007..d93186830 100644 --- a/TestUtil/BuildOrder.txt +++ b/TestUtil/BuildOrder.txt @@ -1,3 +1,4 @@ +tSQLt_RemoteSynonymsTestDatabase.db.sql tSQLt_testutil.class.sql ../Build/temp/CreateTestUtilAssembly.sql ../Build/temp/GetUnsignedEmptyBytes.sql diff --git a/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql b/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql index 041d479ee..40388ef28 100644 --- a/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql +++ b/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql @@ -18,6 +18,16 @@ IF EXISTS ( SELECT * END; GO +IF EXISTS ( SELECT * + FROM sys.tables t + JOIN sys.schemas s ON s.schema_id = t.schema_id + WHERE t.name = 'tbli' + AND s.name = 'MyTestClass' ) + BEGIN + DROP TABLE MyTestClass.tbli; + END; +GO + IF EXISTS ( SELECT * FROM sys.types t JOIN sys.schemas s ON s.schema_id = t.schema_id @@ -28,6 +38,16 @@ IF EXISTS ( SELECT * END; GO +IF EXISTS ( SELECT * + FROM sys.types t + JOIN sys.schemas s ON s.schema_id = t.schema_id + WHERE t.name = 'UDTi' + AND s.name = 'MyTestClass' ) + BEGIN + DROP TYPE MyTestClass.UDTi; + END; +GO + IF EXISTS ( SELECT * FROM sys.schemas WHERE name = 'MyTestClass' ) @@ -92,5 +112,12 @@ GO CREATE TABLE MyTestClass.tbl(i MyTestClass.UDT) GO + +CREATE TYPE MyTestClass.UDTi FROM INT; +GO + +CREATE TABLE MyTestClass.tbli(i MyTestClass.UDTi) +GO + USE $(NewDbName) GO \ No newline at end of file diff --git a/Tests/FakeTableTests.class.sql b/Tests/FakeTableTests.class.sql index 41be6f6c2..8d938b21a 100644 --- a/Tests/FakeTableTests.class.sql +++ b/Tests/FakeTableTests.class.sql @@ -946,27 +946,50 @@ CREATE PROC FakeTableTests.AssertTableStructureBeforeAndAfterCommandForComputedC @ClearComputedCols INT AS BEGIN + + DECLARE @Database NVARCHAR(MAX), + @Instance NVARCHAR(MAX), + @Schema NVARCHAR(MAX), + @Table NVARCHAR(MAX); + + SELECT @Instance = PARSENAME(S.base_object_name, 4), + @Database = PARSENAME(S.base_object_name, 3), + @Schema = PARSENAME(S.base_object_name, 2), + @Table = PARSENAME(S.base_object_name, 1) + FROM sys.synonyms AS S + WHERE S.object_id = OBJECT_ID(@TableName); + + IF (@Database IS NOT NULL) + BEGIN + EXEC tSQLt.Private_CreateRemoteSysObjects @Instance = @Instance, @Database = @Database; + END + CREATE TABLE #Expected(column_id INT, IsComputedColumn BIT, is_persisted BIT, name NVARCHAR(MAX), definition NVARCHAR(MAX), user_type_id INT) + CREATE TABLE #Actual(column_id INT, IsComputedColumn BIT, is_persisted BIT, name NVARCHAR(MAX), definition NVARCHAR(MAX), user_type_id INT) + + INSERT INTO #Expected SELECT c.column_id, CASE WHEN cc.column_id IS NULL THEN 0 ELSE 1 END AS IsComputedColumn, cc.is_persisted, c.name, cc.definition, c.user_type_id - INTO #Expected - FROM sys.columns c - LEFT OUTER JOIN sys.computed_columns cc ON cc.object_id = c.object_id + FROM tSQLt.Private_SysColumns c + JOIN tSQLt.Private_SysObjects o ON o.object_id = c.object_id + JOIN tSQLt.Private_SysSchemas s ON s.schema_id = o.schema_id + LEFT OUTER JOIN tSQLt.Private_SysComputedColumns cc ON cc.object_id = c.object_id AND cc.column_id = c.column_id AND @ClearComputedCols = 0 - WHERE c.object_id = OBJECT_ID('dbo.tst1'); + WHERE o.name = COALESCE(@Table,PARSENAME(@TableName, 1)) AND s.name = COALESCE(@Schema, PARSENAME(@TableName, 2)); EXEC (@Cmd); - + + INSERT INTO #Actual SELECT c.column_id, CASE WHEN cc.column_id IS NULL THEN 0 ELSE 1 END AS IsComputedColumn, cc.is_persisted, c.name, cc.definition, c.user_type_id - INTO #Actual FROM sys.columns c LEFT OUTER JOIN sys.computed_columns cc ON cc.object_id = c.object_id AND cc.column_id = c.column_id - WHERE c.object_id = OBJECT_ID('dbo.tst1'); + WHERE c.object_id = OBJECT_ID(@TableName); EXEC tSQLt.AssertEqualsTable '#Expected','#Actual'; END; GO + CREATE PROC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForComputedCols @TableName NVARCHAR(MAX), @Cmd NVARCHAR(MAX) @@ -996,6 +1019,16 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves computed columns if @ComputedColumns = 1] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT, y AS x + 5 PERSISTED); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + EXEC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForComputedCols 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @ComputedColumns = 1;'; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable preserves persisted computed columns if @ComputedColumns = 1] AS BEGIN @@ -1007,6 +1040,16 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves persisted computed columns if @ComputedColumns = 1] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT, y AS x + 5 PERSISTED); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + EXEC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForComputedCols 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @ComputedColumns = 1;'; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable does not preserve persisted computed columns if @ComputedColumns = 0] AS BEGIN @@ -1018,6 +1061,16 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable does not preserve persisted computed columns if @ComputedColumns = 0] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT, y AS x + 5 PERSISTED); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + EXEC FakeTableTests.AssertTableAfterCommandHasNoComputedCols 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @ComputedColumns = 0;'; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable does not preserve persisted computed columns if @ComputedColumns is not specified] AS BEGIN @@ -1029,6 +1082,16 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable does not preserve persisted computed columns if @ComputedColumns is not specified] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT, y AS x + 5 PERSISTED); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + EXEC FakeTableTests.AssertTableAfterCommandHasNoComputedCols 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'';'; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable preserves multiple mixed persisted computed columns if @ComputedColumns = 1] AS BEGIN @@ -1040,28 +1103,62 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves multiple mixed persisted computed columns if @ComputedColumns = 1] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (NotComputed INT, ComputedAndPersisted AS (NotComputed + 5) PERSISTED, ComputedNotPersisted AS (NotComputed + 7), AnotherComputed AS (GETDATE())); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + EXEC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForComputedCols 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @ComputedColumns = 1;'; +END; +GO + CREATE PROC FakeTableTests.AssertTableStructureBeforeAndAfterCommandForDefaults @TableName NVARCHAR(MAX), @Cmd NVARCHAR(MAX), @ClearDefaults INT AS BEGIN + + DECLARE @Database NVARCHAR(MAX), + @Instance NVARCHAR(MAX), + @Schema NVARCHAR(MAX), + @Table NVARCHAR(MAX); + + SELECT @Instance = PARSENAME(S.base_object_name, 4), + @Database = PARSENAME(S.base_object_name, 3), + @Schema = PARSENAME(S.base_object_name, 2), + @Table = PARSENAME(S.base_object_name, 1) + FROM sys.synonyms AS S + WHERE S.object_id = OBJECT_ID(@TableName); + + IF (@Database IS NOT NULL) + BEGIN + EXEC tSQLt.Private_CreateRemoteSysObjects @Instance = @Instance, @Database = @Database; + END + CREATE TABLE #Expected(column_id INT, IsComputedColumn BIT, name NVARCHAR(MAX), definition NVARCHAR(MAX), user_type_id INT) + CREATE TABLE #Actual(column_id INT, IsComputedColumn BIT, name NVARCHAR(MAX), definition NVARCHAR(MAX), user_type_id INT) + + INSERT INTO #Expected SELECT c.column_id, CASE WHEN dc.parent_column_id IS NULL THEN 0 ELSE 1 END AS IsComputedColumn, c.name, dc.definition, c.user_type_id - INTO #Expected - FROM sys.columns c - LEFT OUTER JOIN sys.default_constraints dc ON dc.parent_object_id = c.object_id + FROM tSQLt.Private_SysColumns c + JOIN tSQLt.Private_SysObjects o ON o.object_id = c.object_id + JOIN tSQLt.Private_SysSchemas s ON s.schema_id = o.schema_id + LEFT OUTER JOIN tSQLt.Private_SysDefaultConstraints dc ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id AND @ClearDefaults = 0 - WHERE c.object_id = OBJECT_ID('dbo.tst1'); - + WHERE o.name = COALESCE(@Table,PARSENAME(@TableName, 1)) AND s.name = COALESCE(@Schema, PARSENAME(@TableName, 2)); + + IF NOT EXISTS (SELECT 1 FROM #Expected) EXEC tSQLt.Fail; + EXEC (@Cmd); + INSERT INTO #Actual SELECT c.column_id, CASE WHEN dc.parent_column_id IS NULL THEN 0 ELSE 1 END AS IsComputedColumn, c.name, dc.definition, c.user_type_id - INTO #Actual FROM sys.columns c LEFT OUTER JOIN sys.default_constraints dc ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id - WHERE c.object_id = OBJECT_ID('dbo.tst1'); + WHERE c.object_id = OBJECT_ID(@TableName); EXEC tSQLt.AssertEqualsTable '#Expected','#Actual'; END; @@ -1096,6 +1193,17 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remoteFakeTable does not preserve defaults if @Defaults is not specified] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT DEFAULT(5)); + + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + EXEC FakeTableTests.AssertTableAfterCommandHasNoDefaults 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'''; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable does not preserve defaults if @Defaults = 0] AS BEGIN @@ -1107,6 +1215,17 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable does not preserve defaults if @Defaults = 0] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT DEFAULT(5)); + + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + EXEC FakeTableTests.AssertTableAfterCommandHasNoDefaults 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @Defaults = 0;'; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable preserves defaults if @Defaults = 1] AS BEGIN @@ -1118,6 +1237,17 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves defaults if @Defaults = 1] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT DEFAULT(5)); + + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + EXEC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForDefaults 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @Defaults = 1;'; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable preserves defaults if @Defaults = 1 when multiple columns exist on table] AS BEGIN @@ -1132,6 +1262,18 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves defaults if @Defaults = 1 when multiple columns exist on table] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 ( ColWithNoDefault CHAR(3), + ColWithDefault DATETIME DEFAULT(GETDATE())); + + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + EXEC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForDefaults 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @Defaults = 1;'; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable preserves defaults if @Defaults = 1 when multiple varied columns exist on table] AS BEGIN @@ -1147,6 +1289,19 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves defaults if @Defaults = 1 when multiple varied columns exist on table] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 ( ColWithNoDefault CHAR(3), + ColWithDefault DATETIME DEFAULT(GETDATE()), + ColWithDiffDefault INT DEFAULT(-3)); + + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + EXEC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForDefaults 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @Defaults = 1;'; +END; +GO + CREATE PROC FakeTableTests.[test FakeTable preserves the collation of a column] AS BEGIN @@ -1172,6 +1327,35 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves the collation of a column] +AS +BEGIN + CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x VARCHAR(30) COLLATE Latin1_General_BIN, + y VARCHAR(40)); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + + CREATE TABLE #Expected (name NVARCHAR(MAX), collation_name NVARCHAR(MAX)); + CREATE TABLE #Actual (name NVARCHAR(MAX), collation_name NVARCHAR(MAX)); + + INSERT INTO #Expected + SELECT C.name ,C.collation_name + FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns AS C + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables AS t ON t.object_id = C.object_id + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas AS s ON s.schema_id = t.schema_id + WHERE t.name = 'tst1' AND s.name = 'dbo'; + + + EXEC tSQLt.FakeTable 'FakeTableTests.tst1'; + INSERT INTO #Actual + SELECT name, collation_name + FROM sys.columns + WHERE object_id = OBJECT_ID('FakeTableTests.tst1'); + + EXEC tSQLt.AssertEqualsTable '#Expected','#Actual'; + +END; +GO + CREATE PROCEDURE FakeTableTests.[test Private_ResolveFakeTableNamesForBackwardCompatibility returns quoted schema when schema and table provided] AS BEGIN @@ -1304,24 +1488,6 @@ BEGIN END; GO -CREATE PROCEDURE FakeTableTests.[test Private_ResolveFakeTableNamesForBackwardCompatibility accepts parms in wrong order] -AS -BEGIN - EXEC ('CREATE SCHEMA MySchema'); - EXEC ('CREATE TABLE MySchema.MyTable (i INT)'); - - SELECT CleanSchemaName, CleanTableName - INTO #actual - FROM tSQLt.Private_ResolveFakeTableNamesForBackwardCompatibility('MySchema','MyTable'); - - SELECT TOP(0) * INTO #expected FROM #actual; - - INSERT INTO #expected (CleanSchemaName, CleanTableName) VALUES ('[MySchema]', '[MyTable]'); - - EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; -END; -GO - CREATE PROC FakeTableTests.[test FakeTable preserves UDTd] AS BEGIN @@ -1344,6 +1510,32 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves UDTd] +AS +BEGIN + CREATE SYNONYM dbo.tbl FOR tSQLt_RemoteSynonymsTestDatabase.MyTestClass.tbli; + + CREATE TABLE #Expected (name NVARCHAR(255), system_type_id INT, max_length INT, precision INT, scale INT, is_nullable BIT); + CREATE TABLE #Actual (name NVARCHAR(255), system_type_id INT, max_length INT, precision INT, scale INT, is_nullable BIT); + + INSERT INTO #Expected + SELECT C.name ,C.system_type_id,C.max_length,C.precision,C.scale,C.is_nullable + FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns AS C + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables AS t ON t.object_id = C.object_id + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas AS s ON s.schema_id = t.schema_id + WHERE t.name = 'tbli' AND s.name = 'MyTestClass'; + + EXEC tSQLt.FakeTable @TableName = 'dbo.tbl'; + + INSERT INTO #Actual + SELECT C.name ,C.system_type_id,C.max_length,C.precision,C.scale,C.is_nullable + FROM sys.columns AS C WHERE C.object_id = OBJECT_ID('dbo.tbl'); + + EXEC tSQLt.AssertEqualsTable '#Expected','#Actual'; + +END; +GO + CREATE PROC FakeTableTests.[test FakeTable preserves UDTd based on char type] AS BEGIN @@ -1366,6 +1558,32 @@ BEGIN END; GO +CREATE PROC FakeTableTests.[test remote FakeTable preserves UDTd based on char type] +AS +BEGIN + CREATE SYNONYM dbo.tbl FOR tSQLt_RemoteSynonymsTestDatabase.MyTestClass.tbl; + + CREATE TABLE #Expected (name NVARCHAR(255), system_type_id INT, max_length INT, precision INT, scale INT, is_nullable BIT); + CREATE TABLE #Actual (name NVARCHAR(255), system_type_id INT, max_length INT, precision INT, scale INT, is_nullable BIT); + + INSERT INTO #Expected + SELECT C.name ,C.system_type_id,C.max_length,C.precision,C.scale,C.is_nullable + FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns AS C + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables AS t ON t.object_id = C.object_id + JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas AS s ON s.schema_id = t.schema_id + WHERE t.name = 'tbl' AND s.name = 'MyTestClass'; + + EXEC tSQLt.FakeTable @TableName = 'dbo.tbl'; + + INSERT INTO #Actual + SELECT C.name ,C.system_type_id,C.max_length,C.precision,C.scale,C.is_nullable + FROM sys.columns AS C WHERE C.object_id = OBJECT_ID('dbo.tbl'); + + EXEC tSQLt.AssertEqualsTable '#Expected','#Actual'; + +END; +GO + CREATE PROC FakeTableTests.[test can fake local synonym of table] AS BEGIN From 6b32fdaea9ffb236830e7cdcced833bd2bbe94fe Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Fri, 6 Dec 2019 08:42:55 +0200 Subject: [PATCH 05/27] Add possibility to fake function with temp or derived tables --- Source/BuildOrder.txt | 3 +- Source/tSQLt.FakeFunction.ssp.sql | 10 +- .../tSQLt.Private_CreateFakeFunction.ssp.sql | 19 +- ...ate_PrepareFakeFunctionOutputTable.ssp.sql | 27 +++ ...eObjectsCompatibleWithFakeFunction.ssp.sql | 39 +++- Tests/FakeFunctionTests.class.sql | 202 +++++++++++++++++- 6 files changed, 277 insertions(+), 23 deletions(-) create mode 100644 Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql diff --git a/Source/BuildOrder.txt b/Source/BuildOrder.txt index fb97a1066..67ef22c4f 100644 --- a/Source/BuildOrder.txt +++ b/Source/BuildOrder.txt @@ -6,6 +6,7 @@ tSQLt.Private_ResetNewTestClassList.ssp.sql tSQLt.Private_SysTypes.svw.sql tSQLt.Private_GetFullTypeName.sfn.sql tSQLt.Private_DisallowOverwritingNonTestSchema.ssp.sql +tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql tSQLt.Private_QuoteClassNameForNewTestClass.sfn.sql tSQLt.Private_MarkSchemaAsTestClass.ssp.sql tSQLt.NewTestClass.ssp.sql @@ -78,4 +79,4 @@ tSQLt.AssertEqualsTableSchema.ssp.sql tSQLt.AssertStringTable.udt.sql tSQLt.AssertStringIn.ssp.sql tSQLt.Reset.ssp.sql -tSQLt._Footer.sql +tSQLt._Footer.sql \ No newline at end of file diff --git a/Source/tSQLt.FakeFunction.ssp.sql b/Source/tSQLt.FakeFunction.ssp.sql index 0514bfe7d..88404a057 100644 --- a/Source/tSQLt.FakeFunction.ssp.sql +++ b/Source/tSQLt.FakeFunction.ssp.sql @@ -3,8 +3,10 @@ GO ---Build+ GO CREATE PROCEDURE tSQLt.FakeFunction - @FunctionName NVARCHAR(MAX), - @FakeFunctionName NVARCHAR(MAX) + @FunctionName NVARCHAR(MAX), + @FakeFunctionName NVARCHAR(MAX) = NULL, + @FakeDataSource NVARCHAR(MAX) = NULL + AS BEGIN DECLARE @FunctionObjectId INT; @@ -14,6 +16,7 @@ BEGIN EXEC tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction @FunctionName = @FunctionName, @FakeFunctionName = @FakeFunctionName, + @FakeDataSource = @FakeDataSource, @FunctionObjectId = @FunctionObjectId OUT, @FakeFunctionObjectId = @FakeFunctionObjectId OUT, @IsScalarFunction = @IsScalarFunction OUT; @@ -23,9 +26,10 @@ BEGIN EXEC tSQLt.Private_CreateFakeFunction @FunctionName = @FunctionName, @FakeFunctionName = @FakeFunctionName, + @FakeDataSource = @FakeDataSource, @FunctionObjectId = @FunctionObjectId, @FakeFunctionObjectId = @FakeFunctionObjectId, @IsScalarFunction = @IsScalarFunction; END; -GO +GO \ No newline at end of file diff --git a/Source/tSQLt.Private_CreateFakeFunction.ssp.sql b/Source/tSQLt.Private_CreateFakeFunction.ssp.sql index 389276d24..e11fa240a 100644 --- a/Source/tSQLt.Private_CreateFakeFunction.ssp.sql +++ b/Source/tSQLt.Private_CreateFakeFunction.ssp.sql @@ -3,11 +3,12 @@ GO ---Build+ GO CREATE PROCEDURE tSQLt.Private_CreateFakeFunction - @FunctionName NVARCHAR(MAX), - @FakeFunctionName NVARCHAR(MAX), - @FunctionObjectId INT, - @FakeFunctionObjectId INT, - @IsScalarFunction BIT + @FunctionName NVARCHAR(MAX), + @FakeFunctionName NVARCHAR(MAX) = NULL, + @FunctionObjectId INT = NULL, + @FakeFunctionObjectId INT = NULL, + @IsScalarFunction BIT = NULL, + @FakeDataSource NVARCHAR(MAX) = NULL AS BEGIN DECLARE @ReturnType NVARCHAR(MAX); @@ -44,9 +45,15 @@ BEGIN BEGIN EXEC('CREATE FUNCTION '+@FunctionName+'('+@ParameterList+') RETURNS '+@ReturnType+' AS BEGIN RETURN '+@FakeFunctionName+'('+@ParameterCallList+');END;'); END + ELSE IF (@FakeDataSource IS NOT NULL) + BEGIN + DECLARE @newTbleName VARCHAR(35); + EXEC tSQLt.Private_PrepareFakeFunctionOutputTable @FakeDataSource, @newTbleName OUTPUT; + EXEC ('CREATE FUNCTION '+@FunctionName+'('+@ParameterList+') RETURNS TABLE AS RETURN ( SELECT * FROM '+@newTbleName+');'); + END ELSE BEGIN EXEC('CREATE FUNCTION '+@FunctionName+'('+@ParameterList+') RETURNS TABLE AS RETURN SELECT * FROM '+@FakeFunctionName+'('+@ParameterCallList+');'); END; END; -GO +GO \ No newline at end of file diff --git a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql new file mode 100644 index 000000000..de020e3ab --- /dev/null +++ b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql @@ -0,0 +1,27 @@ +IF OBJECT_ID('tSQLt.Private_PrepareFakeFunctionOutputTable') IS NOT NULL + DROP PROCEDURE tSQLt.Private_PrepareFakeFunctionOutputTable; +GO +---Build+ +CREATE PROCEDURE tSQLt.Private_PrepareFakeFunctionOutputTable + @FakeDataSource NVARCHAR(MAX) , + @OutputTable sysname OUTPUT +AS + BEGIN + SET @OutputTable = 'tmp' + REPLACE(CAST(NEWID() AS CHAR(36)), '-',''); + + IF ( LOWER(LTRIM(@FakeDataSource)) LIKE 'select%' + AND OBJECT_ID(@FakeDataSource) IS NULL + ) + BEGIN + SET @FakeDataSource = N'(' + @FakeDataSource + N') a'; + END; + + DECLARE @newTblStmt VARCHAR(2000) = 'SELECT * INTO ' + @OutputTable + + ' FROM ' + @FakeDataSource; + + EXEC tSQLt.SuppressOutput @command = @newTblStmt; + + RETURN 0; + END; +---Build- +GO \ No newline at end of file diff --git a/Source/tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction.ssp.sql b/Source/tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction.ssp.sql index be16bf164..01cea8151 100644 --- a/Source/tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction.ssp.sql +++ b/Source/tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction.ssp.sql @@ -3,20 +3,44 @@ GO ---Build+ GO CREATE PROCEDURE tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction - @FunctionName NVARCHAR(MAX), - @FakeFunctionName NVARCHAR(MAX), - @FunctionObjectId INT OUTPUT, - @FakeFunctionObjectId INT OUTPUT, - @IsScalarFunction BIT OUTPUT + @FunctionName NVARCHAR(MAX), + @FakeFunctionName NVARCHAR(MAX) = NULL, + @FakeDataSource NVARCHAR(MAX) = NULL, + @FunctionObjectId INT = NULL OUTPUT, + @FakeFunctionObjectId INT = NULL OUTPUT, + @IsScalarFunction BIT = NULL OUTPUT AS BEGIN SET @FunctionObjectId = OBJECT_ID(@FunctionName); - SET @FakeFunctionObjectId = OBJECT_ID(@FakeFunctionName); IF(@FunctionObjectId IS NULL) BEGIN RAISERROR('%s does not exist!',16,10,@FunctionName); END; + + IF COALESCE(@FakeFunctionName, @FakeDataSource) IS NULL + BEGIN + RAISERROR ('Either @FakeFunctionName or @FakeDataSource must be provided', 16, 10); + END; + + IF (@FakeFunctionName IS NOT NULL AND @FakeDataSource IS NOT NULL ) + BEGIN + RAISERROR ('@FakeFunctionName and @FakeDataSource are mutually exclisive, please use 1 param', 16, 10); + END; + + IF (@FakeDataSource IS NOT NULL ) + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(@FunctionName) and type in ('TF', 'IF') + ) + BEGIN + RAISERROR('You can use @FakeDataSource only with Inline Table-Valued Function and Multi-Statement Table-Valued Function functions', 16, 10); + END + + RETURN 0; + END + + SET @FakeFunctionObjectId = OBJECT_ID(@FakeFunctionName); IF(@FakeFunctionObjectId IS NULL) BEGIN RAISERROR('%s does not exist!',16,10,@FakeFunctionName); @@ -49,5 +73,4 @@ BEGIN RAISERROR('Parameters of both functions must match! (This includes the return type for scalar functions.)',16,10); END; END; -GO - \ No newline at end of file +GO \ No newline at end of file diff --git a/Tests/FakeFunctionTests.class.sql b/Tests/FakeFunctionTests.class.sql index f0d883f70..72e36d4a2 100644 --- a/Tests/FakeFunctionTests.class.sql +++ b/Tests/FakeFunctionTests.class.sql @@ -95,9 +95,7 @@ CREATE PROCEDURE FakeFunctionTests.[test errors when function doesn't exist] AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.Fake() RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); - EXEC tSQLt.ExpectException @ExpectedMessage = 'FakeFunctionTests.ANotExistingFunction does not exist!', @ExpectedSeverity = 16, @ExpectedState = 10; - EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.ANotExistingFunction', @FakeFunctionName = 'FakeFunctionTests.Fake'; END; @@ -373,7 +371,6 @@ AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@id INT) RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); EXEC('CREATE FUNCTION FakeFunctionTests.AFakeFunction(@di INT) RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); - EXEC FakeFunctionTests.[assert parameter missmatch causes error]; END; GO @@ -391,7 +388,6 @@ AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@id NUMERIC(10,1)) RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); EXEC('CREATE FUNCTION FakeFunctionTests.AFakeFunction(@id NUMERIC(11,1)) RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); - EXEC FakeFunctionTests.[assert parameter missmatch causes error]; END; GO @@ -409,7 +405,6 @@ AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@id1 INT, @id2 INT) RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); EXEC('CREATE FUNCTION FakeFunctionTests.AFakeFunction(@id2 INT, @id1 INT) RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); - EXEC FakeFunctionTests.[assert parameter missmatch causes error]; END; GO @@ -422,4 +417,201 @@ BEGIN EXEC FakeFunctionTests.[assert parameter missmatch causes error]; END; GO +CREATE PROCEDURE FakeFunctionTests.[test @FakeFunctionName and @FakeDataSource can't be both NULL] +AS +BEGIN + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@a int, @b int) RETURNS TABLE AS RETURN (SELECT @a AS one);'); + EXEC tSQLt.ExpectException @ExpectedMessage = 'Either @FakeFunctionName or @FakeDataSource must be provided', @ExpectedSeverity = 16, @ExpectedState = 10; + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction'; +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test @FakeFunctionName and @FakeDataSource can't be both NOT NULL] +AS +BEGIN + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@a int, @b int) RETURNS TABLE AS RETURN (SELECT @a AS one);'); + + EXEC tSQLt.ExpectException @ExpectedMessage = '@FakeFunctionName and @FakeDataSource are mutually exclisive, please use 1 param', @ExpectedSeverity = 16, @ExpectedState = 10; + + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeFunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = 'select 1 one'; +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource with temp table with inline table function] +AS +BEGIN + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS TABLE AS RETURN (SELECT 1 AS one);'); + + CREATE TABLE #expected (a CHAR(1)); + INSERT INTO #expected VALUES('a'); + + CREATE TABLE #actual (a CHAR(1)) + + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = '#expected'; + + INSERT INTO #actual SELECT * FROM FakeFunctionTests.AFunction(); + + EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource with temp table with multistatement table valued function] +AS +BEGIN + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@a int) RETURNS @t TABLE (a int) AS BEGIN; + INSERT INTO @t (a) VALUES (0) RETURN; END;'); + + CREATE TABLE #expected (a CHAR(1)); + INSERT INTO #expected VALUES('a'); + + CREATE TABLE #actual (a CHAR(1)) + + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = '#expected'; + + INSERT INTO #actual SELECT * FROM FakeFunctionTests.AFunction(123); + + EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource to accept function with single param] +AS +BEGIN + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@a int) RETURNS TABLE AS RETURN (SELECT @a AS one);'); + + CREATE TABLE #expected (a INT); + INSERT INTO #expected VALUES(1); + + CREATE TABLE #actual (a INT) + + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = '#expected'; + + INSERT INTO #actual SELECT * FROM FakeFunctionTests.AFunction(123); + + EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource to accept function with multiple params] +AS +BEGIN + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@a int, @b int) RETURNS TABLE AS RETURN (SELECT @a AS one);'); + + CREATE TABLE #expected (a INT); + INSERT INTO #expected VALUES(1); + + CREATE TABLE #actual (a INT) + + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = '#expected'; + + INSERT INTO #actual SELECT * FROM FakeFunctionTests.AFunction(123, 321); + + EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource fakes function with all possible standard types] +AS +BEGIN + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction + ( +@p1 BIGINT ,@p2 BINARY ,@p3 BIT ,@p4 CHAR ,@p5 DATE ,@p6 DATETIME ,@p7 DATETIME2 ,@p8 DATETIMEOFFSET ,@p9 DECIMAL ,@p10 FLOAT ,@p11 GEOGRAPHY ,@p12 GEOMETRY , +@p14 IMAGE ,@p15 INT ,@p16 MONEY ,@p17 NCHAR ,@p18 NTEXT ,@p19 NUMERIC ,@p20 NVARCHAR ,@p21 REAL ,@p22 SMALLDATETIME ,@p23 SMALLINT ,@p24 SMALLMONEY ,@p25 SQL_VARIANT , +@p26 sysname ,@p27 TEXT ,@p28 TIME ,@p30 TINYINT ,@p31 UNIQUEIDENTIFIER ,@p32 VARBINARY ,@p33 VARCHAR ,@p34 XML) +RETURNS TABLE +AS RETURN + ( SELECT 1 AS one + ); +'); + + CREATE TABLE #expected (a INT); + INSERT INTO #expected VALUES(1); + + CREATE TABLE #actual (a INT) + + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = '#expected'; + + INSERT INTO #actual SELECT * +FROM FakeFunctionTests.AFunction(1, CAST(NULL AS BINARY), 0, '', '19830430', '19830430', + '19830430', '19830430', 1, 1, + 'LINESTRING(-122.360 47.656, -122.343 47.656 )', + geometry::STGeomFromText('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))', + 0), CAST(NULL AS IMAGE), 1, 1, + '', '', 1, '', 1, '19830430', 1, 1, '', '', '', + '00:00:01', 1, '61864287-DF2A-4FED-B609-26C523666E5A', + CAST(NULL AS VARBINARY), '', CAST(NULL AS XML)); + + EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource fakes function with VALUES clause] +AS +BEGIN + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS TABLE AS RETURN (SELECT 777 AS a);'); + + CREATE TABLE #expected (a INT); + INSERT INTO #expected VALUES(1); + + CREATE TABLE #actual (a INT) + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = '(VALUES(1)) a(a)'; + + INSERT INTO #actual SELECT * FROM FakeFunctionTests.AFunction(); + + EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource fakes function with derived table] +AS +BEGIN + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS TABLE AS RETURN (SELECT 777 AS a);'); + + CREATE TABLE #expected (a INT); + INSERT INTO #expected VALUES(1); + + CREATE TABLE #actual (a INT) + + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = 'select 1 as a'; + + INSERT INTO #actual SELECT * FROM FakeFunctionTests.AFunction(); + + EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource does not work with scalar function] +AS +BEGIN + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS NVARCHAR(10) AS BEGIN RETURN ''''; END;'); + + EXEC tSQLt.ExpectException @ExpectedMessage = 'You can use @FakeDataSource only with Inline Table-Valued Function and Multi-Statement Table-Valued Function functions', + @ExpectedSeverity = 16, + @ExpectedState = 10; + + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = 'select 1 as a'; + +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test Private_PrepareFakeFunctionOutputTable returns table with VALUES] +AS +BEGIN + + DECLARE @NewTable sysname; + + CREATE TABLE #Expected (a int); + INSERT INTO #Expected VALUES(1); + + EXEC tSQLt.Private_PrepareFakeFunctionOutputTable '(VALUES (1)) a(a)', @NewTable OUTPUT; + + EXEC tSQLt.AssertEqualsTable '#Expected', @NewTable; + +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test Private_PrepareFakeFunctionOutputTable returns table with SELECT query] +AS +BEGIN + + DECLARE @NewTable sysname; + + CREATE TABLE #Expected (a int); + INSERT INTO #Expected VALUES(1); + + EXEC tSQLt.Private_PrepareFakeFunctionOutputTable 'SELECT 1 AS a', @NewTable OUTPUT; + + EXEC tSQLt.AssertEqualsTable '#Expected', @NewTable; + +END; +GO \ No newline at end of file From bc92081b7e9e3ccbe682edd2adade835cc44ecb9 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Sun, 8 Dec 2019 20:25:16 +0200 Subject: [PATCH 06/27] Add new files to the SSMS project --- Source/Source.ssmssqlproj | 62 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/Source/Source.ssmssqlproj b/Source/Source.ssmssqlproj index 01b2d9a4d..0ee169c6a 100644 --- a/Source/Source.ssmssqlproj +++ b/Source/Source.ssmssqlproj @@ -205,6 +205,12 @@ tSQLt.NewTestClass.ssp.sql + + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True + Dev_tSQLt + + tSQLt.Private_AlterSysObjectForRemote.ssp.sql + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True Dev_tSQLt @@ -241,6 +247,18 @@ tSQLt.Private_CreateFakeFunction.ssp.sql + + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True + Dev_tSQLt + + tSQLt.Private_CreateRemoteSysObjects.ssp.sql + + + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True + Dev_tSQLt + + tSQLt.Private_CreateRemoteUserDefinedDataTypes.ssp.sql + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True Dev_tSQLt @@ -295,6 +313,12 @@ tSQLt.Private_GetForeignKeyDefinition.sfn.sql + + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True + Dev_tSQLt + + tSQLt.Private_GetRemoteObjectId.ssp.sql + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True Dev_tSQLt @@ -421,12 +445,48 @@ tSQLt.Private_SqlVersion.sfn.sql + + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True + Dev_tSQLt + + tSQLt.Private_SysColumns.svw.sql + + + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True + Dev_tSQLt + + tSQLt.Private_SysComputedColumns.svw.sql + + + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True + Dev_tSQLt + + tSQLt.Private_SysDefaultConstraints.svw.sql + + + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True + Dev_tSQLt + + tSQLt.Private_SysIdentityColumns.svw.sql + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True Dev_tSQLt tSQLt.Private_SysIndexes.svw.sql + + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True + Dev_tSQLt + + tSQLt.Private_SysObjects.svw.sql + + + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True + Dev_tSQLt + + tSQLt.Private_SysSchemas.svw.sql + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True Dev_tSQLt @@ -528,7 +588,7 @@ Dev_tSQLt tSQLtCLR_CreateProcs.sql - + From 7c2f65f3de6cf552a74564168a4d50439935687c Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Mon, 9 Dec 2019 08:56:55 +0200 Subject: [PATCH 07/27] Re-factor FakeTable SP --- Source/BuildOrder.txt | 1 + Source/tSQLt.FakeTable.ssp.sql | 45 +++++-------------- .../tSQLt.Private_GetRemoteObjectId.ssp.sql | 24 ++++++++-- ...eSynonymCompatibilityWithFakeTable.ssp.sql | 24 ++++++++++ 4 files changed, 57 insertions(+), 37 deletions(-) create mode 100644 Source/tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable.ssp.sql diff --git a/Source/BuildOrder.txt b/Source/BuildOrder.txt index e3b2f3974..0ab04bf6c 100644 --- a/Source/BuildOrder.txt +++ b/Source/BuildOrder.txt @@ -17,6 +17,7 @@ tSQLt.Private_AlterSysObjectForRemote.ssp.sql tSQLt.Private_CreateRemoteSysObjects.ssp.sql tSQLt.Private_QuoteClassNameForNewTestClass.sfn.sql tSQLt.Private_MarkSchemaAsTestClass.ssp.sql +tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable.ssp.sql tSQLt.NewTestClass.ssp.sql tSQLt.Fail.ssp.sql tSQLt.class.sql diff --git a/Source/tSQLt.FakeTable.ssp.sql b/Source/tSQLt.FakeTable.ssp.sql index fda84bfeb..680ee3f26 100644 --- a/Source/tSQLt.FakeTable.ssp.sql +++ b/Source/tSQLt.FakeTable.ssp.sql @@ -14,15 +14,16 @@ BEGIN DECLARE @NewNameOfOriginalTable NVARCHAR(4000); DECLARE @OrigTableFullName NVARCHAR(MAX); SET @OrigTableFullName = NULL; DECLARE @RemoteObjectID INT; + DECLARE @SynonymObjectId INT; SELECT @OrigSchemaName = @SchemaName, @OrigTableName = @TableName IF(@OrigTableName NOT IN (PARSENAME(@OrigTableName,1),QUOTENAME(PARSENAME(@OrigTableName,1))) AND @OrigSchemaName IS NOT NULL) - BEGIN - RAISERROR('When @TableName is a multi-part identifier, @SchemaName must be NULL!',16,10); - END + BEGIN + RAISERROR('When @TableName is a multi-part identifier, @SchemaName must be NULL!',16,10); + END SELECT @SchemaName = CleanSchemaName, @TableName = CleanTableName @@ -32,41 +33,17 @@ BEGIN EXEC tSQLt.Private_RenameObjectToUniqueName @SchemaName, @TableName, @NewNameOfOriginalTable OUTPUT; - SELECT @OrigTableFullName = S.base_object_name - FROM sys.synonyms AS S - WHERE S.object_id = OBJECT_ID(@SchemaName + '.' + @NewNameOfOriginalTable); - IF ( @OrigTableFullName IS NOT NULL ) + SET @OrigTableFullName = @SchemaName + '.' + @NewNameOfOriginalTable; + SET @SynonymObjectId = OBJECT_ID(@OrigTableFullName, 'SN'); + IF ( @SynonymObjectId > 0) BEGIN - IF ( PARSENAME(@OrigTableFullName, 3) IS NOT NULL ) - BEGIN + EXEC tSQLt.Private_GetRemoteObjectId @SynonymObjectId = @SynonymObjectId , + @RemoteObjectId = @RemoteObjectID OUTPUT, + @OrigTableFullName = @OrigTableFullName OUTPUT - DECLARE @Cmd NVARCHAR(MAX); - DECLARE @params NVARCHAR(MAX); SET @params = '@RemoteObjectID INT OUT, @OrigTableFullName NVARCHAR(MAX)'; - - EXEC tSQLt.Private_GetRemoteObjectId @OrigTableFullName = @OrigTableFullName , - @RemoteObjectId = @RemoteObjectID OUTPUT - END; - - IF ( COALESCE(OBJECT_ID(@OrigTableFullName, 'U'), - OBJECT_ID(@OrigTableFullName, 'V'), - @RemoteObjectID) IS NULL ) - BEGIN - RAISERROR('Cannot fake synonym %s.%s as it is pointing to %s, which is not a table or view!',16,10,@SchemaName,@TableName,@OrigTableFullName); - END; - ELSE - BEGIN - - DECLARE @Database NVARCHAR(MAX); SET @Database = PARSENAME(@OrigTableFullName, 3); - DECLARE @Instance NVARCHAR(MAX); SET @Instance = PARSENAME(@OrigTableFullName, 4); - - EXEC tSQLt.Private_CreateRemoteSysObjects @Instance = @Instance, @Database = @Database; - END + EXEC tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable @TableName, @SchemaName, @OrigTableFullName; END; - ELSE - BEGIN - SET @OrigTableFullName = @SchemaName + '.' + @NewNameOfOriginalTable; - END; EXEC tSQLt.Private_CreateFakeOfTable @SchemaName, @TableName, @OrigTableFullName, @Identity, @ComputedColumns, @Defaults, @RemoteObjectID; diff --git a/Source/tSQLt.Private_GetRemoteObjectId.ssp.sql b/Source/tSQLt.Private_GetRemoteObjectId.ssp.sql index 9017e57ec..aff4db86a 100644 --- a/Source/tSQLt.Private_GetRemoteObjectId.ssp.sql +++ b/Source/tSQLt.Private_GetRemoteObjectId.ssp.sql @@ -4,11 +4,22 @@ GO ---Build+ GO CREATE PROCEDURE tSQLt.Private_GetRemoteObjectId - @OrigTableFullName NVARCHAR(MAX) , - @RemoteObjectId INT OUTPUT + @SynonymObjectId INT , + @RemoteObjectId INT OUTPUT , + @OrigTableFullName sysname OUTPUT AS BEGIN - DECLARE @RemotePath NVARCHAR(MAX) = COALESCE(QUOTENAME(PARSENAME(@OrigTableFullName, 4))+ '.', '') + DECLARE @Database NVARCHAR(MAX); + DECLARE @Instance NVARCHAR(MAX); + + SELECT @OrigTableFullName = S.base_object_name , + @Database = PARSENAME(S.base_object_name, 3) , + @Instance = PARSENAME(S.base_object_name, 4) + FROM sys.synonyms AS S + WHERE S.object_id = @SynonymObjectId; + + DECLARE @RemotePath NVARCHAR(MAX) = COALESCE(QUOTENAME(PARSENAME(@OrigTableFullName, + 4)) + '.', '') + QUOTENAME(PARSENAME(@OrigTableFullName, 3)); DECLARE @Cmd NVARCHAR(MAX); DECLARE @params NVARCHAR(MAX) = '@RemoteObjectID INT OUT, @OrigTableFullName NVARCHAR(MAX)'; @@ -23,6 +34,13 @@ AS EXEC sp_executesql @Cmd, @params, @RemoteObjectID OUT, @OrigTableFullName; + + + IF ( @RemoteObjectID > 0 ) + BEGIN + EXEC tSQLt.Private_CreateRemoteSysObjects @Instance = @Instance, + @Database = @Database; + END; END; GO ---Build- diff --git a/Source/tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable.ssp.sql b/Source/tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable.ssp.sql new file mode 100644 index 000000000..aaaf34bb4 --- /dev/null +++ b/Source/tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable.ssp.sql @@ -0,0 +1,24 @@ +IF OBJECT_ID('tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable') IS NOT NULL + DROP PROCEDURE tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable; +GO +---Build+ +GO +CREATE PROCEDURE tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable + @TableName sysname , + @SchemaName sysname , + @OrigTableFullName sysname +AS + BEGIN + + IF NOT EXISTS ( SELECT 1 + FROM tSQLt.Private_SysObjects o + JOIN tSQLt.Private_SysSchemas s ON s.schema_id = o.schema_id + WHERE o.type IN ( 'U', 'V' ) + AND o.name = PARSENAME(@OrigTableFullName, 1) + AND s.name = PARSENAME(@OrigTableFullName, 2) ) + BEGIN + RAISERROR('Cannot fake synonym %s.%s as it is pointing to %s, which is not a table or view!',16,10,@SchemaName,@TableName,@OrigTableFullName); + END; + END; +GO + \ No newline at end of file From 554a7d560e0d5e2143e5f8b5a901def07dabdb19 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Thu, 12 Dec 2019 08:27:00 +0200 Subject: [PATCH 08/27] Addmissing configuration for remote database setup --- Build/Build.ssmssqlproj | 6 ++++++ Build/GrantUserAccessToRemoteDatabase.sql | 7 +++++++ Build/tSQLt.build | 2 ++ Build/tSQLt.build.xml | 2 ++ Build/tSQLt.validatebuild | 4 ++++ Build/tSQLt.validatebuild.xml | 6 ++++++ Source/BuildOrder.txt | 2 +- TestUtil/BuildOrder.txt | 2 +- 8 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 Build/GrantUserAccessToRemoteDatabase.sql diff --git a/Build/Build.ssmssqlproj b/Build/Build.ssmssqlproj index a18b2220d..07d36eead 100644 --- a/Build/Build.ssmssqlproj +++ b/Build/Build.ssmssqlproj @@ -103,6 +103,12 @@ GrantBuildPermissions.sql + + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True + Dev_tSQLt + + GrantUserAccessToRemoteDatabase.sql + 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True Dev_tSQLt diff --git a/Build/GrantUserAccessToRemoteDatabase.sql b/Build/GrantUserAccessToRemoteDatabase.sql new file mode 100644 index 000000000..99aabfa37 --- /dev/null +++ b/Build/GrantUserAccessToRemoteDatabase.sql @@ -0,0 +1,7 @@ +IF EXISTS ( SELECT 1 + FROM sys.databases + WHERE name = 'tSQLt_RemoteSynonymsTestDatabase' ) + BEGIN + + EXEC dbo.sp_changedbowner @loginame = N'tSQLt.Build'; + END; \ No newline at end of file diff --git a/Build/tSQLt.build b/Build/tSQLt.build index fc96ac43e..0fd6e9e8a 100644 --- a/Build/tSQLt.build +++ b/Build/tSQLt.build @@ -261,6 +261,7 @@ + @@ -286,6 +287,7 @@ + diff --git a/Build/tSQLt.build.xml b/Build/tSQLt.build.xml index b39bd865a..ac65e01bc 100644 --- a/Build/tSQLt.build.xml +++ b/Build/tSQLt.build.xml @@ -275,6 +275,7 @@ + @@ -300,6 +301,7 @@ + diff --git a/Build/tSQLt.validatebuild b/Build/tSQLt.validatebuild index 36349b27b..a8cfa2569 100644 --- a/Build/tSQLt.validatebuild +++ b/Build/tSQLt.validatebuild @@ -238,6 +238,10 @@ + + + + diff --git a/Build/tSQLt.validatebuild.xml b/Build/tSQLt.validatebuild.xml index af001c0f6..6b85835a0 100644 --- a/Build/tSQLt.validatebuild.xml +++ b/Build/tSQLt.validatebuild.xml @@ -341,6 +341,12 @@ + + + + + + diff --git a/Source/BuildOrder.txt b/Source/BuildOrder.txt index 0ab04bf6c..59a4d771f 100644 --- a/Source/BuildOrder.txt +++ b/Source/BuildOrder.txt @@ -12,9 +12,9 @@ tSQLt.Private_SysObjects.svw.sql tSQLt.Private_SysSchemas.svw.sql tSQLt.Private_GetFullTypeName.sfn.sql tSQLt.Private_DisallowOverwritingNonTestSchema.ssp.sql +tSQLt.Private_CreateRemoteSysObjects.ssp.sql tSQLt.Private_GetRemoteObjectId.ssp.sql tSQLt.Private_AlterSysObjectForRemote.ssp.sql -tSQLt.Private_CreateRemoteSysObjects.ssp.sql tSQLt.Private_QuoteClassNameForNewTestClass.sfn.sql tSQLt.Private_MarkSchemaAsTestClass.ssp.sql tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable.ssp.sql diff --git a/TestUtil/BuildOrder.txt b/TestUtil/BuildOrder.txt index d93186830..a89126bf7 100644 --- a/TestUtil/BuildOrder.txt +++ b/TestUtil/BuildOrder.txt @@ -1,6 +1,6 @@ -tSQLt_RemoteSynonymsTestDatabase.db.sql tSQLt_testutil.class.sql ../Build/temp/CreateTestUtilAssembly.sql ../Build/temp/GetUnsignedEmptyBytes.sql tSQLtTestUtilCLR_CreateItems.sql tSQLt_testutil_test.class.sql +tSQLt_RemoteSynonymsTestDatabase.db.sql \ No newline at end of file From 36d60a7482d5c2c5b277435b297ba493facc1110 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Tue, 20 Oct 2020 12:02:14 +0300 Subject: [PATCH 09/27] Remove wrongly removed new lines --- Tests/FakeFunctionTests.class.sql | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Tests/FakeFunctionTests.class.sql b/Tests/FakeFunctionTests.class.sql index 180cf2c75..a38bfbcb1 100644 --- a/Tests/FakeFunctionTests.class.sql +++ b/Tests/FakeFunctionTests.class.sql @@ -95,7 +95,9 @@ CREATE PROCEDURE FakeFunctionTests.[test errors when function doesn't exist] AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.Fake() RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); + EXEC tSQLt.ExpectException @ExpectedMessage = 'FakeFunctionTests.ANotExistingFunction does not exist!', @ExpectedSeverity = 16, @ExpectedState = 10; + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.ANotExistingFunction', @FakeFunctionName = 'FakeFunctionTests.Fake'; END; @@ -371,6 +373,7 @@ AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@id INT) RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); EXEC('CREATE FUNCTION FakeFunctionTests.AFakeFunction(@di INT) RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); + EXEC FakeFunctionTests.[assert parameter missmatch causes error]; END; GO @@ -388,6 +391,7 @@ AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@id NUMERIC(10,1)) RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); EXEC('CREATE FUNCTION FakeFunctionTests.AFakeFunction(@id NUMERIC(11,1)) RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); + EXEC FakeFunctionTests.[assert parameter missmatch causes error]; END; GO @@ -405,6 +409,7 @@ AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@id1 INT, @id2 INT) RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); EXEC('CREATE FUNCTION FakeFunctionTests.AFakeFunction(@id2 INT, @id1 INT) RETURNS NVARCHAR(MAX) AS BEGIN RETURN ''''; END;'); + EXEC FakeFunctionTests.[assert parameter missmatch causes error]; END; GO From 78650b09824b01ffaf3d5929d7362b67012f65e6 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Thu, 22 Oct 2020 10:15:17 +0300 Subject: [PATCH 10/27] PR#53 Add new lines at the end of the files --- Source/tSQLt.FakeFunction.ssp.sql | 2 +- Source/tSQLt.Private_CreateFakeFunction.ssp.sql | 2 +- Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql | 2 +- ...rivate_ValidateObjectsCompatibleWithFakeFunction.ssp.sql | 6 +++--- Tests/FakeFunctionTests.class.sql | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/tSQLt.FakeFunction.ssp.sql b/Source/tSQLt.FakeFunction.ssp.sql index 88404a057..e93d00a94 100644 --- a/Source/tSQLt.FakeFunction.ssp.sql +++ b/Source/tSQLt.FakeFunction.ssp.sql @@ -32,4 +32,4 @@ BEGIN @IsScalarFunction = @IsScalarFunction; END; -GO \ No newline at end of file +GO diff --git a/Source/tSQLt.Private_CreateFakeFunction.ssp.sql b/Source/tSQLt.Private_CreateFakeFunction.ssp.sql index e11fa240a..28216fa3e 100644 --- a/Source/tSQLt.Private_CreateFakeFunction.ssp.sql +++ b/Source/tSQLt.Private_CreateFakeFunction.ssp.sql @@ -56,4 +56,4 @@ BEGIN EXEC('CREATE FUNCTION '+@FunctionName+'('+@ParameterList+') RETURNS TABLE AS RETURN SELECT * FROM '+@FakeFunctionName+'('+@ParameterCallList+');'); END; END; -GO \ No newline at end of file +GO diff --git a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql index de020e3ab..31b63374d 100644 --- a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql +++ b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql @@ -24,4 +24,4 @@ AS RETURN 0; END; ---Build- -GO \ No newline at end of file +GO diff --git a/Source/tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction.ssp.sql b/Source/tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction.ssp.sql index 01cea8151..97f93f973 100644 --- a/Source/tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction.ssp.sql +++ b/Source/tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction.ssp.sql @@ -25,7 +25,7 @@ BEGIN IF (@FakeFunctionName IS NOT NULL AND @FakeDataSource IS NOT NULL ) BEGIN - RAISERROR ('@FakeFunctionName and @FakeDataSource are mutually exclisive, please use 1 param', 16, 10); + RAISERROR ('Both @FakeFunctionName and @FakeDataSource are valued. Please use only one.', 16, 10); END; IF (@FakeDataSource IS NOT NULL ) @@ -34,7 +34,7 @@ BEGIN SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(@FunctionName) and type in ('TF', 'IF') ) BEGIN - RAISERROR('You can use @FakeDataSource only with Inline Table-Valued Function and Multi-Statement Table-Valued Function functions', 16, 10); + RAISERROR('You can use @FakeDataSource only with Inline or Multi-Statement Table-Valued functions.', 16, 10); END RETURN 0; @@ -73,4 +73,4 @@ BEGIN RAISERROR('Parameters of both functions must match! (This includes the return type for scalar functions.)',16,10); END; END; -GO \ No newline at end of file +GO diff --git a/Tests/FakeFunctionTests.class.sql b/Tests/FakeFunctionTests.class.sql index a38bfbcb1..4b1e3df76 100644 --- a/Tests/FakeFunctionTests.class.sql +++ b/Tests/FakeFunctionTests.class.sql @@ -639,4 +639,4 @@ BEGIN EXEC tSQLt.AssertEqualsTable '#Expected', @NewTable; END; -GO \ No newline at end of file +GO From b2af972033abb9ec836076cfb9629ebd319991d7 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Thu, 22 Oct 2020 10:22:27 +0300 Subject: [PATCH 11/27] PR#53 Add missing schema for the table --- Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql index 31b63374d..2c5d304bd 100644 --- a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql +++ b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql @@ -7,7 +7,7 @@ CREATE PROCEDURE tSQLt.Private_PrepareFakeFunctionOutputTable @OutputTable sysname OUTPUT AS BEGIN - SET @OutputTable = 'tmp' + REPLACE(CAST(NEWID() AS CHAR(36)), '-',''); + SET @OutputTable = 'dbo.tmp' + REPLACE(CAST(NEWID() AS CHAR(36)), '-',''); IF ( LOWER(LTRIM(@FakeDataSource)) LIKE 'select%' AND OBJECT_ID(@FakeDataSource) IS NULL From 3c6628d0e1a24114742b93ea0757b4e8dafdb8fb Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Thu, 22 Oct 2020 10:45:59 +0300 Subject: [PATCH 12/27] Remove test --- Tests/FakeFunctionTests.class.sql | 34 ------------------------------- 1 file changed, 34 deletions(-) diff --git a/Tests/FakeFunctionTests.class.sql b/Tests/FakeFunctionTests.class.sql index 4b1e3df76..594ee15f8 100644 --- a/Tests/FakeFunctionTests.class.sql +++ b/Tests/FakeFunctionTests.class.sql @@ -509,40 +509,6 @@ BEGIN EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; END; GO -CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource fakes function with all possible standard types] -AS -BEGIN - EXEC('CREATE FUNCTION FakeFunctionTests.AFunction - ( -@p1 BIGINT ,@p2 BINARY ,@p3 BIT ,@p4 CHAR ,@p5 DATE ,@p6 DATETIME ,@p7 DATETIME2 ,@p8 DATETIMEOFFSET ,@p9 DECIMAL ,@p10 FLOAT ,@p11 GEOGRAPHY ,@p12 GEOMETRY , -@p14 IMAGE ,@p15 INT ,@p16 MONEY ,@p17 NCHAR ,@p18 NTEXT ,@p19 NUMERIC ,@p20 NVARCHAR ,@p21 REAL ,@p22 SMALLDATETIME ,@p23 SMALLINT ,@p24 SMALLMONEY ,@p25 SQL_VARIANT , -@p26 sysname ,@p27 TEXT ,@p28 TIME ,@p30 TINYINT ,@p31 UNIQUEIDENTIFIER ,@p32 VARBINARY ,@p33 VARCHAR ,@p34 XML) -RETURNS TABLE -AS RETURN - ( SELECT 1 AS one - ); -'); - - CREATE TABLE #expected (a INT); - INSERT INTO #expected VALUES(1); - - CREATE TABLE #actual (a INT) - - EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = '#expected'; - - INSERT INTO #actual SELECT * -FROM FakeFunctionTests.AFunction(1, CAST(NULL AS BINARY), 0, '', '19830430', '19830430', - '19830430', '19830430', 1, 1, - 'LINESTRING(-122.360 47.656, -122.343 47.656 )', - geometry::STGeomFromText('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))', - 0), CAST(NULL AS IMAGE), 1, 1, - '', '', 1, '', 1, '19830430', 1, 1, '', '', '', - '00:00:01', 1, '61864287-DF2A-4FED-B609-26C523666E5A', - CAST(NULL AS VARBINARY), '', CAST(NULL AS XML)); - - EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; -END; -GO CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource fakes function with VALUES clause] AS BEGIN From 83bb699026ec9b7d05b982ee677b2d5eedd67090 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Thu, 22 Oct 2020 11:11:05 +0300 Subject: [PATCH 13/27] PR#53 Fix tests --- Tests/FakeFunctionTests.class.sql | 82 +++++++++++++++++-------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/Tests/FakeFunctionTests.class.sql b/Tests/FakeFunctionTests.class.sql index 594ee15f8..ff3ed5c16 100644 --- a/Tests/FakeFunctionTests.class.sql +++ b/Tests/FakeFunctionTests.class.sql @@ -422,7 +422,7 @@ BEGIN EXEC FakeFunctionTests.[assert parameter missmatch causes error]; END; GO -CREATE PROCEDURE FakeFunctionTests.[test @FakeFunctionName and @FakeDataSource can't be both NULL] +CREATE PROCEDURE FakeFunctionTests.[test errors when both @FakeFunctionName and @FakeDataSource are passed] AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@a int, @b int) RETURNS TABLE AS RETURN (SELECT @a AS one);'); @@ -430,7 +430,7 @@ BEGIN EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction'; END; GO -CREATE PROCEDURE FakeFunctionTests.[test @FakeFunctionName and @FakeDataSource can't be both NOT NULL] +CREATE PROCEDURE FakeFunctionTests.[test errors when neither @FakeFunctionName nor @FakeDataSource are passed] AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@a int, @b int) RETURNS TABLE AS RETURN (SELECT @a AS one);'); @@ -440,7 +440,20 @@ BEGIN EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeFunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = 'select 1 one'; END; GO -CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource with temp table with inline table function] +CREATE PROCEDURE FakeFunctionTests.[test errors when scalar function is passed as @FakeDataSource] +AS +BEGIN + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS NVARCHAR(10) AS BEGIN RETURN ''''; END;'); + + EXEC tSQLt.ExpectException @ExpectedMessage = 'You can use @FakeDataSource only with Inline Table-Valued Function and Multi-Statement Table-Valued Function functions', + @ExpectedSeverity = 16, + @ExpectedState = 10; + + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = 'select 1 as a'; + +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test can fake Inline table function using a temp table as fake data source] AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS TABLE AS RETURN (SELECT 1 AS one);'); @@ -448,16 +461,14 @@ BEGIN CREATE TABLE #expected (a CHAR(1)); INSERT INTO #expected VALUES('a'); - CREATE TABLE #actual (a CHAR(1)) - EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = '#expected'; - INSERT INTO #actual SELECT * FROM FakeFunctionTests.AFunction(); + SELECT * INTO #actual FROM FakeFunctionTests.AFunction(); EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; END; GO -CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource with temp table with multistatement table valued function] +CREATE PROCEDURE FakeFunctionTests.[test can fake multi-statement table function using a temp table as fake data source] AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@a int) RETURNS @t TABLE (a int) AS BEGIN; @@ -466,16 +477,14 @@ BEGIN CREATE TABLE #expected (a CHAR(1)); INSERT INTO #expected VALUES('a'); - CREATE TABLE #actual (a CHAR(1)) - EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = '#expected'; - INSERT INTO #actual SELECT * FROM FakeFunctionTests.AFunction(123); + SELECT * INTO #actual FROM FakeFunctionTests.AFunction(123); EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; END; GO -CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource to accept function with single param] +CREATE PROCEDURE FakeFunctionTests.[test can fake function with one parameter] AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@a int) RETURNS TABLE AS RETURN (SELECT @a AS one);'); @@ -483,33 +492,29 @@ BEGIN CREATE TABLE #expected (a INT); INSERT INTO #expected VALUES(1); - CREATE TABLE #actual (a INT) - EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = '#expected'; - INSERT INTO #actual SELECT * FROM FakeFunctionTests.AFunction(123); + SELECT * INTO #actual FROM FakeFunctionTests.AFunction(123); EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; END; GO -CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource to accept function with multiple params] +CREATE PROCEDURE FakeFunctionTests.[test can fake function with multiple parameters] AS BEGIN - EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@a int, @b int) RETURNS TABLE AS RETURN (SELECT @a AS one);'); + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@a int, @b int, @c char(1)) RETURNS TABLE AS RETURN (SELECT @a AS one);'); CREATE TABLE #expected (a INT); INSERT INTO #expected VALUES(1); - CREATE TABLE #actual (a INT) - EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = '#expected'; - INSERT INTO #actual SELECT * FROM FakeFunctionTests.AFunction(123, 321); + SELECT * INTO #actual FROM FakeFunctionTests.AFunction(123, 321, 'a'); EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; END; GO -CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource fakes function with VALUES clause] +CREATE PROCEDURE FakeFunctionTests.[test can fake function with VALUES clause as fake data source] AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS TABLE AS RETURN (SELECT 777 AS a);'); @@ -517,11 +522,27 @@ BEGIN CREATE TABLE #expected (a INT); INSERT INTO #expected VALUES(1); - CREATE TABLE #actual (a INT) - EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = '(VALUES(1)) a(a)'; - INSERT INTO #actual SELECT * FROM FakeFunctionTests.AFunction(); + SELECT * INTO #actual FROM FakeFunctionTests.AFunction(); + + EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test can fake function with two part named table as fake data source] +AS +BEGIN + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS TABLE AS RETURN (SELECT 777 AS a);'); + + CREATE TABLE #expected (a INT); + INSERT INTO #expected VALUES(1); + + SELECT * INTO FakeFunctionTests.SomeTable FROM #expected; + + + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = 'FakeFunctionTests.SomeTable'; + + SELECT * INTO #actual FROM FakeFunctionTests.AFunction(); EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; END; @@ -546,7 +567,7 @@ BEGIN EXEC tSQLt.AssertEqualsString @Expected = 233515, @Actual = @Actual; END; GO -CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource fakes function with derived table] +CREATE PROCEDURE FakeFunctionTests.[test can fake with derived table] AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS TABLE AS RETURN (SELECT 777 AS a);'); @@ -563,19 +584,6 @@ BEGIN EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; END; GO -CREATE PROCEDURE FakeFunctionTests.[test @FakeDataSource does not work with scalar function] -AS -BEGIN - EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS NVARCHAR(10) AS BEGIN RETURN ''''; END;'); - - EXEC tSQLt.ExpectException @ExpectedMessage = 'You can use @FakeDataSource only with Inline Table-Valued Function and Multi-Statement Table-Valued Function functions', - @ExpectedSeverity = 16, - @ExpectedState = 10; - - EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = 'select 1 as a'; - -END; -GO CREATE PROCEDURE FakeFunctionTests.[test Private_PrepareFakeFunctionOutputTable returns table with VALUES] AS BEGIN From d0ebdd3800bd40bdf729ac12f955dd7cd3e25097 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Fri, 23 Oct 2020 10:42:18 +0300 Subject: [PATCH 14/27] Change naming convention for the FakeFunction data output table name --- Source/tSQLt.Private_CreateFakeFunction.ssp.sql | 4 ++-- ...t.Private_PrepareFakeFunctionOutputTable.ssp.sql | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Source/tSQLt.Private_CreateFakeFunction.ssp.sql b/Source/tSQLt.Private_CreateFakeFunction.ssp.sql index 28216fa3e..c9c34c5b7 100644 --- a/Source/tSQLt.Private_CreateFakeFunction.ssp.sql +++ b/Source/tSQLt.Private_CreateFakeFunction.ssp.sql @@ -47,8 +47,8 @@ BEGIN END ELSE IF (@FakeDataSource IS NOT NULL) BEGIN - DECLARE @newTbleName VARCHAR(35); - EXEC tSQLt.Private_PrepareFakeFunctionOutputTable @FakeDataSource, @newTbleName OUTPUT; + DECLARE @newTbleName NVARCHAR(MAX); + EXEC tSQLt.Private_PrepareFakeFunctionOutputTable @FakeDataSource, @FunctionName, @newTbleName OUTPUT; EXEC ('CREATE FUNCTION '+@FunctionName+'('+@ParameterList+') RETURNS TABLE AS RETURN ( SELECT * FROM '+@newTbleName+');'); END ELSE diff --git a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql index 2c5d304bd..eeec58614 100644 --- a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql +++ b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql @@ -3,11 +3,15 @@ IF OBJECT_ID('tSQLt.Private_PrepareFakeFunctionOutputTable') IS NOT NULL GO ---Build+ CREATE PROCEDURE tSQLt.Private_PrepareFakeFunctionOutputTable - @FakeDataSource NVARCHAR(MAX) , + @FakeDataSource NVARCHAR(MAX), + @FunctionName NVARCHAR(MAX), @OutputTable sysname OUTPUT AS BEGIN - SET @OutputTable = 'dbo.tmp' + REPLACE(CAST(NEWID() AS CHAR(36)), '-',''); + DECLARE @SchemaName SYSNAME; + SET @SchemaName = COALESCE(PARSENAME(@FunctionName, 2), 'tSQlt'); + SET @FunctionName = LEFT(PARSENAME(@FunctionName, 1), 100); + SET @OutputTable = CONCAT(QUOTENAME(@SchemaName), '.', QUOTENAME(CONCAT(@FunctionName, '_', 'FakeFunctionOutputTable'))); IF ( LOWER(LTRIM(@FakeDataSource)) LIKE 'select%' AND OBJECT_ID(@FakeDataSource) IS NULL @@ -16,10 +20,9 @@ AS SET @FakeDataSource = N'(' + @FakeDataSource + N') a'; END; - DECLARE @newTblStmt VARCHAR(2000) = 'SELECT * INTO ' + @OutputTable - + ' FROM ' + @FakeDataSource; + DECLARE @Cmd NVARCHAR(2000) = CONCAT('SELECT * INTO ', @OutputTable, ' FROM ', @FakeDataSource); - EXEC tSQLt.SuppressOutput @command = @newTblStmt; + EXEC sp_executesql @Cmd; RETURN 0; END; From 03e79a1b796b756e7b35fd829ed8d69a656a94e6 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Fri, 23 Oct 2020 10:59:04 +0300 Subject: [PATCH 15/27] Fix issue with the long function names --- ...SQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql index eeec58614..a8df84040 100644 --- a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql +++ b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql @@ -5,22 +5,22 @@ GO CREATE PROCEDURE tSQLt.Private_PrepareFakeFunctionOutputTable @FakeDataSource NVARCHAR(MAX), @FunctionName NVARCHAR(MAX), - @OutputTable sysname OUTPUT + @OutputTable NVARCHAR(MAX) OUTPUT AS BEGIN - DECLARE @SchemaName SYSNAME; + DECLARE @SchemaName NVARCHAR(MAX); SET @SchemaName = COALESCE(PARSENAME(@FunctionName, 2), 'tSQlt'); SET @FunctionName = LEFT(PARSENAME(@FunctionName, 1), 100); - SET @OutputTable = CONCAT(QUOTENAME(@SchemaName), '.', QUOTENAME(CONCAT(@FunctionName, '_', 'FakeFunctionOutputTable'))); + SET @OutputTable = CONCAT(QUOTENAME(@SchemaName), '.', QUOTENAME(CONCAT(@FunctionName, '_FakeFunctionOutputTable'))); IF ( LOWER(LTRIM(@FakeDataSource)) LIKE 'select%' AND OBJECT_ID(@FakeDataSource) IS NULL ) BEGIN - SET @FakeDataSource = N'(' + @FakeDataSource + N') a'; + SET @FakeDataSource = CONCAT(N'(', @FakeDataSource, N') a'); END; - DECLARE @Cmd NVARCHAR(2000) = CONCAT('SELECT * INTO ', @OutputTable, ' FROM ', @FakeDataSource); + DECLARE @Cmd NVARCHAR(MAX) = CONCAT('SELECT * INTO ', @OutputTable, ' FROM ', @FakeDataSource); EXEC sp_executesql @Cmd; From 6d70b471dab7aa4130c8097ec51612df1f455213 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Fri, 23 Oct 2020 12:30:39 +0300 Subject: [PATCH 16/27] Add FakeFunction test for long name and output table schema --- Tests/FakeFunctionTests.class.sql | 50 +++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/Tests/FakeFunctionTests.class.sql b/Tests/FakeFunctionTests.class.sql index ff3ed5c16..6542fe704 100644 --- a/Tests/FakeFunctionTests.class.sql +++ b/Tests/FakeFunctionTests.class.sql @@ -584,6 +584,33 @@ BEGIN EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; END; GO +CREATE PROCEDURE FakeFunctionTests.[test can fake function with very long name] +AS +BEGIN + + DECLARE @maxFunctionName sysname, + @Cmd NVARCHAR(MAX); + SET @maxFunctionName = CONCAT('FakeFunctionTests.', REPLICATE('a', 128)); + + SET @Cmd = CONCAT('CREATE FUNCTION ', @maxFunctionName, '() RETURNS TABLE AS RETURN (SELECT 777 AS a);'); + EXEC(@Cmd); + + CREATE TABLE #Expected (a INT); + SELECT * INTO #Actual FROM #Expected; + + INSERT INTO #Expected VALUES (1); + + EXEC tSQLt.FakeFunction @FunctionName = @maxFunctionName, + @FakeDataSource = N'#Expected'; + + + SET @Cmd = CONCAT('INSERT INTO #Actual SELECT * FROM ', @maxFunctionName, '();'); + EXEC(@Cmd); + + EXEC tSQLt.AssertEqualsTable '#Expected', '#Actual'; + +END; +GO CREATE PROCEDURE FakeFunctionTests.[test Private_PrepareFakeFunctionOutputTable returns table with VALUES] AS BEGIN @@ -593,7 +620,7 @@ BEGIN CREATE TABLE #Expected (a int); INSERT INTO #Expected VALUES(1); - EXEC tSQLt.Private_PrepareFakeFunctionOutputTable '(VALUES (1)) a(a)', @NewTable OUTPUT; + EXEC tSQLt.Private_PrepareFakeFunctionOutputTable '(VALUES (1)) a(a)', 'func', @NewTable OUTPUT; EXEC tSQLt.AssertEqualsTable '#Expected', @NewTable; @@ -608,9 +635,28 @@ BEGIN CREATE TABLE #Expected (a int); INSERT INTO #Expected VALUES(1); - EXEC tSQLt.Private_PrepareFakeFunctionOutputTable 'SELECT 1 AS a', @NewTable OUTPUT; + EXEC tSQLt.Private_PrepareFakeFunctionOutputTable 'SELECT 1 AS a','func', @NewTable OUTPUT; EXEC tSQLt.AssertEqualsTable '#Expected', @NewTable; END; GO +CREATE PROCEDURE FakeFunctionTests.[test Private_PrepareFakeFunctionOutputTable output table in the same schema as function] +AS +BEGIN + DECLARE @Expected INT = 1; + DECLARE @Actual INT = 0; + DECLARE @NewTable sysname; + + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS TABLE AS RETURN (SELECT 777 AS a);'); + + EXEC tSQLt.Private_PrepareFakeFunctionOutputTable 'SELECT 1 AS a', 'FakeFunctionTests.AFunction', @NewTable OUTPUT; + + SELECT @Actual = COUNT(*) + FROM sys.tables + WHERE name = 'AFunction_FakeFunctionOutputTable' AND schema_id = SCHEMA_ID('FakeFunctionTests'); + + EXEC tSQLt.AssertEquals @Expected, @Actual; + +END; +GO From 0f232751cf6078c1b6768973fba849a99ef52100 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Fri, 23 Oct 2020 12:47:04 +0300 Subject: [PATCH 17/27] Add test for data source table starting with SELECT --- Tests/FakeFunctionTests.class.sql | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Tests/FakeFunctionTests.class.sql b/Tests/FakeFunctionTests.class.sql index 6542fe704..585e8c2fb 100644 --- a/Tests/FakeFunctionTests.class.sql +++ b/Tests/FakeFunctionTests.class.sql @@ -609,6 +609,25 @@ BEGIN EXEC tSQLt.AssertEqualsTable '#Expected', '#Actual'; +END; +GO +CREATE PROCEDURE FakeFunctionTests.[test can fake with data source table that starts with select] +AS +BEGIN + DECLARE @Expected INT = 1; + DECLARE @Actual INT = 0; + + EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS TABLE AS RETURN (SELECT 777 AS a);'); + + CREATE TABLE SelectFakeFunctionTestsTable (a int); + INSERT INTO SelectFakeFunctionTestsTable VALUES (@Expected); + + EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', + @FakeDataSource = N'SelectFakeFunctionTestsTable'; + + SELECT @Actual = a FROM FakeFunctionTests.AFunction() + EXEC tSQLt.AssertEquals @Expected, @Actual; + END; GO CREATE PROCEDURE FakeFunctionTests.[test Private_PrepareFakeFunctionOutputTable returns table with VALUES] From b402d209044918f63e812202e6a80b49369bcfd2 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Sun, 25 Oct 2020 21:22:15 +0200 Subject: [PATCH 18/27] Using tSQLt.Private::CreateUniqueObjectName() to generate random object name --- ...ate_PrepareFakeFunctionOutputTable.ssp.sql | 2 +- ...eObjectsCompatibleWithFakeFunction.ssp.sql | 2 +- Tests/FakeFunctionTests.class.sql | 27 ------------------- 3 files changed, 2 insertions(+), 29 deletions(-) diff --git a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql index a8df84040..7d9ea04f0 100644 --- a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql +++ b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql @@ -11,7 +11,7 @@ AS DECLARE @SchemaName NVARCHAR(MAX); SET @SchemaName = COALESCE(PARSENAME(@FunctionName, 2), 'tSQlt'); SET @FunctionName = LEFT(PARSENAME(@FunctionName, 1), 100); - SET @OutputTable = CONCAT(QUOTENAME(@SchemaName), '.', QUOTENAME(CONCAT(@FunctionName, '_FakeFunctionOutputTable'))); + SET @OutputTable = tSQLt.Private::CreateUniqueObjectName(); IF ( LOWER(LTRIM(@FakeDataSource)) LIKE 'select%' AND OBJECT_ID(@FakeDataSource) IS NULL diff --git a/Source/tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction.ssp.sql b/Source/tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction.ssp.sql index 97f93f973..8fadc40ed 100644 --- a/Source/tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction.ssp.sql +++ b/Source/tSQLt.Private_ValidateObjectsCompatibleWithFakeFunction.ssp.sql @@ -36,7 +36,7 @@ BEGIN BEGIN RAISERROR('You can use @FakeDataSource only with Inline or Multi-Statement Table-Valued functions.', 16, 10); END - + RETURN 0; END diff --git a/Tests/FakeFunctionTests.class.sql b/Tests/FakeFunctionTests.class.sql index 585e8c2fb..d97592853 100644 --- a/Tests/FakeFunctionTests.class.sql +++ b/Tests/FakeFunctionTests.class.sql @@ -584,33 +584,6 @@ BEGIN EXEC tSQLt.AssertEqualsTable '#expected', '#actual'; END; GO -CREATE PROCEDURE FakeFunctionTests.[test can fake function with very long name] -AS -BEGIN - - DECLARE @maxFunctionName sysname, - @Cmd NVARCHAR(MAX); - SET @maxFunctionName = CONCAT('FakeFunctionTests.', REPLICATE('a', 128)); - - SET @Cmd = CONCAT('CREATE FUNCTION ', @maxFunctionName, '() RETURNS TABLE AS RETURN (SELECT 777 AS a);'); - EXEC(@Cmd); - - CREATE TABLE #Expected (a INT); - SELECT * INTO #Actual FROM #Expected; - - INSERT INTO #Expected VALUES (1); - - EXEC tSQLt.FakeFunction @FunctionName = @maxFunctionName, - @FakeDataSource = N'#Expected'; - - - SET @Cmd = CONCAT('INSERT INTO #Actual SELECT * FROM ', @maxFunctionName, '();'); - EXEC(@Cmd); - - EXEC tSQLt.AssertEqualsTable '#Expected', '#Actual'; - -END; -GO CREATE PROCEDURE FakeFunctionTests.[test can fake with data source table that starts with select] AS BEGIN From 1da509e8036c0cfa760b0200c27e9b54d0e2849b Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Sun, 25 Oct 2020 21:24:46 +0200 Subject: [PATCH 19/27] Remove `FunctionName` parameter --- Source/tSQLt.Private_CreateFakeFunction.ssp.sql | 2 +- Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Source/tSQLt.Private_CreateFakeFunction.ssp.sql b/Source/tSQLt.Private_CreateFakeFunction.ssp.sql index c9c34c5b7..f3470f881 100644 --- a/Source/tSQLt.Private_CreateFakeFunction.ssp.sql +++ b/Source/tSQLt.Private_CreateFakeFunction.ssp.sql @@ -48,7 +48,7 @@ BEGIN ELSE IF (@FakeDataSource IS NOT NULL) BEGIN DECLARE @newTbleName NVARCHAR(MAX); - EXEC tSQLt.Private_PrepareFakeFunctionOutputTable @FakeDataSource, @FunctionName, @newTbleName OUTPUT; + EXEC tSQLt.Private_PrepareFakeFunctionOutputTable @FakeDataSource, @newTbleName OUTPUT; EXEC ('CREATE FUNCTION '+@FunctionName+'('+@ParameterList+') RETURNS TABLE AS RETURN ( SELECT * FROM '+@newTbleName+');'); END ELSE diff --git a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql index 7d9ea04f0..8cd4d3bf5 100644 --- a/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql +++ b/Source/tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql @@ -4,13 +4,9 @@ GO ---Build+ CREATE PROCEDURE tSQLt.Private_PrepareFakeFunctionOutputTable @FakeDataSource NVARCHAR(MAX), - @FunctionName NVARCHAR(MAX), @OutputTable NVARCHAR(MAX) OUTPUT AS BEGIN - DECLARE @SchemaName NVARCHAR(MAX); - SET @SchemaName = COALESCE(PARSENAME(@FunctionName, 2), 'tSQlt'); - SET @FunctionName = LEFT(PARSENAME(@FunctionName, 1), 100); SET @OutputTable = tSQLt.Private::CreateUniqueObjectName(); IF ( LOWER(LTRIM(@FakeDataSource)) LIKE 'select%' From 12ab3e7b0d149962843623e6aa5d8c6b3a254574 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Sat, 7 Nov 2020 12:55:07 +0200 Subject: [PATCH 20/27] Change build order as CLR is used --- Source/BuildOrder.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/BuildOrder.txt b/Source/BuildOrder.txt index 9ba9fde5e..4d08d5ab4 100644 --- a/Source/BuildOrder.txt +++ b/Source/BuildOrder.txt @@ -11,7 +11,6 @@ tSQLt.Private_ResetNewTestClassList.ssp.sql tSQLt.Private_SysTypes.svw.sql tSQLt.Private_GetFullTypeName.sfn.sql tSQLt.Private_DisallowOverwritingNonTestSchema.ssp.sql -tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql tSQLt.Private_QuoteClassNameForNewTestClass.sfn.sql tSQLt.Private_MarkSchemaAsTestClass.ssp.sql tSQLt.NewTestClass.ssp.sql @@ -26,6 +25,7 @@ tSQLt.CaptureOutputLog.tbl.sql tSQLt.LogCapturedOutput.ssp.sql ../Build/temp/CreateAssembly.sql tSQLtCLR_CreateProcs.sql +tSQLt.Private_PrepareFakeFunctionOutputTable.ssp.sql tSQLt.TableToText.ssp.sql tSQLt.Private_RenamedObjectLog.tbl.sql tSQLt.Private_MarkObjectBeforeRename.ssp.sql From 182126de25c826d6cc551532872ddd81604461b9 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Sat, 7 Nov 2020 12:55:45 +0200 Subject: [PATCH 21/27] Fix fake functions test --- Tests/FakeFunctionTests.class.sql | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/Tests/FakeFunctionTests.class.sql b/Tests/FakeFunctionTests.class.sql index d97592853..a68babe9b 100644 --- a/Tests/FakeFunctionTests.class.sql +++ b/Tests/FakeFunctionTests.class.sql @@ -435,7 +435,7 @@ AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction(@a int, @b int) RETURNS TABLE AS RETURN (SELECT @a AS one);'); - EXEC tSQLt.ExpectException @ExpectedMessage = '@FakeFunctionName and @FakeDataSource are mutually exclisive, please use 1 param', @ExpectedSeverity = 16, @ExpectedState = 10; + EXEC tSQLt.ExpectException @ExpectedMessage = 'Both @FakeFunctionName and @FakeDataSource are valued. Please use only one.', @ExpectedSeverity = 16, @ExpectedState = 10; EXEC tSQLt.FakeFunction @FunctionName = 'FakeFunctionTests.AFunction', @FakeFunctionName = 'FakeFunctionTests.AFunction', @FakeDataSource = 'select 1 one'; END; @@ -445,7 +445,7 @@ AS BEGIN EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS NVARCHAR(10) AS BEGIN RETURN ''''; END;'); - EXEC tSQLt.ExpectException @ExpectedMessage = 'You can use @FakeDataSource only with Inline Table-Valued Function and Multi-Statement Table-Valued Function functions', + EXEC tSQLt.ExpectException @ExpectedMessage = 'You can use @FakeDataSource only with Inline or Multi-Statement Table-Valued functions.', @ExpectedSeverity = 16, @ExpectedState = 10; @@ -612,7 +612,7 @@ BEGIN CREATE TABLE #Expected (a int); INSERT INTO #Expected VALUES(1); - EXEC tSQLt.Private_PrepareFakeFunctionOutputTable '(VALUES (1)) a(a)', 'func', @NewTable OUTPUT; + EXEC tSQLt.Private_PrepareFakeFunctionOutputTable '(VALUES (1)) a(a)', @NewTable OUTPUT; EXEC tSQLt.AssertEqualsTable '#Expected', @NewTable; @@ -627,28 +627,9 @@ BEGIN CREATE TABLE #Expected (a int); INSERT INTO #Expected VALUES(1); - EXEC tSQLt.Private_PrepareFakeFunctionOutputTable 'SELECT 1 AS a','func', @NewTable OUTPUT; + EXEC tSQLt.Private_PrepareFakeFunctionOutputTable 'SELECT 1 AS a', @NewTable OUTPUT; EXEC tSQLt.AssertEqualsTable '#Expected', @NewTable; END; GO -CREATE PROCEDURE FakeFunctionTests.[test Private_PrepareFakeFunctionOutputTable output table in the same schema as function] -AS -BEGIN - DECLARE @Expected INT = 1; - DECLARE @Actual INT = 0; - DECLARE @NewTable sysname; - - EXEC('CREATE FUNCTION FakeFunctionTests.AFunction() RETURNS TABLE AS RETURN (SELECT 777 AS a);'); - - EXEC tSQLt.Private_PrepareFakeFunctionOutputTable 'SELECT 1 AS a', 'FakeFunctionTests.AFunction', @NewTable OUTPUT; - - SELECT @Actual = COUNT(*) - FROM sys.tables - WHERE name = 'AFunction_FakeFunctionOutputTable' AND schema_id = SCHEMA_ID('FakeFunctionTests'); - - EXEC tSQLt.AssertEquals @Expected, @Actual; - -END; -GO From cbc4d7e251187e9895c9091fd1e0270ef042dee6 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Sat, 7 Nov 2020 13:08:17 +0200 Subject: [PATCH 22/27] Add CLR function exception message test --- Tests/FakeFunctionTests.class.sql | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Tests/FakeFunctionTests.class.sql b/Tests/FakeFunctionTests.class.sql index a68babe9b..390d3eb6b 100644 --- a/Tests/FakeFunctionTests.class.sql +++ b/Tests/FakeFunctionTests.class.sql @@ -181,6 +181,15 @@ BEGIN EXEC FakeFunctionTests.[Assert errors on function type mismatch] 'FakeFunctionTests.[An SVF]', 'FakeFunctionTests.[A Table]'; END; GO +CREATE PROCEDURE FakeFunctionTests.[test errors when function is SVF, fake is CLRTVF and data source is used] +AS +BEGIN + EXEC tSQLt.ExpectException @ExpectedMessage = 'You can use @FakeDataSource only with Inline or Multi-Statement Table-Valued functions.', @ExpectedSeverity = 16, @ExpectedState = 10; + + EXEC tSQLt.FakeFunction @FunctionName = N'tSQLt_testutil.AClrTvf', + @FakeDataSource = N'(VALUES (1), (2)) a(one)' +END; +GO CREATE PROCEDURE FakeFunctionTests.[Assert TVF can be faked] @FunctionName NVARCHAR(MAX), @FakeFunctionName NVARCHAR(MAX) From 0a641301fb375f2908dc481b60613058fe64f84d Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Mon, 23 Nov 2020 22:00:07 +0200 Subject: [PATCH 23/27] Remove incorrectly added test --- Tests/FakeFunctionTests.class.sql | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Tests/FakeFunctionTests.class.sql b/Tests/FakeFunctionTests.class.sql index 27b5ef34f..cfa138b19 100644 --- a/Tests/FakeFunctionTests.class.sql +++ b/Tests/FakeFunctionTests.class.sql @@ -181,15 +181,6 @@ BEGIN EXEC FakeFunctionTests.[Assert errors on function type mismatch] 'FakeFunctionTests.[An SVF]', 'FakeFunctionTests.[A Table]'; END; GO -CREATE PROCEDURE FakeFunctionTests.[test errors when function is SVF, fake is CLRTVF and data source is used] -AS -BEGIN - EXEC tSQLt.ExpectException @ExpectedMessage = 'You can use @FakeDataSource only with Inline or Multi-Statement Table-Valued functions.', @ExpectedSeverity = 16, @ExpectedState = 10; - - EXEC tSQLt.FakeFunction @FunctionName = N'tSQLt_testutil.AClrTvf', - @FakeDataSource = N'(VALUES (1), (2)) a(one)' -END; -GO CREATE PROCEDURE FakeFunctionTests.[Assert TVF can be faked] @FunctionName NVARCHAR(MAX), @FakeFunctionName NVARCHAR(MAX) From ada374556a1026307e70bf9c135748d3ff77df36 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Mon, 23 Nov 2020 22:03:18 +0200 Subject: [PATCH 24/27] Add new lines at the end of the files --- Build/GrantUserAccessToRemoteDatabase.sql | 2 +- Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql | 2 +- ...Lt.Private_ValidateSynonymCompatibilityWithFakeTable.ssp.sql | 1 - TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Build/GrantUserAccessToRemoteDatabase.sql b/Build/GrantUserAccessToRemoteDatabase.sql index 99aabfa37..7272a066c 100644 --- a/Build/GrantUserAccessToRemoteDatabase.sql +++ b/Build/GrantUserAccessToRemoteDatabase.sql @@ -4,4 +4,4 @@ IF EXISTS ( SELECT 1 BEGIN EXEC dbo.sp_changedbowner @loginame = N'tSQLt.Build'; - END; \ No newline at end of file + END; diff --git a/Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql b/Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql index 3f966576e..54ae020e5 100644 --- a/Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql +++ b/Source/tSQLt.Private_AlterSysObjectForRemote.ssp.sql @@ -46,4 +46,4 @@ AS RETURN 0; END; ---Build- -GO \ No newline at end of file +GO diff --git a/Source/tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable.ssp.sql b/Source/tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable.ssp.sql index aaaf34bb4..84aa26d6b 100644 --- a/Source/tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable.ssp.sql +++ b/Source/tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable.ssp.sql @@ -21,4 +21,3 @@ AS END; END; GO - \ No newline at end of file diff --git a/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql b/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql index 40388ef28..0924da894 100644 --- a/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql +++ b/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql @@ -120,4 +120,4 @@ CREATE TABLE MyTestClass.tbli(i MyTestClass.UDTi) GO USE $(NewDbName) -GO \ No newline at end of file +GO From 9c2494c8c9a1432bac580c99033ee46132ba9492 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Sun, 3 Oct 2021 20:53:42 +0300 Subject: [PATCH 25/27] Post merge fixes --- Build/LocalValidateBuild.bat | 2 +- Build/tSQLt.validatebuild.xml | 2 +- Source/BuildOrder.txt | 4 +--- Source/tSQLt.Private_CreateFakeOfTable.ssp.sql | 3 --- Source/tSQLt.Private_CreateFakeTableStatement.sfn.sql | 2 +- 5 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Build/LocalValidateBuild.bat b/Build/LocalValidateBuild.bat index 8d466536c..e9197b778 100644 --- a/Build/LocalValidateBuild.bat +++ b/Build/LocalValidateBuild.bat @@ -34,7 +34,7 @@ ECHO LogTableName: %LogTableName% IF "%VerboseOutput%"=="ON" @ECHO ON @REM -----------------------------------------------------------------------------This space character is utterly important! ----v -CALL "ant" -buildfile Build\tSQLt.validatebuild.xml -Ddb.server="%SQLInstanceName%" -Ddb.name=%DBName% -Ddb.login=" %DBLogin%" -Dsqlcmd.path="%SQLCMDPath%" -Dsqlpackage.path="%SQLPackagePath%" -Dlogtable.name="%LogTableName%" || goto :error +CALL "C:\ProgramData\chocolatey\lib\ant\tools\apache-ant-1.10.10\bin\ant" -buildfile Build\tSQLt.validatebuild.xml -Ddb.server="%SQLInstanceName%" -Ddb.name=%DBName% -Ddb.login=" %DBLogin%" -Dsqlcmd.path="%SQLCMDPath%" -Dsqlpackage.path="%SQLPackagePath%" -Dlogtable.name="%LogTableName%" || goto :error @ECHO OFF ECHO +----------------------------------+ diff --git a/Build/tSQLt.validatebuild.xml b/Build/tSQLt.validatebuild.xml index 9957bcc11..2258a414c 100644 --- a/Build/tSQLt.validatebuild.xml +++ b/Build/tSQLt.validatebuild.xml @@ -578,7 +578,7 @@ - + diff --git a/Source/BuildOrder.txt b/Source/BuildOrder.txt index f55da79cd..4f01f1cba 100644 --- a/Source/BuildOrder.txt +++ b/Source/BuildOrder.txt @@ -16,18 +16,16 @@ tSQLt.InstallAssemblyKey.ssp.sql tSQLt.PrepareServer.ssp.sql tSQLt.Private_NewTestClassList.tbl.sql tSQLt.Private_ResetNewTestClassList.ssp.sql -tSQLt.Private_SysTypes.svw.sql tSQLt.Private_SysColumns.svw.sql tSQLt.Private_SysComputedColumns.svw.sql tSQLt.Private_SysDefaultConstraints.svw.sql tSQLt.Private_SysIdentityColumns.svw.sql tSQLt.Private_SysObjects.svw.sql tSQLt.Private_SysSchemas.svw.sql -tSQLt.Private_GetFullTypeName.sfn.sql tSQLt.Private_DisallowOverwritingNonTestSchema.ssp.sql +tSQLt.Private_AlterSysObjectForRemote.ssp.sql tSQLt.Private_CreateRemoteSysObjects.ssp.sql tSQLt.Private_GetRemoteObjectId.ssp.sql -tSQLt.Private_AlterSysObjectForRemote.ssp.sql tSQLt.Private_QuoteClassNameForNewTestClass.sfn.sql tSQLt.Private_MarkSchemaAsTestClass.ssp.sql tSQLt.Private_ValidateSynonymCompatibilityWithFakeTable.ssp.sql diff --git a/Source/tSQLt.Private_CreateFakeOfTable.ssp.sql b/Source/tSQLt.Private_CreateFakeOfTable.ssp.sql index 133ff2cf0..410e34a2f 100644 --- a/Source/tSQLt.Private_CreateFakeOfTable.ssp.sql +++ b/Source/tSQLt.Private_CreateFakeOfTable.ssp.sql @@ -11,9 +11,6 @@ CREATE PROCEDURE tSQLt.Private_CreateFakeOfTable @RemoteObjectID INT AS BEGIN - DECLARE @Cmd NVARCHAR(MAX); - DECLARE @Cols NVARCHAR(MAX); - IF (@RemoteObjectID IS NOT NULL) BEGIN EXEC tSQLt.Private_CreateRemoteUserDefinedDataTypes @RemoteObjectID = @RemoteObjectID diff --git a/Source/tSQLt.Private_CreateFakeTableStatement.sfn.sql b/Source/tSQLt.Private_CreateFakeTableStatement.sfn.sql index 7e3d17c58..7212ea713 100644 --- a/Source/tSQLt.Private_CreateFakeTableStatement.sfn.sql +++ b/Source/tSQLt.Private_CreateFakeTableStatement.sfn.sql @@ -30,7 +30,7 @@ RETURN THEN '' ELSE CASE WHEN @PreserveNOTNULL = 1 AND c.is_nullable = 0 THEN ' NOT NULL' ELSE ' NULL' END END - FROM sys.columns c + FROM tSQLt.Private_SysColumns c CROSS APPLY tSQLt.Private_GetDataTypeOrComputedColumnDefinition(c.user_type_id, c.max_length, c.precision, c.scale, c.collation_name, c.object_id, c.column_id, @ComputedColumns) cc CROSS APPLY tSQLt.Private_GetDefaultConstraintDefinition(c.object_id, c.column_id, @Defaults) AS dc CROSS APPLY tSQLt.Private_GetIdentityDefinition(c.object_id, c.column_id, @Identity) AS id From 000a3e42f80a8493010c4d8c6ef734124b55c079 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Sun, 10 Oct 2021 17:14:43 +0300 Subject: [PATCH 26/27] Using common approach to create "remote" database with `temp_prepare_server.sql` --- Build/Build.ssmssqlproj | 6 - Build/GrantUserAccessToRemoteDatabase.sql | 7 - Build/tSQLt.build.xml | 3 +- Build/tSQLt.remote.class.sql | 27 +++ Build/tSQLt.validatebuild.xml | 26 ++- TestUtil/BuildOrder.txt | 3 +- .../tSQLt_RemoteSynonymsTestDatabase.db.sql | 123 ----------- Tests/FakeTableTests.class.sql | 208 +++++++++--------- 8 files changed, 153 insertions(+), 250 deletions(-) delete mode 100644 Build/GrantUserAccessToRemoteDatabase.sql create mode 100644 Build/tSQLt.remote.class.sql delete mode 100644 TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql diff --git a/Build/Build.ssmssqlproj b/Build/Build.ssmssqlproj index 1770b5242..2d00006a1 100644 --- a/Build/Build.ssmssqlproj +++ b/Build/Build.ssmssqlproj @@ -84,12 +84,6 @@ GrantBuildPermissions.sql - - 8c91a03d-f9b4-46c0-a305-b5dcc79ff907:Dev_tSQLt:True - Dev_tSQLt - - GrantUserAccessToRemoteDatabase.sql - diff --git a/Build/GrantUserAccessToRemoteDatabase.sql b/Build/GrantUserAccessToRemoteDatabase.sql deleted file mode 100644 index 7272a066c..000000000 --- a/Build/GrantUserAccessToRemoteDatabase.sql +++ /dev/null @@ -1,7 +0,0 @@ -IF EXISTS ( SELECT 1 - FROM sys.databases - WHERE name = 'tSQLt_RemoteSynonymsTestDatabase' ) - BEGIN - - EXEC dbo.sp_changedbowner @loginame = N'tSQLt.Build'; - END; diff --git a/Build/tSQLt.build.xml b/Build/tSQLt.build.xml index 327f3a636..ac0c8e917 100644 --- a/Build/tSQLt.build.xml +++ b/Build/tSQLt.build.xml @@ -420,10 +420,10 @@ - + @@ -444,7 +444,6 @@ - diff --git a/Build/tSQLt.remote.class.sql b/Build/tSQLt.remote.class.sql new file mode 100644 index 000000000..a5755ba3d --- /dev/null +++ b/Build/tSQLt.remote.class.sql @@ -0,0 +1,27 @@ +---Build+ +CREATE TABLE dbo.TestTable + ( + c1 INT NULL , + c2 BIGINT NULL , + c3 VARCHAR(MAX) NULL + ); +GO +CREATE VIEW dbo.TestView +AS + SELECT * + FROM dbo.TestTable;; +GO +CREATE PROCEDURE dbo.NotATable +AS + RETURN; +GO +CREATE SCHEMA TestSchema; +GO +CREATE TYPE TestSchema.UDT FROM NVARCHAR(20); +GO +CREATE TABLE TestSchema.tbl(i TestSchema.UDT) +GO +CREATE TYPE TestSchema.UDTi FROM INT; +GO +CREATE TABLE TestSchema.tbli(i TestSchema.UDTi) +GO diff --git a/Build/tSQLt.validatebuild.xml b/Build/tSQLt.validatebuild.xml index 2258a414c..2c1d3cd1a 100644 --- a/Build/tSQLt.validatebuild.xml +++ b/Build/tSQLt.validatebuild.xml @@ -23,6 +23,7 @@ + @@ -32,6 +33,7 @@ + @@ -50,6 +52,7 @@ + @@ -65,6 +68,7 @@ + @@ -75,6 +79,7 @@ + @@ -129,6 +134,7 @@ + @@ -140,6 +146,7 @@ + @@ -500,6 +507,19 @@ + + + + + + + + + + + + + @@ -578,12 +598,6 @@ - - - - - - diff --git a/TestUtil/BuildOrder.txt b/TestUtil/BuildOrder.txt index 698ccd22b..0a483ed88 100644 --- a/TestUtil/BuildOrder.txt +++ b/TestUtil/BuildOrder.txt @@ -1,5 +1,4 @@ tSQLt_testutil.class.sql ../Build/temp/tSQLtBuild/Tests/CreateTestUtilAssembly.sql ../Build/temp/tSQLtBuild/Tests/GetUnsignedEmptyBytes.sql -tSQLtTestUtilCLR_CreateItems.sql -tSQLt_RemoteSynonymsTestDatabase.db.sql \ No newline at end of file +tSQLtTestUtilCLR_CreateItems.sql \ No newline at end of file diff --git a/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql b/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql deleted file mode 100644 index 0924da894..000000000 --- a/TestUtil/tSQLt_RemoteSynonymsTestDatabase.db.sql +++ /dev/null @@ -1,123 +0,0 @@ -IF NOT EXISTS ( SELECT * - FROM sys.databases - WHERE name = 'tSQLt_RemoteSynonymsTestDatabase' ) - BEGIN - CREATE DATABASE tSQLt_RemoteSynonymsTestDatabase; - END; -GO -USE tSQLt_RemoteSynonymsTestDatabase -GO - -IF EXISTS ( SELECT * - FROM sys.tables t - JOIN sys.schemas s ON s.schema_id = t.schema_id - WHERE t.name = 'tbl' - AND s.name = 'MyTestClass' ) - BEGIN - DROP TABLE MyTestClass.tbl; - END; -GO - -IF EXISTS ( SELECT * - FROM sys.tables t - JOIN sys.schemas s ON s.schema_id = t.schema_id - WHERE t.name = 'tbli' - AND s.name = 'MyTestClass' ) - BEGIN - DROP TABLE MyTestClass.tbli; - END; -GO - -IF EXISTS ( SELECT * - FROM sys.types t - JOIN sys.schemas s ON s.schema_id = t.schema_id - WHERE t.name = 'UDT' - AND s.name = 'MyTestClass' ) - BEGIN - DROP TYPE MyTestClass.UDT; - END; -GO - -IF EXISTS ( SELECT * - FROM sys.types t - JOIN sys.schemas s ON s.schema_id = t.schema_id - WHERE t.name = 'UDTi' - AND s.name = 'MyTestClass' ) - BEGIN - DROP TYPE MyTestClass.UDTi; - END; -GO - -IF EXISTS ( SELECT * - FROM sys.schemas - WHERE name = 'MyTestClass' ) - BEGIN - DROP SCHEMA MyTestClass; - END; -GO - -IF EXISTS ( SELECT * - FROM sys.objects o - JOIN sys.schemas s ON s.schema_id = o.schema_id - WHERE o.name = 'TestView' - AND s.name = 'dbo' ) - BEGIN - DROP VIEW dbo.TestView; - END; - - -IF EXISTS ( SELECT * - FROM sys.tables t - JOIN sys.schemas s ON s.schema_id = t.schema_id - WHERE t.name = 'TestTable' - AND s.name = 'dbo' ) - BEGIN - DROP TABLE dbo.TestTable; - END; -GO - -IF EXISTS ( SELECT * - FROM sys.objects o - JOIN sys.schemas s ON s.schema_id = o.schema_id - WHERE o.name = 'NotATable' - AND s.name = 'dbo' ) - BEGIN - DROP PROCEDURE dbo.NotATable; - END; -GO - -CREATE TABLE dbo.TestTable - ( - c1 INT NULL , - c2 BIGINT NULL , - c3 VARCHAR(MAX) NULL - ); -GO -CREATE VIEW dbo.TestView -AS - SELECT * - FROM dbo.TestTable;; -GO - -CREATE PROCEDURE dbo.NotATable -AS - RETURN; -GO - -CREATE SCHEMA MyTestClass; -GO - -CREATE TYPE MyTestClass.UDT FROM NVARCHAR(20); -GO - -CREATE TABLE MyTestClass.tbl(i MyTestClass.UDT) -GO - -CREATE TYPE MyTestClass.UDTi FROM INT; -GO - -CREATE TABLE MyTestClass.tbli(i MyTestClass.UDTi) -GO - -USE $(NewDbName) -GO diff --git a/Tests/FakeTableTests.class.sql b/Tests/FakeTableTests.class.sql index 95577b633..e624dc483 100644 --- a/Tests/FakeTableTests.class.sql +++ b/Tests/FakeTableTests.class.sql @@ -174,8 +174,8 @@ GO CREATE PROC FakeTableTests.[test FakeTable works with remote 2 part names in first parameter] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT); - CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + CREATE TABLE tSQLt_dev_remote.dbo.TempTable1(i INT); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_dev_remote.dbo.TempTable1; EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; @@ -198,8 +198,8 @@ GO CREATE PROC FakeTableTests.[test a faked remote table has no check constraints] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT CHECK(i > 5)); - CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + CREATE TABLE tSQLt_dev_remote.dbo.TempTable1(i INT CHECK(i > 5)); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_dev_remote.dbo.TempTable1; EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; @@ -224,11 +224,11 @@ GO CREATE PROC FakeTableTests.[test a faked remote table has no foreign keys] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable0(i INT PRIMARY KEY); - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT REFERENCES tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable0(i)); + CREATE TABLE tSQLt_dev_remote.dbo.TempTable0(i INT PRIMARY KEY); + CREATE TABLE tSQLt_dev_remote.dbo.TempTable1(i INT REFERENCES tSQLt_dev_remote.dbo.TempTable0(i)); - CREATE SYNONYM FakeTableTests.TempTable0 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable0; - CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + CREATE SYNONYM FakeTableTests.TempTable0 FOR tSQLt_dev_remote.dbo.TempTable0; + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_dev_remote.dbo.TempTable1; EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; @@ -258,8 +258,8 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable: a faked table has any defaults removed] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT DEFAULT(77)); - CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + CREATE TABLE tSQLt_dev_remote.dbo.TempTable1(i INT DEFAULT(77)); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_dev_remote.dbo.TempTable1; EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; @@ -290,8 +290,8 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable: a faked table has any unique constraints removed] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT UNIQUE); - CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + CREATE TABLE tSQLt_dev_remote.dbo.TempTable1(i INT UNIQUE); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_dev_remote.dbo.TempTable1; EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; @@ -318,9 +318,9 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable: a faked table has any unique indexes removed] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT); - CREATE UNIQUE INDEX UQ_tSQLt_test_TempTable1_i ON tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i); - CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + CREATE TABLE tSQLt_dev_remote.dbo.TempTable1(i INT); + CREATE UNIQUE INDEX UQ_tSQLt_test_TempTable1_i ON tSQLt_dev_remote.dbo.TempTable1(i); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_dev_remote.dbo.TempTable1; EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; @@ -345,8 +345,8 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable: a faked table has any not null constraints removed] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1(i INT NOT NULL); - CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + CREATE TABLE tSQLt_dev_remote.dbo.TempTable1(i INT NOT NULL); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_dev_remote.dbo.TempTable1; EXEC tSQLt.FakeTable 'FakeTableTests.TempTable1'; @@ -380,10 +380,10 @@ CREATE PROC FakeTableTests.[test remote FakeTable works on referencedTo tables] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(i INT PRIMARY KEY); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1(i INT PRIMARY KEY); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst2(i INT PRIMARY KEY, tst1i INT REFERENCES tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(i)); + CREATE TABLE tSQLt_dev_remote.dbo.tst2(i INT PRIMARY KEY, tst1i INT REFERENCES tSQLt_dev_remote.dbo.tst1(i)); BEGIN TRY EXEC tSQLt.FakeTable 'FakeTableTests.tst1'; @@ -421,8 +421,8 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable doesn't produce output] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst(i INT); - CREATE SYNONYM FakeTableTests.tst FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst; + CREATE TABLE tSQLt_dev_remote.dbo.tst(i INT); + CREATE SYNONYM FakeTableTests.tst FOR tSQLt_dev_remote.dbo.tst; EXEC tSQLt.CaptureOutput 'EXEC tSQLt.FakeTable ''FakeTableTests.tst'''; @@ -460,8 +460,8 @@ CREATE PROC FakeTableTests.[test remote FakeTable doesn't preserve identity if @ AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(i INT IDENTITY(1,1)); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1(i INT IDENTITY(1,1)); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC tSQLt.FakeTable 'FakeTableTests.tst1'; @@ -490,8 +490,8 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable doesn't preserve identity if @identity parameter is 0] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(i INT IDENTITY(1,1)); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1(i INT IDENTITY(1,1)); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC tSQLt.FakeTable 'FakeTableTests.tst1',@Identity=0; @@ -520,8 +520,8 @@ CREATE PROC FakeTableTests.[test remote FakeTable preserves identity if @identit AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 ( i INT IDENTITY(1, 1) ); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1 ( i INT IDENTITY(1, 1) ); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC tSQLt.FakeTable 'FakeTableTests.tst1', @Identity = 1; @@ -588,8 +588,8 @@ CREATE PROC FakeTableTests.[test remote FakeTable works with more than one colum AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(i1 INT,i2 INT,i3 INT,i4 INT,i5 INT,i6 INT,i7 INT,i8 INT); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1(i1 INT,i2 INT,i3 INT,i4 INT,i5 INT,i6 INT,i7 INT,i8 INT); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; CREATE TABLE #Actual (column_id INT, [name] NVARCHAR(500)); CREATE TABLE #Expected (column_id INT, [name] NVARCHAR(500)); @@ -597,9 +597,9 @@ BEGIN INSERT INTO #Expected SELECT column_id , c.name - FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns c - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables t ON t.object_id = c.object_id - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas s ON s.schema_id = t.schema_id + FROM tSQLt_dev_remote.sys.columns c + JOIN tSQLt_dev_remote.sys.tables t ON t.object_id = c.object_id + JOIN tSQLt_dev_remote.sys.schemas s ON s.schema_id = t.schema_id WHERE t.name = 'tst1' AND s.name = 'dbo'; @@ -642,8 +642,8 @@ CREATE PROC FakeTableTests.[test remote FakeTable works with ugly column and tab AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.[tst!@#$%^&*()_+ 1]([col!@#$%^&*()_+ 1] INT); - CREATE SYNONYM FakeTableTests.[tst!@#$%^&*()_+ 1] FOR tSQLt_RemoteSynonymsTestDatabase.dbo.[tst!@#$%^&*()_+ 1]; + CREATE TABLE tSQLt_dev_remote.dbo.[tst!@#$%^&*()_+ 1]([col!@#$%^&*()_+ 1] INT); + CREATE SYNONYM FakeTableTests.[tst!@#$%^&*()_+ 1] FOR tSQLt_dev_remote.dbo.[tst!@#$%^&*()_+ 1]; CREATE TABLE #Actual (column_id INT, [name] NVARCHAR(500)); CREATE TABLE #Expected (column_id INT, [name] NVARCHAR(500)); @@ -651,9 +651,9 @@ BEGIN INSERT INTO #Expected SELECT column_id , c.name - FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns c - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables t ON t.object_id = c.object_id - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas s ON s.schema_id = t.schema_id + FROM tSQLt_dev_remote.sys.columns c + JOIN tSQLt_dev_remote.sys.tables t ON t.object_id = c.object_id + JOIN tSQLt_dev_remote.sys.schemas s ON s.schema_id = t.schema_id WHERE t.name = 'tst!@#$%^&*()_+ 1' AND s.name = 'dbo'; @@ -695,8 +695,8 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable preserves identity base and step-size] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (i INT IDENTITY(42,13)); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1 (i INT IDENTITY(42,13)); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; INSERT INTO FakeTableTests.tst1 DEFAULT VALUES; INSERT INTO FakeTableTests.tst1 DEFAULT VALUES; @@ -742,18 +742,18 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable preserves data type of identity column with @Identity=0] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 ( i INT ); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1 ( i INT ); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; CREATE TABLE #Expected(type_name NVARCHAR(500)); CREATE TABLE #Actual (type_name NVARCHAR(500)); INSERT INTO #Expected SELECT tp.name type_name - FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns c - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.types tp ON tp.user_type_id = c.user_type_id - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables t ON t.object_id = c.object_id - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas s ON s.schema_id = t.schema_id + FROM tSQLt_dev_remote.sys.columns c + JOIN tSQLt_dev_remote.sys.types tp ON tp.user_type_id = c.user_type_id + JOIN tSQLt_dev_remote.sys.tables t ON t.object_id = c.object_id + JOIN tSQLt_dev_remote.sys.schemas s ON s.schema_id = t.schema_id WHERE t.name = 'tst1' AND s.name = 'dbo'; @@ -796,18 +796,18 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable preserves data type of identity column with @Identity=1] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 ( i [DECIMAL](4) IDENTITY(1,1) ); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1 ( i [DECIMAL](4) IDENTITY(1,1) ); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; CREATE TABLE #Expected(type_name NVARCHAR(500), max_length INT, precision INT, scale INT); CREATE TABLE #Actual(type_name NVARCHAR(500), max_length INT, precision INT, scale INT); INSERT INTO #Expected SELECT tp.name type_name, c.max_length, c.precision, c.scale - FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns c - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.types tp ON tp.user_type_id = c.user_type_id - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables t ON t.object_id = c.object_id - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas s ON s.schema_id = t.schema_id + FROM tSQLt_dev_remote.sys.columns c + JOIN tSQLt_dev_remote.sys.types tp ON tp.user_type_id = c.user_type_id + JOIN tSQLt_dev_remote.sys.tables t ON t.object_id = c.object_id + JOIN tSQLt_dev_remote.sys.schemas s ON s.schema_id = t.schema_id WHERE t.name = 'tst1' AND s.name = 'dbo'; @@ -852,7 +852,7 @@ CREATE PROC FakeTableTests.[test remote FakeTable works if IDENTITYCOL is not th AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(x INT, i INT IDENTITY(1,1), y VARCHAR(30)); + CREATE TABLE tSQLt_dev_remote.dbo.tst1(x INT, i INT IDENTITY(1,1), y VARCHAR(30)); CREATE TABLE #Actual ( name VARCHAR(500) , @@ -865,12 +865,12 @@ BEGIN ); INSERT INTO #Expected SELECT c.name, is_identity - FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns c - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables t ON t.object_id = c.object_id - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas s ON s.schema_id = t.schema_id + FROM tSQLt_dev_remote.sys.columns c + JOIN tSQLt_dev_remote.sys.tables t ON t.object_id = c.object_id + JOIN tSQLt_dev_remote.sys.schemas s ON s.schema_id = t.schema_id WHERE t.name = 'tst1' AND s.name = 'dbo'; - CREATE SYNONYM dbo.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE SYNONYM dbo.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC tSQLt.FakeTable 'dbo.tst1',@Identity = 1; @@ -912,8 +912,8 @@ CREATE PROC FakeTableTests.[test remote FakeTable works if there is no IDENTITYC AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1(x INT, y VARCHAR(30)); - CREATE SYNONYM dbo.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1(x INT, y VARCHAR(30)); + CREATE SYNONYM dbo.tst1 FOR tSQLt_dev_remote.dbo.tst1; CREATE TABLE #Actual ( @@ -927,9 +927,9 @@ BEGIN ); INSERT INTO #Expected SELECT c.name, is_identity - FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns c - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables t ON t.object_id = c.object_id - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas s ON s.schema_id = t.schema_id + FROM tSQLt_dev_remote.sys.columns c + JOIN tSQLt_dev_remote.sys.tables t ON t.object_id = c.object_id + JOIN tSQLt_dev_remote.sys.schemas s ON s.schema_id = t.schema_id WHERE t.name = 'tst1' AND s.name = 'dbo'; EXEC tSQLt.FakeTable 'dbo.tst1',@Identity = 1; @@ -1026,8 +1026,8 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable preserves computed columns if @ComputedColumns = 1] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT, y AS x + 5 PERSISTED); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1 (x INT, y AS x + 5 PERSISTED); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForComputedCols 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @ComputedColumns = 1;'; END; @@ -1047,8 +1047,8 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable preserves persisted computed columns if @ComputedColumns = 1] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT, y AS x + 5 PERSISTED); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1 (x INT, y AS x + 5 PERSISTED); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForComputedCols 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @ComputedColumns = 1;'; END; @@ -1068,8 +1068,8 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable does not preserve persisted computed columns if @ComputedColumns = 0] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT, y AS x + 5 PERSISTED); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1 (x INT, y AS x + 5 PERSISTED); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC FakeTableTests.AssertTableAfterCommandHasNoComputedCols 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @ComputedColumns = 0;'; END; @@ -1089,8 +1089,8 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable does not preserve persisted computed columns if @ComputedColumns is not specified] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT, y AS x + 5 PERSISTED); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1 (x INT, y AS x + 5 PERSISTED); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC FakeTableTests.AssertTableAfterCommandHasNoComputedCols 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'';'; END; @@ -1110,8 +1110,8 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable preserves multiple mixed persisted computed columns if @ComputedColumns = 1] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (NotComputed INT, ComputedAndPersisted AS (NotComputed + 5) PERSISTED, ComputedNotPersisted AS (NotComputed + 7), AnotherComputed AS (GETDATE())); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE TABLE tSQLt_dev_remote.dbo.tst1 (NotComputed INT, ComputedAndPersisted AS (NotComputed + 5) PERSISTED, ComputedNotPersisted AS (NotComputed + 7), AnotherComputed AS (GETDATE())); + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForComputedCols 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @ComputedColumns = 1;'; END; @@ -1200,9 +1200,9 @@ GO CREATE PROC FakeTableTests.[test remoteFakeTable does not preserve defaults if @Defaults is not specified] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT DEFAULT(5)); + CREATE TABLE tSQLt_dev_remote.dbo.tst1 (x INT DEFAULT(5)); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC FakeTableTests.AssertTableAfterCommandHasNoDefaults 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'''; END; @@ -1222,9 +1222,9 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable does not preserve defaults if @Defaults = 0] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT DEFAULT(5)); + CREATE TABLE tSQLt_dev_remote.dbo.tst1 (x INT DEFAULT(5)); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC FakeTableTests.AssertTableAfterCommandHasNoDefaults 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @Defaults = 0;'; END; @@ -1244,9 +1244,9 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable preserves defaults if @Defaults = 1] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x INT DEFAULT(5)); + CREATE TABLE tSQLt_dev_remote.dbo.tst1 (x INT DEFAULT(5)); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForDefaults 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @Defaults = 1;'; END; @@ -1269,10 +1269,10 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable preserves defaults if @Defaults = 1 when multiple columns exist on table] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 ( ColWithNoDefault CHAR(3), + CREATE TABLE tSQLt_dev_remote.dbo.tst1 ( ColWithNoDefault CHAR(3), ColWithDefault DATETIME DEFAULT(GETDATE())); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForDefaults 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @Defaults = 1;'; END; @@ -1296,11 +1296,11 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable preserves defaults if @Defaults = 1 when multiple varied columns exist on table] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 ( ColWithNoDefault CHAR(3), + CREATE TABLE tSQLt_dev_remote.dbo.tst1 ( ColWithNoDefault CHAR(3), ColWithDefault DATETIME DEFAULT(GETDATE()), ColWithDiffDefault INT DEFAULT(-3)); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; EXEC FakeTableTests.AssertTableStructureBeforeAndAfterCommandIsSameForDefaults 'FakeTableTests.tst1', 'EXEC tSQLt.FakeTable ''FakeTableTests.tst1'', @Defaults = 1;'; END; @@ -1334,18 +1334,18 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable preserves the collation of a column] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.tst1 (x VARCHAR(30) COLLATE Latin1_General_BIN, + CREATE TABLE tSQLt_dev_remote.dbo.tst1 (x VARCHAR(30) COLLATE Latin1_General_BIN, y VARCHAR(40)); - CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.tst1; + CREATE SYNONYM FakeTableTests.tst1 FOR tSQLt_dev_remote.dbo.tst1; CREATE TABLE #Expected (name NVARCHAR(MAX), collation_name NVARCHAR(MAX)); CREATE TABLE #Actual (name NVARCHAR(MAX), collation_name NVARCHAR(MAX)); INSERT INTO #Expected SELECT C.name ,C.collation_name - FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns AS C - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables AS t ON t.object_id = C.object_id - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas AS s ON s.schema_id = t.schema_id + FROM tSQLt_dev_remote.sys.columns AS C + JOIN tSQLt_dev_remote.sys.tables AS t ON t.object_id = C.object_id + JOIN tSQLt_dev_remote.sys.schemas AS s ON s.schema_id = t.schema_id WHERE t.name = 'tst1' AND s.name = 'dbo'; @@ -1517,17 +1517,17 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable preserves UDTd] AS BEGIN - CREATE SYNONYM dbo.tbl FOR tSQLt_RemoteSynonymsTestDatabase.MyTestClass.tbli; + CREATE SYNONYM dbo.tbl FOR tSQLt_dev_remote.TestSchema.tbli; CREATE TABLE #Expected (name NVARCHAR(255), system_type_id INT, max_length INT, precision INT, scale INT, is_nullable BIT); CREATE TABLE #Actual (name NVARCHAR(255), system_type_id INT, max_length INT, precision INT, scale INT, is_nullable BIT); INSERT INTO #Expected SELECT C.name ,C.system_type_id,C.max_length,C.precision,C.scale,C.is_nullable - FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns AS C - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables AS t ON t.object_id = C.object_id - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas AS s ON s.schema_id = t.schema_id - WHERE t.name = 'tbli' AND s.name = 'MyTestClass'; + FROM tSQLt_dev_remote.sys.columns AS C + JOIN tSQLt_dev_remote.sys.tables AS t ON t.object_id = C.object_id + JOIN tSQLt_dev_remote.sys.schemas AS s ON s.schema_id = t.schema_id + WHERE t.name = 'tbli' AND s.name = 'TestSchema'; EXEC tSQLt.FakeTable @TableName = 'dbo.tbl'; @@ -1565,17 +1565,17 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable preserves UDTd based on char type] AS BEGIN - CREATE SYNONYM dbo.tbl FOR tSQLt_RemoteSynonymsTestDatabase.MyTestClass.tbl; + CREATE SYNONYM dbo.tbl FOR tSQLt_dev_remote.TestSchema.tbl; CREATE TABLE #Expected (name NVARCHAR(255), system_type_id INT, max_length INT, precision INT, scale INT, is_nullable BIT); CREATE TABLE #Actual (name NVARCHAR(255), system_type_id INT, max_length INT, precision INT, scale INT, is_nullable BIT); INSERT INTO #Expected SELECT C.name ,C.system_type_id,C.max_length,C.precision,C.scale,C.is_nullable - FROM tSQLt_RemoteSynonymsTestDatabase.sys.columns AS C - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.tables AS t ON t.object_id = C.object_id - JOIN tSQLt_RemoteSynonymsTestDatabase.sys.schemas AS s ON s.schema_id = t.schema_id - WHERE t.name = 'tbl' AND s.name = 'MyTestClass'; + FROM tSQLt_dev_remote.sys.columns AS C + JOIN tSQLt_dev_remote.sys.tables AS t ON t.object_id = C.object_id + JOIN tSQLt_dev_remote.sys.schemas AS s ON s.schema_id = t.schema_id + WHERE t.name = 'tbl' AND s.name = 'TestSchema'; EXEC tSQLt.FakeTable @TableName = 'dbo.tbl'; @@ -1615,9 +1615,9 @@ GO CREATE PROC FakeTableTests.[test raises appropriate error if synonym is remote but not of a table] AS BEGIN - CREATE SYNONYM FakeTableTests.TempSynonym1 FOR tSQLt_RemoteSynonymsTestDatabase.FakeTableTests.NotATable; + CREATE SYNONYM FakeTableTests.TempSynonym1 FOR tSQLt_dev_remote.FakeTableTests.NotATable; - EXEC tSQLt.ExpectException @ExpectedMessage = 'Cannot fake synonym [FakeTableTests].[TempSynonym1] as it is pointing to [tSQLt_RemoteSynonymsTestDatabase].[FakeTableTests].[NotATable], which is not a table or view!'; + EXEC tSQLt.ExpectException @ExpectedMessage = 'Cannot fake synonym [FakeTableTests].[TempSynonym1] as it is pointing to [tSQLt_dev_remote].[FakeTableTests].[NotATable], which is not a table or view!'; EXEC tSQLt.FakeTable 'FakeTableTests.TempSynonym1'; END; @@ -1639,9 +1639,9 @@ CREATE PROC FakeTableTests.[test can fake view to remote table] AS BEGIN - SELECT TOP(0) * INTO #actual FROM tSQLt_RemoteSynonymsTestDatabase.dbo.TestTable; + SELECT TOP(0) * INTO #actual FROM tSQLt_dev_remote.dbo.TestTable; - EXEC('CREATE VIEW FakeTableTests.TempView1 AS SELECT * FROM tSQLt_RemoteSynonymsTestDatabase.dbo.TestTable;'); + EXEC('CREATE VIEW FakeTableTests.TempView1 AS SELECT * FROM tSQLt_dev_remote.dbo.TestTable;'); EXEC tSQLt.FakeTable 'FakeTableTests.TempView1'; @@ -1666,7 +1666,7 @@ CREATE PROC FakeTableTests.[test can fake remote synonym of view] AS BEGIN - CREATE SYNONYM FakeTableTests.TempSynonym1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TestView; + CREATE SYNONYM FakeTableTests.TempSynonym1 FOR tSQLt_dev_remote.dbo.TestView; EXEC tSQLt.FakeTable 'FakeTableTests.TempSynonym1'; @@ -1709,8 +1709,8 @@ GO CREATE PROC FakeTableTests.[test remote FakeTable works with two parameters, if they are quoted] AS BEGIN - CREATE TABLE tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1 ( i INT NOT NULL ); - CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_RemoteSynonymsTestDatabase.dbo.TempTable1; + CREATE TABLE tSQLt_dev_remote.dbo.TempTable1 ( i INT NOT NULL ); + CREATE SYNONYM FakeTableTests.TempTable1 FOR tSQLt_dev_remote.dbo.TempTable1; EXEC tSQLt.FakeTable '[FakeTableTests]','[TempTable1]'; From b26c871531eb9bbfb5b643e24129fa7a9d2ff232 Mon Sep 17 00:00:00 2001 From: Dmitrij Kultasev Date: Sun, 10 Oct 2021 20:16:20 +0300 Subject: [PATCH 27/27] Revert incorrectly modified file --- Build/LocalValidateBuild.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build/LocalValidateBuild.bat b/Build/LocalValidateBuild.bat index e9197b778..8d466536c 100644 --- a/Build/LocalValidateBuild.bat +++ b/Build/LocalValidateBuild.bat @@ -34,7 +34,7 @@ ECHO LogTableName: %LogTableName% IF "%VerboseOutput%"=="ON" @ECHO ON @REM -----------------------------------------------------------------------------This space character is utterly important! ----v -CALL "C:\ProgramData\chocolatey\lib\ant\tools\apache-ant-1.10.10\bin\ant" -buildfile Build\tSQLt.validatebuild.xml -Ddb.server="%SQLInstanceName%" -Ddb.name=%DBName% -Ddb.login=" %DBLogin%" -Dsqlcmd.path="%SQLCMDPath%" -Dsqlpackage.path="%SQLPackagePath%" -Dlogtable.name="%LogTableName%" || goto :error +CALL "ant" -buildfile Build\tSQLt.validatebuild.xml -Ddb.server="%SQLInstanceName%" -Ddb.name=%DBName% -Ddb.login=" %DBLogin%" -Dsqlcmd.path="%SQLCMDPath%" -Dsqlpackage.path="%SQLPackagePath%" -Dlogtable.name="%LogTableName%" || goto :error @ECHO OFF ECHO +----------------------------------+