(core) Fix bug causing "unmarshallable object" error during conversion to ReferenceList.

Summary:
When a value $B.A is a ReferenceList, returning it in an Any column can cause
an "unmarshallable object" error, if the RecordSet happens to be storing
row_ids in the form of a nested RecordList object. This happened consistently
when $B.A started off as another type and got converted to ReferenceList.

A specific manifestation was when a reference column $B uses "A" as a display
column, and this column gets converted from Text to ReferenceList.

Test Plan: Added a test that reproduces the problem.

Reviewers: alexmojaki

Reviewed By: alexmojaki

Differential Revision: https://phab.getgrist.com/D3089
This commit is contained in:
Dmitry S 2021-10-23 02:12:59 -04:00
parent 99878c08ed
commit e5beafb256
2 changed files with 13 additions and 2 deletions

View File

@ -190,7 +190,7 @@ def encode_object(value):
elif isinstance(value, (list, tuple)): elif isinstance(value, (list, tuple)):
return ['L'] + [encode_object(item) for item in value] return ['L'] + [encode_object(item) for item in value]
elif isinstance(value, records.RecordSet): elif isinstance(value, records.RecordSet):
return ['r', value._table.table_id, value._row_ids] return ['r', value._table.table_id, value.get_encodable_row_ids()]
elif isinstance(value, RecordSetStub): elif isinstance(value, RecordSetStub):
return ['r', value.table_id, value.row_ids] return ['r', value.table_id, value.row_ids]
elif isinstance(value, dict): elif isinstance(value, dict):

View File

@ -142,7 +142,7 @@ class RecordSet(object):
self._table = table self._table = table
self._row_ids = row_ids self._row_ids = row_ids
self._source_relation = relation or table._identity_relation self._source_relation = relation or table._identity_relation
# If row_ids is itself a RecordSet, default to its _group_by and _sort_by properties. # If row_ids is itself a RecordList, default to its _group_by and _sort_by properties.
self._group_by = group_by or getattr(row_ids, '_group_by', None) self._group_by = group_by or getattr(row_ids, '_group_by', None)
self._sort_by = sort_by or getattr(row_ids, '_sort_by', None) self._sort_by = sort_by or getattr(row_ids, '_sort_by', None)
@ -194,6 +194,17 @@ class RecordSet(object):
group_by=self._group_by, group_by=self._group_by,
sort_by=self._sort_by) sort_by=self._sort_by)
def get_encodable_row_ids(self):
"""
Returns stored rowIds as a simple list or tuple type, even if actually stored as RecordList.
"""
# pylint: disable=unidiomatic-typecheck
if type(self._row_ids) in (list, tuple):
return self._row_ids
else:
return list(self._row_ids)
def adjust_record(relation, value): def adjust_record(relation, value):
""" """