All files / src/abap/5_syntax/statements insert_internal.ts

99.01% Statements 101/102
95.91% Branches 47/49
100% Functions 1/1
99.01% Lines 101/102

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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 1021x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 88x 88x 88x 88x 86x 86x 88x 88x 88x 88x 88x 2x 2x 2x 88x 86x 80x 80x 86x 86x 88x 25x 25x 88x 88x 88x 88x 88x 88x 88x 1x 1x 1x 1x 85x 85x 88x 5x 5x 3x 5x 2x 2x 5x 85x 88x 82x 82x 1x 82x   81x 1x 1x 1x 82x 82x 2x 2x 2x 2x 82x 83x 83x 88x 9x 9x 3x 9x 6x 6x 1x 1x 1x 1x 6x 9x 82x 88x 26x 24x 24x 2x 2x 82x 82x 1x
import * as Expressions from "../../2_statements/expressions";
import {StatementNode} from "../../nodes";
import {InlineFS} from "../expressions/inline_fs";
import {Source} from "../expressions/source";
import {Target} from "../expressions/target";
import {FSTarget} from "../expressions/fstarget";
import {AbstractType} from "../../types/basic/_abstract_type";
import {AnyType, CharacterType, DataReference, Integer8Type, IntegerType, StringType, TableAccessType, TableType, UnknownType, VoidType} from "../../types/basic";
import {StatementSyntax} from "../_statement_syntax";
import {InlineData} from "../expressions/inline_data";
import {TypeUtils} from "../_type_utils";
import {SyntaxInput, syntaxIssue} from "../_syntax_input";
 
export class InsertInternal implements StatementSyntax {
  public runSyntax(node: StatementNode, input: SyntaxInput): void {
 
    let targetType: AbstractType | undefined;
    const t = node.findDirectExpression(Expressions.Target);
    if (t) {
      targetType = Target.runSyntax(t, input);
    }
    if (!(targetType instanceof TableType)
        && !(targetType instanceof VoidType)
        && !(targetType instanceof AnyType)
        && !(targetType instanceof UnknownType)
        && targetType !== undefined) {
      const message = "INSERT target must be a table";
      input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
      return;
    } else if (targetType instanceof TableType
        && node.findDirectTokenByText("LINES") === undefined) {
      targetType = targetType.getRowType();
    }
 
    let source = node.findDirectExpression(Expressions.SimpleSource4);
    if (source === undefined) {
      source = node.findDirectExpression(Expressions.Source);
    }
    const sourceType = source ? Source.runSyntax(source, input, targetType) : targetType;
 
    if (targetType === undefined
        && !(sourceType instanceof TableType)
        && !(sourceType instanceof VoidType)
        && !(sourceType instanceof AnyType)
        && !(sourceType instanceof UnknownType)) {
      const message = "INSERT target must be a table";
      input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
      return;
    }
 
    const afterAssigning = node.findExpressionAfterToken("ASSIGNING");
    if (afterAssigning?.get() instanceof Expressions.FSTarget) {
      const inlinefs = afterAssigning?.findDirectExpression(Expressions.InlineFS);
      if (inlinefs) {
        InlineFS.runSyntax(inlinefs, input, sourceType);
      } else {
        FSTarget.runSyntax(afterAssigning, input, sourceType);
      }
    }
 
    if (node.findDirectTokenByText("INITIAL") === undefined) {
      let error = false;
      if (sourceType instanceof IntegerType && targetType instanceof Integer8Type) {
        error = true;
      } else if (new TypeUtils(input.scope).isAssignable(sourceType, targetType) === false) {
        error = true;
      } else if (sourceType instanceof CharacterType && targetType instanceof StringType) {
        // yea, well, INSERT doesnt convert the values automatically, like everything else?
        error = true;
      }
 
      if (error === true) {
        const message = "Types not compatible";
        input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
        return;
      }
    }
 
    const afterInto = node.findExpressionAfterToken("INTO");
    if (afterInto?.get() instanceof Expressions.Target && sourceType) {
      const inline = afterInto.findDirectExpression(Expressions.InlineData);
      if (inline) {
        InlineData.runSyntax(afterInto, input, new DataReference(sourceType));
      } else {
        const type = Target.runSyntax(afterInto, input);
        if (type instanceof TableType && type.getAccessType() === TableAccessType.hashed) {
          const message = "Implicit or explicit index operation on hashed table is not possible";
          input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
          return;
        }
      }
    }
 
    for (const s of node.findDirectExpressions(Expressions.Source)) {
      if (s === source) {
        continue;
      }
      Source.runSyntax(s, input, targetType);
    }
 
  }
}