(core) Linking summary tables grouped by list columns

Summary:
Prefix keys of `LinkingState.filterColValues` with `_contains:` when the source column is a ChoiceList or ReferenceList.

This is parsed out to make a boolean `isContainsFilter` which is kept in each value of `QueryRefs.filterTuples` (previously `filterPairs`).

Then when converting back in `convertQueryFromRefs` we construct `Query.contains: {[colId: string]: boolean}`.

Finally `getFilterFunc` uses `Query.contains` to decide what kind of filtering to do.

This is not pretty, but the existing code is already very complex and it was hard to find something that wouldn't require touching loads of code just to make things compile.

Test Plan: Added a new nbrowser test and fixture, tests that selecting a source table by summary tables grouped by a choicelist column, non-list column, and both all filter the correct data.

Reviewers: dsagal

Reviewed By: dsagal

Differential Revision: https://phab.getgrist.com/D2940
This commit is contained in:
Alex Hall
2021-08-10 20:21:03 +02:00
parent 4d526da58f
commit 7f1f8fc9e6
8 changed files with 128 additions and 68 deletions

View File

@@ -980,13 +980,22 @@ class Engine(object):
old_tables = self.tables
self.tables = {}
sorted_tables = []
for table_id, user_table in six.iteritems(self.gencode.usercode.__dict__):
if isinstance(user_table, table_module.UserTable):
self.tables[table_id] = (old_tables.get(table_id) or table_module.Table(table_id, self))
if not isinstance(user_table, table_module.UserTable):
continue
self.tables[table_id] = table = (
old_tables.get(table_id) or table_module.Table(table_id, self)
)
# Process non-summary tables first so that summary tables
# can read correct metadata about their source tables
key = (hasattr(user_table.Model, '_summarySourceTable'), table_id)
sorted_tables.append((key, table, user_table))
sorted_tables.sort()
# Now update the table model for each table, and tie it to its UserTable object.
for table_id, table in six.iteritems(self.tables):
user_table = getattr(self.gencode.usercode, table_id)
for _, table, user_table in sorted_tables:
self._update_table_model(table, user_table)
user_table._set_table_impl(table)