multipart/form-data POST requests that carry a SQL statement together with one or more files (Parquet, CSV, …).
The statement reads each file with the upload:// URL scheme through table-valued functions such as READ_PARQUET, READ_CSV, READ_AVRO, READ_TEXT, and READ_FILES.
This lets you query a file on your machine, or load it into a table, without staging it in Amazon S3 first.
Uploaded files exist on the engine’s local disk only while the request runs and are deleted when it finishes.
Nothing is persisted unless the statement writes the data, for example with INSERT INTO ... SELECT.
Request format
Send a POST request with aContent-Type of multipart/form-data to an engine, authenticated like any other API request.
The request must contain:
- Exactly one part with the
namedirective set tosql, holding the SQL statement in UTF-8. - Any number of file parts. Each file part needs a
filenamedirective (the value is ignored) and anamedirective that matches the regex[_0-9a-zA-Z.-]+and is unique within the request. The SQL statement references the part asupload://<name>.
--form "sql=<statement>" produces the statement part and --form "<name>=@<path>" produces a file part.
The engine stores each uploaded file under a unique name built from the part name: a sanitized form of it, a UUID, and the part name’s file extension (events.json.gz becomes events_3f9e....json.gz), which is the name error messages quote.
Format inference reads that extension, so a part name that carries one can be read with READ_FILES, which infers both the format and the compression from it.
The format-specific TVFs take the format from the function you call, so they read a part with any name.
Query an uploaded file
my_file), not the local file name (sales.parquet).
The upload:// URL must match a part name exactly; glob patterns are not supported.
Naming the part after the file lets READ_FILES infer the format, so the statement does not have to name it:
Upload multiple files
A statement can reference any number of uploaded files, each by its own part name:Load an uploaded file into a table
Theupload:// scheme works only in read table-valued functions.
COPY FROM and external tables reject it.
To persist uploaded data, insert the function’s result into a table:
Compress parts
To reduce transfer size, compress individual parts and declare the codec with a per-partContent-Encoding header.
The engine decompresses each part on arrival.
Supported encodings are gzip, deflate, br, xz, zstd, lz4, and snappy.
Both file parts and the sql part can be compressed.
Content-Encoding header on the request is rejected; compress per part instead.
The engine stores the decompressed bytes, so a part that declares a Content-Encoding must not carry a compression suffix in its part name: the extension describes the file on the engine’s disk, and a .gz suffix makes compression inference expect gzip-compressed content.
To have the engine read the file compressed instead, upload it without a Content-Encoding header and keep the suffix in the part name (--form "targets.csv.gz=@./targets.csv.gz").
Limits
- The file parts of one request can hold at most 1 GB of data in total, measured after decompression.