web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics AX (Archived)

update_recordset method within loop appears to cause CIL compile issues

(0) ShareShare
ReportReport
Posted on by

I've only recently discovered the insert_recordset & update_recordset methods, and am trying to refactor a variety of procedural RBAR-style classes to use these methods, but appear to be hitting an issue on CIL compile when the X++ seems fine.

Scenario is that I've written an RDP class that populates a TempDB table (left as regular in the sample XPO below to more easily look at the data) with a record for the cartesian product of workers & dates within a range, and I want to get the worker's target hours for each day into the same temp DB table in order to compare hours worked to target.  With target hours being an array field (as I understand it), I've got a loop that's intended to iterate through days of the week to identify the value, and I wanted to use update_recordset to update the table that holds the report data:

for(loopN = 1; loopN <- 7; loopN++)
{

update_recordSet tblData
setting
TargetHours = tblProjWorkerSetup.MaxWorkingHours[loopN]
outer join tblProjWorkerSetup where tbldata.WorkerRecId == tblProjWorkerSetup.Worker
&& tblData.DayNumber == loopN;
}

The X++ compiles fine, and using this approach in a job to sanity check for logic errors, all appears well.  But when I run the incremental (or full) CIL compile, I get the error below in the log

Error 1. Class: RRH_DataProvider, Method: insertDataTmp, Exception: System.NotSupportedException: Line Number 43 - Stack empty. ---> System.InvalidOperationException: Stack empty.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at Microsoft.Dynamics.Ax.Xpp.ILGenerator.Field(XmlNode node)
at ILGenerator::Field(ILGenerator , XmlNode )
at Microsoft.Dynamics.Ax.Xpp.ReflectionCallHelperGenerator.CallPCode(ILGenerator generator, String PCode, XmlNode node)
at Microsoft.Dynamics.Ax.Xpp.ILGenerator.processBytecode(XmlNode childNode)
--- End of inner exception stack trace ---
at Microsoft.Dynamics.Ax.Xpp.ILGenerator.processBytecode(XmlNode childNode)
at Microsoft.Dynamics.Ax.Xpp.ILGenerator.processBytecodes(TypeBuilder typeBuilder, XmlNode node)
at Microsoft.Dynamics.Ax.Xpp.ILGenerator.GenerateIL(TypeBuilder typeBuilder, XmlNode node)
at Microsoft.Dynamics.Ax.Xpp.ILGenerator.TraversePCode(XmlNode node)
at Microsoft.Dynamics.Ax.Xpp.PCodeTraverser.TraverseMethod(XmlNode methodNode)
at Microsoft.Dynamics.Ax.Xpp.ILGenerator.GenerateXppModule()

I've found innumerable blogs suggesting that a cleardown of the XPPIL folder & full recompile will solve issues like this, but I've tried that any number of times to no avail, so I've uploaded a small XPO that displays the issue in case I haven't explained myself sufficiently here.

Any thoughts greatly appreciated.

*This post is locked for comments

I have the same question (0)
  • Community Member Profile Picture
    on at

    Crispin,

    Thanks for the suggestion (and for pointing to what could be a model class).  Sadly, the join type doesn't seem to change the behaviour.  The exists join won't allow me to use the field on the related table (compile error Attempt to use a field from an exists or notexists join in an illegal context), and changing the outer join to a standard join gave the same behaviour of a successful X++ compile but stack empty error on CIL compile.

    Looking at the LedgerTransStatementDP class highlighted my implicit assumption that the for loop could be a factor, so I tried moving the update_recordset call outside of the loop & having a specific call for each day of the week rather than using the loop variable, but that made no difference either.

    I still haven't quite convinced myself that an XPPIL cleardown & full recompile isn't going to magically fix things, so the slow reply reflects that! Sadly something yet to be discovered is still at play...

  • Douglas Noel Profile Picture
    3,905 on at

    Hi,

    I think the problem is related to the usage of array fields within CIL, not the use of update/insert record set itself.

    I remember some unsupported / not working things using array fields under CIL.

    regards

    Douglas

  • Community Member Profile Picture
    on at

    Douglas,

    That sounds like a possibility well worth investigating (I had tried searching for anything on the subject of arrays and CIL, but the I wasn't convinced the first two posts I found were definitely applicable).  I've tried to build on your suggestion by constructing a view that splits out the [ProjWorkerSetup].[MaxWorkingHours] array field, but despite the properties of the view fields showing the the data type to be the same as the desired temporary table field (screenshots below: note that the view field has no ExtendedDataType like the original array field), the modified X++ gives a compile-time error Operand types are not compatible with the operator, and opening the view within the Dev workspace pretty much confirms that it's still an array field.  Hopefully I'll find something on how to expose individual elements of array fields as columns, and will update if I do, but if anyone reading has that knowledge already, sharing here would be great!

    Source array field:

    ViewField.PNG

    View field attempting to split:

    ViewField.PNG

    Target field in table for report data:

    TargetField.PNG

  • Verified answer
    Mea_ Profile Picture
    60,284 on at

    Hi Rich Hims,

    You definitely need to file a bug with MS.

    Minimum example I found to repro this issue :

    ProjWorkerSetup   tblProjWorkerSetup;
    tblData           tblData;
    
    update_recordSet tblData
        setting TargetHours = tblProjWorkerSetup.MaxWorkingHours[2]
            outer join tblProjWorkerSetup
                where tbldata.WorkerRecId == tblProjWorkerSetup.Worker;


    I think Douglas had good idea, so I tried to create a view with computed columns:

    private static server str compColMaxWorkingHoursTU()
    {
        return SysComputedColumn::returnField(
            tableStr(ProjWorkerSetupView),
            IdentifierStr(ProjWorkerSetup_1),
            fieldid2name(tablenum(ProjWorkerSetup), fieldid2ext(fieldnum(ProjWorkerSetup, MaxWorkingHours), 2)));
    }

    And it perfectly works:

    ProjWorkerSetupView   tblProjWorkerSetup;
    tblData           tblData;
    
    update_recordSet tblData
    setting TargetHours = tblProjWorkerSetup.MaxWorkingHoursTU outer join tblProjWorkerSetup where tbldata.WorkerRecId == tblProjWorkerSetup.Worker;

    Now if you still want to have a loop you can create container or any other collection, add there fieldIds and use them in a loop.
     

  • Community Member Profile Picture
    on at

    Thanks ievgen.  I've used a couple of computed columns in the past, but it's not an approach that would have occurred to me without specific guidance.  I've resolved with 7 day-specific updates rather than a loop because

    • The container approach for field IDs made the code sufficiently less comprehensible IMO that it wasn't worth reducing the down to a single update within a loop, and the performance should be the same either way
    • The way I was identifying field ID & then retrieving from a container gave me the X++ compile error "Container and text fields not allowed in update_recordset setting expression".  I suspect you would have had a different way of retrieving field IDs.

    If the array field in question was hundreds of items long rather than 7, I might feel the need to resolve the second bullet...

    Will update here when I've logged an issue with MS

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics AX (Archived)

#1
Martin Dráb Profile Picture

Martin Dráb 4 Most Valuable Professional

#1
Priya_K Profile Picture

Priya_K 4

#3
MyDynamicsNAV Profile Picture

MyDynamicsNAV 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans