Home page Home page Home page Home page
Pixel Header R1 C1 Pixel
Pixel Header R2 C1 Pixel
Pixel Header R3 C1 Pixel
By Sprezz | Thursday 16 November 2017 17:52 | 0 Comments
Sometimes it doesn't matter how esoteric your knowledge of the internals of the product are - the only way to get to the bottom of an obscure mystery can just be Elbow Grease.

Recently we were contacted by a client with a predicament. He was (finally) converting his client's Rev G system to OpenInsight and he'd run into a snag. Every time he quick painted a form to deal with a specific table, the form was created with no problem. But the moment he reopened the form and tried to look at the properties of specific controls, the controls were no longer data-bound. And to add insult to injury, the columns they had been associated with no longer appeared in the dropdown of selectable columns ; they were still in the dictionary, but not selectable from within the form designer dialog.

Our first thought was that the column names might have retained their Rev G periods. But that wasn't the case. "OK", we queried, "are they in %FIELDS%?". Predictably they were. And anticipating this question the client had already forced a rebuild by clearing the dictionary and copying everything back in.

"Can you check the SYSREPOSWINEXE? Are the columns showing there?". At this point the client indicated that the rows seemed to be corrupted and that the columns weren't showing there. So we suggested REPOSITORY DELETE the EXE and recompiling.

Still no joy.

"OK - check SYSREPOSWINS, SYSREPOSWINEXES and SYSOBJ for GFEs". None. So we decided to try and establish the root cause. Essentially if the design process is removing the column from the control, it's an indicator that the designer hasn't found the column in the dictionary. But we have established that it IS there, so let's start an LH log and see why the read is failing.

Shortly thereafter armed with an LH log, we took a good look at the relevant section and quickly established that the designer was using a TEMP table, not the actual table. Without bothering to test further we simply instructed the client to stop using a TEMP table, as this was likely the cause. The client remonstrated that they WEREN'T using a TEMP table, so at this point we asked for the dictionary and SYSREPOSWIN row to test for ourselves. We ran with the actual table and to our surprise, the LH log showed that regardless of what we told the form designer, a temp table was created and populated with all of the dictionary items from the actual table. And to make matters worse, the columns that wouldn't show up were present both in the temp table AND in the %FIELDS% of the temp table.

Employing Occam's Razor, we then quick painted a form with just two controls, the key prompt and one of the disappearing columns. It quick painted fine BUT the moment we tried to modify the disappearing column's control properties, it was unbound from the data table. All we could gather from that, was that the initial quick paint uses a different column list than the form designer column selection dialog.

Working on the hunch that something in the form read process was removing the column, we then copied all but the two columns needed by our test form into a separate dictionary, and developed a program to copy in a dictionary item, REPOSITORY ACCESS the form, REPOSITORY COMPILE the form, then ACCESS it again to see at what point the column was blanked down. (There were over 700 dictionary items so doing this manually would have been too tedious). To our consternation the column was never blanked down, BUT the moment we entered the form designer it was immediately removed.

At this point all fingers were pointing to the form designer as the culprit, so we had to take a peek inside to see what it was up to. In the absence of source code, the only way to do this was to run an oeprofile.log and dissect that.

The profile log showed that during the loading process, the form designer called DICT_MFS_BUILD, which in turn called COMPILE.PROTECT for a number of dictionary items that was less than the total dictionary items in the table. So in another wild goose chase, we wrote a program to emulate this behaviour and see which dictionary items were failing to compile. Naturally this failed to produce the results we needed.

At this point we were pulling our hair out with frustration, so we just populated the dictionary with only the columns needed for the original data entry form the client had provided. The form worked and the columns remained intact in the controls. So we copied in the rest of the dictionary items and again the columns were removed from the errant controls. It was time to abandon abstruse investigative techniques and just go back to plain old gumshoeing.

It was obvious that at least ONE of the columns in the dictionary was causing the issue but which one? The only way to investigate would be to copy the dictionary items in one by one, go into the form designer, check if the control had had the column removed and if so the last dictionary item copied in was our culprit. The idea of doing this for over 700 columns frankly sucked. Enter our old friend - 'binary chop'.

We wrote a program that selected the temporary dictionary in sorted order , and then copied in the first 360 or so columns. We went into the form designer and sure enough, the affected controls had their columns removed. So we modified the program to do the first 180. Same problem. First 90. Same problem. First 45. The controls kept their columns. First 72. Same problem. First 58. The controls kept their columns. First 65. Same problem. First 61. The controls kept their columns. First 63. Same Problem. First 62. The controls kept their columns.

Ladies and Gentlemen we have a winner! Dictionary item 63 looks to be the culprit. But one final check. We copied in ALL dictionary items apart from that one and the form remained intact. It was the sole dictionary item responsible. We called the client and asked them to confirm. Delightedly they did...

Finally it was time to see WHY this dictionary item was such bad news. Opening it in the table builder showed no obvious reason, but reading it then dropping to the debugger so it could be examined properly gave the game away. There was object code on attribute 20. It was still a Rev G format dictionary item and for reasons best known to C++ this confused the form designer.

Armed with this knowledge we could easily inspect the table and others for dictionary items with code on attribute 20 - and to save ourselves the hassle of writing a program we just used a simple RLIST statement


Note that we could have opted to create a new dict item in SYSDICT pointing to column 20 and  query on that but as the AVERY_LABELS table already had a dictionary item pointing at column 20 we used that instead in combination with the RLIST "USING AltDict" syntax.

Now if only we'd gone down the simple route at the beginning. Still it's hard to beat the adrenaline boost you get when you finally get there!

Pixel Footer R1 C1 Pixel