fix: list-mode insert_all/upsert_all with hash_id misaligns values

When insert_all() or upsert_all() received lists of values plus an
auto-generated hash_id, all_columns had the hash column prepended but
the raw rows were then paired against that expanded list. Every value
shifted one column to the left and the hash_id column ended up holding
the first value instead of a key, e.g. rows (1, 'x') became (1, 'x',
NULL) under columns (id, a, b). Compute the hash from the
user-declared values and prepend it so columns stay aligned.
This commit is contained in:
Harsh Thakkar 2026-09-24 05:53:08 +05:30
commit 5e4525a4f2
2 changed files with 56 additions and 3 deletions

View file

@ -4353,16 +4353,32 @@ class Table(Queryable):
if list_mode:
# In list mode, records are already lists of values
num_columns = len(all_columns)
# With hash_id, all_columns has the hash column prepended, but the
# records themselves only carry the user-declared columns.
user_columns = all_columns[1:] if hash_id else all_columns
user_num_columns = len(user_columns)
has_extracts = bool(extracts)
for record in chunk:
# Pad short records with None, truncate long ones
record_len = len(record)
if record_len < num_columns:
if record_len < user_num_columns:
record_values = [jsonify_if_needed(v) for v in record] + [None] * (
num_columns - record_len
user_num_columns - record_len
)
else:
record_values = [jsonify_if_needed(v) for v in record[:num_columns]]
record_values = [
jsonify_if_needed(v) for v in record[:user_num_columns]
]
if hash_id:
# Compute the hash from the user-declared values so the
# hash_id column gets the right key instead of shifting
# every value one column over.
record_values.insert(
0,
hash_record(
dict(zip(user_columns, record_values)), hash_id_columns
),
)
# Only process extracts if there are any
if has_extracts:
for i, key in enumerate(all_columns):