Skip to content

UPLOAD

Mark endpoint as a file upload handler.

Keywords

upload

Syntax

upload
upload for <handler_type>

If no handler is specified (only upload annotation without for), then the default handler will be used. The default handler is large_object unless configured otherwise via DefaultUploadHandler setting.

Handler Types

There are 4 handler types available:

HandlerKeyDescription
Large Objectlarge_objectStores files using PostgreSQL Large Objects API (default)
File Systemfile_systemStores files on the server file system
CSVcsvParses CSV files and processes rows via PostgreSQL command
ExcelexcelParses Excel files and processes rows via PostgreSQL command

Shared Annotation Options

These options are available for all handler types:

OptionTypeDefaultDescription
stop_after_first_successboolfalseStop upload after first successful upload when multiple handlers are used. Subsequent files will have status Ignored.
included_mime_typesstringnullCSV string of MIME type patterns to include. Set to null to allow all.
excluded_mime_typesstringnullCSV string of MIME type patterns to exclude. Set to null to exclude none.
buffer_sizeintnullBuffer size in bytes for raw content uploads (large_object and file_system).
check_textboolfalseValidate file is a text file (not binary). Set to true to accept only text files.
check_imagebool/stringfalseValidate file is an image. Set to true to accept only images, or CSV of allowed types: jpg, png, gif, bmp, tiff, webp.
test_buffer_sizeint4096Buffer size in bytes when checking text files.
non_printable_thresholdint5Maximum non-printable characters allowed in test buffer to consider a valid text file.

Upload Metadata

All handlers return upload metadata as JSON with the following common properties:

PropertyTypeDescription
typestringHandler type used (large_object, file_system, csv, excel)
fileNamestringOriginal uploaded file name
contentTypestringMIME type of the uploaded file
sizeintFile size in bytes
successboolWhether the upload succeeded
statusstringStatus message (e.g., Ok, InvalidMimeType)

Handler-specific properties:

HandlerPropertyTypeDescription
large_objectoidintPostgreSQL Large Object OID
file_systemfilePathstringPath where file was saved

Large Object Handler

Default handler that stores files using PostgreSQL Large Objects.

Basic Example

sql
create function lo_simple_upload(
    _meta json = null
)
returns json
language plpgsql
as
$$
begin
    return _meta;
end;
$$;

comment on function lo_simple_upload(json) is '
upload
param _meta is upload metadata
';

With Custom OID Parameter

You can specify a custom OID for the large object:

sql
create function lo_custom_parameter_upload(
    _oid bigint,
    _meta json = null
)
returns json
language plpgsql
as
$$
begin
    return _meta;
end;
$$;

comment on function lo_custom_parameter_upload(bigint, json) is '
upload for large_object
param _meta is upload metadata
oid = {_oid}
';

Context Metadata

Upload metadata is also available via PostgreSQL context setting:

sql
create function lo_simple_upload_context_metadata()
returns json
language plpgsql
as
$$
begin
    return current_setting('request.upload_metadata', true)::text;
end;
$$;

comment on function lo_simple_upload_context_metadata() is 'upload';

Large Object Annotation Options

All shared options plus:

OptionDescription
oidCustom OID for the large object
large_object_included_mime_typesHandler-specific MIME types to include
large_object_excluded_mime_typesHandler-specific MIME types to exclude
large_object_buffer_sizeHandler-specific buffer size
large_object_oidHandler-specific OID (alias for oid)
large_object_check_textHandler-specific text check
large_object_check_imageHandler-specific image check
large_object_test_buffer_sizeHandler-specific test buffer size
large_object_non_printable_thresholdHandler-specific non-printable threshold

File System Handler

Stores files on the server file system.

Basic Example

sql
create function fs_simple_upload(
    _meta json = null
)
returns json
language plpgsql
as
$$
begin
    return _meta;
end;
$$;

comment on function fs_simple_upload(json) is '
upload for file_system
param _meta is upload metadata
';

With Custom Parameters

Control the file path, name, and behavior:

sql
create function fs_custom_parameter_upload(
    _path text,
    _file text,
    _unique_name boolean,
    _create_path boolean,
    _meta json = null
)
returns json
language plpgsql
as
$$
begin
    return _meta;
end;
$$;

comment on function fs_custom_parameter_upload(text, text, boolean, boolean, json) is '
upload for file_system
param _meta is upload metadata
path = {_path}
file = {_file}
unique_name = {_unique_name}
create_path = {_create_path}
';

File System Annotation Options

All shared options plus:

OptionDescription
pathDirectory path for uploaded file
fileFile name to use
unique_nameGenerate unique file name (bool)
create_pathCreate directory if not exists (bool)
file_system_included_mime_typesHandler-specific MIME types to include
file_system_excluded_mime_typesHandler-specific MIME types to exclude
file_system_buffer_sizeHandler-specific buffer size
file_system_pathHandler-specific path (alias for path)
file_system_fileHandler-specific file name (alias for file)
file_system_unique_nameHandler-specific unique name setting
file_system_create_pathHandler-specific create path setting
file_system_check_textHandler-specific text check
file_system_check_imageHandler-specific image check
file_system_test_buffer_sizeHandler-specific test buffer size
file_system_non_printable_thresholdHandler-specific non-printable threshold

MIME Type Filtering

sql
comment on function fs_upload_include_mime_type(json) is '
upload for file_system
param _meta is upload metadata
path = ./test
file = mime_type.csv
included_mime_types = image/*, application/*
';

CSV Handler

Parses CSV files and processes each row via a PostgreSQL command.

Basic Example

sql
-- Table for uploads
create table csv_upload_table (
    index int,
    id int,
    name text,
    value int,
    prev_result int,
    meta json
);

-- Row command to process each CSV row
create procedure csv_upload_row(
    _index int,
    _row text[]
)
language plpgsql
as
$$
begin
    insert into csv_upload_table (index, id, name, value)
    values (_index, _row[1]::int, _row[2], _row[3]::int);
end;
$$;

-- HTTP POST endpoint
create function csv_simple_upload(
    _meta json = null
)
returns json
language plpgsql
as
$$
begin
    return _meta;
end;
$$;

comment on function csv_simple_upload(json) is '
upload for csv
param _meta is upload metadata
row_command = call csv_upload_row($1,$2)
';

With Previous Result and Metadata

The row command can receive up to 4 parameters:

sql
create function csv_simple_upload_process_row(
    _index int,
    _row text[],
    _prev_result int,
    _meta json
)
returns int
language plpgsql
as
$$
begin
    if _index > 1 then  -- Skip header row
        insert into csv_simple_upload_table (
            index, id, name, value, prev_result, meta
        ) values (
            _index, _row[1]::int, _row[2], _row[3]::int, _prev_result, _meta
        );
    end if;
    return _index;
end;
$$;

comment on function csv_simple_upload(json) is '
upload for csv
param _meta is upload metadata
row_command = select csv_simple_upload_process_row($1,$2,$3,$4)
';

CSV Row Command Parameters

ParameterTypeDescription
$1intRow index (1-based, includes header)
$2text[]Parsed row values as text array
$3anyResult of previous row command
$4jsonUpload metadata JSON

Custom Delimiters

Support multiple delimiter characters:

sql
comment on function csv_mixed_delimiter_upload(json) is '
upload for csv
param _meta is upload metadata
delimiters = \t,;
row_command = call csv_mixed_delimiter_upload_row($1,$2)
';

This will use tab (\t), comma (,), and semicolon (;) as delimiters.

CSV Annotation Options

All shared options (except buffer_size, check_text, check_image) plus:

OptionDescription
row_commandPostgreSQL command to process each row
delimitersDelimiter character(s) (default: ,)
check_formatCheck file format before processing
has_fields_enclosed_in_quotesFields may be enclosed in quotes (bool)
set_white_space_to_nullConvert whitespace-only values to NULL (bool)
csv_included_mime_typesHandler-specific MIME types to include
csv_excluded_mime_typesHandler-specific MIME types to exclude
csv_check_formatHandler-specific format check
csv_test_buffer_sizeHandler-specific test buffer size
csv_non_printable_thresholdHandler-specific non-printable threshold
csv_delimitersHandler-specific delimiters (alias for delimiters)
csv_has_fields_enclosed_in_quotesHandler-specific quotes setting
csv_set_white_space_to_nullHandler-specific whitespace setting
csv_row_commandHandler-specific row command (alias for row_command)

Excel Handler

Parses Excel files and processes each row via a PostgreSQL command.

Basic Example

sql
-- Row command for Excel processing
create procedure excel_upload_row(
    _index int,
    _row text[]
)
language plpgsql
as
$$
begin
    insert into excel_upload_table (index, id, name, value)
    values (_index, _row[1]::int, _row[2], _row[3]::int);
end;
$$;

-- HTTP POST endpoint
create function excel_simple_upload(
    _meta json = null
)
returns json
language plpgsql
as
$$
begin
    return _meta;
end;
$$;

comment on function excel_simple_upload(json) is '
upload for excel
param _meta is upload metadata
row_command = call excel_upload_row($1,$2)
';

Excel Annotation Options

All shared options (except buffer_size, check_text, check_image, test_buffer_size, non_printable_threshold) plus:

OptionDescription
row_commandPostgreSQL command to process each row
sheet_nameSpecific sheet name to process
all_sheetsProcess all sheets in the workbook (bool)
time_formatFormat for time values (default: HH:mm:ss)
date_formatFormat for date values (default: yyyy-MM-dd)
datetime_formatFormat for datetime values (default: yyyy-MM-dd HH:mm:ss)
row_is_jsonPass row data as JSON instead of text array (bool)
excel_included_mime_typesHandler-specific MIME types to include
excel_excluded_mime_typesHandler-specific MIME types to exclude
excel_sheet_nameHandler-specific sheet name (alias for sheet_name)
excel_all_sheetsHandler-specific all sheets setting
excel_time_formatHandler-specific time format
excel_date_formatHandler-specific date format
excel_datetime_formatHandler-specific datetime format
excel_row_is_jsonHandler-specific row JSON setting
excel_row_commandHandler-specific row command (alias for row_command)

Error Handling and Rollback

All upload handlers support automatic rollback on error. If the handler function raises an exception, any uploaded data is rolled back:

sql
create function lo_upload_raise_exception(
    _oid bigint,
    _meta json = null
)
returns json
language plpgsql
as
$$
begin
    raise exception 'failed upload';
    return _meta;
end;
$$;

comment on function lo_upload_raise_exception(bigint, json) is '
upload for large_object
param _meta is upload metadata
oid = {_oid}
';

If an exception is raised:

  • Large Object: The large object is deleted
  • File System: The uploaded file is deleted
  • CSV/Excel: All database changes are rolled back

Multiple File Uploads

Upload endpoints support multiple files in a single request. The metadata will be returned as a JSON array with one entry per file.

Behavior

  • Enables multipart/form-data file uploads
  • Handlers process the uploaded file (storage, validation, parsing)
  • Metadata parameter receives file information (name, size, type)
  • All uploads are transactional - errors trigger rollback
  • See Upload Options for configuration

Released under the MIT License.