forked from phoedos/pmd
[plsql] Support WithinClause for LISTAGG function (and similar)
This commit is contained in:
@ -1561,6 +1561,19 @@ ASTWindowingClause WindowingClause() :
|
||||
{ return jjtThis; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Within Clause is used for the following analytic functions: CUME_DIST, DENSE_RANK, LISTAGG, PERCENT_RANK, PERCENTILE_CONT,
|
||||
* PERCENTILE_DISC, RANK.
|
||||
*
|
||||
* See e.g. https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/LISTAGG.html
|
||||
*/
|
||||
ASTWithinClause WithinClause() :
|
||||
{}
|
||||
{
|
||||
"WITHIN" <GROUP> "(" OrderByClause() ")" [ LOOKAHEAD(2) "OVER" "(" QueryPartitionClause() ")" ]
|
||||
{ return jjtThis; }
|
||||
}
|
||||
|
||||
ASTColumn Column() :
|
||||
{ ASTID id; }
|
||||
{
|
||||
@ -2950,8 +2963,8 @@ ASTPrimaryPrefix PrimaryPrefix() :
|
||||
}
|
||||
{
|
||||
(
|
||||
// Note: AnalyticClause is only allowed for specific functions, but this grammar allows it for all functions.
|
||||
LOOKAHEAD(FunctionName() "(") simpleNode = FunctionCall() [ AnalyticClause() ]
|
||||
// Note: AnalyticClause and WithinClause are only allowed for specific functions, but this grammar allows it for all functions.
|
||||
LOOKAHEAD(FunctionName() "(") simpleNode = FunctionCall() [ AnalyticClause() ] [ WithinClause() ]
|
||||
| LOOKAHEAD(Literal()) simpleNode = Literal() { sb.append(simpleNode.getImage()) ; }
|
||||
| LOOKAHEAD(MultiSetCondition()) simpleNode = MultiSetCondition()
|
||||
| LOOKAHEAD(TrimExpression()) simpleNode = TrimExpression() //SRT 20110613.3
|
||||
@ -4810,7 +4823,7 @@ ASTKEYWORD_UNRESERVED KEYWORD_UNRESERVED (): {}
|
||||
{
|
||||
// PL/SQL UNRESERVED KEYWORDS - V$RESERVED.RESERVED='N'
|
||||
(
|
||||
"FIRST" | "REPLACE" | "REF" | "LAST" | "TRIM" | "OVER" | "UNBOUNDED" | "PRECEDING" | "FOLLOWING" |
|
||||
"FIRST" | "REPLACE" | "REF" | "LAST" | "TRIM" | "OVER" | "UNBOUNDED" | "PRECEDING" | "FOLLOWING" | "WITHIN" |
|
||||
<FALSE>
|
||||
| <TRUE>
|
||||
| <A>
|
||||
@ -5974,7 +5987,6 @@ ASTID ID(): {}
|
||||
|
||||
// <COMMIT> | <FUNCTION> | // this causes bug 643043 Procedure w/o params appears as variable
|
||||
| <GOTO> //SYNTAX
|
||||
//| <GROUP> //RESERVED WORD
|
||||
| <HAVING> //RESERVED WORD
|
||||
//20120501 | <HEAP>
|
||||
| <IF> //SYNTAX
|
||||
@ -6221,7 +6233,6 @@ ASTQualifiedID QualifiedID(): {}
|
||||
//<FROM>
|
||||
//| <FUNCTION>
|
||||
//<GOTO>
|
||||
//<GROUP>
|
||||
//<HAVING>
|
||||
//20120501 | <HEAP>
|
||||
//<IF>
|
||||
|
@ -1036,4 +1036,9 @@ public class PLSQLParserVisitorAdapter implements PLSQLParserVisitor {
|
||||
public Object visit(ASTWindowingClause node, Object data) {
|
||||
return visit((PLSQLNode) node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTWithinClause node, Object data) {
|
||||
return visit((PLSQLNode) node, data);
|
||||
}
|
||||
}
|
||||
|
@ -1130,6 +1130,11 @@ public abstract class AbstractPLSQLRule extends AbstractRule implements PLSQLPar
|
||||
return visit((PLSQLNode) node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTWithinClause node, Object data) {
|
||||
return visit((PLSQLNode) node, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Treat all Executable Code
|
||||
*/
|
||||
|
@ -25,5 +25,20 @@ SELECT manager_id, last_name, hire_date, salary,
|
||||
FROM employees
|
||||
ORDER BY manager_id, hire_date, salary;
|
||||
|
||||
-- Example from: https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/LISTAGG.html
|
||||
SELECT LISTAGG(last_name, '; ')
|
||||
WITHIN GROUP (ORDER BY hire_date, last_name) "Emp_list",
|
||||
MIN(hire_date) "Earliest"
|
||||
INTO some_record
|
||||
FROM employees
|
||||
WHERE department_id = 30;
|
||||
|
||||
SELECT department_id "Dept.",
|
||||
LISTAGG(last_name, '; ') WITHIN GROUP (ORDER BY hire_date) "Employees"
|
||||
INTO some_record
|
||||
FROM employees
|
||||
GROUP BY department_id
|
||||
ORDER BY department_id;
|
||||
|
||||
END;
|
||||
/
|
Reference in New Issue
Block a user