sql.js 11 KB

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