codigo0/node_modules/highlight.js/lib/languages/sql.js
planetazuzu 5d7a6500fe refactor: Fase 1 - Clean Architecture, refactorización modular y eliminación de duplicidades
-  Ticket 1.1: Estructura Clean Architecture en backend
-  Ticket 1.2: Schemas Zod compartidos
-  Ticket 1.3: Refactorización drugs.ts (1362 → 8 archivos modulares)
-  Ticket 1.4: Refactorización procedures.ts (3583 → 6 archivos modulares)
-  Ticket 1.5: Eliminación de duplicidades (~50 líneas)

Cambios principales:
- Creada estructura Clean Architecture en backend/src/
- Schemas Zod compartidos en backend/src/shared/schemas/
- Refactorización modular de drugs y procedures
- Utilidades genéricas en src/utils/ (filter, validation)
- Eliminados scripts obsoletos y documentación antigua
- Corregidos errores: QueryClient, import test-error-handling
- Build verificado y funcionando correctamente
2026-01-25 21:09:47 +01:00

694 lines
12 KiB
JavaScript

/*
Language: SQL
Website: https://en.wikipedia.org/wiki/SQL
Category: common, database
*/
/*
Goals:
SQL is intended to highlight basic/common SQL keywords and expressions
- If pretty much every single SQL server includes supports, then it's a canidate.
- It is NOT intended to include tons of vendor specific keywords (Oracle, MySQL,
PostgreSQL) although the list of data types is purposely a bit more expansive.
- For more specific SQL grammars please see:
- PostgreSQL and PL/pgSQL - core
- T-SQL - https://github.com/highlightjs/highlightjs-tsql
- sql_more (core)
*/
function sql(hljs) {
const regex = hljs.regex;
const COMMENT_MODE = hljs.COMMENT('--', '$');
const STRING = {
scope: 'string',
variants: [
{
begin: /'/,
end: /'/,
contains: [ { match: /''/ } ]
}
]
};
const QUOTED_IDENTIFIER = {
begin: /"/,
end: /"/,
contains: [ { match: /""/ } ]
};
const LITERALS = [
"true",
"false",
// Not sure it's correct to call NULL literal, and clauses like IS [NOT] NULL look strange that way.
// "null",
"unknown"
];
const MULTI_WORD_TYPES = [
"double precision",
"large object",
"with timezone",
"without timezone"
];
const TYPES = [
'bigint',
'binary',
'blob',
'boolean',
'char',
'character',
'clob',
'date',
'dec',
'decfloat',
'decimal',
'float',
'int',
'integer',
'interval',
'nchar',
'nclob',
'national',
'numeric',
'real',
'row',
'smallint',
'time',
'timestamp',
'varchar',
'varying', // modifier (character varying)
'varbinary'
];
const NON_RESERVED_WORDS = [
"add",
"asc",
"collation",
"desc",
"final",
"first",
"last",
"view"
];
// https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#reserved-word
const RESERVED_WORDS = [
"abs",
"acos",
"all",
"allocate",
"alter",
"and",
"any",
"are",
"array",
"array_agg",
"array_max_cardinality",
"as",
"asensitive",
"asin",
"asymmetric",
"at",
"atan",
"atomic",
"authorization",
"avg",
"begin",
"begin_frame",
"begin_partition",
"between",
"bigint",
"binary",
"blob",
"boolean",
"both",
"by",
"call",
"called",
"cardinality",
"cascaded",
"case",
"cast",
"ceil",
"ceiling",
"char",
"char_length",
"character",
"character_length",
"check",
"classifier",
"clob",
"close",
"coalesce",
"collate",
"collect",
"column",
"commit",
"condition",
"connect",
"constraint",
"contains",
"convert",
"copy",
"corr",
"corresponding",
"cos",
"cosh",
"count",
"covar_pop",
"covar_samp",
"create",
"cross",
"cube",
"cume_dist",
"current",
"current_catalog",
"current_date",
"current_default_transform_group",
"current_path",
"current_role",
"current_row",
"current_schema",
"current_time",
"current_timestamp",
"current_path",
"current_role",
"current_transform_group_for_type",
"current_user",
"cursor",
"cycle",
"date",
"day",
"deallocate",
"dec",
"decimal",
"decfloat",
"declare",
"default",
"define",
"delete",
"dense_rank",
"deref",
"describe",
"deterministic",
"disconnect",
"distinct",
"double",
"drop",
"dynamic",
"each",
"element",
"else",
"empty",
"end",
"end_frame",
"end_partition",
"end-exec",
"equals",
"escape",
"every",
"except",
"exec",
"execute",
"exists",
"exp",
"external",
"extract",
"false",
"fetch",
"filter",
"first_value",
"float",
"floor",
"for",
"foreign",
"frame_row",
"free",
"from",
"full",
"function",
"fusion",
"get",
"global",
"grant",
"group",
"grouping",
"groups",
"having",
"hold",
"hour",
"identity",
"in",
"indicator",
"initial",
"inner",
"inout",
"insensitive",
"insert",
"int",
"integer",
"intersect",
"intersection",
"interval",
"into",
"is",
"join",
"json_array",
"json_arrayagg",
"json_exists",
"json_object",
"json_objectagg",
"json_query",
"json_table",
"json_table_primitive",
"json_value",
"lag",
"language",
"large",
"last_value",
"lateral",
"lead",
"leading",
"left",
"like",
"like_regex",
"listagg",
"ln",
"local",
"localtime",
"localtimestamp",
"log",
"log10",
"lower",
"match",
"match_number",
"match_recognize",
"matches",
"max",
"member",
"merge",
"method",
"min",
"minute",
"mod",
"modifies",
"module",
"month",
"multiset",
"national",
"natural",
"nchar",
"nclob",
"new",
"no",
"none",
"normalize",
"not",
"nth_value",
"ntile",
"null",
"nullif",
"numeric",
"octet_length",
"occurrences_regex",
"of",
"offset",
"old",
"omit",
"on",
"one",
"only",
"open",
"or",
"order",
"out",
"outer",
"over",
"overlaps",
"overlay",
"parameter",
"partition",
"pattern",
"per",
"percent",
"percent_rank",
"percentile_cont",
"percentile_disc",
"period",
"portion",
"position",
"position_regex",
"power",
"precedes",
"precision",
"prepare",
"primary",
"procedure",
"ptf",
"range",
"rank",
"reads",
"real",
"recursive",
"ref",
"references",
"referencing",
"regr_avgx",
"regr_avgy",
"regr_count",
"regr_intercept",
"regr_r2",
"regr_slope",
"regr_sxx",
"regr_sxy",
"regr_syy",
"release",
"result",
"return",
"returns",
"revoke",
"right",
"rollback",
"rollup",
"row",
"row_number",
"rows",
"running",
"savepoint",
"scope",
"scroll",
"search",
"second",
"seek",
"select",
"sensitive",
"session_user",
"set",
"show",
"similar",
"sin",
"sinh",
"skip",
"smallint",
"some",
"specific",
"specifictype",
"sql",
"sqlexception",
"sqlstate",
"sqlwarning",
"sqrt",
"start",
"static",
"stddev_pop",
"stddev_samp",
"submultiset",
"subset",
"substring",
"substring_regex",
"succeeds",
"sum",
"symmetric",
"system",
"system_time",
"system_user",
"table",
"tablesample",
"tan",
"tanh",
"then",
"time",
"timestamp",
"timezone_hour",
"timezone_minute",
"to",
"trailing",
"translate",
"translate_regex",
"translation",
"treat",
"trigger",
"trim",
"trim_array",
"true",
"truncate",
"uescape",
"union",
"unique",
"unknown",
"unnest",
"update",
"upper",
"user",
"using",
"value",
"values",
"value_of",
"var_pop",
"var_samp",
"varbinary",
"varchar",
"varying",
"versioning",
"when",
"whenever",
"where",
"width_bucket",
"window",
"with",
"within",
"without",
"year",
];
// these are reserved words we have identified to be functions
// and should only be highlighted in a dispatch-like context
// ie, array_agg(...), etc.
const RESERVED_FUNCTIONS = [
"abs",
"acos",
"array_agg",
"asin",
"atan",
"avg",
"cast",
"ceil",
"ceiling",
"coalesce",
"corr",
"cos",
"cosh",
"count",
"covar_pop",
"covar_samp",
"cume_dist",
"dense_rank",
"deref",
"element",
"exp",
"extract",
"first_value",
"floor",
"json_array",
"json_arrayagg",
"json_exists",
"json_object",
"json_objectagg",
"json_query",
"json_table",
"json_table_primitive",
"json_value",
"lag",
"last_value",
"lead",
"listagg",
"ln",
"log",
"log10",
"lower",
"max",
"min",
"mod",
"nth_value",
"ntile",
"nullif",
"percent_rank",
"percentile_cont",
"percentile_disc",
"position",
"position_regex",
"power",
"rank",
"regr_avgx",
"regr_avgy",
"regr_count",
"regr_intercept",
"regr_r2",
"regr_slope",
"regr_sxx",
"regr_sxy",
"regr_syy",
"row_number",
"sin",
"sinh",
"sqrt",
"stddev_pop",
"stddev_samp",
"substring",
"substring_regex",
"sum",
"tan",
"tanh",
"translate",
"translate_regex",
"treat",
"trim",
"trim_array",
"unnest",
"upper",
"value_of",
"var_pop",
"var_samp",
"width_bucket",
];
// these functions can
const POSSIBLE_WITHOUT_PARENS = [
"current_catalog",
"current_date",
"current_default_transform_group",
"current_path",
"current_role",
"current_schema",
"current_transform_group_for_type",
"current_user",
"session_user",
"system_time",
"system_user",
"current_time",
"localtime",
"current_timestamp",
"localtimestamp"
];
// those exist to boost relevance making these very
// "SQL like" keyword combos worth +1 extra relevance
const COMBOS = [
"create table",
"insert into",
"primary key",
"foreign key",
"not null",
"alter table",
"add constraint",
"grouping sets",
"on overflow",
"character set",
"respect nulls",
"ignore nulls",
"nulls first",
"nulls last",
"depth first",
"breadth first"
];
const FUNCTIONS = RESERVED_FUNCTIONS;
const KEYWORDS = [
...RESERVED_WORDS,
...NON_RESERVED_WORDS
].filter((keyword) => {
return !RESERVED_FUNCTIONS.includes(keyword);
});
const VARIABLE = {
scope: "variable",
match: /@[a-z0-9][a-z0-9_]*/,
};
const OPERATOR = {
scope: "operator",
match: /[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,
relevance: 0,
};
const FUNCTION_CALL = {
match: regex.concat(/\b/, regex.either(...FUNCTIONS), /\s*\(/),
relevance: 0,
keywords: { built_in: FUNCTIONS }
};
// turns a multi-word keyword combo into a regex that doesn't
// care about extra whitespace etc.
// input: "START QUERY"
// output: /\bSTART\s+QUERY\b/
function kws_to_regex(list) {
return regex.concat(
/\b/,
regex.either(...list.map((kw) => {
return kw.replace(/\s+/, "\\s+")
})),
/\b/
)
}
const MULTI_WORD_KEYWORDS = {
scope: "keyword",
match: kws_to_regex(COMBOS),
relevance: 0,
};
// keywords with less than 3 letters are reduced in relevancy
function reduceRelevancy(list, {
exceptions, when
} = {}) {
const qualifyFn = when;
exceptions = exceptions || [];
return list.map((item) => {
if (item.match(/\|\d+$/) || exceptions.includes(item)) {
return item;
} else if (qualifyFn(item)) {
return `${item}|0`;
} else {
return item;
}
});
}
return {
name: 'SQL',
case_insensitive: true,
// does not include {} or HTML tags `</`
illegal: /[{}]|<\//,
keywords: {
$pattern: /\b[\w\.]+/,
keyword:
reduceRelevancy(KEYWORDS, { when: (x) => x.length < 3 }),
literal: LITERALS,
type: TYPES,
built_in: POSSIBLE_WITHOUT_PARENS
},
contains: [
{
scope: "type",
match: kws_to_regex(MULTI_WORD_TYPES)
},
MULTI_WORD_KEYWORDS,
FUNCTION_CALL,
VARIABLE,
STRING,
QUOTED_IDENTIFIER,
hljs.C_NUMBER_MODE,
hljs.C_BLOCK_COMMENT_MODE,
COMMENT_MODE,
OPERATOR
]
};
}
module.exports = sql;