jw@pan.UUCP (Jamie Watson) (09/01/88)
The Informix 4gl manual attempts to explain that the 'database' statement actually has two distinct uses, one at compile time and the other at run time. Unfortunately, the interpretation of the statement is not as clear cut and unambiguous as the manual makes it seem. The first use, at compile time, is pretty straight forward. If a program contains variable definitions with the 'like field' syntax, the compiler needs to know where to look to find out what type 'field' really is. The second use, at runtime, is likewise simple; when the program runs, it needs to know what database to use. Unfortunately, the implementation of the 'database' statement is, to say the very least, baroque. If a 'database' statement is made outside of any function, then the word which follows it must be the name of a database which exists either in the pwd or in DBPATH at compile time. No quotation marks, no indication that this is actually a data string. So it looks like this: database bletch If a 'database' statement is made inside of the main program or any other function, then things get messy. If the word that follows it matches the name of a previously defined 4gl variable, then the 4gl compiler assumes that this varible will contain the name of the database at runtime. There is no type checking on this variable, however - it could easily have been defined as an integer, or anything else (I haven't figured out how to put a database name in an integer variable yet) (even though I used to be a FORTRAN programmer...). Worse, if the following word does *not* match any defined 4gl variables, then the 4gl compiler (quietly) assumes that it is the literal name of a database to be used at runtime - still with no quotes or other distinguishing notation. This means that errors in typing a variable name at this point are not detected until runtime, and the resulting error message is not exactly clearly indicative of the actual mistake. So, a program might look like this: main define dbname string(20) let dbname = "bletch" database dbname end main Now, what benefit do we get from all this baggage? Well, we can actually write programs that don't know the database name until runtime, right? Wrong. If the program contains *any* variable definitions with 'like', then there must be a 'database' statement outside of any routine. But if there is a 'database' statement outside of any routine, then this is the default startup database at runtime, and that database must exist, even if it is never accessed, even if the first executable statement in the program is a 'database' statement! The case in point. Our application doesn't know what the name of the database it wants to access is until runtime. But we use 'like' defines a lot (of course), so it comes out looking like this: database bletch main define dbname string(20) let dbname = "skrot" database dbname end main Now, we have a database called bletch on our development machines, because that is what we do development and testing in; but there is no such thing on our customers machines; they have only a database called skrot. So the program won't run. What are we supposed to do, put a dummy database on every customer's system, just so the stupid 4gl programs will start? That is an open invitation for trouble... jw