From 8156f957b3b2d20913601554b984580f6714c58f Mon Sep 17 00:00:00 2001 From: Dmitry S Date: Wed, 10 Feb 2021 00:39:02 -0500 Subject: [PATCH] (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 --- app/server/lib/ExpandedQuery.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/app/server/lib/ExpandedQuery.ts b/app/server/lib/ExpandedQuery.ts index f2ec682f..326822e3 100644 --- a/app/server/lib/ExpandedQuery.ts +++ b/app/server/lib/ExpandedQuery.ts @@ -45,26 +45,26 @@ export function expandQuery(iquery: Query, docData: DocData, onDemandFormulas: b 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(); - 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. const joins = new Set(); const selects = new Set(); // Iterate through all formulas, adding joins and selects as we go. 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(); + 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`); for (const column of dataColumns) { selects.add(`${quoteIdent(query.tableId)}.${quoteIdent(column.colId as string)}`);