-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
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.