Global functions
Rell has a diverse collection of built-in functions that you can use to perform common tasks and write efficient Rell code.
Essential calculations
abs(value: integer): integer
Gets the absolute value of an integer.
Parameters:
value: integer- The integer for which to calculate the absolute value.
Returns:
- The absolute value of the input
valueas an integer.
abs(value: big_integer): big_integer
Gets the absolute value of a big integer.
Parameters:
value: big_integer- The big integer for which to calculate the absolute value.
Returns:
- The absolute value of the input
valueas a big integer.
abs(value: decimal): decimal
Gets the absolute value of a decimal.
Parameters:
value: decimal- The decimal for which to calculate the absolute value.
Returns:
- The absolute value of the input
valueas a decimal.
function max(value1: integer, value2: integer): integer
Identifies the larger of two integer values.
Parameters:
value1: integer- The first integer to compare.value2: integer- The second integer to compare.
Returns:
- The larger of the two input integers.
function max(value1: big_integer, value2: big_integer): big_integer
Determines the larger of two big integer values.
Parameters:
value1: big_integer- The first big integer to compare.value2: big_integer- The second big integer to compare.
Returns:
- The larger of the two input big integers.
function max(value1: decimal, value2: decimal): decimal
Determines the larger of two decimal values.
Parameters:
value1: decimal- The first decimal to compare.value2: decimal- The second decimal to compare.
Returns:
- The larger of the two input decimals.
function min(value1: integer, value2: integer): integer
Determine the smaller of two integer values.
Parameters:
value1: integer- The first integer to compare.value2: integer- The second integer to compare.
Returns:
- The smaller of the two input integers.
function min(value1: big_integer, value2: big_integer): big_integer
Identify the smaller of two big integer values.
Parameters:
value1: big_integer- The first big integer to compare.value2: big_integer- The second big integer to compare.
Returns:
- The smaller of the two input big integers.
function min(value1: decimal, value2: decimal): decimal
Pinpoint the smaller of two decimal values.
Parameters:
value1: decimal- The first decimal to compare.value2: decimal- The second decimal to compare.
Returns:
- The smaller of the two input decimals.
Collection checks
empty(value: T?): boolean
Determines if a value is null or an empty collection.
Parameters:
value: T?- The value to check for emptiness, which can be any nullable type.
Returns:
Trueif the value is null or an empty collection,Falseotherwise.
empty(list: list<T>): boolean
Specifically checks if a list is empty.
Parameters:
list: list<T>- The list to check for emptiness.
Returns:
Trueif the list contains no elements,Falseotherwise.
empty(set: set<T>): boolean
Verifies if a set is empty.
Parameters:
set: set<T>- The set to check for emptiness.
Returns:
Trueif the set contains no elements,Falseotherwise.
empty(map: map<K, V>): boolean
Checks if a map is empty.
Parameters:
map: map<K, V>- The map to check for emptiness.
Returns:
Trueif the map contains no key-value pairs,Falseotherwise.
Nested at-expressions with empty()
The empty() function supports nested at-expressions, allowing them to access entities from an outer at-expression.
This enhancement enables more complex and efficient database queries.
Example:
user @* {
empty(company @* { .city == user.city })
}
Translated SQL query:
SELECT U."name"
FROM "c0.user" U
WHERE NOT EXISTS(
SELECT C."rowid"
FROM "c0.company" C
WHERE C."city" = U."city"
)
Usage in update and delete statements:
delete user @* { empty( company @* { .city == user.city } ) } ;
Notes on cardinality:
- Use
@*in nestedat-expressionsto ensure the entire query is executed as a single SQL query. - Using operators
@+,@?, or@will result in independent SQL queries, potentially reducing performance due to loading the entire result set into memory.
Simplified attribute matching:
- In the
wherepart of a nestedat-expression, you can useouter_entity.attributedirectly.
Example:
user @* {
empty(company @* { user.city })
}
exists(value: T?): boolean
Confirms the presence of a value.
Parameters:
value: T?- The value to check for existence, which can be any nullable type.
Returns:
Trueif the value is not null and contains elements (for collections),Falseotherwise.
exists(list: list<T>): boolean
Specifically verifies if a list contains elements.
Parameters:
list: list<T>- The list to check for the existence of elements.
Returns:
Trueif the list has at least one element,Falseif it's empty.
exists(set: set<T>): boolean
Determines if a set contains elements.
Parameters:
set: set<T>- The set to check for the existence of elements.
Returns:
Trueif the set has at least one element,Falseif it's empty.
exists(map: map<K, V>): boolean
Checks if a map contains key-value pairs.
Parameters:
map: map<K, V>- The map to check for the existence of key-value pairs.
Returns:
Trueif the map has at least one key-value pair,Falseif it's empty.
Nested at-expressions with exists()
The exists() function supports nested at-expressions, allowing them to access entities from an outer
at-expression. This enhancement enables more complex and efficient database queries.
Example:
user @* {
exists(company @* { .city == user.city })
}
Translated SQL query:
SELECT U."name"
FROM "c0.user" U
WHERE EXISTS(
SELECT C."rowid"
FROM "c0.company" C
WHERE C."city" = U."city"
)
Usage in update and delete statements:
delete user @* { not exists( company @* { .city == user.city } ) } ;
Notes on cardinality:
- Use
@*in nestedat-expressionsto ensure the entire query is executed as a single SQL query. - Using operators
@+,@?, or@will result in independent SQL queries, potentially reducing performance due to loading the entire result set into memory.
Simplified attribute matching:
- In the
wherepart of a nestedat-expression, you can useouter_entity.attributedirectly.
Example:
user @* {
empty(company @* { .city == user.city })
}
Output and logging
function print(...)
Prints a message to STDOUT.
Example:
print()- prints an empty line.print('Hello', 123)- prints "Hello 123".
Parameters:
...: Accepts any number of arguments to be printed, including strings, numbers, variables, and expressions.
Returns:
None(no explicit return value).
function log(...)
Generates a detailed record of program execution for debugging and analysis purposes.
Parameters:
...: Accepts any number of arguments to be logged, similar toprint.
Returns:
None(no explicit return value).
Cryptographic hashes
function keccak256(byte_array: byte_array): byte_array
Produces a 32-byte Keccak256 hash from a given byte array.
Parameters:
byte_array: byte_array- The byte array to be hashed.
Returns:
- A 32-byte byte array representing the Keccak256 hash of the input
byte_array.
function sha256(byte_array: byte_array): byte_array
Generates a 32-byte SHA-256 hash from a provided byte array.
Parameters:
byte_array: byte_array- The byte array to be hashed.
Returns:
- A 32-byte byte array representing the SHA-256 hash of the input
byte_array.
Signature verification
function verify_signature(message: byte_array, pubkey: pubkey, signature: byte_array): boolean
Verifies the authenticity of a given signature, ensuring data integrity and non-repudiation.
Parameters:
message: byte_array- The original message that was signed.pubkey: pubkey- The public key allegedly used for signing.signature: byte_array- The signature to be verified.
Returns:
Trueif the signature is valid for the given message and public key,Falseotherwise.
Ethereum public key recovery
function eth_ecrecover(r: byte_array, s: byte_array, rec_id: integer, hash: byte_array): byte_array
Derives the Ethereum public key from a signature and hash, enabling identity recovery in blockchain transactions.
Parameters:
r: byte_array- The R component of the elliptic curve signature.s: byte_array- The S component of the elliptic curve signature.rec_id: integer- The recovery ID, indicating which signature variant was used.hash: byte_array- The hash of the message that was signed.
Returns:
- The 64-byte Ethereum public key recovered from the provided signature and hash components.
Error handling with try_call
function try_call()
Catches exceptions within a function call, providing graceful error handling and fallback mechanisms.
Variants:
try_call(f: ()->T): T?- Calls the function
f. - Returns the result of
fon success ornullif an exception occurs.
- Calls the function
try_call(f: ()->unit): boolean- Calls the function
fthat doesn't return a value. - Returns
trueon success orfalseif an exception occurs.
- Calls the function
try_call(f: ()->T, fallback: T): T- Calls the function
f. - Returns the result of
fon success or the specifiedfallbackvalue if an exception occurs.
- Calls the function
The try_call method restores the state of a program in the event of a failure.
This means that even if the program writes data to the database, all changes will be reverted in case of an error.
Examples:
val int_or_null = try_call(integer.from_hex(s, *));- converts the hexadecimal stringsto an integer and assigns it toint_or_null, or assignsNoneif the conversion fails.val int_or_default = try_call(integer.from_hex(s, *), -1);- converts the hexadecimal stringsto an integer and assigns it toint_or_default, or assigns-1if the conversion fails.val l = try_call(list<integer>.from_gtv(my_gtv, *));- converts the GTVmy_gtvto a list of integers and assigns it tolor assignsNoneif the conversion fails.
Text pattern matching with text.like
text.like(pattern: text): boolean
The text.like() function provides a simple way to perform pattern matching, similar to the SQL LIKE clause. It
operates consistently in both interpreted expressions and at-expressions.
Parameters:
pattern: text- The pattern to match against the text, incorporating wildcards for flexibility.
Returns:
Trueif the text matches the pattern,Falseotherwise.
Special Characters:
_: Matches any single character, similar to the SQL LIKE clause.%: Matches any string of zero or more characters, enabling broader matching capabilities.
Examples:
-
Basic pattern matching:
print(name.like(% von %))- returns all names that have a von inside. -
Pattern matching in collections:
user @* { .name.like('% von %') }- returns all users whose names contain the substring " von ". -
Escaping special characters: To match the special characters
_or%, you need to escape them with a backslash (\). Note that in string literals, you must use a double backslash (\\) to produce a single backslash at runtime.title.like('string\\_with\\_underscores')- this matches the stringstring_with_underscoreswhere_is treated as a literal underscore rather than a wildcard.