Differences btw 7.30 and 7.23 when handling blanks
Posted in 1999
Topics: Connectivity: ESQL/C, 4GL & Embedded SQL
When using 7.23 and ESQL/C, a CHAR column filled with one or more blank(s) returns one blank followed with one ASCII null when selecting into a STRING variable. This makes sense. However, when using 7.30 and ESQL/C, a CHAR column filled with one or more blank(s) returns one ASCII null followed with another ASCII null when selecting into a STRING variable. No blanks anymore ! This makes porting quite difficult. Is this a known bug ?
Pierre Henrotay wrote: > > When using 7.23 and ESQL/C, a CHAR column filled with one or more blank(s) > returns one blank followed with one ASCII null when selecting into a STRING > variable. This makes sense. > However, when using 7.30 and ESQL/C, a CHAR column filled with one or more > blank(s) returns one ASCII null followed with another ASCII null when > selecting into a STRING variable. No blanks anymore ! This makes porting > quite difficult. > Is this a known bug ? I assume you were using the single blank to detect the difference between a column of spaces and a NULL column. The real problem is that this is NOT the correct way to detect a NULL. The correct method is to declare a short and use it as an INDICATOR. On FETCH the indicator will be set to -1 if the column value fetched is NULL, >0 if the column is a character column and was truncated on retrieval to fit in the host variable (the indicator contains the actual length), and zero otherwise. The ESQL/C manual has ALWAYS stated that the contents of a host variable after FETCHing a NULL is undefined and should not be relied upon. Yes many programmers initialize to a known value, like NULL, and check to see if the variable was modified to detect NULLs but this is relying on undocumented behavior and is explicitely recommended against. So, to fix your code: EXEC SQL BEGIN DECLARE SECTION; short col1_ind; char col1[21]; EXEC SQL END DECLARE SECTION; ::::::::::::: EXEC SQL SELECT col1 INTO :col1 INDICATOR col1_ind WHERE keyval = 3; if (col1_ind < 0) { col1[0] = (char)NULL; } else if (col1[0] == (char)NULL) { col1[0] = ' '; col1[1] = (char)NULL; } ::::::::::::::: Now your remaining code will work as before. Art S. Kagel
Sorry obviously that char[21] should be string[21] to mean Pierre's specified problem. Art S. Kagel "Art S. Kagel" wrote: > > Pierre Henrotay wrote: > > > > When using 7.23 and ESQL/C, a CHAR column filled with one or more blank(s) > > returns one blank followed with one ASCII null when selecting into a STRING > > variable. This makes sense. > > However, when using 7.30 and ESQL/C, a CHAR column filled with one or more > > blank(s) returns one ASCII null followed with another ASCII null when > > selecting into a STRING variable. No blanks anymore ! This makes porting > > quite difficult. > > Is this a known bug ? > > I assume you were using the single blank to detect the difference between a > column of spaces and a NULL column. The real problem is that this is NOT > the correct way to detect a NULL. The correct method is to declare a short > and use it as an INDICATOR. On FETCH the indicator will be set to -1 if the > column value fetched is NULL, >0 if the column is a character column and was > truncated on retrieval to fit in the host variable (the indicator contains > the actual length), and zero otherwise. The ESQL/C manual has ALWAYS stated > that the contents of a host variable after FETCHing a NULL is undefined and > should not be relied upon. Yes many programmers initialize to a known value, > like NULL, and check to see if the variable was modified to detect NULLs but > this is relying on undocumented behavior and is explicitely recommended > against. So, to fix your code: > > EXEC SQL BEGIN DECLARE SECTION; > short col1_ind; > char col1[21]; > EXEC SQL END DECLARE SECTION; > > ::::::::::::: > > EXEC SQL SELECT col1 INTO :col1 INDICATOR col1_ind WHERE keyval = 3; > > if (col1_ind < 0) { > col1[0] = (char)NULL; > } else if (col1[0] == (char)NULL) { > col1[0] = ' '; > col1[1] = (char)NULL; > } > > ::::::::::::::: > > Now your remaining code will work as before. > > Art S. Kagel
In article <37E932C8.7EE7CBAD@bloomberg.net>, kagel@bloomberg.net says... >the actual length), and zero otherwise. The ESQL/C manual has ALWAYS stated >that the contents of a host variable after FETCHing a NULL is undefined and >should not be relied upon. Yes many programmers initialize to a known value, Then what purpose does the "risnull" function serve? I think you've made a slip here. A host variable can be checked for nullity with risnull (and thus the contents of a host variable *is* defined and *can* be relied upon) - but it should also be noted that a string isn't one of the "data types" that risnull can check. And that is a change in Informix 7.3 that caused me a bit of grief, too - not because of NULL checking, but for some other reason that I don't remember off the top of my head where the program was expecting *something* to be put into the buffer. -- William Harris william@carsinfo.com