All files / src/abap/5_syntax/expressions select.ts

100% Statements 56/56
90% Branches 18/20
100% Functions 1/1
100% Lines 56/56

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 561x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 49x 49x 49x 49x 49x 49x 47x 49x 25x 25x 25x 47x 47x 49x 5x 5x 5x 47x 49x 41x 41x 40x 40x 49x 7x 7x 7x 2x 2x 2x 2x 2x 7x 38x 49x 22x 22x 34x 49x 5x 5x 49x 1x
import * as Expressions from "../../2_statements/expressions";
import {ExpressionNode} from "../../nodes";
import {CurrentScope} from "../_current_scope";
import {VoidType} from "../../types/basic";
import {InlineData} from "./inline_data";
import {Target} from "./target";
import {SQLFrom} from "./sql_from";
import {Source} from "./source";
import {SQLForAllEntries} from "./sql_for_all_entries";
import {ScopeType} from "../_scope_type";
 
export class Select {
  public runSyntax(node: ExpressionNode, scope: CurrentScope, filename: string): void {
    const token = node.getFirstToken();
 
    const from = node.findDirectExpression(Expressions.SQLFrom);
    if (from) {
      new SQLFrom().runSyntax(from, scope, filename);
    }
 
    for (const inline of node.findAllExpressions(Expressions.InlineData)) {
      // todo, for now these are voided
      new InlineData().runSyntax(inline, scope, filename, new VoidType("SELECT_todo"));
    }
 
    const fae = node.findDirectExpression(Expressions.SQLForAllEntries);
    if (fae) {
      scope.push(ScopeType.OpenSQL, "SELECT", token.getStart(), filename);
      new SQLForAllEntries().runSyntax(fae, scope, filename);
    }
 
    for (const t of node.findAllExpressions(Expressions.Target)) {
      new Target().runSyntax(t, scope, filename);
    }
    // check implicit into, the target field is implict equal to the table name
    if (node.findDirectExpression(Expressions.SQLIntoTable) === undefined
        && node.findDirectExpression(Expressions.SQLIntoStructure) === undefined) {
      const fields = node.findFirstExpression(Expressions.SQLAggregation)?.concatTokens();
      const c = new RegExp(/^count\(\s*\*\s*\)$/, "i");
      if (fields === undefined || c.test(fields) === false) {
        const name = from?.findDirectExpression(Expressions.SQLFromSource)?.concatTokens();
        if (name && scope.findVariable(name) === undefined) {
          throw new Error(`Target variable ${name} not found in scope`);
        }
      }
    }
 
    for (const s of node.findAllExpressions(Expressions.Source)) {
      new Source().runSyntax(s, scope, filename);
    }
 
    if (scope.getType() === ScopeType.OpenSQL) {
      scope.pop(node.getLastToken().getEnd());
    }
  }
}