Applies to VAST Cluster 5.5.
Operators combine values in SELECT lists, WHERE clauses and UPDATE ... SET, and a predicate is a condition built from them. This page covers where each predicate runs, in VAST DataBase or in the Query Engine, and how to write filters that VAST DataBase evaluates, then gives an entry for each operator group: what it does, its operand and result types, what it does with NULLs, and an example.
Functions on this page
| Group | Operators and predicates |
|---|---|
| Comparisons | =, <> (!=), <, <=, >, >=, BETWEEN, IN, NOT IN, IS DISTINCT FROM, struct fields |
| NULL and boolean tests | IS NULL, IS NOT NULL, IS TRUE and boolean columns |
| Logic | AND, OR, NOT |
| Pattern matching | LIKE, ILIKE, ESCAPE (also ~~, ~~*, like_escape), GLOB (also ~~~), SIMILAR TO, ~, ^@ |
| Arithmetic | +, -, *, /, //, %, **, ^, @ |
| Bitwise operators | &, |, xor, ~, <<, >> |
| List operators | ||, &&, @>, <@ |
| Other | not available |
How operators and predicates run
The Query Engine runs on the cluster's CNodes. A query's plan, which EXPLAIN shows, starts with a scan in VAST DataBase (VAST_SCAN): it reads only the columns the query uses, and evaluates the WHERE conditions it can push down, so rows that don't match never leave storage. A condition the scan can't evaluate becomes a FILTER step in the Query Engine, which tests every row the scan returns. Operators in the SELECT list are always computed in the Query Engine, on the rows the scan returns.
The scan evaluates a condition when it compares one column, as stored, with a constant, and an AND of such conditions, where each part can OR tests on the same column. The Query Engine computes constant expressions first, and rewrites some conditions into that shape: qty > 1 + 1, qty * 2 > 10 on an integer column, and CAST(ts AS DATE) = DATE '2026-10-02' on a TIMESTAMP column all push down.
| Pushed down to VAST DataBase | Evaluated in the Query Engine (FILTER) |
|---|---|
=, <>, !=, <, <=, >, >= against a constant of the column's type |
A function of the column: upper(name) = 'BOLT', abs(qty) > 5, COALESCE(qty, 0) > 5 |
BETWEEN |
NOT BETWEEN, IS DISTINCT FROM |
IN with consecutive integers |
IN with other values (up to four; five or more fail) |
OR on one column: id = 1 OR id = 3, qty < 6 OR qty > 30 |
OR across columns: id = 1 OR qty > 20 |
IS NULL, IS NOT NULL on a number or text column |
IS NULL on a list or struct column, or on a struct field |
flag = true, flag = false |
A bare boolean column: WHERE flag, NOT flag, flag IS TRUE |
A struct field compared with a constant: bin.aisle = 3 |
Two columns compared: qty > id |
LIKE with no wildcard (it becomes =) |
LIKE with a wildcard, every ILIKE, GLOB, SIMILAR TO, ~, ^@ |
NOT of one comparison: NOT (qty > 5) |
NOT of an AND; list operators such as tags && [...] |
An AND is split: in in_stock AND qty > 5, the scan evaluates qty > 5 and the FILTER step only in_stock, so the scan still drops the rows that fail qty > 5. Other clients have their own rules; see pushdowns.
Make filters faster
- Compare the column as stored with a constant. Move arithmetic to the constant side:
price > 0.4 / 2, notprice * 2 > 0.4. A function of a constant is computed once; a function of the column runs on every row in the Query Engine. - Match the constant to the column's type. On an
INTEGERcolumn,qty >= 6pushes down;qty > 5.5casts the column toDECIMALand runs in the Query Engine. - Test a boolean column with
= trueor= false.WHERE in_stockandWHERE NOT in_stockrun in the Query Engine;WHERE in_stock = truepushes down. - Write a list of values as
ORs on one column.id = 1 OR id = 3 OR id = 5pushes down;id IN (1, 3, 5)runs in the Query Engine, and anINlist of five or more such values fails. - Use a range instead of a prefix pattern.
name >= 'b' AND name < 'c'pushes down;name LIKE 'b%'doesn't. Text compares in byte order, so the range is case-sensitive, likeLIKE. - Rewrite
NOT BETWEENas two ranges.qty < 5 OR qty > 12pushes down.
Examples on this page
The examples connect with the ADBC driver, as in VAST Query Engine (ADBC), and work in a schema called docs_sql_fn_operators. Set QE_ENDPOINT, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and VASTDB_BUCKET (SQL reference), and run the blocks in order in one Python session. Below each block is the output you should see.
This block connects, defines the run() helper, and creates a table of five stock items. The last two have NULLs. It also defines where_it_runs(), which prints the rows a condition selects and whether VAST DataBase evaluated it (no FILTER step in the plan) or the Query Engine did:
import os
import re
import adbc_driver_manager
import adbc_driver_manager.dbapi as dbapi
import adbc_driver_vastdb
BUCKET = os.environ["VASTDB_BUCKET"]
SCHEMA = f'"{BUCKET}/docs_sql_fn_operators"'
conn = dbapi.connect(
driver=adbc_driver_vastdb.get_driver_path(),
db_kwargs={
"vast.db.endpoint": os.environ["QE_ENDPOINT"],
"vast.db.access_key": os.environ["AWS_ACCESS_KEY_ID"],
"vast.db.secret_key": os.environ["AWS_SECRET_ACCESS_KEY"],
},
autocommit=True,
)
def server_message(e):
"""The server's message in a driver error, without the request ID or the echoed statement."""
text = re.sub(r"\[req=0x[0-9a-f]+\]: ", "", str(e))
found = (re.search(r'message: "(.*?)", request_id', text, re.S)
or re.search(r"description: (.*)\)", text, re.S))
message = found.group(1) if found else text.strip().splitlines()[-1]
message = re.sub(r"^Plan query: '.*?' failed with: ", "", message, flags=re.S)
message = re.split(r"\\n|\n", message)[0].replace('\\"', '"')
return message.replace(BUCKET, "<bucket>")
def run(sql):
"""Run one statement. Print the rows it returns, or the error."""
try:
with conn.cursor() as cur:
cur.execute(sql)
rows = cur.fetchall() if cur.description else []
except (adbc_driver_manager.Error, OSError) as e:
print(f"{type(e).__name__}: {server_message(e)}")
else:
print(rows)
TABLE = f"{SCHEMA}.items"
def where_it_runs(condition):
"""Print the ids a WHERE condition selects, and where the condition runs."""
try:
with conn.cursor() as cur:
cur.execute(f"EXPLAIN SELECT id FROM {TABLE} WHERE {condition}")
plan = cur.fetchall()[0][1]
cur.execute(f"SELECT id FROM {TABLE} WHERE {condition} ORDER BY id LIMIT 10")
ids = [row[0] for row in cur.fetchall()]
except (adbc_driver_manager.Error, OSError) as e:
print(f"{condition:<48} {type(e).__name__}: {server_message(e)}")
else:
where = "Query Engine (FILTER)" if "FILTER" in plan else "pushed down"
print(f"{condition:<48} {str(ids):<16} {where}")
run(f"CREATE SCHEMA IF NOT EXISTS {SCHEMA}")
run(f"CREATE TABLE IF NOT EXISTS {TABLE} (id BIGINT, name VARCHAR, qty INTEGER, price DOUBLE, "
"in_stock BOOLEAN, added DATE, tags VARCHAR[], bin STRUCT(aisle INTEGER, shelf INTEGER))")
run(f"INSERT INTO {TABLE} VALUES "
"(1, 'bolt', 12, 0.25, true, DATE '2026-10-01', ['metal', 'small'], {'aisle': 1, 'shelf': 2}), "
"(2, 'Bracket', 5, 3.5, true, DATE '2026-10-02', ['metal'], {'aisle': 3, 'shelf': 1}), "
"(3, 'cable_tie', 40, 0.05, false, DATE '2026-10-03', ['plastic', 'small'], {'aisle': 2, 'shelf': 4}), "
"(4, 'washer', 7, 0.1, NULL, DATE '2026-10-04', NULL, NULL), "
"(5, NULL, 0, NULL, false, NULL, ['misc'], {'aisle': NULL, 'shelf': NULL})")
[]
[]
[(5,)]
Comparisons
Comparison operators
=, <> (or !=), <, <=, > and >= compare two values of the same kind: numbers, text, dates and timestamps, booleans, BLOB and UUID values, lists and structs.
- Returns:
BOOLEAN. - Types: a constant is cast to the column's type, so
qty = '12'works and pushes down. A text column compared with a number is cast to the number's type, soname = 12fails withCould not convert string 'bolt' to INT32. Text compares case-sensitively, in byte order:'Bracket' < 'bolt'is true. - NULLs: a comparison with NULL is NULL, so
WHERE qty > NULLselects no rows. To compare NULLs as values, use IS DISTINCT FROM. - Pushed down: against a constant of the column's type, or a constant expression such as
1 + 1orTIMESTAMP '2026-10-01 00:00:00' + INTERVAL 1 DAY.
for condition in ["qty >= 7", "name <> 'bolt'", "name < 'b'", "added > DATE '2026-10-02'",
"qty > 1 + 1", "qty > 5.5", "qty > id", "price * 2 > 0.4", "price > 0.4 / 2"]:
where_it_runs(condition)
run("SELECT 'Bracket' < 'bolt', 1 = NULL")
qty >= 7 [1, 3, 4] pushed down
name <> 'bolt' [2, 3, 4] pushed down
name < 'b' [2] pushed down
added > DATE '2026-10-02' [3, 4] pushed down
qty > 1 + 1 [1, 2, 3, 4] pushed down
qty > 5.5 [1, 3, 4] Query Engine (FILTER)
qty > id [1, 2, 3, 4] Query Engine (FILTER)
price * 2 > 0.4 [1, 2] Query Engine (FILTER)
price > 0.4 / 2 [1, 2] pushed down
[(True, None)]
BETWEEN
True if a value lies in a range, ends included: x BETWEEN a AND b is x >= a AND x <= b.
- Syntax:
x [NOT] BETWEEN a AND b - Returns:
BOOLEAN. Withagreater thanb, it's false. - NULLs: NULL if
x, or a bound it depends on, is NULL. - Pushed down:
BETWEENyes;NOT BETWEENno. Writex < a OR x > binstead.
for condition in ["qty BETWEEN 5 AND 12", "qty NOT BETWEEN 5 AND 12", "qty < 5 OR qty > 12"]:
where_it_runs(condition)
qty BETWEEN 5 AND 12 [1, 2, 4] pushed down
qty NOT BETWEEN 5 AND 12 [3, 5] Query Engine (FILTER)
qty < 5 OR qty > 12 [3, 5] pushed down
IN
True if a value equals one in a list.
- Syntax:
x [NOT] IN (v1, v2, ...) - Returns:
BOOLEAN. - NULLs: NULL if
xis NULL, or ifxisn't found and the list holds a NULL:2 IN (1, NULL)and2 NOT IN (1, NULL)are both NULL. - Pushed down: a list of consecutive integers, of any length, becomes a range and pushes down. Any other list of up to four values, numbers or text, is evaluated in the Query Engine.
- Errors: a list of five or more values that aren't consecutive integers fails with
The operator 'HASH_JOIN' type=32 is currently not supported., as doesIN (SELECT ...). Write the values asORs on the column instead, which pushes down at any length (IN lists).
for condition in ["id IN (1, 2, 3)", "id IN (1, 3, 5)", "id = 1 OR id = 3 OR id = 5",
"name IN ('bolt', 'washer')", "id IN (1, 3, 5, 7, 9)", "id = 1 OR id = 3 OR id = 5 OR id = 7 OR id = 9"]:
where_it_runs(condition)
id IN (1, 2, 3) [1, 2, 3] pushed down
id IN (1, 3, 5) [1, 3, 5] Query Engine (FILTER)
id = 1 OR id = 3 OR id = 5 [1, 3, 5] pushed down
name IN ('bolt', 'washer') [1, 4] Query Engine (FILTER)
id IN (1, 3, 5, 7, 9) InternalError: The operator 'HASH_JOIN' type=32 is currently not supported.
id = 1 OR id = 3 OR id = 5 OR id = 7 OR id = 9 [1, 3, 5] pushed down
IS DISTINCT FROM
Compares two values and treats NULL as a value: x IS DISTINCT FROM y is true when they differ or only one is NULL. IS NOT DISTINCT FROM is its opposite.
- Syntax:
x IS [NOT] DISTINCT FROM y - Returns:
BOOLEAN, never NULL. - Pushed down: no.
run("SELECT NULL IS DISTINCT FROM NULL, 1 IS DISTINCT FROM NULL, NULL = NULL")
where_it_runs("qty IS DISTINCT FROM 12")
[(False, True, None)]
qty IS DISTINCT FROM 12 [2, 3, 4, 5] Query Engine (FILTER)
Struct fields
A field of a struct column, written column.field, compares like a column. Comparing it with a constant pushes down; IS NULL on it doesn't.
for condition in ["bin.aisle = 3", "bin.aisle > 1", "bin.aisle IS NULL"]:
where_it_runs(condition)
bin.aisle = 3 [2] pushed down
bin.aisle > 1 [2, 3] pushed down
bin.aisle IS NULL [4, 5] Query Engine (FILTER)
NULL and boolean tests
IS NULL and IS NOT NULL
True if a value is NULL, or isn't.
- Syntax:
x IS NULL,x IS NOT NULL - Returns:
BOOLEAN, never NULL. - Pushed down: on a number or text column. On a list or struct column, or a struct field, it's evaluated in the Query Engine.
for condition in ["name IS NULL", "name IS NOT NULL", "tags IS NULL", "bin IS NULL"]:
where_it_runs(condition)
name IS NULL [5] pushed down
name IS NOT NULL [1, 2, 3, 4] pushed down
tags IS NULL [4] Query Engine (FILTER)
bin IS NULL [4] Query Engine (FILTER)
Boolean tests
A BOOLEAN column can be a condition by itself, and IS TRUE and IS NOT TRUE test it without NULLs: x IS NOT TRUE is true for false and for NULL.
- Syntax:
WHERE flag,NOT flag,flag = true,flag IS [NOT] TRUE - Returns:
BOOLEAN. - Pushed down:
flag = trueandflag = false. The bare column,NOT flagandIS [NOT] TRUEare evaluated in the Query Engine.
for condition in ["in_stock", "in_stock = true", "NOT in_stock", "in_stock = false", "in_stock IS NOT TRUE"]:
where_it_runs(condition)
in_stock [1, 2] Query Engine (FILTER)
in_stock = true [1, 2] pushed down
NOT in_stock [3, 5] Query Engine (FILTER)
in_stock = false [3, 5] pushed down
in_stock IS NOT TRUE [3, 4, 5] Query Engine (FILTER)
Logic
AND, OR and NOT
Combine conditions.
- Syntax:
a AND b,a OR b,NOT a - Returns:
BOOLEAN. - NULLs: three-valued logic:
NULL AND falseis false,NULL OR trueis true, and the other combinations with NULL are NULL. - Pushed down: an
ANDof conditions that push down; anORof tests on the same column;NOTof one comparison. AnORacross columns, andNOTof anAND, are evaluated in the Query Engine.
for condition in ["qty > 5 AND price < 1", "id = 1 OR qty > 20", "qty < 6 OR qty > 30",
"NOT (qty > 5)", "NOT (qty > 5 AND id < 3)"]:
where_it_runs(condition)
run("SELECT NULL AND false, NULL OR true, NULL AND true")
qty > 5 AND price < 1 [1, 3, 4] pushed down
id = 1 OR qty > 20 [1, 3] Query Engine (FILTER)
qty < 6 OR qty > 30 [2, 3, 5] pushed down
NOT (qty > 5) [2, 5] pushed down
NOT (qty > 5 AND id < 3) [2, 3, 4, 5] Query Engine (FILTER)
[(False, True, None)]
Pattern matching
LIKE and ILIKE
LIKE matches text against a pattern in which % stands for any run of characters and _ for one character. ILIKE does the same, ignoring case. The operators ~~, !~~, ~~* and !~~* are LIKE, NOT LIKE, ILIKE and NOT ILIKE.
- Syntax:
s [NOT] LIKE pattern [ESCAPE c],s [NOT] ILIKE pattern [ESCAPE c] - Escapes: there's no default escape character, so
\_matches a backslash and any character. Name one withESCAPE, as inname LIKE 'cable\_%' ESCAPE '\'. The functionslike_escape(s, pattern, c),not_like_escape,ilike_escapeandnot_ilike_escapedo the same. - Returns:
BOOLEAN.LIKEis case-sensitive. - NULLs: NULL if
sor the pattern is NULL. - Errors: an escape of more than one character fails with
Invalid escape string. Escape string must be empty or one character. - Pushed down: only
LIKEwithout a wildcard, which becomes=.LIKEwith a wildcard, and everyILIKE, are evaluated in the Query Engine. For a prefix, a range such asname >= 'b' AND name < 'c'pushes down.
for condition in ["name LIKE 'bolt'", "name LIKE 'b%'", "name >= 'b' AND name < 'c'", "name LIKE '%a%'",
"name ILIKE 'b%'", "name LIKE 'cable\\_%' ESCAPE '\\'"]:
where_it_runs(condition)
name LIKE 'bolt' [1] pushed down
name LIKE 'b%' [1] Query Engine (FILTER)
name >= 'b' AND name < 'c' [1] pushed down
name LIKE '%a%' [2, 3, 4] Query Engine (FILTER)
name ILIKE 'b%' [1, 2] Query Engine (FILTER)
name LIKE 'cable\_%' ESCAPE '\' [3] Query Engine (FILTER)
GLOB
Matches text against a shell-style pattern: * for any run of characters, ? for one character, and [...] for one of a set. Case-sensitive. The operator ~~~ is the same.
- Syntax:
s GLOB pattern - Returns:
BOOLEAN. - NULLs: NULL if either side is NULL.
- Pushed down: no, even without wildcards.
run("SELECT 'bolt' GLOB 'b?lt', 'bolt' GLOB '[ab]*', 'bolt' GLOB 'B*'")
where_it_runs("name GLOB '*_*'")
[(True, True, False)]
name GLOB '*_*' [3] Query Engine (FILTER)
SIMILAR TO and regular-expression match
SIMILAR TO and the operator ~ are true if a regular expression matches the whole text; NOT SIMILAR TO and !~ are their opposites. Both are case-sensitive. To match part of the text, use regexp_matches() (regular expressions).
- Syntax:
s [NOT] SIMILAR TO pattern,s ~ pattern,s !~ pattern - Returns:
BOOLEAN. - NULLs: NULL if either side is NULL.
- Errors: an invalid pattern fails when the query is planned, as in
missing ): (. - Pushed down: no.
run("SELECT 'bolt' SIMILAR TO 'b.*', 'bolt' SIMILAR TO 'o', 'bolt' ~ 'b', 'bolt' ~ 'b.*'")
where_it_runs("name SIMILAR TO '[a-c].*'")
[(True, False, False, True)]
name SIMILAR TO '[a-c].*' [1, 3] Query Engine (FILTER)
Starts with
s ^@ prefix is true if s starts with prefix, as are the functions starts_with(s, prefix) and prefix(s, prefix).
- Returns:
BOOLEAN. An empty prefix matches everything. - NULLs: NULL if either side is NULL.
- Pushed down: no. Use a range on the column instead, as under LIKE.
where_it_runs("name ^@ 'b'")
name ^@ 'b' [1] Query Engine (FILTER)
Arithmetic
Arithmetic in WHERE is evaluated in the Query Engine, except where the planner can rewrite an integer comparison onto the column (see how operators run). Multiplication binds more tightly than addition, so 2 + 3 * 4 is 14. Date and time arithmetic is on the date and time page.
Addition, subtraction and multiplication
a + b, a - b, a * b, and the negation -a.
- Arguments: numbers.
DATE,TIMESTAMPandINTERVALvalues too (date and time). - Returns: the wider of the two types:
INTEGERwithINTEGERgivesINTEGER,BIGINTwithINTEGERgivesBIGINT, and with aDOUBLEit'sDOUBLE.DECIMALstays exact:0.1 + 0.2is0.3, as aDecimal. - NULLs: NULL if either side is NULL.
- Errors: a result too large for its integer type stops the query, as in
Overflow in multiplication of INT32 (40 * 1000000000)!. Cast toBIGINTfirst for larger results.
run(f"SELECT qty + 1, qty * 2, -qty, typeof(id + qty), 0.1 + 0.2 FROM {TABLE} WHERE id = 1")
run(f"SELECT qty * 1000000000 FROM {TABLE} WHERE id = 3")
run(f"SELECT CAST(qty AS BIGINT) * 1000000000 FROM {TABLE} WHERE id = 3")
[(13, 24, -12, 'BIGINT', Decimal('0.3'))]
OSError: Overflow in multiplication of INT32 (40 * 1000000000)!
[(40000000000,)]
Division and remainder
a / b divides and always returns a DOUBLE, also for integers. a // b is integer division, which drops the fraction toward zero, and a % b is the remainder, which takes the sign of a.
- Arguments: numbers.
- Returns:
/aDOUBLE;//and%the type of the arguments. - NULLs: NULL if either side is NULL.
- Division by zero:
/returnsinf;//and%return NULL. None of them raises an error.
run("SELECT 7 / 2, 7 // 2, -7 // 2, 7 % 2, -7 % 2")
run("SELECT 1 / 0, 1 // 0, 1 % 0")
[(3.5, 3, -3, 1, -1)]
[(inf, None, None)]
Power and absolute value
a ** b and a ^ b raise a to the power b; @ a is the absolute value, like abs(a).
- Returns:
**and^aDOUBLE;@the type ofa. - NULLs: NULL in, NULL out.
run("SELECT 2 ** 10, 2 ^ 0.5, @ -5")
[(1024.0, 1.4142135623730951, 5)]
Bitwise operators
These work on integers (TINYINT to HUGEINT, signed and unsigned) and return the type of their arguments. They also work on bit strings (binary, hash and UUID functions). On a DECIMAL they fail with No function matches the given name and argument types; cast to an integer first. In WHERE, they're evaluated in the Query Engine.
AND, OR, XOR and NOT on bits
a & b (AND), a | b (OR), xor(a, b) (exclusive OR) and ~a (NOT). There's no XOR operator: # is a syntax error.
- Returns: the integer type of the arguments.
~of a signed integer is negative for a positive one:~12is-13. - NULLs: NULL if either side is NULL.
run("SELECT 12 & 10, 12 | 10, xor(12, 10), ~12")
run(f"SELECT id, qty & 6 FROM {TABLE} ORDER BY id LIMIT 10")
[(8, 14, 6, -13)]
[(1, 4), (2, 4), (3, 0), (4, 6), (5, 0)]
Shifts
a << n shifts the bits of a left by n; a >> n shifts them right. A right shift past the width gives 0.
- Returns: the integer type of
a. - NULLs: NULL if either side is NULL.
- Errors: a left shift that overflows fails with
Overflow in left shift (1 << 31); a negative shift withCannot left-shift by negative number -1.
run("SELECT 1 << 4, 256 >> 4, 256 >> 40")
run("SELECT 1 << 31")
[(16, 16, 0)]
OSError: Overflow in left shift (1 << 31)
List operators
|| joins lists, and strings too; &&, @> and <@ test lists against each other.
Concatenation
a || b joins two strings, two lists, or two BLOB values. Other values are turned into text first: 1 || 2 is the VARCHAR '12'.
- Returns:
VARCHARfor text and other values; a list for lists. - NULLs: NULL if either side is NULL. To skip NULLs, use
concat()(string functions).
run(f"SELECT name || '-' || id, name || NULL FROM {TABLE} ORDER BY id LIMIT 2")
run("SELECT 1 || 2, [1, 2] || [3]")
[('bolt-1', None), ('Bracket-2', None)]
[('12', [1, 2, 3])]
List overlap and containment
l1 && l2 is true if the lists share an element; l1 @> l2 if l1 contains every element of l2; l1 <@ l2 if every element of l1 is in l2.
- Arguments: two lists of comparable element types. Lists of different types, such as
INTEGERandVARCHAR, fail with'&&' cannot compare lists of different types: 'INTEGER' and 'VARCHAR'. - Returns:
BOOLEAN. Every list contains the empty list. - NULLs: NULL if either list is NULL. NULL elements don't match each other:
[1, NULL] && [NULL]is false. - Pushed down: no. More list functions are on lists and structs.
run(f"SELECT id, tags && ['small'], tags @> ['metal'] FROM {TABLE} ORDER BY id LIMIT 10")
where_it_runs("tags && ['small', 'misc']")
[(1, True, True), (2, False, True), (3, True, False), (4, None, None), (5, False, False)]
tags && ['small', 'misc'] [1, 3, 5] Query Engine (FILTER)
Not available in the VAST Query Engine
| Kind | Form | Instead |
|---|---|---|
Long IN lists |
IN with five or more values that aren't consecutive integers, or five or more strings: The operator 'HASH_JOIN' type=32 is currently not supported. |
ORs on the same column, which push down |
IN with a subquery |
id IN (SELECT ...) fails the same way |
Run the subquery first and write its values as ORs |
| Time-zone arithmetic | + and - on TIMESTAMP WITH TIME ZONE values |
Cast to TIMESTAMP first (date and time) |
| An XOR operator | a # b is a syntax error |
xor(a, b) |
| Bitwise operators on non-integers | 1.5 & 1 |
Cast to an integer first |
run(f"SELECT id FROM {TABLE} WHERE id IN (SELECT 1)")
InternalError: The operator 'HASH_JOIN' type=32 is currently not supported.
Clean up:
run(f"DROP TABLE IF EXISTS {TABLE}")
run(f"DROP SCHEMA IF EXISTS {SCHEMA}")
conn.close()
[]
[]
See also
- SELECT (where filters run,
INlists) and EXPLAIN. - Pushdowns: which conditions VAST DataBase evaluates, for every client.
- String functions, numeric functions and date and time functions.
- Functions.
Function pages for operators
The arithmetic and bitwise operators have their own pages, with every type, edge case and error:
| Function | What it does |
|---|---|
+ (addition) (also add(a, b), add(a), +a) |
Add two numbers, or a number of days to a date, with the + operator; add() is the same function, and a unary + returns its operand. |
| / (division) | Divide one number by another with the / operator; the result is a DOUBLE, also for integers. |
| // (integer division) | Divide integers and drop the fraction with the // operator; on DECIMAL and DOUBLE values it divides without dropping it. |
% (modulo) (also mod(a, b)) |
Take the remainder of a division with the % operator or mod(); the remainder has the sign of the dividend. |
* (multiplication) (also multiply(a, b), a * b) |
Multiply two numbers, or an interval by a number, with the * operator or multiply(). |
- (subtraction and negation) (also subtract(a, b), a - b, subtract(a), -a) |
Subtract one number from another, or negate a number, with the - operator or subtract(). |
| & (bitwise AND) | Keep the bits that are set in both of two integers with the & operator, for example to test a flag in a bit mask. |
| | (bitwise OR) | Set the bits that are set in either of two integers with the | operator, for example to add a flag to a bit mask. |
| << (shift left) | Shift the bits of an integer left by n places with the << operator; a result that doesn't fit its type is an error, not a wrap-around. |
| >> (shift right) | Shift the bits of an integer right by n places with the >> operator; negative numbers keep their sign, and a shift past the width gives 0. |
| ~ (bitwise NOT) | Flip every bit of an integer or a BIT value with the unary ~ operator; for signed integers ~x is -x - 1. |