APPENDIX F How to interpret syscolumns (in 4GL)


Here's Jack Parker's routine - as used in his excellent dbdiff2 program:


GLOBALS

   DEFINE  datatype ARRAY[40] OF CHAR(20), # for coltype conversions
	   datetype ARRAY[16] OF CHAR(11)  # for coltype conversions

###########################################################################
# Convert coltype/length into an SQL descriptor string
###########################################################################
FUNCTION col_cnvrt(coltype, collength)

   DEFINE coltype, collength, NONULL SMALLINT,
	  SQL_strg CHAR(40),
	  tmp_strg CHAR(4)

   LET coltype = coltype + 1            # datatype[] is offset by one
   LET NONULL  = coltype/256            # if 256 then is NO NULLS
   LET coltype = coltype MOD 256        # lose the NO NULLS determinator

   LET SQL_strg = datatype[coltype]

   CASE coltype				# these types require special processing

       WHEN 1                           # char
          LET tmp_strg = collength using "<<<<"
          LET SQL_strg = SQL_strg clipped, " (", tmp_strg clipped, ")"

# SQL syntax supports float(n) - Informix ignores this
#      WHEN 4                           # float
#         LET SQL_strg = SQL_strg clipped, " (", ")"

       WHEN 6                           # decimal
          LET SQL_strg = SQL_strg clipped, " (", fix_nm(collength) clipped, ")"

# Syntax supports serial(starting_no) - starting_no is unavaliable
#      WHEN 7                           # serial
#         LET SQL_strg = SQL_strg clipped, " (", ")"

       WHEN 9                           # money
	  LET SQL_strg = SQL_strg clipped, " (", fix_nm(collength) clipped, ")"

       WHEN 11                          # datetime
	  LET SQL_strg = SQL_strg clipped, " (", fix_dt(collength) clipped, ")"

       WHEN 14                          # varchar
	  LET SQL_strg = SQL_strg clipped, " (", fix_nm(collength) clipped, ")"

       WHEN 15                          # interval
	  LET SQL_strg = SQL_strg clipped, " (", fix_dt(collength) clipped, ")"

   END CASE

   IF NONULL THEN
      LET SQL_strg = SQL_strg clipped, " NOT NULL"
   END IF

   RETURN SQL_strg

END FUNCTION

###########################################################################
# Turn collength into two numbers - return as string
###########################################################################
FUNCTION fix_nm(num)

DEFINE num integer,
       strg CHAR(8),
       i, j   SMALLINT,
       strg1, strg2 char(3)

   LET i = num / 256
   LET j = num MOD 256
   LET strg1 = i using "<<<"
   LET strg2 = j using "<<<"
   LET strg = strg1 clipped, ", ", strg2 clipped

   RETURN strg

END FUNCTION

###########################################################################
# Turn collength into meaningful date info - return as string
###########################################################################
FUNCTION fix_dt(num)

DEFINE num integer,
       i, j   SMALLINT,
       strg CHAR(20)

   LET i   = ((num mod 16) mod 12) + 1  # offset again
   LET j   = ((num / 16) mod 12) + 1    # offset again
   LET strg = datetype[j] clipped, " TO ", datetype[i] clipped

   RETURN strg

END FUNCTION

###########################################################################
# Array initialization
###########################################################################
   LET datatype[1]  = "CHAR"
   LET datatype[2]  = "SMALLINT"
   LET datatype[3]  = "INTEGER"
   LET datatype[4]  = "FLOAT"
   LET datatype[5]  = "SMALLFLOAT"
   LET datatype[6]  = "DECIMAL"
   LET datatype[7]  = "SERIAL"
   LET datatype[8]  = "DATE"
   LET datatype[9]  = "MONEY"
   LET datatype[10] = "UNKNOWN"
   LET datatype[11] = "DATETIME"
   LET datatype[12] = "BYTE"
   LET datatype[13] = "TEXT"
   LET datatype[14] = "VARCHAR"
   LET datatype[15] = "INTERVAL"
   LET datatype[16] = "UNKNOWN"         # little room for growth
   LET datatype[17] = "UNKNOWN"
   LET datatype[18] = "UNKNOWN"
   LET datatype[19] = "UNKNOWN"
   LET datatype[20] = "UNKNOWN"

   LET datetype[1] = "YEAR"
   LET datetype[3] = "MONTH"
   LET datetype[5] = "DAY"
   LET datetype[7] = "HOUR"
   LET datetype[9] = "MINUTE"
   LET datetype[11] = "SECOND"
   LET datetype[12] = "FRACTION(1)"
   LET datetype[13] = "FRACTION(2)"
   LET datetype[14] = "FRACTION(3)"
   LET datetype[15] = "FRACTION(4)"
   LET datetype[16] = "FRACTION(5)"