TQL reference
This section covers TQL data types, operators, functions, and reserved keywords. For data definition statements, see DDL and component reference.
Supported data types
SQL data types are not supported in TQL. The following Java data types are supported:
java.lang.Byte, java.lang.Byte[]
java.lang.Double
java.lang.Float
java.lang.Integer
java.lang.Long
java.lang.Short
java.lang.String
For convenience, you may specify these in TQL as byte, byte[], double, float, integer, long, short, and string, and they will be converted to the above types on import.
org.joda.time.DateTime is imported automatically and may be specified as DateTime.
All these types support nulls.
Operators
TQL supports the following operators.
Arithmetic operators
See https://www.w3resource.com/sql/arithmetic-operators/sql-arithmetic-operators.php for an introduction.
+
: add-
: subtract*
: multiply/
: divide%
: modulo
Comparison operators
See http://www.sqltutorial.org/sql-comparison-operators for an introduction.
=
: equal to!=
: not equal to<>
: not equal to>
: greater than<
: less than>=
: greater than or equal to<=
: less than or equal to!<
: not less than!>
: not greater than
Logical operators
See http://www.sqltutorial.org/sql-logical-operators for an introduction.
ALL
AND
ANY
BETWEEN
EXISTS
IN
IS NULL
LIKE
(see Using regular expressions (regex))NOT
OR
UNIQUE
Functions
TQL supports the following functions.
Functions for supported data types
Striim supports all native functions for these supported data types:
Aggregate functions
To avoid unexpected results from a SELECT
statement containing an aggregate function :
Always include a
GROUP BY
clause.If selecting from a window, all fields other than the one in the
GROUP BY
clause should use an aggregate function. For example, instead ofSELECT a, b, SUM(c) FROM WINDOW10s GROUP BY a
, you should useSELECT a, LAST(b), SUM(c) FROM WINDOW10s GROUP BY a
.If a field on a CQ with a
GROUP BY
clause lacks an aggregate function, the output value comes from the last event in the batch. For example, inSELECT a, b, SUM(c) FROM WINDOW10s GROUP BY a
, the value ofb
will equal the value ofb
found in the final event in its batch.
function | notes |
---|---|
AVG | Works only with Double and Float. To calculate an average for an Integer or Long field, cast it as Double or Float. For example: SELECT AVG(TO_FLOAT(MyWindow.PosData)) AS AvgPosData FROM MyWindow; |
COUNT [DISTINCT] | |
FIRST | returns Java.lang.Object: see Using FIRST and LAST |
LAST | returns Java.lang.Object: see Using FIRST and LAST |
LIST(Object,...) | returns a collection of events: see Using pattern matching for an example |
MAX | |
MIN | |
SUM |
Application metadata functions
Use these functions in a CQ to add metadata to its output. For example:
CREATE CQ addAppInvokerName INSERT INTO addAppInvokerNameOutput SELECT getApplicationInvoker(), merchantId, dateTime FROM DSVTransformed_Stream;
function | notes |
---|---|
getApplicationInvoker() | Returns the name of the Striim user that started the application as a String. |
getApplicationName() | Returns the name of the application containing the function as a String. |
getApplicationUUID() | Returns the UUID of the application containing the function as a String. |
getCQName() | Returns the name of the CQ containing the function as a String. |
getOpenProcessorName() | Returns the name of the open processor containing the function as a String. |
Date functions
See http://joda-time.sourceforge.net/apidocs/org/joda/time/Period.html for an explanation of the Period object. A P in printed results represents a Period object.
function | description | notes |
---|---|---|
DADD(DateTime, Period) | add a Period to a DateTime value | for example, |
DAFTER(DateTime, DateTime) | true if the second date is after the first | |
DBEFORE(DateTime, DateTime) | true if the second date is before the first | |
DBETWEEN(DateTime, DateTime, DateTime) | true if the first date is after the second and before the third | DBETWEEN( origTs, DSUBTRACT(ts, DSECS(1)), DADD(ts, DSECS(1)) ) == true |
DDAYS(DateTime) | return the day of the month of the DateTime | |
DDAYS(Integer) | return Integer days as a Period for DADD or DSUBSTRACT | |
DDIFF(DateTime, DateTime) | return a Period in which the difference in milliseconds between the two dates is stored | |
DDIFF(LocalDate, LocalDate) | return the number of whole days between the two partial datetimes as an Integer | |
DHOURS(DateTime) | return the hour of the day of the DateTime | |
DHOURS(Integer) | return Integer hours as a Period for DADD or DSUBSTRACT | |
DMILLIS(DateTime) | return the milliseconds of the DateTime | |
DMILLIS(Integer) | return Integer milliseconds as a Period for DADD or DSUBSTRACT | |
DMINS(DateTime) | return the minutes of the hour of the DateTime | |
DMINS(Integer) | return Integer minutes as a Period for DADD or DSUBSTRACT | |
DMONTHS(DateTime) | return the month of the year of the DateTime | |
DMONTHS(Integer) | return Integer months as a Period for DADD or DSUBSTRACT | |
DNOW() | return the current system time as DateTime | |
DSECS(DateTime) | return the seconds of the DateTime | |
DSECS(Integer) | return Integer seconds as a Period for DADD or DSUBSTRACT | |
DSUBTRACT(DateTime, Period) | subtract a Period from a date | for example, |
DYEARS(DateTime) | return the year of the DateTime | |
DYEARS(Integer) | return Integer years as a Period for DADD or DSUBSTRACT | |
TO_DATE(Long) | convert an epoch time value to a DateTime | See MultiLogApp for an example. |
TO_DATE(Object) | convert a Date, sql.Date. sql.Timestamp, Long, or String to a DateTime | For String input, recommended only for patterns not supported by TO_DATEF. Depending on the format of the input value, output format may be an ISO-formatted date, yyyy/MM/dd, yyyy/MM/dd with time, yyyy-MMM-dd, yyyy-MMM-dd with time, or yyyy/MM/dd HH:mm:ss.SSS. Use TO_Date(Object, String) for other patterns. When using an aggregate function on a DateTime field, use TO_DATE to convert the returned object to a DateTime, for example, |
TO_DATE(Object, String) | convert a String to a DateTime using any org.joda.time.format.DateTimeFormat pattern | Recommended only for patterns not supported by TO_DATEF. See MultiLogApp for an example. |
TO_DATEF(Object, String) | convert a String to a DateTime using an org.joda.time.format.DateTimeFormat pattern containing only y, M, d, h, m, s, and S | TO_DATEF is over ten times faster than the TO_DATE functions, so is preferred for supported formats. See the joda-time API reference for information on writing pattern strings; see PosApp for an example. |
TO_STRING(DateTime, String) | convert a DateTime to a String with specific format | |
TO_ZONEDDATETIME (Long) | convert an epoch time value to a java.time.ZonedDateTime | |
TO_ZONEDDATETIME (Object) | convert a String to a java.time.ZonedDateTime using the yyyy-MM-dd HH:mm:ss.SSSSSSSSS z pattern | If the String does not match the yyyy-MM-dd HH:mm:ss.SSSSSSSSS z pattern, use TO_ZONEDDATETIME(Object,String). |
TO_ZONEDDATETIME (Object, String) | convert a String to a java.time.ZonedDateTime using any org.joda.time.format.DateTimeFormat pattern | See the joda-time API reference for information on writing pattern strings. |
Striim supports all date functions natively associated with Joda-Time. See http://joda-time.sourceforge.net/apidocs for more information.
JSONNode functions
Use the following functions in CQs with an input and/or output stream of type JSONNodeEvent, or to create or manipulate any other JSONNode objects.
When the JSONNode objects are supplied by the CQ's input stream, JsonNode node
is the DATA element of JSONNodeEvent. If there is more than one JSONNodeEvent input stream, choose one by using an alias for the stream, for example, s.data
.
function | description | notes |
---|---|---|
AVROTOJSON(Object datum, Boolean IgnoreNulls) | convert an Avro node to a JSON node | Object datum must be an Avro GenericRecord present in an AvroEvent output by a source using an AvroParser. If Boolean IgnoreNulls is true, any Avro fields with null values will be omitted from the JSON, so, for example, |
clearUserData() |
| |
JSONArrayAdd(JsonNode node, Object value) | add object value at the end of array node | Use |
JSONArrayInsert(JsonNode node, int index, Object value) | add object value as an element at position index in array node | Use |
JSONFrom(Object value) | create a JSONNode from object value | For example, |
JSONGetBoolean(JsonNode node, String field) | get a Boolean value from specified field of JSONNode node | If the field is a Boolean, returns true or false. For other types, returns false. |
JSONGetDouble(JsonNode node, String field) | get a double value from specified field of JSONNode node | If the field is numeric (that is, isNumber() returns true), returns a 64-bit floating point (double) value. For other types, returns 0.0. For integer values, conversion is done using default Java type coercion. With BigInteger values, this may result in overflows. |
JSONGetInteger(JsonNode node, String field) | get an integer value from specified field of JSONNode node | If the field is numeric (that is, isNumber() returns true), returns an integer value. For other types, returns 0. For floating-point numbers, the value is truncated using default Java type coercion. |
JSONGetString(JsonNode node, String field) | get a string value from specified field of JSONNode node | Non-string values (that is, ones for which isTextual() returns false) are returned as null. Empty string values are returned as empty strings. |
JSONNew() | create an empty JSONNode object | |
JSONRemove(JsonNode node, Collection< String >fieldNames) | remove specified fields from of JSONNode node | For example, |
JSONSet(JsonNode node, String field, Object value) | set the value specified field in specified JSONNode to object value | Overwrites any existing value. Object value must be deserialized as per Jackson ObjectMapper.readTree. |
makeJSON(String jsonText) | create a JSONNode |
|
putUserdata() |
| |
removeUserData() |
| |
TO_JSON_NODE(Object obj) | convert object to a JSON node | Object must be in ObjectMapper.readTree format. |
USERDATA() |
|
Masking functions
The primary use for these functions is to anonymize personally identifiable information, for example, as required by the European Union's General Data Protection Regulation.
The String value
argument is the name of the field containing the values to be masked.
The String functionType argument is ANONYMIZE_COMPLETELY, ANONYMIZE_PARTIALLY, or a custom mask:
ANONYMIZE_COMPLETELY will replace all characters in the field with x.
ANONYMIZE_PARTIALLY will use a default mask specific to each function, as detailed below.
A custom mask lets you define which characters to pass and which to mask. A custom mask may include any characters you wish. For example, with maskPhoneNumber, the mask ###-abc-defg would mask 123-456-7890 as 123-abc-defg. See Changing and masking field values using MODIFY and Modifying and masking values in the WAEvent data array using MODIFY for examples.
function | notes |
---|---|
maskCreditCardNumber(String value, String functionType) | Input must be of the format ####-####-####-#### or ################. For the value 1234-5678-9012-3456, partially anonymized output would be xxxx-xxxx-xxxx-3456 and fully anonymized would be xxxx-xxxx-xxxx-xxxx. For the value 1234567890123456, partially anonymized output would be xxxxxxxxxxxx3456 and fully anonymized would be xxxxxxxxxxxxxxxx. |
maskEmailAddress(String value, String functionType) | Input must be a valid email address. For the value msmith@example.com, partially anonymized output would be mxxxxx@example.com and fully anonymized would be xxxxxxxxxxxxxxxxxx. |
maskGeneric(String value, String functionType) | Input may be of any length. Partially anonymized output masks all but the last four characters, fully anonymized masks all characters. |
maskPhoneNumber(String value, String functionType) | The input field format must be a ten-digit telephone number in the format ###-###-####, (###)-###-####, ##########, +1-###-###-####, +1(###)###-####, +1##########, or +1(###)#######. For the value 123-456-7890 or +1-123-456-7890, partially anonymized output would be xxx-xxx-7890 and fully anonymized would be xxx-xxx-xxxx. If you use a custom mask and the input field values are of varying lengths, use ELSE functions to handle each length. See Changing and masking field values using MODIFY for an example. |
maskPhoneNumber(String value, String regex, Integer group) | The |
maskSSN(String value, String functionType) | The input field format must be ###-##-#### (US Social Security number format). For the value 123-45-6789, partially anonymized output would be xxx-xx-6789 and fully anonymized would be xxx-xx-xxxx. |
The following example shows how to mask telephone numbers from various countries that have different lengths:
CREATE SOURCE PhoneNumbers USING FileReader ( positionbyeof: false, directory: 'Samples', wildcard: 'EUPhoneNumbers.csv' ) PARSE USING DSVParser ( header: true, trimquote: false ) OUTPUT TO phoneNumberStream ; CREATE CQ FilterNameAndPhone INSERT INTO TypedStream SELECT TO_STRING(data[0]) as country, TO_STRING(data[1]) as phoneNumber FROM phoneNumberStream p; CREATE CQ MaskPhoneNumberBasedOnPattern INSERT INTO MaskedPhoneNumber SELECT country, maskPhoneNumber(phoneNumber, "(\\\\d{0,4}\\\\s)(\\\\d{0,4}\\\\s)([0-9 ]+)", 1, 2) FROM TypedStream; CREATE TARGET MaskedPhoneNumberOut USING FileWriter ( filename: 'MaskedData' ) FORMAT USING DSVFormatter() INPUT FROM MaskedPhoneNumber;
Within the regular expression, groups 1 and 2 (exposed) are \\\\d{0,4}\\\\s
, which represents zero to four digits followed by a space, and group 3 (masked) is ([0-9 ]+)
, which represents zero to 9 digits.
If Striim/Samples/EUPhoneNumbers.csv
contains the following:
country,phoneNumber AT,43 5 1766 1001 UK,44 844 493 0787 UK,44 20 7730 1234 DE,49 69 86 799 799 DE,49 211 42168340 IE,353 818 365000
the output file will contain:
AT,435xxxxxxxx UK,44844xxxxxxx UK,4420xxxxxxxx DE,4969xxxxxxxx DE,49211xxxxxxxx IE,353818xxxxxx
Creating a masking CQ in the web UI
You can use the Field Masker event transformer to create masking CQs.

Drag Field Masker into the workspace and drop it.
Name the CQ.
Select the input stream.
Click ADD COLUMN and select a column to include in the output.
To pass the field unmasked, do not select a masking function. To mask it, select the appropriate masking function.
Optionally, change the alias.
Repeat steps 4-6 for each field to be included in the output.
Select or specify the output, then click Save.
With the masking CQ above, using FileWriter with JSONFormatter, if the input was:
"Stuart, Mary",1234-5678-9012-3456
the masked output would be:
{ "name":"Stuart, Mary", "cc":"xxxxxxxxxxxxxxx3456" }
If you wish to edit the SELECT statement, click Convert to CQ. When you click Save, the component will be converted to a regular CQ, and if you edit it again the masking UI will no longer be available.
Numeric functions
function | description |
---|---|
NVL(Object, Object) | return the first object if it is not null, otherwise return the second object, for example: NVL(COUNT(*),0) NVL(ROUND_DOUBLE(SUM(Duration/60),1),0) |
ROUND_DOUBLE(Object, Object) | round a double to the specified number of places |
ROUND_FLOAT(Object, Object) | round a float to the specified number of places |
TO_DOUBLE(Object) | convert a byte, float, integer, long, short, or string to a double |
TO_FLOAT(Object) | convert a byte, double, integer, long, short, or string to a float |
TO_INT(Object): | convert a byte, double, float, long, short, or string to an integer. To convert a JSON object to an integer, use this syntax instead: |
TO_LONG(Object) | convert a byte, double, float, integer, short, or string to a long |
TO_SHORT(Object) | convert a byte, double, float, integer, long, or string to a short |
ParquetEvent functions
ParquetEvent events are generated by the Parquet parser. See the Parquet Parser for details. Use the following functions in CQs that use a ParquetEvent input or output stream, or to create or manipulate any other ParquetEvent objects.
function | description | notes |
---|---|---|
putUserData() | Works exactly like the | See Adding user-defined data to JSONNodeEvent streams for details. |
USERDATA(ParquetEvent event, String key) | Works exactly like the | See Adding user-defined data to JSONNodeEvent streams for details. |
String functions
function | description | notes |
---|---|---|
ARLEN(String) | returns the number of fields in the specified array | see Handling variable-length events with CQs for an example |
IP_CITY(String) | get the city for an IP address | uses MaxMind GeoIP |
IP_COUNTRY(String) | get the country for an IP address | uses MaxMind GeoIP |
IP_LAT(String) | get the latitude for an IP address | uses MaxMind GeoIP |
IP_LON(String) | get the longitude for an IP address | uses MaxMind GeoIP |
match(String s, String regex) match(String s, String regex, Integer groupNumber) | match the string using the specified regex expression. You can optionally specify the capture group number (the default is 0). | supports only single return value )see Using regular expressions (regex)) |
maxOccurs(String) | value that had the maximum occurrences in the String | see MultiLogApp for examples |
replaceString(Event s, String findString, String newString) | for input stream s, replaces all occurrences of findString (in all fields) with newString | For example, Use only with events of user-defined types. |
replaceStringRegex(Event s, String regex, String newString) | for input stream s, replaces all strings (in all fields) that match the specified regex expression with newString | For example, Use only with events of user-defined types. |
SLEFT(Object, Integer) | returns only the characters to the left of position Integer from the object | |
SRIGHT(Object, Integer) | returns only the characters to the right of position Integer from the object | for example, |
TO_BOOLEAN(Object) | convert a string to a Boolean | |
TO_STRING(Object) | convert any object to a string |
WAEvent functions
Use the following functions in CQs with an input stream of type WAEvent.
function | description | notes |
---|---|---|
BEFORE(String) / BEFOREORDERED(String) | returns the values in the WAEvent | see Using the DATA(), DATAORDERED(), BEFORE(), and BEFOREORDERED() functions |
changeOperationToInsert | See "To Staging" in Using database event transformers. | |
clearUserdata | ||
DATA[Integer] | returns the value from field number Integer in a WAEvent | |
DATA(String) / DATAORDERED(String) | returns the values in the WAEvent | see Parsing the fields of WAEvent for CDC readers , Using the DATA() function, and Using the DATA(), DATAORDERED(), BEFORE(), and BEFOREORDERED() functions |
IS_PRESENT() | ||
maxOccurs(String) | value that had the maximum occurrences in the String | see MultiLogApp for examples |
META(<stream name>, key) | extracts a value from a WAEvent METADATA map | |
MODIFY() | See Changing and masking field values using MODIFY and Modifying and masking values in the WAEvent data array using MODIFY. | |
putUserdata | ||
replaceData() | See Modifying the WAEvent data array using replace functions. |
|
replaceString() | See Modifying the WAEvent data array using replace functions. | |
replaceStringRegex() | See Modifying the WAEvent data array using replace functions. | |
send() | ||
USERDATA(stream name,key) | extracts a value from a WAEvent USERDATA map | |
VALUE(stream name,key) | returns the value in the specified WAEvent stream that matches the specified key | See NetFlow Parser, NVP (name-value pair) Parser, or SNMP Parser for examples of use. |
Miscellaneous functions
function | notes |
---|---|
CONSTRAINED_MULTIPLE_LINEAR_REGRESSION() | |
CONSTRAINED_POLYNOMIAL_REGRESSION() | |
CONSTRAINED_SIMPLE_LINEAR_REGRESSION() | |
eventList() | See Using EVENTLIST. |
getAppInvoker(String applicationName) | Returns the name of the Striim user that started the application. |
ITERATOR() | See Using ITERATOR. |
MULTIPLE_LINEAR_REGRESSION() | |
NSK_CNVT_TXNID_TO_UNSIGNED() | |
NSK_TXN_STRING() | |
NSK_TXNS_ARE_SAME() | |
POLYNOMIAL_REGRESSION() | |
PREV() | |
SIMPLE_LINEAR_REGRESSION() |
List of reserved keywords
The following reserved keywords may not be used as identifiers in TQL applications or queries. The entries in lowercase are Java keywords that may be used as identifiers provided they are in uppercase or have initial capitals.
abstract ADD ADDONS ADMIN_UI ALIAS ALL ALTER AND ANY APPLICATION APPLICATIONCOUNT APPLICATIONS APPS_UI AS ASC assert AUTORESUME BACKUP BETWEEN boolean break BY byte CACHE CACHES CASCADE case CASE CAST catch CDUMP char CHECKPOINT CID class CLASS CLUSTER CONFIG CONNECT const CONTEXT continue CPUUSAGE CQ CQS CREATE CROSS DASHBOARD DASHBOARD_UI DASHBOARDS DATA DATE DATETIME DAY DAYS default DEFAULT DEFINE DELETE | DEPLOY DEPLOYMENTGROUP DEPLOYMENTGROUPS DESC DESCRIBE DETAILS DG DGS DISABLE DISCARD DISTINCT do double DROP DUMP else ELSE ENABLE ENCRYPTION END ENRICH enum ERROR ERRORS EVENT EVENTSIZE EVENTTABLE EVENTTABLES EVERY EXCACHEBUFFERSIZE EXCEPTIONHANDLER EXCEPTIONSTORE EXCEPTIONSTORES EXCLUDE EXEC EXIT EXPORT extends EXTERNAL false FALSE final finally float FLOW FLOWS for FOR FORCE FORMAT FROM FULL goto GRACE GRANT GROUP GROUPS HAVING HELP | HISTORY HOUR HOURS IDENTIFIED IDLE if IMMEDIATE implements import IMPORT IN INCLUDE INITIALIZER INNER INPUT INPUTOUTPUT INSERT instanceof INSTANCEOF int interface INTERVAL INTO IS ISTREAM ITERATOR JAR JOIN JUMPING KEEP KEY LAST LATENCY LDAP LEE LEFT LIBRARIES LICENSE LIKE LIMIT LINEAGE LINK LIST LOAD long MAP MATCH_PATTERN MAXIMUM MAXLIMIT MAXRETRIES MDUMP MEMORY MEMSIZE MERGE METER MGET MINIMUM MINUTE MINUTES | MODIFY MON MONITOR MONITOR_UI MONTH NAMEDQUERIES NAMEDQUERY NAMESPACE NAMESPACES native new NEW NODE NONE NOT null NULL OBJECTS OF OFF OFFSET ON ONE OPEN OPENPROCESSORS OPENTRANSACTIONS OR ORDER OUTER OUTPUT OVER package PAGE PAGES PARALLELIZE PARSE PARTITION PASSPHRASE PATHS PC PERIOD PERMISSION PERSIST PLAN POLICY POLICYCONFIG PREVIEW private PROCESSOR PROPERTIES PROPERTYSET PROPERTYSETS PROPERTYTEMPLATE PROPERTYTEMPLATES PROPERTYVARIABLE PROPERTYVARIABLES protected public PUSH | QUERY QUERYVISUALIZATION QUERYVISUALIZATIONS QUIESCE QUIT RANGE READ REALTIME REBALANCE RECOMPILE RECOVERY REMOVE REPLACE REPORT RESET RESUME RETRYINTERVAL return REVOKE RIGHT ROLE ROLES ROUTE ROUTER ROW ROWS RSTREAM SAMPLE SCHEDULE SCHEMA SECOND SECONDS SELECT SELECTIVITY SERVER SERVERS SESSION SESSIONS SET short SHOW SLEEP SLIDE SMARTALERT SMART SORTER SORTERS SOURCE SOURCEPREVIEW_UI SOURCES SPOOL START static STATIC STATS STATUS STOP STREAM STREAM_GENERATOR | STREAMS strictfp SUBSCRIPTION SUBSCRIPTIONS super switch synchronized TARGET TARGETS TEST THEN this throw throws TIMEOUT TIMESTAMP TO TRANSACTION TRANSACTIONID transient true TRUE try TTL TYPE TYPES UNDEPLOY UNKNOWN UNLOAD UPDATE USE USER USERS USING VALIDATION VALUETYPE VAULT VAULTKEY VAULTS VAULTSPEC VAULTVALUE VERSION VISUALIZATION void volatile WACACHE WACACHES WACTIONSTORE WACTIONSTORES WAIT WHEN WHERE while WI WINDOW WINDOWS WITH WITHIN WRITE YEAR |
If you mistakenly use a reserved keyword as an identifier, you will receive a syntax error. For example:
Syntax error at: Create Type Order ^^^^^