snowflake-sql-validator
Version:
Snowflake SQL validator for React applications
78 lines • 4.06 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.SnowflakeValidationVisitor = void 0;
// Placeholder imports for generated ANTLR4 files
const SnowflakeVisitor_1 = require("./parser/snowflake/SnowflakeVisitor");
class SnowflakeValidationVisitor extends SnowflakeVisitor_1.SnowflakeVisitor {
constructor() {
super();
this.errors = [];
this.errors = [];
}
// Override the visit method to start the traversal
visit(tree) {
this.errors = [];
if (tree) {
super.visit(tree);
}
return this.errors;
}
// Example: Validate JSON path access (e.g., MEMBER:guid::string)
// This would require identifying specific rule contexts related to expressions or identifiers
// For demonstration, let's assume a rule context `jsonAccessExpression` exists.
// In a real grammar, you'd target specific rule contexts for identifiers or expressions.
visitTerminal(node) {
// This is a very simplistic check. In a real scenario, you would analyze the context of the terminal node.
const text = node.text;
// Check for mixed-case SQL keywords (e.g., sElEcT, fRoM)
const sqlKeywords = [
'SELECT', 'FROM', 'WHERE', 'INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'ALTER',
'AS', 'AND', 'OR', 'INTO', 'VALUES', 'SET', 'JOIN', 'LEFT', 'RIGHT', 'INNER', 'OUTER',
'ON', 'GROUP', 'BY', 'ORDER', 'HAVING', 'LIMIT', 'OFFSET', 'UNION', 'ALL', 'DISTINCT',
'COUNT', 'SUM', 'AVG', 'CASE', 'WHEN', 'THEN', 'ELSE', 'END', 'IS', 'NULL', 'NOT',
'LIKE', 'IN', 'BETWEEN', 'EXISTS', 'CAST', 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP',
'TRUE', 'FALSE'
];
const upperText = text.toUpperCase();
const isKeyword = sqlKeywords.includes(upperText);
if (isKeyword) {
const isLowerCase = text === text.toLowerCase();
const isUpperCase = text === text.toUpperCase();
if (!isLowerCase && !isUpperCase) {
// Mixed case keyword detected
const symbol = node.symbol;
this.errors.push({
startLine: symbol.line,
endLine: symbol.line,
startColumn: symbol.charPositionInLine,
endColumn: symbol.charPositionInLine + text.length - 1,
message: `Mixed case SQL keyword not allowed: '${text}'. Use either lowercase (${text.toLowerCase()}) or uppercase (${text.toUpperCase()}).`,
severity: 'error',
suggestions: [
`Use '${text.toLowerCase()}' for lowercase`,
`Use '${text.toUpperCase()}' for uppercase`
]
});
}
}
// Example: Check for `::string` or `::variant` like casts after an identifier, typical in Snowflake JSON access
if (/(?<!::)\b\w+::(string|variant|int|float|boolean)\b/i.test(text)) {
// This is a basic regex. A proper check would involve checking the parse tree structure.
// For instance, checking if it's an identifier followed by a double colon and a type.
// For now, let's just flag it if it matches the pattern.
const symbol = node.symbol;
this.errors.push({
startLine: symbol.line,
endLine: symbol.line,
startColumn: symbol.charPositionInLine,
endColumn: symbol.charPositionInLine,
message: `Potentially invalid or unrecognized cast syntax: '${text}'. Ensure correct Snowflake JSON path access (e.g., OBJECT:field::TYPE).`,
severity: 'warning',
suggestions: ['Review the JSON path syntax for this identifier.']
});
}
return super.visitTerminal(node);
}
}
exports.SnowflakeValidationVisitor = SnowflakeValidationVisitor;
//# sourceMappingURL=SnowflakeValidationVisitor.js.map
;