RList eXtended - New features for OpenInsight 10.1
Published 07 OCT 2021 at 02:35:35PM
RList is the OpenInsight tool for queries and ad hoc reports. OpenInsight 10 implements an extended version of RList via the new RTI_RLISTX stored procedure which offers additional features for selecting and reporting data. However, you do not need to change existing programs to take advantage of this.
This post takes a look at some of the new RList capabilities, along with a full description of the API and some code examples.
OLIST/RUN_REPORT syntax support
LIST statements can use the same syntax as RUN_REPORT or OLIST if the output is going to the screen or printer.
- With OLIST LIST statements you can use keywords like GRID and PDFFILE. When the target is TARGET_PRINTER$, RList calls OLIST_PRODUCE to render the output.
Stacked selects
RList accepts a stack of SELECT statements and optionally one output (LIST) statement. RList will execute SELECT statements until zero records are selected or a LIST statement is executed. This allows developers to break a complex query into a series of simpler SELECT statements. Each subsequent SELECT statement refines the active select list.
RList to BRW
The TARGET_BRWDESIGN$ option will create a BRW (Banded Report Writer) report from an RList statement and open it in the BRW Designer for the developer to refine it. RList will prompt for the report group name. The intent is to let you quickly rough out a report or even a set of master/detail reports using RList, then use the BRW Designer to refine the result.
RList to a variable
The TARGET_VARIABLE$ option will return the result of an RList statement into a variable. For example, you can get a list of keys without using loop/readnext, you can populate an edit table with a SELECT statement, and you can obtain CSV, XML or JSON data by calling RList. This is similar to the OpenInsight 9 SELECT_INTO stored procedure. The SELECT_INTO syntax is still supported and now calls RTI_RLISTX internally to implement the commands instead.
Cursor support
RList support allows you to specify a cursor number between 0 and 8, or -1 to use the next non-zero cursor. OpenInsight 9 offered cursor support but the RList interface did not. Cursors permit sub-queries that don’t corrupt the main select loop. Sub-queries can operate on other BFS's too. For example OpenInsight calculated columns can query SQL tables.
Reduce, Select by, ReadNext, Swap.Cursor, Make.list, Save_Select, Activate_Save_Select all support cursors in OpenInsight 10.
Performance enhancements
RList implements many optimizations in selecting and reporting:
- It will use indexes to refine an existing select, whereas previous versions only use indexes on a select without an active select list.
- Caching can reduce server IO so RList can now cache rows as they are read if it knows that the same rows will be sorted or reported - previous versions always read the records to select, sort and report.
- RESOLVE_SELECT, the program which finalizes a select, is improved. If you specify the number of rows, RESOLVE_SELECT exits when it reaches that number of rows rather than resolving all of the rows before applying the limit.
- RList calls a new routine, RTI_CHAIN_SELECT, to pre-process selects which has some query optimization built in. For example, it will select on indexed fields before non-indexed, and hard fields before calculated. It performs sorts after the all selects are completed.
RList syntax in OpenInsight 10
Call RList( Statement, Target, TargetName, UserArg, DebugFlag )
Statement parameter
This parameter should contain one or more OpenList (SELECT/LIST) statements, separated by field marks. RList will process each statement sequentially until it exhausts the list of keys, selects zero rows, or executes a LIST statement. Note that in OpenInsight 10 RList accepts the same syntax as the classic OLIST or RUN_REPORT procedures as well as that used in TCL and any legacy OpenInsight 9 syntax.
Target parameter
Target is a code indicating the desired output format. OpenInsight supplies an insert which enumerates the options for target. See the RLIST_EQUATES insert record for more details.
Target | Value | Description |
TARGET_PRINTER$ | 0 | Sends the output of a LIST statement to the printer. |
TARGET_CLIENT$ | 1 | Sends the output of a LIST statement to the screen. |
TARGET_VARIABLE$ | 2 | Returns the output of a LIST statement to a variable. |
TARGET_CALLBACK$ | 3 | Triggers an RLIST_CALLBACK routine. |
TARGET_SAVELIST$ | 4 | Performs a SAVE_SELECT operation on the result of select statements. |
TARGET_ACTIVELIST$ | 5 | Activates a cursor with the result of select statements. |
TARGET_LATENTLIST$ | 6 | Creates a latent cursor for subsequent ReadNext processing. |
TARGET_CHECKSYNTAX$ | 7 | Checks the statements for valid syntax but does not execute them. |
TARGET_CALLBACK_NOFMT$ | 8 | Triggers an RLIST_CALLBACK routine but with no formatting or truncation applied to the returned values. |
TARGET_BRWDESIGN$ | 9 | Generate a Banded report, and open it in the designer. |
TARGET_BRWRUN$ | 10 | Generate a Banded report, and execute immediately. |
TargetName parameter
This parameter is polymorphic. You supply different values for different combinations of target and SELECT or LIST statements:
Target | Select Statement | LIST statement |
TARGET_PRINTER$ | N/a | N/a |
TARGET_CLIENT$ | N/a | N/a |
TARGET_VARIABLE$ | RList will return the keys if the output format is “KEYS”. See the UserArg parameter. | RList will return the output into the variable. The format of the output depends on the UserArg parameter. |
TARGET_CALLBACK$ | N/a | The name of an "RList callback" procedure. |
TARGET_SAVELIST$ | The name of the list to save. The string you pass is the list name in the SYSLISTS table. If you pass a space delimited string, RLIST will write the list to a table other than SYSLISTS using the first word as the name of the table and the second as the id of the list. | N/a |
TARGET_ACTIVELIST$ | N/a | N/a |
TARGET_LATENTLIST$ | N/a | N/a |
TARGET_CHECKSYSTAX$ | N/a | N/a |
TARGET_CALLBACK_NOFMT$ | N/a | The name of an "RList callback" procedure. RList will not enforce column widths on the output. Used by SELECT_INTO in OpenInsight 9. |
TARGET_BRWDESIGN$ | N/a | The name of the report group and report to generate. |
TARGET_BRWRUN$ | N/a | N/a |
UserArg parameter
Another polymorphic parameter whose format depends on the chosen Target parameter:
Target | Select Statement | LIST statement |
TARGET_PRINTER$ | N/a | UserArg<2> = cursor number |
TARGET_CLIENT$ | N/a | UserArg<2> = cursor number |
TARGET_VARIABLE$ | UserArg<1> = output format. “KEYS” is the only relevant format. UserArg<2> = cursor number | UserArg<1> = ResultFormat ( see below ) UserArg<2> = cursor number |
TARGET_CALLBACK$ | N/a | UserArg<2> = cursor number |
TARGET_SAVELIST$ | UserArg<2> = cursor number | N/a |
TARGET_ACTIVELIST$ | UserArg<2> = cursor number | N/a |
TARGET_LATENTLIST$ | N/a | |
TARGET_CHECKSYSTAX$ | N/a | N/a |
TARGET_CALLBACK_NOFMT$ | N/a | UserArg<2> = cursor number |
TARGET_BRWDESIGN$ | N/a | The name of the report group and report to generate. |
TARGET_BRWRUN$ | N/a | N/a |
ResultFormat
ResultFormat values are applicable when returning the result to a variable using the TARGET_VARIABLE$ Target.
ResultFormat | Description |
ADO | Result is an OLE record-set containing VARCHAR values. |
CSV | Result is a set of comma separated values, all values quoted, commas between columns, carriage-return/linefeed characters between rows. |
EDT | Edit Table format. Row 1 is column headings, @vm between columns, @fm between rows. Useful for populating edit tables using RList statements |
HTML | Result is an HTML table. |
JSON | Result is a JSON array of row objects, each column is an object in the row, multi-values are arrays. |
KEYS | Result is an @fm-delimited list of keys. |
MV | Default format. Result is an array - @fm between columns, @rm between rows. Row 1 is the column headers. |
TAB | Result is a set of tab-delimited column values, carriage-return/linefeed characters between rows. |
TXT | Same as TAB (see above). |
XML | Result is an XML collection of rows, each row is an XML collection of columns. |
Cursor Number
Cursor numbers specified in the UserArg parameter should be one of the following values:
- An integer between 0 and 8
- Null to use for cursor 0 (the default)
- -1 for next available, which chooses an inactive cursor from 1 to 8
DebugFlag parameter
N/a.
Code Examples
RList to PDF
Stacked Queries
Sometimes it’s easier to execute a series of select statements rather than a single complex query. RList accepts a list of selects with an optional closing list statement. RList will execute until completed or no records are selected. If one of the conditions selects nothing then the list statement will not run.
Query using a cursor
RList now supports cursors like REDUCE and SELECT BY. Indicate the cursor in field two of the UserArg parameter (in other words, UserArg<2>). Use this to execute sub queries. The sub query can return keys from a select or the output from a LIST statement.
Sub-query without corrupting the main select
Sub query in calculated column
You can use sub-queries in calculated columns too. A cursor variable of -1 uses the next available cursor. This allows you to nest calculated columns which perform sub-selects. If you always use subqueries rather than direct calls to btree.extract then your logic will function with or without indexes. You can make indexing choices in the performance tuning stage of development rather than when designing the dictionaries.
Return results to a variable
A new target type, TARGET_VARIABLE$ ( 2 ), will return the output to a variable. Pass a variable as the third parameter and an output format as the fourth. For SELECT statements, you must specify ‘KEYS’ as the output format. For LISTS statements you supply one of the formats listed above.
Populating an edit table control
The “EDT” output format is convenient for loading data into edit table controls:
Conclusion
RList for OpenInsight 10 offers new features as well as improved performance. Some of the features are available in previous versions but not via the RList interface. We tried to unify the disparate query capabilities (rlist, reduce, btree.extract, select_Into, olist ) under a single interface so you can focus on functionality and we can focus on performance.
Comments
At 07 OCT 2021 03:10PM David Sigafoos wrote:
great article bob ..
At 07 OCT 2021 11:50PM BarryStevens wrote:
👍👌