Route aggregate queries in transaction grouped mode through the correct layer to remove deleted transactions

This commit is contained in:
James Long 2022-09-07 10:34:03 -04:00
parent ffc3e2f423
commit a47edbd466
2 changed files with 23 additions and 13 deletions

View file

@ -951,7 +951,7 @@ function isAggregateFunction(expr) {
return true; return true;
} }
return argExprs.find(ex => isAggregateFunction(ex)); return !!argExprs.find(ex => isAggregateFunction(ex));
} }
export function isAggregateQuery(queryState) { export function isAggregateQuery(queryState) {
@ -963,7 +963,7 @@ export function isAggregateQuery(queryState) {
return true; return true;
} }
return queryState.selectExpressions.find(expr => { return !!queryState.selectExpressions.find(expr => {
if (typeof expr !== 'string') { if (typeof expr !== 'string') {
let [name, value] = Object.entries(expr)[0]; let [name, value] = Object.entries(expr)[0];
return isAggregateFunction(value); return isAggregateFunction(value);

View file

@ -86,18 +86,28 @@ async function execTransactionsGrouped(
let { table: tableName, withDead } = queryState; let { table: tableName, withDead } = queryState;
let whereDead = withDead ? '' : `AND ${sql.from}.tombstone = 0`; let whereDead = withDead ? '' : `AND ${sql.from}.tombstone = 0`;
// Aggregate queries don't make sense for a grouped transactions
// query. We never should include both parent and children
// transactions as it would duplicate amounts and the final number
// would never make sense. In this case, switch back to the "inline"
// type where only non-parent transactions are considered
if (isAggregateQuery(queryState)) { if (isAggregateQuery(queryState)) {
let allSql = ` let s = { ...sql };
SELECT ${sql.select}
FROM ${sql.from} // Modify the where to only include non-parents
${sql.joins} s.where = `${s.where} AND ${s.from}.is_parent = 0`;
${sql.where} AND is_parent = 0 ${whereDead}
${sql.groupBy} // We also want to exclude deleted transactions. Normally we
${sql.orderBy} // handle this manually down below, but now that we are doing a
${sql.limit != null ? `LIMIT ${sql.limit}` : ''} // normal query we want to rely on the view. Unfortunately, SQL
${sql.offset != null ? `OFFSET ${sql.offset}` : ''} // has already been generated so we can't easily change the view
`; // name here; instead, we change it and map it back to the name
return db.all(allSql); // used elsewhere in the query. Ideally we'd improve this
if (!withDead) {
s.from = 'v_transactions_internal_alive v_transactions_internal';
}
return execQuery(queryState, state, s, params, outputTypes);
} }
let rows; let rows;