Was this helpful?
Variable Usage
C variables declared to EQUEL can substitute for most elements of EQUEL statements that are not keywords. Of course, the variable and its data type must make sense in the context of the element. The generic uses of host language variables in EQUEL statements are discussed in the QUEL Reference Guide. The following discussion covers only the usage issues particular to C language variable types.
You must verify that the statement using the variable is in the scope of the variable's declaration. As an example, the following retrieve statement uses the variables "namevar" and "numvar" to receive data, and the variable "idno" as an expression in the where clause:
## retrieve (namevar = employee.empname,
##           numvar = employee.empnum) where 
##           employee.empnum = idno
Simple Variables
The following syntax refers to a simple scalar-valued variable (integer, floating-point, or character string):
simplename
Syntax Notes:
If you use the variable to send values to Ingres, it can be any scalar-valued variable or ##define constant, enumerated variable, or enumerated literal.
If you use the variable to receive values from Ingres, it can only be a scalar-valued variable or enumerated variable.
Character strings that are declared as:
char *character_string_pointer;
or:
char character_string_buffer[];
are considered scalar-valued variables and should not include any indirection when referenced.
External compiled forms that are declared as:
Linux:
extern int *compiled_formname; 
should not include any indirection when referenced in the addform statement:
## addform compiled_formname;
The following example shows a message handling routine. It passes two scalar-valued variables as parameters: "buffer," a character string, and "seconds," an integer variable.
## Print_Message(buffer, seconds)
  ##        char *buffer
  ##        short seconds
  ## {
  ##        message buffer
  ##        sleep seconds
  ## }
Array Variables
The following syntax refers to an array variable:
arrayname [subscript{[subscript]}
Syntax Notes:
You must subscript the variable, because only scalar-valued elements (integers, floating-point, and character strings) are legal EQUEL values.
When the array is referenced, the EQUEL preprocessor notes the number of indices but does not evaluate the subscript values. Consequently, even though the preprocessor confirms that the correct number of array indirections is used, it accepts illegal subscript values. You must verify that the subscript is legal. For example, the preprocessor accepts both of the following references, even though only the first is correct:
## float salary_array[5];  /* declaration */
   salary_array[0]         /* references */
   salary_array[+-1-+]
A character string, declared as an array of characters, is not considered an array and cannot be subscripted in order to reference a single character. In fact, single characters are illegal string values, since all character string values must be null-terminated. For example, if the following variable were declared:
## static char abc[3] = {'a', 'b', 'c'};
you cannot access the character "a" in an EQUEL statement with the reference:
abc[0]
To perform such a task, declare the variable as an array of three single character strings:
## static char *abc[3] = {"a","b","c"};
Any variable that can be denoted with array subscripting can also be denoted with pointers. This is because the preprocessor only records the number of indirection levels used when referencing a variable. The indirection level is the sum of the number of pointer operators preceding the variable reference name and the number of array subscripts following the name. For example, if a variable is declared as an array:
## int age_set[2];
it can be referenced as either an array:
age_set[0]
or a pointer:
*age_set
If you use the pointer variant, you must verify that the pointer does not immediately follow a left parenthesis without a separating space, as "(*" is a reserved operator. For example:
## retrieve ( *age_set = e.age )
Note the space between the "(" and the "*".
In an EQUEL statement, do not precede references to elements of an array with the ampersand operator (&) to denote the address of the element.
Do not subscript arrays of variable addresses that are used with param target lists. For example:
##    char      target_list[200];
##    char      *addresses[10];

##    retrieve   (param(target_list, addresses))
For more information about parameterized target lists, see Dynamically Built Param Statements (see Dynamically Built Param Statements).
Pointer Variables
The following syntax refers to a pointer variable:
*{*}pointername
Syntax Notes:
Refer to the variable indirectly, because only scalar-valued elements (integers, floating-point and character strings) are legal QUEL values.
When the variable is declared, the preprocessor notes the number of preceding asterisks. Later references to the variable must have the same indirection level. The indirection level is the sum of the number of pointer operators (asterisks) preceding the variable declaration name and the number of array subscripts following the name.
A character string, declared as a pointer to a character, is not considered a pointer and cannot be subscripted in order to reference a single character. As with arrays, single characters are illegal string values, because any character string value must be null-terminated. For example, assuming the following declaration:
## char *abc = "abc";
you could not access the character "a" with the reference:
*abc
When you declare external compiled forms:
Linux:
extern int *compiled_formname; 
do not include any indirection when referenced in the addform statement.
As with standard C, any variable that you denote with pointer indirection can also be denoted with array subscripting. This is true because the preprocessor only records the number of indirection levels used when referencing a variable. For example, if a variable is declared as a pointer:
int *age_pointer;
it can be referenced as either a pointer:
*age_pointer;
or an array:
age_pointer[0];
If you use the pointer variant, you must verify that the pointer does not immediately follow a left parenthesis without a separating space, as "(*" is a reserved operator. For example:
##    retrieve   (*age_pointer = e.age )
Note the space between the "(" and the "*."
The following example uses a pointer to insert integer values into a database table:
##      int *numptr;
##      static int numarr[6] = {1, 2, 3, 4, 5, 0};

        for (numptr = numarr; *numptr; numptr++)
##            append items (number = *numptr)
For information on pointers to structures and members of structures, see Structure Variables (see Structure Variables).
Structure Variables
You cannot use a structure variable as a single entity. Only elementary structure members can communicate with Ingres data. This member must be a scalar value (integer, floating-point, or character string).
Using a Structure Member
The syntax EQUEL uses to refer to a structure member is the same as in C:
structure.member{.member}
Syntax Notes:
The structure member the above reference denotes must be a scalar value (integer, floating-point or character string). There can be any combination of arrays and structures, but the last object referenced must be a scalar value. Thus, the following references are all legal in an EQUEL statement, assuming they all translate to scalar values:
employee.sal   /* Structure member */
person[3].name /* Member of element of an array */
structure.mem2.mem3.age /* Deeply nested member */
The preprocessor does not check any array elements that are referred to in the structure reference and not at the very end of the reference. Consequently, both of the following references are accepted, even though one must be wrong, depending on whether "person" is an array:
person[1].age
person.age
Structure references can also include pointers to structures, denoted by the arrow operator (->). The preprocessor treats the arrow operator exactly like the dot operator and does not check to see that the arrow is used when referring to a structure pointer and that the dot is used when referring to a structure variable. For example, the preprocessor accepts both of the following references to a structure, although only the second one is legal C:
## struct
## {
## char *name;
## int  number;
## } people[10], *one_person;

people[i]->name /* Should use the dot operator */
one_person->name
/* Correct use of pointer qualifier   */
In general, the preprocessor supports unambiguous and direct references to structure members, as in the following example:
ptr1->struct2.mem3[ind4]->arr5[ind6][ind7]
In this case, the last object denoted, "arr5[ind6][ind7]," must specify a scalar-valued object.
References to structure variables cannot contain grouping parentheses. For example, assuming "struct1" was declared correctly, the following reference causes a syntax error on the left parenthesis:
(struct1.mem2)->num3
The only exception to this rule occurs when grouping a reference to the first and main member of a structure by starting the reference with a left parenthesis followed by an asterisk. Note that the two operators, "(" and "*" must be bound together without separating spaces, as in the following example:
(*ptr1)->mem2
Because "(" and "*" are reserved when not separated by spaces, you must make sure to use the pointer operator (*) correctly after parentheses when dereferencing simple pointers. For more information, see Pointer Variables.
Structures declared with the varchar storage class do not reference the structure members. For more information, see Using a Varying Length String Variable (Varchar).
Using an Enumerated Variable (Enum)
The syntax for referring to an enumerated variable or enumerated literal is the same as referring to a simple variable:
enum_name
Enumerated variables are treated as integer variables when referenced and can be used to retrieve data from and assign data to Ingres. The enumerated literals are treated as integer constants and follow the same rules as integer constants declared with the ##define statement. Enumerated variables can only be used to assign data to Ingres.
The following program fragment demonstrates a simple example of the enumerated type "color":
##  typedef enum {red, white, blue} color;

##  color col_var, *col_ptr;

##  static color col_arr[3] = {blue, white, red};

##  int i;

     /* Mapping from color to string */
     static char *col_to_str_arr[3] = 
       {"red","white","blue"};
#    define ctos(c) col_to_str_arr[(int)c];
     /* Fill rows with color array */
     for (i = 0; i < 3; i++)
##     append clr (num = i+1, color = col_arr[i])

     /*
     ** Retrieve the rows -demonstrating a color variable
     ** and pointer, and arithmetic on a stored color
     ** value. Results are:
     **     [1] blue, red
     **     [2] white, blue
     **     [3] red, white
     */
            col_ptr = &col_arr[0];
##          retrieve (i = clr.num, col_var = clr.color,
##          *col_ptr = clr.color+1)
##          {
               printf("[%d] %s, %s\n", i, ctos(col_var),
               ctos(*col_ptr%3));
##          }
Using a Varying Length String Variable (Varchar)
The syntax for referring to a varchar variable is the same as referring to a simple variable:
varchar_name
Syntax Notes:
When using a variable declared with the varchar storage class, you cannot reference the two members of the structure individually but only the structure as a whole. This rule differs from the rule that applies to regular structure member referencing. For example, the following declaration and retrieve statement are legal:
## varchar struct {
##       short        buf_size;
##       char        buf[100];
## } vch;

## retrieve (vch = objects.data)
But the following statement will generate an error on the use of the member "buf_size":
## retrieve (vch = objects.data
##       vch.buf_size = length(objects.data))
When you use the variable to retrieve Ingres data, the 2-byte length field is assigned the length of the data and the data is copied into the fixed length character array. The data is not null-terminated. You can use a varchar variable to retrieve data in the retrieve, retrieve cursor, inquire_ingres, getform, finalize, unloadtable, getrow, and inquire_frs statements.
When you use the variable to set Ingres data, the program must assign the length of the data (in the character array) to the 2-byte length field. You can use a varchar variable to set data in the append, replace, replace cursor, putform, initialize, loadtable, putrow, insertrow, and set_frs statements.
Using Indicator Variables
The syntax for referring to an indicator variable is the same as for a simple variable, except that an indicator variable is always associated with a host variable:
host_variable:indicator_variable
Syntax Note:
The indicator variable can be a simple variable, an array element or a structure member that yields a short integer. For example:
## short   ind_var, *ind_ptr, ind_arr[5];
      var_1:ind_var
      var_2:*ind_ptr
      var_3:ind_arr[2]
Last modified date: 08/14/2024