This topic covers the SQL syntax, data types, result limits, and usage recommendations for SQL-based data exploration. Use SQL exploration to query Apache Paimon tables, Paimon system tables, and DLF built-in exploration views.
Limitations and recommendations
Write restriction: SQL exploration is read-only by default. Use it for queries, data previews, aggregation analysis, and permitted DDL operations.
Row limit: Query results are capped at
1000rows by default. You can increase this up to10000rows with an explicitLIMITclause.Multi-statement execution: You can submit multiple SQL statements in a single submission, separated by semicolons (
;). Statements run in order, and execution stops if any statement fails.Default context: SQL exploration uses the Catalog and Database selected at the top of the page as the default context. You can reference tables in the current database without qualification, or use
database.tableto reference tables in a different database.Multimodal search:
vector_search(...)andfull_text_search(...)require tables that have a vector index or full-text index, respectively.
SQL syntax
Metadata queries
List tables in the current database:
SHOW TABLES;View column information for a table:
DESCRIBE orders;Query tables in a specific database:
SELECT table_name
FROM information_schema.tables
WHERE table_schema = '<database name>'
ORDER BY table_name;Query columns of a specific table:
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = '<database name>'
AND table_name = '<table name>'
ORDER BY ordinal_position;SHOW TABLESlists the tables in the Catalog and Database currently selected on the page.To query tables or columns in a specific database, use
information_schema.tablesandinformation_schema.columns.
Basic queries
Simple queries
Query a table in the current database:
SELECT id, name, dt
FROM orders
WHERE dt = '<partition date>'
LIMIT 100;Query a table in a specific database:
SELECT id, name
FROM sales.orders
WHERE id = 1001
LIMIT 100;Column selection
SELECT name
FROM users
LIMIT 100;Filtering, sorting, and pagination
SELECT id, name, amount
FROM orders
WHERE dt = '<partition date>'
AND amount > 100
ORDER BY amount DESC
LIMIT 100;Aggregation
SELECT category, COUNT(*) AS cnt
FROM goods
GROUP BY category
ORDER BY cnt DESC
LIMIT 100;Joins
SELECT u.id, u.name, s.score
FROM users u
JOIN scores s
ON u.id = s.id
WHERE s.score >= 80
LIMIT 100;Subqueries
SELECT id, name
FROM users
WHERE id IN (
SELECT user_id
FROM orders
WHERE dt = '<partition date>'
)
LIMIT 100;Common table expressions (CTEs)
WITH filtered AS (
SELECT *
FROM orders
WHERE dt = '<partition date>'
)
SELECT COUNT(*) AS cnt
FROM filtered;Time travel
Use time travel to query historical versions of a Paimon table. You can specify a version by Snapshot ID, Tag name, or timestamp.
Query by Snapshot ID:
SELECT id, name
FROM orders VERSION AS OF <Snapshot ID>
LIMIT 100;Query by Tag:
SELECT id, name
FROM orders VERSION AS OF '<Tag name>'
LIMIT 100;Query by timestamp:
SELECT id, name
FROM orders TIMESTAMP AS OF '<timestamp>'
LIMIT 100;Query a historical version of a table in a specific database:
SELECT id, name
FROM sales.orders VERSION AS OF <Snapshot ID>
LIMIT 100;You can query available snapshots from the Paimon system table
$snapshots, and available tags from$tags.The timestamp format for
TIMESTAMP AS OFisYYYY-MM-DD HH:mm:ss.Time travel only affects the data version read by the query. It does not modify table data.
Multimodal search
Vector search
vector_search(...) performs similarity search on a vector column. Parameters (in order): table name, vector column name, query vector, and number of results to return.
Syntax:
SELECT *
FROM vector_search('<database name>.<table name>', '<vector column>', '<query vector JSON array>', <number of results>);Example -- before running this query, select the target Catalog at the top of the page:
SELECT *
FROM vector_search(
'multimodal_samples.berkeley_deepdrive_100k_images',
'image_embedding',
'<query vector JSON array>',
3
);Full-text search
full_text_search(...) performs full-text search on a text column. Parameters (in order): table name, text column name, query text, and number of results to return.
Syntax:
SELECT *
FROM full_text_search('<database name>.<table name>', '<text column>', '<query text>', <number of results>);Search by keyword -- before running this query, select the target Catalog at the top of the page:
SELECT *
FROM full_text_search(
'multimodal_samples.berkeley_deepdrive_100k_images',
'tags',
'traffic',
5
);Search by phrase:
SELECT *
FROM full_text_search(
'multimodal_samples.berkeley_deepdrive_100k_images',
'tags',
'"traffic light"',
5
);Dynamic parameters
Use SET and RESET to temporarily configure Paimon query parameters within a single submission. These settings apply only to subsequent statements in that submission. For example, to specify a Snapshot version for querying historical data:
SET 'paimon.scan.version' = '<Snapshot ID>';
SELECT id, name
FROM orders
LIMIT 100;
RESET 'paimon.scan.version';DDL statements
Create and drop a database
In SQL exploration, the SCHEMA keyword maps to a DLF Database.
CREATE SCHEMA IF NOT EXISTS demo_db;
DROP SCHEMA IF EXISTS demo_db CASCADE;Create an append table
CREATE TABLE IF NOT EXISTS demo_db.orders (
order_id BIGINT,
price BIGINT,
customer STRING
);Create a primary key table
CREATE TABLE IF NOT EXISTS demo_db.orders_pk (
order_id BIGINT,
price BIGINT,
customer STRING,
PRIMARY KEY (order_id) NOT ENFORCED
);Create a partitioned table
Define the partition column as a regular table column, then specify it in PARTITIONED BY.
CREATE TABLE IF NOT EXISTS demo_db.events (
event_id BIGINT,
event_name STRING,
dt STRING
)
PARTITIONED BY (dt);Alter a table
ALTER TABLE demo_db.orders
ADD COLUMN remark STRING;ALTER TABLE demo_db.orders
RENAME COLUMN remark TO comment;Drop a table
DROP TABLE IF EXISTS demo_db.orders;Temporary tables and views
Temporary objects are visible only within the current SQL submission. They are useful for organizing intermediate results in multi-statement submissions.
CREATE TEMPORARY TABLE tmp_users AS
SELECT * FROM (VALUES (1, 'alice'), (2, 'bob')) AS t(id, name);
SELECT COUNT(*) FROM tmp_users;
DROP TEMPORARY TABLE tmp_users;CREATE TEMPORARY VIEW tmp_view AS
SELECT * FROM orders WHERE dt = '<partition date>';
SELECT COUNT(*) FROM tmp_view;
DROP TEMPORARY VIEW tmp_view;Drop a partition
ALTER TABLE demo_db.events
DROP PARTITION (dt = '<partition date>');Paimon system table queries
Append the $ suffix to a table name to query Paimon system tables.
Query table options
SELECT key, value
FROM demo_db.orders$options;Query schema history
SELECT *
FROM demo_db.orders$schemas;Query snapshots
SELECT *
FROM demo_db.orders$snapshots
ORDER BY snapshot_id DESC
LIMIT 10;Query tags
SELECT *
FROM demo_db.orders$tags;Query manifests
SELECT *
FROM demo_db.orders$manifests
LIMIT 10;Query partition statistics
SELECT *
FROM demo_db.orders$partitions;Query file size statistics
SELECT *
FROM demo_db.orders$physical_files_size;
SELECT *
FROM demo_db.orders$referenced_files_size;DLF built-in system table queries
DLF provides built-in system tables for viewing statistics about table storage, partitions, compute usage, and permissions. For details, see Table and partition storage statistics, Lakehouse optimization resource consumption, and Incremental logs.
Table storage overview
SELECT dt,
COUNT(DISTINCT table_id) AS table_cnt,
SUM(obj_size) + SUM(meta_obj_size) AS total_size,
SUM(obj_size) AS total_data_obj_size,
SUM(meta_obj_size) AS total_meta_obj_size
FROM system.table_summary
WHERE dt BETWEEN '<start date>' AND '<end date>'
GROUP BY dt
ORDER BY dt;Partition storage statistics
SELECT database_name, table_name, partition_name,
obj_cnt AS data_obj_cnt,
obj_size AS data_obj_size
FROM system.partition_summary
WHERE dt = '<partition date>'
ORDER BY data_obj_size DESC
LIMIT 100;Compute usage trends
SELECT dt,
SUM(cu) AS daily_cu,
MIN(start_time) AS min_start_time,
MAX(start_time) AS max_start_time
FROM system.compute_usage
WHERE dt BETWEEN '<start date>' AND '<end date>'
GROUP BY dt
ORDER BY dt;Permission grants
SELECT principal, principal_kind, principal_name,
database_name, object_name, resource_type, access
FROM system.auth_privilege_grants
WHERE dt = '<partition date>'
AND access = 'SELECT'
ORDER BY database_name, object_name, principal;Data types
You can use the following data types when creating tables. Each type maps to a Paimon type.
SQL type | Paimon type | Description |
|
| Boolean. Values are |
|
| 1-byte integer for small value ranges. |
|
| 2-byte integer. |
|
| 4-byte integer. |
|
| 8-byte integer. Suitable for primary keys, counters, and monetary values in minor units. |
|
| Single-precision floating point. |
|
| Double-precision floating point. |
|
| String. Suitable for text, enum values, and partition columns. |
|
| Binary. Suitable for byte arrays. |
|
| Binary large object. |
|
| Date without a time component. |
|
| Timestamp with precision |
|
| Timestamp with time zone semantics. |
|
| Fixed-point number. |
|
| Array. The element type can be a primitive or complex type, for example |
|
| Key-value collection, for example |
|
| Struct for nested fields, for example |
Example: create a table with all types
CREATE TABLE demo_db.type_demo (
c_boolean BOOLEAN,
c_tinyint TINYINT,
c_smallint SMALLINT,
c_int INT,
c_bigint BIGINT,
c_float FLOAT,
c_double DOUBLE,
c_decimal DECIMAL(10, 2),
c_string STRING,
c_binary BINARY(4),
c_date DATE,
c_timestamp TIMESTAMP(3),
c_array ARRAY<STRING>,
c_map MAP(STRING, BIGINT),
c_struct STRUCT<city STRING, zip BIGINT>
);FAQ
What should I do if a query times out?
Add a LIMIT clause, filter by partition, or use more specific WHERE conditions to reduce the amount of data scanned.
Why does my query return only a partial result set?
SQL exploration enforces a row limit on query results. The default is 1000 rows. To retrieve more rows, set LIMIT explicitly, up to a maximum of 10000.
Why do some DDL statements fail?
DDL support varies depending on the underlying execution engine, Catalog type, or table type. Test DDL statements in a non-production environment before running them against production data.