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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5555x 5555x 8735x 3172x 3172x 8735x 70x 66x 66x 4x 4x 8735x 2x 2x 8735x 423x 423x 8735x 199x 199x 8735x 5290x 5290x 1x 45x 45x 187x 121x 121x 187x 187x 7x 7x 187x 38x 38x 1x 30937x 30937x 54079x 54079x 29604x 54079x 54079x 170262x 170262x 29575x 29575x 30936x 1x 1762x 1762x 1762x 1762x 1762x 447x 447x 1315x 1315x 1315x 1315x 1315x 1315x 1315x 1315x 1315x 1315x 1762x 1762x 487x 1762x 1762x 1762x 1762x 417x 417x 417x 1x 47x 47x 47x 47x 47x 47x 47x 47x 47x 47x 4x 4x 4x 1x 31621x 31621x 31621x 31621x 31621x 31621x 31621x 1762x 1762x 1762x 1312x 1312x 31621x 47x 47x 47x 42x 42x 47x 30267x 30267x | import * as Statements from "./statements";
import * as Expressions from "./expressions";
import {StatementNode} from "../nodes";
import {TokenNode} from "../nodes";
import {AbstractToken} from "../1_lexer/tokens/abstract_token";
import {ExpressionNode} from "../nodes/expression_node";
import {IStatement} from "./statements/_statement";
import {Expression} from "./combi";
type TopChildren = readonly (ExpressionNode | TokenNode)[];
type ExpressionConstructor = new () => Expression;
function containsAggregation(children: TopChildren): boolean {
for (const child of children) {
if (!(child instanceof ExpressionNode)) {
continue;
}
if (child.get() instanceof Expressions.SQLAggregation) {
if (child.findDirectExpression(Expressions.SQLOver) === undefined) {
return true;
}
continue;
}
if (child.get() instanceof Expressions.SQLSetOpGroup) {
continue;
}
if (child.get() instanceof Expressions.SQLFrom) {
continue;
}
if (containsAggregation(child.getChildren())) {
return true;
}
}
return false;
}
function isCountAllPattern(children: TopChildren): boolean {
for (const child of children) {
if (!(child instanceof ExpressionNode)) { continue; }
const e = child.get();
if (e instanceof Expressions.SQLGroupBy ||
e instanceof Expressions.SQLHaving ||
e instanceof Expressions.SQLOrderBy) {
return false;
}
}
return containsAggregation(children);
}
function scanForExprTypes(children: TopChildren, found: Set<ExpressionConstructor>, targets: readonly ExpressionConstructor[]): void {
for (const child of children) {
if (found.size === targets.length) { return; }
if (!(child instanceof ExpressionNode)) { continue; }
const e = child.get();
if (e instanceof Expressions.SQLSetOpGroup) { continue; }
for (const t of targets) {
if (e instanceof t) { found.add(t); break; }
}
scanForExprTypes(child.getChildren(), found, targets);
}
}
function isSelectLoop(node: StatementNode): boolean {
const selectExpr = node.findDirectExpression(Expressions.Select);
const top = selectExpr ? selectExpr.getChildren() : [];
if (top.some(c => c instanceof TokenNode && c.get().getStr().toUpperCase() === "SINGLE")) {
return false;
}
const targets = [
Expressions.SQLSetOp, Expressions.SQLPackageSize, Expressions.SQLIntoTable,
Expressions.SQLIntoStructure, Expressions.SQLIntoList, Expressions.SQLGroupBy,
] as const;
const found = new Set<ExpressionConstructor>();
scanForExprTypes(top, found, targets);
const has = (t: ExpressionConstructor) => found.has(t);
if (has(Expressions.SQLPackageSize)) { return true; }
if (has(Expressions.SQLIntoTable)) { return false; }
const hasInto = has(Expressions.SQLIntoTable) || has(Expressions.SQLIntoStructure) || has(Expressions.SQLIntoList);
if (!hasInto && isCountAllPattern(top)) { return false; }
if (has(Expressions.SQLSetOp)) { return true; }
if (!has(Expressions.SQLGroupBy) && containsAggregation(top)) { return false; }
return true;
}
function isWithLoop(node: StatementNode): boolean {
const selectExpr = node.findDirectExpression(Expressions.Select);
if (!selectExpr) { return true; }
const targets = [Expressions.SQLPackageSize, Expressions.SQLIntoTable] as const;
const found = new Set<ExpressionConstructor>();
scanForExprTypes(selectExpr.getChildren(), found, targets);
if (found.has(Expressions.SQLPackageSize)) { return true; }
if (found.has(Expressions.SQLIntoTable)) { return false; }
return true;
}
export function reclassifySelect(
node: StatementNode,
stmt: IStatement,
pragmas: readonly AbstractToken[],
): StatementNode {
const children = [...node.getChildren()];
if (stmt instanceof Statements.Select || stmt instanceof Statements.SelectLoop) {
const loop = isSelectLoop(node);
if (loop && stmt instanceof Statements.Select) {
return new StatementNode(new Statements.SelectLoop(), node.getColon(), pragmas).setChildren(children);
} else if (!loop && stmt instanceof Statements.SelectLoop) {
return new StatementNode(new Statements.Select(), node.getColon(), pragmas).setChildren(children);
}
} else if (stmt instanceof Statements.With || stmt instanceof Statements.WithLoop) {
const loop = isWithLoop(node);
if (loop && stmt instanceof Statements.With) {
return new StatementNode(new Statements.WithLoop(), node.getColon(), pragmas).setChildren(children);
} else if (!loop && stmt instanceof Statements.WithLoop) {
return new StatementNode(new Statements.With(), node.getColon(), pragmas).setChildren(children);
}
}
return node;
}
|