Back to Contents


ODI Adaptation Guide For Genero DB 3.4, 3.6

Runtime configuration

Install Genero DB and create a database
Prepare the runtime environment

Database concepts

Database concepts
Data consistency and concurrency management
Transactions handling
Avoiding long transactions
Defining database users
Setting privileges

Data dictionary

BOOLEAN data type
CHARACTER data types
NUMERIC data types
DATE and DATETIME data types
INTERVAL data type
SERIAL data type
ROWIDs
Very large data types
National character data types
The ALTER TABLE instruction
Triggers and Stored Procedures
Name resolution of SQL objects
Setup database statistics
Data type conversion table

Data manipulation

Reserved words
Outer joins
Transactions handling
Avoiding long transactions
Temporary tables
Substrings in SQL
Name resolution of SQL objects
String delimiters and object names
Getting one row with SELECT
MATCHES and LIKE conditions
SQL functions and constants
Querying system catalog tables
Syntax of UPDATE statements
The USER constant
The GROUP BY clause

BDL programming

SERIAL data type
IBM® Informix® specific SQL statements in BDL
INSERT cursors
Cursors WITH HOLD
SELECT FOR UPDATE
UPDATE/DELETE WHERE CURRENT OF <cursor>
The LOAD and UNLOAD instructions

Runtime configuration

Install Genero DB and create a database

  1. Install Genero DB on your computer.

    Tip: By default, Genero DB is configured to run alone on a networked machine, having client application hosted on other machines. If applications are co-located on the same machine as the the database server, you should change some configuration parameters: By default Genero DB uses nearly all the memory available on the computer. To share the memory with applications, you must change the MEMORY_OVERRIDE parameter in $ANTSHOME/Server/config.txt. Additionally, if you do not use a RAID 0, 1 or 5 drive for the transaction log, you should set the LOG_MODE server configuration parameter to ASYNCHRONOUS. You should also use the networking=IPC communication protocol in the data source definition, to get better performances. See database server documentation for more details.

    Warning: Genero DB by default relies on local-area-network multicast to enable clients and servers to find one another. If you have a firewall, you need to allow UDP connections on port 12345 for the address 255.0.0.37. If you want to disable multicast search: On the server side, set MULTICAST_ENABLED=FALSE in $ANTSHOME/Server/config.txt. On the client side, for Unix platforms, you must set overridebroadcast=yes in the ODBC data source definition. For Windows platforms, you need to check the "Override Multicast" option in the ODBC data source configuration (click the "Advanced" button, then click on "Connection Method" in the "Networking" section).

  2. Set up an ODBC data source, called mydb.

    Warning: After installing Genero DB, you should edit the data source and remove the default user and password entries, which are defined as the SYSTEM user. This will force client programs to specify a login and password. If you leave the default user and password entries, anyone can connect to the database as the SYSTEM super user.

  3. Create a database user dedicated to your application. You can use the antscmd tool.

           
    $ antscmd -d mydb -u SYSTEM -p SYSTEM

       mydb> CREATE USER appadmin IDENTIFIED BY "password"

    You must grant privileges to this user:

       mydb> GRANT CREATE TABLE TO appadmin
       mydb> GRANT CREATE VIEW TO appadmin

  4. Create the application tables.

    Do not forget to convert Informix data types to Genero DB data types. See issue ODIADS100 for more details.

    Check for reserved words in your table and column names.

Prepare the runtime environment

  1. If you want to connect to a remote Genero DB server from an application server, you must have ODBC properly configured on your application server.

  2. Verify if the ODBC environment is correct.

         $ antscmd -d dns-name -u appadmin -p password

  3. Verify the environment variable defining the search path for shared libraries. On UNIX platforms, the variable is specific to the operating system. For example, on Solaris and Linux systems, it is LD_LIBRARY_PATH.

  4. Set up the fglprofile entries for database connections to your data source.

  5. Create normal application users and define the schema to be used.

    With Genero DB, a schema is created when creating a user. If the APPADMIN user creates the tables, the schema for application tables will be "APPADMIN".

    In order to make application tables visible to normal DB users, you can specify a default schema for normal users, by adding the DEFAULT SCHEMA clause in CREATE USER:

       mydb>
    CREATE USER username IDENTIFIED BY password
                    DEFAULT SCHEMA appadmin;


    You can also use the following FGLPROFILE entry to make the database driver select a default schema after connection:

       dbi.database.dbname.
    ads.schema = "name"

    Here <dbname> identifies the database name used in the BDL program ( DATABASE dbname ) and <name> is the schema name to be used.

    If needed, database users can be authenticated as Operating System users. In order to create a DB user authenticated by the operating system, use the IDENTIFIED EXTERNALLY clause in CREATE USER:

       mydb>
    CREATE USER username IDENTIFIED EXTERNALLY;

    The OS users will be able to connect to the database if the $ANTSHOME/Server/.rhosts file contains an entry to identify the OS user. See the Genero DB documentation for more details.

    Warning: Pay attention to the user name, which is case-sensitive. You must specify the user name in double quotes; otherwise it defaults to uppercase letters.

  6. In order to connect to Genero DB, you must have a database driver "dbmads*" installed.

ODIADS001 - DATE and DATETIME data types

Informix provides two data types to store date and time information:

Genero DB provides four data types to store date and time information:

String representing date time information:

Informix is able to convert quoted strings to DATE / DATETIME data, if the string formatting matches the formatting set by environment parameters (i.e. DBDATE, GL_DATETIME).

Genero DB can also convert quoted strings to DATE / DATETIME, however note that the format for dates is 2005-01-30, not 30/01/2005. Review your code for handling of quoted dates.

Date arithmetic:

Solution:

The Genero DB DATE type is used for Informix DATE data. 

Informix DATETIME data with a precision from HOUR TO SECOND are stored in a Genero DB TIME column. DATETIME data with any other precision is stored in Genero DB TIMESTAMP columns. The database interface makes the conversion automatically. Missing date or time parts default to 1900-01-01 00:00:00. For example, when using a DATETIME HOUR TO MINUTE with the value of "11:45", the Genero DB DATETIME value will be "1900-01-01 11:45:00".

Warning: Using integers (number of days since 1899/12/31) as dates is supported by Genero DB in a SELECT INTO but not in a WHERE. Check your code to detect where you are using integers with DATE columns. Also note that SELECT TO_NUM('1900-01-01' AS INT)  will return 0 and not 1. (With Informix & Genero DB, a date of 1900/1/1 when selected into an INTEGER will return 1.)

Warning: Literal DATETIME expressions (i.e. DATETIME 1999-10-12 YEAR TO DAY) are not converted.

Warning: It is strongly recommended that you use BDL variables in dynamic SQL statements instead of quoted strings representing DATEs. For example:
   LET stmt = "SELECT ... FROM customer WHERE create_date >'", adate,"'"
is not portable.  Use a question mark place holder instead and OPEN the cursor by USING adate:
   LET stmt = "SELECT ... FROM customer WHERE create_date > ?"

Note: Most arithmetic expressions involving dates (for example, to add or remove a number of days from a date) will produce the same result with Genero DB.

Warning: DATE arithmetic expressions using SQL parameters (USING variables) are not fully supported. For example: "SELECT ... WHERE datecol < ? + 1" generates an error at PREPARE time.

Warning: SQL Statements using expressions with EXTEND must be reviewed and adapted to the native syntax.


ODIADS003 - Reserved words

SQL object names, like table and column names, cannot be SQL reserved words in Genero DB.

 An example of a common word which is part of the Genero DB SQL grammar is 'level'

Solution:

You must rename those table or column names which are Genero DB reserved words. Genero DB reserved keywords are listed in the Genero DB documentation. 


ODIADS004 - ROWIDs

Genero DB provides ROWIDs, but the data type is different. Informix ROWIDs are INTEGERs, while Genero DB ROWIDs are BIGINT.

Warning: Genero DB ROWIDs can be used to identify a unique row during the life time of the transaction. After the transaction is committed, the ROWID may change.

With Informix, SQLCA.SQLERRD[6] contains the ROWID of the last INSERTed or UPDATEd row. This is not currently supported with Genero DB.

Solution:

It is recommended to review code and remove usage of ROWIDs, as their use is not portable to other databases and may lead to problems running the code against any other databases. (For example, Oracle has ROWIDs, but they are CHARs and not numeric.)


ODIADS005 - SERIAL data type

Informix SERIAL data type and automatic number production:

Informix allows you to insert rows with a value different from zero for a serial column. Using an explicit value automatically increment the internal serial counter, to avoid conflicts with future INSERTs that are using a zero value:
    CREATE TABLE tab ( k SERIAL );  --> internal counter = 0
    INSERT INTO tab VALUES ( 0 );   --> internal counter = 1
    INSERT INTO tab VALUES ( 10 );  --> internal counter = 10
    INSERT INTO tab VALUES ( 0 );   --> internal counter = 11
    DELETE FROM tab;                --> internal counter = 11
    INSERT INTO tab VALUES ( 0 );   --> internal counter = 12

Genero DB supports SERIAL the same as Informix.

Solution:

When using Genero DB, the SERIAL data type works the same as Informix. After an insert, sqlca.sqlerrd[2] holds the last generated serial value.

CREATE [TEMP] TABLE with a SERIAL column works as Informix.


ODIADS006 - Outer joins

The Genero DB syntax for OUTER joins is different from Informix:

In Informix SQL, outer tables are defined in the FROM clause using the OUTER keyword:

SELECT ... FROM a, OUTER(b)
 WHERE a.key = b.akey
SELECT ... FROM a, OUTER(b,OUTER(c))
 WHERE a.key = b.akey
   AND b.key1 = c.bkey1
   AND b.key2 = c.bkey2 

Genero DB supports ANSI syntax joins.

SELECT ... FROM a, LEFT OUTER JOIN b ON a.key = b.key
SELECT ... FROM a 
    LEFT OUTER JOIN  b LEFT OUTER JOIN c
    ON ( (b.key1 = c.bkey1) AND (b.key2 = c.bkey2) ) ON ( (a.key = b.akey) )

Solution:

The Genero DB interface can convert most Informix OUTER specifications to Genero DB outer joins.

Prerequisites:

  1. In the FROM clause, the main table must be the first item and the outer tables must figure from left to right in the order of outer levels.
       Example which does not work: "FROM OUTER(tab2), tab1 ".
  2. The outer join in the WHERE part must use the table name as prefix.
       Example: "WHERE tab1.col1 = tab2.col2 ".

Restrictions:

  1. Statements composed by 2 or more SELECT instructions are not supported.
      Example: "SELECT ... UNION SELECT" or "SELECT ... WHERE col IN (SELECT...)"

Remarks:

  1. Table aliases are detected in OUTER expressions.
       OUTER example with table alias: "OUTER( tab1 alias1)".
  2. In the outer join, <outer table>.<col> can be placed on both right or left sides of the equal sign.
       OUTER join example with table on the left: "WHERE outertab.col1 = maintab.col2 ".
  3. Table names detection is not case-sensitive.
       Example: "SELECT ... FROM tab1, TAB2 WHERE tab1.col1 = tab2.col2".
  4. Temporary tables are supported in OUTER specifications.

ODIADS007a - Database concepts

Most of BDL applications use only one database instance (in the meaning of Informix). But Informix servers can handle multiple database instances, while Genero DB servers manage only one database instance. However, Genero DB can manage multiple schemas.

      SELECT * FROM stores.customer

Solution:

With Genero DB, you can create as many  users as database schemas are needed. You typically dedicate a database user to administer each occurrence of the application database (i.e. schema in Genero DB).

Any user can select the current database schema with the following SQL command:

      SET SCHEMA = "<schema>"

Using this instruction, any user can access the tables without giving the owner prefix, as long as the table owner has granted privileges required to access the tables.

Genero DB users can be associated to a default schema as follows:

      CREATE USER "<username>" IDENTIFIED ...
             DEFAULT SCHEMA
"<schema>"

This is the preferred way to assign a schema to DB users.

You can also make the database interface select the current schema automatically with the following FGLPROFILE entry:

       dbi.database.<dbname>.ads.schema = "<schema>"


ODIADS008a - Data consistency and concurrency management

Data consistency involves readers that want to access data currently being modified. Concurrency data access involves several writers accessing the same data for modification. Locking granularity defines the amount of data concerned when a lock is set (row, page, table, and other groupings).

Informix

Informix uses a locking mechanism to handle data consistency and concurrency. When a process changes database information with UPDATE, INSERT or DELETE, an exclusive lock is set on the touched rows. The lock remains active until the end of the transaction. Statements performed outside a transaction are treated as a transaction containing a single operation and therefore release the locks immediately after execution. SELECT statements can set shared locks according to the set isolation level. In case of locking conflicts (for example, when two processes want to acquire an exclusive lock on the same row for modification or when a writer is trying to modify data protected by a shared lock), the behavior of a process can be changed by setting the lock wait mode.

Control:

Defaults:

Genero DB

Genero DB does not use the same locking mechanism as Informix to handle concurrency, however it behaves the same way in terms of concurrency.

Informix-specific transaction control instructions have been implemented in Genero DB.

Solution:

You can use the same transaction control instructions and update clauses as Informix:

Warning: There is a little difference when using SET LOCK MODE TO WAIT n with Genero DB: WAIT n is the same as NOT WAIT.

Warning: The LOCK MODE {PAGE|ROW} is not provided by Genero DB. This is specific to data storage mechanisms and cannot be supported in the Genero DB concurrency model.


ODIADS008b - SELECT FOR UPDATE

Many BDL programs implement pessimistic locking in order to prevent several users editing the same rows at the same time.

  DECLARE cc CURSOR FOR
     SELECT ... FOR UPDATE [OF col-list]
  OPEN cc
  FETCH cc <-- lock is acquired
  CLOSE cc <-- lock is released

Genero DB allows individual and exclusive row locking with:

  SELECT ... FOR UPDATE

Genero DB locking granularity is at the row level.

To control the behavior of the program when locking rows, Informix provides a specific instruction to set the wait mode:

   SET LOCK MODE TO { WAIT | NOT WAIT | WAIT seconds }

The default mode is NOT WAIT. This is an Informix-specific SQL statement.

Solution:

Genero DB supports SELECT .. FOR UPDATE as Informix, but the rows are locked when the cursor is opened, not when the first row is fetched as Informix.

Ensure that the use of 'FOR UPDATE' is always inside a transaction.

Ensure that you COMMIT the transaction as soon as possible to prevent rows being locked longer than necessary.


ODIADS009a - Transactions handling

Informix and Genero DB handle transactions in a similar manner but with minor differences.

In both Informix and Genero DB, transactions must be started with BEGIN WORK and finished with COMMIT WORK or ROLLBACK WORK.

Statements executed outside of a transaction are automatically committed.

Warning: With Informix in native mode (non-ANSI), DDL statements can be executed (and cancelled) in transactions. Genero DB does not support DDL statements inside transactions.

Solution:

Regarding transaction control instructions, existing applications do not have to be modified in order to work with Genero DB.

Warning: You must extract the DDL statements from transaction blocks.

Transactions in stored procedures: avoid using transactions in stored procedures and allow the client applications to handle transactions, in accordance with the transaction model.

See also ODIADS008b


ODIADS009b - Avoiding long transactions

Some BDL applications do not care about long transactions because they use an Informix database without transaction logging (transactions are not stored in log files for potential rollbacks).

With Genero DB, using transactions is mandatory. Every database modification is stored in a log file.

BDL applications must be written to avoid long transactions when connected to a database with transaction logging enabled.

Solution:

You must review the program logic in order to avoid long transactions.


ODIADS010 - BOOLEAN data type

Informix provides the BOOLEAN data type, as a "Built-in Opaque Data Type". It is used to store boolean values. You can use the character literals 't' for true and 'f' for false.

Genero DB 3.4 does not have a BOOLEAN type.

Solution:

You must review the database creation scripts and the programs. Replace any BOOLEAN column by a CHAR(1).


ODIADS011a - CHARACTER data types

Informix provides the CHAR and VARCHAR data types to store characters. CHAR columns can store up to 32,767 characters; VARCHARs are limited to 255 characters. Starting with IDS 2000, Informix provides the LVARCHAR data type which is limited to 2K characters.

Genero DB provides the CHAR and VARCHAR data types. Both data types support a length of 60000 (or 3000 if the column is indexed). 

String comparison semantics are equivalent in Informix and Genero DB:

Solution:

The database interface supports character string variables in SQL statements for input (BDL USING) and output (BDL INTO).


ODIADS013 - Triggers and Stored Procedures

Genero DB supports the Informix trigger and stored procedure language.

See Genero DB documentation for more details.


ODIADS016a - Defining database users

Informix users are defined at the operating system level. They must be members of the 'Informix' group. The database administrator must grant CONNECT, RESOURCE or DBA privileges to those users.

Genero DB users must be registered in the database. They are created by the database administrator with the following command:
   CREATE USER <username> IDENTIFIED BY <pswd>
or for Operating System authentication:

   CREATE USER <username> IDENTIFIED EXTERNALLY

Note: For defining database users, there is a file in the <install directory of the database>/Server/.rhosts See the Genero DB documentation for more information.

Solution:

For migration and testing purposes only, you can specify the user name and password in the FGLPROFILE.

For a live system, it is recommended to use the CONNECT TO statement and supply the user name and password, or create database users IDENTIFIED EXTERNALLY. 


ODIADS016b - Setting privileges

Informix and Genero DB user privileges management are similar.

Genero DB provides roles to group privileges which then can be assigned to users. Starting with version 7.20, Informix also provides roles.

Informix users must have at least the CONNECT privilege to access the database:
    GRANT CONNECT TO (PUBLIC|user)

To be able to create tables, Genero DB users need:
    GRANT CREATE TABLE TO <user>

Warning: Informix database privileges do NOT correspond exactly to Genero DB CONNECT, RESOURCE and DBA roles. However, roles can be created with equivalent privileges.

Solution:

Check the Genero DB documentation for a full list of GRANT options available.


ODIADS017 - Temporary tables

Genero DB supports Informix temporary table creation statements:

  SELECT ... INTO TEMP tmpname
 
CREATE TEMP TABLE tmpname ( ... )

Solution:

Since Genero DB supports the same temporary table instructions as Informix, there is nothing to do.


ODIADS018 - Substrings in SQL

Informix SQL statements can use substrings on columns defined with the character data type:
    SELECT ... FROM tab1 WHERE col1[2,3] = 'RO'
    SELECT ... FROM tab1 WHERE col1[10]  = 'R'   -- Same as col1[10,10]
    UPDATE tab1 SET col1[2,3] = 'RO' WHERE ...
    SELECT ... FROM tab1 ORDER BY col1[1,3]

Genero DB provides the SUBSTRING( ) function, to extract a sub-string from a string expression:
 SELECT .... FROM tab1 WHERE SUBSTRIN
G(col1,2,2) = 'RO'
   
SELECT SUBSTRING('Some text' FROM 6 FOR 3)        -- Gives 'tex'

Solution:

The Genero DB Interface will convert SQL expressions containing Informix substring syntax for you. It is recommended, however, that you replace all Informix col[x,y] expressions by SUBSTRING(col FROM x FOR y-x+1).

Warning: In UPDATE instructions, setting column values using subscripts will produce an error with Genero DB:
    UPDATE tab1 SET col1[2,3] = 'RO' WHERE ...
is converted to:
    UPDATE tab1 SET SUBSTR
ING(col1 FROM 2 FOR 3-2+1) = 'RO' WHERE ...


ODIADS019 - Name resolution of SQL objects

Informix uses the following form to identify an SQL object:
  [database[@dbservername]:][{owner|"owner"}.]identifier

The ANSI convention is to use double-quotes for identifier delimiters (For example: "tabname"."colname").

Warning: When using double-quoted identifiers, both Informix and Genero DB become case sensitive. Unlike Informix, Genero DB object names are stored in UPPERCASE in system catalogs. That means that SELECT "col1" FROM "tab1" will produce an error because those objects are identified by "COL1" and "TAB1" in Genero DB system catalogs.

Remark: With Informix ANSI-compliant databases:

With Genero DB, an object name takes the following form:
   [(schema|"schema").](identifier|"identifier")

Object names are limited to 128 chars in Genero DB.

A Genero DB schema is owned by a user (usually the application administrator).

Solution:

Check that you do not use single or double quoted table names or column names in your source. Those quotes must be removed because the database interface automatically converts double quotes to single quotes, and Genero DB does not allow single quotes as database object name delimiters.

See also issue ODIADS007a


ODIADS020 - String delimiters and object names

The ANSI string delimiter character is the single quote ( 'string' ). Double quotes are used to delimit database object names ("object-name").

Example: WHERE "tabname"."colname" = 'a string value'

Informix allows double quotes as string delimiters, but Genero DB doesn't. This is an important distinction, as many BDL programs use double quotes to delimit the strings in SQL commands.

Remark: This problem concerns only double quotes within dynamic SQL statements. Double quotes used in pure BDL string expressions are not subject to SQL compatibility problems. Double quoted string literals in static SQL statements are converted to single quoted strings by compilers.

Genero DB implements ANSI-compliant SQL syntax and therefore does not support double quoted string literals, only database object names can be double quoted.

Solution:

The Genero DB interface can automatically replace all double quotes by single quotes.

Escaped string delimiters can be used inside strings like the following:

     'This is a single quote: '''
     'This is a single quote: \''
     "This is a double quote: """
     "This is a double quote: \""

Warning: Database object names cannot be delimited by double quotes, because the database interface cannot determine the difference between a database object name and a quoted string!

For example, if the program executes the SQL statement:
  
WHERE "tabname"."colname" = "a string value"
replacing all double quotes by single quotes would produce:
  
WHERE 'tabname'.'colname' = 'a string value'
This would produce an error since 'tabname'.'colname' is not allowed by Genero DB.

Although double quotes are replaced automatically in SQL statements, you should use only single quotes to enforce portability.


ODIADS021 - NUMERIC data types

Informix supports several data types to store numbers:

Informix data type Description
SMALLINT 16 bit integer  ( -2^15 to 2^15 )
INT/INTEGER 32 bit integer  ( -2^31 to 2^31 )
DEC/DECIMAL(p) Floating-point decimal number
DEC/DECIMAL(p,s) Fixed-point decimal number
MONEY Equivalent to DECIMAL(16,2)
MONEY(p) Equivalent to DECIMAL(p,2)
MONEY(p,s) Equivalent to DECIMAL(p,s)
REAL/SMALLFLOAT approximate floating point (C float)
DOUBLE PREC./FLOAT approximate floating point (C double)

Genero DB supports the following:

Genero DB data type Description
SMALLINT 16 bit integer
INT/INTEGER 32 bit integer
BIGINT 64 bit integer
DECIMAL(p,s) Fixed-point decimal number (p<=15)
MONEY Number with precision nearly 19 and scale 4
DOUBLE/REAL approximate floating point (C double)

Solution:

We recommend that you use the following conversion rules:

Informix data type Genero DB data type
DECIMAL(p,s), MONEY(p,s) DECIMAL(p,s)
DECIMAL(p) DOUBLE/REAL
SMALLINT SMALLINT
INTEGER INTEGER
SMALLFLOAT DOUBLE/REAL
FLOAT DOUBLE/REAL

Warning: Genero DB 3.4 DECIMAL can store up to 15 digits, while Informix DECIMAL can store 32. A future version of Genero DB will support DECIMAL(p<=32,s).


ODIADS022 - Getting one row with SELECT

With Informix, you must use the system table with a condition on the table id:

  SELECT user FROM systables WHERE tabid=1

With Genero DB some statements can be just done like this:

  PREPARE pre FROM "SELECT USER"
  EXECUTE pre INTO l_user

Solution:

Check the BDL sources for "FROM systables WHERE tabid=1" and use dynamic SQL to resolve this problem.


ODIADS024 - MATCHES and LIKE in SQL conditions

Informix and Genero DB both support MATCHES and LIKE in SQL statements.

MATCHES allows you to use brackets to specify a set of matching characters at a given position:
   ( col MATCHES '[Pp]aris' )
   ( col MATCHES '[0-9][a-z]*' )

In this case, the LIKE statement has no equivalent feature.

Genero DB implements the MATCHES operator.

Solution:

None required.


ODIADS025 - Informix specific SQL statements in BDL

The BDL compiler supports several Informix-specific SQL statements that have no meaning when using Genero DB:

Solution:

Review your BDL source and remove all static SQL statements which are Informix-specific SQL statements.


ODIADS028 - INSERT cursors

Informix supports insert cursors. An "insert cursor" is a special BDL cursor declared with an INSERT statement instead of a SELECT statement. When this kind of cursor is open, you can use the PUT instruction to add rows and the FLUSH instruction to insert the records into the database.

For Informix database with transactions, OPEN, PUT and FLUSH instructions must be executed within a transaction.

Genero DB does not support insert cursors.

Solution:

Insert cursors are emulated by the Genero DB interface.


ODIADS029 - SQL functions and constants

Almost all Informix functions and SQL constants have a different name or behavior in Genero DB.

Here is a comparison list of functions and constant:

Informix Genero DB
today current_date
current year to second current_timestamp
day( value ) dayofmonth(d '2002-12-31')
extend( dtvalue, first to last )
mdy(m,d,y)
month( date ) month( date )
weekday( date ) dayofweek( date '2002-12-31')
year( date ) year( date )
date( "string" | integer ) No equivalent - Depends from DBDATE in IFX
user user ! Uppercase/lowercase: See ODIADS047
trim( [leading | trailing | both "char" FROM] "string") trim( [ [leading | trailing | both] [ pad_character ] from ] string )
length( c ) length( c )
pow(x,y) pow(x,y)

Solution:

Warning: You must review the SQL statements using TODAY / CURRENT / EXTEND expressions.


ODIADS030 - Very large data types

Informix uses the TEXT and BYTE data types to store very large texts or images. Genero DB 8 provides CLOB, BLOB, and BFILE data types. Columns of these types store a kind of pointer ( lob locator ). This technique allows you to use more than one CLOB / BLOB / BFILE column per table.

Solution:

Warning: TEXT & BYTE are not currently supported.


ODIADS031 - Cursors WITH HOLD

Informix closes opened cursors automatically when a transaction ends unless the WITH HOLD option is used in the DECLARE instruction. 

By default Genero DB keeps cursors open when a transaction ends (however, FOR UPDATE locks are released at the end of a transaction).

Solution:

BDL cursors are automatically closed when a COMMIT WORK or ROLLBACK WORK is performed.

WITH HOLD cursors with a SELECT FOR UPDATE can be supported, if the table has a primary key or a unique index.


ODIADS032 - UPDATE/DELETE WHERE CURRENT OF <cursor>

Informix allows positioned UPDATEs and DELETEs with the "WHERE CURRENT OF <cursor>" clause, if the cursor has been DECLARED with a SELECT ... FOR UPDATE statement.

Warning: UPDATE/DELETE ... WHERE CURRENT OF <cursor> is support by the Genero DB API. However, the cursor must be OPENed and used inside a transaction. 

DECLARE cur1 CURSOR FOR SELECT * FROM mytable WHERE 1=1 FOR UPDATE
BEGIN WORK
OPEN cur1
FETCH cur1 INTO x,chr
UPDATE mytable SET mycol2 = "updated" WHERE CURRENT OF cur1
CLOSE cur1
COMMIT WORK

Solution:

Check that you programs correctly put WHERE CURRENT OF <cursorname> inside a transaction.


ODIADS033 - Querying system catalog tables

Both Informix and Genero DB provides system catalog tables, however the table names and structure are different.

Genero DB provides the standard views for system catalog: TABLE_OF_TABLES, TABLE_OF_COLUMNS, and so on.

Solution:

Warning: No automatic conversion of Informix system tables is provided by the database interface.


ODIADS034 - Syntax of UPDATE statements

Informix allows a specific syntax for UPDATE statements:

    UPDATE table SET ( <col-list> ) = ( <val-list> )

Genero DB supports this syntax.

BDL programs can hold the following kind of statements:

    UPDATE table SET table.* = myrecord.*
    UPDATE table SET * = myrecord.*

Solution:

Static UPDATE statements using the above syntax are converted by the compiler to the standard form:

    UPDATE table SET column=value [,...]


ODIADS036 - INTERVAL data type

Informix's INTERVAL data type stores a value that represents a span of time. INTERVAL types are divided into two classes: year-month intervals and day-time intervals.

Genero DB does not provide a data type similar to Informix INTERVAL.

Solution:

It is not recommended that you use the INTERVAL data type because Genero DB has no equivalent native data type. This would cause problems when doing INTERVAL arithmetic on the database server side. However, INTERVAL values can be stored in CHAR columns.

Remark: Genero DB will support INTERVALs in a future version.


ODIADS040 - National characters data types

Informix: NCHAR & NVARCHAR
Genero DB:
Has no solution at this time.

Solution:

Warning: National character data types are not supported yet.


ODIADS046 - The LOAD and UNLOAD instructions

Informix provides SQL instructions to export data from a database table and import data into a database table: The UNLOAD instruction copies rows from a database table into a text file; the LOAD instructions insert rows from a text file into a database table.

Genero DB does not provide LOAD and UNLOAD instructions.

Solution:

In 4gl programs, the LOAD and UNLOAD instructions are supported with Genero DB, with some limitations:

Warning: There is a difference when using Genero DB DATETIME columns.  DATETIME columns created in Genero DB are equivalent to Informix DATETIME YEAR TO SECOND columns.  In LOAD and UNLOAD, all Genero DB DATE columns are treated as Informix DATETIME YEAR TO SECOND columns and thus will be unloaded with the "YYYY-MM-DD hh:mm:ss"  format.

Warning: When using an Informix database, simple dates are unloaded using the DBDATE format (ex: "23/12/1998"). As a result, unloading from an Informix database for loading into an Genero DB is not supported.


ODIADS047 - The USER constant

Both Informix and Genero DB provide the USER constant, which identifies the current user connected to the database server.

Example:

Informix: SELECT USER FROM systables WHERE tabid=1
Genero DB:
SELECT USER

However, there is a difference:

  • Informix returns the user identifier as defined in the operating system, where it can be case sensitive (UNIX) or not (NT).
  • Genero DB returns the user identifier which is stored in the database. By default, Genero DB converts the user name to uppercase letters if you do not put the user name in double quotes when creating it.

This is important if your application stores user names in database records (for example, to audit data modifications). You can, for example, connect to Genero DB with the name 'scott', and perform the following SQL operations:
     (1) INSERT INTO mytab ( creator, comment )
              VALUES ( USER, 'example' );
     (2) SELECT * FROM mytab
               WHERE creator = '
scott';
The first command inserts 'SCOTT' (in uppercase letters) in the author column. The second statement will not find the row.

Solution:

When creating a user in Genero DB, you can put double quotes around the user name in order to force Genero DB to store the given user identifier as is:

CREATE USER "scott" IDENTIFIED BY <pswd>

To verify the user names defined in Genero DB, connect as SYSTEM and list the records of the ALL_USERS table as follows:

    CREATE USER john IDENTIFIED BY <pswd>

    SELECT user_name FROM table_of_users

    USER_NAME                    
    -----------
    SYSTEM
    JOHN
    scott


ODIADS051 - Setup database statistics

Informix provides a special instruction to compute database statistics in order to help the optimizer determine the best query execution plan:

UPDATE STATISTICS ...

Genero DB doesn't have an equivalent statement.

See Genero DB documentation for more details.

Solution:

Centralize the optimization instruction in a function. See the ODILIB.BDL source as example.


ODIADS052 - The GROUP BY clause

Informix allows you to use column numbers in the GROUP BY clause

     SELECT ord_date, sum(ord_amount) FROM order GROUP BY 1

Genero DB does not support column numbers in the GROUP BY clause.

Solution:

Use column names instead:

     SELECT ord_date, sum(ord_amount) FROM order GROUP BY ord_date


ODIADS053 - The ALTER TABLE instruction

Informix and Genero DB have different implementations of the ALTER TABLE instruction. For example, Informix allows you to use multiple ADD clauses separated by commas; this is not supported by Genero DB:

Informix:
     ALTER TABLE customer ADD(col1 INTEGER), ADD(col2 CHAR(20))

Genero DB:
     ALTER TABLE customer ADD
COLUMN col1 INTEGER ADD COLUMN col2 CHAR(20)

Solution:

Warning: No automatic conversion is done by the database interface. There is no real standard for this instruction ( that is, no common syntax for all database servers). Read the SQL documentation and review the SQL scripts or the BDL programs in order to use the database server specific syntax for ALTER TABLE.


ODIADS100 - Data type conversion table

Informix Data Types Genero DB Data Types
CHAR(n) CHAR(n)
VARCHAR(n) VARCHAR(n)
INTEGER INTEGER
SMALLINT SMALLINT
SERIAL SERIAL
SERIAL8 SERIAL8
FLOAT[(n)] DOUBLE / REAL
SMALLFLOAT DOUBLE / REAL
DECIMAL(p,s) DECIMAL(p,s) ! p<=15
DECIMAL(p) DOUBLE / REAL
MONEY(p,s) DECIMAL(p,s) ! p<=15
TEXT TEXT
BYTE BYTE
DATE DATE
DATETIME x TO y (not HOUR TO SECOND) TIMESTAMP
DATETIME HOUR TO SECOND TIME
INTERVAL x TO y CHAR(50)