UNPKG

11.8 kBJavaScriptView Raw
1/*
2 Language: SQL
3 Website: https://en.wikipedia.org/wiki/SQL
4 Category: common, database
5 */
6
7/*
8
9Goals:
10
11SQL is intended to highlight basic/common SQL keywords and expressions
12
13- If pretty much every single SQL server includes supports, then it's a canidate.
14- It is NOT intended to include tons of vendor specific keywords (Oracle, MySQL,
15 PostgreSQL) although the list of data types is purposely a bit more expansive.
16- For more specific SQL grammars please see:
17 - PostgreSQL and PL/pgSQL - core
18 - T-SQL - https://github.com/highlightjs/highlightjs-tsql
19 - sql_more (core)
20
21 */
22
23function sql(hljs) {
24 const regex = hljs.regex;
25 const COMMENT_MODE = hljs.COMMENT('--', '$');
26 const STRING = {
27 className: 'string',
28 variants: [
29 {
30 begin: /'/,
31 end: /'/,
32 contains: [
33 {begin: /''/ }
34 ]
35 }
36 ]
37 };
38 const QUOTED_IDENTIFIER = {
39 begin: /"/,
40 end: /"/,
41 contains: [ { begin: /""/ } ]
42 };
43
44 const LITERALS = [
45 "true",
46 "false",
47 // Not sure it's correct to call NULL literal, and clauses like IS [NOT] NULL look strange that way.
48 // "null",
49 "unknown"
50 ];
51
52 const MULTI_WORD_TYPES = [
53 "double precision",
54 "large object",
55 "with timezone",
56 "without timezone"
57 ];
58
59 const TYPES = [
60 'bigint',
61 'binary',
62 'blob',
63 'boolean',
64 'char',
65 'character',
66 'clob',
67 'date',
68 'dec',
69 'decfloat',
70 'decimal',
71 'float',
72 'int',
73 'integer',
74 'interval',
75 'nchar',
76 'nclob',
77 'national',
78 'numeric',
79 'real',
80 'row',
81 'smallint',
82 'time',
83 'timestamp',
84 'varchar',
85 'varying', // modifier (character varying)
86 'varbinary'
87 ];
88
89 const NON_RESERVED_WORDS = [
90 "add",
91 "asc",
92 "collation",
93 "desc",
94 "final",
95 "first",
96 "last",
97 "view"
98 ];
99
100 // https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#reserved-word
101 const RESERVED_WORDS = [
102 "abs",
103 "acos",
104 "all",
105 "allocate",
106 "alter",
107 "and",
108 "any",
109 "are",
110 "array",
111 "array_agg",
112 "array_max_cardinality",
113 "as",
114 "asensitive",
115 "asin",
116 "asymmetric",
117 "at",
118 "atan",
119 "atomic",
120 "authorization",
121 "avg",
122 "begin",
123 "begin_frame",
124 "begin_partition",
125 "between",
126 "bigint",
127 "binary",
128 "blob",
129 "boolean",
130 "both",
131 "by",
132 "call",
133 "called",
134 "cardinality",
135 "cascaded",
136 "case",
137 "cast",
138 "ceil",
139 "ceiling",
140 "char",
141 "char_length",
142 "character",
143 "character_length",
144 "check",
145 "classifier",
146 "clob",
147 "close",
148 "coalesce",
149 "collate",
150 "collect",
151 "column",
152 "commit",
153 "condition",
154 "connect",
155 "constraint",
156 "contains",
157 "convert",
158 "copy",
159 "corr",
160 "corresponding",
161 "cos",
162 "cosh",
163 "count",
164 "covar_pop",
165 "covar_samp",
166 "create",
167 "cross",
168 "cube",
169 "cume_dist",
170 "current",
171 "current_catalog",
172 "current_date",
173 "current_default_transform_group",
174 "current_path",
175 "current_role",
176 "current_row",
177 "current_schema",
178 "current_time",
179 "current_timestamp",
180 "current_path",
181 "current_role",
182 "current_transform_group_for_type",
183 "current_user",
184 "cursor",
185 "cycle",
186 "date",
187 "day",
188 "deallocate",
189 "dec",
190 "decimal",
191 "decfloat",
192 "declare",
193 "default",
194 "define",
195 "delete",
196 "dense_rank",
197 "deref",
198 "describe",
199 "deterministic",
200 "disconnect",
201 "distinct",
202 "double",
203 "drop",
204 "dynamic",
205 "each",
206 "element",
207 "else",
208 "empty",
209 "end",
210 "end_frame",
211 "end_partition",
212 "end-exec",
213 "equals",
214 "escape",
215 "every",
216 "except",
217 "exec",
218 "execute",
219 "exists",
220 "exp",
221 "external",
222 "extract",
223 "false",
224 "fetch",
225 "filter",
226 "first_value",
227 "float",
228 "floor",
229 "for",
230 "foreign",
231 "frame_row",
232 "free",
233 "from",
234 "full",
235 "function",
236 "fusion",
237 "get",
238 "global",
239 "grant",
240 "group",
241 "grouping",
242 "groups",
243 "having",
244 "hold",
245 "hour",
246 "identity",
247 "in",
248 "indicator",
249 "initial",
250 "inner",
251 "inout",
252 "insensitive",
253 "insert",
254 "int",
255 "integer",
256 "intersect",
257 "intersection",
258 "interval",
259 "into",
260 "is",
261 "join",
262 "json_array",
263 "json_arrayagg",
264 "json_exists",
265 "json_object",
266 "json_objectagg",
267 "json_query",
268 "json_table",
269 "json_table_primitive",
270 "json_value",
271 "lag",
272 "language",
273 "large",
274 "last_value",
275 "lateral",
276 "lead",
277 "leading",
278 "left",
279 "like",
280 "like_regex",
281 "listagg",
282 "ln",
283 "local",
284 "localtime",
285 "localtimestamp",
286 "log",
287 "log10",
288 "lower",
289 "match",
290 "match_number",
291 "match_recognize",
292 "matches",
293 "max",
294 "member",
295 "merge",
296 "method",
297 "min",
298 "minute",
299 "mod",
300 "modifies",
301 "module",
302 "month",
303 "multiset",
304 "national",
305 "natural",
306 "nchar",
307 "nclob",
308 "new",
309 "no",
310 "none",
311 "normalize",
312 "not",
313 "nth_value",
314 "ntile",
315 "null",
316 "nullif",
317 "numeric",
318 "octet_length",
319 "occurrences_regex",
320 "of",
321 "offset",
322 "old",
323 "omit",
324 "on",
325 "one",
326 "only",
327 "open",
328 "or",
329 "order",
330 "out",
331 "outer",
332 "over",
333 "overlaps",
334 "overlay",
335 "parameter",
336 "partition",
337 "pattern",
338 "per",
339 "percent",
340 "percent_rank",
341 "percentile_cont",
342 "percentile_disc",
343 "period",
344 "portion",
345 "position",
346 "position_regex",
347 "power",
348 "precedes",
349 "precision",
350 "prepare",
351 "primary",
352 "procedure",
353 "ptf",
354 "range",
355 "rank",
356 "reads",
357 "real",
358 "recursive",
359 "ref",
360 "references",
361 "referencing",
362 "regr_avgx",
363 "regr_avgy",
364 "regr_count",
365 "regr_intercept",
366 "regr_r2",
367 "regr_slope",
368 "regr_sxx",
369 "regr_sxy",
370 "regr_syy",
371 "release",
372 "result",
373 "return",
374 "returns",
375 "revoke",
376 "right",
377 "rollback",
378 "rollup",
379 "row",
380 "row_number",
381 "rows",
382 "running",
383 "savepoint",
384 "scope",
385 "scroll",
386 "search",
387 "second",
388 "seek",
389 "select",
390 "sensitive",
391 "session_user",
392 "set",
393 "show",
394 "similar",
395 "sin",
396 "sinh",
397 "skip",
398 "smallint",
399 "some",
400 "specific",
401 "specifictype",
402 "sql",
403 "sqlexception",
404 "sqlstate",
405 "sqlwarning",
406 "sqrt",
407 "start",
408 "static",
409 "stddev_pop",
410 "stddev_samp",
411 "submultiset",
412 "subset",
413 "substring",
414 "substring_regex",
415 "succeeds",
416 "sum",
417 "symmetric",
418 "system",
419 "system_time",
420 "system_user",
421 "table",
422 "tablesample",
423 "tan",
424 "tanh",
425 "then",
426 "time",
427 "timestamp",
428 "timezone_hour",
429 "timezone_minute",
430 "to",
431 "trailing",
432 "translate",
433 "translate_regex",
434 "translation",
435 "treat",
436 "trigger",
437 "trim",
438 "trim_array",
439 "true",
440 "truncate",
441 "uescape",
442 "union",
443 "unique",
444 "unknown",
445 "unnest",
446 "update",
447 "upper",
448 "user",
449 "using",
450 "value",
451 "values",
452 "value_of",
453 "var_pop",
454 "var_samp",
455 "varbinary",
456 "varchar",
457 "varying",
458 "versioning",
459 "when",
460 "whenever",
461 "where",
462 "width_bucket",
463 "window",
464 "with",
465 "within",
466 "without",
467 "year",
468 ];
469
470 // these are reserved words we have identified to be functions
471 // and should only be highlighted in a dispatch-like context
472 // ie, array_agg(...), etc.
473 const RESERVED_FUNCTIONS = [
474 "abs",
475 "acos",
476 "array_agg",
477 "asin",
478 "atan",
479 "avg",
480 "cast",
481 "ceil",
482 "ceiling",
483 "coalesce",
484 "corr",
485 "cos",
486 "cosh",
487 "count",
488 "covar_pop",
489 "covar_samp",
490 "cume_dist",
491 "dense_rank",
492 "deref",
493 "element",
494 "exp",
495 "extract",
496 "first_value",
497 "floor",
498 "json_array",
499 "json_arrayagg",
500 "json_exists",
501 "json_object",
502 "json_objectagg",
503 "json_query",
504 "json_table",
505 "json_table_primitive",
506 "json_value",
507 "lag",
508 "last_value",
509 "lead",
510 "listagg",
511 "ln",
512 "log",
513 "log10",
514 "lower",
515 "max",
516 "min",
517 "mod",
518 "nth_value",
519 "ntile",
520 "nullif",
521 "percent_rank",
522 "percentile_cont",
523 "percentile_disc",
524 "position",
525 "position_regex",
526 "power",
527 "rank",
528 "regr_avgx",
529 "regr_avgy",
530 "regr_count",
531 "regr_intercept",
532 "regr_r2",
533 "regr_slope",
534 "regr_sxx",
535 "regr_sxy",
536 "regr_syy",
537 "row_number",
538 "sin",
539 "sinh",
540 "sqrt",
541 "stddev_pop",
542 "stddev_samp",
543 "substring",
544 "substring_regex",
545 "sum",
546 "tan",
547 "tanh",
548 "translate",
549 "translate_regex",
550 "treat",
551 "trim",
552 "trim_array",
553 "unnest",
554 "upper",
555 "value_of",
556 "var_pop",
557 "var_samp",
558 "width_bucket",
559 ];
560
561 // these functions can
562 const POSSIBLE_WITHOUT_PARENS = [
563 "current_catalog",
564 "current_date",
565 "current_default_transform_group",
566 "current_path",
567 "current_role",
568 "current_schema",
569 "current_transform_group_for_type",
570 "current_user",
571 "session_user",
572 "system_time",
573 "system_user",
574 "current_time",
575 "localtime",
576 "current_timestamp",
577 "localtimestamp"
578 ];
579
580 // those exist to boost relevance making these very
581 // "SQL like" keyword combos worth +1 extra relevance
582 const COMBOS = [
583 "create table",
584 "insert into",
585 "primary key",
586 "foreign key",
587 "not null",
588 "alter table",
589 "add constraint",
590 "grouping sets",
591 "on overflow",
592 "character set",
593 "respect nulls",
594 "ignore nulls",
595 "nulls first",
596 "nulls last",
597 "depth first",
598 "breadth first"
599 ];
600
601 const FUNCTIONS = RESERVED_FUNCTIONS;
602
603 const KEYWORDS = [...RESERVED_WORDS, ...NON_RESERVED_WORDS].filter((keyword) => {
604 return !RESERVED_FUNCTIONS.includes(keyword);
605 });
606
607 const VARIABLE = {
608 className: "variable",
609 begin: /@[a-z0-9]+/,
610 };
611
612 const OPERATOR = {
613 className: "operator",
614 begin: /[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,
615 relevance: 0,
616 };
617
618 const FUNCTION_CALL = {
619 begin: regex.concat(/\b/, regex.either(...FUNCTIONS), /\s*\(/),
620 relevance: 0,
621 keywords: {
622 built_in: FUNCTIONS
623 }
624 };
625
626 // keywords with less than 3 letters are reduced in relevancy
627 function reduceRelevancy(list, {exceptions, when} = {}) {
628 const qualifyFn = when;
629 exceptions = exceptions || [];
630 return list.map((item) => {
631 if (item.match(/\|\d+$/) || exceptions.includes(item)) {
632 return item;
633 } else if (qualifyFn(item)) {
634 return `${item}|0`;
635 } else {
636 return item;
637 }
638 });
639 }
640
641 return {
642 name: 'SQL',
643 case_insensitive: true,
644 // does not include {} or HTML tags `</`
645 illegal: /[{}]|<\//,
646 keywords: {
647 $pattern: /\b[\w\.]+/,
648 keyword:
649 reduceRelevancy(KEYWORDS, { when: (x) => x.length < 3 }),
650 literal: LITERALS,
651 type: TYPES,
652 built_in: POSSIBLE_WITHOUT_PARENS
653 },
654 contains: [
655 {
656 begin: regex.either(...COMBOS),
657 relevance: 0,
658 keywords: {
659 $pattern: /[\w\.]+/,
660 keyword: KEYWORDS.concat(COMBOS),
661 literal: LITERALS,
662 type: TYPES
663 },
664 },
665 {
666 className: "type",
667 begin: regex.either(...MULTI_WORD_TYPES)
668 },
669 FUNCTION_CALL,
670 VARIABLE,
671 STRING,
672 QUOTED_IDENTIFIER,
673 hljs.C_NUMBER_MODE,
674 hljs.C_BLOCK_COMMENT_MODE,
675 COMMENT_MODE,
676 OPERATOR
677 ]
678 };
679}
680
681export { sql as default };