Limitations & Errors
What's not supported
| Feature | Alternative |
|---|---|
Subqueries (SELECT ...) |
Use JOINs for cross-table queries, or run separate queries |
UNION / INTERSECT / EXCEPT |
Run separate queries and combine results in the UI |
Window functions (ROW_NUMBER, RANK, LAG, LEAD, NTILE) |
Use ORDER BY + LIMIT for ranking; compute running totals in the UI |
CTEs (WITH ... AS) |
Use JOINs or run separate queries |
INSERT / UPDATE / DELETE |
The Query Console is read-only. Use the table UI to modify data, or the in-app SQL Console for privileged mutations |
CREATE / ALTER / DROP |
Use the column management UI for schema changes |
PRAGMA / ATTACH / DETACH |
Blocked for security |
GRANT / REVOKE |
Blocked for security |
VACUUM / REINDEX |
Blocked for security |
RIGHT JOIN |
Swap table order and use LEFT JOIN instead |
CROSS JOIN |
Not supported |
PIVOT / UNPIVOT |
Use CASE WHEN with GROUP BY to pivot manually |
| User-defined functions | Only built-in functions are available — see Functions |
Other limitations
Result limit — Every query returns a maximum of 1000 rows, even if LIMIT is set higher. Paginate with OFFSET for larger datasets.
Date storage — Date columns store Unix timestamps (seconds since epoch). Use DATE_FORMAT() to display dates in a readable format. Raw timestamp values like 1719792000 will appear if you don't format them.
Automatic date conversion — When you compare a date column against a date string (e.g., WHERE CreatedAt > '2024-06-01'), the engine automatically converts the string to a timestamp. You don't need to wrap it in DATE(), though doing so is also fine.
CONTAINS scope — The CONTAINS family of operators only works on array-type columns (tags, multi-select). Using them on text or number columns won't match anything.
SELECT * performance — SELECT * returns all column data and may use a different (slower) execution path than selecting specific columns. For best performance on large tables, list the columns you need.
Column name resolution — Column names are case-insensitive. If a column name is ambiguous across joined tables, prefix it with the table name or alias (Customers.Name or c.Name).
Table name resolution — Table names are case-insensitive and must match a DataTable name in your workspace exactly (aside from case).
Query caching — Query results are cached for 5 seconds. Writes invalidate the cache immediately so subsequent queries see fresh data.
Error messages
| Error | What it means |
|---|---|
"DROP" is not allowed |
A blocked keyword was detected. Only SELECT queries are allowed |
Only SELECT queries are allowed |
The query doesn't start with SELECT |
Unknown table: "X" |
The table name doesn't match any DataTable in your workspace. The error lists available tables |
Unknown column: "X" |
The column name doesn't exist in the referenced table. Check spelling or specify the table prefix |
Function "X" is not allowed |
The function isn't in the supported function list. The error shows all available functions |
Subqueries are not supported |
A nested (SELECT ...) was detected. Use JOINs instead |
Expected X but found Y |
Syntax error at a specific position in the query |
Unterminated string literal |
A string opened with ' was never closed |
Unterminated quoted identifier |
A quoted identifier opened with " was never closed |
Cannot mix * with other columns |
SELECT * cannot be combined with named columns |
Query must include a FROM clause |
Every SELECT query must specify a table with FROM (except DESCRIBE) |
Need a feature?
If you hit a wall on something not listed here that you think KSQL should support, reach out at team@konduit.work with the use case. The blocked features above are blocked deliberately (security, performance, surface-area control); other gaps are just unprioritized.