@hokaccha/sql-formatter
Version:
Format whitespace in a SQL query to make it more readable
283 lines • 5.91 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Formatter_1 = __importDefault(require("../core/Formatter"));
const Tokenizer_1 = __importDefault(require("../core/Tokenizer"));
const token_1 = require("../core/token");
const tokenTypes_1 = require("../core/tokenTypes");
const reservedWords = [
"ALL",
"ALTER",
"ANALYSE",
"ANALYZE",
"ARRAY_ZIP",
"ARRAY",
"AS",
"ASC",
"AVG",
"BETWEEN",
"CASCADE",
"CASE",
"CAST",
"COALESCE",
"COLLECT_LIST",
"COLLECT_SET",
"COLUMN",
"COLUMNS",
"COMMENT",
"CONSTRAINT",
"CONTAINS",
"CONVERT",
"COUNT",
"CUME_DIST",
"CURRENT ROW",
"CURRENT_DATE",
"CURRENT_TIMESTAMP",
"DATABASE",
"DATABASES",
"DATE_ADD",
"DATE_SUB",
"DATE_TRUNC",
"DAY_HOUR",
"DAY_MINUTE",
"DAY_SECOND",
"DAY",
"DAYS",
"DECODE",
"DEFAULT",
"DELETE",
"DENSE_RANK",
"DESC",
"DESCRIBE",
"DISTINCT",
"DISTINCTROW",
"DIV",
"DROP",
"ELSE",
"ENCODE",
"END",
"EXISTS",
"EXPLAIN",
"EXPLODE_OUTER",
"EXPLODE",
"FILTER",
"FIRST_VALUE",
"FIRST",
"FIXED",
"FLATTEN",
"FOLLOWING",
"FROM_UNIXTIME",
"FULL",
"GREATEST",
"GROUP_CONCAT",
"HOUR_MINUTE",
"HOUR_SECOND",
"HOUR",
"HOURS",
"IF",
"IFNULL",
"IN",
"INSERT",
"INTERVAL",
"INTO",
"IS",
"LAG",
"LAST_VALUE",
"LAST",
"LEAD",
"LEADING",
"LEAST",
"LEVEL",
"LIKE",
"MAX",
"MERGE",
"MIN",
"MINUTE_SECOND",
"MINUTE",
"MONTH",
"NATURAL",
"NOT",
"NOW()",
"NTILE",
"NULL",
"NULLIF",
"OFFSET",
"ON DELETE",
"ON UPDATE",
"ON",
"ONLY",
"OPTIMIZE",
"OVER",
"PERCENT_RANK",
"PRECEDING",
"RANGE",
"RANK",
"REGEXP",
"RENAME",
"RLIKE",
"ROW",
"ROWS",
"SECOND",
"SEPARATOR",
"SEQUENCE",
"SIZE",
"STRING",
"STRUCT",
"SUM",
"TABLE",
"TABLES",
"TEMPORARY",
"THEN",
"TO_DATE",
"TO_JSON",
"TO",
"TRAILING",
"TRANSFORM",
"TRUE",
"TRUNCATE",
"TYPE",
"TYPES",
"UNBOUNDED",
"UNIQUE",
"UNIX_TIMESTAMP",
"UNLOCK",
"UNSIGNED",
"USING",
"VARIABLES",
"VIEW",
"WHEN",
"WITH",
"YEAR_MONTH",
];
const reservedTopLevelWords = [
"ADD",
"AFTER",
"ALTER COLUMN",
"ALTER DATABASE",
"ALTER SCHEMA",
"ALTER TABLE",
"CLUSTER BY",
"CLUSTERED BY",
"DELETE FROM",
"DISTRIBUTE BY",
"FROM",
"GROUP BY",
"HAVING",
"INSERT INTO",
"INSERT",
"LIMIT",
"OPTIONS",
"ORDER BY",
"PARTITION BY",
"PARTITIONED BY",
"RANGE",
"ROWS",
"SELECT",
"SELECT DISTINCT",
"SET CURRENT SCHEMA",
"SET SCHEMA",
"SET",
"TBLPROPERTIES",
"UPDATE",
"USING",
"VALUES",
"WHERE",
"WINDOW",
];
const reservedTopLevelWordsNoIndent = [
"EXCEPT ALL",
"EXCEPT",
"INTERSECT ALL",
"INTERSECT",
"UNION ALL",
"UNION",
];
const reservedNewlineWords = [
"AND",
"CREATE OR",
"CREATE",
"ELSE",
"LATERAL VIEW",
"OR",
"OUTER APPLY",
"WHEN",
"XOR",
// joins
"JOIN",
"INNER JOIN",
"LEFT JOIN",
"LEFT OUTER JOIN",
"RIGHT JOIN",
"RIGHT OUTER JOIN",
"FULL JOIN",
"FULL OUTER JOIN",
"CROSS JOIN",
"NATURAL JOIN",
// non-standard-joins
"ANTI JOIN",
"SEMI JOIN",
"LEFT ANTI JOIN",
"LEFT SEMI JOIN",
"RIGHT OUTER JOIN",
"RIGHT SEMI JOIN",
"NATURAL ANTI JOIN",
"NATURAL FULL OUTER JOIN",
"NATURAL INNER JOIN",
"NATURAL LEFT ANTI JOIN",
"NATURAL LEFT OUTER JOIN",
"NATURAL LEFT SEMI JOIN",
"NATURAL OUTER JOIN",
"NATURAL RIGHT OUTER JOIN",
"NATURAL RIGHT SEMI JOIN",
"NATURAL SEMI JOIN",
];
class SparkSqlFormatter extends Formatter_1.default {
tokenizer() {
return new Tokenizer_1.default({
reservedWords,
reservedTopLevelWords,
reservedNewlineWords,
reservedTopLevelWordsNoIndent,
stringTypes: [`""`, "''", "``", "{}"],
openParens: ["(", "CASE"],
closeParens: [")", "END"],
indexedPlaceholderTypes: ["?"],
namedPlaceholderTypes: ["$"],
lineCommentTypes: ["--"],
operators: ["!=", "<=>", "&&", "||", "=="],
});
}
tokenOverride(token) {
// Fix cases where names are ambiguously keywords or functions
if ((0, token_1.isWindow)(token)) {
const aheadToken = this.tokenLookAhead();
if (aheadToken && aheadToken.type === tokenTypes_1.tokenTypes.OPEN_PAREN) {
// This is a function call, treat it as a reserved word
return {
type: tokenTypes_1.tokenTypes.RESERVED,
value: token.value,
whitespaceBefore: "",
};
}
}
// Fix cases where names are ambiguously keywords or properties
if ((0, token_1.isEnd)(token)) {
const backToken = this.tokenLookBehind();
if (backToken &&
backToken.type === tokenTypes_1.tokenTypes.OPERATOR &&
backToken.value === ".") {
// This is window().end (or similar) not CASE ... END
return {
type: tokenTypes_1.tokenTypes.WORD,
value: token.value,
whitespaceBefore: "",
};
}
}
return token;
}
}
exports.default = SparkSqlFormatter;
//# sourceMappingURL=SparkSqlFormatter.js.map