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 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 136x 136x 136x 136x 136x 7x 7x 7x 129x 136x 129x 136x 113x 146x 113x 113x 113x 146x 113x 113x 113x 129x 129x 136x 16x 16x 129x 136x 136x 97x 97x 97x 97x 97x 97x 1x 97x 96x 96x 96x 96x 96x 1x 96x 95x 95x 2x 95x 93x 93x 97x 4x 4x 97x 136x 1x 1x 97x 100x 100x 13x 13x 100x 84x 84x 1x 1x | import {AbstractToken} from "../../1_lexer/tokens/abstract_token";
import * as Expressions from "../../2_statements/expressions";
import {ExpressionNode, StatementNode} from "../../nodes";
import {CharacterType, IntegerType, NumericType, StructureType} from "../../types/basic";
import {AbstractType} from "../../types/basic/_abstract_type";
import {CurrentScope} from "../_current_scope";
import {SyntaxInput} from "../_syntax_input";
import {DatabaseTableSource} from "./database_table";
import {Dynamic} from "./dynamic";
import {Source} from "./source";
import {SQLIn} from "./sql_in";
import {SQLSource} from "./sql_source";
export class SQLCompare {
public static runSyntax(node: ExpressionNode | StatementNode, input: SyntaxInput, tables: DatabaseTableSource[]): void {
let sourceType: AbstractType | undefined;
let token: AbstractToken | undefined;
if (node.getFirstChild()?.get() instanceof Expressions.Dynamic) {
Dynamic.runSyntax(node.getFirstChild() as ExpressionNode, input);
return;
}
for (const s of node.findDirectExpressions(Expressions.SimpleSource3)) {
Source.runSyntax(s, input);
}
for (const s of node.findDirectExpressions(Expressions.SQLSource)) {
for (const child of s.getChildren()) {
if (child instanceof ExpressionNode) {
token = child.getFirstToken();
break;
}
}
sourceType = SQLSource.runSyntax(s, input);
}
const sqlin = node.findDirectExpression(Expressions.SQLIn);
if (sqlin) {
SQLIn.runSyntax(sqlin, input);
}
const fieldName = node.findDirectExpression(Expressions.SQLFieldName)?.concatTokens().toUpperCase();
if (fieldName && sourceType && token) {
// check compatibility for rule sql_value_conversion
const targetType = this.findType(fieldName, tables, input.scope);
let message = "";
if (sourceType instanceof IntegerType
&& targetType instanceof CharacterType) {
message = `${fieldName}: Integer to CHAR conversion`;
} else if (sourceType instanceof IntegerType
&& targetType instanceof NumericType) {
message = `${fieldName}: Integer to NUMC conversion`;
} else if (sourceType instanceof NumericType
&& targetType instanceof IntegerType) {
message = `${fieldName}: NUMC to Integer conversion`;
} else if (sourceType instanceof CharacterType
&& targetType instanceof IntegerType) {
message = `${fieldName}: CHAR to Integer conversion`;
} else if (sourceType instanceof CharacterType
&& targetType instanceof CharacterType
&& sourceType.getLength() > targetType.getLength()) {
message = `${fieldName}: Source field longer than database field, CHAR -> CHAR`;
} else if (sourceType instanceof NumericType
&& targetType instanceof NumericType
&& sourceType.getLength() > targetType.getLength()) {
message = `${fieldName}: Source field longer than database field, NUMC -> NUMC`;
}
if (message !== "") {
input.scope.addSQLConversion(fieldName, message, token);
}
}
}
private static findType(fieldName: string, tables: DatabaseTableSource[], scope: CurrentScope): AbstractType | undefined {
for (const t of tables) {
const type = t?.parseType(scope.getRegistry());
if (type instanceof StructureType) {
return type.getComponentByName(fieldName);
}
}
return undefined;
}
} |