Skip to content

sqlserver Introspection Fails With "No such table: information_schema.columns" Based on Case Sensitive Database Collation #4333

@dcapotos

Description

@dcapotos

When running the introspect for sqlserver using the preview feature microsoftSqlServer
I receive the following error for one of my database, but not another:

  Error: Error in connector: Error querying the database: Error querying the database: No such table: information_schema.columns

This table does exist on the database but under the name INFORMATION_SCHEMA.COLUMNS in uppercase.

I believe this is directly related to the database collation.

  • SQL_Latin1_General_CP1_CS_AS (case sensitive - does not work)
  • SQL_Latin1_General_CP1_CI_AS (case insensitive - works)
    Both of these databases in question are on the same SQL server.

When running the following in SQL Server Management studio for the case sensitive database:
SELECT * FROM case_sensitive_db.information_schema.columns

It results in the error:

  Msg 208, Level 16, State 1, Line 1
  Invalid object name 'amslivedb.information_schema.columns'.

This query does work if converted to upper case:
SELECT * FROM case_sensitive_db.INFORMATION_SCHEMA.COLUMNS

(Either query works fine in the case insensitive database as expected.)

Based on the documentation from Microsoft, it appears that this table name should be in all UPPER CASE.
https://docs.microsoft.com/en-us/sql/relational-databases/system-information-schema-views/system-information-schema-views-transact-sql?view=sql-server-ver15

It looks like the queries the engine is using for mssql may need be converted to upper case in some areas to be compatible with databases with case sensitive collation.

Here is one of them that I believe is resulting in the error:
libs/sql-schema-describer/src/mssql.rs

            SELECT 
                column_name,
                data_type,
                character_maximum_length,
                column_default,
                is_nullable,
                columnproperty(object_id(@P1 + '.' + table_name), column_name, 'IsIdentity') is_identity,
                table_name,
                numeric_precision,
                numeric_scale
            FROM information_schema.columns c
            INNER JOIN sys.tables t
            ON c.TABLE_NAME = t.name AND SCHEMA_ID(c.TABLE_SCHEMA) = t.schema_id
            WHERE table_schema = @P1
            AND t.is_ms_shipped = 'false'
            ORDER BY ordinal_position

I tried rewriting this query and this appears to work (I replaced @p1 with 'dbo' during my testing)

            SELECT
		COLUMN_NAME,
                DATA_TYPE,
                CHARACTER_MAXIMUM_LENGTH,
		COLUMN_DEFAULT,
		IS_NULLABLE,
                COLUMNPROPERTY(OBJECT_ID(@P1 + '.' + TABLE_NAME), COLUMN_NAME, 'IsIdentity') is_identity,
		TABLE_NAME,
                NUMERIC_PRECISION,
		NUMERIC_SCALE
            FROM INFORMATION_SCHEMA.COLUMNS c
            INNER JOIN sys.tables t
            ON c.TABLE_NAME = t.name AND SCHEMA_ID(c.TABLE_SCHEMA) = t.schema_id
            WHERE TABLE_SCHEMA = @P1
            AND t.is_ms_shipped = 'false'
            ORDER BY ORDINAL_POSITION

There might be other locations that need to be addressed.
This should be easy to reproduce to find other cases that need correction by setting up a database with SQL_Latin1_General_CP1_CS_AS collation.

Metadata

Metadata

Assignees

Labels

bug/1-unconfirmedBug should have enough information for reproduction, but confirmation has not happened yet.kind/bugA reported bug.topic: introspectiontopic: sql serverMicrosoft SQL Server

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions