prestodb/presto · error
INVALID_FUNCTION_ARGUMENT
INVALID_FUNCTION_ARGUMENT
Error message
Column mapped as the Accumulo row ID cannot be null
What it means
Thrown in AccumuloPageSink.toMutation when the row value at the rowIdOrdinal is null. The Accumulo row ID is the mutation's unique row key — Accumulo mutations cannot have a null row — so the Presto Accumulo connector rejects the row with INVALID_FUNCTION_ARGUMENT instead of writing an unusable mutation.
Source
Thrown at presto-accumulo/src/main/java/com/facebook/presto/accumulo/io/AccumuloPageSink.java:148
}
}
/**
* Converts a {@link Row} to an Accumulo mutation.
*
* @param row Row object
* @param rowIdOrdinal Ordinal in the list of columns that is the row ID. This isn't checked at all, so I hope you're right. Also, it is expected that the list of column handles is sorted in ordinal order. This is a very demanding function.
* @param columns All column handles for the Row, sorted by ordinal.
* @param serializer Instance of {@link AccumuloRowSerializer} used to encode the values of the row to the Mutation
* @return Mutation
*/
public static Mutation toMutation(Row row, int rowIdOrdinal, List<AccumuloColumnHandle> columns, AccumuloRowSerializer serializer)
{
// Set our value to the row ID
Text value = new Text();
Field rowField = row.getField(rowIdOrdinal);
if (rowField.isNull()) {
throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "Column mapped as the Accumulo row ID cannot be null");
}
setText(rowField, value, serializer);
// Iterate through all the column handles, setting the Mutation's columns
Mutation mutation = new Mutation(value);
// Store row ID in a special column
mutation.put(ROW_ID_COLUMN, ROW_ID_COLUMN, new Value(value.copyBytes()));
for (AccumuloColumnHandle columnHandle : columns) {
// Skip the row ID ordinal
if (columnHandle.getOrdinal() == rowIdOrdinal) {
continue;
}
// If the value of the field is not null
if (!row.getField(columnHandle.getOrdinal()).isNull()) {
// Serialize the value to the textView on GitHub (pinned to 55bb57d202)
Solutions
- Ensure the row ID column is non-NULL: fix the INSERT column list/order or the source data
- Filter out rows with null keys before inserting: WHERE rowid_col IS NOT NULL
- Coerce nulls to a sentinel/default value if acceptable for the application
- Verify which column is the row ID (SHOW CREATE TABLE) and adjust the INSERT to supply a real value there
Example fix
// before INSERT INTO myschema.mytable SELECT col_a, NULL, col_b FROM staging; -- NULL lands in rowid column // after INSERT INTO myschema.mytable SELECT col_a, coalesce(rowid_src, 'unknown'), col_b FROM staging WHERE rowid_src IS NOT NULL;
Defensive patterns
Strategy: validation
Validate before calling
// Reject inserts whose row ID column is NULL before writing
TableMetadata tableMeta = metadata.getTableMetadata(session, tableName);
AccumuloTableHandle table = (AccumuloTableHandle) tableMeta.getTable();
int rowIdOrdinal = columns.stream()
.filter(c -> c.getName().equals(table.getRowId()))
.map(AccumuloColumnHandle::getOrdinal).findAny()
.orElseThrow(() -> new IllegalArgumentException("row id column missing"));
// per-row check before insert:
if (page.getBlock(rowIdOrdinal).isNull(position)) {
throw new IllegalArgumentException("Row ID column " + table.getRowId() + " cannot be NULL");
} Type guard
boolean hasNonNullRowId(Page page, int rowIdOrdinal) {
Block block = page.getBlock(rowIdOrdinal);
for (int pos = 0; pos < block.getPositionCount(); pos++) {
if (block.isNull(pos)) return false;
}
return true;
} Try / catch
try {
pageSink.appendPage(page);
} catch (PrestoException e) {
if (e.getErrorCode().getCode() == StandardErrorCode.INVALID_FUNCTION_ARGUMENT.toErrorCode().getCode()
&& e.getMessage().contains("row ID cannot be null")) {
throw new IllegalArgumentException("Filter out rows where " + rowIdColumn + " IS NULL before inserting", e);
}
throw e;
} Prevention
- Declare the row ID column NOT NULL in the table definition so nulls fail at insert analysis time
- Always use an explicit column list in INSERT statements to avoid positional mismatches
- Add IS NOT NULL filters when inserting from external sources with nullable keys
- Run SHOW CREATE TABLE to confirm which column is the row ID before bulk loads
When it happens
Trigger: Inserting a row whose column mapped as the Accumulo row ID (table's row_id property) is NULL; commonly via INSERT INTO ... VALUES with a NULL in that position, or data from a source table containing nulls in the row ID column.
Common situations: INSERT with column order mismatch so NULL lands in the row ID column; migrating data from a relational source that permits null keys; CTAS/INSERT from an external feed with missing key values; confusion about which column the connector treats as the row ID.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/bd22e28720c8628a.
Report an issue: GitHub.