by Loren West My understanding of how Informix handles Temporary String Space has increased dramatically over the last couple of months, and I'd like to share that information for anyone (everyone) that has ever had a string space problem. 1) TSS in Informix is limted. It is only about 4K or so. 2) Very few things require TSS. Usually, those things use it, then clear the entire TSS when they're done. In my opinion, Informix's 4K limit on TSS is adequate. It only becomes a problem under certain (and completely avoidable) circumstances. 3) TSS is used in the following scenarios: A) Passing strings to, and returning strings from functions. B) Internal scratchpad usage within certain 4GL commands. * Scenario (A) is blamed for 4GL running out of temporary string space. It also, usually, is not the source of the problem. 4) In order to understand the source of the problem, it's important to understand how temp string space is used, and when it's cleared. When a string is passed to a 4GL function, the calling function places it into TSS. IMMEDIATELY upon invocation, the called function retrieves it into a local variable, and (and this is the key) if there is nothing else in TSS, the ENTIRE TSS is cleared and reset. IF there is something else in TSS, it waits until that something is used, THEN it resets TSS. IF that something never uses it, then you get the out of string space problem. The following example shows normal TSS usage: 1 main 2 call myfunct("Hello") 3 end main 4 5 function myfunct(str_var) 6 define 7 str_var char(20) 8 display str_var clipped, " World" 9 end function In the above example, line 2 places the string "Hello" into TSS. Line 7 actually retrieves "Hello" from TSS, puts it into the local str_var variable, and because there is nothing else in TSS, it is cleared and reset. Line 8 puts str_var into TSS, then puts " World" into TSS, then calls (an internal 4GL) display function. This display function retrieves "Hello" from TSS, then retrieves " World" from TSS, then (because there is nothing else on the stack) clears and resets TSS. It then goes about it's business of displaying "Hello World" onto the screen. The following example shows how you can get into trouble with TSS: 1 main 2 define 3 local_var char(20) 4 let local_var = "Hello", myfunct(" World") 5 end main 6 7 function myfunct(str_var) 8 define 9 str_var char(20) 10 return str_var 11 end function In line 4, the "Hello" string is put into TSS (for the `let' command), then " World" is placed into TSS for the function call to myfunct(). The difference here is line 9. When " World" is removed from TSS, it is not cleared because "Hello" is still there. In line 10, TSS is used again to return the string " World" back to the calling function. At this point, TSS contains the following: "Hello" " World" " World" When myfunct() returns, " World" is taken from the TSS, then put back into the TSS for the let command to process. At this time, TSS looks like: "Hello" " World" " World" " World" Finally, the let command gets the " World", then the "Hello", and when it gets the "Hello", the TSS is cleared. This is a normal situation. It uses TSS, but not much, and it is appropriately cleared after the `let' command is done processing. The problem that can arise using this syntax is if the myfunct() command doesn't return right away. If myfunct() calls alot of different function, and if those functions consume any TSS, then it will not be reset until the first `let' command has finished processing. You're very likely to get a string space error in this scenario. 5) The following scenarios will result in an out of string space error if the function that is called is a "string hog" (a string hog function is one that uses TSS alot - not necessarily one that uses alot of TSS, but one that uses TSS alot): A) Calling a function from within a string concatenation" This will error: let a_string="Hello",string_hog() This will not: let temp_string=myfunct() let a_string="String",temp_str B) Using the `case' command with a string argument. This will error: case a_string when "A" display "OK" when "B" call string_hog() end case This will not: case when a_string="A" display "OK" when a_string="B" call string_hog() end case Note also that the `using' keyword can be categorized as a `string hog' function. This doesn't mean that it inappropriately uses TSS, it just uses alot. 6) In most cases, finding the source of the string space error is incredibly difficult. It usually is caused in a function far away from the place that the program actually fails. What follows is a function that is guaranteed to work if TSS is clear, and is guaranteed to fail is TSS has something in it. Since there is no way of printing out the TSS, I suggest setting breakpoints in your program (using the debugger), and calling this function from the debugger command line. If you get the string space error when you call this function, then there definately is something in TSS. If you don't get an error, then there is definately nothing in TSS. Once you get the error, keep running the program the same way, (calling this function from the debugger command line) and setting breakpoints earlier and earlier. Using this method, you should be able to find the place in the program that uses TSS without resetting it. In most cases, the fix is to write the chunk of code in a different way. You might find that the error occurs in a C function that you have written. It is very easy to write a C function that doesn't use TSS properly. Because of this fact, also don't be surprised if a 4GL command used in a non-standard way causes this result. No programmers are perfect - Informix may have a bug in one of their commands if used in a non-standard way. Once found, simply write the block of code a different way. If you are getting "out of temporary string space" errors, put the following functions in your main.4gl and call tss_hog() from the debugger command line (as specified above): function tss_hog() define n smallint, str_var char(50) for n=1 to 1000 let str_var=tss_hog1() end for end function function tss_hog1() return "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" end function If you don't have the debugger, you can put calls to tss_hog() in strategic places in your program, then recompile and test narrowing the gap between a call to tss_hog() that works and the call to tss_hog that fails. Once you've narrowed it down to one line in your program where, if you call tss_hog() before executing that line, it works and if you call tss_hog() after executing that line, it fails - you've found the offensive line. If the syntax of that line doesn't match one of the above "don't do" scenarios, please let me know. I'll add that scenario to the list next time this article is published.