Summary:
See also: Variables, Records, Data Types.
Arrays can store a one-, two- or three-dimensional array of elements.
DEFINE variable
ARRAY [ size
[,size [,size]
] ] OF datatype
DEFINE
variable DYNAMIC
ARRAY [ WITH DIMENSION rank ] OF datatype
DEFINE variable
ARRAY [ ] OF datatype
| Object Methods | |
| Name | Description |
appendElement( ) |
Adds a new element at the end of a dynamic array. This method has no effect on a static array. |
clear( ) |
Removes all elements in a dynamic array. Sets all elements to NULL in a static array. |
deleteElement( INTEGER ) |
Removes an element at the given position. In a static or dynamic array, the elements after the given position are moved up. In a dynamic array, the number of elements is decremented by 1. |
getLength( )RETURNING INTEGER |
Returns the length of a one-dimensional array. |
insertElement( INTEGER ) |
Inserts a new element at the given position. In a static or dynamic array, the elements after the given position are moved down. In a dynamic array, the number of elements is incremented by 1. |
The Java Array type is an interface to a real Java array type, with the java array features. Java arrays must be instantiated before usage and have a fixed length.
| Class Methods | |
| Name | Description |
create(int size) |
Creates a new instance of a Java array with the given size. |
| Object Methods | |
| Name | Description |
getLength( )RETURNING INTEGER |
Returns the length of a one-dimensional array. |
By default, when an array index is out of range, fglrun raises error -1326. Note that this is only the case for static arrays: When using a dynamic array, new elements are allocated if the index is greater than the actual array size.
Raising an index out of bounds error is natural for static arrays. However, in some situations, legacy 4gl code must execute without error and evaluate expressions using indexes that are greater than the size of the array, especially with Boolean expressions in IF statements as in following example:
01IF index <= max_index OR arr[index] == some_value THEN02...03END IF
In the above example, since the 4GL language requires to evaluate all parts of a Boolean expression, the runtime system must get the value of the arr[index] element. This code was executing with Informix 4gl, but with the default Genero behavior, it will abort with error -1326 if the index is greater than the array size (i.e. max_index).
You can use an FGLPROFILE entry to control the behavior of the runtime system when an array index is out of bounds for a static array:
fglrun.arrayIgnoreRangeError = true
When the above FGLPROFILE entry is set to true, the runtime system will return the first element of the array if the index is <=0 or greater than the size of the array and continue with the normal program flow.
Unless legacy code is relying on this behavior, it is better to let the default get array out of bounds errors when the index is invalid.
Arrays can store a one-, two- or three-dimensional array of variables, all of the same type. These can be any of the supported data types or a record definition, but it cannot be another array (ARRAY .. OF ARRAY).
The first syntax (ARRAY[i[,j[,k]]]) defines traditional static arrays, which are defined with an explicit size for all dimensions. Static arrays have a size limit. The biggest static array size you can define is 65535.
A single array element can be referenced by specifying its coordinates in each dimension of the array.
Note that because of backward compatibility with Informix 4gl, all elements of static arrays are initialized, even if the array is not used. Therefore, it is not recommended that you define huge static arrays, as they can use a lot of memory.
The second syntax (DYNAMIC ARRAY) defines arrays with a variable size. Dynamic arrays have no theoretical size limit. The elements of dynamic arrays are allocated automatically by the runtime system, according to the indexes used.
01MAIN02DEFINE a1 ARRAY[100] OF INTEGER -- This is a static array03DEFINE a2 DYNAMIC ARRAY OF INTEGER -- This is a dynamic array04LET a1[50] = 1245605LET a2[5000] = 12456 -- Automatic allocation for element 500006LET a1[5000] = 12456 -- Runtime error!07END MAIN
The elements of an array variable can be of any data type except an array definition, but an element can be a record that contains an array member.
01MAIN02DEFINE arr ARRAY[50] OF RECORD03key INTEGER,04name CHAR(10),05address VARCHAR(200),06contacts ARRAY[50] OF VARCHAR(20)07END RECORD08LET arr[1].key = 1245609LET arr[1].name = "Scott"10LET arr[1].contacts[1] = "Bryan COX"11LET arr[1].contacts[2] = "Courtney FLOW"12END MAIN
Warning: When a dynamic array element does not exist, it is automatically allocated before it is used. For example, when you assign an array element with the LET instruction by specifying an array index greater as the current length of the array, the new element is created automatically before assigning the value. This is also true when using a dynamic array in a FOREACH loop or when dynamic array elements are used in r-values.
01MAIN02DEFINE a DYNAMIC ARRAY OF INTEGER03LET a[50] = 1245604DISPLAY a[100] -- Allocates new element and displays NULL05END MAIN
The compiler allows the .* notation to assign an array to another array with the same structure. Static array elements are copied by value (except objects and LOB members). However, the elements of dynamic arrays are copied by reference, even for simple data types. This means that after assigning a dynamic array with the .* notation, if you modify an element in one of the arrays, the change will be visible in the other array. You must pay attention to this behavior if you are used to the .* notation for simple records.
Note: When assigning a dynamic array with the .* notation, all elements are copied by reference:
01MAIN02DEFINE a1, a2 DYNAMIC ARRAY OF RECORD03key INTEGER04END RECORD05LET a1[1].key = 12306LET a2.* = a1.*07DISPLAY a2[1].key -- shows 12308LET a2[1].key = 45609DISPLAY a1[1].key -- shows 45610END MAIN
The dynamic array can be used as a function parameter (or returning element) and will be passed by reference (i.e. the dynamic array can be modified inside the called function, and the caller will see the modifications). You can pass a static array as an argument of a function, but this is not recommended as all array members will be copied on the stack. Note also that a static array cannot be returned from a function.
In the DEFINE section of a REPORT statement, formal arguments cannot be declared as arrays, nor as record variables that contain array members.
Arrays can be queried with the getLength() method, to get the number
of allocated elements:
01MAIN02DEFINE a DYNAMIC ARRAY OF INTEGER03LET a[5000] = 1245604DISPLAY a.getLength()05END MAIN
You can insert a new element at a given position with the insertElement()
method. The new element will be initialized to NULL. All subsequent elements are
moved down by an offset of +1. Dynamic arrays will grow by 1, while static
arrays will lose the last element:
01MAIN02DEFINE a DYNAMIC ARRAY OF INTEGER03LET a[10] = 1104CALL a.insertElement(10)05LET a[10] = 1006DISPLAY a.getLength() -- shows 1107DISPLAY a[10] -- shows 1008DISPLAY a[11] -- shows 1109END MAIN
You can append a new element at
the end of a dynamic array with the appendElement()
method. The new element will be initialized to NULL. Dynamic arrays will grow by 1, while static
arrays will not be affected by this method:
01MAIN02DEFINE a DYNAMIC ARRAY OF INTEGER03LET a[10] = 1004CALL a.appendElement()05LET a[a.getLength()] = a.getLength()06DISPLAY a.getLength() -- shows 1107DISPLAY a[10] -- shows 1008DISPLAY a[11] -- shows 1109END MAIN
The deleteElement() method can be used to remove elements from a
static or dynamic array. Subsequent elements are moved up by an offset of -1.
Dynamic arrays will shrink by 1, while static arrays will have NULLs in the last
element.
01MAIN02DEFINE a DYNAMIC ARRAY OF INTEGER03LET a[10] = 904CALL a.deleteElement(5)06DISPLAY a.getLength() -- shows 907DISPLAY a[9] -- shows 908END MAIN
You can clear an array with the clear()
method. When used on a static array, this method sets all elements to NULL. When
used on a dynamic array, it removes all elements:
01MAIN02DEFINE a DYNAMIC ARRAY OF INTEGER03LET a[10] = 1104DISPLAY a.getLength() -- shows 1005CALL a.clear()06DISPLAY a.getLength() -- shows 007END MAIN
When used as a function parameter, static arrays are passed by value, while dynamic arrays are passed by reference:
01MAIN02DEFINE a DYNAMIC ARRAY OF INTEGER03CALL fill(a)04DISPLAY a.getLength() -- shows 205END MAIN06FUNCTION fill(x)07DEFINE x DYNAMIC ARRAY OF INTEGER08CALL x.appendElement()09CALL x.appendElement()10END FUNCTION
Array methods can be used on two- and three-dimensional arrays with the brackets notation:
01MAIN02DEFINE a2 DYNAMIC ARRAY WITH DIMENSION 2 OF INTEGER03DEFINE a3 DYNAMIC ARRAY WITH DIMENSION 3 OF INTEGER04LET a2[50,100] = 1245605LET a2[51,1000] = 1245606DISPLAY a2.getLength() -- shows 5107DISPLAY a2[50].getLength() -- shows 10008DISPLAY a2[51].getLength() -- shows 100009LET a3[50,100,100] = 1245610LET a3[51,101,1000] = 1245611DISPLAY a3.getLength() -- shows 5112DISPLAY a3[50].getLength() -- shows 10013DISPLAY a3[51].getLength() -- shows 10114DISPLAY a3[50,100].getLength() -- shows 10015DISPLAY a3[51,101].getLength() -- shows 100016CALL a3[50].insertElement(10) -- inserts at 50,1017CALL a3[50,10].insertElement(1)-- inserts at 50,10,118END MAIN
01MAIN02DEFINE a1 DYNAMIC ARRAY OF INTEGER03DEFINE a2 DYNAMIC ARRAY WITH DIMENSION 2 OF INTEGER04DEFINE a3 ARRAY[10,20] OF RECORD05id INTEGER,06name VARCHAR(100),07birth DATE08END RECORD09LET a1[5000] = 1245610LET a2[5000,300] = 1245611LET a3[5,1].id = a1[50]12LET a3[5,1].name = 'Scott'13LET a3[5,1].birth = TODAY14END MAIN
01SCHEMA stores02MAIN03DEFINE a DYNAMIC ARRAY OF RECORD LIKE customer.*04DEFINE r RECORD LIKE customer.*05DATABASE stores06DECLARE c CURSOR FOR SELECT * FROM customer07FOREACH c INTO r.*08CALL a.appendElement()09LET a[a.getLength()].* = r.*10END FOREACH11DISPLAY "Rows found: ", a.getLength()12END MAIN