CSV, JSON & Parquet SQL Data Lab

Load a file as the table named data, then run a SELECT or WITH query. The displayed and exported preview is limited to 200 rows.

LOCAL ENGINEDuckDB-Wasm 1.32.0CSV · TSV · JSON · NDJSON · ParquetSELECT / WITH queries
Selected files are read by the SQL engine inside this browser. VoriTools does not upload the file, query, or query result.
Local SQL query

The loaded file is exposed as data. To keep the workspace non-destructive, this tool accepts SELECT and WITH queries only and displays at most 200 rows.

Query result
Load a local file, then run a SELECT query.

Analyze data without a data upload

Data Lab is useful for a quick schema check, a targeted SQL slice, or a local Parquet preview. It is not a replacement for access-controlled production analytics, and it never opens a URL or sends the selected file to VoriTools.

How to run a SQL query over a local data file

Load a CSV, TSV, JSON, NDJSON or Parquet file, then query it with SQL: the page hands the file to a DuckDB engine running inside the browser tab, exposes it as the table data, and shows the result of your SELECT or WITH statement in a table you can export. The engine is DuckDB-Wasm 1.32.0 in a Web Worker — the file bytes go to that worker and nowhere else.

The scope is deliberately narrow: one file at a time, read-only statements, and a preview of at most 200 rows. That is enough for the jobs this kind of page gets used for — a schema check before importing a dump, a GROUP BY over an exported report, or a first look at a Parquet file when no desktop reader is installed — without standing up a database.

  1. Choose a file under Local data file and press Load selected file. The picker accepts .csv, .tsv, .json, .ndjson, .jsonl, .parquet and .txt, and a .txt file is parsed as comma-separated CSV. Once the engine has read the file the status line names it: “orders.csv is ready in the local table named data.”
  2. Type a statement against data in the box, or keep the default SELECT * FROM data LIMIT 100. Press Load sample data to try the tool without a file: it loads four rows of a small CSV (id, name, team, monthly_events) plus a GROUP BY query over it that returns three rows.
  3. Press Run query to execute the statement in the browser. The result table lists the column names the engine returned and up to 200 rows, and the strip above it reports the file, the column count and the rows on screen — a value such as 200+ means the result was longer than the preview.
  4. Press Export visible CSV to save exactly the rows on screen, header included, as kivtools-query-results.csv, or Reset query to restore the default statement and clear the table. The export button stays disabled until a query has returned rows.

Where the query runs, what the tool reads, and where the 200-row limit comes from

Formats, the data table, and the SELECT-only rule

CSV and TXT go through the CSV reader, TSV through the same reader with a tab delimiter, JSON and NDJSON/JSONL through the JSON reader, and Parquet through the Parquet reader, so column types are inferred from the file instead of being declared by you. Everything lands in a view called data, and loading another file replaces it: there is no second table and no join across two files.

Only statements that start with SELECT or WITH are accepted. DROP TABLE data and DELETE FROM data are rejected before the engine sees them, with the message “For safety, Data Lab runs SELECT and WITH queries only.” A single trailing semicolon is fine, but one press runs one statement: SELECT 1; SELECT 2 comes back as a Parser Error, and an unsupported extension such as .xlsx is refused with a message naming the formats that do work.

The 200-row preview is a display limit, not a query limit

Whatever you type is wrapped as SELECT * FROM (<your query>) AS kivtools_visible_result LIMIT 201, and the page renders at most 200 of the rows that come back. Ask for SELECT * FROM data over a 1,000-row Parquet file and the status line reads “200 rows shown (limited to 200)” while the metrics strip counts 200+; add your own ORDER BY salary DESC LIMIT 5 and you get exactly five rows.

Export visible CSV writes what the table shows — a header line plus those same rows, up to 200, with CRLF line endings — not the full result set, so a grouped result of five rows exports five lines of data. For more, aggregate or slice inside the statement: the preview is built for reading, not for moving a file out of the browser.

What a failed query tells you

Error text comes from the engine itself and is printed as it arrives. A misspelled column gives Binder Error: Referenced column “nope” not found in FROM clause! Candidate bindings: “name”, “monthly_events”; a missing table gives Catalog Error: Table with name nowhere does not exist!; broken syntax gives a Parser Error with the position marked; a truncated Parquet file gives Invalid Input Error: No magic bytes found at end of file.

A failed statement leaves the previous result on screen and does not damage the session — the next Run query behaves normally and the file stays loaded. Because failures arrive as message text rather than as a broken page, you can iterate on a statement in the box without reloading the page or picking the file again.

Speed, first-run download and privacy

In Chrome, a 6 MB CSV holding 200,000 rows became queryable in about a quarter of a second, and a GROUP BY and a window function over it each came back in about the same time; a 1,000-row, 13-column Parquet file needed a few seconds for the first Parquet read. The first visit to the page downloads the engine — 34 MB of WebAssembly plus Apache Arrow modules — before the first query runs, and later visits start it from the browser cache in about a second.

Selected files are read inside the tab: the bytes are registered with the Web Worker that hosts the engine, and neither the file, the statement you type nor the result rows are sent to VoriTools. With the browser network panel open, running a query against a loaded file produces no request at all. The flip side is that the tool cannot fetch a file from a URL, and a question that needs two files has to be asked in two passes.

Recent tools: