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 111x 111x 111x 111x 111x 3x 3x 3x 108x 111x 108x 111x 100x 123x 100x 100x 100x 123x 100x 100x 100x 108x 108x 111x 8x 8x 108x 111x 111x 87x 87x 87x 87x 87x 87x 1x 87x 86x 86x 86x 86x 86x 1x 86x 85x 85x 2x 85x 83x 83x 87x 4x 4x 87x 111x 1x 1x 87x 90x 90x 11x 11x 90x 76x 76x 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;
}
} |