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

View file

@ -86,18 +86,28 @@ async function execTransactionsGrouped(
let { table: tableName, withDead } = queryState;
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)) {
let allSql = `
SELECT ${sql.select}
FROM ${sql.from}
${sql.joins}
${sql.where} AND is_parent = 0 ${whereDead}
${sql.groupBy}
${sql.orderBy}
${sql.limit != null ? `LIMIT ${sql.limit}` : ''}
${sql.offset != null ? `OFFSET ${sql.offset}` : ''}
`;
return db.all(allSql);
let s = { ...sql };
// Modify the where to only include non-parents
s.where = `${s.where} AND ${s.from}.is_parent = 0`;
// We also want to exclude deleted transactions. Normally we
// handle this manually down below, but now that we are doing a
// normal query we want to rely on the view. Unfortunately, SQL
// 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
// 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;