(core) Fix 'table not found' error when converting columns in the presence of per-row ACL rules.

Summary:
Column conversions involve changes to metadata tables such as
_grist_Tables_column. When fetched (from GranularAccess), ExpandedQuery used to
fail with 'table not found' because there is no metadata for metadata tables.

This diff limits the need for metadata in ExpandedQuery to when it's actually
needed (to implmement some formulas for on-demand tables), which no longer
interferes with GranularAccess.

Test Plan: Added a test case that reproduces the issue before the fix.

Reviewers: paulfitz

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D2729
This commit is contained in:
Dmitry S 2021-02-10 00:39:02 -05:00
parent 8a2a14ce74
commit 8156f957b3

View File

@ -45,26 +45,26 @@ export function expandQuery(iquery: Query, docData: DocData, onDemandFormulas: b
limit: iquery.limit limit: iquery.limit
}; };
// Look up the main table for the query.
const tables = docData.getTable('_grist_Tables')!;
const columns = docData.getTable('_grist_Tables_column')!;
const tableRef = tables.findRow('tableId', query.tableId);
if (!tableRef) { throw new ApiError('table not found', 404); }
// Find any references to other tables.
const dataColumns = columns.filterRecords({parentId: tableRef, isFormula: false});
const references = new Map<string, string>();
for (const column of dataColumns) {
const refTableId = removePrefix(column.type as string, 'Ref:');
if (refTableId) { references.set(column.colId as string, refTableId); }
}
// Start accumulating a set of joins and selects needed for the query. // Start accumulating a set of joins and selects needed for the query.
const joins = new Set<string>(); const joins = new Set<string>();
const selects = new Set<string>(); const selects = new Set<string>();
// Iterate through all formulas, adding joins and selects as we go. // Iterate through all formulas, adding joins and selects as we go.
if (onDemandFormulas) { if (onDemandFormulas) {
// Look up the main table for the query.
const tables = docData.getTable('_grist_Tables')!;
const columns = docData.getTable('_grist_Tables_column')!;
const tableRef = tables.findRow('tableId', query.tableId);
if (!tableRef) { throw new ApiError('table not found', 404); }
// Find any references to other tables.
const dataColumns = columns.filterRecords({parentId: tableRef, isFormula: false});
const references = new Map<string, string>();
for (const column of dataColumns) {
const refTableId = removePrefix(column.type as string, 'Ref:');
if (refTableId) { references.set(column.colId as string, refTableId); }
}
selects.add(`${quoteIdent(query.tableId)}.id`); selects.add(`${quoteIdent(query.tableId)}.id`);
for (const column of dataColumns) { for (const column of dataColumns) {
selects.add(`${quoteIdent(query.tableId)}.${quoteIdent(column.colId as string)}`); selects.add(`${quoteIdent(query.tableId)}.${quoteIdent(column.colId as string)}`);