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.
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.
Expressions use the StreamBase static data types. The currently supported types are:
See StreamBase Data Types for details.
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.
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.
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
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.
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.
Unary operators act on only one operand in an expression. +a and -a are valid for
integer and double types.
You can use the <, <=, = or ==, >, >=, and != relational operators. The relational operator <> is not supported.
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.
The precedence order of mathematical operators in expressions, from highest to lowest, is as follows:
-
Unary operators: ! and -
The logical negation operator, !, reverses the meaning of its operand.
The unary negation operator, -, produces the negative of its operand.
-
Multiplicative operators: * and / and %
Multiplication: *
Division: /
Modulus, the remainder from division: %
-
Additive operators: + and -
Addition: +
Subtraction: -
-
Relational operators: < and <= and > and >=
Less than: <
Less than or equal to: <=
Greater than: >
Greater than or equal to: >=
-
Equality operator: == or =
-
Not equal: !=
-
Logical AND: && or AND
-
Logical OR: || or OR
You can use parentheses in expressions to override the default precedence.
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.
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.
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
trueandfalse. - int
-
Enter a number that is in the range of the int data type.
Examples:
0and31337are both ints - double
-
Enter a number using a decimal point, or using scientific notation.
Examples:
10.0and1e1are both doubles. - long
-
Enter a number that is in the range of the long data type, appending L to the number.
Examples:
100Land3147483650Lare 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
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.
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.
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.
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.
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)
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.
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,...)
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
calljavaorcallcppfunction. 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
calljavaorcallcppfunction. 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.
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 |
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:
- black_scholes(type, underlying, strike, dividendYield, riskFreeInterestRate, Volatility, exerciseDate, dealDate)
-
The
black_scholesfunction 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_scholesfunction takes eight input arguments; the first seven arguments are required, while the eighth argument,dealDate, is optional.The arguments are:
-
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
-
-
