comparison third_party/highlight/languages/sql.js @ 157:2db6253f355d

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