UNPKG

@abaplint/core

Version:
116 lines (114 loc) 5.13 kB
"use strict"; 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