@abaplint/core 2.85.31 → 2.85.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/abaplint.d.ts +5 -0
- package/build/src/abap/2_statements/expressions/index.js +1 -0
- package/build/src/abap/2_statements/expressions/select_loop.js +2 -12
- package/build/src/abap/2_statements/expressions/sql_field_list_loop.js +21 -0
- package/build/src/abap/5_syntax/expressions/constant.js +5 -1
- package/build/src/registry.js +1 -1
- package/build/src/rules/downport.js +26 -9
- package/package.json +1 -1
package/build/abaplint.d.ts
CHANGED
|
@@ -1912,6 +1912,7 @@ declare namespace Expressions {
|
|
|
1912
1912
|
SQLCompareOperator,
|
|
1913
1913
|
SQLCompare,
|
|
1914
1914
|
SQLCond,
|
|
1915
|
+
SQLFieldListLoop,
|
|
1915
1916
|
SQLFieldList,
|
|
1916
1917
|
SQLFieldName,
|
|
1917
1918
|
SQLForAllEntries,
|
|
@@ -4894,6 +4895,10 @@ declare class SQLFieldList extends Expression {
|
|
|
4894
4895
|
getRunnable(): IStatementRunnable;
|
|
4895
4896
|
}
|
|
4896
4897
|
|
|
4898
|
+
declare class SQLFieldListLoop extends Expression {
|
|
4899
|
+
getRunnable(): IStatementRunnable;
|
|
4900
|
+
}
|
|
4901
|
+
|
|
4897
4902
|
declare class SQLFieldName extends Expression {
|
|
4898
4903
|
getRunnable(): IStatementRunnable;
|
|
4899
4904
|
}
|
|
@@ -158,6 +158,7 @@ __exportStar(require("./sql_client"), exports);
|
|
|
158
158
|
__exportStar(require("./sql_compare_operator"), exports);
|
|
159
159
|
__exportStar(require("./sql_compare"), exports);
|
|
160
160
|
__exportStar(require("./sql_cond"), exports);
|
|
161
|
+
__exportStar(require("./sql_field_list_loop"), exports);
|
|
161
162
|
__exportStar(require("./sql_field_list"), exports);
|
|
162
163
|
__exportStar(require("./sql_field_name"), exports);
|
|
163
164
|
__exportStar(require("./sql_for_all_entries"), exports);
|
|
@@ -3,25 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SelectLoop = void 0;
|
|
4
4
|
const combi_1 = require("../combi");
|
|
5
5
|
const _1 = require(".");
|
|
6
|
-
const version_1 = require("../../../version");
|
|
7
6
|
const sql_order_by_1 = require("./sql_order_by");
|
|
8
7
|
const sql_having_1 = require("./sql_having");
|
|
9
|
-
const sql_path_1 = require("./sql_path");
|
|
10
|
-
const sql_as_name_1 = require("./sql_as_name");
|
|
11
|
-
const sql_case_1 = require("./sql_case");
|
|
12
8
|
const sql_into_structure_1 = require("./sql_into_structure");
|
|
13
9
|
const sql_field_list_1 = require("./sql_field_list");
|
|
14
10
|
const sql_hints_1 = require("./sql_hints");
|
|
15
|
-
const
|
|
11
|
+
const sql_field_list_loop_1 = require("./sql_field_list_loop");
|
|
16
12
|
class SelectLoop extends combi_1.Expression {
|
|
17
13
|
getRunnable() {
|
|
18
14
|
const where = (0, combi_1.seq)("WHERE", _1.SQLCond);
|
|
19
|
-
const comma = (0, combi_1.opt)((0, combi_1.ver)(version_1.Version.v740sp05, ","));
|
|
20
|
-
const as = (0, combi_1.seq)("AS", sql_as_name_1.SQLAsName);
|
|
21
|
-
const someField = (0, combi_1.seq)((0, combi_1.alt)(_1.SQLFieldName, sql_path_1.SQLPath, _1.SQLAggregation, sql_function_1.SQLFunction, sql_case_1.SQLCase), (0, combi_1.optPrio)(as), comma);
|
|
22
|
-
const fieldList = (0, combi_1.seq)((0, combi_1.star)(someField), (0, combi_1.alt)(_1.SQLFieldName, sql_path_1.SQLPath), (0, combi_1.optPrio)(as), comma, (0, combi_1.star)(someField));
|
|
23
|
-
// todo, use SQLFieldList instead?
|
|
24
|
-
const fields = (0, combi_1.alt)("*", _1.Dynamic, fieldList);
|
|
25
15
|
const client = "CLIENT SPECIFIED";
|
|
26
16
|
const bypass = "BYPASSING BUFFER";
|
|
27
17
|
const up = (0, combi_1.seq)("UP TO", _1.SQLSource, "ROWS");
|
|
@@ -29,7 +19,7 @@ class SelectLoop extends combi_1.Expression {
|
|
|
29
19
|
const tab = (0, combi_1.seq)(_1.SQLIntoTable, (0, combi_1.alt)(pack, (0, combi_1.seq)(_1.SQLFrom, pack), (0, combi_1.seq)(pack, _1.SQLFrom)));
|
|
30
20
|
const perm = (0, combi_1.per)(_1.SQLFrom, where, up, sql_order_by_1.SQLOrderBy, sql_having_1.SQLHaving, client, bypass, _1.SQLGroupBy, _1.SQLForAllEntries, (0, combi_1.alt)(tab, sql_into_structure_1.SQLIntoStructure));
|
|
31
21
|
const strict = (0, combi_1.seq)(_1.SQLFrom, "FIELDS", sql_field_list_1.SQLFieldList, where, sql_into_structure_1.SQLIntoStructure, up);
|
|
32
|
-
const ret = (0, combi_1.seq)("SELECT", (0, combi_1.altPrio)((0, combi_1.seq)((0, combi_1.optPrio)("DISTINCT"),
|
|
22
|
+
const ret = (0, combi_1.seq)("SELECT", (0, combi_1.altPrio)((0, combi_1.seq)((0, combi_1.optPrio)("DISTINCT"), sql_field_list_loop_1.SQLFieldListLoop, perm), strict), (0, combi_1.optPrio)(sql_hints_1.SQLHints));
|
|
33
23
|
return ret;
|
|
34
24
|
}
|
|
35
25
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SQLFieldListLoop = void 0;
|
|
4
|
+
const combi_1 = require("../combi");
|
|
5
|
+
const _1 = require(".");
|
|
6
|
+
const version_1 = require("../../../version");
|
|
7
|
+
const sql_function_1 = require("./sql_function");
|
|
8
|
+
const sql_path_1 = require("./sql_path");
|
|
9
|
+
// loop must include one field from the database table
|
|
10
|
+
class SQLFieldListLoop extends combi_1.Expression {
|
|
11
|
+
getRunnable() {
|
|
12
|
+
const comma = (0, combi_1.opt)((0, combi_1.ver)(version_1.Version.v740sp05, ","));
|
|
13
|
+
const as = (0, combi_1.seq)("AS", _1.SQLAsName);
|
|
14
|
+
const someField = (0, combi_1.seq)((0, combi_1.alt)(_1.SQLFieldName, sql_path_1.SQLPath, _1.SQLAggregation, sql_function_1.SQLFunction, _1.SQLCase), (0, combi_1.optPrio)(as), comma);
|
|
15
|
+
const fieldList = (0, combi_1.seq)((0, combi_1.star)(someField), (0, combi_1.alt)(_1.SQLFieldName, sql_path_1.SQLPath), (0, combi_1.optPrio)(as), comma, (0, combi_1.star)(someField));
|
|
16
|
+
const fields = (0, combi_1.alt)("*", _1.Dynamic, fieldList);
|
|
17
|
+
return fields;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.SQLFieldListLoop = SQLFieldListLoop;
|
|
21
|
+
//# sourceMappingURL=sql_field_list_loop.js.map
|
|
@@ -9,7 +9,11 @@ class Constant {
|
|
|
9
9
|
return new basic_1.IntegerType("I");
|
|
10
10
|
}
|
|
11
11
|
else if (node.getFirstToken().getStr().startsWith("'")) {
|
|
12
|
-
|
|
12
|
+
let len = node.getFirstToken().getStr().length - 2;
|
|
13
|
+
if (len <= 0) {
|
|
14
|
+
len = 1;
|
|
15
|
+
}
|
|
16
|
+
return new basic_1.CharacterType(len);
|
|
13
17
|
}
|
|
14
18
|
else {
|
|
15
19
|
return new basic_1.StringType("STRING");
|
package/build/src/registry.js
CHANGED
|
@@ -291,8 +291,10 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
downportSelectInline(low, high, lowFile, highSyntax) {
|
|
294
|
-
if (!(low.get() instanceof _statement_1.Unknown)
|
|
295
|
-
|
|
294
|
+
if (!(low.get() instanceof _statement_1.Unknown)) {
|
|
295
|
+
return undefined;
|
|
296
|
+
}
|
|
297
|
+
else if (!(high.get() instanceof Statements.Select) && !(high.get() instanceof Statements.SelectLoop)) {
|
|
296
298
|
return undefined;
|
|
297
299
|
}
|
|
298
300
|
// as first step outline the @DATA, note that void types are okay, as long the field names are specified
|
|
@@ -325,7 +327,10 @@ Only one transformation is applied to a statement at a time, so multiple steps m
|
|
|
325
327
|
return undefined;
|
|
326
328
|
}
|
|
327
329
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
328
|
-
|
|
330
|
+
let fieldList = high.findFirstExpression(Expressions.SQLFieldList);
|
|
331
|
+
if (fieldList === undefined) {
|
|
332
|
+
fieldList = high.findFirstExpression(Expressions.SQLFieldListLoop);
|
|
333
|
+
}
|
|
329
334
|
if (fieldList === undefined) {
|
|
330
335
|
return undefined;
|
|
331
336
|
}
|
|
@@ -368,26 +373,31 @@ ${indentation}`);
|
|
|
368
373
|
if (targets.length !== 1) {
|
|
369
374
|
return undefined;
|
|
370
375
|
}
|
|
376
|
+
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
371
377
|
const inlineData = targets[0].findFirstExpression(Expressions.InlineData);
|
|
372
378
|
if (inlineData === undefined) {
|
|
373
379
|
return undefined;
|
|
374
380
|
}
|
|
375
381
|
const sqlFrom = high.findAllExpressions(Expressions.SQLFromSource);
|
|
376
|
-
if (sqlFrom.length
|
|
377
|
-
return
|
|
382
|
+
if (sqlFrom.length === 0) {
|
|
383
|
+
return issue_1.Issue.atToken(lowFile, high.getFirstToken(), "Error outlining, sqlFrom not found", this.getMetadata().key, this.conf.severity);
|
|
378
384
|
}
|
|
379
|
-
|
|
385
|
+
let tableName = (_b = sqlFrom[0].findDirectExpression(Expressions.DatabaseTable)) === null || _b === void 0 ? void 0 : _b.concatTokens();
|
|
380
386
|
if (tableName === undefined) {
|
|
381
387
|
return undefined;
|
|
382
388
|
}
|
|
383
|
-
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
384
389
|
const fieldList = high.findFirstExpression(Expressions.SQLFieldList);
|
|
385
390
|
if (fieldList === undefined) {
|
|
386
391
|
return undefined;
|
|
387
392
|
}
|
|
388
393
|
let fieldDefinitions = "";
|
|
389
394
|
for (const f of fieldList.findDirectExpressions(Expressions.SQLFieldName)) {
|
|
390
|
-
|
|
395
|
+
let fieldName = f.concatTokens();
|
|
396
|
+
if (fieldName.includes("~")) {
|
|
397
|
+
const split = fieldName.split("~");
|
|
398
|
+
fieldName = split[0];
|
|
399
|
+
tableName = split[1];
|
|
400
|
+
}
|
|
391
401
|
fieldDefinitions += indentation + " " + fieldName + " TYPE " + tableName + "-" + fieldName + ",\n";
|
|
392
402
|
}
|
|
393
403
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
@@ -1103,11 +1113,18 @@ ${indentation} output = ${topTarget}.`;
|
|
|
1103
1113
|
}
|
|
1104
1114
|
buildCondBody(body, uniqueName, indent, lowFile, highSyntax) {
|
|
1105
1115
|
let code = "";
|
|
1116
|
+
let first = true;
|
|
1106
1117
|
for (const c of body.getChildren()) {
|
|
1107
1118
|
if (c instanceof nodes_1.TokenNode) {
|
|
1108
1119
|
switch (c.getFirstToken().getStr().toUpperCase()) {
|
|
1109
1120
|
case "WHEN":
|
|
1110
|
-
|
|
1121
|
+
if (first === true) {
|
|
1122
|
+
code += indent + "IF ";
|
|
1123
|
+
first = false;
|
|
1124
|
+
}
|
|
1125
|
+
else {
|
|
1126
|
+
code += indent + "ELSEIF ";
|
|
1127
|
+
}
|
|
1111
1128
|
break;
|
|
1112
1129
|
case "THEN":
|
|
1113
1130
|
code += ".\n";
|