ArpeNetezza — Data types
How Netezza types map to Apache Arrow on the read path, and how Arrow types map back to Netezza on the ingest and bind paths.
The non-obvious cases are called out below:
TIMESTAMPis a zoneless microsecond timestamp.TIME WITH TIME ZONEandINTERVALcome back as text by default.CHAR/VARCHARare transcoded from LATIN9.- Fixed-length
BINARYcannot be read yet.
Read path: Netezza → Arrow
Netezza returns ordinary query results as a DBOS binary tuple stream, which
the driver decodes straight into Arrow buffers. The table below describes that
path. A few server-evaluated queries with no table (for example
SELECT CURRENT_SCHEMA or SELECT version()) come back as text instead; see
Text results.
Numeric
| Netezza type | Arrow type | Notes |
|---|---|---|
BYTEINT | int8 | |
SMALLINT | int16 | |
INTEGER | int32 | |
BIGINT | int64 | |
NUMERIC(p,s) / DECIMAL(p,s) | decimal128(p,s) | Exact, decoded from the binary value with no string detour. Netezza's maximum precision is 38, so decimal256 is never needed. |
NUMERIC with no precision | decimal128(18,0) | Netezza's default precision and scale. |
REAL | float32 | |
DOUBLE PRECISION | float64 | |
MONEY | decimal128(19,2) |
Character, JSON & binary
| Netezza type | Arrow type | Notes |
|---|---|---|
CHAR(n) / VARCHAR(n) | utf8 | Netezza stores these in LATIN9; the driver transcodes to UTF-8. CHAR values keep their blank padding. Set char_encoding=utf8 if your site stores UTF-8 bytes in VARCHAR. |
NCHAR(n) / NVARCHAR(n) | utf8 | Already UTF-8; passed through. |
JSON / JSONB | utf8 | With json_extension=on, tagged with the arrow.json extension type. |
JSONPATH | utf8 | Never tagged. |
VARBINARY(n) | binary | |
ST_GEOMETRY(n) | binary | The raw stored bytes, with no GeoArrow annotation. |
VECTOR | binary | The raw stored bytes. |
BINARY(n) (fixed length) | — | Not supported: the query fails with "NzType … not yet supported". Cast to VARBINARY in the query. |
Each session runs SET DATATYPE_BACKWARD_COMPATIBILITY ON after login, so
JSON columns can be returned to the driver.
Temporal
| Netezza type | Arrow type | Notes |
|---|---|---|
DATE | date32 | |
TIME | time64[us] | |
TIME WITH TIME ZONE | utf8 | Rendered by the driver, e.g. 12:34:56+02 or 12:34:56+05:30. |
TIMESTAMP | timestamp[us] (no time zone) | Netezza timestamps carry no zone. |
INTERVAL | utf8 (default) / interval(month_day_nano) | See interval_type. |
Read options
interval_type
adbc.arpenz.interval_type (since v0.2.8) chooses the Arrow type of
INTERVAL columns:
| Value | Arrow type | Example |
|---|---|---|
text (default; alias string) | utf8 | 1 day 02:00 |
native (alias month_day_nano) | interval(month_day_nano) | months, then the rest in nanoseconds (the days field is always 0) |
interval(month_day_nano) has no Parquet representation, which is why text is
the default. native applies to binary (DBOS) results only: a text result with
an interval column fails to decode under native.
char_encoding
adbc.arpenz.char_encoding (since v0.3.1): latin9 (default) transcodes
CHAR / VARCHAR bytes from LATIN9 to UTF-8; utf8 passes them through
unchanged. NCHAR / NVARCHAR are never transcoded.
json_extension
adbc.arpenz.json_extension (since v0.2.8): on tags JSON and JSONB
columns with the canonical arrow.json extension type (storage stays utf8).
Default off.
There is no option to change the NUMERIC mapping: it is always
decimal128(p,s).
Text results
Server-evaluated queries with no table come back as text rows. The types follow the same table, with these differences:
INTERVAL,TIME WITH TIME ZONEandVARBINARYhold the server's own text rendering.JSONis never taggedarrow.json.interval_type=nativefails on an interval column (see above).
Schemas without a query
AdbcStatementExecuteSchemareturns exactly the schema the query would return, using the same mapping and read options.AdbcConnectionGetTableSchemabuilds the schema frominformation_schema.columnsand is less exact:- It ignores
interval_typeandjson_extension:INTERVALis alwaysutf8, and JSON is never tagged. - A
NUMERICwith no precision isutf8. - A type it does not recognise is reported as
utf8.
- It ignores
When the exact Arrow schema matters, use ExecuteSchema on
SELECT * FROM <table>.
Write path: Arrow → Netezza (ingest)
adbc_ingest (bulk ingest) is supported in the four ADBC modes: create,
append, replace and create_append. adbc.ingest.mode must be set
explicitly. Data is taken from a stream: Python's adbc_ingest and R's
write_adbc do that for you. In the other APIs, bind the data with
BindStream (an ArrowArrayStream / record-batch reader). Bind of a single
batch to an ingest statement fails with "no data was bound".
Table and column names are quoted as given, so my_table is created as the
case-sensitive "my_table".
How rows are loaded
With autocommit on, an ingest is one transaction: it succeeds or fails as a
whole. With ingest_method=auto (the default):
- External-table load (since v0.3.0). The driver sends one
INSERT INTO t (…) SELECT … FROM EXTERNAL … USING (REMOTESOURCE …)statement, then streams the rows as delimited text. The server parses them in parallel. It needs onlyINSERTon the target. Any rejected row fails the whole load, and the error includes the server's first bad-record diagnostic. - Batched
INSERTfallback. When the load cannot express the ingest, the driver usesINSERT … SELECT … UNION ALLstatements of up to 1000 rows instead. This is much slower: Netezza plans eachUNION ALLbranch. The fallback happens before any data is sent when:- an Arrow column has no target column of exactly the same name;
- an Arrow/target type pair is not in the table below;
- a target
NUMERIChas no precision, or a targetVARBINARYis longer than 32000; - the row is wider than Netezza's 64 KiB external-record limit (for example,
a
JSONBcolumn); - a temporary table shadows a permanent table of the same name.
With ingest_method=external those cases are an error instead; with
ingest_method=insert the external load is never tried.
| Arrow type | External load into |
|---|---|
| integers | integer, floating-point and NUMERIC columns; character columns |
float32 / float64 | floating-point columns; character columns |
decimal128 | NUMERIC and floating-point columns; character columns |
bool | BOOLEAN |
utf8 / binary | character columns; VARBINARY (sent as hex) |
date32 | DATE |
timestamp | TIMESTAMP |
time32 / time64 | TIME |
interval(month_day_nano) | INTERVAL |
Accepted Arrow types
| Accepted | Rejected before any DDL (NOT_IMPLEMENTED) |
|---|---|
bool, int8/int16/int32/int64, float32/float64, utf8, large_utf8, binary, large_binary, decimal128(p,s) (p 1–38, s 0–p), date32, timestamp (any unit, with or without zone), time32/time64, interval(month_day_nano), dictionary-encoded columns (ingested as their values) | unsigned integers, fixed_size_binary, string_view / binary_view, decimal32 / decimal64 / decimal256, negative scale, interval(months), interval(day_time) |
Strings are sent as UTF-8; the server converts them for CHAR / VARCHAR
targets. A NUL byte inside a string is an error. Time zones on timestamps are
ignored, so the UTC value is stored, and nanoseconds are truncated to
microseconds.
Tables created by create / replace / create_append
| Arrow | Netezza column |
|---|---|
bool | BOOLEAN |
int8 | SMALLINT |
int16 / int32 / int64 | SMALLINT / INTEGER / BIGINT |
float32 / float64 | REAL / DOUBLE PRECISION |
utf8 / large_utf8 | NVARCHAR(n), n ≤ 16000 |
binary / large_binary | VARBINARY(n), n ≤ 64000 |
decimal128(p,s) | NUMERIC(p,s) |
date32 | DATE |
time32 / time64 | TIME |
timestamp | TIMESTAMP |
interval(month_day_nano) | not supported in create: ingest intervals in append mode into an existing INTERVAL column |
- An
int8column becomesSMALLINT, notBYTEINT, so it reads back asint16. - Non-nullable Arrow fields become
NOT NULLcolumns. - String and binary widths. Netezza counts
NVARCHAR(n)as 4n bytes of its 64 KiB row. The driver shares the row budget evenly across the string and binary columns, so a single string column getsNVARCHAR(16000)and many string columns get narrower ones. When the data needs a specific width, create the table yourself and ingest withappend. - Temporary tables.
adbc.ingest.temporary=truecreates aCREATE TEMP TABLEand needs a username and password on the connection.adbc.ingest.target_db_schemais ignored for a temporary table.
Bound parameters
Netezza has no server-side prepared statements, so Prepare does nothing on
the server and bound values are rendered into the SQL text by the driver as
escaped literals. Use ? placeholders ($1, $2, … are also recognised);
placeholders inside string literals, quoted identifiers and comments are
ignored. A batch of N parameter rows runs the statement N times. For a query,
the N results are concatenated into one stream; for DML, the row counts are
summed.
| Arrow type | Rendered as |
|---|---|
| null | NULL |
bool | true / false |
int8, uint8, int16, uint16, int32, int64 | integer literal |
float32 / float64 | numeric literal; NaN and ±Infinity as casts |
decimal128(p,s) (p ≤ 38, s ≥ 0) | numeric literal |
utf8, large_utf8, string_view, string dictionaries | quoted string (' doubled) |
binary, large_binary, binary_view, fixed_size_binary(n ≤ 255) | CAST(X'…' AS VARBINARY(n)) |
date32 | quoted date |
timestamp | quoted YYYY-MM-DD HH:MM:SS.ffffff (a zoned timestamp is rendered in UTC, with a +00 suffix) |
time32 / time64 | quoted HH:MM:SS.ffffff |
uint32, uint64, date64 and intervals cannot be bound (NOT_IMPLEMENTED).
GetParameterSchema reports the number of placeholders, typed as int32
unless parameters were already bound.
See also
- Connection: the read options
- Examples: bind and ingest recipes
- Compatibility: supported NPS versions