SRC
All tql scripts must start with one of the data source functions.
There are several SRC functions are included. For example, SQL() produces records by querying machbase-neo database or even external (bridged) database with the given sql statement. FAKE() generates artificial data. CSV() can read csv data, BYTES() reads arbitrary binary data from file system or client’s HTTP request and MQTT payload.

SQL()
Syntax: SQL( [bridge(),] sqltext [, params...])
bridge()bridge(’name’) If a bridge is given, the SQL query is executed on the bridgesqltextstring : SQL SELECT statement to retrieve data from database. Use backtick(`) for multi-line sql string.params: Variadic arguments for the bind arguments for the query.
Example)
- Query to machbase
SQL (`
SELECT time, value
FROM example
WHERE name ='temperature'
LIMIT 10000
`)- Query with variadic arguments
SQL(`SELECT time, value FROM example WHERE name = ? LIMIT ?`,
param('name') ?? 'temperature',
param('limit') ?? 10)- Query to bridge database
SQL( bridge('sqlite'), `SELECT * FROM EXAMPLE`)SQL(
bridge('sqlite'),
`SELECT time, value FROM example WHERE name = ?`,
param('name') ?? "temperature")SQL_SELECT()
Syntax: SQL_SELECT( fields..., from(), between() [, limit()] )
Since v8.0.15
fieldsstring: column names, multiple columns are possible.
SQL_SELECT() source function provides same functionality with SQL(), but it simplifies the usage by standardization option functions other than using the raw SQL statement.
This function actually works equivalent to SQL() but it takes query conditions via simplified options instead of a full SQL statement.
It assigns time range condition easier way than using WHERE condition in SQL statement.
The example below process data by query SELECT time, value FROM example WHERE NAME = 'temperature' AND time BETWEEN....
SQL_SELECT(
'time', 'value',
from('example', 'temperature'),
between('last-10s', 'last')
)is equivalent with the SQL() statement below
SQL(`SELECT
time, value
FROM
EXAMPLE
WHERE
name = 'TAG1'
AND time BETWEEN (
SELECT MAX_TIME-10000000000
FROM V$EXAMPLE_STAT
WHERE name = 'temperature')
AND (
SELECT MAX_TIME
FROM V$EXAMPLE_STAT
WHERE name = 'temperature')
LIMIT 0, 1000000
`)from()
Syntax: from( table, tag [, time_column [, name_column] ] )
It provides table name and tag name to SQL_SELECT() function generating SQL internally. It may equivalent to ... FROM <table> WHERE NAME = <tag> ....
tablestring table nametagstring tag nametime_columnstring specify “time” column name, if omitted default is'time'.name_columnstring specify “name” column name, if omitted default is'name'. Since v8.0.5
between()
Syntax: between( fromTime, toTime [, period] )
It provides time range condition to SQL_SELECT() function generating SQL internally.
It may equivalent to ... WHERE ... TIME BETWEEN <fromTime> AND <toTime>....
fromTimestring,number time expression with ’now’ and ’last’ as string, Or assign number as unix epoch time in nanosecondtoTimestring,number time expressionperiodstring,number duration expression, Or assign number for the unix epoch time in nanoseconds. Logically only positive period makes sense.
You can specify fromTime and toTime with ’now’ and ’last’ with delta duration expression.
For example, 'now-1h30m' specifies the time that 1 hour 30 minutes before from now.
'last-30s' means 30 seconds before the latest(=max) time of the base_time_column.
If period is specified it will generate ‘GROUP BY’ time expression with aggregation SQL functions. In this case the base time column should be included in the fields arguments of the SQL_SELECT().
If it is required to use string expressions for the fromTime, toTime instead of unix epoch nano seconds, use parseTime() to convert
string-time-expression to time value. Refer to the document about utility function parseTime()
Example)
between( parseTime("2023-03-01 14:00:00", "DEFAULT", tz("Local")),
parseTime("2023-03-01 14:05:00", "DEFAULT", tz("Local")))limit()
Syntax: limit( [offset ,] count )
It will be translated into SELECT... LIMIT offset, count statement.
offsetnumber default is0. if omittedcountnumber
CSV()
Syntax: CSV( file(file_path_string) | payload() [, charset()] [,field()...[, header()]] )
Load CSV and yield key-value records, the key is generated in sequence number and the fields of CSV become the value of the record.
The string parameter of ‘file’ should be absolute path to the CSV.
If payload() is used, it will reads CSV from HTTP POST request body stream. It is useful to make an API that writes data into database when remote client sends data by HTTP POST.
file() | payload()input streamfield(idx, type, name)specifying fieldsheader(bool)specifies if the first line of input stream is a headercharset(string)specify charset if the CSV data is in non UTF-8. Since v8.0.8logProgress([int])logs progress messages everynrows. Ifnis omitted, it defaults to 500,000. Since v8.0.29
Example)
// Read CSV from HTTP request body.
// ex)
// barn,1677646800,0.03135
// dew_point,1677646800,24.4
// dishwasher,1677646800,3.33e-05
CSV(payload(),
field(0, stringType(), 'name'),
field(1, timeType('s'), 'time'),
field(2, floatType(), 'value'),
header(false)
)
APPEND(table('example'))Combination of CSV() and APPEND() as above example, it is simple, useful. Be aware that it is 5 times slower than command line import command, but still faster than INSERT() function when writing more than several thousands records per a HTTP request.
Use ?? operator to make it works with or without HTTP POST request.
CSV(payload() ?? file('/absolute/path/to/data.csv'),
field(0, floatType(), 'freq'),
field(1, floatType(), 'ampl')
)
CHART_LINE()file()
Syntax: file(path)
Open the given file and returns input stream for the content. the path should be the absolute path to the file.
pathstring path to the file to open, or http url where to get resource from.
If path starts with “http://” or “https://”, it retrieves the content of the specified http url
Since v8.0.7
. Otherwise it is looking for the path on the file system.
The code below shows how to call a remote HTTP api with file() that it actually invokes machbase-neo itself for the demonstration purpose, the SQL query which safely url escaped by escapeParam().
CSV( file(`http://127.0.0.1:5654/db/query?`+
`format=csv&`+
`q=`+escapeParam(`select * from example limit 10`)
))
CSV() // or JSON()
payload()
Syntax: payload()
Returns the input stream of the request content if the tql script has been invoked from HTTP POST or MQTT PUBLISH.
field()
Syntax: field(idx, typefunc, name)
Specify field-types of the input CSV data.
idxnumber 0-based index of the field.typefuncspecify the type of the field. (see below)namestring specify the name of the field.
| type function | type |
|---|---|
stringType() | string |
doubleType() | double |
datetimeType() | datetime |
boolType() | boolean Since v8.0.20 |
floatType() | deprecated, use doubleType()
Since v8.0.20 |
timeType() | deprecated, use datetimeType()
Since v8.0.20 |
The stringType(), boolType() and floatType() take no arguments, timeType() function takes one or two parameters for proper conversion of date-time data.
If the input data of the field specifies time in unix epoch time, specify the one of the time units ns, us, ms and s.
datetimeType('s')datetimeType('ms')datetimeType('us')datetimeType('ns')
The input field represents time in human readable format, it is requires to specifying how to parse them including time zone.
datetimeType('DEFAULT', 'Local')
CSV(payload() ??
`name,2006-01-02 15:04:05.999,10`,
field(1, datetimeType('DEFAULT', 'Local'), 'time'))
CSV()datetimeType('RFC3339', 'EST')
CSV(payload() ??
`name,2006-01-02T15:04:05.999Z,10`,
field(1, datetimeType('RFC3339', 'EST'), 'time'))
CSV()If the timezone is omitted, it assumes ‘UTC’ by default.
datetimeType('RC822')
The first argument of the timeType() directs how to parse the input data that uses the same syntax with timeformat() function. Please refer to the description of the timeformat() function for the timeformat spec.
charset()
Syntax: charset(name)
Since v8.0.8
namestring character set name
Supported character set.
UTF-8, ISO-2022-JP, EUC-KR, SJIS , CP932, SHIFT_JIS, EUC-JP, UTF-16, UTF-16BE, UTF-16LE, CP437, CP850, CP852, CP855, CP858, CP860, CP862, CP863, CP865, CP866, LATIN-1, ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-10, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16, KOI8R, KOI8U, MACINTOSH, MACINTOSHCYRILLIC, WINDOWS1250, WINDOWS1251, WINDOWS1252, WINDOWS1253, WINDOWS1254, WINDOWS1255, WINDOWS1256, WINDOWS1257, WINDOWS1258, WINDOWS874, XUSERDEFINED, HZ-GB2312
SCRIPT()
Supporting user defined script language.
See SCRIPT section for the details with examples.
HTTP()
Request HTTP Request within simple DSL.
See HTTP section for the details with examples.
BYTES(), STRING()
Syntax: BYTES( src [, separator(char), trimspace(boolean) ] )
Syntax: STRING( src [, separator(char), trimspace(boolean) ] )
srcdata source, it can be one ofpayload(),file()and a constant textstring.separator(char)optional setseparator("\n")to read a line by line, or omit it to read whole string in a time.trimspace(boolean)optional trim spaces, default isfalse
Split the input content by separator and yield records that separated sub content as value and the key is increment number of records.
Example)
STRING('A,B,C', separator(","))yields 3 records["A"],["B"]and["C"].STRING('A,B,C')yields 1 record["A,B,C"].
The both of BYTES() and STRING() works exactly same,
except the value types that yields, as the function’s name implies,
BYTES() yields value in ‘array of byte’ and STRING() yields string value.
STRING(payload() ?? `12345
23456
78901`, separator("\n"))The example code above generates 3 records ["12345"], ["␣␣␣␣␣␣␣␣␣␣23456"], ["␣␣␣␣␣␣␣␣␣␣78901"].
STRING(payload() ?? `12345
23456
78901`, separator("\n"), trimspace(true))The example code above generates 3 records ["12345"], ["23456"], ["78901"].
STRING( file(`http://example.com/data/words.txt`), separator("\n") )It retrieves the content from the http address. file() supports http url
Since v8.0.7
.
ARGS()
Syntax: ARGS()
Since v8.0.7
ARGS generates a record that values are passed by parent TQL flow as arguments.
It is purposed to be used as a SRC of a sub flow within a WHEN...do() statement.
| |
The code print log message on the output console.
OUTPUT: 2 WORLDFAKE()
Syntax: FAKE( generator )
generatorone of theoscillator(),meshgrid(),linspace(),arrange(),csv(),json()
Producing “fake” data by given generator.
oscillator()
Syntax: oscillator( freq() [, freq()...], range() )
Generating wave data by given frequency and time range. If provide multiple freq() arguments, it composites waves.
| |
| |
freq()
Syntax: freq( frequency, amplitude [, bias, phase])
It produce sine wave by time amplitude * SIN( 2*Pi * frequency * time + phase) + bias.
frequencynumber frequency in Hertz (Hz).amplitudenumberbiasnumberphasenumber in radian
range()
Syntax: range( fromTime, duration, period )
It specifies time range from fromTime to fromTime+duration.
fromTimestring|number ’now’ and ’last’ is available for string type, Or assign number as unix epoch time in nanoseconddurationstring|number duration expression, Or assign number in nanoseconds. ex)'-1d2h30m','1s100ms'periodstring|number duration expression, Or assign number in nanoseconds. Logically only positive period makes sense.
arrange()
Syntax: arrange(start, stop, step)
Since v8.0.12
startnumberstopnumberstepnumber
| |
1
1.5
2linspace()
Syntax: linspace(start, stop, num)
It generates 1 dimension linear space.
| |
1
2
3 | |

meshgrid()
Syntax: meshgrid(xseries, yseries)
It generates meshed values - [xseries, yseries].
| |
1,10
1,20
1,30
2,10
2,20
2,30
3,10
3,20
3,30 | |

csv()
Syntax: csv(content)
Since v8.0.7
contentstring csv content
It generates records from the given csv content.
| |
A,10,true
B,20,false
C,30,truejson()
Syntax: json({...})
Since v8.0.7
It generates records from the given multiple json array.
| |
A,10,true
B,20,false
C,30,true