[comp.databases] Bizarre Informix 4gl 'database' statement

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