When starting the data API builder, it goes out to a couple system tables (sys.columns and information_schema.columns) to check for read-only fields. The following syntax is employed by the app:
SELECT ifsc.column_name
from sys.columns as sc
INNER JOIN information_schema.columns as ifsc ON ( sc.is_computed = 1 or ifsc.data_type = 'timestamp' )
AND sc.object_id = object_id(@param1+'.'+@param2)
and ifsc.table_name = @param1
AND ifsc.table_schema = @param2
and ifsc.column_name = sc.name;
This works fine for the out-of-the-box database collation. But when the database is set to a case sensitive collation, the query fails with 'invalid object' error. Below is the same query, with the correct case for the field names, so it should work with both case-sensitive and case-insensitive collations:
SELECT ifsc.COLUMN_NAME
from sys.columns as sc
INNER JOIN INFORMATION_SCHEMA.COLUMNS as ifsc ON ( sc.is_computed = 1 or ifsc.DATA_TYPE = 'timestamp' )
AND sc.object_id = object_id(@param1+'.'+@param2)
AND ifsc.TABLE_NAME = @param1
AND ifsc.TABLE_SCHEMA = @param2
AND ifsc.COLUMN_NAME = sc.name;
Wanted to create a bug report before attempting to create branches myself. I suspect that MSSQL queries further in the app may have a similar issue since there's no test for this.
Version
0.9.7+e560142426d1c080b9fd7b7fabff51a276f6bf61
What database are you using?
Azure SQL
What hosting model are you using?
Local (including CLI)
Which API approach are you accessing DAB through?
REST
Relevant log output
dab start --config "C:\Users\sample_user\dab-config.json"
Information: Microsoft.DataApiBuilder 0.9.7+e560142426d1c080b9fd7b7fabff51a276f6bf61
Information: Generating default config file: C:\Users\sample_user\dab-config.json
Information: Config file generated.
Information: SUGGESTION: Use 'dab add [entity-name] [options]' to add new entities in your config.
Information: Microsoft.DataApiBuilder 0.9.7+e560142426d1c080b9fd7b7fabff51a276f6bf61
Information: User provided config file: C:\Users\sample_user\dab-config.json
Loading config file from C:\Users\sample_user\dab-config.json.
Information: Added new entity: DUAL with source: dbo.DUAL and permissions: anonymous:*.
Information: SUGGESTION: Use 'dab update [entity-name] [options]' to update any entities in your config.
Information: Microsoft.DataApiBuilder 0.9.7+e560142426d1c080b9fd7b7fabff51a276f6bf61
Information: User provided config file: C:\Users\sample_user\dab-config.json
Loading config file from C:\Users\sample_user\dab-config.json.
Information: Loaded config file: C:\Users\sample_user\dab-config.json
Information: Setting default minimum LogLevel: Debug for Development mode.
Starting the runtime engine...
Loading config file from C:\Users\sample_user\dab-config.json.
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[63]
User profile is available. Using 'C:\Users\sample_user\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
info: Azure.DataApiBuilder.Core.Services.ISqlMetadataProvider[0]
[DUAL] REST path: /api/DUAL
dbug: Azure.DataApiBuilder.Core.Resolvers.IQueryExecutor[0]
Executing query: SELECT STE.type_desc FROM sys.triggers ST inner join sys.trigger_events STE On ST.object_id = STE.object_id AND ST.parent_id = object_id(@param0 + '.' + @param1) WHERE ST.is_disable
d = 0;
dbug: Azure.DataApiBuilder.Core.Resolvers.IQueryExecutor[0]
Executing query: SELECT ifsc.column_name from sys.columns as sc INNER JOIN information_schema.columns as ifsc ON (sc.is_computed = 1 or ifsc.data_type = 'timestamp') AND sc.object_id = object_id(@pa
ram0+'.'+@param1) and ifsc.table_name = @param1 AND ifsc.table_schema = @param0 and ifsc.column_name = sc.name;
fail: Azure.DataApiBuilder.Core.Resolvers.IQueryExecutor[0]
Query execution error due to:
Invalid object name 'information_schema.columns'.
Microsoft.Data.SqlClient.SqlException (0x80131904): Invalid object name 'information_schema.columns'.
at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__209_0(Task`1 result)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
at Azure.DataApiBuilder.Core.Resolvers.QueryExecutor`1.ExecuteQueryAgainstDbAsync[TResult](TConnection conn, String sqltext, IDictionary`2 parameters, Func`3 dataReaderHandler, HttpContext httpCon
text, List`1 args)
ClientConnectionId:3f9f4563-3a15-449a-a262-0a8838217224
Error Number:208,State:1,Class:16
fail: Azure.DataApiBuilder.Service.Startup[0]
Unable to complete runtime initialization. Refer to exception for error details.
Azure.DataApiBuilder.Service.Exceptions.DataApiBuilderException: Invalid object name 'information_schema.columns'.
---> Microsoft.Data.SqlClient.SqlException (0x80131904): Invalid object name 'information_schema.columns'.
at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__209_0(Task`1 result)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
at Azure.DataApiBuilder.Core.Resolvers.QueryExecutor`1.ExecuteQueryAgainstDbAsync[TResult](TConnection conn, String sqltext, IDictionary`2 parameters, Func`3 dataReaderHandler, HttpContext httpCon
text, List`1 args)
ClientConnectionId:3f9f4563-3a15-449a-a262-0a8838217224
Error Number:208,State:1,Class:16
--- End of inner exception stack trace ---
at Azure.DataApiBuilder.Core.Resolvers.QueryExecutor`1.ExecuteQueryAgainstDbAsync[TResult](TConnection conn, String sqltext, IDictionary`2 parameters, Func`3 dataReaderHandler, HttpContext httpCon
text, List`1 args)
at Azure.DataApiBuilder.Core.Resolvers.QueryExecutor`1.<>c__DisplayClass19_0`1.<<ExecuteQueryAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Polly.Retry.AsyncRetryEngine.ImplementationAsync[TResult](Func`3 action, Context context, CancellationToken cancellationToken, ExceptionPredicates shouldRetryExceptionPredicates, ResultPredicat
es`1 shouldRetryResultPredicates, Func`5 onRetryAsync, Int32 permittedRetryCount, IEnumerable`1 sleepDurationsEnumerable, Func`4 sleepDurationProvider, Boolean continueOnCapturedContext)
at Polly.AsyncPolicy.ExecuteAsync[TResult](Func`3 action, Context context, CancellationToken cancellationToken, Boolean continueOnCapturedContext)
at Azure.DataApiBuilder.Core.Resolvers.QueryExecutor`1.ExecuteQueryAsync[TResult](String sqltext, IDictionary`2 parameters, Func`3 dataReaderHandler, HttpContext httpContext, List`1 args, String d
ataSourceName)
at Azure.DataApiBuilder.Core.Services.SqlMetadataProvider`3.PopulateColumnDefinitionsWithReadOnlyFlag(String tableName, String schemaOrDatabaseName, SourceDefinition sourceDefinition)
at Azure.DataApiBuilder.Core.Services.SqlMetadataProvider`3.PopulateSourceDefinitionAsync(String entityName, String schemaName, String tableName, SourceDefinition sourceDefinition, String[] runtim
eConfigKeyFields)
at Azure.DataApiBuilder.Core.Services.SqlMetadataProvider`3.PopulateObjectDefinitionForEntities()
at Azure.DataApiBuilder.Core.Services.SqlMetadataProvider`3.InitializeAsync()
at Azure.DataApiBuilder.Service.Startup.PerformOnConfigChangeAsync(IApplicationBuilder app)
fail: Azure.DataApiBuilder.Service.Startup[0]
Could not initialize the engine with the runtime config file: C:\Users\sample_user\dab-config.json
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
dab : Unable to launch the Data API builder engine.
At line:9 char:1
+ dab start --config "C:\Users\sample_user\dab-config.json"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Unable to launc...builder engine.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Error: Failed to start the engine.
Code of Conduct
[X] I agree to follow this project's Code of Conduct
What happened?
A bug happened!
When starting the data API builder, it goes out to a couple system tables (sys.columns and information_schema.columns) to check for read-only fields. The following syntax is employed by the app:
This works fine for the out-of-the-box database collation. But when the database is set to a case sensitive collation, the query fails with 'invalid object' error. Below is the same query, with the correct case for the field names, so it should work with both case-sensitive and case-insensitive collations:
Wanted to create a bug report before attempting to create branches myself. I suspect that MSSQL queries further in the app may have a similar issue since there's no test for this.
Version
0.9.7+e560142426d1c080b9fd7b7fabff51a276f6bf61
What database are you using?
Azure SQL
What hosting model are you using?
Local (including CLI)
Which API approach are you accessing DAB through?
REST
Relevant log output
Code of Conduct