rawsql-ts
Version:
[beta]High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.
54 lines • 2.02 kB
JavaScript
import { BaseTokenReader } from './BaseTokenReader';
import { TokenType } from '../models/Lexeme';
/**
* Reads SQL identifier tokens
*/
export class EscapedIdentifierTokenReader extends BaseTokenReader {
/**
* Try to read an identifier token
*/
tryRead(previous) {
if (this.isEndOfInput()) {
return null;
}
const char = this.input[this.position];
// MySQL escaped identifier (escape character is backtick)
if (char === '`') {
const identifier = this.readEscapedIdentifier('`');
return this.createLexeme(TokenType.Identifier, identifier);
}
// Postgres escaped identifier (escape character is double quote)
if (char === '"') {
const identifier = this.readEscapedIdentifier('"');
return this.createLexeme(TokenType.Identifier, identifier);
}
// SQLServer escaped identifier (escape character is square bracket)
if (char === '[' && (previous === null || previous.value !== "array")) {
const identifier = this.readEscapedIdentifier(']');
return this.createLexeme(TokenType.Identifier, identifier);
}
return null;
}
/**
* Read an escaped identifier (surrounded by delimiters)
*/
readEscapedIdentifier(delimiter) {
const start = this.position;
// Skip the opening delimiter
this.position++;
while (this.canRead()) {
if (this.input[this.position] === delimiter) {
break;
}
this.position++;
}
if (start === this.position) {
throw new Error(`Closing delimiter is not found. position: ${start}, delimiter: ${delimiter}\n${this.getDebugPositionInfo(start)}`);
}
// Skip the closing delimiter
this.position++;
// exclude the delimiter
return this.input.slice(start + 1, this.position - 1);
}
}
//# sourceMappingURL=EscapedIdentifierTokenReader.js.map