(core) Fix issue with spurious changes produced by Calculate action.

Summary:
- Replace unicode strings with byte strings when decoding values in sandbox.
- Columns that rely on float values should derive from NumericColumn, so
  that set() ensures that a float is stored even if loading an int.
- Parse unmarshallable values (['U']) into an object that can be encoded
  back to the same value (rather than info a RaisedException).
- Compare NaN's as equal for deciding whether a change is a no-op.

Unrelated:
- Removed a tiny bit of unhelpful logging

Test Plan:
Added a test case that reproduces several causes of Calculate
discrepancies by loading various values into various types of formula columns.

Reviewers: paulfitz

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D2676
This commit is contained in:
Dmitry S
2020-12-01 16:53:33 -05:00
parent 0e2deecc55
commit 0289e3ea17
4 changed files with 42 additions and 20 deletions

View File

@@ -239,7 +239,7 @@ class NumericColumn(BaseColumn):
_sample_date = moment.ts_to_date(0)
_sample_datetime = moment.ts_to_dt(0, None, moment.TZ_UTC)
class DateColumn(BaseColumn):
class DateColumn(NumericColumn):
"""
DateColumn contains numerical timestamps represented as seconds since epoch, in type float,
to midnight of specific UTC dates. Accessing them yields date objects.
@@ -250,7 +250,7 @@ class DateColumn(BaseColumn):
def sample_value(self):
return _sample_date
class DateTimeColumn(BaseColumn):
class DateTimeColumn(NumericColumn):
"""
DateTimeColumn contains numerical timestamps represented as seconds since epoch, in type float,
and a timestamp associated with the column. Accessing them yields datetime objects.
@@ -265,7 +265,7 @@ class DateTimeColumn(BaseColumn):
def sample_value(self):
return _sample_datetime
class PositionColumn(BaseColumn):
class PositionColumn(NumericColumn):
def __init__(self, table, col_id, col_info):
super(PositionColumn, self).__init__(table, col_id, col_info)
# This is a list of row_ids, ordered by the position.