Security advisory GHSA-6457-6jrx-69cr: Sequelize v6 Vulnerable to SQL Injection via JSON Column Cast Type
Package: sequelize (npm), vulnerable version: 6.37.7, fixed in: 6.37.8
CWE: CWE-89
Files changed by the fix:
b/lib/dialects/abstract/query-generator.js

Fix diff:
diff -ruN --no-dereference /home/ubuntu/closed-source-intelligence/data/cache/npm-tarballs/sequelize-6.37.7/lib/dialects/abstract/query-generator.js /home/ubuntu/closed-source-intelligence/data/cache/npm-tarballs/sequelize-6.37.8/lib/dialects/abstract/query-generator.js
--- a/lib/dialects/abstract/query-generator.js
+++ b/lib/dialects/abstract/query-generator.js
@@ -33,6 +33,30 @@
 const Op = require("../../operators");
 const sequelizeError = require("../../errors");
 const IndexHints = require("../../index-hints");
+const ALLOWED_CAST_TYPES = /* @__PURE__ */ new Set([
+  "integer",
+  "int",
+  "smallint",
+  "bigint",
+  "float",
+  "real",
+  "double precision",
+  "decimal",
+  "numeric",
+  "boolean",
+  "text",
+  "char",
+  "varchar",
+  "nvarchar",
+  "date",
+  "timestamp",
+  "timestamptz",
+  "datetime",
+  "json",
+  "jsonb",
+  "signed",
+  "unsigned"
+]);
 class QueryGenerator {
   constructor(options) {
     if (!options.sequelize)
@@ -1895,6 +1919,7 @@
       const tmp = path[path.length - 1].split("::");
       cast = tmp[1];
       path[path.length - 1] = tmp[0];
+      this._validateCastType(cast);
     }
     let pathKey = this.jsonPathExtractionQuery(baseKey, path);
     if (_.isPlainObject(item)) {
@@ -1941,6 +1966,11 @@
     }
     return;
   }
+  _validateCastType(cast) {
+    if (!ALLOWED_CAST_TYPES.has(cast.toLowerCase())) {
+      throw new Error(`Invalid cast type: ${cast}`);
+    }
+  }
   _joinKeyValue(key, value, comparator, prefix) {
     if (!key) {
       return value;
diff -ruN --no-dereference /home/ubuntu/closed-source-intelligence/data/cache/npm-tarballs/sequelize-6.37.7/lib/dialects/abstract/query-generator.js.map /home/ubuntu/closed-source-intelligence/data/cache/npm-tarballs/sequelize-6.37.8/lib/dialects/abstract/query-generator.js.map
--- a/lib/dialects/abstract/query-generator.js.map
+++ b/lib/dialects/abstract/query-generator.js.map
@@ -1,7 +1,7 @@
 {
   "version": 3,
   "sources": ["../../../src/dialects/abstract/query-generator.js"],
-  "sourcesContent": ["'use strict';\n\nconst util = require('util');\nconst _ = require('lodash');\nconst uuidv4 = require('uuid').v4;\n\nconst Utils = require('../../utils');\nconst deprecations = require('../../utils/deprecations');\nconst SqlString = require('../../sql-string');\nconst DataTypes = require('../../data-types');\nconst Model = require('../../model');\nconst Association = require('../../associations/base');\nconst BelongsTo = require('../../associations/belongs-to');\nconst BelongsToMany = require('../../associations/belongs-to-many');\nconst HasMany = require('../../associations/has-many');\nconst Op = require('../../operators');\nconst sequelizeError = require('../../errors');\nconst IndexHints = require('../../index-hints');\n\n\n/**\n * Abstract Query Generator\n *\n * @private\n */\nclass QueryGenerator {\n  constructor(options) {\n    if (!options.sequelize) throw new Error('QueryGenerator initialized without options.sequelize');\n    if (!options._dialect) throw new Error('QueryGenerator initialized without options._dialect');\n\n    this.sequelize = options.sequelize;\n    this.options = options.sequelize.options;\n\n    // dialect name\n    this.dialect = options._dialect.name;\n    this._dialect = options._dialect;\n\n    // wrap quoteIdentifier with common logic\n    this._initQuoteIdentifier();\n  }\n\n  extractTableDetails(tableName, options) {\n    options = options || {};\n    tableName = tableName || {};\n    return {\n      schema: tableName.schema || options.schema || this.options.schema || 'public',\n      tableName: _.isPlainObject(tableName) ? tableName.tableName : tableName,\n      delimiter: tableName.delimiter || options.delimiter || '.'\n    };\n  }\n\n  addSchema(param) {\n    if (!param._schema) return param.tableName || param;\n    const self = this;\n    return {\n      tableName: param.tableName || param,\n      table: param.tableName || param,\n      name: param.name || param,\n      schema: param._schema,\n      delimiter: param._schemaDelimiter || '.',\n      toString() {\n        return self.quoteTable(this);\n      }\n    };\n  }\n\n  dropSchema(tableName, options) {\n    return this.dropTableQuery(tableName, options);\n  }\n\n  describeTableQuery(tableName, schema, schemaDelimiter) {\n    const table = this.quoteTable(\n      this.addSchema({\n        tableName,\n        _schema: schema,\n        _schemaDelimiter: schemaDelimiter\n      })\n    );\n\n    return `DESCRIBE ${table};`;\n  }\n\n  dropTableQuery(tableName) {\n    return `DROP TABLE IF EXISTS ${this.quoteTable(tableName)};`;\n  }\n\n  renameTableQuery(before, after) {\n    return `ALTER TABLE ${this.quoteTable(before)} RENAME TO ${this.quoteTable(after)};`;\n  }\n\n  /**\n   * Helper method for populating the returning into bind information\n   * that is needed by some dialects (currently Oracle)\n   *\n   * @private\n   */\n  populateInsertQueryReturnIntoBinds() {\n    // noop by default\n  }\n\n  /**\n   * Returns an insert into command\n   *\n   * @param {string} table\n   * @param {object} valueHash       attribute value pairs\n   * @param {object} modelAttributes\n   * @param {object} [options]\n   *\n   * @private\n   */\n  insertQuery(table, valueHash, modelAttributes, options) {\n    options = options || {};\n    _.defaults(options, this.options);\n\n    const modelAttributeMap = {};\n    const bind = options.bind || [];\n    const fields = [];\n    const returningModelAttributes = [];\n    const returnTypes = [];\n    const values = [];\n    const quotedTable = this.quoteTable(table);\n    const bindParam = options.bindParam === undefined ? this.bindParam(bind) : options.bindParam;\n    const returnAttributes = [];\n    let query;\n    let valueQuery = '';\n    let emptyQuery = '';\n    let outputFragment = '';\n    let returningFragment = '';\n    let identityWrapperRequired = false;\n    let tmpTable = ''; //tmpTable declaration for trigger\n\n    if (modelAttributes) {\n      _.each(modelAttributes, (attribute, key) => {\n        modelAttributeMap[key] = attribute;\n        if (attribute.field) {\n          modelAttributeMap[attribute.field] = attribute;\n        }\n      });\n    }\n\n    if (this._dialect.supports['DEFAULT VALUES']) {\n      emptyQuery += ' DEFAULT VALUES';\n    } else if (this._dialect.supports['VALUES ()']) {\n      emptyQuery += ' VALUES ()';\n    }\n\n    if ((this._dialect.supports.returnValues || this._dialect.supports.returnIntoValues) && options.returning) {\n      const returnValues = this.generateReturnValues(modelAttributes, options);\n\n      returningModelAttributes.push(...returnValues.returnFields);\n      // Storing the returnTypes for dialects that need to have returning into bind information for outbinds\n      if (this._dialect.supports.returnIntoValues) {\n        returnTypes.push(...returnValues.returnTypes);\n      }\n      returningFragment = returnValues.returningFragment;\n      tmpTable = returnValues.tmpTable || '';\n      outputFragment = returnValues.outputFragment || '';\n    }\n\n    if (_.get(this, ['sequelize', 'options', 'dialectOptions', 'prependSearchPath']) || options.searchPath) {\n      // Not currently supported with search path (requires output of multiple queries)\n      options.bindParam = false;\n    }\n\n    if (this._dialect.supports.EXCEPTION && options.exception) {\n      // Not currently supported with bind parameters (requires output of multiple queries)\n      options.bindParam = false;\n    }\n\n    valueHash = Utils.removeNullValuesFromHash(valueHash, this.options.omitNull);\n    for (const key in valueHash) {\n      if (Object.prototype.hasOwnProperty.call(valueHash, key)) {\n        const value = valueHash[key];\n        fields.push(this.quoteIdentifier(key));\n\n        // SERIALS' can't be NULL in postgresql, use DEFAULT where supported\n        if (modelAttributeMap && modelAttributeMap[key] && modelAttributeMap[key].autoIncrement === true && value == null) {\n          if (!this._dialect.supports.autoIncrement.defaultValue) {\n            fields.splice(-1, 1);\n          } else if (this._dialect.supports.DEFAULT) {\n            values.push('DEFAULT');\n          } else {\n            values.push(this.escape(null));\n          }\n        } else {\n          if (modelAttributeMap && modelAttributeMap[key] && modelAttributeMap[key].autoIncrement === true) {\n            identityWrapperRequired = true;\n          }\n\n          if (value instanceof Utils.SequelizeMethod || options.bindParam === false) {\n            values.push(this.escape(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'INSERT' }));\n          } else {\n            values.push(this.format(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'INSERT' }, bindParam));\n          }\n        }\n      }\n    }\n\n    let onDuplicateKeyUpdate = '';\n\n    if (\n      !_.isEmpty(options.conflictWhere)\n      && !this._dialect.supports.inserts.onConflictWhere\n    ) {\n      throw new Error('missing dialect support for conflictWhere option');\n    }\n\n    // `options.updateOnDuplicate` is the list of field names to update if a duplicate key is hit during the insert.  It\n    // contains just the field names.  This option is _usually_ explicitly set by the corresponding query-interface\n    // upsert function.\n    if (this._dialect.supports.inserts.updateOnDuplicate && options.updateOnDuplicate) {\n      if (this._dialect.supports.inserts.updateOnDuplicate == ' ON CONFLICT DO UPDATE SET') { // postgres / sqlite\n        // If no conflict target columns were specified, use the primary key names from options.upsertKeys\n        const conflictKeys = options.upsertKeys.map(attr => this.quoteIdentifier(attr));\n        const updateKeys = options.updateOnDuplicate.map(attr => `${this.quoteIdentifier(attr)}=EXCLUDED.${this.quoteIdentifier(attr)}`);\n\n        const fragments = [\n          'ON CONFLICT',\n          '(',\n          conflictKeys.join(','),\n          ')'\n        ];\n\n        if (!_.isEmpty(options.conflictWhere)) {\n          fragments.push(this.whereQuery(options.conflictWhere, options));\n        }\n\n        // if update keys are provided, then apply them here.  if there are no updateKeys provided, then do not try to\n        // do an update.  Instead, fall back to DO NOTHING.\n        if (_.isEmpty(updateKeys)) {\n          fragments.push('DO NOTHING');\n        } else {\n          fragments.push('DO UPDATE SET', updateKeys.join(','));\n        }\n\n        onDuplicateKeyUpdate = ` ${Utils.joinSQLFragments(fragments)}`;\n\n      } else {\n        const valueKeys = options.updateOnDuplicate.map(attr => `${this.quoteIdentifier(attr)}=VALUES(${this.quoteIdentifier(attr)})`);\n        // the rough equivalent to ON CONFLICT DO NOTHING in mysql, etc is ON DUPLICATE KEY UPDATE id = id\n        // So, if no update values were provided, fall back to the identifier columns provided in the upsertKeys array.\n        // This will be the primary key in most cases, but it could be some other constraint.\n        if (_.isEmpty(valueKeys) && options.upsertKeys) {\n          valueKeys.push(...options.upsertKeys.map(attr => `${this.quoteIdentifier(attr)}=${this.quoteIdentifier(attr)}`));\n        }\n\n        // edge case... but if for some reason there were no valueKeys, and there were also no upsertKeys... then we\n        // can no longer build the requested query without a syntax error.  Let's throw something more graceful here\n        // so the devs know what the problem is.\n        if (_.isEmpty(valueKeys)) {\n          throw new Error('No update values found for ON DUPLICATE KEY UPDATE clause, and no identifier fields could be found to use instead.');\n        }\n        onDuplicateKeyUpdate += `${this._dialect.supports.inserts.updateOnDuplicate} ${valueKeys.join(',')}`;\n      }\n    }\n\n    const replacements = {\n      ignoreDuplicates: options.ignoreDuplicates ? this._dialect.supports.inserts.ignoreDuplicates : '',\n      onConflictDoNothing: options.ignoreDuplicates ? this._dialect.supports.inserts.onConflictDoNothing : '',\n      attributes: fields.join(','),\n      output: outputFragment,\n      values: values.join(','),\n      tmpTable\n    };\n\n    valueQuery = `${tmpTable}INSERT${replacements.ignoreDuplicates} INTO ${quotedTable} (${replacements.attributes})${replacements.output} VALUES (${replacements.values})${onDuplicateKeyUpdate}${replacements.onConflictDoNothing}${valueQuery}`;\n    emptyQuery = `${tmpTable}INSERT${replacements.ignoreDuplicates} INTO ${quotedTable}${replacements.output}${onDuplicateKeyUpdate}${replacements.onConflictDoNothing}${emptyQuery}`;\n\n    // Mostly for internal use, so we expect the user to know what he's doing!\n    // pg_temp functions are private per connection, so we never risk this function interfering with another one.\n    if (this._dialect.supports.EXCEPTION && options.exception) {\n      const dropFunction = 'DROP FUNCTION IF EXISTS pg_temp.testfunc()';\n\n      if (returningModelAttributes.length === 0) {\n        returningModelAttributes.push('*');\n      }\n\n      const delimiter = `$func_${uuidv4().replace(/-/g, '')}$`;\n      const selectQuery = `SELECT (testfunc.response).${returningModelAttributes.join(', (testfunc.response).')}, testfunc.sequelize_caught_exception FROM pg_temp.testfunc();`;\n\n      options.exception = 'WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL;';\n      valueQuery = `CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response ${quotedTable}, OUT sequelize_caught_exception text) RETURNS RECORD AS ${delimiter} BEGIN ${valueQuery} RETURNING * INTO response; EXCEPTION ${options.exception} END ${delimiter} LANGUAGE plpgsql; ${selectQuery} ${dropFunction}`;\n    } else {\n      valueQuery += returningFragment;\n      emptyQuery += returningFragment;\n    }\n\n    if (this._dialect.supports.returnIntoValues && options.returning) {\n      // Populating the returnAttributes array and performing operations needed for output binds of insertQuery\n      this.populateInsertQueryReturnIntoBinds(returningModelAttributes, returnTypes, bind.length, returnAttributes, options);\n    }\n\n    query = `${replacements.attributes.length ? valueQuery : emptyQuery}${returnAttributes.join(',')};`;\n    if (this._dialect.supports.finalTable) {\n      query = `SELECT * FROM FINAL TABLE(${ replacements.attributes.length ? valueQuery : emptyQuery });`;\n    }\n    if (identityWrapperRequired && this._dialect.supports.autoIncrement.identityInsert) {\n      query = `SET IDENTITY_INSERT ${quotedTable} ON; ${query} SET IDENTITY_INSERT ${quotedTable} OFF;`;\n    }\n\n    // Used by Postgres upsertQuery and calls to here with options.exception set to true\n    const result = { query };\n    if (options.bindParam !== false) {\n      result.bind = bind;\n    }\n\n    return result;\n  }\n\n  /**\n   * Returns an insert into command for multiple values.\n   *\n   * @param {string} tableName\n   * @param {object} fieldValueHashes\n   * @param {object} options\n   * @param {object} fieldMappedAttributes\n   *\n   * @private\n   */\n  bulkInsertQuery(tableName, fieldValueHashes, options, fieldMappedAttributes) {\n    options = options || {};\n    fieldMappedAttributes = fieldMappedAttributes || {};\n\n    const tuples = [];\n    const serials = {};\n    const allAttributes = [];\n    let onDuplicateKeyUpdate = '';\n\n    for (const fieldValueHash of fieldValueHashes) {\n      _.forOwn(fieldValueHash, (value, key) => {\n        if (!allAttributes.includes(key)) {\n          allAttributes.push(key);\n        }\n        if (\n          fieldMappedAttributes[key]\n          && fieldMappedAttributes[key].autoIncrement === true\n        ) {\n          serials[key] = true;\n        }\n      });\n    }\n\n    for (const fieldValueHash of fieldValueHashes) {\n      const values = allAttributes.map(key => {\n        if (\n          this._dialect.supports.bulkDefault\n          && serials[key] === true\n        ) {\n          // fieldValueHashes[key] ?? 'DEFAULT'\n          return fieldValueHash[key] != null ? fieldValueHash[key] : 'DEFAULT';\n        }\n\n        return this.escape(fieldValueHash[key], fieldMappedAttributes[key], { context: 'INSERT' });\n      });\n\n      tuples.push(`(${values.join(',')})`);\n    }\n\n    // `options.updateOnDuplicate` is the list of field names to update if a duplicate key is hit during the insert.  It\n    // contains just the field names.  This option is _usually_ explicitly set by the corresponding query-interface\n    // upsert function.\n    if (this._dialect.supports.inserts.updateOnDuplicate && options.updateOnDuplicate) {\n      if (this._dialect.supports.inserts.updateOnDuplicate == ' ON CONFLICT DO UPDATE SET') { // postgres / sqlite\n        // If no conflict target columns were specified, use the primary key names from options.upsertKeys\n        const conflictKeys = options.upsertKeys.map(attr => this.quoteIdentifier(attr));\n        const updateKeys = options.updateOnDuplicate.map(attr => `${this.quoteIdentifier(attr)}=EXCLUDED.${this.quoteIdentifier(attr)}`);\n\n        let whereClause = false;\n        if (options.conflictWhere) {\n          if (!this._dialect.supports.inserts.onConflictWhere) {\n            throw new Error(`conflictWhere not supported for dialect ${this._dialect.name}`);\n          }\n\n          whereClause = this.whereQuery(options.conflictWhere, options);\n        }\n\n        // The Utils.joinSQLFragments later on will join this as it handles nested arrays.\n        onDuplicateKeyUpdate = [\n          'ON CONFLICT',\n          '(',\n          conflictKeys.join(','),\n          ')',\n          whereClause,\n          'DO UPDATE SET',\n          updateKeys.join(',')\n        ];\n      } else { // mysql / maria\n        if (options.conflictWhere) {\n          throw new Error(`conflictWhere not supported for dialect ${this._dialect.name}`);\n        }\n\n        const valueKeys = options.updateOnDuplicate.map(attr => `${this.quoteIdentifier(attr)}=VALUES(${this.quoteIdentifier(attr)})`);\n        onDuplicateKeyUpdate = `${this._dialect.supports.inserts.updateOnDuplicate} ${valueKeys.join(',')}`;\n      }\n    }\n\n    const ignoreDuplicates = options.ignoreDuplicates ? this._dialect.supports.inserts.ignoreDuplicates : '';\n    const attributes = allAttributes.map(attr => this.quoteIdentifier(attr)).join(',');\n    const onConflictDoNothing = options.ignoreDuplicates ? this._dialect.supports.inserts.onConflictDoNothing : '';\n    let returning = '';\n\n    if (this._dialect.supports.returnValues && options.returning) {\n      const returnValues = this.generateReturnValues(fieldMappedAttributes, options);\n\n      returning += returnValues.returningFragment;\n    }\n\n    return Utils.joinSQLFragments([\n      'INSERT',\n      ignoreDuplicates,\n      'INTO',\n      this.quoteTable(tableName),\n      `(${attributes})`,\n      'VALUES',\n      tuples.join(','),\n      onDuplicateKeyUpdate,\n      onConflictDoNothing,\n      returning,\n      ';'\n    ]);\n  }\n\n  /**\n   * Returns an update query\n   *\n   * @param {string} tableName\n   * @param {object} attrValueHash\n   * @param {object} where A hash with conditions (e.g. {name: 'foo'}) OR an ID as integer\n   * @param {object} options\n   * @param {object} attributes\n   *\n   * @private\n   */\n  updateQuery(tableName, attrValueHash, where, options, attributes) {\n    options = options || {};\n    _.defaults(options, this.options);\n\n    attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, options.omitNull, options);\n\n    const values = [];\n    const bind = [];\n    const modelAttributeMap = {};\n    let outputFragment = '';\n    let tmpTable = ''; // tmpTable declaration for trigger\n    let suffix = '';\n\n    if (_.get(this, ['sequelize', 'options', 'dialectOptions', 'prependSearchPath']) || options.searchPath) {\n      // Not currently supported with search path (requires output of multiple queries)\n      options.bindParam = false;\n    }\n\n    const bindParam = options.bindParam === undefined ? this.bindParam(bind) : options.bindParam;\n\n    if (this._dialect.supports['LIMIT ON UPDATE'] && options.limit) {\n      if (!['mssql', 'db2', 'oracle'].includes(this.dialect)) {\n        suffix = ` LIMIT ${this.escape(options.limit)} `;\n      } else if (this.dialect === 'oracle') {\n        // This cannot be setted in where because rownum will be quoted\n        if (where && (where.length && where.length > 0 || Object.keys(where).length > 0)) {\n          // If we have a where clause, we add AND\n          suffix += ' AND ';\n        } else {\n          // No where clause, we add where\n          suffix += ' WHERE ';\n        }\n        suffix += `rownum <= ${this.escape(options.limit)} `;\n      }\n    }\n\n    if (this._dialect.supports.returnValues && options.returning) {\n      const returnValues = this.generateReturnValues(attributes, options);\n\n      suffix += returnValues.returningFragment;\n      tmpTable = returnValues.tmpTable || '';\n      outputFragment = returnValues.outputFragment || '';\n\n      // ensure that the return output is properly mapped to model fields.\n      if (!this._dialect.supports.returnValues.output && options.returning) {\n        options.mapToModel = true;\n      }\n    }\n\n    if (attributes) {\n      _.each(attributes, (attribute, key) => {\n        modelAttributeMap[key] = attribute;\n        if (attribute.field) {\n          modelAttributeMap[attribute.field] = attribute;\n        }\n      });\n    }\n\n    for (const key in attrValueHash) {\n      if (modelAttributeMap && modelAttributeMap[key] &&\n        modelAttributeMap[key].autoIncrement === true &&\n        !this._dialect.supports.autoIncrement.update) {\n        // not allowed to update identity column\n        continue;\n      }\n\n      const value = attrValueHash[key];\n\n      if (value instanceof Utils.SequelizeMethod || options.bindParam === false) {\n        values.push(`${this.quoteIdentifier(key)}=${this.escape(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'UPDATE' })}`);\n      } else {\n        values.push(`${this.quoteIdentifier(key)}=${this.format(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'UPDATE' }, bindParam)}`);\n      }\n    }\n\n    const whereOptions = { ...options, bindParam };\n\n    if (values.length === 0) {\n      return '';\n    }\n\n    const query = `${tmpTable}UPDATE ${this.quoteTable(tableName)} SET ${values.join(',')}${outputFragment} ${this.whereQuery(where, whereOptions)}${suffix}`.trim();\n    // Used by Postgres upsertQuery and calls to here with options.exception set to true\n    const result = { query };\n    if (options.bindParam !== false) {\n      result.bind = bind;\n    }\n    return result;\n  }\n\n  /**\n   * Returns an update query using arithmetic operator\n   *\n   * @param {string} operator                    String with the arithmetic operator (e.g. '+' or '-')\n   * @param {string} tableName                   Name of the table\n   * @param {object} where                       A plain-object with conditions (e.g. {name: 'foo'}) OR an ID as integer\n   * @param {object} incrementAmountsByField     A plain-object with attribute-value-pairs\n   * @param {object} extraAttributesToBeUpdated  A plain-object with attribute-value-pairs\n   * @param {object} options\n   *\n   * @private\n   */\n  arithmeticQuery(operator, tableName, where, incrementAmountsByField, extraAttributesToBeUpdated, options) {\n    options = options || {};\n    _.defaults(options, { returning: true });\n\n    extraAttributesToBeUpdated = Utils.removeNullValuesFromHash(extraAttributesToBeUpdated, this.options.omitNull);\n\n    let outputFragment = '';\n    let returningFragment = '';\n\n    if (this._dialect.supports.returnValues && options.returning) {\n      const returnValues = this.generateReturnValues(null, options);\n\n      outputFragment = returnValues.outputFragment;\n      returningFragment = returnValues.returningFragment;\n    }\n\n    const updateSetSqlFragments = [];\n    for (const field in incrementAmountsByField) {\n      const incrementAmount = incrementAmountsByField[field];\n      const quotedField = this.quoteIdentifier(field);\n      const escapedAmount = this.escape(incrementAmount);\n      updateSetSqlFragments.push(`${quotedField}=${quotedField}${operator} ${escapedAmount}`);\n    }\n    for (const field in extraAttributesToBeUpdated) {\n      const newValue = extraAttributesToBeUpdated[field];\n      const quotedField = this.quoteIdentifier(field);\n      const escapedValue = this.escape(newValue);\n      updateSetSqlFragments.push(`${quotedField}=${escapedValue}`);\n    }\n\n    return Utils.joinSQLFragments([\n      'UPDATE',\n      this.quoteTable(tableName),\n      'SET',\n      updateSetSqlFragments.join(','),\n      outputFragment,\n      this.whereQuery(where),\n      returningFragment\n    ]);\n  }\n\n  /*\n    Returns an add index query.\n    Parameters:\n      - tableName -> Name of an existing table, possibly with schema.\n      - options:\n        - type: UNIQUE|FULLTEXT|SPATIAL\n        - name: The name of the index. Default is <table>_<attr1>_<attr2>\n        - fields: An array of attributes as string or as hash.\n                  If the attribute is a hash, it must have the following content:\n                  - name: The name of the attribute/column\n                  - length: An integer. Optional\n                  - order: 'ASC' or 'DESC'. Optional\n        - parser\n        - using\n        - operator\n        - concurrently: Pass CONCURRENT so other operations run while the index is created\n      - rawTablename, the name of the table, without schema. Used to create the name of the index\n   @private\n  */\n  addIndexQuery(tableName, attributes, options, rawTablename) {\n    options = options || {};\n\n    if (!Array.isArray(attributes)) {\n      options = attributes;\n      attributes = undefined;\n    } else {\n      options.fields = attributes;\n    }\n\n    options.prefix = options.prefix || rawTablename || tableName;\n    if (options.prefix && typeof options.prefix === 'string') {\n      options.prefix = options.prefix.replace(/\\./g, '_');\n      options.prefix = options.prefix.replace(/(\"|')/g, '');\n    }\n\n    const fieldsSql = options.fields.map(field => {\n      if (field instanceof Utils.SequelizeMethod) {\n        return this.handleSequelizeMethod(field);\n      }\n      if (typeof field === 'string') {\n        field = {\n          name: field\n        };\n      }\n      let result = '';\n\n      if (field.attribute) {\n        field.name = field.attribute;\n      }\n\n      if (!field.name) {\n        throw new Error(`The following index field has no name: ${util.inspect(field)}`);\n      }\n\n      result += this.quoteIdentifier(field.name);\n\n      if (this._dialect.supports.index.collate && field.collate) {\n        result += ` COLLATE ${this.quoteIdentifier(field.collate)}`;\n      }\n\n      if (this._dialect.supports.index.operator) {\n        const operator = field.operator || options.operator;\n        if (operator) {\n          result += ` ${operator}`;\n        }\n      }\n\n      if (this._dialect.supports.index.length && field.length) {\n        result += `(${field.length})`;\n      }\n\n      if (field.order) {\n        result += ` ${field.order}`;\n      }\n\n      return result;\n    });\n\n    if (!options.name) {\n      // Mostly for cases where addIndex is called directly by the user without an options object (for example in migrations)\n      // All calls that go through sequelize should already have a name\n      options = Utils.nameIndex(options, options.prefix);\n    }\n\n    options = Model._conformIndex(options);\n\n    if (!this._dialect.supports.index.type) {\n      delete options.type;\n    }\n\n    if (options.where) {\n      options.where = this.whereQuery(options.where);\n    }\n\n    if (typeof tableName === 'string') {\n      tableName = this.quoteIdentifiers(tableName);\n    } else {\n      tableName = this.quoteTable(tableName);\n    }\n\n    const concurrently = this._dialect.supports.index.concurrently && options.concurrently ? 'CONCURRENTLY' : undefined;\n    let ind;\n    if (this._dialect.supports.indexViaAlter) {\n      ind = [\n        'ALTER TABLE',\n        tableName,\n        concurrently,\n        'ADD'\n      ];\n    } else {\n      ind = ['CREATE'];\n    }\n\n    ind = ind.concat(\n      options.unique ? 'UNIQUE' : '',\n      options.type, 'INDEX',\n      !this._dialect.supports.indexViaAlter ? concurrently : undefined,\n      this.quoteIdentifiers(options.name),\n      this._dialect.supports.index.using === 1 && options.using ? `USING ${options.using}` : '',\n      !this._dialect.supports.indexViaAlter ? `ON ${tableName}` : undefined,\n      this._dialect.supports.index.using === 2 && options.using ? `USING ${options.using}` : '',\n      `(${fieldsSql.join(', ')})`,\n      this._dialect.supports.index.parser && options.parser ? `WITH PARSER ${options.parser}` : undefined,\n      this._dialect.supports.index.where && options.where ? options.where : undefined\n    );\n\n    return _.compact(ind).join(' ');\n  }\n\n  addConstraintQuery(tableName, options) {\n    if (typeof tableName === 'string') {\n      tableName = this.quoteIdentifiers(tableName);\n    } else {\n      tableName = this.quoteTable(tableName);\n    }\n\n    return Utils.joinSQLFragments([\n      'ALTER TABLE',\n      tableName,\n      'ADD',\n      this.getConstraintSnippet(tableName, options || {}),\n      ';'\n    ]);\n  }\n\n  getConstraintSnippet(tableName, options) {\n    let constraintSnippet, constraintName;\n\n    const fieldsSql = options.fields.map(field => {\n      if (typeof field === 'string') {\n        return this.quoteIdentifier(field);\n      }\n      if (field instanceof Utils.SequelizeMethod) {\n        return this.handleSequelizeMethod(field);\n      }\n      if (field.attribute) {\n        field.name = field.attribute;\n      }\n\n      if (!field.name) {\n        throw new Error(`The following index field has no name: ${field}`);\n      }\n\n      return this.quoteIdentifier(field.name);\n    });\n\n    const fieldsSqlQuotedString = fieldsSql.join(', ');\n    const fieldsSqlString = fieldsSql.join('_');\n\n    switch (options.type.toUpperCase()) {\n      case 'UNIQUE':\n        constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_uk`);\n        constraintSnippet = `CONSTRAINT ${constraintName} UNIQUE (${fieldsSqlQuotedString})`;\n        break;\n      case 'CHECK':\n        options.where = this.whereItemsQuery(options.where);\n        constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_ck`);\n        constraintSnippet = `CONSTRAINT ${constraintName} CHECK (${options.where})`;\n        break;\n      case 'DEFAULT':\n        if (options.defaultValue === undefined) {\n          throw new Error('Default value must be specified for DEFAULT CONSTRAINT');\n        }\n\n        if (this._dialect.name !== 'mssql') {\n          throw new Error('Default constraints are supported only for MSSQL dialect.');\n        }\n\n        constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_df`);\n        constraintSnippet = `CONSTRAINT ${constraintName} DEFAULT (${this.escape(options.defaultValue)}) FOR ${fieldsSql[0]}`;\n        break;\n      case 'PRIMARY KEY':\n        constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_pk`);\n        constraintSnippet = `CONSTRAINT ${constraintName} PRIMARY KEY (${fieldsSqlQuotedString})`;\n        break;\n      case 'FOREIGN KEY':\n        const references = options.references;\n        if (!references || !references.table || !(references.field || references.fields)) {\n          throw new Error('references object with table and field must be specified');\n        }\n        constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_${references.table}_fk`);\n        const quotedReferences =\n          typeof references.field !== 'undefined'\n            ? this.quoteIdentifier(references.field)\n            : references.fields.map(f => this.quoteIdentifier(f)).join(', ');\n        const referencesSnippet = `${this.quoteTable(references.table)} (${quotedReferences})`;\n        constraintSnippet = `CONSTRAINT ${constraintName} `;\n        constraintSnippet += `FOREIGN KEY (${fieldsSqlQuotedString}) REFERENCES ${referencesSnippet}`;\n        if (options.onUpdate) {\n          constraintSnippet += ` ON UPDATE ${options.onUpdate.toUpperCase()}`;\n        }\n        if (options.onDelete) {\n          constraintSnippet += ` ON DELETE ${options.onDelete.toUpperCase()}`;\n        }\n        break;\n      default: throw new Error(`${options.type} is invalid.`);\n    }\n\n    if (options.deferrable && ['UNIQUE', 'PRIMARY KEY', 'FOREIGN KEY'].includes(options.type.toUpperCase())) {\n      constraintSnippet += ` ${this.deferConstraintsQuery(options)}`;\n    }\n\n    return constraintSnippet;\n  }\n\n  removeConstraintQuery(tableName, constraintName) {\n    if (typeof tableName === 'string') {\n      tableName = this.quoteIdentifiers(tableName);\n    } else {\n      tableName = this.quoteTable(tableName);\n    }\n\n    return Utils.joinSQLFragments([\n      'ALTER TABLE',\n      tableName,\n      'DROP CONSTRAINT',\n      this.quoteIdentifiers(constraintName)\n    ]);\n  }\n\n  /*\n    Quote an object based on its type. This is a more general version of quoteIdentifiers\n    Strings: should proxy to quoteIdentifiers\n    Arrays:\n      * Expects array in the form: [<model> (optional), <model> (optional),... String, String (optional)]\n        Each <model> can be a model, or an object {model: Model, as: String}, matching include, or an\n        association object, or the name of an association.\n      * Zero or more models can be included in the array and are used to trace a path through the tree of\n        included nested associations. This produces the correct table name for the ORDER BY/GROUP BY SQL\n        and quotes it.\n      * If a single string is appended to end of array, it is quoted.\n        If two strings appended, the 1st string is quoted, the 2nd string unquoted.\n    Objects:\n      * If raw is set, that value should be returned verbatim, without quoting\n      * If fn is set, the string should start with the value of fn, starting paren, followed by\n        the values of cols (which is assumed to be an array), quoted and joined with ', ',\n        unless they are themselves objects\n      * If direction is set, should be prepended\n\n    Currently this function is only used for ordering / grouping columns and Sequelize.col(), but it could\n    potentially also be used for other places where we want to be able to call SQL functions (e.g. as default values)\n   @private\n  */\n  quote(collection, parent, connector) {\n    // init\n    const validOrderOptions = [\n      'ASC',\n      'DESC',\n      'ASC NULLS LAST',\n      'DESC NULLS LAST',\n      'ASC NULLS FIRST',\n      'DESC NULLS FIRST',\n      'NULLS FIRST',\n      'NULLS LAST'\n    ];\n\n    // default\n    connector = connector || '.';\n\n    // just quote as identifiers if string\n    if (typeof collection === 'string') {\n      return this.quoteIdentifiers(collection);\n    }\n    if (Array.isArray(collection)) {\n      // iterate through the collection and mutate objects into associations\n      collection.forEach((item, index) => {\n        const previous = collection[index - 1];\n        let previousAssociation;\n        let previousModel;\n\n        // set the previous as the parent when previous is undefined or the target of the association\n        if (!previous && parent !== undefined) {\n          previousModel = parent;\n        } else if (previous && previous instanceof Association) {\n          previousAssociation = previous;\n          previousModel = previous.target;\n        }\n\n        // if the previous item is a model, then attempt getting an association\n        if (previousModel && previousModel.prototype instanceof Model) {\n          let model;\n          let as;\n\n          if (typeof item === 'function' && item.prototype instanceof Model) {\n            // set\n            model = item;\n          } else if (_.isPlainObject(item) && item.model && item.model.prototype instanceof Model) {\n            // set\n            model = item.model;\n            as = item.as;\n          }\n\n          if (model) {\n            // set the as to either the through name or the model name\n            if (!as && previousAssociation && previousAssociation instanceof Association && previousAssociation.through && previousAssociation.through.model === model) {\n              // get from previous association\n              item = new Association(previousModel, model, {\n                as: model.name\n              });\n            } else {\n              // get association from previous model\n              item = previousModel.getAssociationForAlias(model, as);\n\n              // attempt to use the model name if the item is still null\n              if (!item) {\n                item = previousModel.getAssociationForAlias(model, model.name);\n              }\n            }\n\n            // make sure we have an association\n            if (!(item instanceof Association)) {\n              throw new Error(util.format('Unable to find a valid association for model, \\'%s\\'', model.name));\n            }\n          }\n        }\n\n        if (typeof item === 'string') {\n          // get order index\n          const orderIndex = validOrderOptions.indexOf(item.toUpperCase());\n\n          // see if this is an order\n          if (index > 0 && orderIndex !== -1) {\n            item = this.sequelize.literal(` ${validOrderOptions[orderIndex]}`);\n          } else if (previousModel && previousModel.prototype instanceof Model) {\n            // only go down this path if we have preivous model and check only once\n            if (previousModel.associations !== undefined && previousModel.associations[item]) {\n              // convert the item to an association\n              item = previousModel.associations[item];\n            } else if (previousModel.rawAttributes !== undefined && previousModel.rawAttributes[item] && item !== previousModel.rawAttributes[item].field) {\n              // convert the item attribute from its alias\n              item = previousModel.rawAttributes[item].field;\n            } else if (\n              item.includes('.')\n              && previousModel.rawAttributes !== undefined\n            ) {\n              const itemSplit = item.split('.');\n\n              if (previousModel.rawAttributes[itemSplit[0]].type instanceof DataTypes.JSON) {\n                // just quote identifiers for now\n                const identifier = this.quoteIdentifiers(`${previousModel.name}.${previousModel.rawAttributes[itemSplit[0]].field}`);\n\n                // get path\n                const path = itemSplit.slice(1);\n\n                // extract path\n                item = this.jsonPathExtractionQuery(identifier, path);\n\n                // literal because we don't want to append the model name when string\n                item = this.sequelize.literal(item);\n              }\n            }\n          }\n        }\n\n        collection[index] = item;\n      }, this);\n\n      // loop through array, adding table names of models to quoted\n      const collectionLength = collection.length;\n      const tableNames = [];\n      let item;\n      let i = 0;\n\n      for (i = 0; i < collectionLength - 1; i++) {\n        item = collection[i];\n        if (typeof item === 'string' || item._modelAttribute || item instanceof Utils.SequelizeMethod) {\n          break;\n        } else if (item instanceof Association) {\n          tableNames[i] = item.as;\n        }\n      }\n\n      // start building sql\n      let sql = '';\n\n      if (i > 0) {\n        sql += `${this.quoteIdentifier(tableNames.join(connector))}.`;\n      } else if (typeof collection[0] === 'string' && parent) {\n        sql += `${this.quoteIdentifier(parent.name)}.`;\n      }\n\n      // loop through everything past i and append to the sql\n      collection.slice(i).forEach(collectionItem => {\n        sql += this.quote(collectionItem, parent, connector);\n      }, this);\n\n      return sql;\n    }\n    if (collection._modelAttribute) {\n      return `${this.quoteTable(collection.Model.name)}.${this.quoteIdentifier(collection.fieldName)}`;\n    }\n    if (collection instanceof Utils.SequelizeMethod) {\n      return this.handleSequelizeMethod(collection);\n    }\n    if (_.isPlainObject(collection) && collection.raw) {\n      // simple objects with raw is no longer supported\n      throw new Error('The `{raw: \"...\"}` syntax is no longer supported.  Use `sequelize.literal` instead.');\n    }\n    throw new Error(`Unknown structure passed to order / group: ${util.inspect(collection)}`);\n  }\n\n  _initQuoteIdentifier() {\n    this._quoteIdentifier = this.quoteIdentifier;\n    this.quoteIdentifier = function(identifier, force) {\n      if (identifier === '*') return identifier;\n      return this._quoteIdentifier(identifier, force);\n    };\n  }\n\n  /**\n   * Adds quotes to identifier\n   *\n   * @param {string} identifier\n   * @param {boolean} force\n   *\n   * @returns {string}\n   */\n  quoteIdentifier(identifier, force) {\n    throw new Error(`quoteIdentifier for Dialect \"${this.dialect}\" is not implemented`);\n  }\n\n  /**\n   * Split a list of identifiers by \".\" and quote each part.\n   *\n   * @param {string} identifiers\n   *\n   * @returns {string}\n   */\n  quoteIdentifiers(identifiers) {\n    if (identifiers.includes('.')) {\n      identifiers = identifiers.split('.');\n\n      const head = identifiers.slice(0, identifiers.length - 1).join('->');\n      const tail = identifiers[identifiers.length - 1];\n\n      return `${this.quoteIdentifier(head)}.${this.quoteIdentifier(tail)}`;\n    }\n\n    return this.quoteIdentifier(identifiers);\n  }\n\n  quoteAttribute(attribute, model) {\n    if (model && attribute in model.rawAttributes) {\n      return this.quoteIdentifier(attribute);\n    }\n    return this.quoteIdentifiers(attribute);\n  }\n\n  /**\n   * Returns the alias token\n   *\n   * @returns {string}\n   */\n  getAliasToken() {\n    return 'AS';\n  }\n\n  /**\n   * Quote table name with optional alias and schema attribution\n   *\n   * @param {string|object}  param table string or object\n   * @param {string|boolean} alias alias name\n   *\n   * @returns {string}\n   */\n  quoteTable(param, alias) {\n    let table = '';\n\n    if (alias === true) {\n      alias = param.as || param.name || param;\n    }\n\n    if (_.isObject(param)) {\n      if (this._dialect.supports.schemas) {\n        if (param.schema) {\n          table += `${this.quoteIdentifier(param.schema)}.`;\n        }\n\n        table += this.quoteIdentifier(param.tableName);\n      } else {\n        if (param.schema) {\n          table += param.schema + (param.delimiter || '.');\n        }\n\n        table += param.tableName;\n        table = this.quoteIdentifier(table);\n      }\n    } else {\n      table = this.quoteIdentifier(param);\n    }\n\n    if (alias) {\n      table += ` ${this.getAliasToken()} ${this.quoteIdentifier(alias)}`;\n    }\n\n    return table;\n  }\n\n  /*\n    Escape a value (e.g. a string, number or date)\n    @private\n  */\n  escape(value, field, options) {\n    options = options || {};\n\n    if (value !== null && value !== undefined) {\n      if (value instanceof Utils.SequelizeMethod) {\n        return this.handleSequelizeMethod(value);\n      }\n      if (field && field.type) {\n        if (field.type instanceof DataTypes.STRING\n            && ['mysql', 'mariadb'].includes(this.dialect)\n            && ['number', 'boolean'].includes(typeof value)) {\n          value = String(Number(value));\n        }\n              \n        this.validate(value, field, options);\n\n        if (field.type.stringify) {\n          // Users shouldn't have to worry about these args - just give them a function that takes a single arg\n          const simpleEscape = escVal => SqlString.escape(escVal, this.options.timezone, this.dialect);\n\n          value = field.type.stringify(value, { escape: simpleEscape, field, timezone: this.options.timezone, operation: options.operation });\n\n          if (field.type.escape === false) {\n            // The data-type already did the required escaping\n            return value;\n          }\n        }\n      }\n    }\n    return SqlString.escape(value, this.options.timezone, this.dialect);\n  }\n\n  bindParam(bind) {\n    return value => {\n      bind.push(value);\n      return `$${bind.length}`;\n    };\n  }\n\n  /*\n    Returns a bind parameter representation of a value (e.g. a string, number or date)\n    @private\n  */\n  format(value, field, options, bindParam) {\n    options = options || {};\n\n    if (value !== null && value !== undefined) {\n      if (value instanceof Utils.SequelizeMethod) {\n        throw new Error('Cannot pass SequelizeMethod as a bind parameter - use escape instead');\n      }\n      if (field && field.type) {\n        this.validate(value, field, options);\n\n        if (field.type.bindParam) {\n          return field.type.bindParam(value, { escape: _.identity, field, timezone: this.options.timezone, operation: options.operation, bindParam });\n        }\n      }\n    }\n\n    return bindParam(value);\n  }\n\n  /*\n    Validate a value against a field specification\n    @private\n  */\n  validate(value, field, options) {\n    if (this.typeValidation && field.type.validate && value) {\n      try {\n        if (options.isList && Array.isArray(value)) {\n          for (const item of value) {\n            field.type.validate(item, options);\n          }\n        } else {\n          field.type.validate(value, options);\n        }\n      } catch (error) {\n        if (error instanceof sequelizeError.ValidationError) {\n          error.errors.push(new sequelizeError.ValidationErrorItem(\n            error.message,\n            'Validation error',\n            field.fieldName,\n            value,\n            null,\n            `${field.type.key} validator`\n          ));\n        }\n\n        throw error;\n      }\n    }\n  }\n\n  isIdentifierQuoted(identifier) {\n    return /^\\s*(?:([`\"'])(?:(?!\\1).|\\1{2})*\\1\\.?)+\\s*$/i.test(identifier);\n  }\n\n  /**\n   * Generates an SQL query that extract JSON property of given path.\n   *\n   * @param   {string}               column   The JSON column\n   * @param   {string|Array<string>} [path]   The path to extract (optional)\n   * @param   {boolean}              [isJson] The value is JSON use alt symbols (optional)\n   * @returns {string}                        The generated sql query\n   * @private\n   */\n  jsonPathExtractionQuery(column, path, isJson) {\n    let paths = _.toPath(path);\n    let pathStr;\n    const quotedColumn = this.isIdentifierQuoted(column)\n      ? column\n      : this.quoteIdentifier(column);\n\n    switch (this.dialect) {\n      case 'mysql':\n      case 'mariadb':\n      case 'sqlite':\n        /**\n         * Non digit sub paths need to be quoted as ECMAScript identifiers\n         * https://bugs.mysql.com/bug.php?id=81896\n         */\n        if (this.dialect === 'mysql') {\n          paths = paths.map(subPath => {\n            return /\\D/.test(subPath)\n              ? Utils.addTicks(subPath, '\"')\n              : subPath;\n          });\n        }\n\n        pathStr = this.escape(['$']\n          .concat(paths)\n          .join('.')\n          .replace(/\\.(\\d+)(?:(?=\\.)|$)/g, (__, digit) => `[${digit}]`));\n\n        if (this.dialect === 'sqlite') {\n          return `json_extract(${quotedColumn},${pathStr})`;\n        }\n\n        return `json_unquote(json_extract(${quotedColumn},${pathStr}))`;\n\n      case 'postgres':\n        const join = isJson ? '#>' : '#>>';\n        pathStr = this.escape(`{${paths.join(',')}}`);\n        return `(${quotedColumn}${join}${pathStr})`;\n\n      default:\n        throw new Error(`Unsupported ${this.dialect} for JSON operations`);\n    }\n  }\n\n  /*\n    Returns a query for selecting elements in the table <tableName>.\n    Options:\n      - attributes -> An array of attributes (e.g. ['name', 'birthday']). Default: *\n      - where -> A hash with conditions (e.g. {name: 'foo'})\n                 OR an ID as integer\n      - order -> e.g. 'id DESC'\n      - group\n      - limit -> The maximum count you want to get.\n      - offset -> An offset value to start from. Only useable with limit!\n   @private\n  */\n  selectQuery(tableName, options, model) {\n    options = options || {};\n    const limit = options.limit;\n    const mainQueryItems = [];\n    const subQueryItems = [];\n    const subQuery = options.subQuery === undefined ? limit && options.hasMultiAssociation : options.subQuery;\n    const attributes = {\n      main: options.attributes && options.attributes.slice(),\n      subQuery: null\n    };\n    const mainTable = {\n      name: tableName,\n      quotedName: null,\n      as: null,\n      model\n    };\n    const topLevelInfo = {\n      names: mainTable,\n      options,\n      subQuery\n    };\n    let mainJoinQueries = [];\n    let subJoinQueries = [];\n    let query;\n\n    // Aliases can be passed through subqueries and we don't want to reset them\n    if (this.options.minifyAliases && !options.aliasesMapping) {\n      options.aliasesMapping = new Map();\n      options.aliasesByTable = {};\n      options.includeAliases = new Map();\n    }\n\n    // resolve table name options\n    if (options.tableAs) {\n      mainTable.as = this.quoteIdentifier(options.tableAs);\n    } else if (!Array.isArray(mainTable.name) && mainTable.model) {\n      mainTable.as = this.quoteIdentifier(mainTable.model.name);\n    }\n\n    mainTable.quotedName = !Array.isArray(mainTable.name) ? this.quoteTable(mainTable.name) : tableName.map(t => {\n      return Array.isArray(t) ? this.quoteTable(t[0], t[1]) : this.quoteTable(t, true);\n    }).join(', ');\n\n    if (subQuery && attributes.main) {\n      for (const keyAtt of mainTable.model.primaryKeyAttributes) {\n        // Check if mainAttributes contain the primary key of the model either as a field or an aliased field\n        if (!attributes.main.some(attr => keyAtt === attr || keyAtt === attr[0] || keyAtt === attr[1])) {\n          attributes.main.push(mainTable.model.rawAttributes[keyAtt].field ? [keyAtt, mainTable.model.rawAttributes[keyAtt].field] : keyAtt);\n        }\n      }\n    }\n\n    attributes.main = this.escapeAttributes(attributes.main, options, mainTable.as);\n    attributes.main = attributes.main || (options.include ? [`${mainTable.as}.*`] : ['*']);\n\n    // If subquery, we add the mainAttributes to the subQuery and set the mainAttributes to select * from subquery\n    if (subQuery || options.groupedLimit) {\n      // We need primary keys\n      attributes.subQuery = attributes.main;\n      attributes.main = [`${mainTable.as || mainTable.quotedName}.*`];\n    }\n\n    if (options.include) {\n      for (const include of options.include) {\n        if (include.separate) {\n          continue;\n        }\n        const joinQueries = this.generateInclude(include, { externalAs: mainTable.as, internalAs: mainTable.as }, topLevelInfo);\n\n        subJoinQueries = subJoinQueries.concat(joinQueries.subQuery);\n        mainJoinQueries = mainJoinQueries.concat(joinQueries.mainQuery);\n\n        if (joinQueries.attributes.main.length > 0) {\n          attributes.main = _.uniq(attributes.main.concat(joinQueries.attributes.main));\n        }\n        if (joinQueries.attributes.subQuery.length > 0) {\n          attributes.subQuery = _.uniq(attributes.subQuery.concat(joinQueries.attributes.subQuery));\n        }\n      }\n    }\n\n    if (subQuery) {\n      subQueryItems.push(this.selectFromTableFragment(options, mainTable.model, attributes.subQuery, mainTable.quotedName, mainTable.as));\n      subQueryItems.push(subJoinQueries.join(''));\n    } else {\n      if (options.groupedLimit) {\n        if (!mainTable.as) {\n          mainTable.as = mainTable.quotedName;\n        }\n        const where = { ...options.where };\n        let groupedLimitOrder,\n          whereKey,\n          include,\n          groupedTableName = mainTable.as;\n\n        if (typeof options.groupedLimit.on === 'string') {\n          whereKey = options.groupedLimit.on;\n        } else if (options.groupedLimit.on instanceof HasMany) {\n          whereKey = options.groupedLimit.on.foreignKeyField;\n        }\n\n        if (options.groupedLimit.on instanceof BelongsToMany) {\n          // BTM includes needs to join the through table on to check ID\n          groupedTableName = options.groupedLimit.on.manyFromSource.as;\n          const groupedLimitOptions = Model._validateIncludedElements({\n            include: [{\n              association: options.groupedLimit.on.manyFromSource,\n              duplicating: false, // The UNION'ed query may contain duplicates, but each sub-query cannot\n              required: true,\n              where: {\n                [Op.placeholder]: true,\n                ...options.groupedLimit.through && options.groupedLimit.through.where\n              }\n            }],\n            model\n          });\n\n          // Make sure attributes from the join table are mapped back to models\n          options.hasJoin = true;\n          options.hasMultiAssociation = true;\n          options.includeMap = Object.assign(groupedLimitOptions.includeMap, options.includeMap);\n          options.includeNames = groupedLimitOptions.includeNames.concat(options.includeNames || []);\n          include = groupedLimitOptions.include;\n\n          if (Array.isArray(options.order)) {\n            // We need to make sure the order by attributes are available to the parent query\n            options.order.forEach((order, i) => {\n              if (Array.isArray(order)) {\n                order = order[0];\n              }\n\n              let alias = `subquery_order_${i}`;\n              options.attributes.push([order, alias]);\n\n              // We don't want to prepend model name when we alias the attributes, so quote them here\n              alias = this.sequelize.literal(this.quote(alias));\n\n              if (Array.isArray(options.order[i])) {\n                options.order[i][0] = alias;\n              } else {\n                options.order[i] = alias;\n              }\n            });\n            groupedLimitOrder = options.order;\n          }\n        } else {\n          // Ordering is handled by the subqueries, so ordering the UNION'ed result is not needed\n          groupedLimitOrder = options.order;\n\n          // For the Oracle dialect, the result of a select is a set, not a sequence, and so is the result of UNION.\n          // So the top level ORDER BY is required\n          if (!this._dialect.supports.topLevelOrderByRequired) {\n            delete options.order;\n          }\n          where[Op.placeholder] = true;\n        }\n\n        // Caching the base query and splicing the where part into it is consistently > twice\n        // as fast than generating from scratch each time for values.length >= 5\n        const baseQuery = `SELECT * FROM (${this.selectQuery(\n          tableName,\n          {\n            attributes: options.attributes,\n            offset: options.offset,\n            limit: options.groupedLimit.limit,\n            order: groupedLimitOrder,\n            aliasesMapping: options.aliasesMapping,\n            aliasesByTable: options.aliasesByTable,\n            where,\n            include,\n            model\n          },\n          model\n        ).replace(/;$/, '')}) ${this.getAliasToken()} sub`; // Every derived table must have its own alias\n        const placeHolder = this.whereItemQuery(Op.placeholder, true, { model });\n        const splicePos = baseQuery.indexOf(placeHolder);\n\n        mainQueryItems.push(this.selectFromTableFragment(options, mainTable.model, attributes.main, `(${\n          options.groupedLimit.values.map(value => {\n            let groupWhere;\n            if (whereKey) {\n              groupWhere = {\n                [whereKey]: value\n              };\n            }\n            if (include) {\n              groupWhere = {\n                [options.groupedLimit.on.foreignIdentifierField]: value\n              };\n            }\n\n            return Utils.spliceStr(baseQuery, splicePos, placeHolder.length, this.getWhereConditions(groupWhere, groupedTableName));\n          }).join(\n            this._dialect.supports['UNION ALL'] ? ' UNION ALL ' : ' UNION '\n          )\n        })`, mainTable.as));\n      } else {\n        mainQueryItems.push(this.selectFromTableFragment(options, mainTable.model, attributes.main, mainTable.quotedName, mainTable.as));\n      }\n\n      mainQueryItems.push(mainJoinQueries.join(''));\n    }\n\n    // Add WHERE to sub or main query\n    if (Object.prototype.hasOwnProperty.call(options, 'where') && !options.groupedLimit) {\n      options.where = this.getWhereConditions(options.where, mainTable.as || tableName, model, options);\n      if (options.where) {\n        if (subQuery) {\n          subQueryItems.push(` WHERE ${options.where}`);\n        } else {\n          mainQueryItems.push(` WHERE ${options.where}`);\n          // Walk the main query to update all selects\n          mainQueryItems.forEach((value, key) => {\n            if (value.startsWith('SELECT')) {\n              mainQueryItems[key] = this.selectFromTableFragment(options, model, attributes.main, mainTable.quotedName, mainTable.as, options.where);\n            }\n          });\n        }\n      }\n    }\n\n    // Add GROUP BY to sub or main query\n    if (options.group) {\n      options.group = Array.isArray(options.group) ? options.group.map(t => this.aliasGrouping(t, model, mainTable.as, options)).join(', ') : this.aliasGrouping(options.group, model, mainTable.as, options);\n\n      if (subQuery && options.group) {\n        subQueryItems.push(` GROUP BY ${options.group}`);\n      } else if (options.group) {\n        mainQueryItems.push(` GROUP BY ${options.group}`);\n      }\n    }\n\n    // Add HAVING to sub or main query\n    if (Object.prototype.hasOwnProperty.call(options, 'having')) {\n      options.having = this.getWhereConditions(options.having, tableName, model, options, false);\n      if (options.having) {\n        if (subQuery) {\n          subQueryItems.push(` HAVING ${options.having}`);\n        } else {\n          mainQueryItems.push(` HAVING ${options.having}`);\n        }\n      }\n    }\n\n    // Add ORDER to sub or main query\n    if (options.order) {\n      const orders = this.getQueryOrders(options, model, subQuery);\n      if (orders.mainQueryOrder.length) {\n        mainQueryItems.push(` ORDER BY ${orders.mainQueryOrder.join(', ')}`);\n      }\n      if (orders.subQueryOrder.length) {\n        subQueryItems.push(` ORDER BY ${orders.subQueryOrder.join(', ')}`);\n      }\n    }\n\n    // Add LIMIT, OFFSET to sub or main query\n    const limitOrder = this.addLimitAndOffset(options, mainTable.model);\n    if (limitOrder && !options.groupedLimit) {\n      if (subQuery) {\n        subQueryItems.push(limitOrder);\n      } else {\n        mainQueryItems.push(limitOrder);\n      }\n    }\n\n    if (subQuery) {\n      this._throwOnEmptyAttributes(attributes.main, { modelName: model && model.name, as: mainTable.as });\n      query = `SELECT ${attributes.main.join(', ')} FROM (${subQueryItems.join('')}) ${this.getAliasToken()} ${mainTable.as}${mainJoinQueries.join('')}${mainQueryItems.join('')}`;\n    } else {\n      query = mainQueryItems.join('');\n    }\n\n    if (options.lock && this._dialect.supports.lock) {\n      let lock = options.lock;\n      if (typeof options.lock === 'object') {\n        lock = options.lock.level;\n      }\n      if (this._dialect.supports.lockKey && ['KEY SHARE', 'NO KEY UPDATE'].includes(lock)) {\n        query += ` FOR ${lock}`;\n      } else if (lock === 'SHARE') {\n        query += ` ${this._dialect.supports.forShare}`;\n      } else {\n        query += ' FOR UPDATE';\n      }\n      if (this._dialect.supports.lockOf && options.lock.of && options.lock.of.prototype instanceof Model) {\n        query += ` OF ${this.quoteTable(options.lock.of.name)}`;\n      }\n      if (this._dialect.supports.skipLocked && options.skipLocked) {\n        query += ' SKIP LOCKED';\n      }\n    }\n\n    return `${query};`;\n  }\n\n  aliasGrouping(field, model, tableName, options) {\n    const src = Array.isArray(field) ? field[0] : field;\n\n    return this.quote(this._getAliasForField(tableName, src, options) || src, model);\n  }\n\n  escapeAttributes(attributes, options, mainTableAs) {\n    return attributes && attributes.map(attr => {\n      let addTable = true;\n\n      if (attr instanceof Utils.SequelizeMethod) {\n        return this.handleSequelizeMethod(attr);\n      }\n      if (Array.isArray(attr)) {\n        if (attr.length !== 2) {\n          throw new Error(`${JSON.stringify(attr)} is not a valid attribute definition. Please use the following format: ['attribute definition', 'alias']`);\n        }\n        attr = attr.slice();\n\n        if (attr[0] instanceof Utils.SequelizeMethod) {\n          attr[0] = this.handleSequelizeMethod(attr[0]);\n          addTable = false;\n        } else if (this.options.attributeBehavior === 'escape' || !attr[0].includes('(') && !attr[0].includes(')')) {\n          attr[0] = this.quoteIdentifier(attr[0]);\n        } else if (this.options.attributeBehavior !== 'unsafe-legacy') {\n          throw new Error(`Attributes cannot include parentheses in Sequelize 6:\nIn order to fix the vulnerability CVE-2023-22578, we had to remove support for treating attributes as raw SQL if they included parentheses.\nSequelize 7 escapes all attributes, even if they include parentheses.\nFor Sequelize 6, because we're introducing this change in a minor release, we've opted for throwing an error instead of silently escaping the attribute as a way to warn you about this change.\n\nHere is what you can do to fix this error:\n- Wrap the attribute in a literal() call. This will make Sequelize treat it as raw SQL.\n- Set the \"attributeBehavior\" sequelize option to \"escape\" to make Sequelize escape the attribute, like in Sequelize v7. We highly recommend this option.\n- Set the \"attributeBehavior\" sequelize option to \"unsafe-legacy\" to make Sequelize escape the attribute, like in Sequelize v5.\n\nWe sincerely apologize for the inconvenience this may cause you. You can find more information on the following threads:\nhttps://github.com/sequelize/sequelize/security/advisories/GHSA-f598-mfpv-gmfx\nhttps://github.com/sequelize/sequelize/discussions/15694`);\n        }\n\n        let alias = attr[1];\n\n        if (this.options.minifyAliases) {\n          alias = this._getMinifiedAlias(alias, mainTableAs, options);\n        }\n\n        attr = [attr[0], this.quoteIdentifier(alias)].join(' AS ');\n      } else {\n        attr = !attr.includes(Utils.TICK_CHAR) && !attr.includes('\"')\n          ? this.quoteAttribute(attr, options.model)\n          : this.escape(attr);\n      }\n      if (!_.isEmpty(options.include) && (!attr.includes('.') || options.dotNotation) && addTable) {\n        attr = `${mainTableAs}.${attr}`;\n      }\n\n      return attr;\n    });\n  }\n\n  generateInclude(include, parentTableName, topLevelInfo) {\n    const joinQueries = {\n      mainQuery: [],\n      subQuery: []\n    };\n    const mainChildIncludes = [];\n    const subChildIncludes = [];\n    let requiredMismatch = false;\n    const includeAs = {\n      internalAs: include.as,\n      externalAs: include.as\n    };\n    const attributes = {\n      main: [],\n      subQuery: []\n    };\n    let joinQuery;\n\n    topLevelInfo.options.keysEscaped = true;\n\n    if (topLevelInfo.names.name !== parentTableName.externalAs && topLevelInfo.names.as !== parentTableName.externalAs) {\n      includeAs.internalAs = `${parentTableName.internalAs}->${include.as}`;\n      includeAs.externalAs = `${parentTableName.externalAs}.${include.as}`;\n    }\n\n    // includeIgnoreAttributes is used by aggregate functions\n    if (topLevelInfo.options.includeIgnoreAttributes !== false) {\n      include.model._expandAttributes(include);\n      Utils.mapFinderOptions(include, include.model);\n\n      const includeAttributes = include.attributes.map(attr => {\n        let attrAs = attr;\n        let verbatim = false;\n\n        if (Array.isArray(attr) && attr.length === 2) {\n          if (attr[0] instanceof Utils.SequelizeMethod && (\n            attr[0] instanceof Utils.Literal ||\n            attr[0] instanceof Utils.Cast ||\n            attr[0] instanceof Utils.Fn\n          )) {\n            verbatim = true;\n          }\n\n          attr = attr.map(attr => attr instanceof Utils.SequelizeMethod ? this.handleSequelizeMethod(attr) : attr);\n\n          attrAs = attr[1];\n          attr = attr[0];\n        }\n        if (attr instanceof Utils.Literal) {\n          return attr.val; // We trust the user to rename the field correctly\n        }\n        if (attr instanceof Utils.Cast || attr instanceof Utils.Fn) {\n          throw new Error(\n            'Tried to select attributes using Sequelize.cast or Sequelize.fn without specifying an alias for the result, during eager loading. ' +\n            'This means the attribute will not be added to the returned instance'\n          );\n        }\n\n        let prefix;\n        if (verbatim === true) {\n          prefix = attr;\n        } else if (/#>>|->>/.test(attr)) {\n          prefix = `(${this.quoteIdentifier(includeAs.internalAs)}.${attr.replace(/\\(|\\)/g, '')})`;\n        } else if (/json_extract\\(/.test(attr)) {\n          prefix = attr.replace(/json_extract\\(/i, `json_extract(${this.quoteIdentifier(includeAs.internalAs)}.`);\n        } else if (/json_value\\(/.test(attr)) {\n          prefix = attr.replace(/json_value\\(/i, `json_value(${this.quoteIdentifier(includeAs.internalAs)}.`);\n        } else {\n          prefix = `${this.quoteIdentifier(includeAs.internalAs)}.${this.quoteIdentifier(attr)}`;\n        }\n        let alias = `${includeAs.externalAs}.${attrAs}`;\n\n        if (this.options.minifyAliases) {\n          alias = this._getMinifiedAlias(alias, includeAs.internalAs, topLevelInfo.options);\n        }\n\n        return Utils.joinSQLFragments([\n          prefix,\n          'AS',\n          this.quoteIdentifier(alias, true)\n        ]);\n      });\n      if (include.subQuery && topLevelInfo.subQuery) {\n        for (const attr of includeAttributes) {\n          attributes.subQuery.push(attr);\n        }\n      } else {\n        for (const attr of includeAttributes) {\n          attributes.main.push(attr);\n        }\n      }\n    }\n\n    //through\n    if (include.through) {\n      joinQuery = this.generateThroughJoin(include, includeAs, parentTableName.internalAs, topLevelInfo);\n    } else {\n      this._generateSubQueryFilter(include, includeAs, topLevelInfo);\n      joinQuery = this.generateJoin(include, topLevelInfo);\n    }\n\n    // handle possible new attributes created in join\n    if (joinQuery.attributes.main.length > 0) {\n      attributes.main = attributes.main.concat(joinQuery.attributes.main);\n    }\n\n    if (joinQuery.attributes.subQuery.length > 0) {\n      attributes.subQuery = attributes.subQuery.concat(joinQuery.attributes.subQuery);\n    }\n\n    if (include.include) {\n      for (const childInclude of include.include) {\n        if (childInclude.separate || childInclude._pseudo) {\n          continue;\n        }\n\n        const childJoinQueries = this.generateInclude(childInclude, includeAs, topLevelInfo);\n\n        if (include.required === false && childInclude.required === true) {\n          requiredMismatch = true;\n        }\n        // if the child is a sub query we just give it to the\n        if (childInclude.subQuery && topLevelInfo.subQuery) {\n          subChildIncludes.push(childJoinQueries.subQuery);\n        }\n        if (childJoinQueries.mainQuery) {\n          mainChildIncludes.push(childJoinQueries.mainQuery);\n        }\n        if (childJoinQueries.attributes.main.length > 0) {\n          attributes.main = attributes.main.concat(childJoinQueries.attributes.main);\n        }\n        if (childJoinQueries.attributes.subQuery.length > 0) {\n          attributes.subQuery = attributes.subQuery.concat(childJoinQueries.attributes.subQuery);\n        }\n      }\n    }\n\n    if (include.subQuery && topLevelInfo.subQuery) {\n      if (requiredMismatch && subChildIncludes.length > 0) {\n        joinQueries.subQuery.push(` ${joinQuery.join} ( ${joinQuery.body}${subChildIncludes.join('')} ) ON ${joinQuery.condition}`);\n      } else {\n        joinQueries.subQuery.push(` ${joinQuery.join} ${joinQuery.body} ON ${joinQuery.condition}`);\n        if (subChildIncludes.length > 0) {\n          joinQueries.subQuery.push(subChildIncludes.join(''));\n        }\n      }\n      joinQueries.mainQuery.push(mainChildIncludes.join(''));\n    } else {\n      if (requiredMismatch && mainChildIncludes.length > 0) {\n        joinQueries.mainQuery.push(` ${joinQuery.join} ( ${joinQuery.body}${mainChildIncludes.join('')} ) ON ${joinQuery.condition}`);\n      } else {\n        joinQueries.mainQuery.push(` ${joinQuery.join} ${joinQuery.body} ON ${joinQuery.condition}`);\n        if (mainChildIncludes.length > 0) {\n          joinQueries.mainQuery.push(mainChildIncludes.join(''));\n        }\n      }\n      joinQueries.subQuery.push(subChildIncludes.join(''));\n    }\n\n    return {\n      mainQuery: joinQueries.mainQuery.join(''),\n      subQuery: joinQueries.subQuery.join(''),\n      attributes\n    };\n  }\n\n  _getMinifiedAlias(alias, tableName, options) {\n    // We do not want to re-alias in case of a subquery\n    if (options.aliasesByTable[`${tableName}${alias}`]) {\n      return options.aliasesByTable[`${tableName}${alias}`];\n    }\n\n    // Do not alias custom suquery_orders\n    if (alias.match(/subquery_order_[0-9]/)) {\n      return alias;\n    }\n\n    const minifiedAlias = `_${options.aliasesMapping.size}`;\n\n    options.aliasesMapping.set(minifiedAlias, alias);\n    options.aliasesByTable[`${tableName}${alias}`] = minifiedAlias;\n\n    return minifiedAlias;\n  }\n\n  _getAliasForField(tableName, field, options) {\n    if (this.options.minifyAliases) {\n      if (options.aliasesByTable[`${tableName}${field}`]) {\n        return options.aliasesByTable[`${tableName}${field}`];\n      }\n    }\n    return null;\n  }\n\n  generateJoin(include, topLevelInfo) {\n    const association = include.association;\n    const parent = include.parent;\n    const parentIsTop = !!parent && !include.parent.association && include.parent.model.name === topLevelInfo.options.model.name;\n    let $parent;\n    let joinWhere;\n    /* Attributes for the left side */\n    const left = association.source;\n    const attrLeft = association instanceof BelongsTo ?\n      association.identifier :\n      association.sourceKeyAttribute || left.primaryKeyAttribute;\n    const fieldLeft = association instanceof BelongsTo ?\n      association.identifierField :\n      left.rawAttributes[association.sourceKeyAttribute || left.primaryKeyAttribute].field;\n    let asLeft;\n    /* Attributes for the right side */\n    const right = include.model;\n    const tableRight = right.getTableName();\n    const fieldRight = association instanceof BelongsTo ?\n      right.rawAttributes[association.targetIdentifier || right.primaryKeyAttribute].field :\n      association.identifierField;\n    let asRight = include.as;\n\n    while (($parent = $parent && $parent.parent || include.parent) && $parent.association) {\n      if (asLeft) {\n        asLeft = `${$parent.as}->${asLeft}`;\n      } else {\n        asLeft = $parent.as;\n      }\n    }\n\n    if (!asLeft) asLeft = parent.as || parent.model.name;\n    else asRight = `${asLeft}->${asRight}`;\n\n    let joinOn = `${this.quoteTable(asLeft)}.${this.quoteIdentifier(fieldLeft)}`;\n    const subqueryAttributes = [];\n\n    if (topLevelInfo.options.groupedLimit && parentIsTop || topLevelInfo.subQuery && include.parent.subQuery && !include.subQuery) {\n      if (parentIsTop) {\n        // The main model attributes is not aliased to a prefix\n        const tableName = this.quoteTable(parent.as || parent.model.name);\n\n        // Check for potential aliased JOIN condition\n        joinOn = this._getAliasForField(tableName, attrLeft, topLevelInfo.options) || `${tableName}.${this.quoteIdentifier(attrLeft)}`;\n\n        if (topLevelInfo.subQuery) {\n          const dbIdentifier = `${tableName}.${this.quoteIdentifier(fieldLeft)}`;\n          subqueryAttributes.push(dbIdentifier !== joinOn ? `${dbIdentifier} AS ${this.quoteIdentifier(attrLeft)}` : dbIdentifier);\n        }\n      } else {\n        const joinSource = `${asLeft.replace(/->/g, '.')}.${attrLeft}`;\n\n        // Check for potential aliased JOIN condition\n        joinOn = this._getAliasForField(asLeft, joinSource, topLevelInfo.options) || this.quoteIdentifier(joinSource);\n      }\n    }\n\n    joinOn += ` = ${this.quoteIdentifier(asRight)}.${this.quoteIdentifier(fieldRight)}`;\n\n    if (include.on) {\n      joinOn = this.whereItemsQuery(include.on, {\n        prefix: this.sequelize.literal(this.quoteIdentifier(asRight)),\n        model: include.model\n      });\n    }\n\n    if (include.where) {\n      joinWhere = this.whereItemsQuery(include.where, {\n        prefix: this.sequelize.literal(this.quoteIdentifier(asRight)),\n        model: include.model\n      });\n      if (joinWhere) {\n        if (include.or) {\n          joinOn += ` OR ${joinWhere}`;\n        } else {\n          joinOn += ` AND ${joinWhere}`;\n        }\n      }\n    }\n\n    this.aliasAs(asRight, topLevelInfo);\n\n    return {\n      join: include.required ? 'INNER JOIN' : include.right && this._dialect.supports['RIGHT JOIN'] ? 'RIGHT OUTER JOIN' : 'LEFT OUTER JOIN',\n      body: this.quoteTable(tableRight, asRight),\n      condition: joinOn,\n      attributes: {\n        main: [],\n        subQuery: subqueryAttributes\n      }\n    };\n  }\n\n  /**\n   * Returns the SQL fragments to handle returning the attributes from an insert/update query.\n   *\n   * @param  {object} modelAttributes An object with the model attributes.\n   * @param  {object} options         An object with options.\n   *\n   * @private\n   */\n  generateReturnValues(modelAttributes, options) {\n    const returnFields = [];\n    const returnTypes = [];\n    let outputFragment = '';\n    let returningFragment = '';\n    let tmpTable = '';\n\n    if (Array.isArray(options.returning)) {\n      returnFields.push(...options.returning.map(field => this.quoteIdentifier(field)));\n    } else if (modelAttributes) {\n      _.each(modelAttributes, attribute => {\n        if (!(attribute.type instanceof DataTypes.VIRTUAL)) {\n          returnFields.push(this.quoteIdentifier(attribute.field));\n          returnTypes.push(attribute.type);\n        }\n      });\n    }\n\n    if (_.isEmpty(returnFields)) {\n      returnFields.push('*');\n    }\n\n    if (this._dialect.supports.returnValues.returning) {\n      returningFragment = ` RETURNING ${returnFields.join(',')}`;\n    } else if (this._dialect.supports.returnIntoValues) {\n      returningFragment = ` RETURNING ${returnFields.join(',')} INTO `;\n    } else if (this._dialect.supports.returnValues.output) {\n      outputFragment = ` OUTPUT ${returnFields.map(field => `INSERTED.${field}`).join(',')}`;\n\n      //To capture output rows when there is a trigger on MSSQL DB\n      if (options.hasTrigger && this._dialect.supports.tmpTableTrigger) {\n        const tmpColumns = returnFields.map((field, i) => `${field} ${returnTypes[i].toSql()}`);\n\n        tmpTable = `DECLARE @tmp TABLE (${tmpColumns.join(',')}); `;\n        outputFragment += ' INTO @tmp';\n        returningFragment = '; SELECT * FROM @tmp';\n      }\n    }\n\n    return { outputFragment, returnFields, returnTypes, returningFragment, tmpTable };\n  }\n\n  generateThroughJoin(include, includeAs, parentTableName, topLevelInfo) {\n    const through = include.through;\n    const throughTable = through.model.getTableName();\n    const throughAs = `${includeAs.internalAs}->${through.as}`;\n    const externalThroughAs = `${includeAs.externalAs}.${through.as}`;\n    const throughAttributes = through.attributes.map(attr => {\n      let alias = `${externalThroughAs}.${Array.isArray(attr) ? attr[1] : attr}`;\n\n      if (this.options.minifyAliases) {\n        alias = this._getMinifiedAlias(alias, throughAs, topLevelInfo.options);\n      }\n\n      return Utils.joinSQLFragments([\n        `${this.quoteIdentifier(throughAs)}.${this.quoteIdentifier(Array.isArray(attr) ? attr[0] : attr)}`,\n        'AS',\n        this.quoteIdentifier(alias)\n      ]);\n    });\n    const association = include.association;\n    const parentIsTop = !include.parent.association && include.parent.model.name === topLevelInfo.options.model.name;\n    const tableSource = parentTableName;\n    const identSource = association.identifierField;\n    const tableTarget = includeAs.internalAs;\n    const identTarget = association.foreignIdentifierField;\n    const attrTarget = association.targetKeyField;\n\n    const joinType = include.required ? 'INNER JOIN' : include.right && this._dialect.supports['RIGHT JOIN'] ? 'RIGHT OUTER JOIN' : 'LEFT OUTER JOIN';\n    let joinBody;\n    let joinCondition;\n    const attributes = {\n      main: [],\n      subQuery: []\n    };\n    let attrSource = association.sourceKey;\n    let sourceJoinOn;\n    let targetJoinOn;\n    let throughWhere;\n    let targetWhere;\n\n    if (topLevelInfo.options.includeIgnoreAttributes !== false) {\n      // Through includes are always hasMany, so we need to add the attributes to the mainAttributes no matter what (Real join will never be executed in subquery)\n      for (const attr of throughAttributes) {\n        attributes.main.push(attr);\n      }\n    }\n\n    // Figure out if we need to use field or attribute\n    if (!topLevelInfo.subQuery) {\n      attrSource = association.sourceKeyField;\n    }\n    if (topLevelInfo.subQuery && !include.subQuery && !include.parent.subQuery && include.parent.model !== topLevelInfo.options.mainModel) {\n      attrSource = association.sourceKeyField;\n    }\n\n    // Filter statement for left side of through\n    // Used by both join and subquery where\n    // If parent include was in a subquery need to join on the aliased attribute\n    if (topLevelInfo.subQuery && !include.subQuery && include.parent.subQuery && !parentIsTop) {\n      // If we are minifying aliases and our JOIN target has been minified, we need to use the alias instead of the original column name\n      const joinSource = this._getAliasForField(tableSource, `${tableSource}.${attrSource}`, topLevelInfo.options) || `${tableSource}.${attrSource}`;\n\n      sourceJoinOn = `${this.quoteIdentifier(joinSource)} = `;\n    } else {\n      // If we are minifying aliases and our JOIN target has been minified, we need to use the alias instead of the original column name\n      const aliasedSource = this._getAliasForField(tableSource, attrSource, topLevelInfo.options) || attrSource;\n\n      sourceJoinOn = `${this.quoteTable(tableSource)}.${this.quoteIdentifier(aliasedSource)} = `;\n    }\n    sourceJoinOn += `${this.quoteIdentifier(throughAs)}.${this.quoteIdentifier(identSource)}`;\n\n    // Filter statement for right side of through\n    // Used by both join and subquery where\n    targetJoinOn = `${this.quoteIdentifier(tableTarget)}.${this.quoteIdentifier(attrTarget)} = `;\n    targetJoinOn += `${this.quoteIdentifier(throughAs)}.${this.quoteIdentifier(identTarget)}`;\n\n    if (through.where) {\n      throughWhere = this.getWhereConditions(through.where, this.sequelize.literal(this.quoteIdentifier(throughAs)), through.model);\n    }\n\n    this.aliasAs(includeAs.internalAs, topLevelInfo);\n\n    // Generate a wrapped join so that the through table join can be dependent on the target join\n    joinBody = `( ${this.quoteTable(throughTable, throughAs)} INNER JOIN ${this.quoteTable(include.model.getTableName(), includeAs.internalAs)} ON ${targetJoinOn}`;\n    if (throughWhere) {\n      joinBody += ` AND ${throughWhere}`;\n    }\n    joinBody += ')';\n    joinCondition = sourceJoinOn;\n\n    if (include.where || include.through.where) {\n      if (include.where) {\n        targetWhere = this.getWhereConditions(include.where, this.sequelize.literal(this.quoteIdentifier(includeAs.internalAs)), include.model, topLevelInfo.options);\n        if (targetWhere) {\n          joinCondition += ` AND ${targetWhere}`;\n        }\n      }\n    }\n\n    this._generateSubQueryFilter(include, includeAs, topLevelInfo);\n\n    return {\n      join: joinType,\n      body: joinBody,\n      condition: joinCondition,\n      attributes\n    };\n  }\n\n  /*\n   * Appends to the alias cache if the alias 64+ characters long and minifyAliases is true.\n   * This helps to avoid character limits in PostgreSQL.\n   */\n  aliasAs(as, topLevelInfo) {\n    if (this.options.minifyAliases && as.length >= 64) {\n      const alias = `%${topLevelInfo.options.includeAliases.size}`;\n\n      topLevelInfo.options.includeAliases.set(alias, as);\n    }\n  }\n\n  /*\n   * Generates subQueryFilter - a select nested in the where clause of the subQuery.\n   * For a given include a query is generated that contains all the way from the subQuery\n   * table to the include table plus everything that's in required transitive closure of the\n   * given include.\n   */\n  _generateSubQueryFilter(include, includeAs, topLevelInfo) {\n    if (!topLevelInfo.subQuery || !include.subQueryFilter) {\n      return;\n    }\n\n    if (!topLevelInfo.options.where) {\n      topLevelInfo.options.where = {};\n    }\n    let parent = include;\n    let child = include;\n    let nestedIncludes = this._getRequiredClosure(include).include;\n    let query;\n\n    while ((parent = parent.parent)) { // eslint-disable-line\n      if (parent.parent && !parent.required) {\n        return; // only generate subQueryFilter if all the parents of this include are required\n      }\n\n      if (parent.subQueryFilter) {\n        // the include is already handled as this parent has the include on its required closure\n        // skip to prevent duplicate subQueryFilter\n        return;\n      }\n\n      nestedIncludes = [{ ...child, include: nestedIncludes, attributes: [] }];\n      child = parent;\n    }\n\n    const topInclude = nestedIncludes[0];\n    const topParent = topInclude.parent;\n    const topAssociation = topInclude.association;\n    topInclude.association = undefined;\n\n    if (topInclude.through && Object(topInclude.through.model) === topInclude.through.model) {\n      query = this.selectQuery(topInclude.through.model.getTableName(), {\n        attributes: [topInclude.through.model.primaryKeyField],\n        include: Model._validateIncludedElements({\n          model: topInclude.through.model,\n          include: [{\n            association: topAssociation.toTarget,\n            required: true,\n            where: topInclude.where,\n            include: topInclude.include\n          }]\n        }).include,\n        model: topInclude.through.model,\n        where: {\n          [Op.and]: [\n            this.sequelize.literal([\n              `${this.quoteTable(topParent.model.name)}.${this.quoteIdentifier(topParent.model.primaryKeyField)}`,\n              `${this.quoteIdentifier(topInclude.through.model.name)}.${this.quoteIdentifier(topAssociation.identifierField)}`\n            ].join(' = ')),\n            topInclude.through.where\n          ]\n        },\n        limit: 1,\n        includeIgnoreAttributes: false\n      }, topInclude.through.model);\n    } else {\n      const isBelongsTo = topAssociation.associationType === 'BelongsTo';\n      const sourceField = isBelongsTo ? topAssociation.identifierField : topAssociation.sourceKeyField || topParent.model.primaryKeyField;\n      const targetField = isBelongsTo ? topAssociation.sourceKeyField || topInclude.model.primaryKeyField : topAssociation.identifierField;\n\n      const join = [\n        `${this.quoteIdentifier(topInclude.as)}.${this.quoteIdentifier(targetField)}`,\n        `${this.quoteTable(topParent.as || topParent.model.name)}.${this.quoteIdentifier(sourceField)}`\n      ].join(' = ');\n\n      query = this.selectQuery(topInclude.model.getTableName(), {\n        attributes: [targetField],\n        include: Model._validateIncludedElements(topInclude).include,\n        model: topInclude.model,\n        where: {\n          [Op.and]: [\n            topInclude.where,\n            { [Op.join]: this.sequelize.literal(join) }\n          ]\n        },\n        limit: 1,\n        tableAs: topInclude.as,\n        includeIgnoreAttributes: false\n      }, topInclude.model);\n    }\n\n    if (!topLevelInfo.options.where[Op.and]) {\n      topLevelInfo.options.where[Op.and] = [];\n    }\n\n    topLevelInfo.options.where[`__${includeAs.internalAs}`] = this.sequelize.literal([\n      '(',\n      query.replace(/;$/, ''),\n      ')',\n      'IS NOT NULL'\n    ].join(' '));\n  }\n\n  /*\n   * For a given include hierarchy creates a copy of it where only the required includes\n   * are preserved.\n   */\n  _getRequiredClosure(include) {\n    const copy = { ...include, attributes: [], include: [] };\n\n    if (Array.isArray(include.include)) {\n      copy.include = include.include\n        .filter(i => i.required)\n        .map(inc => this._getRequiredClosure(inc));\n    }\n\n    return copy;\n  }\n\n  getQueryOrders(options, model, subQuery) {\n    const mainQueryOrder = [];\n    const subQueryOrder = [];\n\n    if (Array.isArray(options.order)) {\n      for (let order of options.order) {\n\n        // wrap if not array\n        if (!Array.isArray(order)) {\n          order = [order];\n        }\n\n        if (\n          subQuery\n          && Array.isArray(order)\n          && order[0]\n          && !(order[0] instanceof Association)\n          && !(typeof order[0] === 'function' && order[0].prototype instanceof Model)\n          && !(typeof order[0].model === 'function' && order[0].model.prototype instanceof Model)\n          && !(typeof order[0] === 'string' && model && model.associations !== undefined && model.associations[order[0]])\n        ) {\n          const field = model.rawAttributes[order[0]] ? model.rawAttributes[order[0]].field : order[0];\n          const subQueryAlias = this._getAliasForField(this.quoteIdentifier(model.name), field, options);\n\n          let parent = null;\n          let orderToQuote = [];\n\n          // we need to ensure that the parent is null if we use the subquery alias, else we'll get an exception since\n          // \"model_name\".\"alias\" doesn't exist - only \"alias\" does. we also need to ensure that we preserve order direction\n          // by pushing order[1] to the subQueryOrder as well - in case it doesn't exist, we want to push \"ASC\"\n          if (subQueryAlias === null) {\n            orderToQuote = order;\n            parent = model;\n          } else {\n            orderToQuote = [subQueryAlias, order.length > 1 ? order[1] : 'ASC'];\n            parent = null;\n          }\n\n          subQueryOrder.push(this.quote(orderToQuote, parent, '->'));\n        }\n\n        // Handle case where renamed attributes are used to order by,\n        // see https://github.com/sequelize/sequelize/issues/8739\n        // need to check if either of the attribute options match the order\n        if (options.attributes && model) {\n          const aliasedAttribute = options.attributes.find(attr => Array.isArray(attr)\n              && attr[1]\n              && (attr[0] === order[0] || attr[1] === order[0]));\n\n          if (aliasedAttribute) {\n            const modelName = this.quoteIdentifier(model.name);\n            const alias = this._getAliasForField(modelName, aliasedAttribute[1], options);\n\n            order[0] = new Utils.Col(alias || aliasedAttribute[1]);\n          }\n        }\n\n        mainQueryOrder.push(this.quote(order, model, '->'));\n      }\n    } else if (options.order instanceof Utils.SequelizeMethod) {\n      const sql = this.quote(options.order, model, '->');\n      if (subQuery) {\n        subQueryOrder.push(sql);\n      }\n      mainQueryOrder.push(sql);\n    } else {\n      throw new Error('Order must be type of array or instance of a valid sequelize method.');\n    }\n\n    return { mainQueryOrder, subQueryOrder };\n  }\n\n  _throwOnEmptyAttributes(attributes, extraInfo = {}) {\n    if (attributes.length > 0) return;\n    const asPart = extraInfo.as && `as ${extraInfo.as}` || '';\n    const namePart = extraInfo.modelName && `for model '${extraInfo.modelName}'` || '';\n    const message = `Attempted a SELECT query ${namePart} ${asPart} without selecting any columns`;\n    throw new sequelizeError.QueryError(message.replace(/ +/g, ' '));\n  }\n\n  selectFromTableFragment(options, model, attributes, tables, mainTableAs) {\n    this._throwOnEmptyAttributes(attributes, { modelName: model && model.name, as: mainTableAs });\n\n    let fragment = `SELECT ${attributes.join(', ')} FROM ${tables}`;\n\n    if (mainTableAs) {\n      fragment += ` ${this.getAliasToken()} ${mainTableAs}`;\n    }\n\n    if (options.indexHints && this._dialect.supports.indexHints) {\n      for (const hint of options.indexHints) {\n        if (IndexHints[hint.type]) {\n          fragment += ` ${IndexHints[hint.type]} INDEX (${hint.values.map(indexName => this.quoteIdentifiers(indexName)).join(',')})`;\n        }\n      }\n    }\n\n    return fragment;\n  }\n\n  /**\n   * Returns an SQL fragment for adding result constraints.\n   *\n   * @param  {object} options An object with selectQuery options.\n   * @returns {string}         The generated sql query.\n   * @private\n   */\n  addLimitAndOffset(options) {\n    let fragment = '';\n\n    /* eslint-disable */\n    if (options.offset != null && options.limit == null) {\n      fragment += ' LIMIT ' + this.escape(options.offset) + ', ' + 10000000000000;\n    } else if (options.limit != null) {\n      if (options.offset != null) {\n        fragment += ' LIMIT ' + this.escape(options.offset) + ', ' + this.escape(options.limit);\n      } else {\n        fragment += ' LIMIT ' + this.escape(options.limit);\n      }\n    }\n    /* eslint-enable */\n\n    return fragment;\n  }\n\n  handleSequelizeMethod(smth, tableName, factory, options, prepend) {\n    let result;\n\n    if (Object.prototype.hasOwnProperty.call(this.OperatorMap, smth.comparator)) {\n      smth.comparator = this.OperatorMap[smth.comparator];\n    }\n\n    if (smth instanceof Utils.Where) {\n      let value = smth.logic;\n      let key;\n\n      if (smth.attribute instanceof Utils.SequelizeMethod) {\n        key = this.getWhereConditions(smth.attribute, tableName, factory, options, prepend);\n      } else {\n        key = `${this.quoteTable(smth.attribute.Model.name)}.${this.quoteIdentifier(smth.attribute.field || smth.attribute.fieldName)}`;\n      }\n\n      if (value && value instanceof Utils.SequelizeMethod) {\n        value = this.getWhereConditions(value, tableName, factory, options, prepend);\n\n        if (value === 'NULL') {\n          if (smth.comparator === '=') {\n            smth.comparator = 'IS';\n          }\n          if (smth.comparator === '!=') {\n            smth.comparator = 'IS NOT';\n          }\n        }\n\n        return [key, value].join(` ${smth.comparator} `);\n      }\n      if (_.isPlainObject(value)) {\n        return this.whereItemQuery(smth.attribute, value, {\n          model: factory\n        });\n      }\n      if ([this.OperatorMap[Op.between], this.OperatorMap[Op.notBetween]].includes(smth.comparator)) {\n        value = `${this.escape(value[0])} AND ${this.escape(value[1])}`;\n      } else if (typeof value === 'boolean') {\n        value = this.booleanValue(value);\n      } else {\n        value = this.escape(value);\n      }\n\n      if (value === 'NULL') {\n        if (smth.comparator === '=') {\n          smth.comparator = 'IS';\n        }\n        if (smth.comparator === '!=') {\n          smth.comparator = 'IS NOT';\n        }\n      }\n\n      return [key, value].join(` ${smth.comparator} `);\n    }\n    if (smth instanceof Utils.Literal) {\n      return smth.val;\n    }\n    if (smth instanceof Utils.Cast) {\n      if (smth.val instanceof Utils.SequelizeMethod) {\n        result = this.handleSequelizeMethod(smth.val, tableName, factory, options, prepend);\n      } else if (_.isPlainObject(smth.val)) {\n        result = this.whereItemsQuery(smth.val);\n      } else {\n        result = this.escape(smth.val);\n      }\n\n      return `CAST(${result} AS ${smth.type.toUpperCase()})`;\n    }\n    if (smth instanceof Utils.Fn) {\n      return `${smth.fn}(${\n        smth.args.map(arg => {\n          if (arg instanceof Utils.SequelizeMethod) {\n            return this.handleSequelizeMethod(arg, tableName, factory, options, prepend);\n          }\n          if (_.isPlainObject(arg)) {\n            return this.whereItemsQuery(arg);\n          }\n          return this.escape(typeof arg === 'string' ? arg.replace(/\\$/g, '$$$') : arg);\n        }).join(', ')\n      })`;\n    }\n    if (smth instanceof Utils.Col) {\n      if (Array.isArray(smth.col) && !factory) {\n        throw new Error('Cannot call Sequelize.col() with array outside of order / group clause');\n      }\n      if (smth.col.startsWith('*')) {\n        return '*';\n      }\n      return this.quote(smth.col, factory);\n    }\n    return smth.toString(this, factory);\n  }\n\n  whereQuery(where, options) {\n    const query = this.whereItemsQuery(where, options);\n    if (query && query.length) {\n      return `WHERE ${query}`;\n    }\n    return '';\n  }\n\n  whereItemsQuery(where, options, binding) {\n    if (\n      where === null ||\n      where === undefined ||\n      Utils.getComplexSize(where) === 0\n    ) {\n      // NO OP\n      return '';\n    }\n\n    if (typeof where === 'string') {\n      throw new Error('Support for `{where: \\'raw query\\'}` has been removed.');\n    }\n\n    const items = [];\n\n    binding = binding || 'AND';\n    if (binding[0] !== ' ') binding = ` ${binding} `;\n\n    if (_.isPlainObject(where)) {\n      Utils.getComplexKeys(where).forEach(prop => {\n        const item = where[prop];\n        items.push(this.whereItemQuery(prop, item, options));\n      });\n    } else {\n      items.push(this.whereItemQuery(undefined, where, options));\n    }\n\n    return items.length && items.filter(item => item && item.length).join(binding) || '';\n  }\n\n  whereItemQuery(key, value, options = {}) {\n    if (value === undefined) {\n      throw new Error(`WHERE parameter \"${key}\" has invalid \"undefined\" value`);\n    }\n\n    if (typeof key === 'string' && key.includes('.') && options.model) {\n      const keyParts = key.split('.');\n      if (options.model.rawAttributes[keyParts[0]] && options.model.rawAttributes[keyParts[0]].type instanceof DataTypes.JSON) {\n        const tmp = {};\n        const field = options.model.rawAttributes[keyParts[0]];\n        _.set(tmp, keyParts.slice(1), value);\n        return this.whereItemQuery(field.field || keyParts[0], tmp, { field, ...options });\n      }\n    }\n\n    const field = this._findField(key, options);\n    const fieldType = field && field.type || options.type;\n\n    const isPlainObject = _.isPlainObject(value);\n    const isArray = !isPlainObject && Array.isArray(value);\n    key = this.OperatorsAliasMap && this.OperatorsAliasMap[key] || key;\n    if (isPlainObject) {\n      value = this._replaceAliases(value);\n    }\n    const valueKeys = isPlainObject && Utils.getComplexKeys(value);\n\n    if (key === undefined) {\n      if (typeof value === 'string') {\n        return value;\n      }\n\n      if (isPlainObject && valueKeys.length === 1) {\n        return this.whereItemQuery(valueKeys[0], value[valueKeys[0]], options);\n      }\n    }\n\n    if (value === null) {\n      const opValue = options.bindParam ? 'NULL' : this.escape(value, field);\n      return this._joinKeyValue(key, opValue, this.OperatorMap[Op.is], options.prefix);\n    }\n\n    if (!value) {\n      const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);\n      return this._joinKeyValue(key, opValue, this.OperatorMap[Op.eq], options.prefix);\n    }\n\n    if (value instanceof Utils.SequelizeMethod && !(key !== undefined && value instanceof Utils.Fn)) {\n      return this.handleSequelizeMethod(value);\n    }\n\n    // Convert where: [] to Op.and if possible, else treat as literal/replacements\n    if (key === undefined && isArray) {\n      if (Utils.canTreatArrayAsAnd(value)) {\n        key = Op.and;\n      } else {\n        throw new Error('Support for literal replacements in the `where` object has been removed.');\n      }\n    }\n\n    if (key === Op.or || key === Op.and || key === Op.not) {\n      return this._whereGroupBind(key, value, options);\n    }\n\n\n    if (value[Op.or]) {\n      return this._whereBind(this.OperatorMap[Op.or], key, value[Op.or], options);\n    }\n\n    if (value[Op.and]) {\n      return this._whereBind(this.OperatorMap[Op.and], key, value[Op.and], options);\n    }\n\n    if (isArray && fieldType instanceof DataTypes.ARRAY) {\n      const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);\n      return this._joinKeyValue(key, opValue, this.OperatorMap[Op.eq], options.prefix);\n    }\n\n    if (isPlainObject && fieldType instanceof DataTypes.JSON && options.json !== false) {\n      return this._whereJSON(key, value, options);\n    }\n    // If multiple keys we combine the different logic conditions\n    if (isPlainObject && valueKeys.length > 1) {\n      return this._whereBind(this.OperatorMap[Op.and], key, value, options);\n    }\n\n    if (isArray) {\n      return this._whereParseSingleValueObject(key, field, Op.in, value, options);\n    }\n    if (isPlainObject) {\n      if (this.OperatorMap[valueKeys[0]]) {\n        return this._whereParseSingleValueObject(key, field, valueKeys[0], value[valueKeys[0]], options);\n      }\n      return this._whereParseSingleValueObject(key, field, this.OperatorMap[Op.eq], value, options);\n    }\n\n    if (key === Op.placeholder) {\n      const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);\n      return this._joinKeyValue(this.OperatorMap[key], opValue, this.OperatorMap[Op.eq], options.prefix);\n    }\n\n    const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);\n    return this._joinKeyValue(key, opValue, this.OperatorMap[Op.eq], options.prefix);\n  }\n\n  _findField(key, options) {\n    if (options.field) {\n      return options.field;\n    }\n\n    if (options.model && options.model.rawAttributes && options.model.rawAttributes[key]) {\n      return options.model.rawAttributes[key];\n    }\n\n    if (options.model && options.model.fieldRawAttributesMap && options.model.fieldRawAttributesMap[key]) {\n      return options.model.fieldRawAttributesMap[key];\n    }\n  }\n\n  // OR/AND/NOT grouping logic\n  _whereGroupBind(key, value, options) {\n    const binding = key === Op.or ? this.OperatorMap[Op.or] : this.OperatorMap[Op.and];\n    const outerBinding = key === Op.not ? 'NOT ' : '';\n\n    if (Array.isArray(value)) {\n      value = value.map(item => {\n        let itemQuery = this.whereItemsQuery(item, options, this.OperatorMap[Op.and]);\n        if (itemQuery && itemQuery.length && (Array.isArray(item) || _.isPlainObject(item)) && Utils.getComplexSize(item) > 1) {\n          itemQuery = `(${itemQuery})`;\n        }\n        return itemQuery;\n      }).filter(item => item && item.length);\n\n      value = value.length && value.join(binding);\n    } else {\n      value = this.whereItemsQuery(value, options, binding);\n    }\n    // Op.or: [] should return no data.\n    // Op.not of no restriction should also return no data\n    if ((key === Op.or || key === Op.not) && !value) {\n      return '0 = 1';\n    }\n\n    return value ? `${outerBinding}(${value})` : undefined;\n  }\n\n  _whereBind(binding, key, value, options) {\n    if (_.isPlainObject(value)) {\n      value = Utils.getComplexKeys(value).map(prop => {\n        const item = value[prop];\n        return this.whereItemQuery(key, { [prop]: item }, options);\n      });\n    } else {\n      value = value.map(item => this.whereItemQuery(key, item, options));\n    }\n\n    value = value.filter(item => item && item.length);\n\n    return value.length ? `(${value.join(binding)})` : undefined;\n  }\n\n  _whereJSON(key, value, options) {\n    const items = [];\n    let baseKey = this.quoteIdentifier(key);\n    if (options.prefix) {\n      if (options.prefix instanceof Utils.Literal) {\n        baseKey = `${this.handleSequelizeMethod(options.prefix)}.${baseKey}`;\n      } else {\n        baseKey = `${this.quoteTable(options.prefix)}.${baseKey}`;\n      }\n    }\n\n    Utils.getOperators(value).forEach(op => {\n      const where = {\n        [op]: value[op]\n      };\n      items.push(this.whereItemQuery(key, where, { ...options, json: false }));\n    });\n\n    _.forOwn(value, (item, prop) => {\n      this._traverseJSON(items, baseKey, prop, item, [prop]);\n    });\n\n    const result = items.join(this.OperatorMap[Op.and]);\n    return items.length > 1 ? `(${result})` : result;\n  }\n\n  _traverseJSON(items, baseKey, prop, item, path) {\n    let cast;\n\n    if (path[path.length - 1].includes('::')) {\n      const tmp = path[path.length - 1].split('::');\n      cast = tmp[1];\n      path[path.length - 1] = tmp[0];\n    }\n\n    let pathKey = this.jsonPathExtractionQuery(baseKey, path);\n\n    if (_.isPlainObject(item)) {\n      Utils.getOperators(item).forEach(op => {\n        const value = this._toJSONValue(item[op]);\n        let isJson = false;\n        if (typeof value === 'string' && op === Op.contains) {\n          try {\n            JSON.stringify(value);\n            isJson = true;\n          } catch (e) {\n            // failed to parse, is not json so isJson remains false\n          }\n        }\n        pathKey = this.jsonPathExtractionQuery(baseKey, path, isJson);\n        items.push(this.whereItemQuery(this._castKey(pathKey, value, cast), { [op]: value }));\n      });\n      _.forOwn(item, (value, itemProp) => {\n        this._traverseJSON(items, baseKey, itemProp, value, path.concat([itemProp]));\n      });\n\n      return;\n    }\n\n    item = this._toJSONValue(item);\n    items.push(this.whereItemQuery(this._castKey(pathKey, item, cast), { [Op.eq]: item }));\n  }\n\n  _toJSONValue(value) {\n    return value;\n  }\n\n  _castKey(key, value, cast, json) {\n    cast = cast || this._getJsonCast(Array.isArray(value) ? value[0] : value);\n    if (cast) {\n      return new Utils.Literal(this.handleSequelizeMethod(new Utils.Cast(new Utils.Literal(key), cast, json)));\n    }\n\n    return new Utils.Literal(key);\n  }\n\n  _getJsonCast(value) {\n    if (typeof value === 'number') {\n      return 'double precision';\n    }\n    if (value instanceof Date) {\n      return 'timestamptz';\n    }\n    if (typeof value === 'boolean') {\n      return 'boolean';\n    }\n    return;\n  }\n\n  _joinKeyValue(key, value, comparator, prefix) {\n    if (!key) {\n      return value;\n    }\n    if (comparator === undefined) {\n      throw new Error(`${key} and ${value} has no comparator`);\n    }\n    key = this._getSafeKey(key, prefix);\n    return [key, value].join(` ${comparator} `);\n  }\n\n  _getSafeKey(key, prefix) {\n    if (key instanceof Utils.SequelizeMethod) {\n      key = this.handleSequelizeMethod(key);\n      return this._prefixKey(this.handleSequelizeMethod(key), prefix);\n    }\n\n    if (Utils.isColString(key)) {\n      key = key.substr(1, key.length - 2).split('.');\n\n      if (key.length > 2) {\n        key = [\n          // join the tables by -> to match out internal namings\n          key.slice(0, -1).join('->'),\n          key[key.length - 1]\n        ];\n      }\n\n      return key.map(identifier => this.quoteIdentifier(identifier)).join('.');\n    }\n\n    return this._prefixKey(this.quoteIdentifier(key), prefix);\n  }\n\n  _prefixKey(key, prefix) {\n    if (prefix) {\n      if (prefix instanceof Utils.Literal) {\n        return [this.handleSequelizeMethod(prefix), key].join('.');\n      }\n\n      return [this.quoteTable(prefix), key].join('.');\n    }\n\n    return key;\n  }\n\n  _whereParseSingleValueObject(key, field, prop, value, options) {\n    if (prop === Op.not) {\n      if (Array.isArray(value)) {\n        prop = Op.notIn;\n      } else if (value !== null && value !== true && value !== false) {\n        prop = Op.ne;\n      }\n    }\n\n    let comparator = this.OperatorMap[prop] || this.OperatorMap[Op.eq];\n\n    switch (prop) {\n      case Op.in:\n      case Op.notIn:\n        if (value instanceof Utils.Literal) {\n          return this._joinKeyValue(key, value.val, comparator, options.prefix);\n        }\n\n        if (value.length) {\n          return this._joinKeyValue(key, `(${value.map(item => this.escape(item, field)).join(', ')})`, comparator, options.prefix);\n        }\n\n        if (comparator === this.OperatorMap[Op.in]) {\n          return this._joinKeyValue(key, '(NULL)', comparator, options.prefix);\n        }\n\n        return '';\n      case Op.any:\n      case Op.all:\n        comparator = `${this.OperatorMap[Op.eq]} ${comparator}`;\n        if (value[Op.values]) {\n          return this._joinKeyValue(key, `(VALUES ${value[Op.values].map(item => `(${this.escape(item)})`).join(', ')})`, comparator, options.prefix);\n        }\n\n        return this._joinKeyValue(key, `(${this.escape(value, field)})`, comparator, options.prefix);\n      case Op.between:\n      case Op.notBetween:\n        return this._joinKeyValue(key, `${this.escape(value[0], field)} AND ${this.escape(value[1], field)}`, comparator, options.prefix);\n      case Op.raw:\n        throw new Error('The `$raw` where property is no longer supported.  Use `sequelize.literal` instead.');\n      case Op.col:\n        comparator = this.OperatorMap[Op.eq];\n        value = value.split('.');\n\n        if (value.length > 2) {\n          value = [\n            // join the tables by -> to match out internal namings\n            value.slice(0, -1).join('->'),\n            value[value.length - 1]\n          ];\n        }\n\n        return this._joinKeyValue(key, value.map(identifier => this.quoteIdentifier(identifier)).join('.'), comparator, options.prefix);\n      case Op.startsWith:\n      case Op.endsWith:\n      case Op.substring:\n        comparator = this.OperatorMap[Op.like];\n\n        if (value instanceof Utils.Literal) {\n          value = value.val;\n        }\n\n        let pattern = `${value}%`;\n\n        if (prop === Op.endsWith) pattern = `%${value}`;\n        if (prop === Op.substring) pattern = `%${value}%`;\n\n        return this._joinKeyValue(key, this.escape(pattern), comparator, options.prefix);\n    }\n\n    const escapeOptions = {\n      acceptStrings: comparator.includes(this.OperatorMap[Op.like])\n    };\n\n    if (_.isPlainObject(value)) {\n      if (value[Op.col]) {\n        return this._joinKeyValue(key, this.whereItemQuery(null, value), comparator, options.prefix);\n      }\n      if (value[Op.any]) {\n        escapeOptions.isList = true;\n        return this._joinKeyValue(key, `(${this.escape(value[Op.any], field, escapeOptions)})`, `${comparator} ${this.OperatorMap[Op.any]}`, options.prefix);\n      }\n      if (value[Op.all]) {\n        escapeOptions.isList = true;\n        return this._joinKeyValue(key, `(${this.escape(value[Op.all], field, escapeOptions)})`, `${comparator} ${this.OperatorMap[Op.all]}`, options.prefix);\n      }\n    }\n\n    if (value === null && comparator === this.OperatorMap[Op.eq]) {\n      return this._joinKeyValue(key, this.escape(value, field, escapeOptions), this.OperatorMap[Op.is], options.prefix);\n    }\n    if (value === null && comparator === this.OperatorMap[Op.ne]) {\n      return this._joinKeyValue(key, this.escape(value, field, escapeOptions), this.OperatorMap[Op.not], options.prefix);\n    }\n\n    return this._joinKeyValue(key, this.escape(value, field, escapeOptions), comparator, options.prefix);\n  }\n\n  /*\n    Takes something and transforms it into values of a where condition.\n   @private\n  */\n  getWhereConditions(smth, tableName, factory, options, prepend) {\n    const where = {};\n\n    if (Array.isArray(tableName)) {\n      tableName = tableName[0];\n      if (Array.isArray(tableName)) {\n        tableName = tableName[1];\n      }\n    }\n\n    options = options || {};\n\n    if (prepend === undefined) {\n      prepend = true;\n    }\n\n    if (smth && smth instanceof Utils.SequelizeMethod) { // Checking a property is cheaper than a lot of instanceof calls\n      return this.handleSequelizeMethod(smth, tableName, factory, options, prepend);\n    }\n    if (_.isPlainObject(smth)) {\n      return this.whereItemsQuery(smth, {\n        model: factory,\n        prefix: prepend && tableName,\n        type: options.type\n      });\n    }\n    if (typeof smth === 'number' || typeof smth === 'bigint') {\n      let primaryKeys = factory ? Object.keys(factory.primaryKeys) : [];\n\n      if (primaryKeys.length > 0) {\n        // Since we're just a number, assume only the first key\n        primaryKeys = primaryKeys[0];\n      } else {\n        primaryKeys = 'id';\n      }\n\n      where[primaryKeys] = smth;\n\n      return this.whereItemsQuery(where, {\n        model: factory,\n        prefix: prepend && tableName\n      });\n    }\n    if (typeof smth === 'string') {\n      return this.whereItemsQuery(smth, {\n        model: factory,\n        prefix: prepend && tableName\n      });\n    }\n    if (Buffer.isBuffer(smth)) {\n      return this.escape(smth);\n    }\n    if (Array.isArray(smth)) {\n      if (smth.length === 0 || smth.length > 0 && smth[0].length === 0) return '1=1';\n      if (Utils.canTreatArrayAsAnd(smth)) {\n        const _smth = { [Op.and]: smth };\n        return this.getWhereConditions(_smth, tableName, factory, options, prepend);\n      }\n      throw new Error('Support for literal replacements in the `where` object has been removed.');\n    }\n    if (smth == null) {\n      return this.whereItemsQuery(smth, {\n        model: factory,\n        prefix: prepend && tableName\n      });\n    }\n\n    throw new Error(`Unsupported where option value: ${util.inspect(smth)}. Please refer to the Sequelize documentation to learn more about which values are accepted as part of the where option.`);\n  }\n\n  // A recursive parser for nested where conditions\n  parseConditionObject(conditions, path) {\n    path = path || [];\n    return _.reduce(conditions, (result, value, key) => {\n      if (_.isObject(value)) {\n        return result.concat(this.parseConditionObject(value, path.concat(key))); // Recursively parse objects\n      }\n      result.push({ path: path.concat(key), value });\n      return result;\n    }, []);\n  }\n\n  booleanValue(value) {\n    return value;\n  }\n\n  /**\n   * Returns the authenticate test query string\n   */\n  authTestQuery() {\n    return 'SELECT 1+1 AS result';\n  }\n}\n\nObject.assign(QueryGenerator.prototype, require('./query-generator/operators'));\nObject.assign(QueryGenerator.prototype, require('./query-generator/transaction'));\n\nmodule.exports = QueryGenerator;\n"],
-  "mappings": "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",
+  "sourcesContent": ["'use strict';\n\nconst util = require('util');\nconst _ = require('lodash');\nconst uuidv4 = require('uuid').v4;\n\nconst Utils = require('../../utils');\nconst deprecations = require('../../utils/deprecations');\nconst SqlString = require('../../sql-string');\nconst DataTypes = require('../../data-types');\nconst Model = require('../../model');\nconst Association = require('../../associations/base');\nconst BelongsTo = require('../../associations/belongs-to');\nconst BelongsToMany = require('../../associations/belongs-to-many');\nconst HasMany = require('../../associations/has-many');\nconst Op = require('../../operators');\nconst sequelizeError = require('../../errors');\nconst IndexHints = require('../../index-hints');\n\n/**\n * Whitelist of SQL data types allowed in JSON key cast notation (e.g. \"key::integer\").\n * This prevents SQL injection via user-controlled cast types in _traverseJSON.\n * Includes types produced by _getJsonCast() and types transformed by dialect overrides.\n */\nconst ALLOWED_CAST_TYPES = new Set([\n  'integer',\n  'int',\n  'smallint',\n  'bigint',\n  'float',\n  'real',\n  'double precision',\n  'decimal',\n  'numeric',\n  'boolean',\n  'text',\n  'char',\n  'varchar',\n  'nvarchar',\n  'date',\n  'timestamp',\n  'timestamptz',\n  'datetime',\n  'json',\n  'jsonb',\n  'signed',\n  'unsigned'\n]);\n\n/**\n * Abstract Query Generator\n *\n * @private\n */\nclass QueryGenerator {\n  constructor(options) {\n    if (!options.sequelize) throw new Error('QueryGenerator initialized without options.sequelize');\n    if (!options._dialect) throw new Error('QueryGenerator initialized without options._dialect');\n\n    this.sequelize = options.sequelize;\n    this.options = options.sequelize.options;\n\n    // dialect name\n    this.dialect = options._dialect.name;\n    this._dialect = options._dialect;\n\n    // wrap quoteIdentifier with common logic\n    this._initQuoteIdentifier();\n  }\n\n  extractTableDetails(tableName, options) {\n    options = options || {};\n    tableName = tableName || {};\n    return {\n      schema: tableName.schema || options.schema || this.options.schema || 'public',\n      tableName: _.isPlainObject(tableName) ? tableName.tableName : tableName,\n      delimiter: tableName.delimiter || options.delimiter || '.'\n    };\n  }\n\n  addSchema(param) {\n    if (!param._schema) return param.tableName || param;\n    const self = this;\n    return {\n      tableName: param.tableName || param,\n      table: param.tableName || param,\n      name: param.name || param,\n      schema: param._schema,\n      delimiter: param._schemaDelimiter || '.',\n      toString() {\n        return self.quoteTable(this);\n      }\n    };\n  }\n\n  dropSchema(tableName, options) {\n    return this.dropTableQuery(tableName, options);\n  }\n\n  describeTableQuery(tableName, schema, schemaDelimiter) {\n    const table = this.quoteTable(\n      this.addSchema({\n        tableName,\n        _schema: schema,\n        _schemaDelimiter: schemaDelimiter\n      })\n    );\n\n    return `DESCRIBE ${table};`;\n  }\n\n  dropTableQuery(tableName) {\n    return `DROP TABLE IF EXISTS ${this.quoteTable(tableName)};`;\n  }\n\n  renameTableQuery(before, after) {\n    return `ALTER TABLE ${this.quoteTable(before)} RENAME TO ${this.quoteTable(after)};`;\n  }\n\n  /**\n   * Helper method for populating the returning into bind information\n   * that is needed by some dialects (currently Oracle)\n   *\n   * @private\n   */\n  populateInsertQueryReturnIntoBinds() {\n    // noop by default\n  }\n\n  /**\n   * Returns an insert into command\n   *\n   * @param {string} table\n   * @param {object} valueHash       attribute value pairs\n   * @param {object} modelAttributes\n   * @param {object} [options]\n   *\n   * @private\n   */\n  insertQuery(table, valueHash, modelAttributes, options) {\n    options = options || {};\n    _.defaults(options, this.options);\n\n    const modelAttributeMap = {};\n    const bind = options.bind || [];\n    const fields = [];\n    const returningModelAttributes = [];\n    const returnTypes = [];\n    const values = [];\n    const quotedTable = this.quoteTable(table);\n    const bindParam = options.bindParam === undefined ? this.bindParam(bind) : options.bindParam;\n    const returnAttributes = [];\n    let query;\n    let valueQuery = '';\n    let emptyQuery = '';\n    let outputFragment = '';\n    let returningFragment = '';\n    let identityWrapperRequired = false;\n    let tmpTable = ''; //tmpTable declaration for trigger\n\n    if (modelAttributes) {\n      _.each(modelAttributes, (attribute, key) => {\n        modelAttributeMap[key] = attribute;\n        if (attribute.field) {\n          modelAttributeMap[attribute.field] = attribute;\n        }\n      });\n    }\n\n    if (this._dialect.supports['DEFAULT VALUES']) {\n      emptyQuery += ' DEFAULT VALUES';\n    } else if (this._dialect.supports['VALUES ()']) {\n      emptyQuery += ' VALUES ()';\n    }\n\n    if ((this._dialect.supports.returnValues || this._dialect.supports.returnIntoValues) && options.returning) {\n      const returnValues = this.generateReturnValues(modelAttributes, options);\n\n      returningModelAttributes.push(...returnValues.returnFields);\n      // Storing the returnTypes for dialects that need to have returning into bind information for outbinds\n      if (this._dialect.supports.returnIntoValues) {\n        returnTypes.push(...returnValues.returnTypes);\n      }\n      returningFragment = returnValues.returningFragment;\n      tmpTable = returnValues.tmpTable || '';\n      outputFragment = returnValues.outputFragment || '';\n    }\n\n    if (_.get(this, ['sequelize', 'options', 'dialectOptions', 'prependSearchPath']) || options.searchPath) {\n      // Not currently supported with search path (requires output of multiple queries)\n      options.bindParam = false;\n    }\n\n    if (this._dialect.supports.EXCEPTION && options.exception) {\n      // Not currently supported with bind parameters (requires output of multiple queries)\n      options.bindParam = false;\n    }\n\n    valueHash = Utils.removeNullValuesFromHash(valueHash, this.options.omitNull);\n    for (const key in valueHash) {\n      if (Object.prototype.hasOwnProperty.call(valueHash, key)) {\n        const value = valueHash[key];\n        fields.push(this.quoteIdentifier(key));\n\n        // SERIALS' can't be NULL in postgresql, use DEFAULT where supported\n        if (modelAttributeMap && modelAttributeMap[key] && modelAttributeMap[key].autoIncrement === true && value == null) {\n          if (!this._dialect.supports.autoIncrement.defaultValue) {\n            fields.splice(-1, 1);\n          } else if (this._dialect.supports.DEFAULT) {\n            values.push('DEFAULT');\n          } else {\n            values.push(this.escape(null));\n          }\n        } else {\n          if (modelAttributeMap && modelAttributeMap[key] && modelAttributeMap[key].autoIncrement === true) {\n            identityWrapperRequired = true;\n          }\n\n          if (value instanceof Utils.SequelizeMethod || options.bindParam === false) {\n            values.push(this.escape(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'INSERT' }));\n          } else {\n            values.push(this.format(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'INSERT' }, bindParam));\n          }\n        }\n      }\n    }\n\n    let onDuplicateKeyUpdate = '';\n\n    if (\n      !_.isEmpty(options.conflictWhere)\n      && !this._dialect.supports.inserts.onConflictWhere\n    ) {\n      throw new Error('missing dialect support for conflictWhere option');\n    }\n\n    // `options.updateOnDuplicate` is the list of field names to update if a duplicate key is hit during the insert.  It\n    // contains just the field names.  This option is _usually_ explicitly set by the corresponding query-interface\n    // upsert function.\n    if (this._dialect.supports.inserts.updateOnDuplicate && options.updateOnDuplicate) {\n      if (this._dialect.supports.inserts.updateOnDuplicate == ' ON CONFLICT DO UPDATE SET') { // postgres / sqlite\n        // If no conflict target columns were specified, use the primary key names from options.upsertKeys\n        const conflictKeys = options.upsertKeys.map(attr => this.quoteIdentifier(attr));\n        const updateKeys = options.updateOnDuplicate.map(attr => `${this.quoteIdentifier(attr)}=EXCLUDED.${this.quoteIdentifier(attr)}`);\n\n        const fragments = [\n          'ON CONFLICT',\n          '(',\n          conflictKeys.join(','),\n          ')'\n        ];\n\n        if (!_.isEmpty(options.conflictWhere)) {\n          fragments.push(this.whereQuery(options.conflictWhere, options));\n        }\n\n        // if update keys are provided, then apply them here.  if there are no updateKeys provided, then do not try to\n        // do an update.  Instead, fall back to DO NOTHING.\n        if (_.isEmpty(updateKeys)) {\n          fragments.push('DO NOTHING');\n        } else {\n          fragments.push('DO UPDATE SET', updateKeys.join(','));\n        }\n\n        onDuplicateKeyUpdate = ` ${Utils.joinSQLFragments(fragments)}`;\n\n      } else {\n        const valueKeys = options.updateOnDuplicate.map(attr => `${this.quoteIdentifier(attr)}=VALUES(${this.quoteIdentifier(attr)})`);\n        // the rough equivalent to ON CONFLICT DO NOTHING in mysql, etc is ON DUPLICATE KEY UPDATE id = id\n        // So, if no update values were provided, fall back to the identifier columns provided in the upsertKeys array.\n        // This will be the primary key in most cases, but it could be some other constraint.\n        if (_.isEmpty(valueKeys) && options.upsertKeys) {\n          valueKeys.push(...options.upsertKeys.map(attr => `${this.quoteIdentifier(attr)}=${this.quoteIdentifier(attr)}`));\n        }\n\n        // edge case... but if for some reason there were no valueKeys, and there were also no upsertKeys... then we\n        // can no longer build the requested query without a syntax error.  Let's throw something more graceful here\n        // so the devs know what the problem is.\n        if (_.isEmpty(valueKeys)) {\n          throw new Error('No update values found for ON DUPLICATE KEY UPDATE clause, and no identifier fields could be found to use instead.');\n        }\n        onDuplicateKeyUpdate += `${this._dialect.supports.inserts.updateOnDuplicate} ${valueKeys.join(',')}`;\n      }\n    }\n\n    const replacements = {\n      ignoreDuplicates: options.ignoreDuplicates ? this._dialect.supports.inserts.ignoreDuplicates : '',\n      onConflictDoNothing: options.ignoreDuplicates ? this._dialect.supports.inserts.onConflictDoNothing : '',\n      attributes: fields.join(','),\n      output: outputFragment,\n      values: values.join(','),\n      tmpTable\n    };\n\n    valueQuery = `${tmpTable}INSERT${replacements.ignoreDuplicates} INTO ${quotedTable} (${replacements.attributes})${replacements.output} VALUES (${replacements.values})${onDuplicateKeyUpdate}${replacements.onConflictDoNothing}${valueQuery}`;\n    emptyQuery = `${tmpTable}INSERT${replacements.ignoreDuplicates} INTO ${quotedTable}${replacements.output}${onDuplicateKeyUpdate}${replacements.onConflictDoNothing}${emptyQuery}`;\n\n    // Mostly for internal use, so we expect the user to know what he's doing!\n    // pg_temp functions are private per connection, so we never risk this function interfering with another one.\n    if (this._dialect.supports.EXCEPTION && options.exception) {\n      const dropFunction = 'DROP FUNCTION IF EXISTS pg_temp.testfunc()';\n\n      if (returningModelAttributes.length === 0) {\n        returningModelAttributes.push('*');\n      }\n\n      const delimiter = `$func_${uuidv4().replace(/-/g, '')}$`;\n      const selectQuery = `SELECT (testfunc.response).${returningModelAttributes.join(', (testfunc.response).')}, testfunc.sequelize_caught_exception FROM pg_temp.testfunc();`;\n\n      options.exception = 'WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL;';\n      valueQuery = `CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response ${quotedTable}, OUT sequelize_caught_exception text) RETURNS RECORD AS ${delimiter} BEGIN ${valueQuery} RETURNING * INTO response; EXCEPTION ${options.exception} END ${delimiter} LANGUAGE plpgsql; ${selectQuery} ${dropFunction}`;\n    } else {\n      valueQuery += returningFragment;\n      emptyQuery += returningFragment;\n    }\n\n    if (this._dialect.supports.returnIntoValues && options.returning) {\n      // Populating the returnAttributes array and performing operations needed for output binds of insertQuery\n      this.populateInsertQueryReturnIntoBinds(returningModelAttributes, returnTypes, bind.length, returnAttributes, options);\n    }\n\n    query = `${replacements.attributes.length ? valueQuery : emptyQuery}${returnAttributes.join(',')};`;\n    if (this._dialect.supports.finalTable) {\n      query = `SELECT * FROM FINAL TABLE(${ replacements.attributes.length ? valueQuery : emptyQuery });`;\n    }\n    if (identityWrapperRequired && this._dialect.supports.autoIncrement.identityInsert) {\n      query = `SET IDENTITY_INSERT ${quotedTable} ON; ${query} SET IDENTITY_INSERT ${quotedTable} OFF;`;\n    }\n\n    // Used by Postgres upsertQuery and calls to here with options.exception set to true\n    const result = { query };\n    if (options.bindParam !== false) {\n      result.bind = bind;\n    }\n\n    return result;\n  }\n\n  /**\n   * Returns an insert into command for multiple values.\n   *\n   * @param {string} tableName\n   * @param {object} fieldValueHashes\n   * @param {object} options\n   * @param {object} fieldMappedAttributes\n   *\n   * @private\n   */\n  bulkInsertQuery(tableName, fieldValueHashes, options, fieldMappedAttributes) {\n    options = options || {};\n    fieldMappedAttributes = fieldMappedAttributes || {};\n\n    const tuples = [];\n    const serials = {};\n    const allAttributes = [];\n    let onDuplicateKeyUpdate = '';\n\n    for (const fieldValueHash of fieldValueHashes) {\n      _.forOwn(fieldValueHash, (value, key) => {\n        if (!allAttributes.includes(key)) {\n          allAttributes.push(key);\n        }\n        if (\n          fieldMappedAttributes[key]\n          && fieldMappedAttributes[key].autoIncrement === true\n        ) {\n          serials[key] = true;\n        }\n      });\n    }\n\n    for (const fieldValueHash of fieldValueHashes) {\n      const values = allAttributes.map(key => {\n        if (\n          this._dialect.supports.bulkDefault\n          && serials[key] === true\n        ) {\n          // fieldValueHashes[key] ?? 'DEFAULT'\n          return fieldValueHash[key] != null ? fieldValueHash[key] : 'DEFAULT';\n        }\n\n        return this.escape(fieldValueHash[key], fieldMappedAttributes[key], { context: 'INSERT' });\n      });\n\n      tuples.push(`(${values.join(',')})`);\n    }\n\n    // `options.updateOnDuplicate` is the list of field names to update if a duplicate key is hit during the insert.  It\n    // contains just the field names.  This option is _usually_ explicitly set by the corresponding query-interface\n    // upsert function.\n    if (this._dialect.supports.inserts.updateOnDuplicate && options.updateOnDuplicate) {\n      if (this._dialect.supports.inserts.updateOnDuplicate == ' ON CONFLICT DO UPDATE SET') { // postgres / sqlite\n        // If no conflict target columns were specified, use the primary key names from options.upsertKeys\n        const conflictKeys = options.upsertKeys.map(attr => this.quoteIdentifier(attr));\n        const updateKeys = options.updateOnDuplicate.map(attr => `${this.quoteIdentifier(attr)}=EXCLUDED.${this.quoteIdentifier(attr)}`);\n\n        let whereClause = false;\n        if (options.conflictWhere) {\n          if (!this._dialect.supports.inserts.onConflictWhere) {\n            throw new Error(`conflictWhere not supported for dialect ${this._dialect.name}`);\n          }\n\n          whereClause = this.whereQuery(options.conflictWhere, options);\n        }\n\n        // The Utils.joinSQLFragments later on will join this as it handles nested arrays.\n        onDuplicateKeyUpdate = [\n          'ON CONFLICT',\n          '(',\n          conflictKeys.join(','),\n          ')',\n          whereClause,\n          'DO UPDATE SET',\n          updateKeys.join(',')\n        ];\n      } else { // mysql / maria\n        if (options.conflictWhere) {\n          throw new Error(`conflictWhere not supported for dialect ${this._dialect.name}`);\n        }\n\n        const valueKeys = options.updateOnDuplicate.map(attr => `${this.quoteIdentifier(attr)}=VALUES(${this.quoteIdentifier(attr)})`);\n        onDuplicateKeyUpdate = `${this._dialect.supports.inserts.updateOnDuplicate} ${valueKeys.join(',')}`;\n      }\n    }\n\n    const ignoreDuplicates = options.ignoreDuplicates ? this._dialect.supports.inserts.ignoreDuplicates : '';\n    const attributes = allAttributes.map(attr => this.quoteIdentifier(attr)).join(',');\n    const onConflictDoNothing = options.ignoreDuplicates ? this._dialect.supports.inserts.onConflictDoNothing : '';\n    let returning = '';\n\n    if (this._dialect.supports.returnValues && options.returning) {\n      const returnValues = this.generateReturnValues(fieldMappedAttributes, options);\n\n      returning += returnValues.returningFragment;\n    }\n\n    return Utils.joinSQLFragments([\n      'INSERT',\n      ignoreDuplicates,\n      'INTO',\n      this.quoteTable(tableName),\n      `(${attributes})`,\n      'VALUES',\n      tuples.join(','),\n      onDuplicateKeyUpdate,\n      onConflictDoNothing,\n      returning,\n      ';'\n    ]);\n  }\n\n  /**\n   * Returns an update query\n   *\n   * @param {string} tableName\n   * @param {object} attrValueHash\n   * @param {object} where A hash with conditions (e.g. {name: 'foo'}) OR an ID as integer\n   * @param {object} options\n   * @param {object} attributes\n   *\n   * @private\n   */\n  updateQuery(tableName, attrValueHash, where, options, attributes) {\n    options = options || {};\n    _.defaults(options, this.options);\n\n    attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, options.omitNull, options);\n\n    const values = [];\n    const bind = [];\n    const modelAttributeMap = {};\n    let outputFragment = '';\n    let tmpTable = ''; // tmpTable declaration for trigger\n    let suffix = '';\n\n    if (_.get(this, ['sequelize', 'options', 'dialectOptions', 'prependSearchPath']) || options.searchPath) {\n      // Not currently supported with search path (requires output of multiple queries)\n      options.bindParam = false;\n    }\n\n    const bindParam = options.bindParam === undefined ? this.bindParam(bind) : options.bindParam;\n\n    if (this._dialect.supports['LIMIT ON UPDATE'] && options.limit) {\n      if (!['mssql', 'db2', 'oracle'].includes(this.dialect)) {\n        suffix = ` LIMIT ${this.escape(options.limit)} `;\n      } else if (this.dialect === 'oracle') {\n        // This cannot be setted in where because rownum will be quoted\n        if (where && (where.length && where.length > 0 || Object.keys(where).length > 0)) {\n          // If we have a where clause, we add AND\n          suffix += ' AND ';\n        } else {\n          // No where clause, we add where\n          suffix += ' WHERE ';\n        }\n        suffix += `rownum <= ${this.escape(options.limit)} `;\n      }\n    }\n\n    if (this._dialect.supports.returnValues && options.returning) {\n      const returnValues = this.generateReturnValues(attributes, options);\n\n      suffix += returnValues.returningFragment;\n      tmpTable = returnValues.tmpTable || '';\n      outputFragment = returnValues.outputFragment || '';\n\n      // ensure that the return output is properly mapped to model fields.\n      if (!this._dialect.supports.returnValues.output && options.returning) {\n        options.mapToModel = true;\n      }\n    }\n\n    if (attributes) {\n      _.each(attributes, (attribute, key) => {\n        modelAttributeMap[key] = attribute;\n        if (attribute.field) {\n          modelAttributeMap[attribute.field] = attribute;\n        }\n      });\n    }\n\n    for (const key in attrValueHash) {\n      if (modelAttributeMap && modelAttributeMap[key] &&\n        modelAttributeMap[key].autoIncrement === true &&\n        !this._dialect.supports.autoIncrement.update) {\n        // not allowed to update identity column\n        continue;\n      }\n\n      const value = attrValueHash[key];\n\n      if (value instanceof Utils.SequelizeMethod || options.bindParam === false) {\n        values.push(`${this.quoteIdentifier(key)}=${this.escape(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'UPDATE' })}`);\n      } else {\n        values.push(`${this.quoteIdentifier(key)}=${this.format(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'UPDATE' }, bindParam)}`);\n      }\n    }\n\n    const whereOptions = { ...options, bindParam };\n\n    if (values.length === 0) {\n      return '';\n    }\n\n    const query = `${tmpTable}UPDATE ${this.quoteTable(tableName)} SET ${values.join(',')}${outputFragment} ${this.whereQuery(where, whereOptions)}${suffix}`.trim();\n    // Used by Postgres upsertQuery and calls to here with options.exception set to true\n    const result = { query };\n    if (options.bindParam !== false) {\n      result.bind = bind;\n    }\n    return result;\n  }\n\n  /**\n   * Returns an update query using arithmetic operator\n   *\n   * @param {string} operator                    String with the arithmetic operator (e.g. '+' or '-')\n   * @param {string} tableName                   Name of the table\n   * @param {object} where                       A plain-object with conditions (e.g. {name: 'foo'}) OR an ID as integer\n   * @param {object} incrementAmountsByField     A plain-object with attribute-value-pairs\n   * @param {object} extraAttributesToBeUpdated  A plain-object with attribute-value-pairs\n   * @param {object} options\n   *\n   * @private\n   */\n  arithmeticQuery(operator, tableName, where, incrementAmountsByField, extraAttributesToBeUpdated, options) {\n    options = options || {};\n    _.defaults(options, { returning: true });\n\n    extraAttributesToBeUpdated = Utils.removeNullValuesFromHash(extraAttributesToBeUpdated, this.options.omitNull);\n\n    let outputFragment = '';\n    let returningFragment = '';\n\n    if (this._dialect.supports.returnValues && options.returning) {\n      const returnValues = this.generateReturnValues(null, options);\n\n      outputFragment = returnValues.outputFragment;\n      returningFragment = returnValues.returningFragment;\n    }\n\n    const updateSetSqlFragments = [];\n    for (const field in incrementAmountsByField) {\n      const incrementAmount = incrementAmountsByField[field];\n      const quotedField = this.quoteIdentifier(field);\n      const escapedAmount = this.escape(incrementAmount);\n      updateSetSqlFragments.push(`${quotedField}=${quotedField}${operator} ${escapedAmount}`);\n    }\n    for (const field in extraAttributesToBeUpdated) {\n      const newValue = extraAttributesToBeUpdated[field];\n      const quotedField = this.quoteIdentifier(field);\n      const escapedValue = this.escape(newValue);\n      updateSetSqlFragments.push(`${quotedField}=${escapedValue}`);\n    }\n\n    return Utils.joinSQLFragments([\n      'UPDATE',\n      this.quoteTable(tableName),\n      'SET',\n      updateSetSqlFragments.join(','),\n      outputFragment,\n      this.whereQuery(where),\n      returningFragment\n    ]);\n  }\n\n  /*\n    Returns an add index query.\n    Parameters:\n      - tableName -> Name of an existing table, possibly with schema.\n      - options:\n        - type: UNIQUE|FULLTEXT|SPATIAL\n        - name: The name of the index. Default is <table>_<attr1>_<attr2>\n        - fields: An array of attributes as string or as hash.\n                  If the attribute is a hash, it must have the following content:\n                  - name: The name of the attribute/column\n                  - length: An integer. Optional\n                  - order: 'ASC' or 'DESC'. Optional\n        - parser\n        - using\n        - operator\n        - concurrently: Pass CONCURRENT so other operations run while the index is created\n      - rawTablename, the name of the table, without schema. Used to create the name of the index\n   @private\n  */\n  addIndexQuery(tableName, attributes, options, rawTablename) {\n    options = options || {};\n\n    if (!Array.isArray(attributes)) {\n      options = attributes;\n      attributes = undefined;\n    } else {\n      options.fields = attributes;\n    }\n\n    options.prefix = options.prefix || rawTablename || tableName;\n    if (options.prefix && typeof options.prefix === 'string') {\n      options.prefix = options.prefix.replace(/\\./g, '_');\n      options.prefix = options.prefix.replace(/(\"|')/g, '');\n    }\n\n    const fieldsSql = options.fields.map(field => {\n      if (field instanceof Utils.SequelizeMethod) {\n        return this.handleSequelizeMethod(field);\n      }\n      if (typeof field === 'string') {\n        field = {\n          name: field\n        };\n      }\n      let result = '';\n\n      if (field.attribute) {\n        field.name = field.attribute;\n      }\n\n      if (!field.name) {\n        throw new Error(`The following index field has no name: ${util.inspect(field)}`);\n      }\n\n      result += this.quoteIdentifier(field.name);\n\n      if (this._dialect.supports.index.collate && field.collate) {\n        result += ` COLLATE ${this.quoteIdentifier(field.collate)}`;\n      }\n\n      if (this._dialect.supports.index.operator) {\n        const operator = field.operator || options.operator;\n        if (operator) {\n          result += ` ${operator}`;\n        }\n      }\n\n      if (this._dialect.supports.index.length && field.length) {\n        result += `(${field.length})`;\n      }\n\n      if (field.order) {\n        result += ` ${field.order}`;\n      }\n\n      return result;\n    });\n\n    if (!options.name) {\n      // Mostly for cases where addIndex is called directly by the user without an options object (for example in migrations)\n      // All calls that go through sequelize should already have a name\n      options = Utils.nameIndex(options, options.prefix);\n    }\n\n    options = Model._conformIndex(options);\n\n    if (!this._dialect.supports.index.type) {\n      delete options.type;\n    }\n\n    if (options.where) {\n      options.where = this.whereQuery(options.where);\n    }\n\n    if (typeof tableName === 'string') {\n      tableName = this.quoteIdentifiers(tableName);\n    } else {\n      tableName = this.quoteTable(tableName);\n    }\n\n    const concurrently = this._dialect.supports.index.concurrently && options.concurrently ? 'CONCURRENTLY' : undefined;\n    let ind;\n    if (this._dialect.supports.indexViaAlter) {\n      ind = [\n        'ALTER TABLE',\n        tableName,\n        concurrently,\n        'ADD'\n      ];\n    } else {\n      ind = ['CREATE'];\n    }\n\n    ind = ind.concat(\n      options.unique ? 'UNIQUE' : '',\n      options.type, 'INDEX',\n      !this._dialect.supports.indexViaAlter ? concurrently : undefined,\n      this.quoteIdentifiers(options.name),\n      this._dialect.supports.index.using === 1 && options.using ? `USING ${options.using}` : '',\n      !this._dialect.supports.indexViaAlter ? `ON ${tableName}` : undefined,\n      this._dialect.supports.index.using === 2 && options.using ? `USING ${options.using}` : '',\n      `(${fieldsSql.join(', ')})`,\n      this._dialect.supports.index.parser && options.parser ? `WITH PARSER ${options.parser}` : undefined,\n      this._dialect.supports.index.where && options.where ? options.where : undefined\n    );\n\n    return _.compact(ind).join(' ');\n  }\n\n  addConstraintQuery(tableName, options) {\n    if (typeof tableName === 'string') {\n      tableName = this.quoteIdentifiers(tableName);\n    } else {\n      tableName = this.quoteTable(tableName);\n    }\n\n    return Utils.joinSQLFragments([\n      'ALTER TABLE',\n      tableName,\n      'ADD',\n      this.getConstraintSnippet(tableName, options || {}),\n      ';'\n    ]);\n  }\n\n  getConstraintSnippet(tableName, options) {\n    let constraintSnippet, constraintName;\n\n    const fieldsSql = options.fields.map(field => {\n      if (typeof field === 'string') {\n        return this.quoteIdentifier(field);\n      }\n      if (field instanceof Utils.SequelizeMethod) {\n        return this.handleSequelizeMethod(field);\n      }\n      if (field.attribute) {\n        field.name = field.attribute;\n      }\n\n      if (!field.name) {\n        throw new Error(`The following index field has no name: ${field}`);\n      }\n\n      return this.quoteIdentifier(field.name);\n    });\n\n    const fieldsSqlQuotedString = fieldsSql.join(', ');\n    const fieldsSqlString = fieldsSql.join('_');\n\n    switch (options.type.toUpperCase()) {\n      case 'UNIQUE':\n        constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_uk`);\n        constraintSnippet = `CONSTRAINT ${constraintName} UNIQUE (${fieldsSqlQuotedString})`;\n        break;\n      case 'CHECK':\n        options.where = this.whereItemsQuery(options.where);\n        constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_ck`);\n        constraintSnippet = `CONSTRAINT ${constraintName} CHECK (${options.where})`;\n        break;\n      case 'DEFAULT':\n        if (options.defaultValue === undefined) {\n          throw new Error('Default value must be specified for DEFAULT CONSTRAINT');\n        }\n\n        if (this._dialect.name !== 'mssql') {\n          throw new Error('Default constraints are supported only for MSSQL dialect.');\n        }\n\n        constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_df`);\n        constraintSnippet = `CONSTRAINT ${constraintName} DEFAULT (${this.escape(options.defaultValue)}) FOR ${fieldsSql[0]}`;\n        break;\n      case 'PRIMARY KEY':\n        constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_pk`);\n        constraintSnippet = `CONSTRAINT ${constraintName} PRIMARY KEY (${fieldsSqlQuotedString})`;\n        break;\n      case 'FOREIGN KEY':\n        const references = options.references;\n        if (!references || !references.table || !(references.field || references.fields)) {\n          throw new Error('references object with table and field must be specified');\n        }\n        constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_${references.table}_fk`);\n        const quotedReferences =\n          typeof references.field !== 'undefined'\n            ? this.quoteIdentifier(references.field)\n            : references.fields.map(f => this.quoteIdentifier(f)).join(', ');\n        const referencesSnippet = `${this.quoteTable(references.table)} (${quotedReferences})`;\n        constraintSnippet = `CONSTRAINT ${constraintName} `;\n        constraintSnippet += `FOREIGN KEY (${fieldsSqlQuotedString}) REFERENCES ${referencesSnippet}`;\n        if (options.onUpdate) {\n          constraintSnippet += ` ON UPDATE ${options.onUpdate.toUpperCase()}`;\n        }\n        if (options.onDelete) {\n          constraintSnippet += ` ON DELETE ${options.onDelete.toUpperCase()}`;\n        }\n        break;\n      default: throw new Error(`${options.type} is invalid.`);\n    }\n\n    if (options.deferrable && ['UNIQUE', 'PRIMARY KEY', 'FOREIGN KEY'].includes(options.type.toUpperCase())) {\n      constraintSnippet += ` ${this.deferConstraintsQuery(options)}`;\n    }\n\n    return constraintSnippet;\n  }\n\n  removeConstraintQuery(tableName, constraintName) {\n    if (typeof tableName === 'string') {\n      tableName = this.quoteIdentifiers(tableName);\n    } else {\n      tableName = this.quoteTable(tableName);\n    }\n\n    return Utils.joinSQLFragments([\n      'ALTER TABLE',\n      tableName,\n      'DROP CONSTRAINT',\n      this.quoteIdentifiers(constraintName)\n    ]);\n  }\n\n  /*\n    Quote an object based on its type. This is a more general version of quoteIdentifiers\n    Strings: should proxy to quoteIdentifiers\n    Arrays:\n      * Expects array in the form: [<model> (optional), <model> (optional),... String, String (optional)]\n        Each <model> can be a model, or an object {model: Model, as: String}, matching include, or an\n        association object, or the name of an association.\n      * Zero or more models can be included in the array and are used to trace a path through the tree of\n        included nested associations. This produces the correct table name for the ORDER BY/GROUP BY SQL\n        and quotes it.\n      * If a single string is appended to end of array, it is quoted.\n        If two strings appended, the 1st string is quoted, the 2nd string unquoted.\n    Objects:\n      * If raw is set, that value should be returned verbatim, without quoting\n      * If fn is set, the string should start with the value of fn, starting paren, followed by\n        the values of cols (which is assumed to be an array), quoted and joined with ', ',\n        unless they are themselves objects\n      * If direction is set, should be prepended\n\n    Currently this function is only used for ordering / grouping columns and Sequelize.col(), but it could\n    potentially also be used for other places where we want to be able to call SQL functions (e.g. as default values)\n   @private\n  */\n  quote(collection, parent, connector) {\n    // init\n    const validOrderOptions = [\n      'ASC',\n      'DESC',\n      'ASC NULLS LAST',\n      'DESC NULLS LAST',\n      'ASC NULLS FIRST',\n      'DESC NULLS FIRST',\n      'NULLS FIRST',\n      'NULLS LAST'\n    ];\n\n    // default\n    connector = connector || '.';\n\n    // just quote as identifiers if string\n    if (typeof collection === 'string') {\n      return this.quoteIdentifiers(collection);\n    }\n    if (Array.isArray(collection)) {\n      // iterate through the collection and mutate objects into associations\n      collection.forEach((item, index) => {\n        const previous = collection[index - 1];\n        let previousAssociation;\n        let previousModel;\n\n        // set the previous as the parent when previous is undefined or the target of the association\n        if (!previous && parent !== undefined) {\n          previousModel = parent;\n        } else if (previous && previous instanceof Association) {\n          previousAssociation = previous;\n          previousModel = previous.target;\n        }\n\n        // if the previous item is a model, then attempt getting an association\n        if (previousModel && previousModel.prototype instanceof Model) {\n          let model;\n          let as;\n\n          if (typeof item === 'function' && item.prototype instanceof Model) {\n            // set\n            model = item;\n          } else if (_.isPlainObject(item) && item.model && item.model.prototype instanceof Model) {\n            // set\n            model = item.model;\n            as = item.as;\n          }\n\n          if (model) {\n            // set the as to either the through name or the model name\n            if (!as && previousAssociation && previousAssociation instanceof Association && previousAssociation.through && previousAssociation.through.model === model) {\n              // get from previous association\n              item = new Association(previousModel, model, {\n                as: model.name\n              });\n            } else {\n              // get association from previous model\n              item = previousModel.getAssociationForAlias(model, as);\n\n              // attempt to use the model name if the item is still null\n              if (!item) {\n                item = previousModel.getAssociationForAlias(model, model.name);\n              }\n            }\n\n            // make sure we have an association\n            if (!(item instanceof Association)) {\n              throw new Error(util.format('Unable to find a valid association for model, \\'%s\\'', model.name));\n            }\n          }\n        }\n\n        if (typeof item === 'string') {\n          // get order index\n          const orderIndex = validOrderOptions.indexOf(item.toUpperCase());\n\n          // see if this is an order\n          if (index > 0 && orderIndex !== -1) {\n            item = this.sequelize.literal(` ${validOrderOptions[orderIndex]}`);\n          } else if (previousModel && previousModel.prototype instanceof Model) {\n            // only go down this path if we have preivous model and check only once\n            if (previousModel.associations !== undefined && previousModel.associations[item]) {\n              // convert the item to an association\n              item = previousModel.associations[item];\n            } else if (previousModel.rawAttributes !== undefined && previousModel.rawAttributes[item] && item !== previousModel.rawAttributes[item].field) {\n              // convert the item attribute from its alias\n              item = previousModel.rawAttributes[item].field;\n            } else if (\n              item.includes('.')\n              && previousModel.rawAttributes !== undefined\n            ) {\n              const itemSplit = item.split('.');\n\n              if (previousModel.rawAttributes[itemSplit[0]].type instanceof DataTypes.JSON) {\n                // just quote identifiers for now\n                const identifier = this.quoteIdentifiers(`${previousModel.name}.${previousModel.rawAttributes[itemSplit[0]].field}`);\n\n                // get path\n                const path = itemSplit.slice(1);\n\n                // extract path\n                item = this.jsonPathExtractionQuery(identifier, path);\n\n                // literal because we don't want to append the model name when string\n                item = this.sequelize.literal(item);\n              }\n            }\n          }\n        }\n\n        collection[index] = item;\n      }, this);\n\n      // loop through array, adding table names of models to quoted\n      const collectionLength = collection.length;\n      const tableNames = [];\n      let item;\n      let i = 0;\n\n      for (i = 0; i < collectionLength - 1; i++) {\n        item = collection[i];\n        if (typeof item === 'string' || item._modelAttribute || item instanceof Utils.SequelizeMethod) {\n          break;\n        } else if (item instanceof Association) {\n          tableNames[i] = item.as;\n        }\n      }\n\n      // start building sql\n      let sql = '';\n\n      if (i > 0) {\n        sql += `${this.quoteIdentifier(tableNames.join(connector))}.`;\n      } else if (typeof collection[0] === 'string' && parent) {\n        sql += `${this.quoteIdentifier(parent.name)}.`;\n      }\n\n      // loop through everything past i and append to the sql\n      collection.slice(i).forEach(collectionItem => {\n        sql += this.quote(collectionItem, parent, connector);\n      }, this);\n\n      return sql;\n    }\n    if (collection._modelAttribute) {\n      return `${this.quoteTable(collection.Model.name)}.${this.quoteIdentifier(collection.fieldName)}`;\n    }\n    if (collection instanceof Utils.SequelizeMethod) {\n      return this.handleSequelizeMethod(collection);\n    }\n    if (_.isPlainObject(collection) && collection.raw) {\n      // simple objects with raw is no longer supported\n      throw new Error('The `{raw: \"...\"}` syntax is no longer supported.  Use `sequelize.literal` instead.');\n    }\n    throw new Error(`Unknown structure passed to order / group: ${util.inspect(collection)}`);\n  }\n\n  _initQuoteIdentifier() {\n    this._quoteIdentifier = this.quoteIdentifier;\n    this.quoteIdentifier = function(identifier, force) {\n      if (identifier === '*') return identifier;\n      return this._quoteIdentifier(identifier, force);\n    };\n  }\n\n  /**\n   * Adds quotes to identifier\n   *\n   * @param {string} identifier\n   * @param {boolean} force\n   *\n   * @returns {string}\n   */\n  quoteIdentifier(identifier, force) {\n    throw new Error(`quoteIdentifier for Dialect \"${this.dialect}\" is not implemented`);\n  }\n\n  /**\n   * Split a list of identifiers by \".\" and quote each part.\n   *\n   * @param {string} identifiers\n   *\n   * @returns {string}\n   */\n  quoteIdentifiers(identifiers) {\n    if (identifiers.includes('.')) {\n      identifiers = identifiers.split('.');\n\n      const head = identifiers.slice(0, identifiers.length - 1).join('->');\n      const tail = identifiers[identifiers.length - 1];\n\n      return `${this.quoteIdentifier(head)}.${this.quoteIdentifier(tail)}`;\n    }\n\n    return this.quoteIdentifier(identifiers);\n  }\n\n  quoteAttribute(attribute, model) {\n    if (model && attribute in model.rawAttributes) {\n      return this.quoteIdentifier(attribute);\n    }\n    return this.quoteIdentifiers(attribute);\n  }\n\n  /**\n   * Returns the alias token\n   *\n   * @returns {string}\n   */\n  getAliasToken() {\n    return 'AS';\n  }\n\n  /**\n   * Quote table name with optional alias and schema attribution\n   *\n   * @param {string|object}  param table string or object\n   * @param {string|boolean} alias alias name\n   *\n   * @returns {string}\n   */\n  quoteTable(param, alias) {\n    let table = '';\n\n    if (alias === true) {\n      alias = param.as || param.name || param;\n    }\n\n    if (_.isObject(param)) {\n      if (this._dialect.supports.schemas) {\n        if (param.schema) {\n          table += `${this.quoteIdentifier(param.schema)}.`;\n        }\n\n        table += this.quoteIdentifier(param.tableName);\n      } else {\n        if (param.schema) {\n          table += param.schema + (param.delimiter || '.');\n        }\n\n        table += param.tableName;\n        table = this.quoteIdentifier(table);\n      }\n    } else {\n      table = this.quoteIdentifier(param);\n    }\n\n    if (alias) {\n      table += ` ${this.getAliasToken()} ${this.quoteIdentifier(alias)}`;\n    }\n\n    return table;\n  }\n\n  /*\n    Escape a value (e.g. a string, number or date)\n    @private\n  */\n  escape(value, field, options) {\n    options = options || {};\n\n    if (value !== null && value !== undefined) {\n      if (value instanceof Utils.SequelizeMethod) {\n        return this.handleSequelizeMethod(value);\n      }\n      if (field && field.type) {\n        if (field.type instanceof DataTypes.STRING\n            && ['mysql', 'mariadb'].includes(this.dialect)\n            && ['number', 'boolean'].includes(typeof value)) {\n          value = String(Number(value));\n        }\n              \n        this.validate(value, field, options);\n\n        if (field.type.stringify) {\n          // Users shouldn't have to worry about these args - just give them a function that takes a single arg\n          const simpleEscape = escVal => SqlString.escape(escVal, this.options.timezone, this.dialect);\n\n          value = field.type.stringify(value, { escape: simpleEscape, field, timezone: this.options.timezone, operation: options.operation });\n\n          if (field.type.escape === false) {\n            // The data-type already did the required escaping\n            return value;\n          }\n        }\n      }\n    }\n    return SqlString.escape(value, this.options.timezone, this.dialect);\n  }\n\n  bindParam(bind) {\n    return value => {\n      bind.push(value);\n      return `$${bind.length}`;\n    };\n  }\n\n  /*\n    Returns a bind parameter representation of a value (e.g. a string, number or date)\n    @private\n  */\n  format(value, field, options, bindParam) {\n    options = options || {};\n\n    if (value !== null && value !== undefined) {\n      if (value instanceof Utils.SequelizeMethod) {\n        throw new Error('Cannot pass SequelizeMethod as a bind parameter - use escape instead');\n      }\n      if (field && field.type) {\n        this.validate(value, field, options);\n\n        if (field.type.bindParam) {\n          return field.type.bindParam(value, { escape: _.identity, field, timezone: this.options.timezone, operation: options.operation, bindParam });\n        }\n      }\n    }\n\n    return bindParam(value);\n  }\n\n  /*\n    Validate a value against a field specification\n    @private\n  */\n  validate(value, field, options) {\n    if (this.typeValidation && field.type.validate && value) {\n      try {\n        if (options.isList && Array.isArray(value)) {\n          for (const item of value) {\n            field.type.validate(item, options);\n          }\n        } else {\n          field.type.validate(value, options);\n        }\n      } catch (error) {\n        if (error instanceof sequelizeError.ValidationError) {\n          error.errors.push(new sequelizeError.ValidationErrorItem(\n            error.message,\n            'Validation error',\n            field.fieldName,\n            value,\n            null,\n            `${field.type.key} validator`\n          ));\n        }\n\n        throw error;\n      }\n    }\n  }\n\n  isIdentifierQuoted(identifier) {\n    return /^\\s*(?:([`\"'])(?:(?!\\1).|\\1{2})*\\1\\.?)+\\s*$/i.test(identifier);\n  }\n\n  /**\n   * Generates an SQL query that extract JSON property of given path.\n   *\n   * @param   {string}               column   The JSON column\n   * @param   {string|Array<string>} [path]   The path to extract (optional)\n   * @param   {boolean}              [isJson] The value is JSON use alt symbols (optional)\n   * @returns {string}                        The generated sql query\n   * @private\n   */\n  jsonPathExtractionQuery(column, path, isJson) {\n    let paths = _.toPath(path);\n    let pathStr;\n    const quotedColumn = this.isIdentifierQuoted(column)\n      ? column\n      : this.quoteIdentifier(column);\n\n    switch (this.dialect) {\n      case 'mysql':\n      case 'mariadb':\n      case 'sqlite':\n        /**\n         * Non digit sub paths need to be quoted as ECMAScript identifiers\n         * https://bugs.mysql.com/bug.php?id=81896\n         */\n        if (this.dialect === 'mysql') {\n          paths = paths.map(subPath => {\n            return /\\D/.test(subPath)\n              ? Utils.addTicks(subPath, '\"')\n              : subPath;\n          });\n        }\n\n        pathStr = this.escape(['$']\n          .concat(paths)\n          .join('.')\n          .replace(/\\.(\\d+)(?:(?=\\.)|$)/g, (__, digit) => `[${digit}]`));\n\n        if (this.dialect === 'sqlite') {\n          return `json_extract(${quotedColumn},${pathStr})`;\n        }\n\n        return `json_unquote(json_extract(${quotedColumn},${pathStr}))`;\n\n      case 'postgres':\n        const join = isJson ? '#>' : '#>>';\n        pathStr = this.escape(`{${paths.join(',')}}`);\n        return `(${quotedColumn}${join}${pathStr})`;\n\n      default:\n        throw new Error(`Unsupported ${this.dialect} for JSON operations`);\n    }\n  }\n\n  /*\n    Returns a query for selecting elements in the table <tableName>.\n    Options:\n      - attributes -> An array of attributes (e.g. ['name', 'birthday']). Default: *\n      - where -> A hash with conditions (e.g. {name: 'foo'})\n                 OR an ID as integer\n      - order -> e.g. 'id DESC'\n      - group\n      - limit -> The maximum count you want to get.\n      - offset -> An offset value to start from. Only useable with limit!\n   @private\n  */\n  selectQuery(tableName, options, model) {\n    options = options || {};\n    const limit = options.limit;\n    const mainQueryItems = [];\n    const subQueryItems = [];\n    const subQuery = options.subQuery === undefined ? limit && options.hasMultiAssociation : options.subQuery;\n    const attributes = {\n      main: options.attributes && options.attributes.slice(),\n      subQuery: null\n    };\n    const mainTable = {\n      name: tableName,\n      quotedName: null,\n      as: null,\n      model\n    };\n    const topLevelInfo = {\n      names: mainTable,\n      options,\n      subQuery\n    };\n    let mainJoinQueries = [];\n    let subJoinQueries = [];\n    let query;\n\n    // Aliases can be passed through subqueries and we don't want to reset them\n    if (this.options.minifyAliases && !options.aliasesMapping) {\n      options.aliasesMapping = new Map();\n      options.aliasesByTable = {};\n      options.includeAliases = new Map();\n    }\n\n    // resolve table name options\n    if (options.tableAs) {\n      mainTable.as = this.quoteIdentifier(options.tableAs);\n    } else if (!Array.isArray(mainTable.name) && mainTable.model) {\n      mainTable.as = this.quoteIdentifier(mainTable.model.name);\n    }\n\n    mainTable.quotedName = !Array.isArray(mainTable.name) ? this.quoteTable(mainTable.name) : tableName.map(t => {\n      return Array.isArray(t) ? this.quoteTable(t[0], t[1]) : this.quoteTable(t, true);\n    }).join(', ');\n\n    if (subQuery && attributes.main) {\n      for (const keyAtt of mainTable.model.primaryKeyAttributes) {\n        // Check if mainAttributes contain the primary key of the model either as a field or an aliased field\n        if (!attributes.main.some(attr => keyAtt === attr || keyAtt === attr[0] || keyAtt === attr[1])) {\n          attributes.main.push(mainTable.model.rawAttributes[keyAtt].field ? [keyAtt, mainTable.model.rawAttributes[keyAtt].field] : keyAtt);\n        }\n      }\n    }\n\n    attributes.main = this.escapeAttributes(attributes.main, options, mainTable.as);\n    attributes.main = attributes.main || (options.include ? [`${mainTable.as}.*`] : ['*']);\n\n    // If subquery, we add the mainAttributes to the subQuery and set the mainAttributes to select * from subquery\n    if (subQuery || options.groupedLimit) {\n      // We need primary keys\n      attributes.subQuery = attributes.main;\n      attributes.main = [`${mainTable.as || mainTable.quotedName}.*`];\n    }\n\n    if (options.include) {\n      for (const include of options.include) {\n        if (include.separate) {\n          continue;\n        }\n        const joinQueries = this.generateInclude(include, { externalAs: mainTable.as, internalAs: mainTable.as }, topLevelInfo);\n\n        subJoinQueries = subJoinQueries.concat(joinQueries.subQuery);\n        mainJoinQueries = mainJoinQueries.concat(joinQueries.mainQuery);\n\n        if (joinQueries.attributes.main.length > 0) {\n          attributes.main = _.uniq(attributes.main.concat(joinQueries.attributes.main));\n        }\n        if (joinQueries.attributes.subQuery.length > 0) {\n          attributes.subQuery = _.uniq(attributes.subQuery.concat(joinQueries.attributes.subQuery));\n        }\n      }\n    }\n\n    if (subQuery) {\n      subQueryItems.push(this.selectFromTableFragment(options, mainTable.model, attributes.subQuery, mainTable.quotedName, mainTable.as));\n      subQueryItems.push(subJoinQueries.join(''));\n    } else {\n      if (options.groupedLimit) {\n        if (!mainTable.as) {\n          mainTable.as = mainTable.quotedName;\n        }\n        const where = { ...options.where };\n        let groupedLimitOrder,\n          whereKey,\n          include,\n          groupedTableName = mainTable.as;\n\n        if (typeof options.groupedLimit.on === 'string') {\n          whereKey = options.groupedLimit.on;\n        } else if (options.groupedLimit.on instanceof HasMany) {\n          whereKey = options.groupedLimit.on.foreignKeyField;\n        }\n\n        if (options.groupedLimit.on instanceof BelongsToMany) {\n          // BTM includes needs to join the through table on to check ID\n          groupedTableName = options.groupedLimit.on.manyFromSource.as;\n          const groupedLimitOptions = Model._validateIncludedElements({\n            include: [{\n              association: options.groupedLimit.on.manyFromSource,\n              duplicating: false, // The UNION'ed query may contain duplicates, but each sub-query cannot\n              required: true,\n              where: {\n                [Op.placeholder]: true,\n                ...options.groupedLimit.through && options.groupedLimit.through.where\n              }\n            }],\n            model\n          });\n\n          // Make sure attributes from the join table are mapped back to models\n          options.hasJoin = true;\n          options.hasMultiAssociation = true;\n          options.includeMap = Object.assign(groupedLimitOptions.includeMap, options.includeMap);\n          options.includeNames = groupedLimitOptions.includeNames.concat(options.includeNames || []);\n          include = groupedLimitOptions.include;\n\n          if (Array.isArray(options.order)) {\n            // We need to make sure the order by attributes are available to the parent query\n            options.order.forEach((order, i) => {\n              if (Array.isArray(order)) {\n                order = order[0];\n              }\n\n              let alias = `subquery_order_${i}`;\n              options.attributes.push([order, alias]);\n\n              // We don't want to prepend model name when we alias the attributes, so quote them here\n              alias = this.sequelize.literal(this.quote(alias));\n\n              if (Array.isArray(options.order[i])) {\n                options.order[i][0] = alias;\n              } else {\n                options.order[i] = alias;\n              }\n            });\n            groupedLimitOrder = options.order;\n          }\n        } else {\n          // Ordering is handled by the subqueries, so ordering the UNION'ed result is not needed\n          groupedLimitOrder = options.order;\n\n          // For the Oracle dialect, the result of a select is a set, not a sequence, and so is the result of UNION.\n          // So the top level ORDER BY is required\n          if (!this._dialect.supports.topLevelOrderByRequired) {\n            delete options.order;\n          }\n          where[Op.placeholder] = true;\n        }\n\n        // Caching the base query and splicing the where part into it is consistently > twice\n        // as fast than generating from scratch each time for values.length >= 5\n        const baseQuery = `SELECT * FROM (${this.selectQuery(\n          tableName,\n          {\n            attributes: options.attributes,\n            offset: options.offset,\n            limit: options.groupedLimit.limit,\n            order: groupedLimitOrder,\n            aliasesMapping: options.aliasesMapping,\n            aliasesByTable: options.aliasesByTable,\n            where,\n            include,\n            model\n          },\n          model\n        ).replace(/;$/, '')}) ${this.getAliasToken()} sub`; // Every derived table must have its own alias\n        const placeHolder = this.whereItemQuery(Op.placeholder, true, { model });\n        const splicePos = baseQuery.indexOf(placeHolder);\n\n        mainQueryItems.push(this.selectFromTableFragment(options, mainTable.model, attributes.main, `(${\n          options.groupedLimit.values.map(value => {\n            let groupWhere;\n            if (whereKey) {\n              groupWhere = {\n                [whereKey]: value\n              };\n            }\n            if (include) {\n              groupWhere = {\n                [options.groupedLimit.on.foreignIdentifierField]: value\n              };\n            }\n\n            return Utils.spliceStr(baseQuery, splicePos, placeHolder.length, this.getWhereConditions(groupWhere, groupedTableName));\n          }).join(\n            this._dialect.supports['UNION ALL'] ? ' UNION ALL ' : ' UNION '\n          )\n        })`, mainTable.as));\n      } else {\n        mainQueryItems.push(this.selectFromTableFragment(options, mainTable.model, attributes.main, mainTable.quotedName, mainTable.as));\n      }\n\n      mainQueryItems.push(mainJoinQueries.join(''));\n    }\n\n    // Add WHERE to sub or main query\n    if (Object.prototype.hasOwnProperty.call(options, 'where') && !options.groupedLimit) {\n      options.where = this.getWhereConditions(options.where, mainTable.as || tableName, model, options);\n      if (options.where) {\n        if (subQuery) {\n          subQueryItems.push(` WHERE ${options.where}`);\n        } else {\n          mainQueryItems.push(` WHERE ${options.where}`);\n          // Walk the main query to update all selects\n          mainQueryItems.forEach((value, key) => {\n            if (value.startsWith('SELECT')) {\n              mainQueryItems[key] = this.selectFromTableFragment(options, model, attributes.main, mainTable.quotedName, mainTable.as, options.where);\n            }\n          });\n        }\n      }\n    }\n\n    // Add GROUP BY to sub or main query\n    if (options.group) {\n      options.group = Array.isArray(options.group) ? options.group.map(t => this.aliasGrouping(t, model, mainTable.as, options)).join(', ') : this.aliasGrouping(options.group, model, mainTable.as, options);\n\n      if (subQuery && options.group) {\n        subQueryItems.push(` GROUP BY ${options.group}`);\n      } else if (options.group) {\n        mainQueryItems.push(` GROUP BY ${options.group}`);\n      }\n    }\n\n    // Add HAVING to sub or main query\n    if (Object.prototype.hasOwnProperty.call(options, 'having')) {\n      options.having = this.getWhereConditions(options.having, tableName, model, options, false);\n      if (options.having) {\n        if (subQuery) {\n          subQueryItems.push(` HAVING ${options.having}`);\n        } else {\n          mainQueryItems.push(` HAVING ${options.having}`);\n        }\n      }\n    }\n\n    // Add ORDER to sub or main query\n    if (options.order) {\n      const orders = this.getQueryOrders(options, model, subQuery);\n      if (orders.mainQueryOrder.length) {\n        mainQueryItems.push(` ORDER BY ${orders.mainQueryOrder.join(', ')}`);\n      }\n      if (orders.subQueryOrder.length) {\n        subQueryItems.push(` ORDER BY ${orders.subQueryOrder.join(', ')}`);\n      }\n    }\n\n    // Add LIMIT, OFFSET to sub or main query\n    const limitOrder = this.addLimitAndOffset(options, mainTable.model);\n    if (limitOrder && !options.groupedLimit) {\n      if (subQuery) {\n        subQueryItems.push(limitOrder);\n      } else {\n        mainQueryItems.push(limitOrder);\n      }\n    }\n\n    if (subQuery) {\n      this._throwOnEmptyAttributes(attributes.main, { modelName: model && model.name, as: mainTable.as });\n      query = `SELECT ${attributes.main.join(', ')} FROM (${subQueryItems.join('')}) ${this.getAliasToken()} ${mainTable.as}${mainJoinQueries.join('')}${mainQueryItems.join('')}`;\n    } else {\n      query = mainQueryItems.join('');\n    }\n\n    if (options.lock && this._dialect.supports.lock) {\n      let lock = options.lock;\n      if (typeof options.lock === 'object') {\n        lock = options.lock.level;\n      }\n      if (this._dialect.supports.lockKey && ['KEY SHARE', 'NO KEY UPDATE'].includes(lock)) {\n        query += ` FOR ${lock}`;\n      } else if (lock === 'SHARE') {\n        query += ` ${this._dialect.supports.forShare}`;\n      } else {\n        query += ' FOR UPDATE';\n      }\n      if (this._dialect.supports.lockOf && options.lock.of && options.lock.of.prototype instanceof Model) {\n        query += ` OF ${this.quoteTable(options.lock.of.name)}`;\n      }\n      if (this._dialect.supports.skipLocked && options.skipLocked) {\n        query += ' SKIP LOCKED';\n      }\n    }\n\n    return `${query};`;\n  }\n\n  aliasGrouping(field, model, tableName, options) {\n    const src = Array.isArray(field) ? field[0] : field;\n\n    return this.quote(this._getAliasForField(tableName, src, options) || src, model);\n  }\n\n  escapeAttributes(attributes, options, mainTableAs) {\n    return attributes && attributes.map(attr => {\n      let addTable = true;\n\n      if (attr instanceof Utils.SequelizeMethod) {\n        return this.handleSequelizeMethod(attr);\n      }\n      if (Array.isArray(attr)) {\n        if (attr.length !== 2) {\n          throw new Error(`${JSON.stringify(attr)} is not a valid attribute definition. Please use the following format: ['attribute definition', 'alias']`);\n        }\n        attr = attr.slice();\n\n        if (attr[0] instanceof Utils.SequelizeMethod) {\n          attr[0] = this.handleSequelizeMethod(attr[0]);\n          addTable = false;\n        } else if (this.options.attributeBehavior === 'escape' || !attr[0].includes('(') && !attr[0].includes(')')) {\n          attr[0] = this.quoteIdentifier(attr[0]);\n        } else if (this.options.attributeBehavior !== 'unsafe-legacy') {\n          throw new Error(`Attributes cannot include parentheses in Sequelize 6:\nIn order to fix the vulnerability CVE-2023-22578, we had to remove support for treating attributes as raw SQL if they included parentheses.\nSequelize 7 escapes all attributes, even if they include parentheses.\nFor Sequelize 6, because we're introducing this change in a minor release, we've opted for throwing an error instead of silently escaping the attribute as a way to warn you about this change.\n\nHere is what you can do to fix this error:\n- Wrap the attribute in a literal() call. This will make Sequelize treat it as raw SQL.\n- Set the \"attributeBehavior\" sequelize option to \"escape\" to make Sequelize escape the attribute, like in Sequelize v7. We highly recommend this option.\n- Set the \"attributeBehavior\" sequelize option to \"unsafe-legacy\" to make Sequelize escape the attribute, like in Sequelize v5.\n\nWe sincerely apologize for the inconvenience this may cause you. You can find more information on the following threads:\nhttps://github.com/sequelize/sequelize/security/advisories/GHSA-f598-mfpv-gmfx\nhttps://github.com/sequelize/sequelize/discussions/15694`);\n        }\n\n        let alias = attr[1];\n\n        if (this.options.minifyAliases) {\n          alias = this._getMinifiedAlias(alias, mainTableAs, options);\n        }\n\n        attr = [attr[0], this.quoteIdentifier(alias)].join(' AS ');\n      } else {\n        attr = !attr.includes(Utils.TICK_CHAR) && !attr.includes('\"')\n          ? this.quoteAttribute(attr, options.model)\n          : this.escape(attr);\n      }\n      if (!_.isEmpty(options.include) && (!attr.includes('.') || options.dotNotation) && addTable) {\n        attr = `${mainTableAs}.${attr}`;\n      }\n\n      return attr;\n    });\n  }\n\n  generateInclude(include, parentTableName, topLevelInfo) {\n    const joinQueries = {\n      mainQuery: [],\n      subQuery: []\n    };\n    const mainChildIncludes = [];\n    const subChildIncludes = [];\n    let requiredMismatch = false;\n    const includeAs = {\n      internalAs: include.as,\n      externalAs: include.as\n    };\n    const attributes = {\n      main: [],\n      subQuery: []\n    };\n    let joinQuery;\n\n    topLevelInfo.options.keysEscaped = true;\n\n    if (topLevelInfo.names.name !== parentTableName.externalAs && topLevelInfo.names.as !== parentTableName.externalAs) {\n      includeAs.internalAs = `${parentTableName.internalAs}->${include.as}`;\n      includeAs.externalAs = `${parentTableName.externalAs}.${include.as}`;\n    }\n\n    // includeIgnoreAttributes is used by aggregate functions\n    if (topLevelInfo.options.includeIgnoreAttributes !== false) {\n      include.model._expandAttributes(include);\n      Utils.mapFinderOptions(include, include.model);\n\n      const includeAttributes = include.attributes.map(attr => {\n        let attrAs = attr;\n        let verbatim = false;\n\n        if (Array.isArray(attr) && attr.length === 2) {\n          if (attr[0] instanceof Utils.SequelizeMethod && (\n            attr[0] instanceof Utils.Literal ||\n            attr[0] instanceof Utils.Cast ||\n            attr[0] instanceof Utils.Fn\n          )) {\n            verbatim = true;\n          }\n\n          attr = attr.map(attr => attr instanceof Utils.SequelizeMethod ? this.handleSequelizeMethod(attr) : attr);\n\n          attrAs = attr[1];\n          attr = attr[0];\n        }\n        if (attr instanceof Utils.Literal) {\n          return attr.val; // We trust the user to rename the field correctly\n        }\n        if (attr instanceof Utils.Cast || attr instanceof Utils.Fn) {\n          throw new Error(\n            'Tried to select attributes using Sequelize.cast or Sequelize.fn without specifying an alias for the result, during eager loading. ' +\n            'This means the attribute will not be added to the returned instance'\n          );\n        }\n\n        let prefix;\n        if (verbatim === true) {\n          prefix = attr;\n        } else if (/#>>|->>/.test(attr)) {\n          prefix = `(${this.quoteIdentifier(includeAs.internalAs)}.${attr.replace(/\\(|\\)/g, '')})`;\n        } else if (/json_extract\\(/.test(attr)) {\n          prefix = attr.replace(/json_extract\\(/i, `json_extract(${this.quoteIdentifier(includeAs.internalAs)}.`);\n        } else if (/json_value\\(/.test(attr)) {\n          prefix = attr.replace(/json_value\\(/i, `json_value(${this.quoteIdentifier(includeAs.internalAs)}.`);\n        } else {\n          prefix = `${this.quoteIdentifier(includeAs.internalAs)}.${this.quoteIdentifier(attr)}`;\n        }\n        let alias = `${includeAs.externalAs}.${attrAs}`;\n\n        if (this.options.minifyAliases) {\n          alias = this._getMinifiedAlias(alias, includeAs.internalAs, topLevelInfo.options);\n        }\n\n        return Utils.joinSQLFragments([\n          prefix,\n          'AS',\n          this.quoteIdentifier(alias, true)\n        ]);\n      });\n      if (include.subQuery && topLevelInfo.subQuery) {\n        for (const attr of includeAttributes) {\n          attributes.subQuery.push(attr);\n        }\n      } else {\n        for (const attr of includeAttributes) {\n          attributes.main.push(attr);\n        }\n      }\n    }\n\n    //through\n    if (include.through) {\n      joinQuery = this.generateThroughJoin(include, includeAs, parentTableName.internalAs, topLevelInfo);\n    } else {\n      this._generateSubQueryFilter(include, includeAs, topLevelInfo);\n      joinQuery = this.generateJoin(include, topLevelInfo);\n    }\n\n    // handle possible new attributes created in join\n    if (joinQuery.attributes.main.length > 0) {\n      attributes.main = attributes.main.concat(joinQuery.attributes.main);\n    }\n\n    if (joinQuery.attributes.subQuery.length > 0) {\n      attributes.subQuery = attributes.subQuery.concat(joinQuery.attributes.subQuery);\n    }\n\n    if (include.include) {\n      for (const childInclude of include.include) {\n        if (childInclude.separate || childInclude._pseudo) {\n          continue;\n        }\n\n        const childJoinQueries = this.generateInclude(childInclude, includeAs, topLevelInfo);\n\n        if (include.required === false && childInclude.required === true) {\n          requiredMismatch = true;\n        }\n        // if the child is a sub query we just give it to the\n        if (childInclude.subQuery && topLevelInfo.subQuery) {\n          subChildIncludes.push(childJoinQueries.subQuery);\n        }\n        if (childJoinQueries.mainQuery) {\n          mainChildIncludes.push(childJoinQueries.mainQuery);\n        }\n        if (childJoinQueries.attributes.main.length > 0) {\n          attributes.main = attributes.main.concat(childJoinQueries.attributes.main);\n        }\n        if (childJoinQueries.attributes.subQuery.length > 0) {\n          attributes.subQuery = attributes.subQuery.concat(childJoinQueries.attributes.subQuery);\n        }\n      }\n    }\n\n    if (include.subQuery && topLevelInfo.subQuery) {\n      if (requiredMismatch && subChildIncludes.length > 0) {\n        joinQueries.subQuery.push(` ${joinQuery.join} ( ${joinQuery.body}${subChildIncludes.join('')} ) ON ${joinQuery.condition}`);\n      } else {\n        joinQueries.subQuery.push(` ${joinQuery.join} ${joinQuery.body} ON ${joinQuery.condition}`);\n        if (subChildIncludes.length > 0) {\n          joinQueries.subQuery.push(subChildIncludes.join(''));\n        }\n      }\n      joinQueries.mainQuery.push(mainChildIncludes.join(''));\n    } else {\n      if (requiredMismatch && mainChildIncludes.length > 0) {\n        joinQueries.mainQuery.push(` ${joinQuery.join} ( ${joinQuery.body}${mainChildIncludes.join('')} ) ON ${joinQuery.condition}`);\n      } else {\n        joinQueries.mainQuery.push(` ${joinQuery.join} ${joinQuery.body} ON ${joinQuery.condition}`);\n        if (mainChildIncludes.length > 0) {\n          joinQueries.mainQuery.push(mainChildIncludes.join(''));\n        }\n      }\n      joinQueries.subQuery.push(subChildIncludes.join(''));\n    }\n\n    return {\n      mainQuery: joinQueries.mainQuery.join(''),\n      subQuery: joinQueries.subQuery.join(''),\n      attributes\n    };\n  }\n\n  _getMinifiedAlias(alias, tableName, options) {\n    // We do not want to re-alias in case of a subquery\n    if (options.aliasesByTable[`${tableName}${alias}`]) {\n      return options.aliasesByTable[`${tableName}${alias}`];\n    }\n\n    // Do not alias custom suquery_orders\n    if (alias.match(/subquery_order_[0-9]/)) {\n      return alias;\n    }\n\n    const minifiedAlias = `_${options.aliasesMapping.size}`;\n\n    options.aliasesMapping.set(minifiedAlias, alias);\n    options.aliasesByTable[`${tableName}${alias}`] = minifiedAlias;\n\n    return minifiedAlias;\n  }\n\n  _getAliasForField(tableName, field, options) {\n    if (this.options.minifyAliases) {\n      if (options.aliasesByTable[`${tableName}${field}`]) {\n        return options.aliasesByTable[`${tableName}${field}`];\n      }\n    }\n    return null;\n  }\n\n  generateJoin(include, topLevelInfo) {\n    const association = include.association;\n    const parent = include.parent;\n    const parentIsTop = !!parent && !include.parent.association && include.parent.model.name === topLevelInfo.options.model.name;\n    let $parent;\n    let joinWhere;\n    /* Attributes for the left side */\n    const left = association.source;\n    const attrLeft = association instanceof BelongsTo ?\n      association.identifier :\n      association.sourceKeyAttribute || left.primaryKeyAttribute;\n    const fieldLeft = association instanceof BelongsTo ?\n      association.identifierField :\n      left.rawAttributes[association.sourceKeyAttribute || left.primaryKeyAttribute].field;\n    let asLeft;\n    /* Attributes for the right side */\n    const right = include.model;\n    const tableRight = right.getTableName();\n    const fieldRight = association instanceof BelongsTo ?\n      right.rawAttributes[association.targetIdentifier || right.primaryKeyAttribute].field :\n      association.identifierField;\n    let asRight = include.as;\n\n    while (($parent = $parent && $parent.parent || include.parent) && $parent.association) {\n      if (asLeft) {\n        asLeft = `${$parent.as}->${asLeft}`;\n      } else {\n        asLeft = $parent.as;\n      }\n    }\n\n    if (!asLeft) asLeft = parent.as || parent.model.name;\n    else asRight = `${asLeft}->${asRight}`;\n\n    let joinOn = `${this.quoteTable(asLeft)}.${this.quoteIdentifier(fieldLeft)}`;\n    const subqueryAttributes = [];\n\n    if (topLevelInfo.options.groupedLimit && parentIsTop || topLevelInfo.subQuery && include.parent.subQuery && !include.subQuery) {\n      if (parentIsTop) {\n        // The main model attributes is not aliased to a prefix\n        const tableName = this.quoteTable(parent.as || parent.model.name);\n\n        // Check for potential aliased JOIN condition\n        joinOn = this._getAliasForField(tableName, attrLeft, topLevelInfo.options) || `${tableName}.${this.quoteIdentifier(attrLeft)}`;\n\n        if (topLevelInfo.subQuery) {\n          const dbIdentifier = `${tableName}.${this.quoteIdentifier(fieldLeft)}`;\n          subqueryAttributes.push(dbIdentifier !== joinOn ? `${dbIdentifier} AS ${this.quoteIdentifier(attrLeft)}` : dbIdentifier);\n        }\n      } else {\n        const joinSource = `${asLeft.replace(/->/g, '.')}.${attrLeft}`;\n\n        // Check for potential aliased JOIN condition\n        joinOn = this._getAliasForField(asLeft, joinSource, topLevelInfo.options) || this.quoteIdentifier(joinSource);\n      }\n    }\n\n    joinOn += ` = ${this.quoteIdentifier(asRight)}.${this.quoteIdentifier(fieldRight)}`;\n\n    if (include.on) {\n      joinOn = this.whereItemsQuery(include.on, {\n        prefix: this.sequelize.literal(this.quoteIdentifier(asRight)),\n        model: include.model\n      });\n    }\n\n    if (include.where) {\n      joinWhere = this.whereItemsQuery(include.where, {\n        prefix: this.sequelize.literal(this.quoteIdentifier(asRight)),\n        model: include.model\n      });\n      if (joinWhere) {\n        if (include.or) {\n          joinOn += ` OR ${joinWhere}`;\n        } else {\n          joinOn += ` AND ${joinWhere}`;\n        }\n      }\n    }\n\n    this.aliasAs(asRight, topLevelInfo);\n\n    return {\n      join: include.required ? 'INNER JOIN' : include.right && this._dialect.supports['RIGHT JOIN'] ? 'RIGHT OUTER JOIN' : 'LEFT OUTER JOIN',\n      body: this.quoteTable(tableRight, asRight),\n      condition: joinOn,\n      attributes: {\n        main: [],\n        subQuery: subqueryAttributes\n      }\n    };\n  }\n\n  /**\n   * Returns the SQL fragments to handle returning the attributes from an insert/update query.\n   *\n   * @param  {object} modelAttributes An object with the model attributes.\n   * @param  {object} options         An object with options.\n   *\n   * @private\n   */\n  generateReturnValues(modelAttributes, options) {\n    const returnFields = [];\n    const returnTypes = [];\n    let outputFragment = '';\n    let returningFragment = '';\n    let tmpTable = '';\n\n    if (Array.isArray(options.returning)) {\n      returnFields.push(...options.returning.map(field => this.quoteIdentifier(field)));\n    } else if (modelAttributes) {\n      _.each(modelAttributes, attribute => {\n        if (!(attribute.type instanceof DataTypes.VIRTUAL)) {\n          returnFields.push(this.quoteIdentifier(attribute.field));\n          returnTypes.push(attribute.type);\n        }\n      });\n    }\n\n    if (_.isEmpty(returnFields)) {\n      returnFields.push('*');\n    }\n\n    if (this._dialect.supports.returnValues.returning) {\n      returningFragment = ` RETURNING ${returnFields.join(',')}`;\n    } else if (this._dialect.supports.returnIntoValues) {\n      returningFragment = ` RETURNING ${returnFields.join(',')} INTO `;\n    } else if (this._dialect.supports.returnValues.output) {\n      outputFragment = ` OUTPUT ${returnFields.map(field => `INSERTED.${field}`).join(',')}`;\n\n      //To capture output rows when there is a trigger on MSSQL DB\n      if (options.hasTrigger && this._dialect.supports.tmpTableTrigger) {\n        const tmpColumns = returnFields.map((field, i) => `${field} ${returnTypes[i].toSql()}`);\n\n        tmpTable = `DECLARE @tmp TABLE (${tmpColumns.join(',')}); `;\n        outputFragment += ' INTO @tmp';\n        returningFragment = '; SELECT * FROM @tmp';\n      }\n    }\n\n    return { outputFragment, returnFields, returnTypes, returningFragment, tmpTable };\n  }\n\n  generateThroughJoin(include, includeAs, parentTableName, topLevelInfo) {\n    const through = include.through;\n    const throughTable = through.model.getTableName();\n    const throughAs = `${includeAs.internalAs}->${through.as}`;\n    const externalThroughAs = `${includeAs.externalAs}.${through.as}`;\n    const throughAttributes = through.attributes.map(attr => {\n      let alias = `${externalThroughAs}.${Array.isArray(attr) ? attr[1] : attr}`;\n\n      if (this.options.minifyAliases) {\n        alias = this._getMinifiedAlias(alias, throughAs, topLevelInfo.options);\n      }\n\n      return Utils.joinSQLFragments([\n        `${this.quoteIdentifier(throughAs)}.${this.quoteIdentifier(Array.isArray(attr) ? attr[0] : attr)}`,\n        'AS',\n        this.quoteIdentifier(alias)\n      ]);\n    });\n    const association = include.association;\n    const parentIsTop = !include.parent.association && include.parent.model.name === topLevelInfo.options.model.name;\n    const tableSource = parentTableName;\n    const identSource = association.identifierField;\n    const tableTarget = includeAs.internalAs;\n    const identTarget = association.foreignIdentifierField;\n    const attrTarget = association.targetKeyField;\n\n    const joinType = include.required ? 'INNER JOIN' : include.right && this._dialect.supports['RIGHT JOIN'] ? 'RIGHT OUTER JOIN' : 'LEFT OUTER JOIN';\n    let joinBody;\n    let joinCondition;\n    const attributes = {\n      main: [],\n      subQuery: []\n    };\n    let attrSource = association.sourceKey;\n    let sourceJoinOn;\n    let targetJoinOn;\n    let throughWhere;\n    let targetWhere;\n\n    if (topLevelInfo.options.includeIgnoreAttributes !== false) {\n      // Through includes are always hasMany, so we need to add the attributes to the mainAttributes no matter what (Real join will never be executed in subquery)\n      for (const attr of throughAttributes) {\n        attributes.main.push(attr);\n      }\n    }\n\n    // Figure out if we need to use field or attribute\n    if (!topLevelInfo.subQuery) {\n      attrSource = association.sourceKeyField;\n    }\n    if (topLevelInfo.subQuery && !include.subQuery && !include.parent.subQuery && include.parent.model !== topLevelInfo.options.mainModel) {\n      attrSource = association.sourceKeyField;\n    }\n\n    // Filter statement for left side of through\n    // Used by both join and subquery where\n    // If parent include was in a subquery need to join on the aliased attribute\n    if (topLevelInfo.subQuery && !include.subQuery && include.parent.subQuery && !parentIsTop) {\n      // If we are minifying aliases and our JOIN target has been minified, we need to use the alias instead of the original column name\n      const joinSource = this._getAliasForField(tableSource, `${tableSource}.${attrSource}`, topLevelInfo.options) || `${tableSource}.${attrSource}`;\n\n      sourceJoinOn = `${this.quoteIdentifier(joinSource)} = `;\n    } else {\n      // If we are minifying aliases and our JOIN target has been minified, we need to use the alias instead of the original column name\n      const aliasedSource = this._getAliasForField(tableSource, attrSource, topLevelInfo.options) || attrSource;\n\n      sourceJoinOn = `${this.quoteTable(tableSource)}.${this.quoteIdentifier(aliasedSource)} = `;\n    }\n    sourceJoinOn += `${this.quoteIdentifier(throughAs)}.${this.quoteIdentifier(identSource)}`;\n\n    // Filter statement for right side of through\n    // Used by both join and subquery where\n    targetJoinOn = `${this.quoteIdentifier(tableTarget)}.${this.quoteIdentifier(attrTarget)} = `;\n    targetJoinOn += `${this.quoteIdentifier(throughAs)}.${this.quoteIdentifier(identTarget)}`;\n\n    if (through.where) {\n      throughWhere = this.getWhereConditions(through.where, this.sequelize.literal(this.quoteIdentifier(throughAs)), through.model);\n    }\n\n    this.aliasAs(includeAs.internalAs, topLevelInfo);\n\n    // Generate a wrapped join so that the through table join can be dependent on the target join\n    joinBody = `( ${this.quoteTable(throughTable, throughAs)} INNER JOIN ${this.quoteTable(include.model.getTableName(), includeAs.internalAs)} ON ${targetJoinOn}`;\n    if (throughWhere) {\n      joinBody += ` AND ${throughWhere}`;\n    }\n    joinBody += ')';\n    joinCondition = sourceJoinOn;\n\n    if (include.where || include.through.where) {\n      if (include.where) {\n        targetWhere = this.getWhereConditions(include.where, this.sequelize.literal(this.quoteIdentifier(includeAs.internalAs)), include.model, topLevelInfo.options);\n        if (targetWhere) {\n          joinCondition += ` AND ${targetWhere}`;\n        }\n      }\n    }\n\n    this._generateSubQueryFilter(include, includeAs, topLevelInfo);\n\n    return {\n      join: joinType,\n      body: joinBody,\n      condition: joinCondition,\n      attributes\n    };\n  }\n\n  /*\n   * Appends to the alias cache if the alias 64+ characters long and minifyAliases is true.\n   * This helps to avoid character limits in PostgreSQL.\n   */\n  aliasAs(as, topLevelInfo) {\n    if (this.options.minifyAliases && as.length >= 64) {\n      const alias = `%${topLevelInfo.options.includeAliases.size}`;\n\n      topLevelInfo.options.includeAliases.set(alias, as);\n    }\n  }\n\n  /*\n   * Generates subQueryFilter - a select nested in the where clause of the subQuery.\n   * For a given include a query is generated that contains all the way from the subQuery\n   * table to the include table plus everything that's in required transitive closure of the\n   * given include.\n   */\n  _generateSubQueryFilter(include, includeAs, topLevelInfo) {\n    if (!topLevelInfo.subQuery || !include.subQueryFilter) {\n      return;\n    }\n\n    if (!topLevelInfo.options.where) {\n      topLevelInfo.options.where = {};\n    }\n    let parent = include;\n    let child = include;\n    let nestedIncludes = this._getRequiredClosure(include).include;\n    let query;\n\n    while ((parent = parent.parent)) { // eslint-disable-line\n      if (parent.parent && !parent.required) {\n        return; // only generate subQueryFilter if all the parents of this include are required\n      }\n\n      if (parent.subQueryFilter) {\n        // the include is already handled as this parent has the include on its required closure\n        // skip to prevent duplicate subQueryFilter\n        return;\n      }\n\n      nestedIncludes = [{ ...child, include: nestedIncludes, attributes: [] }];\n      child = parent;\n    }\n\n    const topInclude = nestedIncludes[0];\n    const topParent = topInclude.parent;\n    const topAssociation = topInclude.association;\n    topInclude.association = undefined;\n\n    if (topInclude.through && Object(topInclude.through.model) === topInclude.through.model) {\n      query = this.selectQuery(topInclude.through.model.getTableName(), {\n        attributes: [topInclude.through.model.primaryKeyField],\n        include: Model._validateIncludedElements({\n          model: topInclude.through.model,\n          include: [{\n            association: topAssociation.toTarget,\n            required: true,\n            where: topInclude.where,\n            include: topInclude.include\n          }]\n        }).include,\n        model: topInclude.through.model,\n        where: {\n          [Op.and]: [\n            this.sequelize.literal([\n              `${this.quoteTable(topParent.model.name)}.${this.quoteIdentifier(topParent.model.primaryKeyField)}`,\n              `${this.quoteIdentifier(topInclude.through.model.name)}.${this.quoteIdentifier(topAssociation.identifierField)}`\n            ].join(' = ')),\n            topInclude.through.where\n          ]\n        },\n        limit: 1,\n        includeIgnoreAttributes: false\n      }, topInclude.through.model);\n    } else {\n      const isBelongsTo = topAssociation.associationType === 'BelongsTo';\n      const sourceField = isBelongsTo ? topAssociation.identifierField : topAssociation.sourceKeyField || topParent.model.primaryKeyField;\n      const targetField = isBelongsTo ? topAssociation.sourceKeyField || topInclude.model.primaryKeyField : topAssociation.identifierField;\n\n      const join = [\n        `${this.quoteIdentifier(topInclude.as)}.${this.quoteIdentifier(targetField)}`,\n        `${this.quoteTable(topParent.as || topParent.model.name)}.${this.quoteIdentifier(sourceField)}`\n      ].join(' = ');\n\n      query = this.selectQuery(topInclude.model.getTableName(), {\n        attributes: [targetField],\n        include: Model._validateIncludedElements(topInclude).include,\n        model: topInclude.model,\n        where: {\n          [Op.and]: [\n            topInclude.where,\n            { [Op.join]: this.sequelize.literal(join) }\n          ]\n        },\n        limit: 1,\n        tableAs: topInclude.as,\n        includeIgnoreAttributes: false\n      }, topInclude.model);\n    }\n\n    if (!topLevelInfo.options.where[Op.and]) {\n      topLevelInfo.options.where[Op.and] = [];\n    }\n\n    topLevelInfo.options.where[`__${includeAs.internalAs}`] = this.sequelize.literal([\n      '(',\n      query.replace(/;$/, ''),\n      ')',\n      'IS NOT NULL'\n    ].join(' '));\n  }\n\n  /*\n   * For a given include hierarchy creates a copy of it where only the required includes\n   * are preserved.\n   */\n  _getRequiredClosure(include) {\n    const copy = { ...include, attributes: [], include: [] };\n\n    if (Array.isArray(include.include)) {\n      copy.include = include.include\n        .filter(i => i.required)\n        .map(inc => this._getRequiredClosure(inc));\n    }\n\n    return copy;\n  }\n\n  getQueryOrders(options, model, subQuery) {\n    const mainQueryOrder = [];\n    const subQueryOrder = [];\n\n    if (Array.isArray(options.order)) {\n      for (let order of options.order) {\n\n        // wrap if not array\n        if (!Array.isArray(order)) {\n          order = [order];\n        }\n\n        if (\n          subQuery\n          && Array.isArray(order)\n          && order[0]\n          && !(order[0] instanceof Association)\n          && !(typeof order[0] === 'function' && order[0].prototype instanceof Model)\n          && !(typeof order[0].model === 'function' && order[0].model.prototype instanceof Model)\n          && !(typeof order[0] === 'string' && model && model.associations !== undefined && model.associations[order[0]])\n        ) {\n          const field = model.rawAttributes[order[0]] ? model.rawAttributes[order[0]].field : order[0];\n          const subQueryAlias = this._getAliasForField(this.quoteIdentifier(model.name), field, options);\n\n          let parent = null;\n          let orderToQuote = [];\n\n          // we need to ensure that the parent is null if we use the subquery alias, else we'll get an exception since\n          // \"model_name\".\"alias\" doesn't exist - only \"alias\" does. we also need to ensure that we preserve order direction\n          // by pushing order[1] to the subQueryOrder as well - in case it doesn't exist, we want to push \"ASC\"\n          if (subQueryAlias === null) {\n            orderToQuote = order;\n            parent = model;\n          } else {\n            orderToQuote = [subQueryAlias, order.length > 1 ? order[1] : 'ASC'];\n            parent = null;\n          }\n\n          subQueryOrder.push(this.quote(orderToQuote, parent, '->'));\n        }\n\n        // Handle case where renamed attributes are used to order by,\n        // see https://github.com/sequelize/sequelize/issues/8739\n        // need to check if either of the attribute options match the order\n        if (options.attributes && model) {\n          const aliasedAttribute = options.attributes.find(attr => Array.isArray(attr)\n              && attr[1]\n              && (attr[0] === order[0] || attr[1] === order[0]));\n\n          if (aliasedAttribute) {\n            const modelName = this.quoteIdentifier(model.name);\n            const alias = this._getAliasForField(modelName, aliasedAttribute[1], options);\n\n            order[0] = new Utils.Col(alias || aliasedAttribute[1]);\n          }\n        }\n\n        mainQueryOrder.push(this.quote(order, model, '->'));\n      }\n    } else if (options.order instanceof Utils.SequelizeMethod) {\n      const sql = this.quote(options.order, model, '->');\n      if (subQuery) {\n        subQueryOrder.push(sql);\n      }\n      mainQueryOrder.push(sql);\n    } else {\n      throw new Error('Order must be type of array or instance of a valid sequelize method.');\n    }\n\n    return { mainQueryOrder, subQueryOrder };\n  }\n\n  _throwOnEmptyAttributes(attributes, extraInfo = {}) {\n    if (attributes.length > 0) return;\n    const asPart = extraInfo.as && `as ${extraInfo.as}` || '';\n    const namePart = extraInfo.modelName && `for model '${extraInfo.modelName}'` || '';\n    const message = `Attempted a SELECT query ${namePart} ${asPart} without selecting any columns`;\n    throw new sequelizeError.QueryError(message.replace(/ +/g, ' '));\n  }\n\n  selectFromTableFragment(options, model, attributes, tables, mainTableAs) {\n    this._throwOnEmptyAttributes(attributes, { modelName: model && model.name, as: mainTableAs });\n\n    let fragment = `SELECT ${attributes.join(', ')} FROM ${tables}`;\n\n    if (mainTableAs) {\n      fragment += ` ${this.getAliasToken()} ${mainTableAs}`;\n    }\n\n    if (options.indexHints && this._dialect.supports.indexHints) {\n      for (const hint of options.indexHints) {\n        if (IndexHints[hint.type]) {\n          fragment += ` ${IndexHints[hint.type]} INDEX (${hint.values.map(indexName => this.quoteIdentifiers(indexName)).join(',')})`;\n        }\n      }\n    }\n\n    return fragment;\n  }\n\n  /**\n   * Returns an SQL fragment for adding result constraints.\n   *\n   * @param  {object} options An object with selectQuery options.\n   * @returns {string}         The generated sql query.\n   * @private\n   */\n  addLimitAndOffset(options) {\n    let fragment = '';\n\n    /* eslint-disable */\n    if (options.offset != null && options.limit == null) {\n      fragment += ' LIMIT ' + this.escape(options.offset) + ', ' + 10000000000000;\n    } else if (options.limit != null) {\n      if (options.offset != null) {\n        fragment += ' LIMIT ' + this.escape(options.offset) + ', ' + this.escape(options.limit);\n      } else {\n        fragment += ' LIMIT ' + this.escape(options.limit);\n      }\n    }\n    /* eslint-enable */\n\n    return fragment;\n  }\n\n  handleSequelizeMethod(smth, tableName, factory, options, prepend) {\n    let result;\n\n    if (Object.prototype.hasOwnProperty.call(this.OperatorMap, smth.comparator)) {\n      smth.comparator = this.OperatorMap[smth.comparator];\n    }\n\n    if (smth instanceof Utils.Where) {\n      let value = smth.logic;\n      let key;\n\n      if (smth.attribute instanceof Utils.SequelizeMethod) {\n        key = this.getWhereConditions(smth.attribute, tableName, factory, options, prepend);\n      } else {\n        key = `${this.quoteTable(smth.attribute.Model.name)}.${this.quoteIdentifier(smth.attribute.field || smth.attribute.fieldName)}`;\n      }\n\n      if (value && value instanceof Utils.SequelizeMethod) {\n        value = this.getWhereConditions(value, tableName, factory, options, prepend);\n\n        if (value === 'NULL') {\n          if (smth.comparator === '=') {\n            smth.comparator = 'IS';\n          }\n          if (smth.comparator === '!=') {\n            smth.comparator = 'IS NOT';\n          }\n        }\n\n        return [key, value].join(` ${smth.comparator} `);\n      }\n      if (_.isPlainObject(value)) {\n        return this.whereItemQuery(smth.attribute, value, {\n          model: factory\n        });\n      }\n      if ([this.OperatorMap[Op.between], this.OperatorMap[Op.notBetween]].includes(smth.comparator)) {\n        value = `${this.escape(value[0])} AND ${this.escape(value[1])}`;\n      } else if (typeof value === 'boolean') {\n        value = this.booleanValue(value);\n      } else {\n        value = this.escape(value);\n      }\n\n      if (value === 'NULL') {\n        if (smth.comparator === '=') {\n          smth.comparator = 'IS';\n        }\n        if (smth.comparator === '!=') {\n          smth.comparator = 'IS NOT';\n        }\n      }\n\n      return [key, value].join(` ${smth.comparator} `);\n    }\n    if (smth instanceof Utils.Literal) {\n      return smth.val;\n    }\n    if (smth instanceof Utils.Cast) {\n      if (smth.val instanceof Utils.SequelizeMethod) {\n        result = this.handleSequelizeMethod(smth.val, tableName, factory, options, prepend);\n      } else if (_.isPlainObject(smth.val)) {\n        result = this.whereItemsQuery(smth.val);\n      } else {\n        result = this.escape(smth.val);\n      }\n\n      return `CAST(${result} AS ${smth.type.toUpperCase()})`;\n    }\n    if (smth instanceof Utils.Fn) {\n      return `${smth.fn}(${\n        smth.args.map(arg => {\n          if (arg instanceof Utils.SequelizeMethod) {\n            return this.handleSequelizeMethod(arg, tableName, factory, options, prepend);\n          }\n          if (_.isPlainObject(arg)) {\n            return this.whereItemsQuery(arg);\n          }\n          return this.escape(typeof arg === 'string' ? arg.replace(/\\$/g, '$$$') : arg);\n        }).join(', ')\n      })`;\n    }\n    if (smth instanceof Utils.Col) {\n      if (Array.isArray(smth.col) && !factory) {\n        throw new Error('Cannot call Sequelize.col() with array outside of order / group clause');\n      }\n      if (smth.col.startsWith('*')) {\n        return '*';\n      }\n      return this.quote(smth.col, factory);\n    }\n    return smth.toString(this, factory);\n  }\n\n  whereQuery(where, options) {\n    const query = this.whereItemsQuery(where, options);\n    if (query && query.length) {\n      return `WHERE ${query}`;\n    }\n    return '';\n  }\n\n  whereItemsQuery(where, options, binding) {\n    if (\n      where === null ||\n      where === undefined ||\n      Utils.getComplexSize(where) === 0\n    ) {\n      // NO OP\n      return '';\n    }\n\n    if (typeof where === 'string') {\n      throw new Error('Support for `{where: \\'raw query\\'}` has been removed.');\n    }\n\n    const items = [];\n\n    binding = binding || 'AND';\n    if (binding[0] !== ' ') binding = ` ${binding} `;\n\n    if (_.isPlainObject(where)) {\n      Utils.getComplexKeys(where).forEach(prop => {\n        const item = where[prop];\n        items.push(this.whereItemQuery(prop, item, options));\n      });\n    } else {\n      items.push(this.whereItemQuery(undefined, where, options));\n    }\n\n    return items.length && items.filter(item => item && item.length).join(binding) || '';\n  }\n\n  whereItemQuery(key, value, options = {}) {\n    if (value === undefined) {\n      throw new Error(`WHERE parameter \"${key}\" has invalid \"undefined\" value`);\n    }\n\n    if (typeof key === 'string' && key.includes('.') && options.model) {\n      const keyParts = key.split('.');\n      if (options.model.rawAttributes[keyParts[0]] && options.model.rawAttributes[keyParts[0]].type instanceof DataTypes.JSON) {\n        const tmp = {};\n        const field = options.model.rawAttributes[keyParts[0]];\n        _.set(tmp, keyParts.slice(1), value);\n        return this.whereItemQuery(field.field || keyParts[0], tmp, { field, ...options });\n      }\n    }\n\n    const field = this._findField(key, options);\n    const fieldType = field && field.type || options.type;\n\n    const isPlainObject = _.isPlainObject(value);\n    const isArray = !isPlainObject && Array.isArray(value);\n    key = this.OperatorsAliasMap && this.OperatorsAliasMap[key] || key;\n    if (isPlainObject) {\n      value = this._replaceAliases(value);\n    }\n    const valueKeys = isPlainObject && Utils.getComplexKeys(value);\n\n    if (key === undefined) {\n      if (typeof value === 'string') {\n        return value;\n      }\n\n      if (isPlainObject && valueKeys.length === 1) {\n        return this.whereItemQuery(valueKeys[0], value[valueKeys[0]], options);\n      }\n    }\n\n    if (value === null) {\n      const opValue = options.bindParam ? 'NULL' : this.escape(value, field);\n      return this._joinKeyValue(key, opValue, this.OperatorMap[Op.is], options.prefix);\n    }\n\n    if (!value) {\n      const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);\n      return this._joinKeyValue(key, opValue, this.OperatorMap[Op.eq], options.prefix);\n    }\n\n    if (value instanceof Utils.SequelizeMethod && !(key !== undefined && value instanceof Utils.Fn)) {\n      return this.handleSequelizeMethod(value);\n    }\n\n    // Convert where: [] to Op.and if possible, else treat as literal/replacements\n    if (key === undefined && isArray) {\n      if (Utils.canTreatArrayAsAnd(value)) {\n        key = Op.and;\n      } else {\n        throw new Error('Support for literal replacements in the `where` object has been removed.');\n      }\n    }\n\n    if (key === Op.or || key === Op.and || key === Op.not) {\n      return this._whereGroupBind(key, value, options);\n    }\n\n\n    if (value[Op.or]) {\n      return this._whereBind(this.OperatorMap[Op.or], key, value[Op.or], options);\n    }\n\n    if (value[Op.and]) {\n      return this._whereBind(this.OperatorMap[Op.and], key, value[Op.and], options);\n    }\n\n    if (isArray && fieldType instanceof DataTypes.ARRAY) {\n      const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);\n      return this._joinKeyValue(key, opValue, this.OperatorMap[Op.eq], options.prefix);\n    }\n\n    if (isPlainObject && fieldType instanceof DataTypes.JSON && options.json !== false) {\n      return this._whereJSON(key, value, options);\n    }\n    // If multiple keys we combine the different logic conditions\n    if (isPlainObject && valueKeys.length > 1) {\n      return this._whereBind(this.OperatorMap[Op.and], key, value, options);\n    }\n\n    if (isArray) {\n      return this._whereParseSingleValueObject(key, field, Op.in, value, options);\n    }\n    if (isPlainObject) {\n      if (this.OperatorMap[valueKeys[0]]) {\n        return this._whereParseSingleValueObject(key, field, valueKeys[0], value[valueKeys[0]], options);\n      }\n      return this._whereParseSingleValueObject(key, field, this.OperatorMap[Op.eq], value, options);\n    }\n\n    if (key === Op.placeholder) {\n      const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);\n      return this._joinKeyValue(this.OperatorMap[key], opValue, this.OperatorMap[Op.eq], options.prefix);\n    }\n\n    const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);\n    return this._joinKeyValue(key, opValue, this.OperatorMap[Op.eq], options.prefix);\n  }\n\n  _findField(key, options) {\n    if (options.field) {\n      return options.field;\n    }\n\n    if (options.model && options.model.rawAttributes && options.model.rawAttributes[key]) {\n      return options.model.rawAttributes[key];\n    }\n\n    if (options.model && options.model.fieldRawAttributesMap && options.model.fieldRawAttributesMap[key]) {\n      return options.model.fieldRawAttributesMap[key];\n    }\n  }\n\n  // OR/AND/NOT grouping logic\n  _whereGroupBind(key, value, options) {\n    const binding = key === Op.or ? this.OperatorMap[Op.or] : this.OperatorMap[Op.and];\n    const outerBinding = key === Op.not ? 'NOT ' : '';\n\n    if (Array.isArray(value)) {\n      value = value.map(item => {\n        let itemQuery = this.whereItemsQuery(item, options, this.OperatorMap[Op.and]);\n        if (itemQuery && itemQuery.length && (Array.isArray(item) || _.isPlainObject(item)) && Utils.getComplexSize(item) > 1) {\n          itemQuery = `(${itemQuery})`;\n        }\n        return itemQuery;\n      }).filter(item => item && item.length);\n\n      value = value.length && value.join(binding);\n    } else {\n      value = this.whereItemsQuery(value, options, binding);\n    }\n    // Op.or: [] should return no data.\n    // Op.not of no restriction should also return no data\n    if ((key === Op.or || key === Op.not) && !value) {\n      return '0 = 1';\n    }\n\n    return value ? `${outerBinding}(${value})` : undefined;\n  }\n\n  _whereBind(binding, key, value, options) {\n    if (_.isPlainObject(value)) {\n      value = Utils.getComplexKeys(value).map(prop => {\n        const item = value[prop];\n        return this.whereItemQuery(key, { [prop]: item }, options);\n      });\n    } else {\n      value = value.map(item => this.whereItemQuery(key, item, options));\n    }\n\n    value = value.filter(item => item && item.length);\n\n    return value.length ? `(${value.join(binding)})` : undefined;\n  }\n\n  _whereJSON(key, value, options) {\n    const items = [];\n    let baseKey = this.quoteIdentifier(key);\n    if (options.prefix) {\n      if (options.prefix instanceof Utils.Literal) {\n        baseKey = `${this.handleSequelizeMethod(options.prefix)}.${baseKey}`;\n      } else {\n        baseKey = `${this.quoteTable(options.prefix)}.${baseKey}`;\n      }\n    }\n\n    Utils.getOperators(value).forEach(op => {\n      const where = {\n        [op]: value[op]\n      };\n      items.push(this.whereItemQuery(key, where, { ...options, json: false }));\n    });\n\n    _.forOwn(value, (item, prop) => {\n      this._traverseJSON(items, baseKey, prop, item, [prop]);\n    });\n\n    const result = items.join(this.OperatorMap[Op.and]);\n    return items.length > 1 ? `(${result})` : result;\n  }\n\n  _traverseJSON(items, baseKey, prop, item, path) {\n    let cast;\n\n    if (path[path.length - 1].includes('::')) {\n      const tmp = path[path.length - 1].split('::');\n      cast = tmp[1];\n      path[path.length - 1] = tmp[0];\n\n      this._validateCastType(cast);\n    }\n\n    let pathKey = this.jsonPathExtractionQuery(baseKey, path);\n\n    if (_.isPlainObject(item)) {\n      Utils.getOperators(item).forEach(op => {\n        const value = this._toJSONValue(item[op]);\n        let isJson = false;\n        if (typeof value === 'string' && op === Op.contains) {\n          try {\n            JSON.stringify(value);\n            isJson = true;\n          } catch (e) {\n            // failed to parse, is not json so isJson remains false\n          }\n        }\n        pathKey = this.jsonPathExtractionQuery(baseKey, path, isJson);\n        items.push(this.whereItemQuery(this._castKey(pathKey, value, cast), { [op]: value }));\n      });\n      _.forOwn(item, (value, itemProp) => {\n        this._traverseJSON(items, baseKey, itemProp, value, path.concat([itemProp]));\n      });\n\n      return;\n    }\n\n    item = this._toJSONValue(item);\n    items.push(this.whereItemQuery(this._castKey(pathKey, item, cast), { [Op.eq]: item }));\n  }\n\n  _toJSONValue(value) {\n    return value;\n  }\n\n  _castKey(key, value, cast, json) {\n    cast = cast || this._getJsonCast(Array.isArray(value) ? value[0] : value);\n    if (cast) {\n      return new Utils.Literal(this.handleSequelizeMethod(new Utils.Cast(new Utils.Literal(key), cast, json)));\n    }\n\n    return new Utils.Literal(key);\n  }\n\n  _getJsonCast(value) {\n    if (typeof value === 'number') {\n      return 'double precision';\n    }\n    if (value instanceof Date) {\n      return 'timestamptz';\n    }\n    if (typeof value === 'boolean') {\n      return 'boolean';\n    }\n    return;\n  }\n\n  _validateCastType(cast) {\n    if (!ALLOWED_CAST_TYPES.has(cast.toLowerCase())) {\n      throw new Error(`Invalid cast type: ${cast}`);\n    }\n  }\n\n  _joinKeyValue(key, value, comparator, prefix) {\n    if (!key) {\n      return value;\n    }\n    if (comparator === undefined) {\n      throw new Error(`${key} and ${value} has no comparator`);\n    }\n    key = this._getSafeKey(key, prefix);\n    return [key, value].join(` ${comparator} `);\n  }\n\n  _getSafeKey(key, prefix) {\n    if (key instanceof Utils.SequelizeMethod) {\n      key = this.handleSequelizeMethod(key);\n      return this._prefixKey(this.handleSequelizeMethod(key), prefix);\n    }\n\n    if (Utils.isColString(key)) {\n      key = key.substr(1, key.length - 2).split('.');\n\n      if (key.length > 2) {\n        key = [\n          // join the tables by -> to match out internal namings\n          key.slice(0, -1).join('->'),\n          key[key.length - 1]\n        ];\n      }\n\n      return key.map(identifier => this.quoteIdentifier(identifier)).join('.');\n    }\n\n    return this._prefixKey(this.quoteIdentifier(key), prefix);\n  }\n\n  _prefixKey(key, prefix) {\n    if (prefix) {\n      if (prefix instanceof Utils.Literal) {\n        return [this.handleSequelizeMethod(prefix), key].join('.');\n      }\n\n      return [this.quoteTable(prefix), key].join('.');\n    }\n\n    return key;\n  }\n\n  _whereParseSingleValueObject(key, field, prop, value, options) {\n    if (prop === Op.not) {\n      if (Array.isArray(value)) {\n        prop = Op.notIn;\n      } else if (value !== null && value !== true && value !== false) {\n        prop = Op.ne;\n      }\n    }\n\n    let comparator = this.OperatorMap[prop] || this.OperatorMap[Op.eq];\n\n    switch (prop) {\n      case Op.in:\n      case Op.notIn:\n        if (value instanceof Utils.Literal) {\n          return this._joinKeyValue(key, value.val, comparator, options.prefix);\n        }\n\n        if (value.length) {\n          return this._joinKeyValue(key, `(${value.map(item => this.escape(item, field)).join(', ')})`, comparator, options.prefix);\n        }\n\n        if (comparator === this.OperatorMap[Op.in]) {\n          return this._joinKeyValue(key, '(NULL)', comparator, options.prefix);\n        }\n\n        return '';\n      case Op.any:\n      case Op.all:\n        comparator = `${this.OperatorMap[Op.eq]} ${comparator}`;\n        if (value[Op.values]) {\n          return this._joinKeyValue(key, `(VALUES ${value[Op.values].map(item => `(${this.escape(item)})`).join(', ')})`, comparator, options.prefix);\n        }\n\n        return this._joinKeyValue(key, `(${this.escape(value, field)})`, comparator, options.prefix);\n      case Op.between:\n      case Op.notBetween:\n        return this._joinKeyValue(key, `${this.escape(value[0], field)} AND ${this.escape(value[1], field)}`, comparator, options.prefix);\n      case Op.raw:\n        throw new Error('The `$raw` where property is no longer supported.  Use `sequelize.literal` instead.');\n      case Op.col:\n        comparator = this.OperatorMap[Op.eq];\n        value = value.split('.');\n\n        if (value.length > 2) {\n          value = [\n            // join the tables by -> to match out internal namings\n            value.slice(0, -1).join('->'),\n            value[value.length - 1]\n          ];\n        }\n\n        return this._joinKeyValue(key, value.map(identifier => this.quoteIdentifier(identifier)).join('.'), comparator, options.prefix);\n      case Op.startsWith:\n      case Op.endsWith:\n      case Op.substring:\n        comparator = this.OperatorMap[Op.like];\n\n        if (value instanceof Utils.Literal) {\n          value = value.val;\n        }\n\n        let pattern = `${value}%`;\n\n        if (prop === Op.endsWith) pattern = `%${value}`;\n        if (prop === Op.substring) pattern = `%${value}%`;\n\n        return this._joinKeyValue(key, this.escape(pattern), comparator, options.prefix);\n    }\n\n    const escapeOptions = {\n      acceptStrings: comparator.includes(this.OperatorMap[Op.like])\n    };\n\n    if (_.isPlainObject(value)) {\n      if (value[Op.col]) {\n        return this._joinKeyValue(key, this.whereItemQuery(null, value), comparator, options.prefix);\n      }\n      if (value[Op.any]) {\n        escapeOptions.isList = true;\n        return this._joinKeyValue(key, `(${this.escape(value[Op.any], field, escapeOptions)})`, `${comparator} ${this.OperatorMap[Op.any]}`, options.prefix);\n      }\n      if (value[Op.all]) {\n        escapeOptions.isList = true;\n        return this._joinKeyValue(key, `(${this.escape(value[Op.all], field, escapeOptions)})`, `${comparator} ${this.OperatorMap[Op.all]}`, options.prefix);\n      }\n    }\n\n    if (value === null && comparator === this.OperatorMap[Op.eq]) {\n      return this._joinKeyValue(key, this.escape(value, field, escapeOptions), this.OperatorMap[Op.is], options.prefix);\n    }\n    if (value === null && comparator === this.OperatorMap[Op.ne]) {\n      return this._joinKeyValue(key, this.escape(value, field, escapeOptions), this.OperatorMap[Op.not], options.prefix);\n    }\n\n    return this._joinKeyValue(key, this.escape(value, field, escapeOptions), comparator, options.prefix);\n  }\n\n  /*\n    Takes something and transforms it into values of a where condition.\n   @private\n  */\n  getWhereConditions(smth, tableName, factory, options, prepend) {\n    const where = {};\n\n    if (Array.isArray(tableName)) {\n      tableName = tableName[0];\n      if (Array.isArray(tableName)) {\n        tableName = tableName[1];\n      }\n    }\n\n    options = options || {};\n\n    if (prepend === undefined) {\n      prepend = true;\n    }\n\n    if (smth && smth instanceof Utils.SequelizeMethod) { // Checking a property is cheaper than a lot of instanceof calls\n      return this.handleSequelizeMethod(smth, tableName, factory, options, prepend);\n    }\n    if (_.isPlainObject(smth)) {\n      return this.whereItemsQuery(smth, {\n        model: factory,\n        prefix: prepend && tableName,\n        type: options.type\n      });\n    }\n    if (typeof smth === 'number' || typeof smth === 'bigint') {\n      let primaryKeys = factory ? Object.keys(factory.primaryKeys) : [];\n\n      if (primaryKeys.length > 0) {\n        // Since we're just a number, assume only the first key\n        primaryKeys = primaryKeys[0];\n      } else {\n        primaryKeys = 'id';\n      }\n\n      where[primaryKeys] = smth;\n\n      return this.whereItemsQuery(where, {\n        model: factory,\n        prefix: prepend && tableName\n      });\n    }\n    if (typeof smth === 'string') {\n      return this.whereItemsQuery(smth, {\n        model: factory,\n        prefix: prepend && tableName\n      });\n    }\n    if (Buffer.isBuffer(smth)) {\n      return this.escape(smth);\n    }\n    if (Array.isArray(smth)) {\n      if (smth.length === 0 || smth.length > 0 && smth[0].length === 0) return '1=1';\n      if (Utils.canTreatArrayAsAnd(smth)) {\n        const _smth = { [Op.and]: smth };\n        return this.getWhereConditions(_smth, tableName, factory, options, prepend);\n      }\n      throw new Error('Support for literal replacements in the `where` object has been removed.');\n    }\n    if (smth == null) {\n      return this.whereItemsQuery(smth, {\n        model: factory,\n        prefix: prepend && tableName\n      });\n    }\n\n    throw new Error(`Unsupported where option value: ${util.inspect(smth)}. Please refer to the Sequelize documentation to learn more about which values are accepted as part of the where option.`);\n  }\n\n  // A recursive parser for nested where conditions\n  parseConditionObject(conditions, path) {\n    path = path || [];\n    return _.reduce(conditions, (result, value, key) => {\n      if (_.isObject(value)) {\n        return result.concat(this.parseConditionObject(value, path.concat(key))); // Recursively parse objects\n      }\n      result.push({ path: path.concat(key), value });\n      return result;\n    }, []);\n  }\n\n  booleanValue(value) {\n    return value;\n  }\n\n  /**\n   * Returns the authenticate test query string\n   */\n  authTestQuery() {\n    return 'SELECT 1+1 AS result';\n  }\n}\n\nObject.assign(QueryGenerator.prototype, require('./query-generator/operators'));\nObject.assign(QueryGenerator.prototype, require('./query-generator/transaction'));\n\nmodule.exports = QueryGenerator;\n"],
+  "mappings": "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",
   "names": []
 }
diff -ruN --no-dereference /home/ubuntu/closed-source-intelligence/data/cache/npm-tarballs/sequelize-6.37.7/package.json /home/ubuntu/closed-source-intelligence/data/cache/npm-tarballs/sequelize-6.37.8/package.json
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "sequelize",
   "description": "Sequelize is a promise-based Node.js ORM tool for Postgres, MySQL, MariaDB, SQLite, Microsoft SQL Server, Amazon Redshift and Snowflake’s Data Cloud. It features solid transaction support, relations, eager and lazy loading, read replication and more.",
-  "version": "6.37.7",
+  "version": "6.37.8",
   "funding": [
     {
       "type": "opencollective",