From ed11b9e5a15d3f52727681624ad3a95ed5e3060e Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Tue, 29 Dec 2020 15:07:32 +0100 Subject: [PATCH] designer - aggregate, group by, order by --- packages/sqltree/src/dumpSqlExpression.ts | 3 +- .../web/src/designer/DesignerQueryDumper.ts | 52 ++++++++++++++++++- .../web/src/designer/QueryDesignColumns.js | 36 +++++++------ packages/web/src/designer/types.ts | 2 + 4 files changed, 73 insertions(+), 20 deletions(-) diff --git a/packages/sqltree/src/dumpSqlExpression.ts b/packages/sqltree/src/dumpSqlExpression.ts index cd70f817..d5c395a6 100644 --- a/packages/sqltree/src/dumpSqlExpression.ts +++ b/packages/sqltree/src/dumpSqlExpression.ts @@ -29,7 +29,8 @@ export function dumpSqlExpression(dmp: SqlDumper, expr: Expression) { break; case 'call': - dmp.put('%s(%s', expr.func, expr.argsPrefix); + dmp.put('%s(', expr.func); + if (expr.argsPrefix) dmp.put('%s ', expr.argsPrefix); dmp.putCollection(',', expr.args, (x) => dumpSqlExpression(dmp, x)); dmp.put(')'); break; diff --git a/packages/web/src/designer/DesignerQueryDumper.ts b/packages/web/src/designer/DesignerQueryDumper.ts index 3779f742..fce451d9 100644 --- a/packages/web/src/designer/DesignerQueryDumper.ts +++ b/packages/web/src/designer/DesignerQueryDumper.ts @@ -88,14 +88,62 @@ export class DesignerQueryDumper { const topLevelColumns = this.designer.columns.filter((col) => topLevelTables.find((tbl) => tbl.designerId == col.designerId) ); + const selectIsGrouped = !!topLevelColumns.find((x) => x.isGrouped || (x.aggregate && x.aggregate != '---')); const outputColumns = topLevelColumns.filter((x) => x.isOutput); if (outputColumns.length == 0) { res.selectAll = true; } else { - res.columns = outputColumns.map((col) => ({ + res.columns = outputColumns.map((col) => { + const source = findQuerySource(this.designer, col.designerId); + const { columnName } = col; + let { alias } = col; + if (selectIsGrouped && !col.isGrouped) { + // use aggregate + const aggregate = col.aggregate == null || col.aggregate == '---' ? 'MAX' : col.aggregate; + if (!alias) alias = `${aggregate}(${columnName})`; + + return { + exprType: 'call', + func: aggregate == 'COUNT DISTINCT' ? 'COUNT' : aggregate, + argsPrefix: aggregate == 'COUNT DISTINCT' ? 'DISTINCT' : null, + alias, + args: [ + { + exprType: 'column', + columnName, + source, + }, + ], + }; + } else { + return { + exprType: 'column', + columnName, + alias, + source, + }; + } + }); + } + + const groupedColumns = topLevelColumns.filter((x) => x.isGrouped); + if (groupedColumns.length > 0) { + res.groupBy = groupedColumns.map((col) => ({ exprType: 'column', columnName: col.columnName, - alias: col.alias, + source: findQuerySource(this.designer, col.designerId), + })); + } + + const orderColumns = _.sortBy( + topLevelColumns.filter((x) => x.sortOrder), + (x) => Math.abs(x.sortOrder) + ); + if (orderColumns.length > 0) { + res.orderBy = orderColumns.map((col) => ({ + exprType: 'column', + direction: col.sortOrder < 0 ? 'DESC' : 'ASC', + columnName: col.columnName, source: findQuerySource(this.designer, col.designerId), })); } diff --git a/packages/web/src/designer/QueryDesignColumns.js b/packages/web/src/designer/QueryDesignColumns.js index 03b221d9..30257fed 100644 --- a/packages/web/src/designer/QueryDesignColumns.js +++ b/packages/web/src/designer/QueryDesignColumns.js @@ -71,22 +71,24 @@ export default function QueryDesignColumns({ value, onChange }) { ( - { - changeColumn({ ...row, aggregate: e.target.value }); - }} - > - - - - - - - - - )} + formatter={(row) => + !row.isGrouped && ( + { + changeColumn({ ...row, aggregate: e.target.value }); + }} + > + + + + + + + + + ) + } /> { - changeColumn({ ...row, sortOrder: e.target.value }); + changeColumn({ ...row, sortOrder: parseInt(e.target.value) }); }} > diff --git a/packages/web/src/designer/types.ts b/packages/web/src/designer/types.ts index b6257785..9eff0968 100644 --- a/packages/web/src/designer/types.ts +++ b/packages/web/src/designer/types.ts @@ -26,7 +26,9 @@ export type DesignerColumnInfo = { columnName: string; alias?: string; isGrouped?: boolean; + aggregate?: string; isOutput?: boolean; + sortOrder?: number; filter: string; };