/** @page statements Statements

    @tableofcontents

    Non-block statements in %Qore are always terminated by a semi-colon \c ";" as in Perl, C, C++, or Java. Statements can be grouped into blocks, which are delimited by curly brackets \c "{" and \c "}" containing zero or more semi-colon delimited statements, as in C or Java. Like C, C++, and Java, but unlike perl, any %Qore statement taking a statement modifier will accept a single statement or a statement block.

    A statement can be any of the following (note that statements are also recursively defined, and note furthermore that all examples are given in @ref new-style "%new-style"):

    <b>%Qore Statements</b>
    |!Type|!Examples|!Reference
    |An expression that changes an lvalue|@code{.py} var = 1;@endcode @code{.py} var += 5;@endcode @code{.py} var[1].count++;@endcode @code{.py} shift var.key[i];@endcode|@ref expressions
    |An expression with the @ref new "new operator"|@code{.py} new ObjectClass(1, 2, 3);@endcode|@ref new
    |An expression with the @ref background "background operator"|@code{.py} background function();@endcode|@ref background
    |An @ref if "if statement"|@code{.py} if (var == 3) {}@endcode|@ref if
    |An @ref if "if ... else" statement|@code{.py} if (var == 3) {} else {}@endcode|@ref if
    |A @ref while "while statement"|@code{.py} while (var < 10) {}@endcode|@ref while
    |A @ref do "do while statement"|@code{.py} do {} while (True);@endcode|@ref do
    |A @ref for "for statement"|@code{.py} for (int i = 0; i < 10; ++ i) {}@endcode|@ref for
    |A @ref foreach "foreach statement"|@code{.py} foreach softint i in (list) {}@endcode|@ref foreach
    |A @ref switch "switch statement"|@code{.py} switch (var) { case =~ /error/: throw "ERROR", var; default: printf("%s\n", var); }@endcode|@ref switch
    |A @ref return "return statement"|@code{.py} return val;@endcode|@ref return
    |A @ref variable_declarations "local variable declaration"|@code{.py} string var;@endcode @code{.py} my (int a, string b, bool c);@endcode|@ref variables, @ref variable_declarations
    |A @ref variable_declarations "global variable declaration"|@code{.py} our int var;@endcode @code{.py} our (float a, int b, hash c);@endcode|@ref variables, @ref variable_declarations
    |A @ref qore_functions "function call"|@code{.py} calculate(this, that, the_other);@endcode|@ref qore_functions, @ref object_method_calls, @ref static_method_calls, @ref closure, @ref call_reference
    |A @ref continue "continue statement"|@code{.py} continue;@endcode|@ref continue
    |A @ref break "break statement"|@code{.py} break;@endcode|@ref break
    |A statement block|@code{.py} {}@endcode|zero or more statements enclosed in curly brackets
    |A @ref throw "throw statement"|@code{.py} throw "ERROR", description;@endcode|@ref throw
    |A @ref try "try and catch statement"|@code{.py} try { func(); } catch (hash ex) { printf("%s:%d: %s: %s\n", ex.file, ex.line, ex.err, ex.desc); }@endcode|@ref try
    |A @ref rethrow "rethrow statement"|@code{.py} rethrow;@endcode|@ref rethrow
    |A @ref thread_exit "thread_exit statement"|@code{.py} thread_exit;@endcode|@ref thread_exit
    |A @ref context "context statement"|@code{.py} context top (q) {}@endcode|@ref context
    |A @ref summarize "summarize statement"|@code{.py} summarize (q) by (%date) where (%id != NULL) {}@endcode|@ref summarize
    |A @ref subcontext "subcontext statement"|@code{.py} subcontext where (%type == "INBOUND" ) {}@endcode|@ref subcontext
    |An @ref on_exit "on_exit statement"|@code{.py} on_exit l.unlock();@endcode|@ref on_exit
    |An @ref on_success "on_success statement"|@code{.py} on_success ds.commit();@endcode|@ref on_success
    |An @ref on_error "on_error statement"|@code{.py} on_error ds.rollback();@endcode|@ref on_error

    <hr>
    @section if if and else Statements

    @par Synopsis
    The <tt><b>if</b></tt> statement allows for conditional logic in a %Qore program's flow; the syntax is similar to that of C, C++, or Java.

    @par Syntax
    <tt><b>if</b></tt> <tt>(</tt><em>@ref expressions "expression"</em><tt>)</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em>\n
    <tt>[\b else</tt> \n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em><tt>]</tt>

    @par Description
    %Qore if statements work like if statements in C or Java. If the result of evaluating the expression converted to a @ref boolean value is @ref True "True", then the first statement (which can also be a block) is executed. If the result is @ref False "False", and there is an <tt><b>else</b></tt> keyword after the first statement, the following statement is executed.

    @note Any expression that evaluates to a non-zero integer value will be converted to a @ref boolean @ref True "True". Any expression that evaluates to zero value is interpreted as @ref False "False". This is more like C and Java's behavior and not like Perl's (where any non-null string except "0" is @ref True "True").  To simulate Perl's boolean evaluation, use <value>::val().

    <hr>
    @section for for Statements

    @par Synopsis
    The %Qore <tt><b>for</b></tt> statement is most similar to the for statement in C and Java, or the non array iterator for statement in Perl. This statement is ideal for loops that should execute a given number of times, then complete. Each of the three expressions in the for statement is optional and may be omitted. To iterate through a list without directly referencing list index values, see the @ref foreach "foreach statement".

    @par Syntax
    <tt><b>for</b></tt> <tt>(</tt> <em>@ref expressions "[initial_expression]"</em><tt>;</tt> <em>@ref expressions "[test_expression]"</em><tt>;</tt> <em>@ref expressions "[iterator_expression]"</em>)\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em>

    @par Description
    <em>@ref expressions "[initial_expression]"</em>\n
    The \a initial_expression is executed only once at the start of each for loop. It is typically used to initialize a loop variable.\n\n
    <em>@ref expressions "[test_expression]"</em>\n
    The \a test_expression is executed at the start of each for loop iteration. If this expression evaluates to @ref boolean @ref False "False", the loop will terminate.\n\n
    <em>@ref expressions "[iterator_expression]"</em>\n
    The \a iterator_expression is executed at the end of each for loop iteration. It is typically used to increment or decrement a loop variable that will be used in the test_expression.

    @par Example
    Here is an example of a for loop using a local variable:\n
    @code{.py}
for (int i = 0; i < 10; i++)
    print("%d\n", i);@endcode

    <hr>
    @section foreach foreach Statements

    @par Synopsis
    The %Qore <tt><b>foreach</b></tt> statement is most similar to the <tt><b>for</b></tt> or <tt><b>foreach</b></tt> array iterator statement in Perl. To iterate an action until a condition is @ref True "True", use the @ref for "for statement" instead.

    @par Syntax
    <tt><b>foreach</b></tt> <tt>[\b my|\b our] [</tt><em>@ref data_type_declarations "type"</em><tt>]</tt> variable <tt><b>in</b></tt> <tt>(</tt><em>@ref expressions "expression"</em><tt>)</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em>

    @par Description
    If \a expression does not evaluate to a list, then the variable will be assigned the value of the expression evaluation and the statement will only execute one time. Otherwise the variable will be assigned to each value of the list and the statement will be called once for each value.\n\n
    If \a expression evaluates to an object inheriting the @ref Qore::AbstractIterator "AbstractIterator" class, the <b><tt>foreach</tt></b> operator iterates the object by calling @ref Qore::AbstractIterator::next() "AbstractIterator::next()", and the values assigned to the iterator variable on each iteration are the container values returned by @ref Qore::AbstractIterator::getValue() "AbstractIterator::getValue()".\n\n
    If possible, \a expression is evaluated using @ref op_functional "lazy functional evaluation".\n\n
    If \a expression evaluates to @ref nothing (no value); then the loop is not executed at all.

    @par Example
    Here is an example of a foreach loop using a local variable:\n
    @code{.py}
# if str_list is a list of strings, this will remove all whitespace from the
# strings; the reference in the list expression ensures that changes
# to the iterator variable are written back to the list
foreach string str in (\str_list)
    trim str;
    @endcode
    Here is an example of a foreach loop using an object derived from @ref Qore::AbstractIterator "AbstractIterator":\n
    @code{.py}
hash h = ("a": 1, "b": 2);
foreach hash ih in (h.pairIterator())
    printf("%s = %y\n", ih.key, ih.value);
    @endcode

    @note
    - If a reference (<tt>\\lvalue_expression</tt>) is used as the list expression, any changes made to the <tt><b>foreach</b></tt> iterator variable will be written back to the list (in which case any @ref Qore::AbstractIterator "AbstractIterator" object is not iterated; references cannot be used with @ref Qore::AbstractIterator "AbstractIterator" objects as such objects provide read-only iteration).
    - When used with @ref new-style "%new-style" (which is a recommended parse option) or @ref allow-bare-refs "%allow-bare-refs", the \c \b my or \c \b our keywords are required with new variables or their type has to be declared, otherwise a parse exception will be raised

    @see @ref map for a flexible way to iterate a list or @ref Qore::AbstractIterator "AbstractIterator" object in a single expression

    <hr>
    @section switch switch Statements

    @par Synopsis
    The %Qore switch statement is similar to the switch statement in C and C++, except that the case values can be any expression that does not need run-time evaluation and can also be expressions with simple relational operators or regular expressions using the switch value as an implied operand.

    @par Syntax
    <tt><b>switch</b></tt> <tt>(</tt><em>@ref expressions "expression"</em><tt>) {</tt>\n
    &nbsp;&nbsp;<tt><b>case</b></tt> <em>case_expression</em><tt>:</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "[statement(s)...]"</em>\n
    &nbsp;&nbsp;<tt>[\b default:</tt> \n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "[statement(s)...]"</em><tt>]</tt>\n
    <tt>}</tt>

    @par Example
    @code{.py}
switch (val) {
    case < -1:
        printf("less than -1\n");
	break;
    case "string":
        printf("string\n");
	break;
    case > 2007-01-22T15:00:00:
        printf("greater than 2007-01-22 15:00:00\n");
	break;
    case /abc/:
        printf("string with 'abc' somewhere inside\n");
	break;
    default:
        printf("default\n");
	break;
}@endcode

    @par Description
    The first \a expression is evaluated and then compared to the value of each \a case_expression in declaration order until one of the \a case_expressions matches or is evaluated to @ref True "True". In this case all code up to a @ref break "break statement" is executed, at which time execution flow exits the <tt><b>switch</b></tt> statement.\n\n
    Unless relational operators are used, the comparisons are "hard" comparisons; no type conversions are done, so in order for a match to be made, both the value and types of the expressions must match exactly. When relational operators are used, the operators are executed exactly as they are in the rest of %Qore, so type conversions may be performed if nesessary.  The only exception to this is when both arguments are strings then a soft comparison is made in order to avoid the case that strings fail to match only because their encodings are different.\n\n
    To use soft comparisons, you must explicitly specify the soft equals operator as follows:\n
    @code{.py}
switch (1) {
    case == "1": print("true\n"); break;
}@endcode \n
    If no match is found and a default label has been given, then any statements after the default label will be executed. If a match is made, then the statements following that case label are executed.\n\n
    To break out of the switch statement, use the @ref break "break statement".\n\n
    As with C and C++, if no @ref break "break" or @ref return "return" statement is encountered, program control will continue to execute through other <tt><b>case</b></tt> blocks until on of the previous statements is encountered or until the end of the <tt><b>switch</b></tt> statement.

    @anchor case_expressions
    <b>Valid Case Expression Operators</b>
    |!Operator|!Description
    |<tt>\></tt>|@ref logical_greater_than_operator
    |<tt>\>=</tt>|@ref logical_greater_than_or_equals_operator
    |<tt>\<</tt>|@ref logical_less_than_operator
    |<tt>\<=</tt>|@ref logical_less_than_or_equals_operator
    |<tt>==</tt>|@ref logical_equality_operator (with type conversions)
    |<tt>=~</tt>|@ref regex_match_operator (in this case the regular expression may be optionally given without the operator)
    |<tt>!~</tt>|@ref regex_no_match_operator

    <hr>
    @section while while Statements

    @par Synopsis
    <tt><b>while</b></tt> statements in %Qore are similar to while statements in Perl, C and Java. They are used to loop while a given condition is @ref True "True".

    @par Syntax
    <tt><b>while</b></tt> <tt>(</tt><em>@ref expressions "expression"</em><tt>)</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em>

    @par Description
First the expression will be evaluated; if it evaluates to @ref True "True", then statement will be executed. If it evaluates to @ref False "False", the loop terminates.

    @par Example
    @code{.py}
int a = 1;
while (a < 10)
    a++;@endcode

    <hr>
    @section do do while Statements

    @par Synopsis
<tt><b>do</b></tt> <tt><b>while</b></tt> statements in %Qore are similar to do while statements in C. They are used to guarantee at least one iteration and loop until a given expression evaluates to @ref False "False".

    @par Syntax
    <b><tt>do</tt></b>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em> \n
    <tt><b>while</b></tt> <tt>(</tt><em>@ref expressions "expression"</em><tt>);</tt>

    @par Description
    First, the \a statement will be executed, then the \a expression will be evaluated; if it evaluates to @ref True "True", then the loop iterates again. If it evaluates to @ref False "False", the loop terminates.\n\n
    The difference between <tt><b>do</b></tt> <tt><b>while</b></tt> statements and @ref while "while statements" is that the <tt><b>do</b></tt> <tt><b>while</b></tt> statement evaluates its loop expression at the end of the loop, and therefore guarantees at least one iteration of the loop.

    @par Example
    @code{.py}
a = 1;
do
    a++;
while (a < 10);@endcode

    <hr>
    @section continue continue Statements

    @par Synopsis
Skips the rest of a loop and jumps right to the evaluation of the iteration expression.

    @par Syntax
    \b \c continue;

    @par Description
    The <tt><b>continue</b></tt> statement affects loop processing; that is; it has an affect on @ref for "for", @ref foreach "foreach", @ref while "while", @ref do "do while", @ref context "context", @ref summarize "summarize", and @ref subcontext "subcontext" loop processing.\n\n
    When this statement is encountered while executing a loop, execution control jumps immediately to the evaluation of the iteration expression, skipping any other statements that might otherwise be executed.

    <hr>
    @section break break Statements

    @par Synopsis
    Exits immediately from a loop statement or @ref switch "switch" block.

    @par Syntax
    \b \c break;

    @par Description
    The <tt><b>break</b></tt> statement affects loop processing; that is; it has an affect on @ref for "for", @ref foreach "foreach", @ref while "while", @ref do "do while", @ref context "context", @ref summarize "summarize", and @ref subcontext "subcontext" loop processing as well as on @ref switch "switch" block processing.\n\n
    When this statement is encountered while executing a loop, the loop is immediately exited, and execution control passes to the next statement outside the loop.

    <hr>
    @section throw throw Statements

    @par Synopsis
    In order to throw an exception explicitly, the <tt><b>throw</b></tt> statement must be used.

    @par Syntax
    <tt><b>throw</b></tt> expression;

    @par Description
    The expression will be passed to the <tt><b>catch</b></tt> block of a @ref try "try/catch statement", if the <tt><b>throw</b></tt> is executed in a @ref try "try block". Otherwise the default system exception handler will be run and the currently running thread will terminate.\n\n
    %Qore convention dictates that a direct list is thrown with at least two string elements, the error code and a description. All system exceptions have this format.\n\n
    See @ref try "try/catch statements" for information on how to handle exceptions, and see @ref exception_handling for information about how throw arguments are mapped to the exception hash.

    <hr>
    @section try try and catch Statements

    @par Synopsis
    Some error conditions can only be detected and handled using exception handlers. To catch exceptions, <tt><b>try</b></tt> and <tt><b>catch</b></tt> statements have to be used. When an exception occurs while executing the <tt><b>try</b></tt> block, execution control will immediately be passed to the <tt><b>catch</b></tt> block, which can capture information about the exception.

    @par Syntax
    <b><tt>try</tt></b>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em>\n
    <tt>\b catch ([@ref hash_type "hash"[&lt;@ref Qore::ExceptionInfo "ExceptionInfo"&gt;]] [</tt><em>exception_hash_variable</em><tt>])</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em>

    @par Description
    A single variable can be specified in the catch block to be instantiated with the exception hash, giving information about the exception that has occurred. For detailed information about the exception hash, see @ref exception_handling .\n\n
    If no variable is given in the <tt><b>catch</b></tt> declaration, it will not be possible to access any information about the exception in the <b><tt>catch</tt></b> block. However, the @ref rethrow "rethrow statement" can be used to rethrow exceptions at any time in a <tt><b>catch</b></tt> block.

    <hr>
    @section rethrow rethrow Statements

    @par Synopsis
    A <tt><b>rethrow</b></tt> statement can be used to rethrow an exception in <tt><b>catch</b></tt> and
    @ref on_error "on_error" blocks. In this case a entry tagged as a rethrow entry will be placed on the exception
    call stack.

    @par Syntax
    \b \c rethrow;
    \b \c rethrow expression;

    @par Description
    The rethrown exception will be either passed to the next higher-level <tt><b>catch</b></tt> block, or to the
    system default exception handler, as with a @ref throw "throw statement".\n\n
    This statement can be used to maintain coherent call stacks even when exceptions are handled by more than one
    <tt><b>catch</b></tt> block (for detailed information about the exception hash and the format of call stacks, see
    @ref exception_handling).\n\n
    The second variant taking an expression can be used to enrich or override the original exception; the
    \a expression is processed as with @ref throw "throw", except in this case the call stack of the original
    exception is maintained.  Also any exception values not overridden by the \c rethrow statement remain unchanged.
    Note that it is an error to use the <tt><b>rethrow</b></tt> statement outside of a <tt><b>catch</b></tt> block.

    <hr>
    @section thread_exit thread_exit Statements

    @par Synopsis
    <tt><b>thread_exit</b></tt> statements cause the current thread to exit immediately. Use this statement instead of the exit() function when only the current thread should exit.

    @par Syntax
    \b \c thread_exit;

    @par Description
    This statement will cause the current thread to stop executing immediately.

    <hr>
    @section context context Statements

    @par Synopsis
    To easily iterate through multiple rows in a hash of arrays (such as a query result set returned by the
    Qore::SQL::Datasource::select() or Qore::SQL::SQLStatement::fetchColumns() methods), the <tt><b>context</b></tt>
    statement can be used. Column names can be referred to directly in expressions in the scope of the context
    statement by preceding the name with a \c "%" character, while the current row can be referenced with \c %%.

    @par Syntax
    <tt><b>context</b></tt> <em>[name]</em> <tt>(</tt><em>@ref expressions "data_expression"</em><tt>)</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<tt>[\b where (</tt><em>@ref expressions "where_expression"</em><tt>)]</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<tt>[\b sortBy (</tt><em>@ref expressions "sort_expression"</em><tt>)]</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<tt>[\b sortDescendingBy (</tt><em>@ref expressions "sort_descending_expression"</em><tt>)]</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em>

    @par Description
    <em>@ref expressions "data_expression"</em>\n
    This must evaluate to a hash of arrays in order for the <tt><b>context</b></tt> statement to execute.\n\n
    <em>@ref expressions "where_expression"</em>\n
    An optional <b><tt>where</tt></b> expression may be given, in which case for each row in the hash, the expression
    will be executed, and if the where expression evaluates to @ref True "True", the row will be iterated in the
    context loop. If this expression evaluates to @ref False "False", then the row will not be iterated. This option
    is given so the programmer can create multiple views of a single data structure (such as a query result set) in
    memory rather than build different data structures by hand (or retrieve the data multiple times from a
    database).\n\n
    <em>@ref expressions "sort_expression"</em>\n
    An optional <tt><b>sortBy</b></tt> expression may also be given. In this case, the expression will be evaluated
    for each row of the query given, and then the result set will be sorted in ascending order by the results of the
    expressions according to the resulting type of the evaluated expression (i.e. if the result of the evaluation of
    the expression gives a string, then string order is used to sort, if the result of the evaluation is an integer,
    then integer order is used, etc).\n\n
    <em>@ref expressions "sort_descending_expression"</em>\n
    Another optional modifier to the <tt><b>context</b></tt> statement that behaves the same as above except that the
    results are sorted in descending order.

    @par Example
    @code{.py}
# note that "%service_type" and "%effective_start_date" represent values
# in the service_history hash of arrays.
context (service_history) where (%service_type == "voice")
        sortBy (%effective_start_date) {
    # %% is a hash of the current row
    check_row(%%);
    printf("%s: start date: %s\n", %msisdn, format_date("YYYY-MM-DD HH:mm:SS", %effective_start_date));
}
    @endcode

    @see
    - @ref context_functions
    - @ref find
    - @ref subcontext
    - @ref summarize
    - @ref Qore::HashListIterator "HashListIterator"
    - @ref Qore::ListHashIterator "ListHashIterator"
    - @ref <hash>::contextIterator()

    <hr>
    @section summarize summarize Statements

    @par Synopsis
    <tt><b>summarize</b></tt> statements are like context statements with one important difference: results sets are grouped by a <tt><b>by</b></tt> expression, and the statement is executed only once per discrete <tt><b>by</b></tt> expression result. This statement is designed to be used with the @ref subcontext "subcontext statement".

    @par Syntax
    <tt><b>summarize</b></tt> <tt>(</tt><em>@ref expressions "data_expression"</em><tt>) \b by (</tt><em>@ref expressions "by_expression"</em><tt>)</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<tt>[\b where (</tt><em>@ref expressions "where_expression"</em><tt>)]</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<tt>[\b sortBy (</tt><em>@ref expressions "sort_expression"</em><tt>)]</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<tt>[\b sortDescendingBy (</tt><em>@ref expressions "sort_descending_expression"</em><tt>)]</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em>

    @par Description
    <tt><b>summarize</b></tt> statements modifiers have the same effect as those for the @ref context "context statement", except for the following:\n\n
    <tt>\b by (</tt><em>@ref expressions "by_expression"</em><tt>)</tt>\n
    The <tt><b>by</b></tt> expression is executed for each row in the data structure indicated. The set of unique results defines groups of result rows. For each group of result rows, each row having an identical result of the evaluation of the by expression, the statement is executed only once.

    @par Example
    @code{.py}
# note that "%service_type" and "%effective_start_date" represent values
# in the services hash of arrays.
summarize (services)
    by (%effective_start_date)
    where (%service_type == "voice")
    sortBy (%effective_start_date) {
    printf("account has %d service(s) starting on %s\n",
           context_rows(),
           format_date("YYYY-MM-DD HH:mm:SS", %effective_start_date));
}@endcode

    @see
    - @ref context_functions
    - @ref find
    - @ref context
    - @ref subcontext
    - @ref Qore::HashListIterator "HashListIterator"
    - @ref Qore::ListHashIterator "ListHashIterator"

    <hr>
    @section subcontext subcontext Statements

    @par Synopsis
    Statement used to loop through values within a @ref summarize "summarize statement".

    @par Syntax
    <tt><b>subcontext</b></tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<tt>[\b where (</tt><em>@ref expressions "where_expression"</em><tt>)]</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<tt>[\b sortBy (</tt><em>@ref expressions "sort_expression"</em><tt>)]</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<tt>[\b sortDescendingBy (</tt><em>@ref expressions "sort_descending_expression"</em><tt>)]</tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em>

    @par Description
    The <tt><b>subcontext</b></tt> statement is used in conjunction with @ref summarize "summarize statements". When result rows of a query should be grouped, and then each row in the result set should be individually processed, the %Qore programmer should first use a @ref summarize "summarize statement", and then a <tt><b>subcontext</b></tt> statement. The @ref summarize "summarize statement" will group rows, and then the nested <tt><b>subcontext</b></tt> statement will iterate through each row in the current summary group.

    @par Example
    @code{.py}
summarize (services)
    by (%effective_start_date)
    where (%service_type == "voice")
    sortBy (%effective_start_date) {
    printf("account has %d service(s) starting on %s\n",
           context_rows(),
           format_date("YYYY-MM-DD HH:mm:SS", %effective_start_date));
    subcontext sortDescendingBy (%effective_end_date) {
        printf("\tservice %s: ends: %s\n", %msisdn, format_date("YYYY-MM-DD HH:mm:SS", %effective_end_date));
    }
}@endcode

    @see
    - @ref context_functions
    - @ref find
    - @ref context
    - @ref summarize
    - @ref Qore::HashListIterator "HashListIterator"
    - @ref Qore::ListHashIterator "ListHashIterator"

    <hr>
    @section return return Statements

    @par Synopsis
    <tt><b>return</b></tt> statements causes the flow of execution of the function, method or program to stop immediately and return to the caller. This statement can take an optional expression to return a value to the caller as well.

    @par Syntax
    <tt><b>return</b></tt> <em>@ref expressions "[expression]"</em>;

    @par Description
    This statement causes execution of the current function, method, or program to returns to the caller, optionally with a return value.

    @par Example
    @code{.py}
string sub getName() {
   return "Barney";
}
string name = getName();@endcode

    <hr>
    @section on_exit on_exit Statements

    @par Synopsis
    Queues a statement or statement block for unconditional execution when the block is exited, even in the case of
    exceptions or @ref return "return statements". For similar statement that queue code for execution depending on
    the exception status when the block exits, see @ref on_success "on_success statements" and
    @ref on_error "on_error statements".

    @par Syntax
    <tt><b>on_exit</b></tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em>

    @par Description
    The <tt><b>on_exit</b></tt> statement provides a clean way to do exception-safe cleanup within %Qore code. Any
    single statment (or statement block) after the <tt><b>on_exit</b></tt> keyword will be executed when the current
    block exits (as long as the statement itself is reached when executing - <tt><b>on_exit</b></tt> statements that
    are never reached when executing will have no effect).\n\n
    The position of the <tt><b>on_exit</b></tt> statement in the block is important, as the immediate effect of this
    statement is to queue its code for execution when the block is exited, meaning that <tt><b>on_exit</b></tt>
    statements (along with <tt><b>on_success</b></tt> and <tt><b>on_error</b></tt> statements) are executed in reverse
    order respective their declaration when the local scope is exited for any reason, even due to an exception or a
    @ref return "return statement".  Therefore it's ideal for putting cleanup code right next to the code that
    requires the cleanup.\n\n
    Note that if this statement is reached when executing in a loop, the <tt><b>on_exit</b></tt> code will be executed
    for each iteration of the loop.\n\n
    By using this statement, programmers ensure that necessary cleanup will be performed regardless of the exit status
    of the block (exception, @ref return "return", etc).

    @par Example
@code{.py}
{
    mutex.lock();
    # here we queue the unlock of the mutex when the block exits, even if an exception is thrown below
    on_exit mutex.unlock();
    if (error)
        throw "ERROR", "Scary error happened";
    print("everything's OK!\n");
    return "OK";
}
# when the block exits for any reason, the mutex will be unlocked@endcode

    <hr>
    @section on_success on_success Statements

    @par Synopsis
    Queues a statement or statement block for execution when the block is exited in the case that no exception is
    active. Used often in conjunction with the @ref on_error "on_error statement" and related to the
    @ref on_exit "on_exit statement".

    @par Syntax
    <tt><b>on_success</b></tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em>

    @par Description
    The <tt><b>on_success</b></tt> statement provides a clean way to do block-level cleanup within %Qore code in the
    case that no exception is thrown in the block. Any single statment (or statement block) after the
    <tt><b>on_success</b></tt> keyword will be executed when the current block exits as long as no unhandled exception
    has been thrown (and as long as the statement itself is reached when executing - <tt><b>on_success</b></tt>
    statements that are never reached when executing will have no effect).\n\n
    The position of the <tt><b>on_success</b></tt> statement in the block is important, as the immediate effect of
    this statement is to queue its code for execution when the block is exited, meaning that
    <tt><b>on_success</b></tt> statements (along with <tt><b>on_exit</b></tt> and <tt><b>on_error</b></tt> statements)
    are executed in reverse order respective their declaration when the local scope is exited for any reason, even due
    to an exception or a @ref return "return statement".  Therefore it's ideal for putting cleanup code right next to
    the code that requires the cleanup, along with @ref on_error "on_error statements", which are executed in a manner
    similar to <tt><b>on_success</b></tt> statements, except <tt><b>on_error</b></tt> statements are only executed
    when there is an active exception when the block is exited.\n\n
    Note that if this statement is reached when executing in a loop, the <tt><b>on_success</b></tt> code will be
    executed for each iteration of the loop (as long as there is no active exception).

    @par Example
@code{.py}
{
    db.beginTransaction();
    # here we queue the commit in the case there are no errors
    on_success db.commit();
    # here we queue a rollback in the case of an exception
    on_error db.rollback();
    db.select("select * from table where id = %v for update", id);
    # .. more code

    return "OK";
}
# when the block exits. the transaction will be either committed or rolled back,
# depending on if an exception was raised or not@endcode

    <hr>
    @section on_error on_error Statements

    @par Synopsis
    Queues a statement or statement block for execution when the block is exited in the case that an exception is
    active. Used often in conjunction with the @ref on_success "on_success statement" and related to the
    @ref on_exit "on_exit statement".

    @par Syntax
    <tt><b>on_error</b></tt>\n
    &nbsp;&nbsp;&nbsp;&nbsp;<em>@ref statements "statement"</em>

    @par Description
    The <tt><b>on_error</b></tt> statement provides a clean way to do block-level cleanup within %Qore code in the
    case that an exception is thrown in the block. Any single statment (or statement block) after the
    <tt><b>on_error</b></tt> keyword will be executed when the current block exits as long as an unhandled exception
    has been thrown (and as long as the statement itself is reached when executing - <tt><b>on_error</b></tt>
    statements that are never reached when executing will have no effect).\n\n
    The position of the <tt><b>on_error</b></tt> statement in the block is important, as the immediate effect of this
    statement is to queue its code for execution when the block is exited, meaning that <tt><b>on_error</b></tt>
    statements (along with <tt><b>on_exit</b></tt> and <tt><b>on_error</b></tt> statements) are executed in reverse
    order respective their declaration when the local scope is exited for any reason, even due to an exception or a
    @ref return "return statement".  Therefore it's ideal for putting cleanup code right next to the code that
    requires the cleanup, along with @ref on_success "on_success statements", which are executed in a manner similar
    to <tt><b>on_error</b></tt> statements, except @ref on_success "on_success statements" are only executed when
    there is no active exception when the block is exited.\n\n
    The implicit argument <tt>$1</tt> is set to the current active exception, and also
    @ref rethrow "rethrow statements" are allowed in \c on_error statements, allowing for exception enrichment.
    Note that the code in this statement can only be executed once in any block, as a block (even a block within a
    loop) can only exit the loop once with an active exception (in contrast to @ref on_success "on_success" and
    @ref on_exit "on_exit statements", which are executed for every iteration of a loop).

    @par Example
@code{.py}{
    db.beginTransaction();
    # here we queue the commit in the case there are no errors
    on_success db.commit();
    # here we queue a rollback in the case of an exception
    on_error {
        db.rollback();
        # this replaces the exception error code, updated the exception description, and leaves any exception
        # argument unchanged
        rethrow "TRANSACTION-ERROR", sprintf("%s: $s", $1.err, $1.desc);
    }
    db.select("select * from table where id = %v for update", id);
    # .. more code

    return "OK";
}
# when the block exits. the transaction will be either committed or rolled back,
# depending on if an exception was raised or not
@endcode
*/
