cursor name mangling
Posted in 1997
Hi fellow informix professionals: The following question on cursor name mangling was answered by Hi fellow informix professions: The following is e-mail with Jonathan concerning cursor name mangling. I figured I'd share this with the rest of you. regards, Ed Schaefer > Hi Jonathan: > > I'm looking at upgrading a ton of 4.x 4GL code to 6.x. I was wondering > if I'm passing on the straight "poop" about name mangling. I know there > is a global setting which might overide this, but what is your opinion? > > Thanks and best regards, > > > Ed > Schaefer > > SUBJECT: Updating 4GL from 4.x to 6.x, CURSOR NAME MANGLING > > In the 4GL and EQL/C compiler prior to Version 4.13, all cursor and statement > names are local to a single 4GL file so reusing the names in different > files caused no problems. In Versions 5.0 and 6.0 ESQL/C, all cursor and > statement names are global by default. (Remember 4GL is preprocessed to > "C"). In I4GL 4.1x and 4.20, and ESQL/C 4.1x (which is what's used by I4GL 4.1x and 4.20), all cursor names are local to the single I4GL source file... The 4.13 is a red-herring; it implies that it isn't true for 4.14..4.20 but it still applies to them too. > To preserve the old behavior of cursors, Informix now mangles cursor names. > The mangled name is an 18-character string consisting of the i-node of the > 4GL source file and a hash number derived from the cursor or statement name. Correct. > Informix has now introduced a problem with name mangling cursors with > update and delete cursors. Here's an example: I'd prefer to describe this as: One side-effect of this change is that prepared UPDATE or DELETE statements with a WHERE CURRENT OF clause need special treatment. > DECLARE c_name CURSOR FOR SELECT ... FOR UPDATE > PREPARE update_table FROM > "UPDATE sometable SET somecolumn = ? WHERE CURRENT OF c_name" > > In the preprocessed code, the cursor name, c_name, is mangled to some > strange 18-character string, but the name embeddded in the update string > is not. > > It's now left to the programmer to make sure the name mangling of update > and delete cursors is done. Informix has provided a built in function, > cursor_name(), to provide the proper name mangling. Here's an example > fix: > > DECLARE c_name CURSOR FOR SELECT ... FOR UPDATE > PREPARE update_table FROM > "UPDATE sometable SET somecolumn = ? WHERE CURRENT OF > cursor_name(\\"c_name\\")" No: LET upd = "UPDATE sometable SET somecolumn = ? WHERE CURRENT OF ", cursor_name("c_name") PREPARE update_table FROM upd The cursor_name() function is an I4GL function; the contents of a prepared string are only interpreted by the engine. Thus, the cursor_name() function cannot be embedded inside the string which is prepared; only the result of calling it can. Note, too, that the cursor name hashing algorithm is not perfect; two different names can hash to the same string in the same file, even though the original names were different. There is, unfortunately, a number of pairs of 2-character suffixes which always hash to the same value. See the notes below from my email archives. Also, and most complexly, I've recently discovered that you cannot reliably use a given cursor name (eg c_name) in file1.4gl as a CURSOR ... FOR UPDATE and in file2.4gl as a plain cursor, and have both prepared, and then use the WHERE CURRENT OF c_name clause -- you can get error -290 about the cursor not being declared for update. This is an independent problem, and exists in pure 4.1x I4GL running against 4.1x OnLine, let alone more complex setups. > For more information, check out the INFORMIX 4GL Reference Manual > Supplement Version 6.0. Note that the cursor_name() function is present in the 4.1x compiler and runtime, but it does nothing -- this allows the same source code to be used with either 4.1x or 6.0x I4GL. > Thanks for listening. If you think it's worth posting this to the rest > of comp.databases.informix I will. Yes, it's probably worth posting it, as amended. Also notify David Williams who has just taken over the FAQ... Yours, Jonathan Leffler (johnl@informix.com) #include <witticism.h> ======================================================================= === Date: Tue, 9 Aug 94 07:59:49 PDT From: johnl@anubis (Jonathan Leffler) Subject: Re: 4371 error at compile time, 4GL 6.00.UE1 >Date: Tue, 9 Aug 94 09:28:56 CDT >From: joea@jupiter2 (Joe Arroyo) >Subject: 4371 error at compile time, 4GL 6.00.UE1 > > IHAC reporting that at compile time he receives a -4371 error. > > -4371 Cursors must be uniquely declared within one program module. > > He just upgraded to I-4GL RDS version 6.0, Online 6.0 and changed > the program to add the Declare Cursor. He claims that the cursor > name is used only once. > > Caselog isn't providing me much help, I've also checked PTS and > couldn't find any matches. If anyone has upgraded to 6.0 and > experienced this problem I would like to hear from you or if you > know what might be causing this error feel free to respond. Version 6.00 4GL (both c-code and p-code) uses 6.00 ESQL/C, and 6.00 ESQL/C provides only global cursor names. (The -local option to esql doesn't work reliably unless your cursor names are short enough: 9 is the maximum guaranteed to work; anything longer than 16 definitely won't work; anything in between may or may not work, depending on the inode number of the source file.) I4GL has always worked with cursor names local to the source file. To try and maintain the previous semantics, we mangle the cursor names using an algorithm based on the inode number and the cursor name. All cursor and statement names therefore look like I01234568_12345678, where the digits are in hex. You can suppress this transformation by using the -globcurs option to either fglpc or c4gl. I need a list of all the cursor names and statement names from the module where your customer is running into problems, so that I can see which two are hashed to the same value, and we may need to improve the hashing algorithm. Without this information, the problem cannot be resolved in the future. Changing the cursor name will fix the problem. Using -globcurs will fix the problem in this file -- be wary of using it generally because if you use the same cursor name in two different files, they must NOT both be compiled with -globcurs. Reading the TOOLREL_6.0 release notes (page 14) would reveal a discussion of this issue, though error 4371 is not mentioned. See also B31661 for another aspect of this problem. Yours, Jonathan Leffler (johnl@godzilla) Date: Wed Aug 2 10:34:31 1995 From: johnl (Jonathan Leffler) To: informix-list@rmy.emory.edu Subject: Cursor Name Mangling -- clashes Hi, The 6.0x ve