rawsql-ts
Version:
[beta]High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.
87 lines • 3.88 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.InsertQueryParser = void 0;
// filepath: src/parsers/InsertQueryParser.ts
// Provides parsing for INSERT queries, supporting optional columns and WITH/SELECT/VALUES structure.
const InsertQuery_1 = require("../models/InsertQuery");
const Lexeme_1 = require("../models/Lexeme");
const SqlTokenizer_1 = require("./SqlTokenizer");
const SelectQueryParser_1 = require("./SelectQueryParser");
const WithClauseParser_1 = require("./WithClauseParser");
const SimpleSelectQuery_1 = require("../models/SimpleSelectQuery");
const SourceExpressionParser_1 = require("./SourceExpressionParser");
const Clause_1 = require("../models/Clause");
class InsertQueryParser {
/**
* Parse SQL string to InsertQuery AST.
* @param query SQL string
*/
static parse(query) {
const tokenizer = new SqlTokenizer_1.SqlTokenizer(query);
const lexemes = tokenizer.readLexmes();
const result = this.parseFromLexeme(lexemes, 0);
if (result.newIndex < lexemes.length) {
throw new Error(`Syntax error: Unexpected token "${lexemes[result.newIndex].value}" at position ${result.newIndex}. The INSERT query is complete but there are additional tokens.`);
}
return result.value;
}
/**
* Parse from lexeme array (for internal use and tests)
*/
static parseFromLexeme(lexemes, index) {
var _a, _b, _c;
let idx = index;
let withclause = null;
if (lexemes[idx].value === "with") {
const result = WithClauseParser_1.WithClauseParser.parseFromLexeme(lexemes, idx);
withclause = result.value;
idx = result.newIndex;
}
// Expect INSERT INTO
if (lexemes[idx].value !== "insert into") {
throw new Error(`Syntax error at position ${idx}: Expected 'INSERT INTO' but found '${lexemes[idx].value}'.`);
}
idx++;
// Parse table and optional alias/schema using SourceExpressionParser
const sourceResult = SourceExpressionParser_1.SourceExpressionParser.parseTableSourceFromLexemes(lexemes, idx);
idx = sourceResult.newIndex;
// Optional columns
let columns = [];
if (((_a = lexemes[idx]) === null || _a === void 0 ? void 0 : _a.type) === Lexeme_1.TokenType.OpenParen) {
idx++;
while (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.Identifier) {
columns.push(lexemes[idx].value);
idx++;
if (((_b = lexemes[idx]) === null || _b === void 0 ? void 0 : _b.type) === Lexeme_1.TokenType.Comma) {
idx++;
}
else {
break;
}
}
if (((_c = lexemes[idx]) === null || _c === void 0 ? void 0 : _c.type) !== Lexeme_1.TokenType.CloseParen) {
throw new Error(`Syntax error at position ${idx}: Expected ')' after column list.`);
}
idx++;
}
const selectResult = SelectQueryParser_1.SelectQueryParser.parseFromLexeme(lexemes, idx);
if (withclause) {
if (selectResult.value instanceof SimpleSelectQuery_1.SimpleSelectQuery) {
selectResult.value.withClause = withclause;
}
else {
throw new Error(`WITH clause is not supported in this context.`);
}
}
idx = selectResult.newIndex;
return {
value: new InsertQuery_1.InsertQuery({
insertClause: new Clause_1.InsertClause(sourceResult.value, columns),
selectQuery: selectResult.value
}),
newIndex: idx
};
}
}
exports.InsertQueryParser = InsertQueryParser;
//# sourceMappingURL=InsertQueryParser.js.map
;