MarkMpn / Sql4Cds

SQL 4 CDS core engine and XrmToolbox tool
MIT License
74 stars 22 forks source link

Object reference not set to an instance of an object in 9.3.0 #564

Closed sybaris closed 1 week ago

sybaris commented 1 week ago

Hi,

Upgrading from 9.1.0 to 9.3.0 nuget package, I have the following error :

Exception message: Object reference not set to an instance of an object.
Exception type: MarkMpn.Sql4Cds.Engine.Sql4CdsException
Source: MarkMpn.Sql4Cds.Engine
TargetSite: Boolean Execute(System.Collections.Generic.Dictionary`2[System.String,Microsoft.SqlServer.TransactSql.ScriptDom.DataTypeReference], System.Collections.Generic.Dictionary`2[System.String,System.Data.SqlTypes.INullable])
CallStack:
at MarkMpn.Sql4Cds.Engine.Sql4CdsDataReader.Execute(Dictionary`2 parameterTypes, Dictionary`2 parameterValues)
at MarkMpn.Sql4Cds.Engine.Sql4CdsDataReader.ExecuteWithExceptionHandling(Dictionary`2 parameterTypes, Dictionary`2 parameterValues)
at MarkMpn.Sql4Cds.Engine.Sql4CdsDataReader.NextResult()
at MarkMpn.Sql4Cds.Engine.Sql4CdsDataReader..ctor(Sql4CdsCommand command, IQueryExecutionOptions options, CommandBehavior behavior)
at MarkMpn.Sql4Cds.Engine.Sql4CdsCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
...
Inner(0)Exception Exception message: Object reference not set to an instance of an object.
Inner(0)Exception Exception type: System.NullReferenceException
Inner(0)Exception Source: MarkMpn.Sql4Cds.Engine
Inner(0)Exception TargetSite: Double EstimateFilterRate(Microsoft.Xrm.Sdk.Metadata.EntityMetadata, MarkMpn.Sql4Cds.Engine.FetchXml.filter, MarkMpn.Sql4Cds.Engine.ExecutionPlan.ITableSizeCache, Boolean ByRef)
Inner(0)Exception CallStack:
at MarkMpn.Sql4Cds.Engine.ExecutionPlan.FetchXmlScan.EstimateFilterRate(EntityMetadata metadata, filter filter, ITableSizeCache tableSize, Boolean& singleRow)
at MarkMpn.Sql4Cds.Engine.ExecutionPlan.FetchXmlScan.EstimateRowsOut(String name, Object[] items, IDictionary`2 dataSources, Double multiplier)
at MarkMpn.Sql4Cds.Engine.ExecutionPlan.FetchXmlScan.EstimateRowsOutInternal(NodeCompilationContext context)
at MarkMpn.Sql4Cds.Engine.ExecutionPlan.BaseDataNode.EstimateRowsOut(NodeCompilationContext context)
at MarkMpn.Sql4Cds.Engine.ExecutionPlan.DistinctNode.FoldQuery(NodeCompilationContext context, IList`1 hints)
at MarkMpn.Sql4Cds.Engine.ExecutionPlan.SelectNode.FoldQuery(NodeCompilationContext context, IList`1 hints)
at MarkMpn.Sql4Cds.Engine.ExecutionPlanOptimizer.Optimize(IRootExecutionPlanNodeInternal node, IList`1 hints)
at MarkMpn.Sql4Cds.Engine.ExecutionPlanBuilder.ConvertStatementInternal(TSqlStatement statement, ExecutionPlanOptimizer optimizer)
at MarkMpn.Sql4Cds.Engine.ExecutionPlan.UnparsedStatementNode.Compile()
at MarkMpn.Sql4Cds.Engine.Sql4CdsDataReader.Execute(Dictionary`2 parameterTypes, Dictionary`2 parameterValues)

And it was when I try in my C# code to execute the following query :


            SELECT DISTINCT SC.objectid, SC.componenttype
            FROM solutioncomponent SC
            JOIN solution S ON S.solutionid = SC.solutionid
            WHERE S.uniquename = 'Active'
                  and SC.componenttype != 1 and SC.componenttype != 201 -- Ignore Entity and SDK Message

Regards Sybaris

MarkMpn commented 1 week ago

I can't reproduce this error. Can you share the code you use to set up the connection please?

sybaris commented 1 week ago

Hi,

Here source code to reproduce.

Downgrade to 9.1.0 version, and you will see that there is no more error.

Issue564.zip

Regards Sybaris

MarkMpn commented 1 week ago

I get the same error with 9.1.0 as well. The error is due to the metadata of the faked componenttype attribute not having any options - SQL 4 CDS assumes that an EnumAttributeMetadata will have its OptionSet property populated. In this case FakeXrmEasy hasn't populated that property, so SQL 4 CDS can't work out how many different values it could have when it tries to estimate how selective the filter on the componenttype field is.

To resolve this issue you would need to ensure the OptionSet property on all EnumAttributeMetadatas is set correctly.