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