Declaration Syntax
This section describes the syntax for variable, type, and constant declarations. It also describes how to declare labels.
Attributes
In type definitions, Embedded SQL allows VMS Pascal attributes both at the beginning of the definition and just before the type name. The only attributes the preprocessor recognizes in type definitions are byte, word, and long. The preprocessor ignores any optional storage unit constant "(n)" appearing with the attribute. The preprocessor also ignores all other attributes, although it allows them.
The following example shows how to use the byte attribute in order to convert a 4-byte integer subrange into a 1-byte variable.
exec sql begin declare section;
var
v_i1 : [byte] -128..127;
exec sql end declare section;
Note that Pascal requires that a size attribute be at least as large as the size of its type. Therefore, the following declaration would be illegal, because 400 will not fit into one byte:
exec sql begin declare section;
var
v_i1 : [byte] 0..400;
exec sql end declare section;
Embedded SQL/Pascal does not allow explicit attribute size conflicts, as, for example:
exec sql begin declare section;
type
i1 = [byte] -128..127; {i1 is a 1-byte integer type}
var
v_i2 : [word] i1; {i1 cannot be extended to 2 bytes}
exec sql end declare section;
Label Declarations
An Embedded SQL block-structured statement is a statement delimited by the begin and end clauses. The select loop and the forms statements display, unloadtable, submenu, formdata, and tabledata are examples of these block-structured statements. All these statements generate Pascal labels in order to handle the complex control flow implicit in the statement.
Because Pascal requires that all labels be declared before their use, Embedded SQL/Pascal requires that you issue an exec sql label statement in the Pascal declaration section of every routine (program, procedure, or function) that issues one of these statements. You must also end the routine with the Embedded SQL exec sql end statement, rather than the Pascal end statement, so that the preprocessor will know the scope of the label declaration.
The syntax for a label declaration is:
exec sql label [label_name {, label_name}];
...
exec sql end ; | .
Note:
1. You can use exec frs and exec sql interchangeably with the Embedded SQL label and end statements.
2. The preprocessor ignores label_names, except that they will appear in the generated Pascal label statement.
3. The terminating semicolon of the Embedded SQL label statement is required, even if there are no label_names.
4. Only one Embedded SQL label statement can occur in each routine.
5. Each Embedded SQL label statement must have a matching Embedded SQL end statement. This exec sql end statement replaces the Pascal end statement and can be terminated with a semicolon or a period.
6. The label statement must appear in a Pascal declaration section, and not in an Embedded SQL declare section.
The following example illustrates the use of label declarations:
procedure Unload_Table;
exec frs label; {Must include this statement or exec sql
label,because unloadtable uses labels}
exec sql begin declare section;
var
age : integer;
exec sql end declare section;
begin {unload_table}
exec frs unloadtable 'form' 'table' (:age = emp_age);
exec frs begin;
...
exec frs end;
exec frs end; {Unload_Table}
Constant Declarations
The syntax for a constant declaration is:
const constant_name = constant_expr;
{constant_name = constant_expr;}
where a constant_expr is one of the following:
[+|-] constant_number
[+|-] constant_name
string_constant
Constants can be used to set Ingres values but cannot be assigned values from Ingres.
Note:
1. A constant_name must be a legal Pascal identifier beginning with an underscore or alphabetic character.
2. A constant_number can be either an integer or real number.
3. A variable or type name must begin with an alphabetic character, which can be followed by alphanumeric characters or underscores.
4. Embedded SQL/Pascal recognizes only single, and not double or quadruple, exponential notation for constants of type real.
5. The type of a constant_name is determined from the type of its constant_expr.
6. If a "+" or a "-" precedes a constant_name that is used as a constant_expr, the constant_name must be numeric.
7. Embedded SQL/Pascal does not support the declaration of arbitrary constant expressions.
The following example illustrates the use of constants declarations:
exec sql begin declare section;
const
min_sal = 15000.00; {Real}
pi = 3.14159; {Real}
max_emps = +99; {Integer}
max_credit = 100000.00; {Real}
max_debt = -max_credit; {Real}
yes = 'y'; {Char}
exec sql end declare section;
Type Declarations
An Embedded SQL/Pascal type declaration has the following syntax:
type type_name = type_definition;
{type_name = type_definition;}
where type_definition is any of the following:
Each of these type definitions is discussed in its own section below. All type names must be legal Pascal identifiers beginning with an alphabetic or underscore character.
Rename Type Definitions
The declaration for the renaming of a type uses the following syntax:
type new_type_name = type_name;
Note:
1. The type_name must be either an Embedded SQL/Pascal type or a type name already declared to Embedded SQL (such as Integer or Real).
2. The new_type_name cannot be Integer, Real or Char or any other type listed at the beginning of this section.
The following example illustrates how to use this declaration:
exec sql begin declare section;
type
NaturalInt = Integer; {A "natural" sized integer}
exec sql end declare section;
Enumeration Type Definitions
The declaration for an enumeration type definition has the following syntax:
type type_name = ( enum_identifier {, enum_identifier} );
Note:
1. An enum_identifier must be a legal Pascal identifier beginning with an alphabetic or underscore character.
2. The enum_identifiers are treated as 4-byte integer constant identifiers.
3. The type_name maps to a 1-byte integer if there are fewer than 257 enumerated identifiers. Otherwise, it maps to a 2-byte integer.
4. When using an enumerated identifier as a value in an Embedded SQL statement, only the ordinal position of the identifier in the original enumerated list is important. In assigning a value to a variable of enumeration type, Embedded SQL passes the variable by address and assumes that the value is a legal one for the variable.
The following example illustrates the use of this declaration:
exec sql begin declare section;
type
Table_Field_States =
(undefined, newrow, unchanged, changed, deleted);
exec sql end declare section;
Subrange Type Definitions
The syntax for declaring a subrange type definition is either:
type type_name = [+|-]integer_const .. [+|-]integer_const;
or
type type_name = string_const .. string_const;
Note:
1. An integer_const can be either an integer literal or a named integer constant.
2. A string_const must be either a string literal or the name of a string constant. Although the preprocessor accepts any length string constant, the compiler requires the constant to be a single character.
The following example illustrates the use of this declaration:
exec sql begin declare section;
type
alpha = 'a' .. 'z';
months = 1 .. 12;
minmax = -value .. value; {"value" is an integer constant}
updated_states = changed .. deleted; {from previous example}
exec sql end declare section;
Pointer Type Definitions
The declaration for a pointer type definition has the following syntax:
type pointer_name = ^type_name;
Note:
The type_name can be either a previously defined type, or a type not yet defined. If the type has not yet been defined, the pointer type definition is a forward pointer definition. In that case, Embedded SQL requires that you define the type_name before using a variable of type pointer_name in an Embedded SQL statement.
The following example illustrates the use of this declaration:
exec sql begin declare section;
type
empptr = ^emprecord; {forward pointer declaration}
emprecord = record
e_name : varying[40] of char;
e_salary : real;
e_id : integer;
e_next : empptr;
end;
var
empnode = empptr;
exec sql end declare section;
...
exec sql select name, salary, id
into :empnode^.e_name,
:empnode^.e_salary,
:empnode^.e_id
from emp;
Varying Length String Type Definition
The declaration for a varying length string type definition has the following syntax:
type varying_type_name = varying [upper_bound] of
char_type_name;
Note:
1. The upper_bound of a varying array specification is not parsed by the Embedded SQL preprocessor. Consequently, an illegal upper bound (such as a non-numeric expression) will be accepted by the preprocessor but will later cause Pascal compiler errors. For example, both of the following type declarations are accepted, even though only the first is legal in Pascal:
exec sql begin declare section;
type
string20 = varying[20] of char;
what = varying['upperbound'] of char;
exec sql end declare section;
2. Embedded SQL/Pascal treats a variable of type varying of char as a string, not an array.
The following example illustrates the use of this declaration:
exec sql begin declare section;
type
pname = varying[100] of char;
var
user_name : pname;
exec sql end declare section;
...
exec sql insert into person (name)
values (:user_name);
Array Type Definition
The declaration for an array type definition has the following syntax:
type type_name = [packed] array [dimensions] of type_definition;
Note:
1. The dimensions of an array specification are not parsed by the Embedded SQL preprocessor. Consequently, an illegal dimension (such as a non-numeric expression) will be accepted by the preprocessor but will later cause Pascal compiler errors. For example, both of the type declarations shown below are accepted, even though only the first is legal in Pascal.
exec sql begin declare section;
type
square = array[1..10, 1..10] of integer;
what = array['dimensions'] of real;
exec sql end declare section;
The preprocessor only verifies that an array variable is followed by brackets when used (except packed array of char--see below).
2. ESQL/Pascal treats a variable of type packed array of char as a string, not an array. Thus, it is not followed by brackets when used.
3. Components of a packed array cannot be passed to the Embedded SQL runtime routines. Therefore, you should not declare packed arrays to Embedded SQL, except for packed arrays of char, which are passed as a whole (for example, as character strings).
The following example illustrates the use of the array type definition:
exec sql begin declare section;
type
ssid = packed array [1..9] of char;
var
user_ssid : ssid;
exec sql end declare section;
...
exec sql insert into person (ssno)
values (:user_ssid);
Record Type Definitions
The declaration for a record type definition has the following syntax:
type record_type_name =
record
field_list [;]
end;
where field_list is:
field_element {; field_element}
[case [tag_name :] type_name of
[case_element {; case_element}]
[otherwise ( field_list )]]
where field_element is:
field_name {, field_name} : type_definition
and case_element is:
case_label {, case_label} : ( field_list )
Note:
1. All clauses of a record component have the same rules and restrictions as they do in a regular type declaration. For example, as with regular declarations, the preprocessor does not check dimensions for correctness.
2. In the case list, the case_labels can be numbers or names. Embedded SQL need not know the names.
3. ESQL/Pascal record declarations must be entirely contained in a declaration section; consequently all of the record components will be declared to the preprocessor. To minimize the effect of this restriction, the types quadruple and set of are allowed as legal types in an Embedded SQL record declaration. It is, however, an error to use variables of those types in Embedded SQL statements.
4. Components of a packed record cannot be passed to the runtime ESQL routines. Thus, do not declare packed records to ESQL.
The following example illustrates the use of the record type definition:
exec sql begin declare section;
type
addressrec = record
street: packed array[1..30] of char;
town: packed array[1..10] of char;
zip: 1 .. 9999;
end;
employeerec = record
name: packed array[1..20] of char;
age: [byte] 0 .. 128;
salary: real;
address: addressrec;
checked: boolean;
scale: Quadruple; {Cannot be used
by Embedded SQL}
end;
exec sql end declare section;
File Type Definitions
The declaration for a file type definition, has the following syntax:
type type_name = file of type_definition;
Note:
1. A variable of type file can only be used with Embedded SQL through the file buffer. A file buffer for a given type_definition is referenced in the same manner as a pointer to the same type.
2. Components of a packed file cannot be passed to the Embedded SQL runtime routines. Do not declare packed files to ESQL.
The following example illustrates the use of the file type definition:
exec sql begin declare section;
var
myfile : file of integer;
exec sql end declare section;
...
get (myfile);
exec sql insert into emp (floor)
values (:myfile^);
...
exec sql select floor
into :myfile^;
from emp;
put (myfile);
Set Type Definitions
The declaration for a set type definition has the following syntax:
type type_name = set of type_definition;
Although the preprocessor accepts set definitions, no set variables can be used in Embedded SQL statements. As stated in the section on record declarations, set declarations are accepted only because all record components must be declared to Embedded SQL.
Variable Declarations
An Embedded SQL/Pascal variable declaration has the following syntax:
var var_name {, var_name} : type_definition [:= initial_value];
{var_name {, var_name} : type_definition [:= initial_value];}
Note:
1. See the previous sections for information on the type_definition.
2. The initial_value is not parsed by the preprocessor. Consequently, any initial value is accepted, even if it may later cause a Pascal compiler error. Furthermore, the preprocessor accepts an initial value with any variable declaration, even where not allowed by the compiler. For example, both of the following initializations are accepted, even though only the first is legal in Pascal:
exec sql begin declare section;
var
rowcount: integer := 1;
msgbuf: packed array[1..100] of char := 2;
exec sql end declare section;
The following example illustrates the use of variable declarations:
exec sql begin declare section;
var
rows, records: 0..500 := 0;
was_error: boolean;
msgbuf: varying[100] of char := ' ';
operators: array[1..6] of packed array[1..2] :=
('= ', '!=', '< ', '> ', '<=', '>=');
employees: array[1..100] of employeerec;
emp_ptr: ^employeerec;
work_days: (mon, tue, wed, thu, fri);
day_name: varying[8] of char;
random_ints: file of integer;
ind_set: array[1...10] of indicator;
exec sql end declare section;
Formal Parameter Declarations
Most VAX/VMS Pascal formal parameter declarations are acceptable to Embedded SQL.
An Embedded SQL/Pascal formal parameter declaration has the following syntax:
formal_param_section {; formal_param_section}
where formal_param_section is:
formal_var | formal_routine [:= [%mechanism] default_value]
A formal_var has the syntax:
[var | %mechanism] identifier {, identifier} : typename_or_schema
where typename_or_schema is one of the following:
type_name
varying [upper_bound_identifier] of type_name
packed array [schema_dimensions] of typename_or_schema
array [schema_dimensions {; schema_dimensions}] of
typename_or_schema
where schema_dimensions is:
lower_bound_identifier .. upper_bound_identifier : scalar_type_name
A formal_routine has the syntax:
[%mechanism] routine_header
where routine_header is one of the following:
procedure proc_name ( [formal_parameter_declaration] )
function func_name ( [formal_parameter_declaration] )
:return_type_name
In a subprogram declaration, the syntax of a formal parameter declaration is:
procedure proc_name
exec sql begin declare section;
( formal_parameter_declaration )
exec sql end declare section;
;
...
or:
function func_name
exec sql begin declare section;
( formal_parameter_declaration )
exec sql end declare section;
: return_type_name;
...
Note:
1. The Embedded SQL preprocessor ignores the names of procedures and functions used as formal parameters, but checks their formal parameters for legality.
2. The default_value is not parsed by the preprocessor. Consequently, any default value is accepted, even if it may later cause a Pascal compiler error. For example, both of the parameter default values shown below are accepted, even though only the first is legal in Pascal:
procedure Load_table
exec sql begin declare section;
(clear_it: boolean := true;
var is_error: boolean := 'false')
exec sql end declare section;
;
...
3. Any mechanism specification is ignored.
The following example illustrates the use of these declarations:
function Getesqlerror
exec sql begin declare section;
( buf : varying[ub] of char )
exec sql end declare section;
: boolean;
procedure Handleerror
exec sql begin declare section;
( procedure errorhandle(err : integer); var
errnum : integer )
exec sql end declare section;
;
function Doappend
exec sql begin declare section;
( emp_id, floor : integer;
name : varying[ub] of char;
salary : real )
exec sql end declare section;
: integer;