expression

NAME
SYNTAX
DESCRIPTION
CONSTANTS
OPERATORS
FUNCTIONS
EXAMPLES
NOTES
BUGS
COPYRIGHT
SEE ALSO

NAME

expression, concatenation, function − rwl syntax for expressions and standard functions

SYNTAX

primary_expression ::=
  identifier
| constant
| function
| ( concatenation )

function ::=
  uniform ( expression , expression )
| ( erlang | erlang2 ) ( expression )
| erlangk ( expression , expression )
| ( atan2 | normalrandom ) ( expression , expression )
| ( sin | cos | sqrt | round | ceil | floor | trunc ) ( expression )
| ( exp | log ) ( [ expression ,) ] expression )
| lengthb ( concatenation )
| instrb ( concatenation , concatenation  [ , expression ] )
| substrb ( concatenation , expression [ , expression ] )
| sql_id ( [ identifier ] )
| ( activesessioncount | opensessioncount ) ( identifier )
| ( serverrelease ) ( identifier | default | results )
| ( runseconds | epochseconds ) ()
| getenv ( expression )
| system ( concatenation [ , identifier ] )
| access ( concatenation , expression )
| winslashf2b ( concatenation )
| winslashf2bb ( concatenation )
| defined ( identifier )
| defined ( default database )
| identifier ( [ concatenation { , concatenation } ] )

unary_expression ::=
  primary_expression [ is [ not ] null ]
| ( - | ! | not ) multiplication

multiplication ::=
  unary_expression
| multiplication ( * | / | % ) unary_expression

addition ::=
  multiplication
| addition ( + | - ) multiplication

comparison ::=
  addition
| comparison ( < | > | <= | >= ) addition
| comparison between addition and addition

equality ::=
  comparison
| equality ( = | != | <> ) comparison

logicaland ::=
  equality
| logicaland and equality

logicalor ::=
  logicaland
| logicalor or logicaland

conditional ::=
  logicalor
| logicalor ? conditional : conditional

expression ::=
  conditional
| expression || conditional

concatenation ::=
  expression { expression }

constant ::=
  integer
| string
| digit { digit } . { digit } { exponent }
| digit { digit } { exponent }
| null

integer ::= digit { digit }

digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

exponent ::= e [ + | - ] digit { digit }

string ::=
  " {character} "
| $ ( A | B | ... Z { A | B ... | 0 | 1 ... | _ }

DESCRIPTION

In the RWP*Load Simulator, expressions are very similar to expressions in any other programming language with operator precedence, association etc. The operator syntax is a mix of operators from C and SQL.

String concatenation has the same syntax as in the SQL language, i.e. using || as the concatenation operator. However, in many contexts where a disambiguation does not exist, the operator can be omitted. See NOTE below for details.

Although variables are declared with some type (integer, double, string) they are internally always represented as all three types, similar to how awk does it. Type conversion is implicit and behaves similar to how it is done in C. As an example if a is a double variable, a:=1/2 will assign the double value 0.0 to a since the division is done using integer arithmetic. If at least one operator of an expression is double, double arithmetic will be used. Therefore a:=1.0/2 will assign the double value 0.5 to a. The same rules apply to numeric comparisons.

If a double result is assigned to an integer variable or used in another context where an integer is expected, the standard function trunc(3) is implicitly applied to the double value.

Strings are implicitly converted to integer or double without error handling similar to how atoi(3) or atof(3) do it. If complete control of this is needed, it is recommended to only use variables and functions of one specific type in the expression.

CONSTANTS

In rwloadsim, you can have constants of type integer, double or string and the additional constant null. Integer constants are sequences of digits, double constants are sequences of digits, a decimal dot, and potentially another sequence of digits. Double constants can additionally have an exponent which is the letter e (or E), potentially followed by + or - and terminated by a sequence of digits.

A potential - in front of an integer or double constant is not part of the constant; where appropriate, it will be parsed as the unary minus operator.

Strings are delimited by double quotes and they can span newline in which case the newline becomes part of the string unless preceded by \. Within a string a backslash initiates one of the following escapes:

\" represents the double quote character

\\ represents a backslash

\t represents the TAB character

\n represents newline

\e represents the ESC characters

\r represents the CR character

No other escapes are allowed.

In string constants, all characters in your terminals character set are allowed; however, they are always treated as a sequence of bytes. You must always ensure the NLS_LANG environment variable includes the correct setting for the actual character used by your terminal session.

Environment variables of the form $NAME where NAME is upper case potentially followed by uppercase, underscore or digits are also string constants. Except when used in the $if $then directive, attempts at using non existing environment variables cause a warning to be displayed. The same syntax with $ for environment expansion is also used on Microsoft Windows. Due to the fact that expressions are always calculated as all three simple types, you can assign such environment variables to integers and doubles.

Please note that $ followed by lower case are directives, so you cannot expand environment variables in lower case using $. If needed, use the getenv() function.

There are also variables named $#, $1, $2, etc, see identifier(1rwl).

A random string array is treated like a string constant.

OPERATORS

The rwl language has the following operators in order of precedence. All logical operators have the result 1 when true and 0 when false, and all operators operating on logic values use 0 as false and any other value as true. Except when noted, operators are dyadic.

is null

is not null

Similar to their equivalents in the SQL language; these are monadic and post-fix.

- ! not

These monadic prefix operators are respectively numeric negative and two synonyms for boolean not.

* / %

Multiplication, division and remainder. If both arguments to % are integer, the result is as the % operator in C. Otherwise, the effective implementation of a%b is a-floor(a/b)*b, implying the result of the % operator is ether zero or has same sign as the second argument. This is different from the C function remainder(), but is what Knuth recommends according to https://en.wikipedia.org/wiki/Modulo. The preferred implementation of the remainder function can lead to heated debates; if you want the C implementation that can return negative values when both operands are positive, you can create a function that returns a-round(a/b)*b.

+ -

Addition and subtraction.

< <= > >=

between and

The first four are the standard inequality comparison operators. The latter is like its counterpart in the SQL language and is a triadic operator. If either operand is numeric, all comparisons are done on the numeric value; If both operands are string, all comparisons are done using the byte values of the strings. All operands of the between and operator are calculated irrespective of their values.

= <> !=

Equality and two synonyms for inequality comparison. The type rules are the same as for the comparison operators.

and

Logical and; if the first operand is 0, the second operand is not calculated.

or

Logical or; if the first operand is not 0, the second operand is not calculated.

? :

Comparison operator as found in the C programming language. Only one of the second and third operand is calculated depending on the value of the first, and the operator is right associative.

||

String concatenation. Note that in most cases, the concatenation operator can be omitted as two expressions immediately after each other are taken as concatenation. See NOTE below.

FUNCTIONS

User declared functions can be called as part of expression evaluation using the syntax

name( arguments )

where arguments is a potentially empty list of comma-separated expressions; note that functions without arguments still require the parenthesis.

The following lists all built-in functions. Note that neither user defined nor built-in functions are available in a $if $then directive, except when explicitly noted.

uniform(a,b)

Return a random uniformly distributed number. If either of the arguments are double, the result is a double value greater than or equal to the value of the first argument and less than the second argument. If both arguments are integer, the result will be an integer greater than or equal to the value of the first argument and less than or equal to the second argument.

erlang(a) erlang2(a)

Return a random double value with an average of a. The value will be erlang distributed with k=1 or k=2 respectively. Erlang distribution with k=1 is also known as exponential distribution. Erlang distribution with k=2 is often used when simulating expected arrival rates.

erlangk(k,a)

Return a random value with an average of a using an erlang k distribution. Only the integer part of k is used.

normalrandom(a,s)

Return a normal distributed random value with an average of a and a standard deviation of s.

sqrt(a)

Return the square root of the argument.

round(a) ceil(a) floor(a) trunc(a)

Return an integer value that is either rounded, the smallest not less than, the largest not greater than or truncated towards zero of its argument. Note that the return values is a double as in the C functions of the same names, but that it will retain its value if assigned to an integer under the assumption it is not outside the range of integers. The trunc function is in most cases not needed as it is implicitly applied when assigning a double to an integer.

exp(p,a) exp(a)

Return the value of p raised to the power a. If p is omitted, return e raised to the power of a.

log(l,a) log(a)

Return the logarithm of base l, respectively e, of the argument a.

sin(a) cos(a)

Return the sine or cosine of argument a degrees.

atan2(b,a)

Return the angle in degrees between the a-coordinate and b-coordinate for the quadrant.

lengthb(s)

Return the length in bytes of the string s.

instrb(x,s) instrb(x,s,p)

Returns the byte position (starting at 1) of the string s in the string x or 0 if not found. With three arguments, start the search at position p. Semantics is like the same function in SQL with two or three arguments, although negative values for p are not allowed.

substrb(s,p) substrb(s,p,l)

Returns a sub-string of its first argument, starting at byte position p; if l is specified that number of bytes will be returned. Semantics is like the same function in SQL.

sql_id(n) sql_id()

The first call eturns the sqlid of the named identifier which must be a sql statement. The function is only available if both the client and the server are release 12.2 or newer, and the value is only available after the sql statement has been executed. If you omit the identifier, the function will return the sqlid of the latest sql statement found in your rwl source file before the call to sql_id(). This can be used to get the sql_id of immediate or embedded sql.

activesessioncount(n) opensessioncount(n)

The argument must be an identifier naming a database using a sessionpool, and the value returned is respectively the OCI_ATTR_SPOOL_BUSY_COUNT or OCI_ATTR_SPOOL_OPEN_COUNT from the associated session pool handle.

serverrelease(n)

The argument must be an identifier naming a database or either of the keywords default or results and the return value is the five element release of that database as a string in the format a.b.c.d.e.

runseconds()

A double function taking no arguments, which returns the time-stamp with microsecond resolution since the common start time of all control loops in threads. It is available in both the main and worker threads, and the value can be negative.

epochseconds()

A double function taking no arguments, which returns the UNIX epoch in seconds. The resolution is normally microseconds, but it depends on the resolution of the gettimeofday(2) system call.

getenv(s)

Return the value of the environment variable provided as the argument. If the environment variable does not exist, an empty string is returned.

system(s) system(s,n)

Execute the first argument as an operating system command and return the exit code from its execution. If there is a second argument, it must be the name of a string variable into which the stdout from the execution is stored. If the last character in stdout from the call is a newline (which is normally the case), the newline is removed. This is somewhat equivalent to doing something like n=‘$s‘ in the shell. Note that there also is a system statement that can be used if the return value can be ignored.

access(f,c)

Return true (1) if the file named as the first argument has the access explained as the second argument. The second argument must be a combination of the characters r, w, x, f, d, u, p, c, The first three refer to the standard access methods, f means check if the path refers to an ordinary file, d to check if it refers to a directory. The directories that are checked can be modified using the last three characters: If the character u is present, the public directory will also be checked, if the character p is present, all entries in the RWLOADSIM_PATH environment will be checked and if the character c is present, the current directory will not be checked. As an exception to the general rule, this function is available in $if $then directives.

winslashf2b(s) winslashf2bb(s)

These two functions are only relevant if you plan for your code to run on Microsoft Windows, where they are used to replace / with repsectively \ or \\. They both take a string as argument and return a string. In most cases, you do not need to explicitly use these functions, as any file open call when executed on Microsoft Windows by default replaces / by \. You will typically only need to use either of these calls if you call system and need to ensure some file name is using the proper \ character to separate directory path elements, or if you generate some code for later execution via system. When not running on Microsoft Windoes, both of these functions perform no operation.

defined(n) defined(default database)

The first call returns true if the identifier named as its argument has been defined and can be used. As an example, a database that has not connected successfully will return false. The second call returns true if there is default database declared and it has connected successfully. The function is only available inside the $if $then directive.

EXAMPLES

# assign either 1 or 2 with equal probability to the variable a
integer a := uniform(1,2);

# assign a random number at least 0 but smaller than 1 to the variable d
double d := uniform(0.0,1.0);

# Print a line telling if this is executed by root or not
printline access("/root","dw") ? "you are root" : "you are not root";

# Print the value of a, then a :, then the value of d.
printline a ":" d;


# Use of the conditional operator
string ss :=
  a = 1 ? "one" :
  a = 2 ? "two" :
          "something else";

NOTES

An identifier followed by a left parenthesis is always taken as the beginning of a function call. In a context with attempted concatenation such as

printline "aaa and expression " aaa ( 1+2+3 );

the name aaa is assumed to be a function implying there is no implicit concatenation of a variable named aaa and a parenthesized expression 1+2+3. Hence, if you want this to be taken as a concatenation of the variable and the expression, you need to use an explicit concatenation operator as shown here:

printline "aaa and expression " aaa || ( 1+2+3 );

or alternatively simply omit the parenthesis.

For legacy reasons, you can write runsecons and epochseconds without the empty set of parentheses; this usage is deprecated and will be desuported in some future release.

BUGS

If the serverrelease function is used with a database version 18 or later when the client is version 12 or earlier, only the major release (the first number) is correct. This is not a bug in rwloadsim itself.

COPYRIGHT

Copyright © 2023 Oracle Corporation
Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl

SEE ALSO

identifier(1rwl), simpledeclaration(1rwl), statement(1rwl), declaration(1rwl), functiondeclaration(1rwl), atoi(3), atof(3), randomstringdeclaration(1rwl)