Recently stumbled across the following problem: changing metadata changes query output.
Here is how to get it.
CREATE TABLE [dbo].[prod]
(
[ID] [tinyint] NOT NULL,
[values] [tinyint] NOT NULL
)
GO
The following query always returns ‘This is the end’ (error always raised). Also the filter should be some sort of a random generator.
BEGIN TRY
SELECT [id] FROM
(
SELECT [id] as [id]
FROM dbo.prod
WHERE ([id]=1/0)
) t1
WHERE
-- Random generator 1 always returns false
(FLOOR(RAND()*(1))=1)
-- Random generator 2 does not always return false
/*
SUBSTRING( cast(NEWID() as varchar(max)), 1, 1)
IN ('1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F')
*/
-- Random generator 3 does not always return false
/*
SUBSTRING(cast(cast( DATEPART(MILLISECOND,GETDATE()) as char(3)) as varchar(3)), 2, 1)
IN ('1', '2', '3', '4', '5', '6', '7', '8', '9', '0')
*/
END TRY
BEGIN CATCH
SELECT 'This is the end'
END CATCH;
Now add primary key constraint. Note: no data changes.
ALTER TABLE dbo.prod
ADD CONSTRAINT PK_1 PRIMARY KEY NONCLUSTERED(id);
And now the same query
BEGIN TRY
SELECT [id] FROM
(
SELECT [id] as [id]
FROM dbo.prod
WHERE ([id]=1/0)
) t1
WHERE
(FLOOR(RAND()*(1))=1)
END TRY
BEGIN CATCH
SELECT 'This is the end'
END CATCH;
never returns an error.
It is understandable that changing metadata may change execution plan but it was unexpected that it changes query’s output. Is this behaviour correct?