System.OutOfMemoryException thrown on JSONTABLE with Twinfield BI-ON-Focus

Dank voor statement.

De OutOfMemory exception bij het inlezen vanuit (ik gok) BI ON Focus PowerBI for Twinfield is verwacht gedrag. Mogelijk dat er in de toekomst een uitbreiding komt voor dergelijke grote downloads.

Achterliggend probleem is dat er wel 64-bits processen zijn, maar dat bijvoorbeeld een aaneengesloten tekst maximaal 2 GB lang mag zijn. Aangezien Invantive SQL werkt met twee bytes per karakter is de theoretische limiet 1 miljard tekens (1 Unicode karakter per 16 bits).

De download is ruim 1 GB na decompressie, maar het opslagformaat is waarschijnlijk UTF-8 (meeste Unicode karakters vergen 8 bits, sommigen tot/met 32 bit). De download kan dus niet in een 2 GB tekst opgenomen worden. Dit is vergelijkbaar met de veelvoorkomende lengtebeperking van 2 GB (na omzetting UTF 8 in UTF 16) voor blob en clob op platformen zoals Oracle en PostgreSQL.

Waarschijnlijk staat er in de call stack iets zoals:

System.OutOfMemoryException
ValidationException
   bij System.String.CreateStringFromEncoding(Byte* bytes, Int32 byteLength, Encoding encoding)
   bij System.Text.UTF8Encoding.GetString(Byte[] bytes, Int32 index, Int32 count)
   bij Invantive.Data.DataDictionaryProvider.FetchYieldUnfilteredInternal(GlobalState owner, ExecutionOptions executionOptions, EntityFieldCollection entityFields, QueryObject queryObject, ParameterList parameters, Boolean fetchSingle, Boolean fetchCountFirst, Int32 pagingSteps, Boolean fetchCount)

Het filteren van de data met een on zoals:

select ...
from   httpdownload@datadictionary(...)
join   jsontable() t
on    t.kolom = waarde

zal niet helpen. De HTTPDownload mislukt al omdat er meer dan 2 GB aan karakterdata in UTF-16 nodig is.

Aanbevolen oplossing is om over te stappen op Invantive’s eigen Twinfield driver voor Power BI of Data Replicator. Die heeft intern een streaming architectuur en object-georiënteerde structuur waardoor datavolumes van 32 GB of meer geen probleem zijn (mits het OS dat ondersteunt en 64-bit proces gebruikt wordt). Het datamodel zal waarschijnlijk vergelijkbaar zijn. Om traffic naar Twinfield te beperken wordt ook gewerkt met automatisch bepaalde server-side filters zoals beschreven in Filteren op velden uit de Twinfield API.

Er kan dan gewerkt worden met:

select count(*) from TWINFIELDTABEL

om de data in SQL Server te krijgen of met tussenstap met filter:

create or replace table xyz@inmemorystorage
as
select /*+ ods(false) */
       *
from   TWINFIELDTABEL
where  kolom = WAARDE

select /*+ ods(true, interval '0 seconds') */ count(*) from xyz@inmemorystorage

Het maken van een Twinfield settingsbestand staat beschreven in bijvoorbeeld Instellingen voor koppeling naar Twinfield.