Skip to content

Commit 3a0f78b

Browse files
committed
fix Parser for SELECT with aggregate functions inside parentheses (#134)
1 parent 60e5af5 commit 3a0f78b

File tree

2 files changed

+18
-2
lines changed
  • com.sap.adt.abapcleaner/src/com/sap/adt/abapcleaner/parser
  • test/com.sap.adt.abapcleaner.test/src/com/sap/adt/abapcleaner/parser

2 files changed

+18
-2
lines changed

com.sap.adt.abapcleaner/src/com/sap/adt/abapcleaner/parser/Command.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,7 @@ private boolean opensSelectLoop() throws NullPointerException {
10981098
// - SELECT DISTINCT (column) FROM spfli WHERE ...
10991099
// (see https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapselect_list.htm)
11001100
Token selectListStart = selectClauseStart;
1101-
if (selectListStart.textStartsWith("("))
1101+
if (selectListStart.textStartsWith("(") && selectListStart.getNext().isAttached())
11021102
return true;
11031103

11041104
// loop over the columns in the select list. Examples showing the [select list] in brackets:
@@ -1113,8 +1113,23 @@ private boolean opensSelectLoop() throws NullPointerException {
11131113
while (token != null && token != selectClauseEnd) {
11141114
// if any of the columns in the select clause is NOT an aggregate function, ENDSELECT is required
11151115
// (do not use token.isAnyKeyword() here, since some aggregate functions may not be classified correctly)
1116-
if (!token.textEqualsAny(aggregateFunctions))
1116+
boolean aggregateFunctionFound = false;
1117+
if (token.textEquals("(")) {
1118+
// consider arithmetic expressions such as '( SUM( amt1 ) + SUM( amt2 ) ) AS amt_sum'
1119+
Token test = token.getNextCodeToken();
1120+
while (test != token.getNextSibling()) {
1121+
if (test.textEqualsAny(aggregateFunctions)) {
1122+
aggregateFunctionFound = true;
1123+
break;
1124+
}
1125+
test = test.getNextCodeToken();
1126+
}
1127+
} else {
1128+
aggregateFunctionFound = token.textEqualsAny(aggregateFunctions);
1129+
}
1130+
if (!aggregateFunctionFound) {
11171131
return true;
1132+
}
11181133

11191134
// move behind the closing parenthesis ")" of the aggregate function; even "COUNT(*)" is tokenized into 3 Tokens
11201135
token = token.getNextCodeSibling().getNextCodeSibling();

test/com.sap.adt.abapcleaner.test/src/com/sap/adt/abapcleaner/parser/CommandTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,7 @@ void testRequiresEndSelect() {
11101110
assertFalse(buildCommand("SELECT FROM dtab FIELDS fld1, MIN( price ) AS min_price, MAX( price ) AS max_price GROUP BY fld1 INTO TABLE @DATA(result).").getOpensLevel());
11111111
assertFalse(buildCommand("SELECT FROM dtab FIELDS COUNT( CASE WHEN num1 < 4 THEN 'X' WHEN num1 BETWEEN 4 AND 7 THEN 'Y' END ) AS cnt, COUNT(*) AS cntstar INTO TABLE @DATA(result).").getOpensLevel());
11121112
assertFalse(buildCommand("SELECT FROM dtab FIELDS COUNT(*) INTO (@DATA(avg)).").getOpensLevel());
1113+
assertFalse(buildCommand("SELECT ( SUM( amt1 ) + SUM( amt2 ) ) AS amt_sum FROM any_table INTO @DATA(lt_amount).").getOpensLevel());
11131114
}
11141115

11151116
@Test

0 commit comments

Comments
 (0)