StreamBase Expression Language and Functions

This topic describes the StreamBase expression language and each of the built-in functions that you can use with StreamBase applications. In application diagrams, you use StreamBase functions in operators (except Heartbeat, Metronome, Split, and Union, which do not take an expression). You can also use StreamBase expressions in statements within StreamSQL applications, as described in the StreamSQL Guide.

Pointer to StreamBase Functions

Are you looking for information about the functions provided by StreamBase? Start in the StreamBase Functions section below. If you want an alphabetized list of all functions, with links to the descriptions, please see Alphabetical Index of StreamBase Functions.

Evaluating Expressions

A useful tool for understanding and testing simple expressions is the sbd --eval command, documented in the sbd help topic. Use sbd --eval to test the results of simple expressions as you read this topic, and before using them in your StreamBase applications. For example:

$ sbd --eval "1e1 * (15 % -4)"

(double) 30.0

sbd --eval does not work with aggregate functions. You must evaluate aggregate functions using other methods, such as running a test application and checking the results.

Back to Top ^

Data Types

Expressions use the StreamBase static data types. The currently supported types are:

  • blob

  • bool

  • double

  • int

  • long

  • string

  • timestamp

See StreamBase Data Types for details.

Back to Top ^

Case Sensitivity

Expressions are case sensitive. Function names should be all lowercase.

Back to Top ^

Identifiers

Only use alphabetic characters, numbers, and underscores. The first character must be alphabetic or an underscore. Do not use hyphens or other special characters. Identifier rules apply to the name you assign to any StreamBase component, including schemas, fields, operators, tables, lock sets, and modules.

Note

The StreamBase software creates identifiers that include colons, but you cannot use colons in your identifiers.

Back to Top ^

Reserved Words

When you name fields, do not use the following reserved words:

  • blob

  • bool

  • double

  • else

  • false

  • if

  • int

  • long

  • null

  • string

  • then

  • timestamp

  • then

  • true

In an Input Stream's Properties View, StreamBase Studio does not prevent you from specifying a reserved word for a field name. However, a schema that contains reserved words causes one or more typecheck errors in the connected downstream components. The error message in the Typecheck View identifies the offending field's name. Rename the field in the Input Stream's Property View.

Back to Top ^

Qualifying Field Names

If a name conflict occurs in a field name that's used in an expression within an operator instance, you can qualify them to clarify the inbound tuple stream to which you are referring.

In the Properties view for a Gather operator, you can qualify the fields as input[port-number].field-name.

Example: input1.is_alarm, input2.is_alarm, input3.is_alarm.

In the Properties view for a Join operator, you can qualify the fields in the two input streams as input1.field-name and input2.field-name. The input1.field-name refers to a field in the stream arriving at the top port (#1). The input2.field-name refers to a field in the stream arriving at the bottom port (#2).

Examples:

input1.SKU
input2.SKU

In the Properties view for a Query operator, you can qualify the fields in the two input streams as input.field-name and old.field-name. The input.field-name refers to the current input tuple, while old.field-name refers to the field's old (prior) value.

Examples:

Table1_current_Name
Nasdaq100Table_old_Symbol

Back to Top ^

Arithmetic Operators

You can use +, -, *, /, and %. The ^ expression is not supported.

For example, in the Compliance sample that we provide with the StreamBase kit, the is_alarm field is a bool. In one of the Compliance application's Map operators, we use this expression for the is_alarm check on each tuple:

((((sector_in_fund_value_t + (shares_traded * price_at_trade)) * 100) / fund_value_t) > 25)

This expression is designed to execute the 25% sector test; that is, one sector is not allowed to be more than 25% of the total fund value. is_alarm is set to true if the test fails.

Modulus Operators

The modulus operator ( % ) finds the remainder of a division operation. Division and modulus are always related such that a/b*b+(a%b) == a, where a/b is an integer division. For example, 15%4 can be resolved as follows: as:

15 / 4 * 4 + MOD == 15
3 * 4 + MOD = 15
12 + MOD = 15
MOD = 3

This relationship is preserved with negative divisors. As a result, whenever the quotient is negative, the modulus is negative. For example:

15 % 4 = 3
15 % -4 = 3
-15 % 4 = -3
    -15% -4 = -3

Also note that if you divide a smaller number by a larger number, the modulus is always the smaller number. For example:

4 % 15 = 4

This behavior may be different than modulus in some programming languages.

Tip

The easiest way to understand StreamBase modulus operations is to try out different expressions using the sbd --eval command.

Back to Top ^

Unary Operators

Unary operators act on only one operand in an expression. +a and -a are valid for integer and double types.

Back to Top ^

Relational Operators

You can use the <, <=, = or ==, >, >=, and != relational operators. The relational operator <> is not supported.

Back to Top ^

Logical Operators

You can use && or AND, || or OR, and !.

Logical Operator Meaning
&& or AND AND
|| or OR OR
! NOT

Note

The evaluation of expressions using && and || will short-circuit. This means that after StreamBase encounters the first term that evaluates as false, no other terms in a statement using && are evaluated. Similarly, evaluation of a statement using || stops after the first true term.

For related information on Boolean logic and nulls, see Using Nulls in StreamBase Applications.

Back to Top ^

Precedence Order

The precedence order of mathematical operators in expressions, from highest to lowest, is as follows:

  1. Unary operators: ! and -

    The logical negation operator, !, reverses the meaning of its operand.

    The unary negation operator, -, produces the negative of its operand.

  2. Multiplicative operators: * and / and %

    Multiplication: *

    Division: /

    Modulus, the remainder from division: %

  3. Additive operators: + and -

    Addition: +

    Subtraction: -

  4. Relational operators: < and <= and > and >=

    Less than: <

    Less than or equal to: <=

    Greater than: >

    Greater than or equal to: >=

  5. Equality operator: == or =

  6. Not equal: !=

  7. Logical AND: && or AND

  8. Logical OR: || or OR

You can use parentheses in expressions to override the default precedence.

Back to Top ^

Casting

To recast data types, use one of the StreamBase type conversion functions. For example, to cast a value to a double in an expression, use the double() function. To cast a value to a string, use the string() function, and so on. Casting may not be necessary if type coercion is supported for the data types. See the next section.

Back to Top ^

Data Type Coercion

Some StreamBase functions support data type coercion of input arguments from long to double data types. Type coercion is the implicit conversion of a value from one data type to another. For example, the floor function is listed in this reference as taking a double argument. However, you can enter an integer or long value instead: the function implicitly converts the value to its double equivalent.

There are only two possible data type coercions:

Input data type Converts to
int long
long double

Observe the following rules for coercion:

  • You can supply an int value for a double argument: the intermediate coercion to long happens implicitly.

  • For long-to-double coercion where the precision of the long cannot be preserved in the double, Java rounding rules apply.

Back to Top ^

White Space

The StreamBase parser ignores any spaces, new lines, and tab characters in expressions.

Specifying Literals in Expressions

This section describes how to specify literals in expressions, for each data type. (For information about the data types themselves, see StreamBase Data Types).

blob

Use the StreamBase blob() function, which converts a string to a blob.

Example: blob("abcde") creates a blob containing the bytes representing the string "abcde".

bool

Use the literals true and false.

int

Enter a number that is in the range of the int data type.

Examples: 0 and 31337 are both ints

double

Enter a number using a decimal point, or using scientific notation.

Examples: 10.0 and 1e1 are both doubles.

long

Enter a number that is in the range of the long data type, appending L to the number.

Examples: 100L and 3147483650L are both longs.

Note

If the L is omitted, StreamBase will interpret your number as an int no matter how large the value is.

string

You can use single quotes ( 'string' ) or double quotes ( "string" ) around strings. Escape characters are supported, as follows:

Character Results in
\" Double quotation mark
\' Single quotation mark
\n Newline
\t Tab
\b Backspace
\r Carriage return
\\ Backslash

Examples:

String Literal Results in
"He said, \"Hello.\"" He said, "Hello."
'She said, \'Hello.\'' She said, 'Hello.'
"A\tB" A<tab>B
"A\nB" A<newline>B
"C:\\WINDOWS" C:\WINDOWS
timestamp

You cannot enter timestamp literals directly in expressions. Instead, use the StreamBase timestamp() function, which converts a string in the following format to a timestamp:

YYYY-MM-DD hh:mm:ss[.sss][+TTTT]

The maximum precision date is milliseconds.

Examples:

"2005-10-08" Implicit time of "00:00:00", local time zone
"2005-10-08 13:17" Implicit seconds of "00", local time zone
"2005-10-08 13:17:23" Local time zone
"2005-10-08 13:17:23.12355" Fractional seconds
"2005-10-08 13:17:23" == "2005-10-08 13:17:23"
"2005-10-08 24:00:00" == "2005-10-09 00:00:00"
"2005-10-08 13:17:23-0500" Explicit time zone (EST in this case)
"2005-10-08 13:17-05:00" Explicit time zone, implicit seconds

Back to Top ^

Null Literals

You can use nulls in the StreamBase expression language, one for each data type:

blob(null)
bool(null)
int(null)
double(null)
long(null)
string(null)
timestamp(null)

Each null literal is case sensitive; for example, Int(NULL) is invalid. The data type of each null is never implicit: you must specify which type of null you are using in the expression.

In general, when you apply any arithmetic operator or function with data-type(null) as one of the arguments, the result is null. Three exceptions are the isnull() and notnull() functions, which test whether an expression evaluates to null, and the coalesce() function, which selects a non-null value from a list of potentially null arguments.

Expression Example Result
3 + int(null) A null int
int(null) + int(null) A null int
int(null) + bool(null) A typecheck error. You cannot add an int and a bool.
if bool(null) then 3 else 4 A null int
int(null) == int(null) A null bool, because null is not equal to itself
int(null) != int(null) A null bool, because null is not equal to itself
isnull(int(null)) A bool that evaluates to true
notnull(int(null)) A bool that evaluates to false

For related information, please see Using Nulls in StreamBase Applications.

Back to Top ^

Conditional Expressions

In an expression such as: if p then e1 else e2, p must be a valid bool expression, and both e1 and e2 must be expressions that have the same type. If p is true, then e1 will be evaluated and the result returned. If p is false, e2 will be evaluated and the result returned. In either case the other sub-expression is not evaluated.

Note

In the StreamBase expression language, each if clause must have a pair of explicit then and else clauses. Should you create compound if clauses, to avoid ambiguity, remember to specify the then and else clauses for each if clause. For an example, please see the next section.

Back to Top ^

Compound Conditional Expressions

You can use combinations of if-then and else-if-then statements to form compound conditional expressions. For example:

if i==0 then "Buy" else if i==1 then "Sell" else if i==2 then "Hold" else "None of the above"

Here is a second example (indented for clarity), where we nest an if then else in a then clause:

if p1
    then
        if p2
            then 1
            else 2
else
        if p2
            then 3
            else 4

Notice how each if clause contains a then clause and an else clause.

Back to Top ^

Concatenation in Expressions

You can enter an expression that performs concatenation. For a string variable, the concatenation expression is

stringvar + x

For example: b + 25. For a numeric variable with a static string, the concatenation expression is

"staticstring" + numvar

For example: "foo" + a. For two variables, the concatenation expression is

stringvar + numvar

For example: b+a. Note that when you use an expression to concatenate a number to a string, the total size becomes the original string size + 12.

Back to Top ^

Timestamp Expressions

When used with comparison operators ( == != > < <= >= ) you must compare time interval-to-interval, or timestamp-to-timestamp. You cannot use the comparison operators with interval-to-timestamp.

To express constant intervals, you can use the seconds() and minutes() functions. For example, if you want to add 60 seconds to a timestamp, you can enter expressions such as:

t + seconds(60)
t + minutes(1)

Back to Top ^

Parameters in Expressions

You can declare operator-parameters in the sbd.sbconf file, and then use them as parameters within StreamBase expressions. StreamBase Server Configuration XML explains how to declare operator-parameters.

To then reference a parameter in an expression, wrap the operator-parameter name in braces and prefix the open brace with a dollar sign. If you are referencing an operator-parameter that is defined as a string, use quotes around the entire reference.

For example, consider an sbd.sbconf file that defines these two operator-parameters:

<operator-parameters>
    <operator-parameter name="MyInt" value="2"/>
    <operator-parameter name="MyString" value="somestring"/>
</operator-parameters>

You could reference the first parameter (for example, in an output field) using an expression like 35* ${myInt}. The expression would evaluate at run time to 70. This StreamSQL statement references the second parameter:

SELECT * FROM InputStream1 "${MyString}" AS source

Notice the quotation marks: they are needed so that the expression is resolved as a string.

Note

Expression parameters are distinct from both module parameters, which are described in Using Module Parameters, and StreamSQL CREATE PARAMETER statements:

  • A module parameter is defined only for a parameterized module (or, in StreamSQL, a Java operator or an embedded Java adapter), not globally in the sbd configuration.

  • If you use an expression parameter and a module parameter with the same name, the module parameter value takes precedence.

  • Expression parameters can only be used within expressions. StreamSQL parameters are more flexible: they can be used to represent expressions as well as other parts of a statement.

Note

Expression parameters can be referenced in both EventFlows and StreamSQL applications. However, if you convert an EventFlow .sbapp file to StreamSQL, any expression parameters are resolved during the conversion; the parameter itself is not preserved.

Back to Top ^

StreamBase Functions

This section provides reference information for all the StreamBase functions. You can also get help on functions directly in StreamBase Studio when you edit an expression: In the Properties view, the Functions tab shows the syntax of each function and provides editing shortcuts. See Properties View for details.

StreamBase provides two types of functions:

Simple functions are evaluated over one set of arguments, and return a single result. The strlen() function is an example of a simple function. Simple functions can be used in expressions for any StreamBase operator, except Heartbeat, Metronome, and Union, which do not use an expression.

Aggregate functions are evaluated over multiple sets of arguments and return a single result. In StreamBase applications, aggregate functions are used only in Aggregate operators and in Query operators that do query read operations. The avg() function, which calculates an average value for tuples in an Aggregate window, is an example of an aggregate function.

function_name(arg1,arg2,arg3,...)

Back to Top ^

Using Custom Functions in Expressions

In addition to the functions that are provided by StreamBase (sometimes called built-in functions), you can call custom functions that you have created yourself by extending the StreamBase API for Java, C++, or .NET API (see Developing Custom Functions to learn how). After creating a custom function and configuring it in your project, you can call it in an expression, using one of these methods:

  • Using the calljava or callcpp function. For example, the following expression uses calljava() to call a custom class and its arguments:

    calljava(myCustomFunction, x, y)

  • Using an alias that you have defined for your custom function. The alias allows you to reference the function class directly, without using the calljava or callcpp function. For example:

    myCustomFunction(x, y)

StreamBase provides several sample applications, featuring custom functions, that you can load in StreamBase Studio to see how they are built and configured. The custom sample applications are listed in Extending StreamBase Samples.

Back to Top ^

Alphabetical Index of StreamBase Functions

For your convenience, here is a complete, alphabetized index into the available functions provided by StreamBase, with links to the function descriptions in this section. As described in the preceding section, if you do not find a built-in function that you need here, you can use the StreamBase custom function APIs to implement your own function and configure your application to use it. For details, please see these topics in the API Guide:

Function Name and Link to Section Summary Comment
abs function Simple function: math
acos function Simple function: math
alpha function Aggregate function: statistical calculations
avg function Aggregate function: statistical calculations
asin function Simple function: math
atan function Simple function: math
atan2 function Simple function: math
beta function Aggregate function: statistical calculations
black_scholes function Simple function: financial
blob function Simple function: type conversions
bool function Simple function: type conversions
callcpp:: Simple function: C++ API call

Aggregate function: C++ API call

calljava: Simple function: Java API call

Aggregate function: Java API call

catchexception function Simple function: check for errors in expression
cbrt function Simple function: math
ceil function Simple function: math
closeval function Aggregate function: for windowing
coalesce function Simple function: working with nulls
compound_interest Simple function: financial
correlation_coefficient function Aggregate function: statistical calculations
correlation_coefficientp function Aggregate function: statistical calculations
cos function Simple function: math
cosh function Simple function: math
count function Aggregate function: statistical calculations
count_distinct function Aggregate function: statistical calculations
covariance function Aggregate function: statistical calculations
covariancep function Aggregate function: statistical calculations
date function Simple function: creating absolute timestamps
days function Simple function: creating interval timestamps
double function Simple function: type conversions
error function Simple function: error
exp function Simple function: math
exp_moving_avg function Aggregate function: statistical calculations
expm1 function Simple function: math
firstval function Aggregate function: for windowing
floor function Simple function: math
from_gmtime function Simple function: creating absolute timestamps
from_localtime function Simple function: creating absolute timestamps
getContainer Simple function: Java API call
getNodeName Simple function: Java API call
getLeadershipStatus Simple function: Java API call
get_day_of_week function Simple function: working with timestamp fields
get_day_of_month function Simple function: working with timestamp fields
get_hour function Simple function: working with timestamp fields
get_minute function Simple function: working with timestamp fields
get_month function Simple function: working with timestamp fields
get_second function Simple function: working with timestamp fields
get_year function Simple function: working with timestamp fields
hash function Simple function: type conversions
hours function Simple function: creating interval timestamps
indexof function Simple function: strings
int function Simple function: type conversions
intercept function Aggregate function: statistical calculations
interval function Simple function: creating absolute timestamps
isnan function Simple function: NaN (not a number)
isnull function Simple function: detecting null values
lastindexof function Simple function: strings
lastval function Aggregate function: for windowing
ln function Simple function: math
log1p function Simple function: math
log10 function Simple function: math
long function Simple function: type conversions
max function:
Simple function: math

Aggregate function: statistical calculations

min function:
Simple function: math

Aggregate function: statistical calculations

minutes function Simple function: creating interval timestamps
notnan function Simple function: detecting NaN (not a number)
notnull function Simple function: detecting null values
now function Simple function: creating absolute timestamps
openval function Aggregate function: for windowing
pow function Simple function: math
product function Aggregate function: statistical calculations
random function Simple function: math
regexmatch function Simple function: strings
round function Simple function: math
seconds function Simple function: creating interval timestamps
securerandom function Simple function: math
securitytag function Simple function: API call
set_day_of_month function Simple function: working with timestamp fields
set_day_of_week function Simple function: timestamp
set_hour function Simple function: working with timestamp fields
set_minute function Simple function: working with timestamp fields
set_month function Simple function: working with timestamp fields
set_second function Simple function: working with timestamp fields
set_year function Simple function: working with timestamp fields
sign function Simple function: math
sin function Simple function: math
sinh function Simple function: math
sleep function Simple function: pause execution
slope function Aggregate function: statistical calculations
sqrt function Simple function: math
stdev function Aggregate function: statistical calculations
stdevp function Aggregate function: statistical calculations
strftime function Simple function: creating absolute timestamps
string function Simple function: type conversions
strlen function Simple function: strings
strpinterval function Simple function: creating absolute timestamps
strptime function Simple function: creating absolute timestamps
strresize function Simple function: strings
strresizetrunc function Simple function: strings
substr function Simple function: strings
sum function Aggregate function: statistical calculations
systemenv function Simple function: Java API call
systemproperty function Simple function: Java API call
tan function Simple function: math
tanh function Simple function: math
time function Simple function: creating absolute timestamps
timestamp function Simple function: type conversions
today function Simple function: creating absolute timestamps
to_degrees function Simple function: math
to_milliseconds function Simple function: working with timestamp fields
to_radians function Simple function: math
to_seconds function Simple function: working with timestamp fields
variance function Aggregate function: statistical calculations
variancep function Aggregate function: statistical calculations
vwap function Aggregate function: statistical calculations
weeks function Simple function: creating interval timestamps

Back to Top ^

Simple Functions

This section describes the simple functions that you can use in expressions for any StreamBase operator, except the Heartbeat, Metronome, and Union operators, which do not accept an expression.

This section is organized according to categories of simple functions:

Simple Functions: Financial

black_scholes(type, underlying, strike, dividendYield, riskFreeInterestRate, Volatility, exerciseDate, dealDate)

The black_scholes function calculates fair-value and risk statistics (delta, gamma, vega) for European style options on securities with continuous dividend yields. This is known as the Black-Scholes Generalized model. It also calculates implied volatility.

The black_scholes function takes eight input arguments; the first seven arguments are required, while the eighth argument, dealDate, is optional.

The arguments are:

  1. type: Required. Should be set to one of the following string values:

    • Call (The price of an option.)

    • Put (The price of an option.)

    • DeltaCall (The sensitivity of the price of an option to changes in the price of the stock.)

    • DeltaPut (The sensitivity of the price of an option to changes in the price of the stock.)

    • ThetaCall (Theta measures how the price of an option changes with time.)

    • ThetaPut (Theta measures how the price of an option changes with time.)

    • Gamma (The sensitivity of a stock's delta to the stock price.)

    • Vega (The rate of change of the value of an option with respect to the volatility of the stock's price.)

    • RhoCall (The sensitivity of the price of an option with respect to the risk-free interest rate.)

    • RhoPut (The sensitivity of the price of an option with respect to the risk-free interest rate.)

    • ImpliedVolatilityCall (Implied volatility of the underlying stock for a given price.)

    • ImpliedVolatilityPut (Implied volatility of the underlying stock for a given p