@abaplint/core
Version:
abaplint - Core API
116 lines (114 loc) • 5.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SelectAddOrderBy = exports.SelectAddOrderByConf = void 0;
const Expressions = require("../abap/2_statements/expressions");
const Statements = require("../abap/2_statements/statements");
const _basic_rule_config_1 = require("./_basic_rule_config");
const issue_1 = require("../issue");
const _irule_1 = require("./_irule");
const syntax_1 = require("../abap/5_syntax/syntax");
const _abap_object_1 = require("../objects/_abap_object");
const basic_1 = require("../abap/types/basic");
class SelectAddOrderByConf extends _basic_rule_config_1.BasicRuleConfig {
constructor() {
super(...arguments);
this.skipForAllEntries = false;
}
}
exports.SelectAddOrderByConf = SelectAddOrderByConf;
class SelectAddOrderBy {
constructor() {
this.conf = new SelectAddOrderByConf();
}
getMetadata() {
return {
key: "select_add_order_by",
title: "SELECT add ORDER BY",
shortDescription: `SELECTs add ORDER BY clause`,
extendedInformation: `
This will make sure that the SELECT statement returns results in the same sequence on different databases
add ORDER BY PRIMARY KEY if in doubt
If the target is a sorted/hashed table, no issue is reported`,
tags: [_irule_1.RuleTag.SingleFile],
badExample: `SELECT * FROM db INTO TABLE @DATA(tab).`,
goodExample: `SELECT * FROM db INTO TABLE @DATA(tab) ORDER BY PRIMARY KEY.`,
};
}
getConfig() {
return this.conf;
}
initialize(reg) {
this.reg = reg;
return this;
}
setConfig(conf) {
this.conf = conf;
}
run(obj) {
var _a, _b;
const issues = [];
if (!(obj instanceof _abap_object_1.ABAPObject) || obj.getType() === "INTF") {
return [];
}
const spaghetti = new syntax_1.SyntaxLogic(this.reg, obj).run().spaghetti;
for (const file of obj.getABAPFiles()) {
const stru = file.getStructure();
if (stru === undefined) {
return issues;
}
const selects = stru.findAllStatements(Statements.Select);
selects.push(...stru.findAllStatements(Statements.SelectLoop));
for (const s of selects) {
const concat = s.concatTokens().toUpperCase();
if (concat.startsWith("SELECT SINGLE ")) {
continue;
}
else if (((_a = this.getConfig()) === null || _a === void 0 ? void 0 : _a.skipForAllEntries) === true && concat.includes(" FOR ALL ENTRIES ")) {
continue;
}
// skip COUNT(*)
const list = s.findAllExpressions(Expressions.SQLField);
if (list.length === 1 && ((_b = list[0].getFirstChild()) === null || _b === void 0 ? void 0 : _b.get()) instanceof Expressions.SQLAggregation) {
continue;
}
else if (s.findFirstExpression(Expressions.SQLOrderBy)) {
continue;
}
if (this.isTargetSortedOrHashed(s, spaghetti, file)) {
continue;
}
else if (s.findFirstExpression(Expressions.SQLJoin) && s.findFirstExpression(Expressions.SQLForAllEntries)) {
// see https://github.com/abaplint/abaplint/issues/2957
continue;
}
issues.push(issue_1.Issue.atStatement(file, s, "Add ORDER BY", this.getMetadata().key, this.conf.severity));
}
}
return issues;
}
isTargetSortedOrHashed(s, spaghetti, file) {
var _a, _b;
const target = (_a = s.findFirstExpression(Expressions.SQLIntoTable)) === null || _a === void 0 ? void 0 : _a.findFirstExpression(Expressions.Target);
if (target) {
const start = target.getFirstToken().getStart();
const scope = spaghetti.lookupPosition(start, file.getFilename());
let type = (_b = scope === null || scope === void 0 ? void 0 : scope.findWriteReference(start)) === null || _b === void 0 ? void 0 : _b.getType();
const children = target.getChildren();
if (type instanceof basic_1.StructureType && children.length >= 3 && children[1].concatTokens() === "-") {
const found = type.getComponentByName(children[2].concatTokens());
if (found === undefined) {
return false;
}
type = found;
}
if (type instanceof basic_1.TableType
&& ((type === null || type === void 0 ? void 0 : type.getAccessType()) === basic_1.TableAccessType.sorted
|| (type === null || type === void 0 ? void 0 : type.getAccessType()) === basic_1.TableAccessType.hashed)) {
return true;
}
}
return false;
}
}
exports.SelectAddOrderBy = SelectAddOrderBy;
//# sourceMappingURL=select_add_order_by.js.map