Skip to content

Commit

Permalink
support ARRAY_AGG distinct
Browse files Browse the repository at this point in the history
  • Loading branch information
taozhi8833998 committed Sep 2, 2020
1 parent ef3e94c commit e278e6c
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 6 deletions.
18 changes: 17 additions & 1 deletion pegjs/postgresql.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -2274,6 +2274,7 @@ param
aggr_func
= aggr_fun_count
/ aggr_fun_smma
/ aggr_array_agg

aggr_fun_smma
= name:KW_SUM_MAX_MIN_AVG __ LPAREN __ e:additive_expr __ RPAREN {
Expand All @@ -2300,9 +2301,23 @@ aggr_fun_count
};
}

distinct_args
= d:KW_DISTINCT? __ c:column_ref { /* => { distinct: 'DISTINCT'; expr: column_ref; } */ return { distinct: d, expr: c }; }

count_arg
= e:star_expr { /* => { expr: star_expr } */ return { expr: e }; }
/ d:KW_DISTINCT? __ c:column_ref { /* => { distinct: 'DISTINCT'; expr: column_ref; } */ return { distinct: d, expr: c }; }
/ distinct_args

aggr_array_agg
= name:KW_ARRAY_AGG __ LPAREN __ arg:distinct_args __ o:order_by_clause? __ RPAREN {
// => { type: 'aggr_func'; name: 'ARRAY_AGG'; args:count_arg; orderby?: order_by_clause }
return {
type: 'aggr_func',
name: name,
args: arg,
orderby: o,
};
}

star_expr
= "*" { /* => { type: 'star'; value: '*' } */ return { type: 'star', value: '*' }; }
Expand Down Expand Up @@ -2652,6 +2667,7 @@ KW_NOT = "NOT"i !ident_start { return 'NOT'; }
KW_AND = "AND"i !ident_start { return 'AND'; }
KW_OR = "OR"i !ident_start { return 'OR'; }

KW_ARRAY_AGG = "ARRAY_AGG"i !ident_start { return 'ARRAY_AGG'; }
KW_COUNT = "COUNT"i !ident_start { return 'COUNT'; }
KW_MAX = "MAX"i !ident_start { return 'MAX'; }
KW_MIN = "MIN"i !ident_start { return 'MIN'; }
Expand Down
7 changes: 4 additions & 3 deletions src/aggregation.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { exprToSQL } from './expr'
import { exprToSQL, orderOrPartitionByToSQL } from './expr'
import { hasVal } from './util'
import { overToSQL } from './over'

function aggrToSQL(expr) {
/** @type {Object} */
const { args, over } = expr
const { args, over, orderby } = expr
let str = exprToSQL(args.expr)
const fnName = expr.name
const overStr = overToSQL(over)
if (fnName === 'COUNT' && args.distinct) str = `DISTINCT ${str}`
if (args.distinct) str = `DISTINCT ${str}`
if (orderby) str = `${str} ${orderOrPartitionByToSQL(orderby, 'order by')}`
return [`${fnName}(${str})`, overStr].filter(hasVal).join(' ')
}

Expand Down
10 changes: 9 additions & 1 deletion test/select.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,14 @@ describe('select', () => {
const backSQL = parser.sqlify(ast, opt)
expect(backSQL).to.equal('SELECT "column_name" AS "Column Name" FROM "table_name"')
})

it('should support array_agg', () => {
const sql = `SELECT shipmentId, ARRAY_AGG(distinct abc order by name) AS shipmentStopIDs, ARRAY_AGG (first_name || ' ' || last_name) actors FROM table_name GROUP BY shipmentId
`
const ast = parser.astify(sql, opt)
const backSQL = parser.sqlify(ast, opt)
expect(backSQL).to.equal('SELECT "shipmentId", ARRAY_AGG(DISTINCT "abc" ORDER BY "name" ASC) AS "shipmentStopIDs", ARRAY_AGG("first_name" || \' \' || "last_name") AS "actors" FROM "table_name" GROUP BY "shipmentId"')
})
})


Expand Down Expand Up @@ -1289,7 +1297,7 @@ describe('select', () => {
it('should parse COLLECT aggr_func expression', () => {
const sql = 'SELECT bar, COLLECT(DISTINCT foo) FROM tablename GROUP BY bar';
expect(getParsedSql(sql, opt))
.to.be.equal('SELECT `bar`, COLLECT(`foo`) FROM `tablename` GROUP BY `bar`', opt)
.to.be.equal('SELECT `bar`, COLLECT(DISTINCT `foo`) FROM `tablename` GROUP BY `bar`', opt)
})

it('should parse LISTAGG aggr_func', () => {
Expand Down
2 changes: 1 addition & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const moduleCfg = {
},
{
test: /\.pegjs$/,
loader: 'pegjs-loader'
loader: 'pegjs-loader?dependencies={"BigInt":"big-integer"}'
}
],
}
Expand Down

0 comments on commit e278e6c

Please sign in to comment.