3.4. Identifiers #

3.4.1. Identifier names
3.4.2. Query field identifiers
3.4.3. User defined variables
3.4.4. Special purpose identifier domains

Expressions may reference query column names, environment variables, internal variables and user defined Report variables. These references are called identifiers. Their values are evaluated during the report execution.

3.4.1. Identifier names #

Identifiers are in the format domain.identifier where the domain name or the dot are optional.

OpenCReports uses UTF-8 encoding even in identifier names. National or accented characters are accepted in identifiers.

Valid names for domain and identifier may start with an underscore or UTF-8 letters and may contain underscore, UTF-8 letters and numbers in subsequent characters.

3.4.2. Query field identifiers #

Any valid identifier is by default a query column reference, with or without the domain name. Examples:

field_name
field_name5
myquery1.field_name
oszlop_név
lekérdezés.oszlop_név

In the above example, oszlop_név means field_name, and lekérdezés.oszlop_név means query.field_name in Hungarian. The accented characters are a courtesy of UTF-8.

Query field identifiers in expressions are resolved by matching them against query names (used as the domain) and their field names.

If the domain name is specified, a query matching the domain name name must be declared for the report, either as the primary query, a follower query, or an independent query. That query must have a column name that matches the identifier name.

If the domain name is not specified, the field name references are matched against all the queries of the report in the order of their declaration. The first query with a matching column name will be used for that reference.

For exceptions (and exceptions from under the exceptions!), see below.

3.4.3. User defined variables #

Domain v signifies user defined report variables, which can be used to shortcut expressions. Example:

v.my_variable

For details, see Report variables and Variable node.

3.4.4. Special purpose identifier domains #

Some domain names carry special meaning for the report.

3.4.4.1. Environment variables #

Domain m indicates the domain of environment variables.

The nature of environment variables depends on the languange binding. For example in C, it's the environment variables in the operating system. In PHP, the identifier name is first matched against global PHP variables, and if not found, against the operating system environment variables. Example:

m.current_date

Since such a setting is controlled outside the report, and for the duration of running the report, its value cannot (or shouldn't) change, environment variable references are optimized into constants at the beginning of the report execution.

Environment variables can't change during report execution in single threaded applications, but they can in multi-threaded ones. By optimizing environment variables into constants in expressions instead of querying the environment every time the same expression is evaluated, potential data races (that may result in inconsistent results) are eliminated.

3.4.4.2. Internal report variables #

Domain r indicates the domain of internal report variables.

3.4.4.2.1. Current page number #

r.pageno

The current page of the report is maintained by the report layout during the report run. For example, if an expression is evaluated on page 4 of the report, and happens to reference the current page number variable, then this variable will have the value 4 in the result.

PDF output supports pagination. Other output formats do not. For them the value of this variable is 1.

3.4.4.2.2. Total number of pages #

r.totpages

This variable carries the total number of pages in the report. Its value is maintained by the report.

Only the PDF output format supports pagination. For output formats not supporting pagination, the value of this variable is 1 throughout the report.

This variable is inherently precalculated. Expressions like this will intuitively produce the expected result:

printf("Page: %d / %d", r.pageno, r.totpages)

For example, on the 3rd page of a 5-page report, the value would be:

Page: 3 / 5

3.4.4.2.3. Line number #

r.lineno

This variable gives the current row (line) number in the data set.

It can be thought as an alias to the Query row number function function which does the same by default. But functions may be overridden by user defined functions, while this variable will always work as described.

3.4.4.2.4. Detail count #

r.detailcnt

This variable works similarly to the Line number variable and Query row number function, except it restarts from 1 when a field header is emitted on the report. See Detail node.

With the default behaviour of the field header regarding breaks (see Report field header priority attribute), i.e. when field header is printed on the top of every page, r.detailcnt works as a per page line count value.

When the report field header priority is set to low, the effect may be more emphasized because the value of this variable is reset more often.

3.4.4.2.5. Field value #

r.value

Data on the report is represented by field description. Along with the data expression, supplementary expressions are used for metadata that make up the displaying of the value. Such supplementary expression exist for the foreground and background colors, the formatting of the value, and others.

The supplementary expressions may reference the field value, without having to type out the field expression multiple times.

Using r.value also helps reducing the report runtime because the value expression is not computed multiple times. This is a manual optimization.

Referencing r.value is only possible for supplementary expressions in the same field description. This variable cannot cross-reference other field descriptions, or anything not in the same scope. For this purpose, there are user Report variables.

3.4.4.2.6. Report output format value #

r.format

This variable returns the current output format name as a string. For example: PDF, HTML, etc.

3.4.4.2.7. Expression self reference #

r.self

This variable references the previous result of the expression. It is used in iterative expressions, like in user-defined Report variables. It can also be used in any user defined expression.

3.4.4.2.8. Subexpressions of user-defined variables #

r.baseexpr
r.ignoreexpr
r.intermedexpr
r.intermed2expr

These variables are references for the four subexpressions that potentially make up a user-defined custom variable. The expressions in order are: base expression, the row ignoring expression and two intermediary expressions.

Actually, there's a fifth subexpression that exists in every user defined variable, namely the result expression. It's reference is simply the user variable reference, see User defined variables and Custom variable attributes.

They are evaluated in this order:

  • r.baseexpr

    The base expression must not reference any of the others of r.ignoreexpr, r.intermedexpr, and r.intermed2expr.

  • r.ignoreexpr

    The data row ignoring expression must not reference r.intermedexpr and r.intermed2expr, but it can reference r.baseexpr.

  • r.intermedexpr

    The first intermediary expression can reference r.baseexpr and r.ignoreexpr, but it must not reference r.intermed2expr.

  • r.intermed2expr

    The second intermediary expression can reference any of r.baseexpr, r.ignoreexpr, and r.intermedexpr.

  • The result expression, which has no internal variable name. It can reference all of r.baseexpr, r.ignoreexpr, r.intermedexpr and r.intermed2expr.

For example, a running average over a data series needs two intermediary expressions: one for the sum of the values, the other for the number of values in the series. The result is the sum of values divided by the number of values.

Their usage is only valid when declaring a custom user defined variable.

3.4.4.3. Quoted and dot-prefixed identifiers #

Both domain and identifier names may be quoted or unquoted. Quoting names allow using semi-reserved and reserved words as identifiers and also allow special characters in identifier names. Examples:

query.field_name1
query."field_name2"
query."field with space in the name"
"query2".field_name3
"query2"."and"

3.4.4.4. Dot-prefixed identifiers #

A dot-prefixed identifier is one where the domain name is not specified, but the identifier name is prefixed with a dot. Examples:

.field_name
."field_name"

The boolean constants are semi-reserved words. They can be used as identifiers with dot-prefixed identifier names without a domain name and without quoting:

.yes
.no
.true
.false
yes.no

The above unquoted identifiers are equivalent with these quoted ones below:

."yes"
."no"
."true"
."false"
"yes"."no"

Operator names are reserved words, e.g. and and or. They cannot be used with dot-prefixed operator names without quoting, as it would cause an expression syntax error. But they can be used as quoted identifiers, in case you would want to use such a query name and column name:

."and"
."or"
"and"."or"

3.4.4.5. Quoted special purpose identifier domains #

When identifier domains are quoted, they lose their special meaning and the identifiers become query field identifiers. Of course, in this case, such a query name must exist and the query must have a field name specified in the identifier. Examples:

"m".current_date
"r".totpages
"v".my_variable