query-generator.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. "use strict";
  2. var __defProp = Object.defineProperty;
  3. var __defProps = Object.defineProperties;
  4. var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
  5. var __getOwnPropSymbols = Object.getOwnPropertySymbols;
  6. var __hasOwnProp = Object.prototype.hasOwnProperty;
  7. var __propIsEnum = Object.prototype.propertyIsEnumerable;
  8. var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  9. var __spreadValues = (a, b) => {
  10. for (var prop in b || (b = {}))
  11. if (__hasOwnProp.call(b, prop))
  12. __defNormalProp(a, prop, b[prop]);
  13. if (__getOwnPropSymbols)
  14. for (var prop of __getOwnPropSymbols(b)) {
  15. if (__propIsEnum.call(b, prop))
  16. __defNormalProp(a, prop, b[prop]);
  17. }
  18. return a;
  19. };
  20. var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
  21. const _ = require("lodash");
  22. const Utils = require("../../utils");
  23. const AbstractQueryGenerator = require("../abstract/query-generator");
  24. const util = require("util");
  25. const Op = require("../../operators");
  26. const JSON_FUNCTION_REGEX = /^\s*((?:[a-z]+_){0,2}jsonb?(?:_[a-z]+){0,2})\([^)]*\)/i;
  27. const JSON_OPERATOR_REGEX = /^\s*(->>?|@>|<@|\?[|&]?|\|{2}|#-)/i;
  28. const TOKEN_CAPTURE_REGEX = /^\s*((?:([`"'])(?:(?!\2).|\2{2})*\2)|[\w\d\s]+|[().,;+-])/i;
  29. const FOREIGN_KEY_FIELDS = [
  30. "CONSTRAINT_NAME as constraint_name",
  31. "CONSTRAINT_NAME as constraintName",
  32. "CONSTRAINT_SCHEMA as constraintSchema",
  33. "CONSTRAINT_SCHEMA as constraintCatalog",
  34. "TABLE_NAME as tableName",
  35. "TABLE_SCHEMA as tableSchema",
  36. "TABLE_SCHEMA as tableCatalog",
  37. "COLUMN_NAME as columnName",
  38. "REFERENCED_TABLE_SCHEMA as referencedTableSchema",
  39. "REFERENCED_TABLE_SCHEMA as referencedTableCatalog",
  40. "REFERENCED_TABLE_NAME as referencedTableName",
  41. "REFERENCED_COLUMN_NAME as referencedColumnName"
  42. ].join(",");
  43. const SNOWFLAKE_RESERVED_WORDS = "account,all,alter,and,any,as,between,by,case,cast,check,column,connect,connections,constraint,create,cross,current,current_date,current_time,current_timestamp,current_user,database,delete,distinct,drop,else,exists,false,following,for,from,full,grant,group,gscluster,having,ilike,in,increment,inner,insert,intersect,into,is,issue,join,lateral,left,like,localtime,localtimestamp,minus,natural,not,null,of,on,or,order,organization,qualify,regexp,revoke,right,rlike,row,rows,sample,schema,select,set,some,start,table,tablesample,then,to,trigger,true,try_cast,union,unique,update,using,values,view,when,whenever,where,with".split(",");
  44. const typeWithoutDefault = /* @__PURE__ */ new Set(["BLOB", "TEXT", "GEOMETRY", "JSON"]);
  45. class SnowflakeQueryGenerator extends AbstractQueryGenerator {
  46. constructor(options) {
  47. super(options);
  48. this.OperatorMap = __spreadProps(__spreadValues({}, this.OperatorMap), {
  49. [Op.regexp]: "REGEXP",
  50. [Op.notRegexp]: "NOT REGEXP"
  51. });
  52. }
  53. createDatabaseQuery(databaseName, options) {
  54. options = __spreadValues({
  55. charset: null,
  56. collate: null
  57. }, options);
  58. return Utils.joinSQLFragments([
  59. "CREATE DATABASE IF NOT EXISTS",
  60. this.quoteIdentifier(databaseName),
  61. options.charset && `DEFAULT CHARACTER SET ${this.escape(options.charset)}`,
  62. options.collate && `DEFAULT COLLATE ${this.escape(options.collate)}`,
  63. ";"
  64. ]);
  65. }
  66. dropDatabaseQuery(databaseName) {
  67. return `DROP DATABASE IF EXISTS ${this.quoteIdentifier(databaseName)};`;
  68. }
  69. createSchema() {
  70. return "SHOW TABLES";
  71. }
  72. showSchemasQuery() {
  73. return "SHOW TABLES";
  74. }
  75. versionQuery() {
  76. return "SELECT CURRENT_VERSION()";
  77. }
  78. createTableQuery(tableName, attributes, options) {
  79. options = __spreadValues({
  80. charset: null,
  81. rowFormat: null
  82. }, options);
  83. const primaryKeys = [];
  84. const foreignKeys = {};
  85. const attrStr = [];
  86. for (const attr in attributes) {
  87. if (!Object.prototype.hasOwnProperty.call(attributes, attr))
  88. continue;
  89. const dataType = attributes[attr];
  90. let match;
  91. if (dataType.includes("PRIMARY KEY")) {
  92. primaryKeys.push(attr);
  93. if (dataType.includes("REFERENCES")) {
  94. match = dataType.match(/^(.+) (REFERENCES.*)$/);
  95. attrStr.push(`${this.quoteIdentifier(attr)} ${match[1].replace("PRIMARY KEY", "")}`);
  96. foreignKeys[attr] = match[2];
  97. } else {
  98. attrStr.push(`${this.quoteIdentifier(attr)} ${dataType.replace("PRIMARY KEY", "")}`);
  99. }
  100. } else if (dataType.includes("REFERENCES")) {
  101. match = dataType.match(/^(.+) (REFERENCES.*)$/);
  102. attrStr.push(`${this.quoteIdentifier(attr)} ${match[1]}`);
  103. foreignKeys[attr] = match[2];
  104. } else {
  105. attrStr.push(`${this.quoteIdentifier(attr)} ${dataType}`);
  106. }
  107. }
  108. const table = this.quoteTable(tableName);
  109. let attributesClause = attrStr.join(", ");
  110. const pkString = primaryKeys.map((pk) => this.quoteIdentifier(pk)).join(", ");
  111. if (options.uniqueKeys) {
  112. _.each(options.uniqueKeys, (columns, indexName) => {
  113. if (columns.customIndex) {
  114. if (typeof indexName !== "string") {
  115. indexName = `uniq_${tableName}_${columns.fields.join("_")}`;
  116. }
  117. attributesClause += `, UNIQUE ${this.quoteIdentifier(indexName)} (${columns.fields.map((field) => this.quoteIdentifier(field)).join(", ")})`;
  118. }
  119. });
  120. }
  121. if (pkString.length > 0) {
  122. attributesClause += `, PRIMARY KEY (${pkString})`;
  123. }
  124. for (const fkey in foreignKeys) {
  125. if (Object.prototype.hasOwnProperty.call(foreignKeys, fkey)) {
  126. attributesClause += `, FOREIGN KEY (${this.quoteIdentifier(fkey)}) ${foreignKeys[fkey]}`;
  127. }
  128. }
  129. return Utils.joinSQLFragments([
  130. "CREATE TABLE IF NOT EXISTS",
  131. table,
  132. `(${attributesClause})`,
  133. options.comment && typeof options.comment === "string" && `COMMENT ${this.escape(options.comment)}`,
  134. options.charset && `DEFAULT CHARSET=${options.charset}`,
  135. options.collate && `COLLATE ${options.collate}`,
  136. options.rowFormat && `ROW_FORMAT=${options.rowFormat}`,
  137. ";"
  138. ]);
  139. }
  140. describeTableQuery(tableName, schema, schemaDelimiter) {
  141. const table = this.quoteTable(this.addSchema({
  142. tableName,
  143. _schema: schema,
  144. _schemaDelimiter: schemaDelimiter
  145. }));
  146. return `SHOW FULL COLUMNS FROM ${table};`;
  147. }
  148. showTablesQuery(database) {
  149. return Utils.joinSQLFragments([
  150. "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'",
  151. database ? `AND TABLE_SCHEMA = ${this.escape(database)}` : "AND TABLE_SCHEMA NOT IN ( 'INFORMATION_SCHEMA', 'PERFORMANCE_SCHEMA', 'SYS')",
  152. ";"
  153. ]);
  154. }
  155. tableExistsQuery(table) {
  156. const tableName = table.tableName || table;
  157. const schema = table.schema;
  158. return Utils.joinSQLFragments([
  159. "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'",
  160. `AND TABLE_SCHEMA = ${schema !== void 0 ? this.escape(schema) : "CURRENT_SCHEMA()"}`,
  161. `AND TABLE_NAME = ${this.escape(tableName)}`,
  162. ";"
  163. ]);
  164. }
  165. addColumnQuery(table, key, dataType) {
  166. return Utils.joinSQLFragments([
  167. "ALTER TABLE",
  168. this.quoteTable(table),
  169. "ADD",
  170. this.quoteIdentifier(key),
  171. this.attributeToSQL(dataType, {
  172. context: "addColumn",
  173. tableName: table,
  174. foreignKey: key
  175. }),
  176. ";"
  177. ]);
  178. }
  179. removeColumnQuery(tableName, attributeName) {
  180. return Utils.joinSQLFragments([
  181. "ALTER TABLE",
  182. this.quoteTable(tableName),
  183. "DROP",
  184. this.quoteIdentifier(attributeName),
  185. ";"
  186. ]);
  187. }
  188. changeColumnQuery(tableName, attributes) {
  189. const query = (...subQuerys) => Utils.joinSQLFragments([
  190. "ALTER TABLE",
  191. this.quoteTable(tableName),
  192. "ALTER COLUMN",
  193. ...subQuerys,
  194. ";"
  195. ]);
  196. const sql = [];
  197. for (const attributeName in attributes) {
  198. let definition = this.dataTypeMapping(tableName, attributeName, attributes[attributeName]);
  199. const attrSql = [];
  200. if (definition.includes("NOT NULL")) {
  201. attrSql.push(query(this.quoteIdentifier(attributeName), "SET NOT NULL"));
  202. definition = definition.replace("NOT NULL", "").trim();
  203. } else if (!definition.includes("REFERENCES")) {
  204. attrSql.push(query(this.quoteIdentifier(attributeName), "DROP NOT NULL"));
  205. }
  206. if (definition.includes("DEFAULT")) {
  207. attrSql.push(query(this.quoteIdentifier(attributeName), "SET DEFAULT", definition.match(/DEFAULT ([^;]+)/)[1]));
  208. definition = definition.replace(/(DEFAULT[^;]+)/, "").trim();
  209. } else if (!definition.includes("REFERENCES")) {
  210. attrSql.push(query(this.quoteIdentifier(attributeName), "DROP DEFAULT"));
  211. }
  212. if (definition.match(/UNIQUE;*$/)) {
  213. definition = definition.replace(/UNIQUE;*$/, "");
  214. attrSql.push(query("ADD UNIQUE (", this.quoteIdentifier(attributeName), ")").replace("ALTER COLUMN", ""));
  215. }
  216. if (definition.includes("REFERENCES")) {
  217. definition = definition.replace(/.+?(?=REFERENCES)/, "");
  218. attrSql.push(query("ADD FOREIGN KEY (", this.quoteIdentifier(attributeName), ")", definition).replace("ALTER COLUMN", ""));
  219. } else {
  220. attrSql.push(query(this.quoteIdentifier(attributeName), "TYPE", definition));
  221. }
  222. sql.push(attrSql.join(""));
  223. }
  224. return sql.join("");
  225. }
  226. renameColumnQuery(tableName, attrBefore, attributes) {
  227. const attrString = [];
  228. for (const attrName in attributes) {
  229. const definition = attributes[attrName];
  230. attrString.push(`'${attrBefore}' '${attrName}' ${definition}`);
  231. }
  232. return Utils.joinSQLFragments([
  233. "ALTER TABLE",
  234. this.quoteTable(tableName),
  235. "RENAME COLUMN",
  236. attrString.join(" to "),
  237. ";"
  238. ]);
  239. }
  240. handleSequelizeMethod(attr, tableName, factory, options, prepend) {
  241. if (attr instanceof Utils.Json) {
  242. if (attr.conditions) {
  243. const conditions = this.parseConditionObject(attr.conditions).map((condition) => `${this.jsonPathExtractionQuery(condition.path[0], _.tail(condition.path))} = '${condition.value}'`);
  244. return conditions.join(" AND ");
  245. }
  246. if (attr.path) {
  247. let str;
  248. if (this._checkValidJsonStatement(attr.path)) {
  249. str = attr.path;
  250. } else {
  251. const paths = _.toPath(attr.path);
  252. const column = paths.shift();
  253. str = this.jsonPathExtractionQuery(column, paths);
  254. }
  255. if (attr.value) {
  256. str += util.format(" = %s", this.escape(attr.value));
  257. }
  258. return str;
  259. }
  260. } else if (attr instanceof Utils.Cast) {
  261. if (/timestamp/i.test(attr.type)) {
  262. attr.type = "datetime";
  263. } else if (attr.json && /boolean/i.test(attr.type)) {
  264. attr.type = "char";
  265. } else if (/double precision/i.test(attr.type) || /boolean/i.test(attr.type) || /integer/i.test(attr.type)) {
  266. attr.type = "decimal";
  267. } else if (/text/i.test(attr.type)) {
  268. attr.type = "char";
  269. }
  270. }
  271. return super.handleSequelizeMethod(attr, tableName, factory, options, prepend);
  272. }
  273. truncateTableQuery(tableName) {
  274. return Utils.joinSQLFragments([
  275. "TRUNCATE",
  276. this.quoteTable(tableName)
  277. ]);
  278. }
  279. deleteQuery(tableName, where, options = {}, model) {
  280. const table = this.quoteTable(tableName);
  281. let whereClause = this.getWhereConditions(where, null, model, options);
  282. const limit = options.limit && ` LIMIT ${this.escape(options.limit)}`;
  283. let primaryKeys = "";
  284. let primaryKeysSelection = "";
  285. if (whereClause) {
  286. whereClause = `WHERE ${whereClause}`;
  287. }
  288. if (limit) {
  289. if (!model) {
  290. throw new Error("Cannot LIMIT delete without a model.");
  291. }
  292. const pks = Object.values(model.primaryKeys).map((pk) => this.quoteIdentifier(pk.field)).join(",");
  293. primaryKeys = model.primaryKeyAttributes.length > 1 ? `(${pks})` : pks;
  294. primaryKeysSelection = pks;
  295. return Utils.joinSQLFragments([
  296. "DELETE FROM",
  297. table,
  298. "WHERE",
  299. primaryKeys,
  300. "IN (SELECT",
  301. primaryKeysSelection,
  302. "FROM",
  303. table,
  304. whereClause,
  305. limit,
  306. ")",
  307. ";"
  308. ]);
  309. }
  310. return Utils.joinSQLFragments([
  311. "DELETE FROM",
  312. table,
  313. whereClause,
  314. ";"
  315. ]);
  316. }
  317. showIndexesQuery() {
  318. return "SELECT '' FROM DUAL";
  319. }
  320. showConstraintsQuery(table, constraintName) {
  321. const tableName = table.tableName || table;
  322. const schemaName = table.schema;
  323. return Utils.joinSQLFragments([
  324. "SELECT CONSTRAINT_CATALOG AS constraintCatalog,",
  325. "CONSTRAINT_NAME AS constraintName,",
  326. "CONSTRAINT_SCHEMA AS constraintSchema,",
  327. "CONSTRAINT_TYPE AS constraintType,",
  328. "TABLE_NAME AS tableName,",
  329. "TABLE_SCHEMA AS tableSchema",
  330. "from INFORMATION_SCHEMA.TABLE_CONSTRAINTS",
  331. `WHERE table_name='${tableName}'`,
  332. constraintName && `AND constraint_name = '${constraintName}'`,
  333. schemaName && `AND TABLE_SCHEMA = '${schemaName}'`,
  334. ";"
  335. ]);
  336. }
  337. removeIndexQuery(tableName, indexNameOrAttributes) {
  338. let indexName = indexNameOrAttributes;
  339. if (typeof indexName !== "string") {
  340. indexName = Utils.underscore(`${tableName}_${indexNameOrAttributes.join("_")}`);
  341. }
  342. return Utils.joinSQLFragments([
  343. "DROP INDEX",
  344. this.quoteIdentifier(indexName),
  345. "ON",
  346. this.quoteTable(tableName),
  347. ";"
  348. ]);
  349. }
  350. attributeToSQL(attribute, options) {
  351. if (!_.isPlainObject(attribute)) {
  352. attribute = {
  353. type: attribute
  354. };
  355. }
  356. const attributeString = attribute.type.toString({ escape: this.escape.bind(this) });
  357. let template = attributeString;
  358. if (attribute.allowNull === false) {
  359. template += " NOT NULL";
  360. }
  361. if (attribute.autoIncrement) {
  362. template += " AUTOINCREMENT";
  363. }
  364. if (!typeWithoutDefault.has(attributeString) && attribute.type._binary !== true && Utils.defaultValueSchemable(attribute.defaultValue)) {
  365. template += ` DEFAULT ${this.escape(attribute.defaultValue)}`;
  366. }
  367. if (attribute.unique === true) {
  368. template += " UNIQUE";
  369. }
  370. if (attribute.primaryKey) {
  371. template += " PRIMARY KEY";
  372. }
  373. if (attribute.comment) {
  374. template += ` COMMENT ${this.escape(attribute.comment)}`;
  375. }
  376. if (attribute.first) {
  377. template += " FIRST";
  378. }
  379. if (attribute.after) {
  380. template += ` AFTER ${this.quoteIdentifier(attribute.after)}`;
  381. }
  382. if (attribute.references) {
  383. if (options && options.context === "addColumn" && options.foreignKey) {
  384. const attrName = this.quoteIdentifier(options.foreignKey);
  385. const fkName = this.quoteIdentifier(`${options.tableName}_${attrName}_foreign_idx`);
  386. template += `, ADD CONSTRAINT ${fkName} FOREIGN KEY (${attrName})`;
  387. }
  388. template += ` REFERENCES ${this.quoteTable(attribute.references.model)}`;
  389. if (attribute.references.key) {
  390. template += ` (${this.quoteIdentifier(attribute.references.key)})`;
  391. } else {
  392. template += ` (${this.quoteIdentifier("id")})`;
  393. }
  394. if (attribute.onDelete) {
  395. template += ` ON DELETE ${attribute.onDelete.toUpperCase()}`;
  396. }
  397. if (attribute.onUpdate) {
  398. template += ` ON UPDATE ${attribute.onUpdate.toUpperCase()}`;
  399. }
  400. }
  401. return template;
  402. }
  403. attributesToSQL(attributes, options) {
  404. const result = {};
  405. for (const key in attributes) {
  406. const attribute = attributes[key];
  407. result[attribute.field || key] = this.attributeToSQL(attribute, options);
  408. }
  409. return result;
  410. }
  411. _checkValidJsonStatement(stmt) {
  412. if (typeof stmt !== "string") {
  413. return false;
  414. }
  415. let currentIndex = 0;
  416. let openingBrackets = 0;
  417. let closingBrackets = 0;
  418. let hasJsonFunction = false;
  419. let hasInvalidToken = false;
  420. while (currentIndex < stmt.length) {
  421. const string = stmt.substr(currentIndex);
  422. const functionMatches = JSON_FUNCTION_REGEX.exec(string);
  423. if (functionMatches) {
  424. currentIndex += functionMatches[0].indexOf("(");
  425. hasJsonFunction = true;
  426. continue;
  427. }
  428. const operatorMatches = JSON_OPERATOR_REGEX.exec(string);
  429. if (operatorMatches) {
  430. currentIndex += operatorMatches[0].length;
  431. hasJsonFunction = true;
  432. continue;
  433. }
  434. const tokenMatches = TOKEN_CAPTURE_REGEX.exec(string);
  435. if (tokenMatches) {
  436. const capturedToken = tokenMatches[1];
  437. if (capturedToken === "(") {
  438. openingBrackets++;
  439. } else if (capturedToken === ")") {
  440. closingBrackets++;
  441. } else if (capturedToken === ";") {
  442. hasInvalidToken = true;
  443. break;
  444. }
  445. currentIndex += tokenMatches[0].length;
  446. continue;
  447. }
  448. break;
  449. }
  450. if (hasJsonFunction && (hasInvalidToken || openingBrackets !== closingBrackets)) {
  451. throw new Error(`Invalid json statement: ${stmt}`);
  452. }
  453. return hasJsonFunction;
  454. }
  455. dataTypeMapping(tableName, attr, dataType) {
  456. if (dataType.includes("PRIMARY KEY")) {
  457. dataType = dataType.replace("PRIMARY KEY", "");
  458. }
  459. if (dataType.includes("SERIAL")) {
  460. if (dataType.includes("BIGINT")) {
  461. dataType = dataType.replace("SERIAL", "BIGSERIAL");
  462. dataType = dataType.replace("BIGINT", "");
  463. } else if (dataType.includes("SMALLINT")) {
  464. dataType = dataType.replace("SERIAL", "SMALLSERIAL");
  465. dataType = dataType.replace("SMALLINT", "");
  466. } else {
  467. dataType = dataType.replace("INTEGER", "");
  468. }
  469. dataType = dataType.replace("NOT NULL", "");
  470. }
  471. return dataType;
  472. }
  473. getForeignKeysQuery(table, schemaName) {
  474. const tableName = table.tableName || table;
  475. return Utils.joinSQLFragments([
  476. "SELECT",
  477. FOREIGN_KEY_FIELDS,
  478. `FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = '${tableName}'`,
  479. `AND CONSTRAINT_NAME!='PRIMARY' AND CONSTRAINT_SCHEMA='${schemaName}'`,
  480. "AND REFERENCED_TABLE_NAME IS NOT NULL",
  481. ";"
  482. ]);
  483. }
  484. getForeignKeyQuery(table, columnName) {
  485. const quotedSchemaName = table.schema ? wrapSingleQuote(table.schema) : "";
  486. const quotedTableName = wrapSingleQuote(table.tableName || table);
  487. const quotedColumnName = wrapSingleQuote(columnName);
  488. return Utils.joinSQLFragments([
  489. "SELECT",
  490. FOREIGN_KEY_FIELDS,
  491. "FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE",
  492. "WHERE (",
  493. [
  494. `REFERENCED_TABLE_NAME = ${quotedTableName}`,
  495. table.schema && `AND REFERENCED_TABLE_SCHEMA = ${quotedSchemaName}`,
  496. `AND REFERENCED_COLUMN_NAME = ${quotedColumnName}`
  497. ],
  498. ") OR (",
  499. [
  500. `TABLE_NAME = ${quotedTableName}`,
  501. table.schema && `AND TABLE_SCHEMA = ${quotedSchemaName}`,
  502. `AND COLUMN_NAME = ${quotedColumnName}`,
  503. "AND REFERENCED_TABLE_NAME IS NOT NULL"
  504. ],
  505. ")"
  506. ]);
  507. }
  508. dropForeignKeyQuery(tableName, foreignKey) {
  509. return Utils.joinSQLFragments([
  510. "ALTER TABLE",
  511. this.quoteTable(tableName),
  512. "DROP FOREIGN KEY",
  513. this.quoteIdentifier(foreignKey),
  514. ";"
  515. ]);
  516. }
  517. addLimitAndOffset(options) {
  518. let fragment = [];
  519. if (options.offset !== null && options.offset !== void 0 && options.offset !== 0) {
  520. fragment = fragment.concat([" LIMIT ", this.escape(options.limit), " OFFSET ", this.escape(options.offset)]);
  521. } else if (options.limit !== null && options.limit !== void 0) {
  522. fragment = [" LIMIT ", this.escape(options.limit)];
  523. }
  524. return fragment.join("");
  525. }
  526. quoteIdentifier(identifier, force) {
  527. const optForceQuote = force || false;
  528. const optQuoteIdentifiers = this.options.quoteIdentifiers !== false;
  529. const rawIdentifier = Utils.removeTicks(identifier, '"');
  530. if (optForceQuote === true || optQuoteIdentifiers !== false || identifier.includes(".") || identifier.includes("->") || SNOWFLAKE_RESERVED_WORDS.includes(rawIdentifier.toLowerCase())) {
  531. return Utils.addTicks(rawIdentifier, '"');
  532. }
  533. return rawIdentifier;
  534. }
  535. }
  536. function wrapSingleQuote(identifier) {
  537. return Utils.addTicks(identifier, "'");
  538. }
  539. module.exports = SnowflakeQueryGenerator;
  540. //# sourceMappingURL=query-generator.js.map