If this isn't a bug, it should be ... temp-tables and bi

Posted by jmls on 16-Apr-2012 06:24

OE11, windows 7

given this code:

class1

class temp.class1:

def  temp-table TTBug no-undo serialize-name "IsThisABug"

      field field1 as character

      field field2 as character

      field field3 as character.


  method public void Bind(output table TTBug bind):

  end method.

 

  method public void foo():

    find first TTBug.

   

    message "In class1" skip

            "field1" TTBug.Field1 skip

            "field2" TTBug.Field2 skip

            "field3" TTBug.Field3 skip

            view-as alert-box.

  end method.

      

end class.

class2:

class temp.class2:

def  temp-table TTBug no-undo serialize-name "IsThisABug" reference-only

      field field1 as character

      field field3 as character

      field field2 as character.

     

  method public void foo():

    def var class1 as temp.class1 no-undo.

   

    class1 = new temp.class1().

   

    class1:Bind(output table TTBug bind).

   

    create TTBug.

    assign TTBug.field1 = "field1"

           TTBug.field2 = "field2"

           TTBug.field3 = "field3".

    message "In class2" skip

            "field1" TTBug.Field1 skip

            "field2" TTBug.Field2 skip

            "field3" TTBug.Field3 skip

            view-as alert-box.


    class1:Foo().   

  end method.

end class.

run this code:

(NEW temp.class2()):foo().
do you see the error ?

All Replies

Posted by Peter Judge on 16-Apr-2012 08:56

Ouch. Take you long to find?

Looks like a bug to me. Compiler complains when you change the type or name of field3.

-- peter

Posted by jmls on 16-Apr-2012 10:12

in a word, yes.

I simply could not understand why the data was ok. Then it wasn't.

I suspect that either the buffer allocation is wrong , should be using field name not field position in the table, or the compiler should determine that the definitions are not the same.

Either way, it was an , errm, interesting few hours ..

Posted by Peter Judge on 16-Apr-2012 10:20

Having the field names and their data being the same, couldn't've helped much

(I know that's the repro).

For the record, below are screenshots of the messages. Note the content of field2 between the 2 classes.

Message was edited by: Peter Judge: email reply didn't include the messages

Posted by jmls on 16-Apr-2012 10:36

Yeah, the real world case actually had nearly a dozen fields, with two swapped round (BuildUnitGUID and AccessMode)

So , whenever I updated some data, the BuildUnitGUID got allocated to "public" (which was the content of the AccessMode field), which then meant that nothing was linked to the parent table anymore, and *poof* , as if by magic, all children disappeared from the xml file

Posted by Thomas Mercer-Hursh on 16-Apr-2012 11:16

Seems like another argument for only having the TT in one place ....

Posted by Peter Judge on 16-Apr-2012 14:35

jmls wrote:

in a word, yes.

I simply could not understand why the data was ok. Then it wasn't.

I suspect that either the buffer allocation is wrong , should be using field name not field position in the table, or the compiler should determine that the definitions are not the same.

Either way, it was an , errm, interesting few hours ..

So, some further feedback. First, some info on the cause of the behaviour from a core developer

The CRC that we keep to show that it is ok to bind the two tables only cares about the extent and datatype of the columns, and the indexes.  If those match, then it allows the binding.  It does not even look at the field names themselves. 

And second, this is not currently considered a bug

Posted by Admin on 16-Apr-2012 14:58

Or - which involves less of an architectural change - that EVERY temp-table and ProDataset definition belongs into an include file with parameters for

- access member (PROTECTED / PRIVATE)

- REFERENCE-ONLY

- before-table (yes/no)

- name prefix

Posted by Admin on 16-Apr-2012 15:00

So, some further feedback. First, some info on the cause of the behaviour from a core developer

The CRC that we keep to show that it is ok to bind the two tables only cares about the extent and datatype of the columns, and the indexes. If those match, then it allows the binding. It does not even look at the field names themselves.

I just had a quick look in to online help - but is there some reference on this CRC calculation somewhere?

I didn't find anything.

I must say, I agree to Julian, that this smells buggy. The behaviour is so unexpected, that I'd consider it a bug as well. If it's not documented somewhere.

Posted by Thomas Mercer-Hursh on 16-Apr-2012 15:05

Bottom line, if it behaved properly, then there would be no bug to fix, but since it is not well-behaved and no warning is given, then, perforce, it must be a bug.

Posted by jmls on 17-Apr-2012 00:22

pjudge wrote:

So, some further feedback. First, some info on the cause of the behaviour from a core developer

The CRC that we keep to show that it is ok to bind the two tables only cares about the extent and datatype of the columns, and the indexes. If those match, then it allows the binding. It does not even look at the field names themselves.

And second, this is not currently considered a bug

First - changing the name of the field does matter (see your previous post) - so it *does* look at the field names themselves

Second: you have to be kidding. Anything that corrupts data (and, yes, I consider this as a corruption as in my case the unique key guid was magically transformed into "public", without me lifting a finger) _has_ to be considered a bug.

I very rarely say this is public - Progress is way wrong here. This smells like the old "that's a documentation error" rather than actually conceding that a bug exists.

Posted by jmls on 17-Apr-2012 01:21

As you know, I *hate* include files. With a passion.

However, in this case, I may have to concede and agree with you.

Ouch. That hurt.

Posted by Admin on 17-Apr-2012 01:46

I'll spend you a beer at the PUG Challenge Americas to relief you from the pain.

Posted by jmls on 17-Apr-2012 02:11

The pain is so intense I fear that it will take at least a dozen beers to releive it ....

Posted by Peter Judge on 17-Apr-2012 08:00

As you know, I hate include files. With a passion.

However, in this case, I may have to concede and agree with you.

Ouch. That hurt.

Which part? Agreeing with Mike, or using include files?

Can you generate the TT defs?

-- peter

Posted by Admin on 17-Apr-2012 10:36

The pain is so intense I fear that it will take at least a dozen beers to releive it ....

I it's Bud light, that's understandable.

Posted by jmls on 17-Apr-2012 10:59

pjudge wrote:

Which part? Agreeing with Mike, or using include files?

Can you generate the TT defs?

-- peter

1) I agree with Mike on a lot of things. Apart from .net. and include files ...

2) I am doing now. My problems were caused by having to bootstrap Maia using Maia. So I had to hand-code until it could generate it's own code ...

Posted by jmls on 17-Apr-2012 11:00

if it's bud lite, then that will simply cause more pain. Although I have been reliably informed that there is a great selection of decent beer at Pug challenge

Posted by Thomas Mercer-Hursh on 17-Apr-2012 11:25

You could agree with me, instead, and that would spare you the include file ... but might be even more painful!

Posted by Admin on 17-Apr-2012 11:31

You could agree with me, instead, and that would spare you the include file ... but might be even more painful!

So when it's even more pain, why go that way? Are you offering more beer?

Posted by Peter Judge on 17-Apr-2012 12:36

Although I have been reliably informed that there is a great selection of decent beer at

Pug challenge

Yep: Bud Light, Miller Light, Coors Light. And Natty Ice if you're lucky.

Aaaaannnnnnd I think that was the sound of my registration being revoked

-- peter

Posted by Peter Judge on 17-Apr-2012 12:51

You could agree with me, instead, and that would spare you the include

file ... but might be even more painful!

This may not be the correct forum, but can you clarify something?

Let's take a CustomerTable class that defines a tt.

Class CustomerTable :

define protected temp-table ttCustomer no-undo

field CustNum as int

field Name as char

.

End class.

Q1. Is this CustomerTable the message (or part of it) that gets passed around from client to server? Between server layers (BE-> DA -> DS) too?

Q2. How do I attach logic/code to it? Inheritance ("Class CustomerModel inherits CustomerTable" or " Class CustomerBusinessEntity inherits CustomerTable") or decoration or some other mechanism? Important here is the ability to write static code (FOR EACH ttCustomer) in this logic.

-- peter

Posted by Thomas Mercer-Hursh on 17-Apr-2012 13:39

We probably are diverting the thread a bit, but ...

For the first question, I think it is important to distinguish the TT from the message.  The message may be many, many things depending on context.  In particular, in most cases there is no reason to pass the whole contents of the data from one session to another.   One might pass in or out a single instance, but not the whole table.  The one obvious *possible* exception to this is the special case of needing to populate a client side browser with a body of data.  Even then, one may not send the entire table, but only one visible set at a time.  Even when whole sets of data are to be sent, I would distinguish between the message and the TT in which they are going to be held at either end, rather than simply passing the TT itself.

I am not sure of the issue you are trying to raise in Q2.  For starters, I would not have a "CustomerTable" class.  I would have a class that had a particular purpose that happened to use a TT as the internal structure for storing the data elements of the class.  E.g., one might have a state code validation class which had a TT of valid state codes and names.  The TT is invisible from the outside; all one knows that one can submit a state code and get back a name or an error message that the code is not valid.  Whether the inside is a TT, array, linked list, or whatever is not a visible part of the class.

Given classes which have a purpose and some BL and happen to use a TT to hold the data, I'm not sure what your issue is about attaching logic.  E.g., I recently had a need for a class which would create and manage a list of files below a specified starting directory.  I created a superclass which had all of the logic for managing the file list and nexting through it and subclasses which overrode one method to determine what types of files were included in the list.  This means that all the logic for what might be a site-specific set of criteria, e.g., "how do I recognize what files are compile units?" is in a very small subclass separate from the mechanics of managing the list.

This thread is closed