rawsql-ts
Version:
High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.
141 lines • 5.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SelectBodyExtractor = void 0;
const CreateTableQuery_1 = require("../models/CreateTableQuery");
const InsertQuery_1 = require("../models/InsertQuery");
const Lexeme_1 = require("../models/Lexeme");
const ValuesQuery_1 = require("../models/ValuesQuery");
const Clause_1 = require("../models/Clause");
const FullNameParser_1 = require("../parsers/FullNameParser");
const SelectQueryParser_1 = require("../parsers/SelectQueryParser");
const SqlParser_1 = require("../parsers/SqlParser");
const SqlTokenizer_1 = require("../parsers/SqlTokenizer");
class SelectBodyExtractor {
static extract(input) {
if (typeof input === "string") {
return this.extractFromSql(input);
}
return this.extractFromStatement(input);
}
static extractFromSql(sql) {
const lexemes = new SqlTokenizer_1.SqlTokenizer(sql).readLexemes();
if (this.isCreateViewStatement(lexemes)) {
return this.extractCreateViewFromLexemes(lexemes);
}
return this.extractFromStatement(SqlParser_1.SqlParser.parse(sql));
}
static extractFromStatement(statement) {
if (statement instanceof CreateTableQuery_1.CreateTableQuery) {
const targetName = this.createTableTargetName(statement);
if (!statement.asSelectQuery) {
return this.unsupported(targetName);
}
return {
supported: true,
kind: "create-table-as",
targetName,
selectQuery: statement.asSelectQuery
};
}
if (statement instanceof InsertQuery_1.InsertQuery) {
const targetName = this.insertTargetName(statement);
if (!statement.selectQuery || statement.selectQuery instanceof ValuesQuery_1.ValuesQuery) {
return this.unsupported(targetName);
}
return {
supported: true,
kind: "insert-select",
targetName,
selectQuery: statement.selectQuery
};
}
return {
supported: false,
kind: null,
targetName: null,
selectQuery: null,
reason: "Statement type is not supported."
};
}
static extractCreateViewFromLexemes(lexemes) {
var _a, _b, _c, _d, _e, _f;
let idx = 0;
idx++; // CREATE
const materialized = ((_a = lexemes[idx]) === null || _a === void 0 ? void 0 : _a.value.toLowerCase()) === "materialized";
if (materialized) {
idx++;
}
if (((_b = lexemes[idx]) === null || _b === void 0 ? void 0 : _b.value.toLowerCase()) !== "view") {
return this.unsupported(null, "Statement type is not supported.");
}
idx++;
if (((_c = lexemes[idx]) === null || _c === void 0 ? void 0 : _c.value.toLowerCase()) === "if not exists") {
idx++;
}
const targetResult = FullNameParser_1.FullNameParser.parseFromLexeme(lexemes, idx);
idx = targetResult.newIndex;
const targetName = [...((_d = targetResult.namespaces) !== null && _d !== void 0 ? _d : []), targetResult.name.name].join(".");
if (((_e = lexemes[idx]) === null || _e === void 0 ? void 0 : _e.type) === Lexeme_1.TokenType.OpenParen) {
idx = this.consumeBalancedParentheses(lexemes, idx);
}
if (((_f = lexemes[idx]) === null || _f === void 0 ? void 0 : _f.value.toLowerCase()) !== "as") {
return this.unsupported(targetName);
}
idx++;
const selectResult = SelectQueryParser_1.SelectQueryParser.parseFromLexeme(lexemes, idx);
return {
supported: true,
kind: materialized ? "create-materialized-view" : "create-view",
targetName,
selectQuery: selectResult.value
};
}
static isCreateViewStatement(lexemes) {
var _a, _b, _c;
if (((_a = lexemes[0]) === null || _a === void 0 ? void 0 : _a.value.toLowerCase()) !== "create") {
return false;
}
const second = (_b = lexemes[1]) === null || _b === void 0 ? void 0 : _b.value.toLowerCase();
const third = (_c = lexemes[2]) === null || _c === void 0 ? void 0 : _c.value.toLowerCase();
return second === "view" || (second === "materialized" && third === "view");
}
static consumeBalancedParentheses(lexemes, index) {
let idx = index;
let depth = 0;
while (idx < lexemes.length) {
if (lexemes[idx].type === Lexeme_1.TokenType.OpenParen) {
depth++;
}
else if (lexemes[idx].type === Lexeme_1.TokenType.CloseParen) {
depth--;
if (depth === 0) {
return idx + 1;
}
}
idx++;
}
return idx;
}
static createTableTargetName(query) {
var _a;
return [...((_a = query.namespaces) !== null && _a !== void 0 ? _a : []), query.tableName.name].join(".");
}
static insertTargetName(query) {
const source = query.insertClause.source;
if (source.datasource instanceof Clause_1.TableSource) {
return source.datasource.getSourceName();
}
return source.getAliasName();
}
static unsupported(targetName, reason = "No embedded SELECT body found.") {
return {
supported: false,
kind: null,
targetName,
selectQuery: null,
reason
};
}
}
exports.SelectBodyExtractor = SelectBodyExtractor;
//# sourceMappingURL=SelectBodyExtractor.js.map