General Questions


Is a Warehouse script able to access more than one database?

A single Warehouse script is capable of accessing multiple local and remote input sources and multiple local and remote output targets.


On what port number does the Warehouse Server listen?

By default, the Warehouse server listens on port 1610. And by default, a Warehouse client will attempt to remotely connect to a Warehouse server on that same port 1610. To configure a different listening port, see the Warehouse Manual. For Windows platforms, see the Release Notes for Warehouse version 3.00.4500.


Is a Warehouse script required to execute on a particular machine?

No, the script is not required to execute on a particular machine. The only requirement of a machine is that Warehouse be installed and running on that system and that the system have connectivity with systems that house the script’s data sources and targets. These remote systems should have Warehouse installed and running as well.

Utilization and contention being equal, co-locating script execution with the most heavily-used data sets can often improve performance by reducing network latencies. Since scripts can be written in a portable manner, an unchanged script can be run and performance-evaluated on any system where Warehouse is present.


What’s the difference between the START and XEQ commands?

When you use START, the statements are not displayed as they are processed. When you use XEQ they are displayed.

Tip: when debugging your Warehouse scripts, use XEQ.


What’s the difference between a FORMAT and a DEFINE?

A FORMAT is a template: it establishes a definition that describes a record or a variable. A FORMAT can be used by subsequent DEFINEs to allocate actual variables. A FORMAT can also be nested within another FORMAT. To a C programmer, a FORMAT is equivalent to a struct.


What are the respective effects of the ;NOWAIT (the default) and ;WAIT directives in the context of a remote COPY command within a READ loop?

Let us consider the following abbreviated example:

read row = localdb.emp
setvar rec_emp.ename = ename
copy rec_emp to remotedb.emp

In this example, the COPY statement to a remote database remotedb is NOWAITed (the default): Warehouse will continue to process the script, reading from  localdb and inserting toremotedb, without waiting for a response from the remote Warehouse server for each remote operation. This is a significant performance optimization as operations are interleaved.

NOWAIT has implications when used inside a TRY/RECOVER block. Should an error occur during a NOWAITed COPY, the RECOVER statement would not be entered with the record that had the error.

On the other hand, if the COPY statement were coded as follows:
    copy rec_emp to remotedb.emp; wait

Warehouse would wait until the remote COPY operation completed before reading the next row from the source. Should an error occur during a WAITed COPY, RECOVER would be entered with the specific record that had the error. Within a TRY/RECOVER block a COPY statement should be WAITed.

Tip: when debugging failures, particularly network failures, use the ;WAIT option for better fault isolation.


What are the reserved words in Warehouse?

Reserved word lists are published for languages that have a syntax where identifiers can occur in the same places as keywords. This makes it illegal to use keywords as an identifier and requires a list of reserved words or keywords. Warehouse’s language was designed not to require reserved words. Therefore there is no need to publish a list of keywords.

To illustrate, the following syntax is legal but is neither sanctioned nor maintainable:

1> define print : string value ‘hello’
2> define string : string value ‘world’
3> print print, string

hello world

Tip: code obfuscation of this kind is extremely poor practice. Consider, for example, the consequences of performing a change all on a name that is both a variable identifier and a Warehouse statement, such as print or string.


What are the scope rules for Warehouse variables?

All variables are considered global to a script unless defined within a function. If a variable is defined within a function, it is considered local to its defining function.

Global variables are persistent and can be accessed from anywhere in the script. A function variable is local to its defining function and as such cannot be accessed from outside of that function. A function variable is an automatic variable: it is created upon entry to the function and destroyed upon exit.

If a global variable and a function variable share the same name then any use of that shared name outside the defining function will reference the global variable. Any use of that shared name inside the defining function will reference the local function variable. The following code demonstrates these scope rules, where the variables i and j are variously defined as both global and local variables:

1> define i : integer
2> define j : integer
4> function func2
5>     define j : integer
6>     setvar j = 219
7>     print “global i=”, i, “func2 j= “, j
8>     return
9>     endfunction
11> function func1
12>     define i : integer
13>     setvar i = 111
14>     print “func1 i= “, i, “global j=”, j
15>     call func2
16>     return
17> endfunction
19> setvar i = 13
20> setvar j = 17
21> print “global i=”, i, “global j=”, j
22> call func1
23> print “global i=”, i, “global j=”, j

global i= 13   global j= 17
func1 i= 111   global j= 17
global i= 13   func2 j= 219
global i= 13   global j= 17

Tip: unless a variable is truly being used as a temporary work area – for example, as a simple loop counter – then it is safer practice to use unique names. Consider the unintended consequence of accidentally deleting the DEFINE for a local variable that shares a name with a global variable. Given compatible data types the script will compile, but the execution results will probably be unexpected.


What is the scope of the Warehouse comment (*) character?

Unlike some languages where a comment indicator applies only to the physical line it occupies, the Warehouse comment character (*) applies to a logical line, where a logical line is composed of one or more physical lines. Hence the scope of a Warehouse comment is one or more physical lines.

In the following OPEN statement, the Warehouse continuation character (&) is used to extend the statement across multiple physical lines:

open db &
remote sol22 user=qa password=homer &
oracle scott/tiger home=c:\oracle\ora81 sid=ora816

When Warehouse encounters a comment character in the script, it looks for trailing continuation characters, and discards all continued physical lines that immediately follow. Warehouse then resumes its detailed parsing at the next un-continued line.

Here a single comment character disables all three physical lines spanned by the OPEN statement:

* open db &
remote sol22 user=qa password=homer &
oracle scott/tiger home=c:\oracle\ora81 sid=ora816


How can I reference tables or columns with lower-case or mixed-case names?

Warehouse assumes that database object names are stored in upper-case. In the event that an object name is not stored in upper-case, then in order to reference this name within a Warehouse script, you will need to delimit it with braces (curly brackets). The use of braces instructs Warehouse to work with the database object name as it appears in the script.


For example, let’s assume a SQL Server database that was created with a binary collation, containing the table MixedCase formed by the three columns, Col1Col2, and Col3.


In this first example, we get a compilation error referencing the table name MixedCase because the required braces have not been used:

1> open db odbc unibin
[Microsoft][ODBC SQL Server Driver][SQL Server]Changed database context to ‘UniBin’. (ODBC 01000)
[Microsoft][ODBC SQL Server Driver][SQL Server]Changed language setting to us_english. (ODBC 01000)

2> list db

TABLE NAME                        OWNER                   TYPE
———-                        —–                   —-
MixedCase                         dbo                     TABLE
dtproperties                      dbo                     TABLE
sysconstraints                    dbo                     VIEW
syssegments                       dbo                     VIEW

3> show db MixedCase
Error getting number of Result Columns. (WHERR 21037)
ODBC error 208: [Microsoft][ODBC SQL Server Driver][SQL Server]Invalid object name ‘MIXEDCASE’. (ODBC S0002)
[Microsoft][ODBC SQL Server Driver][SQL Server]Statement(s) could not be prepared. (ODBC 37000)
Error attempting to show table ‘”MIXEDCASE”‘. (WHERR 21018)


In this second case, the compilation is successful as we reference the mixed-case names within braces:

1> open db odbc unibin
[Microsoft][ODBC SQL Server Driver][SQL Server]Changed database context to ‘UniBin’. (ODBC 01000)
[Microsoft][ODBC SQL Server Driver][SQL Server]Changed language setting to us_english. (ODBC 01000)
2> show db {MixedCase}
    RECORD  // 46 bytes
        Col1                 : ODBC CHAR(10) ALLOW NULLS OFFSET 1
        Col2                 : ODBC CHAR(10) ALLOW NULLS OFFSET 17
        Col3                 : ODBC CHAR(10) ALLOW NULLS OFFSET 33
3> read x = db.{MixedCase} order by {Col3}
[Using serial read]
4>     update x set {Col1} = {Col2}
5> endread