Timestamp columns and InvalidOperationException - linq-to-sql

I've recently added a timestamp column to a table in a linq-to-sql DBML file. It caused an InvalidOperationException when the entire web service loaded (no queries were even run).
The exception is:
[InvalidOperationException: System.Data.Linq.Binary cannot be serialized because it does not have a parameterless constructor.]
[InvalidOperationException: Cannot serialize member 'server.DBHandlers.TableName.RowStamp' of type 'System.Data.Linq.Binary', see inner exception for more details.]
System.Xml.Serialization.StructModel.CheckSupportedMember(TypeDesc typeDesc, MemberInfo member, Type type) +1549853
System.Xml.Serialization.StructModel.GetPropertyModel(PropertyInfo propertyInfo) +189
System.Xml.Serialization.StructModel.GetFieldModel(MemberInfo memberInfo) +146
System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter) +1237
System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter) +631
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) +1719
What's the cause? How can it be fixed?
Posting the entire stack trace as per leppie's request:
[InvalidOperationException: System.Data.Linq.Binary cannot be serialized because it does not have a parameterless constructor.]
[InvalidOperationException: Cannot serialize member 'server.DBHandlers.TableName.RowStamp' of type 'System.Data.Linq.Binary', see inner exception for more details.]
System.Xml.Serialization.StructModel.CheckSupportedMember(TypeDesc typeDesc, MemberInfo member, Type type) +1549853
System.Xml.Serialization.StructModel.GetPropertyModel(PropertyInfo propertyInfo) +189
System.Xml.Serialization.StructModel.GetFieldModel(MemberInfo memberInfo) +146
System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter) +1237
System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter) +631
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) +1719
[InvalidOperationException: There was an error reflecting type 'server.DBHandlers.TableName'.]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) +1516787
System.Xml.Serialization.XmlReflectionImporter.CreateArrayElementsFromAttributes(ArrayMapping arrayMapping, XmlArrayItemAttributes attributes, Type arrayElementType, String arrayElementNs, RecursionLimiter limiter) +412
System.Xml.Serialization.XmlReflectionImporter.ImportArrayLikeMapping(ArrayModel model, String ns, RecursionLimiter limiter) +337
System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +6535
System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter) +210
System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter) +1295
[InvalidOperationException: There was an error reflecting property 'TableName'.]
System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter) +3631
System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter) +631
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) +1719
[InvalidOperationException: There was an error reflecting type 'server.DBHandlers.RelatedTableName'.]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) +1516787
System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +9555
System.Xml.Serialization.XmlReflectionImporter.ImportMemberMapping(XmlReflectionMember xmlReflectionMember, String ns, XmlReflectionMember[] xmlReflectionMembers, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +963
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +418
[InvalidOperationException: There was an error reflecting 'getRelatedTable'.]
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +1504534
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(String elementName, String ns, XmlReflectionMember[] members, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, XmlMappingAccess access) +195
System.Web.Services.Protocols.SoapReflector.ImportMembersMapping(XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, Boolean serviceDefaultIsEncoded, Boolean rpc, SoapBindingUse use, SoapParameterStyle paramStyle, String elementName, String elementNamespace, Boolean nsIsDefault, XmlReflectionMember[] members, Boolean validate, Boolean openModel, String key, Boolean writeAccess) +388
System.Web.Services.Protocols.SoapReflector.ReflectMethod(LogicalMethodInfo methodInfo, Boolean client, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, String defaultNs) +3366
[InvalidOperationException: Method ServiceName.getRelatedTable can not be reflected.]
System.Web.Services.Protocols.SoapReflector.ReflectMethod(LogicalMethodInfo methodInfo, Boolean client, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, String defaultNs) +841901
System.Web.Services.Description.SoapProtocolReflector.ReflectMethod() +142
System.Web.Services.Description.ProtocolReflector.ReflectBinding(ReflectedBinding reflectedBinding) +1610
System.Web.Services.Description.ProtocolReflector.Reflect() +710
System.Web.Services.Description.ServiceDescriptionReflector.ReflectInternal(ProtocolReflector[] reflectors) +565
System.Web.Services.Description.ServiceDescriptionReflector.Reflect(Type type, String url) +153
System.Web.Services.Protocols.DocumentationServerType..ctor(Type type, String uri) +203
System.Web.Services.Protocols.DocumentationServerProtocol.Initialize() +388
System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response) +75
System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) +143
[InvalidOperationException: Unable to handle request.]
System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) +458731
System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +285
[InvalidOperationException: Failed to handle request.]
System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +401482
System.Web.Services.Protocols.WebServiceHandlerFactory.GetHandler(HttpContext context, String verb, String url, String filePath) +281
System.Web.Script.Services.ScriptHandlerFactory.GetHandler(HttpContext context, String requestType, String url, String pathTranslated) +89
System.Web.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +425
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +263

Or change timestamp's type to Byte[]. More [info]:http://geekswithblogs.net/frankw/archive/2008/08/29/serialization-issue-with-timestamp-in-linq-to-sql.aspx

It can be fixed by changing the ReadOnly property on the timestamp column, in the DBML, to true.

Related

The deserialization constructor on type 'FSI_0080+{..}' may not have more than 64 parameters for deserialization

I am using the library FsHttp to create REST API calls with F#.
I got one API call with returns (potentially) large amount of data. I created records for the JSON responses. In this case the record contains 65 entries.
type Event = {
policyName: string option
hash: string
publisher: string
eventType: string
sourceType: string
... 60 more paramters
}
With this response I encounter the error:
System.AggregateException: One or more errors occurred. (The deserialization constructor on type 'FSI_0080+Event' may not have more than 64 parameters for deserialization. Path: $.events[0] | LineNumber: 0 | BytePositionInLine: 2087.)
---> System.NotSupportedException: The deserialization constructor on type 'FSI_0080+Event' may not have more than 64 parameters for deserialization. Path: $.events[0] |
LineNumber: 0 | BytePositionInLine: 2087.
---> System.NotSupportedException: The deserialization constructor on type 'FSI_0080+Event' may not have more than 64 parameters for deserialization.
at System.Text.Json.ThrowHelper.ThrowNotSupportedException_ConstructorMaxOf64Parameters(Type type)
at System.Text.Json.Serialization.Converters.LargeObjectWithParameterizedConstructorConverter`1.CreateObject(ReadStackFrame& frame)
at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.Converters.SmallObjectWithParameterizedConstructorConverter`5.TryRead[TArg](ReadStack& state, Utf8JsonReader& reader, JsonParameterInfo jsonParameterInfo, TArg& arg)
at System.Text.Json.Serialization.Converters.SmallObjectWithParameterizedConstructorConverter`5.ReadAndCacheConstructorArgument(ReadStack& state, Utf8JsonReader& reader, JsonParameterInfo jsonParameterInfo)
at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.ReadConstructorArgumentsWithContinuation(ReadStack& state, Utf8JsonReader& reader, JsonSerializerOptions options)
at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
--- End of inner exception stack trace ---
at System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack& state, Utf8JsonReader& reader, NotSupportedException ex)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadCore[TValue](JsonConverter jsonConverter, Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadCore[TValue](JsonReaderState& readerState, Boolean isFinalBlock, ReadOnlySpan`1 buffer, JsonSerializerOptions options, ReadStack& state, JsonConverter converterBase)
at System.Text.Json.JsonSerializer.ContinueDeserialize[TValue](ReadBufferState& bufferState, JsonReaderState& jsonReaderState, ReadStack& readStack, JsonConverter converter, JsonSerializerOptions options)
at System.Text.Json.JsonSerializer.ReadAllAsync[TValue](Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at Microsoft.FSharp.Control.AsyncResult`1.Commit() in D:\a\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 394
at Microsoft.FSharp.Control.AsyncPrimitives.QueueAsyncAndWaitForResultSynchronously[a](CancellationToken token, FSharpAsync`1 computation, FSharpOption`1 timeout) in D:\a\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 1045
at Microsoft.FSharp.Control.AsyncPrimitives.RunSynchronously[T](CancellationToken cancellationToken, FSharpAsync`1 computation, FSharpOption`1 timeout) in D:\a\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 1071
at Microsoft.FSharp.Control.FSharpAsync.RunSynchronously[T](FSharpAsync`1 computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken)
at <StartupCode$FSI_0087>.$FSI_0087.main#() in C:\Users\Alex_P\Documents\PowerShell\stdin:line 606
Stopped due to error
Does JSON deserialization have a limit on parameters?
How to go around this limitation?
This is a known issue in System.Text.Json. It looks like they plan to raise or eliminate the limit. It's not a limit on JSON deserialization in general.
To get around it for now, I think you might have to refactor your type into smaller pieces, or switch to a different JSON library.

How to get ssrs tablix limit

I've a report where I've added an column (no matter if it's populated or not).
When I try to upload report I get error
An error has occurred. Try again later
My tablix has 78 column (I need to add 6 more column). There is a limit of tablix column?
Any idea what the issue may be?
This is log message:
Microsoft.ReportingServices.Portal.WebHost!reportserverwebapp!7b!12/22/2020-16:55:38:: e ERROR: [c0y2u4py]: OData exception occurred: System.Resources.MissingManifestResourceException: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "Microsoft.SqlServer.ReportingServices.SoapExceptionStrings.resources" was correctly embedded or linked into assembly "Microsoft.ReportingServices.Portal.Services" at compile time, or that all the satellite assemblies required are loadable and fully signed. at System.Resources.ManifestBasedResourceGroveler.HandleResourceStreamMissing(String fileName) at System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo culture, Dictionary 2 localResourceSets, Boolean tryParents, Boolean createIfNotExists, StackCrawlMark& stackMark)
at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark)
at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
at Microsoft.SqlServer.ReportingServices.SoapExceptionStrings.Keys.GetString(String key)
at Microsoft.SqlServer.ReportingServices.SoapExceptionStrings.get_MissingEndpoint()
at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.MissingEndpointException..ctor(Exception inner)
at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.SoapMethodWrapper`1.ExecuteMethod(Boolean setConnectionProtocol)
at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.SoapMethodWrapper`1.ExecuteMethod()
at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.CreateCatalogItem(String itemType, String name, String parent, Boolean overwrite, Byte[] definition, Property[] properties, Warning[]& warnings)
at Microsoft.ReportingServices.Portal.Services.SoapProxy.SoapRS2010Proxy.<>c__DisplayClass1.<CreateCatalogItem>b__0()
at Microsoft.ReportingServices.Portal.Services.SoapProxy.SoapAuthenticationHelper.ExecuteWithWindowsAuth[TReturn](SoapHttpClientProtocol soapClient, IPrincipal userPrincipal, Func'1 func)
at Microsoft.ReportingServices.Portal.Services.SoapProxy.SoapAuthenticationHelper.ExecuteWithCorrespondingAuthMechanism[TReturn](SoapHttpClientProtocol soapClient, IPrincipal userPrincipal, Func`1 func)
at Microsoft.ReportingServices.Portal.Services.SoapProxy.SoapRS2010Proxy.CreateCatalogItem(IPrincipal userPrincipal, String itemType, String name, String parentFolder, Boolean overwrite, Byte[] definition, Property[] properties)
at Microsoft.ReportingServices.Portal.Repositories.CatalogItemRepository.CreateReport(IPrincipal userPrincipal, String reportName, String parentFolder, Boolean overwrite, Byte[] definition, Property[] properties)
at Microsoft.ReportingServices.Portal.Repositories.CatalogItemRepository.Create(IPrincipal userPrincipal, CatalogItem catalogItem, CatalogItem& createdItem)
at Microsoft.ReportingServices.Portal.ODataWebApi.V1.Controllers.CatalogItemsController.AddEntity(CatalogItem entity, CatalogItem& createdEntity)
at Microsoft.ReportingServices.Portal.ODataWebApi.V1.Controllers.Reflection.EntitySetReflectionODataController`1.Post(ODataPath oDataPath, T value)
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext().
Microsoft.ReportingServices.Portal.WebHost!reportserverwebapp!e3!12/22/2020-16:55:38:: i INFO: [c0y2u4py]: 10.81.234.123: POST /api/v1.0/catalogitems - Response 500 - 0:00:11,4747865
Thanks for the help.

How to include an Excel formula with a reference to a table in Invantive Control Excel add-in

I'm making a financial report in Excel using the data from Exact Online using the Invantive Control Excel Add-in. In Exact Online I have a classification for the General Ledgers. In my Excel file, I would like to match these classifications on my reporting schedule. Therefore, I made a table with a mapping of the Exact Online classifications and the reporting classifications.
Using the Invantive Control Excel add-in, I entered the following SQL query:
select periods_year_reportingyear_attr
, reportingperiod_attr
, division_code
, division_hid
, division_name
, periods_year_years_balance_code_attr
, periods_year_years_balance_description
, '=I_EOL_GL_ACTCLN_CODE($C{E,.,.,^+2,.}, $C{E,.,.,^+5,.})' verdichting_code
, '=I_EOL_GL_ACTCLN_DESCRIPTION($C{E,.,.,^+2,.}, $C{E,.,.,^+5,.})' verdichting_naam
, '=i_eol_bal_year_open($C{E,.,.,^+2,.} , $C{E,.,.,^,.}, $C{E,.,.,^+5,.}) + if($C{E,.,.,^+1,.} = 1, 0, i_eol_bal_pder($C{E,.,.,^+2,.},$C{E,.,.,^,.},1,$C{E,.,.,^+1,.}-1,$C{E,.,.,^+5,.}))' startsaldo
, balance
, '=i_eol_bal_year_open($C{E,.,.,^+2,.} , $C{E,.,.,^,.}, $C{E,.,.,^+5,.}) + i_eol_bal_pder($C{E,.,.,^+2,.},$C{E,.,.,^,.},1,$C{E,.,.,^+1,.},$C{E,.,.,^+5,.})' eindsaldo
, periods_year_years_balance_balancetype_attr
from balancelinesperperiod
order
by periods_year_reportingyear_attr
, reportingperiod_attr
, division_hid
, periods_year_years_balance_code_attr
, '=INDEX(tab_reporting[Reporting];MATCH(NUMBERVALUE($C{E,.,.,^+7,.});tab_reporting[GL Class - Code];0))'
In which tab_reporting is the name of a table with de mapping of the reporting classifications and the Exact Online. This table is on a different tab within Excel. I could send the Excel file upon request.
This last line of the query results in the following error message:
Syntax error between the two '*' on line 20, column 7:select periods_year_re...ance_code_attr, *'=INDEX(tab_reporting[Reporting];MATCH(NUMBERVALUE($C{E,.,.,^+7,.});tab_reporting[GLClass - Code];0))'*** Error: no viable alternative at input '=INDEX(tab_reporting[Reporting];MATCH(NUMBERVALUE($C{E,.,.,^+7,.});tab_reporting[GLClass - Code];0))''
and in more detail:
itgensql056: Syntax error between the two '***' on line 20, column 7:select periods_year_re...ance_code_attr<LF>, ***'=INDEX(tab_reporting[Reporting];MATCH(NUMBERVALUE($C{E,.,.,^+7,.});tab_reporting[GL Class - Code];0))'***Error: no viable alternative at input ''=INDEX(tab_reporting[Reporting];MATCH(NUMBERVALUE($C{E,.,.,^+7,.});tab_reporting[GL Class - Code];0))''select periods_year_reportingyear_attr, reportingperiod_attr, division_code, division_hid, division_name, periods_year_years_balance_code_attr, periods_year_years_balance_description, '=I_EOL_GL_ACTCLN_CODE($C{E,.,.,^+2,.}, $C{E,.,.,^+5,.})' verdichting_code, '=I_EOL_GL_ACTCLN_DESCRIPTION($C{E,.,.,^+2,.}, $C{E,.,.,^+5,.})' verdichting_naam, '=i_eol_bal_year_open($C{E,.,.,^+2,.} , $C{E,.,.,^,.}, $C{E,.,.,^+5,.}) + if($C{E,.,.,^+1,.} = 1, 0, i_eol_bal_pder($C{E,.,.,^+2,.},$C{E,.,.,^,.},1,$C{E,.,.,^+1,.}-1,$C{E,.,.,^+5,.}))' startsaldo, balance, '=i_eol_bal_year_open($C{E,.,.,^+2,.} , $C{E,.,.,^,.}, $C{E,.,.,^+5,.}) + i_eol_bal_pder($C{E,.,.,^+2,.},$C{E,.,.,^,.},1,$C{E,.,.,^+1,.},$C{E,.,.,^+5,.})' eindsaldo, periods_year_years_balance_balancetype_attrfrom balancelinesperperiod order by periods_year_reportingyear_attr, reportingperiod_attr, division_hid, periods_year_years_balance_code_attr, '=INDEX(tab_reporting[Reporting];MATCH(NUMBERVALUE($C{E,.,.,^+7,.});tab_reporting[GL Class - Code];0))'Type: Invantive.Data.ValidationException at Invantive.Data.ValidationException..ctor(String messageCode, String messageText, String kindRequest, String localStackTrace, String nk, Exception innerException) at Invantive.Data.InvantiveParserErrorListener.SyntaxError(IRecognizer recognizer, IToken offendingSymbol, Int32 line, Int32 charPositionInLine, String msg, RecognitionException triggeringException) at Antlr4.Runtime.ProxyErrorListener`1.SyntaxError(IRecognizer recognizer, Symbol offendingSymbol, Int32 line, Int32 charPositionInLine, String msg, RecognitionException e) at Antlr4.Runtime.Parser.NotifyErrorListeners(IToken offendingToken, String msg, RecognitionException e) at Antlr4.Runtime.DefaultErrorStrategy.NotifyErrorListeners(Parser recognizer, String message, RecognitionException e) at Antlr4.Runtime.DefaultErrorStrategy.ReportNoViableAlternative(Parser recognizer, NoViableAltException e) at Antlr4.Runtime.DefaultErrorStrategy.ReportError(Parser recognizer, RecognitionException e) at Invantive.Sql.InvantiveSQLParser.column() at Invantive.Sql.InvantiveSQLParser.sortedColumnList() at Invantive.Sql.InvantiveSQLParser.sortedColumnList() at Invantive.Sql.InvantiveSQLParser.sortedColumnList() at Invantive.Sql.InvantiveSQLParser.sortedColumnList() at Invantive.Sql.InvantiveSQLParser.sortedColumnList() at Invantive.Sql.InvantiveSQLParser.orderBy() at Invantive.Sql.InvantiveSQLParser.selectStatement() at Invantive.Sql.InvantiveSQLParser.sqlStatement() at Invantive.Sql.InvantiveSQLParser.sqlBatch() at Invantive.Sql.SqlEngine.ParseStatement(String sqlStatement, Boolean allowSelect) at Invantive.Sql.SqlEngine.Execute(IProviderManager manager, String sqlStatement, ParameterList parameters, Boolean allowSelect) at Invantive.Sql.SqlEngine.ExecuteAndFetch(IProviderManager manager, String sqlStatement, ParameterList parameters, Boolean allowSelect) at Invantive.Data.ConnectionManager.ExecuteProviderPassthroughSqlActionTable(String actionSql, ParameterList parameters, String& handlingPath) at Invantive.Data.ConnectionManager.PassthroughSqlActionTable(String actionSql, ParameterList parameters) at Invantive.Data.ActionProceduresBase.PassthroughSqlActionTable(String actionSql, ParameterList parameters) at Invantive.Producer.Windows.Forms.FactsForm.SetDataSource(String sqlQuery, ParameterList parameters, String objectName) at Invantive.Producer.Control.Editors.BlockFactsEdit.showFactsButton_Click(Object sender, EventArgs e) at System.Windows.Forms.Control.OnClick(EventArgs e) at System.Windows.Forms.Button.OnClick(EventArgs e) at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ButtonBase.WndProc(Message& m) at System.Windows.Forms.Button.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ThreadContext.LocalModalMessageLoop(Form form) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.RunDialog(Form form) at System.Windows.Forms.Form.ShowDialog(IWin32Window owner) at System.Windows.Forms.Form.ShowDialog() at Invantive.Producer.Control.Utility.OpenRepositoryEditor(Workbook workbook) at Invantive.Producer.Control.ActionsRibbon.editModelButton_Click(Object sender, RibbonControlEventArgs e) at Microsoft.Office.Tools.Ribbon.RibbonPropertyStorage.ControlActionRaise(IRibbonControl control) at Microsoft.Office.Tools.Ribbon.RibbonPropertyStorage.ButtonClickCallback(RibbonComponentImpl component, Object[] args) at Microsoft.Office.Tools.Ribbon.RibbonManagerImpl.Invoke(RibbonComponentCallback callback, Object[] args) at Microsoft.Office.Tools.Ribbon.RibbonMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at Microsoft.Office.Tools.Ribbon.RibbonManagerImpl.System.Reflection.IReflect.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters) at Invantive.Data.InvantiveParserErrorListener.SyntaxError(IRecognizer recognizer, IToken offendingSymbol, Int32 line, Int32 charPositionInLine, String msg, RecognitionException triggeringException) in File104:line 122 at Antlr4.Runtime.ProxyErrorListener`1.SyntaxError(IRecognizer recognizer, Symbol offendingSymbol, Int32 line, Int32 charPositionInLine, String msg, RecognitionException e) at Antlr4.Runtime.Parser.NotifyErrorListeners(IToken offendingToken, String msg, RecognitionException e) at Antlr4.Runtime.DefaultErrorStrategy.NotifyErrorListeners(Parser recognizer, String message, RecognitionException e) at Antlr4.Runtime.DefaultErrorStrategy.ReportNoViableAlternative(Parser recognizer, NoViableAltException e) at Antlr4.Runtime.DefaultErrorStrategy.ReportError(Parser recognizer, RecognitionException e) at Invantive.Sql.InvantiveSQLParser.column() in File59:line 1649 at Invantive.Sql.InvantiveSQLParser.sortedColumnList() in File59:line 1571 at Invantive.Sql.InvantiveSQLParser.sortedColumnList() in File59:line 1585 at Invantive.Sql.InvantiveSQLParser.sortedColumnList() in File59:line 1585 at Invantive.Sql.InvantiveSQLParser.sortedColumnList() in File59:line 1585 at Invantive.Sql.InvantiveSQLParser.sortedColumnList() in File59:line 1585 at Invantive.Sql.InvantiveSQLParser.orderBy() in File59:line 1398 at Invantive.Sql.InvantiveSQLParser.selectStatement() in File59:line 491 at Invantive.Sql.InvantiveSQLParser.sqlStatement() in File59:line 366 at Invantive.Sql.InvantiveSQLParser.sqlBatch() in File59:line 283 at Invantive.Sql.SqlEngine.ParseStatement(String sqlStatement, Boolean allowSelect) in File35:line 652 at Invantive.Sql.SqlEngine.Execute(IProviderManager manager, String sqlStatement, ParameterList parameters, Boolean allowSelect) in File35:line 552 at Invantive.Sql.SqlEngine.ExecuteAndFetch(IProviderManager manager, String sqlStatement, ParameterList parameters, Boolean allowSelect) in File35:line 513 at Invantive.Data.ConnectionManager.ExecuteProviderPassthroughSqlActionTable(String actionSql, ParameterList parameters, String& handlingPath) in File73:line 4499--- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Invantive.Data.ConnectionManager.ExecuteProviderPassthroughSqlActionTable(String actionSql, ParameterList parameters, String& handlingPath) in File73:line 4537 at Invantive.Data.ConnectionManager.PassthroughSqlActionTable(String actionSql, ParameterList parameters) in File73:line 2357--- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Invantive.Data.ConnectionManager.PassthroughSqlActionTable(String actionSql, ParameterList parameters) in File73:line 2369 at Invantive.Data.ActionProceduresBase.PassthroughSqlActionTable(String actionSql, ParameterList parameters) in File63:line 134 at Invantive.Producer.Windows.Forms.FactsForm.SetDataSource(String sqlQuery, ParameterList parameters, String objectName) in File604:line 82 at Invantive.Producer.Control.Editors.BlockFactsEdit.showFactsButton_Click(Object sender, EventArgs e) in File180:line 189Invantive Control for Excel (stable-20161021-2025-ge3e5e61 Prod, L162135034)
The problem is in the order by part of your query. Invantive SQL currently only allows column names in the order by clause. Omitting the last line in the order by fixes the issue. You can sort on fields constructed in the select though, like eindsaldo.
I am not sure why you were trying to sort on a formule that doesn't exist in the actual select statement, it seems unnecessary to me.

Parse strings that are surrounded with quotes

I'm parsing some data I don't control. I have values that are an array of strings. They can either be normal strings, a string representation of a number, or a number with quotes around it.
["This is just a string", "\"5\"", "3"]
I would like to write a function toValue that converts them into the appropriate type to be converted to JSON.
toValue :: (ToJSON a) => String -> a
toValue (if a number) = parseInt
toValue (if a quoted number) = parseInt . stripQuotes
toValue _ = id
I would like to strip the quotes if it is a number surrounded by quotes, then convert it to a number if a number, otherwise pass it back as a string.
Can I do this with pattern matching? Some other way?
import Data.Char
import Data.Bool
parse a#('"':n:'"':[]) = bool (Left a) (Right (read [n] :: Int)) (isNumber n)
parse a#('"':n:m:'"':[]) = bool (Left a) (Right (read [n,n] :: Int)) (isNumber n && isNumber m)
parse a#(n:[]) = bool (Left a) (Right (read [n] :: Int)) (isNumber n)
parse a#(n:m:[]) = bool (Left a) (Right (read [n,n] :: Int)) (isNumber n && isNumber m)
parse xs = Left xs
> map parse ["This is just a string", "\"5\"", "3"]
[Left "This is just a string",Right 5,Right 3]
then, you can use either function from Data.Either module to encode number (Rights) and string (Lefts) to JSON.
Writing a function toValue :: ToJSON a => String -> a as you are proposing is not so hard: let us simply make toValue a method of the class ToJSON
class ToJSON a where
toValue :: String -> a
and then define the instance for Int as
instance ToJSON Int where
toValue s#('\"' : _) = read (read s) -- with quotes
toValue s = read s -- without quotes
The instance for String is slightly more involved (as String is a synonym for [Char]) but by no means rocket science:
class ToJSONList a where
toValues :: String -> [a]
instance ToJSONList Char where
toValues = id
instance ToJSONList a => ToJSON [a] where
toValue = toValues
Now, testing it in an interactive session, we have:
> toValue "This is just a string" :: String
"This is just a string"
> toValue "\"5\"" :: Int
5
> toValue "3" :: Int
3
However, from your question it seems that you have a use case that is not well supported by such a function toValue, i.e., to convert all elements of a list to their appropriate JSON-representation. To do so, you probably want to introduce an algebraic datatype for representing JSON-values:
data JSON = JInt Int | JString String deriving Show
and then have function toJSON that takes strings to their most appropriate JSON-representation:
toJSON :: String -> JSON
toJSON s =
case reads s of
[(n, "")] -> JInt n -- Int, no quotes
_ -> case reads s of
[(s, "")] -> case reads s of
[(n, "")] -> JInt n -- Int, quotes
_ -> JString s -- String, quotes
_ -> JString s -- String, no quotes
Indeed, to answer that part of your question, this function is defined just by (nested) pattern matching. However, if the (grammar of the) language you need to parse becomes more complicated then just integer literals, quoted integer literals, and string literals, this way of defining parsers quickly becomes to clumsy and error-prone, and you may want to start looking into parser combinators or parser generators then.
For your simple language of JSON values, this is arguably still fine though. Here is a simple example in an interactive session:
> map toJSON ["This is just a string", "\"5\"", "3"]
[JString "This is just a string",JInt 5,JInt 3]

Defining and Catching Exceptions

I'm still getting the hang of haskell, and am trying to build my first "real" coding project, i.e. one where I'm going to including testing, write up documentation, etc. I'm sufficiently new to haskell where I know I don't have a lot of the knowledge of the language necessary so that everything I want to do is immediately within reach, but that's kind of the idea, so that the act of finishing will require that I touch most of the major pieces of the language.
Anyway, so the current issue I'm having is regarding throwing and catching exceptions in the language, something that I understand can be done with quite varied approaches. I have a function here, toLower:
toLower :: String -> String
toLower plaintext =
if (catch (nonAlpha plaintext) handlerNonAlpha)
then map charToLower plaintext
else exitFailure
Which will take a string, throw an exception and exit if the string includes any non-alpha characters (so if not A-Z or a-z), or if not convert the string to lowercase. So what I have for the nonAlpha function is:
--- detect non-alpha character - throw error if existant
data NonNumericException = NonNumException
instance Exception NonNumericException
handlerNonAlpha :: NonNumericException -> IO()
handlerNonAlpha ex =
putStrLn "Caught Exception: " ++ (show ex) ++ " - A non-alpha character was included in the plaintext."
nonAlpha :: String -> Bool
nonAlpha str =
let nonalphas = [x | x <- str, (ord x) < 65 || (90 < (ord x) && (ord x) < 97) || 123 < (ord x)]
in if (length nonalphas) == 0
then True
else throw NonNumException
As I said I'm pretty new to haskell, so I'm a little vague on how this data/instance structure works, but as I understand it I'm defining an parent NonNumericException, of which NonNumException is a child (and I could have more), and in the instance line defining them to be Exceptions. The catch structure, if it detects an exception (for instance, when one is thrown at the end of nonAlpha if there is a non-alpha character), then calls the handler.
So here are the compile errors that I get:
utilities.hs:61:3:
Couldn't match expected type `[Char]' with actual type `IO ()'
In the return type of a call of `putStrLn'
In the first argument of `(++)', namely
`putStrLn "Caught Exception: "'
In the expression:
putStrLn "Caught Exception: "
++
(show ex)
++ " - A non-alpha character was included in the plaintext."
utilities.hs:61:3:
Couldn't match expected type `IO ()' with actual type `[Char]'
In the expression:
putStrLn "Caught Exception: "
++
(show ex)
++ " - A non-alpha character was included in the plaintext."
In an equation for `handlerNonAlpha':
handlerNonAlpha ex
= putStrLn "Caught Exception: "
++
(show ex)
++ " - A non-alpha character was included in the plaintext."
utilities.hs:73:7:
Couldn't match expected type `Bool' with actual type `IO ()'
In the return type of a call of `catch'
In the expression: (catch (nonAlpha plaintext) handlerNonAlpha)
In the expression:
if (catch (nonAlpha plaintext) handlerNonAlpha) then
map charToLower plaintext
else
exitFailure
utilities.hs:73:14:
Couldn't match expected type `IO ()' with actual type `Bool'
In the return type of a call of `nonAlpha'
In the first argument of `catch', namely `(nonAlpha plaintext)'
In the expression: (catch (nonAlpha plaintext) handlerNonAlpha)
utilities.hs:75:8:
Couldn't match type `IO a0' with `[Char]'
Expected type: String
Actual type: IO a0
In the expression: exitFailure
In the expression:
if (catch (nonAlpha plaintext) handlerNonAlpha) then
map charToLower plaintext
else
exitFailure
In an equation for `toLower':
toLower plaintext
= if (catch (nonAlpha plaintext) handlerNonAlpha) then
map charToLower plaintext
else
exitFailure
So I guess my two question are, a) what's going wrong with the types for the handler (the line 61 errors), and b) how do I properly set the types for the functions that may throw an exception or exit with failure, but otherwise will return a bool or a string?
EDIT: I guess I should note. I do see the similarities between this question and a number of others that have been asked. Part of what I'm looking for that I don't see is a description of what the structures here are actually doing, and what is best practice and why.
What is best practice in Haskell is to leverage the awesome power of its type system to avoid needing to throw/catch exceptions for pure functions. There are cases where throwing an exception can actually make sense, but for something like your toLower function you can just choose to have a different return type. For example:
-- We can factor out our check for a non-alpha character
isNonAlpha :: Char -> Bool
isNonAlpha c = c' < 65 || (90 < c' && c' < 97) || 123 < c'
where c' = ord c
-- Why throw an exception? Just return False
hasNonAlpha :: String -> Bool
hasNonAlpha str = any isNonAlpha str
-- Renamed to not conflict with Data.Char.toLower
myToLower :: String -> Maybe String
myToLower plaintext =
if hasNonAlpha plaintext
then Nothing
else Just $ map toLower plaintext
Not only is this cleaner code, but now we don't have to worry about error handling at all, and someone else using your code won't get a nasty surprise. Instead, the notion of failure is encoded at the type level. To use this as an "error handling" mechanism, just work in the Maybe monad:
doSomething :: String -> String -> Maybe String
doSomething s1 s2 = do
s1Lower <- myToLower s1
s2Lower <- myToLower s2
return $ s1Lower ++ s2Lower
If either myToLower s1 or myToLower s2 returns Nothing, then doSomething will return Nothing. There is no ambiguity, no chance for an unhandled exception, and no crashing at runtime. Haskell exceptions themselves, those thrown by the function throw, must be caught by catch, which has to execute in the IO monad. Without the IO monad, you can't catch exceptions. In pure functions, you can always represent the concept of failure with another data type without having to resort to throw, so there is no need to over-complicate code with it.
Alternative, you could have even written myToLower monadically as
import Control.Monad
-- Other code
myToLower :: String -> Maybe String
myToLower plaintext = do
guard $ not $ hasNonAlpha plaintext
return $ map toLower plaintext
The guard from Control.Monad acts as a sort of filter for MonadPlus instances. Since Maybe is an instance of MonadPlus (as are lists), this gives us very simple code.
Or, if you want to pass around an error message:
type MyError = String
myToLower :: String -> Either MyError String
myToLower plaintext = if hasNonAlpha plaintext
then Left $ "The string " ++ plaintext ++ " has non-alpha character(s)"
else Right $ map toLower plaintext
Then you can change the type of doSomething to match:
doSomething :: String -> String -> Either MyError String
doSomething s1 s2 = do
s1Lower <- myToLower s1
s2Lower <- myToLower s2
return $ s1Lower ++ s2Lower
If you notice, the monadic syntax lets us change the type signature of our function without even having to change the code! Play around with this implementation to get a feel for how it works.
Learning about exceptions is useful, and they are great for handling exceptional circumstances.
The best place to read about exceptions is Simon Marlow's paper, An Extensible Dynamically-Typed Heirarchy of Exceptions. His book, Parallel Concurrent Programming in Haskell is another good resource on their use.
The following are a few comments on your question.
error on line 61
handlerNonAlpha :: NonNumericException -> IO()
handlerNonAlpha ex =
putStrLn "Caught Exception: " ++ (show ex) ++ ...
Function arguments are consumed eagerly in haskell. You'll have to modify this line as follows to perform string concatenation before calling putStrLn:
putStrLn $ "Caught Exception: " ++ (show ex) ++ ...
comment on nonAlpha
Exceptions can only be caught from an IO computation, and it's best to avoid throwing them from pure functions. Besides this, the problem with nonAlpha is that it claims to return a Bool, but actually returns either True or throws an exception. Why not just return False?
nonAlpha :: String -> Bool
nonAlpha str =
let nonalphas = [x | x <- str, (ord x) < 65 || (90 < (ord x) && (ord x) < 97) || 123 < (ord x)]
in if (length nonalphas) == 0
then True
else False
Pull your exception throwing code out of nonAlpha like so. The name of this function and its lack of return value indicate that it might throw an exception:
trapInvalid :: String -> IO ()
trapInvalid str = unless (nonAlpha str) $ throw NonNumException