7. Embedded SQL for Pascal : Dynamic Programming for Pascal : SQLVAR Array Usage : Pointer Usage with Pascal Variables
 
Share this page                  
Pointer Usage with Pascal Variables
In order to fill an element of the sqlvar array, you must set the type information and assign a valid address to sqldata. The address must be that of a legal variable address. If the element is nullable, the corresponding sqlind component must point at a legally declared null indicator.
Because both the sqldata and sqlind components of the IISQLDA record are declared as integers, you must assign integer values to them. This requires the use of the built-in iaddress function (as shown in Appendices E and F), or other pointer and address operations. The Pascal compiler requires you to declare the target variables with the volatile attribute in order to use the iaddress and address functions.
For example, the following fragment sets the type information of and points at a 4-byte integer variable, an 8-byte nullable floating-point variable, and an sqllen-specified character substring. This example demonstrates how a program can maintain a pool of available variables, such as large arrays of the few different typed variables, and a large string space. The next available spot is chosen from the pool, as in the following example:
{
| Assume sqlda has been declared, as well as
| the following VOLATILE numeric arrays and
| large array of characters: int4_store,
| float8_store, indicator_store, char_store
}

sqlda.sqlvar[1].sqltype     := IISQ_INT_TYPE;     { 4-byte integer }
sqlda.sqlvar[1].sqllen      := 4;
sqlda.sqlvar[1].sqldata     := iaddress(int4_store[current_int]);
sqlda.sqlvar[1].sqlind      := 0;
current_int := current_int + 1; { Update integer pool }

sqlda.sqlvar[2].sqltype     := -IISQ_FLT_TYPE;    { 8-byte nullable float }
sqlda.sqlvar[2].sqllen      := 8;
sqlda.sqlvar[2].sqldata     :=iaddress
                        (float8_store[current_float]);
sqlda.sqlvar[2].sqlind
                            := iaddress(indicator_store[current_ind]);
current_float               := current_float + 1; { Update float and }
current_ind := current_ind + 1; { indicator pool }

{
| SQLLEN has been assigned by DESCRIBE to be the length of a specific result
| column. This length is used to pick off a substring from a large string space.
}
needlen                     := sqlda.sqlvar[3].sqllen;
sqlda.sqlvar[3].sqltype     := IISQ_CHA_TYPE;
sqlda.sqlvar[3].sqldata
                            := iaddress(char_store[current_char]);
sqlda.sqlvar[3].sqlind      := 0;
current_char := current_char + needlen;         { Update char pool }
Of course, in the above example, verification of enough pool storage must be made before referencing each cell of the different arrays in order to prevent sqldata and sqlind from pointing at undefined storage. Appendices E and F demonstrate this method.
The IISQ_HDLR_TYPE is a host language type that is used for transmitting data to and from Ingres. Because it is not an Ingres data type, it will never be returned as a data type from the describe statement.
If you code your own SQLDA, and, in place of sqldata, you declare a variant record of pointers to a subset of different data types, you may find that you can use dynamic allocation routines and simple pointer assignments. For example, you can declare a type:
type
        Data_Pointer = record
                case Integer of
                IISQ_INT_TYPE: (int_ptr: ^Integer);
                IISQ_FLT_TYPE: (flt_ptr: ^Double);
                IISQ_CHA_TYPE: (str_ptr: ^Char);
         end;
and use this type instead of the sqldata component. If you confirm that the layout of the variant record of different pointers is the same as that of a 4-byte integer (sqldata), then you may use this method. This approach is not discussed further in this manual.