databaseChangeLog:
# The quoting strategy decides when things like column names should be quoted.
# This is in place to deal with Liquibase not knowing about all of the new
# reserved words in MySQL 8+. Using a column name that is a reserved word
# causes a failure. Quoting all objects breaks H2 support though as it will
# quote table names but not quote that same table name in a foreign key reference
# which will cause a failure when trying to initially setup the database.
  - property:
      name: quote_strategy
      value: QUOTE_ALL_OBJECTS
      dbms: mysql,mariadb
  - property:
      name: quote_strategy
      value: LEGACY
      dbms: postgresql,h2
  - property:
      name: timestamp_type
      value: timestamp with time zone
      dbms: postgresql,h2
  - property:
      name: timestamp_type
      value: timestamp(6)
      dbms: mysql,mariadb

  - changeSet:
      id: '1'
      author: agilliland
      objectQuotingStrategy: ${quote_strategy}
      changes:
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
                unique: true
              name: slug
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: name
              type: varchar(254)
          - column:
              name: description
              type: text
          - column:
              name: logo_url
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: inherits
              type: boolean
          tableName: core_organization
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
                unique: true
              name: email
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: first_name
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: last_name
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: password
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              defaultValue: default
              name: password_salt
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: date_joined
              type: DATETIME
          - column:
              constraints:
                nullable: true
              name: last_login
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: is_staff
              type: boolean
          - column:
              constraints:
                nullable: false
              name: is_superuser
              type: boolean
          - column:
              constraints:
                nullable: false
              name: is_active
              type: boolean
          - column:
              name: reset_token
              type: varchar(254)
          - column:
              name: reset_triggered
              type: BIGINT
          tableName: core_user
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: admin
              type: boolean
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_userorgperm_ref_user_id
                initiallyDeferred: false
                nullable: false
                references: core_user(id)
              name: user_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_userorgperm_ref_organization_id
                initiallyDeferred: false
                nullable: false
                references: core_organization(id)
              name: organization_id
              type: int
          tableName: core_userorgperm
      - addUniqueConstraint:
          columnNames: user_id, organization_id
          constraintName: idx_unique_user_id_organization_id
          tableName: core_userorgperm
      - createIndex:
          columns:
          - column:
              name: user_id
              type: int
          indexName: idx_userorgperm_user_id
          tableName: core_userorgperm
      - createIndex:
          columns:
          - column:
              name: organization_id
              type: int
          indexName: idx_userorgperm_organization_id
          tableName: core_userorgperm
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: url
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: timestamp
              type: DATETIME
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_permissionviolation_ref_user_id
                initiallyDeferred: false
                nullable: false
                references: core_user(id)
              name: user_id
              type: int
          tableName: core_permissionsviolation
      - createIndex:
          columns:
          - column:
              name: user_id
              type: int
          indexName: idx_permissionsviolation_user_id
          tableName: core_permissionsviolation
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: name
              type: varchar(254)
          - column:
              name: description
              type: text
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_database_ref_organization_id
                initiallyDeferred: false
                nullable: false
                references: core_organization(id)
              name: organization_id
              type: int
          - column:
              name: details
              type: text
          - column:
              constraints:
                nullable: false
              name: engine
              type: varchar(254)
          tableName: metabase_database
      - createIndex:
          columns:
          - column:
              name: organization_id
          indexName: idx_database_organization_id
          tableName: metabase_database
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: name
              type: varchar(254)
          - column:
              name: rows
              type: int
          - column:
              name: description
              type: text
          - column:
              name: entity_name
              type: varchar(254)
          - column:
              name: entity_type
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: active
              type: boolean
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_table_ref_database_id
                initiallyDeferred: false
                nullable: false
                references: metabase_database(id)
              name: db_id
              type: int
          tableName: metabase_table
      - createIndex:
          columns:
          - column:
              name: db_id
          indexName: idx_table_db_id
          tableName: metabase_table
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: name
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: base_type
              type: varchar(255)
          - column:
              name: special_type
              type: varchar(255)
          - column:
              constraints:
                nullable: false
              name: active
              type: boolean
          - column:
              name: description
              type: text
          - column:
              constraints:
                nullable: false
              name: preview_display
              type: boolean
          - column:
              constraints:
                nullable: false
              name: position
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_field_ref_table_id
                initiallyDeferred: false
                nullable: false
                references: metabase_table(id)
              name: table_id
              type: int
          - column:
              constraints:
                nullable: false
              name: field_type
              type: varchar(254)
          tableName: metabase_field
      - createIndex:
          columns:
          - column:
              name: table_id
          indexName: idx_field_table_id
          tableName: metabase_field
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: relationship
              type: varchar(254)
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_foreignkey_dest_ref_field_id
                initiallyDeferred: false
                nullable: false
                references: metabase_field(id)
              name: destination_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_foreignkey_origin_ref_field_id
                initiallyDeferred: false
                nullable: false
                references: metabase_field(id)
              name: origin_id
              type: int
          tableName: metabase_foreignkey
      - createIndex:
          columns:
          - column:
              name: destination_id
          indexName: idx_foreignkey_destination_id
          tableName: metabase_foreignkey
      - createIndex:
          columns:
          - column:
              name: origin_id
          indexName: idx_foreignkey_origin_id
          tableName: metabase_foreignkey
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              name: values
              type: text
          - column:
              name: human_readable_values
              type: text
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_fieldvalues_ref_field_id
                initiallyDeferred: false
                nullable: false
                references: metabase_field(id)
              name: field_id
              type: int
          tableName: metabase_fieldvalues
      - createIndex:
          columns:
          - column:
              name: field_id
          indexName: idx_fieldvalues_field_id
          tableName: metabase_fieldvalues
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: name
              type: varchar(254)
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_tablesegment_ref_table_id
                initiallyDeferred: false
                nullable: false
                references: metabase_table(id)
              name: table_id
              type: int
          - column:
              constraints:
                nullable: false
              name: filter_clause
              type: text
          tableName: metabase_tablesegment
      - createIndex:
          columns:
          - column:
              name: table_id
          indexName: idx_tablesegment_table_id
          tableName: metabase_tablesegment
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: name
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: type
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: details
              type: text
          - column:
              constraints:
                nullable: false
              name: version
              type: int
          - column:
              constraints:
                nullable: false
              name: public_perms
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_query_ref_user_id
                initiallyDeferred: false
                nullable: false
                references: core_user(id)
              name: creator_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_query_ref_database_id
                initiallyDeferred: false
                nullable: false
                references: metabase_database(id)
              name: database_id
              type: int
          tableName: query_query
      - createIndex:
          columns:
          - column:
              name: creator_id
          indexName: idx_query_creator_id
          tableName: query_query
      - createIndex:
          columns:
          - column:
              name: database_id
          indexName: idx_query_database_id
          tableName: query_query
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
                unique: true
              name: uuid
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: version
              type: int
          - column:
              constraints:
                nullable: false
              name: json_query
              type: text
          - column:
              constraints:
                nullable: false
              name: raw_query
              type: text
          - column:
              constraints:
                nullable: false
              name: status
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: started_at
              type: DATETIME
          - column:
              name: finished_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: running_time
              type: int
          - column:
              constraints:
                nullable: false
              name: error
              type: text
          - column:
              constraints:
                nullable: false
              name: result_file
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: result_rows
              type: int
          - column:
              constraints:
                nullable: false
              name: result_data
              type: text
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_queryexecution_ref_query_id
                initiallyDeferred: false
                nullable: true
                references: query_query(id)
              name: query_id
              type: int
          - column:
              constraints:
                nullable: false
              name: additional_info
              type: text
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_queryexecution_ref_user_id
                initiallyDeferred: false
                nullable: false
                references: core_user(id)
              name: executor_id
              type: int
          tableName: query_queryexecution
      - createIndex:
          columns:
          - column:
              name: query_id
          indexName: idx_queryexecution_query_id
          tableName: query_queryexecution
      - createIndex:
          columns:
          - column:
              name: executor_id
          indexName: idx_queryexecution_executor_id
          tableName: query_queryexecution
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: name
              type: varchar(254)
          - column:
              name: description
              type: text
          - column:
              constraints:
                nullable: false
              name: display
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: public_perms
              type: int
          - column:
              constraints:
                nullable: false
              name: dataset_query
              type: text
          - column:
              constraints:
                nullable: false
              name: visualization_settings
              type: text
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_card_ref_user_id
                initiallyDeferred: false
                nullable: false
                references: core_user(id)
              name: creator_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_card_ref_organization_id
                initiallyDeferred: false
                nullable: false
                references: core_organization(id)
              name: organization_id
              type: int
          tableName: report_card
      - createIndex:
          columns:
          - column:
              name: creator_id
          indexName: idx_card_creator_id
          tableName: report_card
      - createIndex:
          columns:
          - column:
              name: organization_id
          indexName: idx_card_organization_id
          tableName: report_card
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_cardfavorite_ref_card_id
                initiallyDeferred: false
                nullable: false
                references: report_card(id)
              name: card_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_cardfavorite_ref_user_id
                initiallyDeferred: false
                nullable: false
                references: core_user(id)
              name: owner_id
              type: int
          tableName: report_cardfavorite
      - addUniqueConstraint:
          columnNames: card_id, owner_id
          constraintName: idx_unique_cardfavorite_card_id_owner_id
          tableName: report_cardfavorite
      - createIndex:
          columns:
          - column:
              name: card_id
          indexName: idx_cardfavorite_card_id
          tableName: report_cardfavorite
      - createIndex:
          columns:
          - column:
              name: owner_id
          indexName: idx_cardfavorite_owner_id
          tableName: report_cardfavorite
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: name
              type: varchar(254)
          - column:
              name: description
              type: text
          - column:
              constraints:
                nullable: false
              name: public_perms
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_dashboard_ref_user_id
                initiallyDeferred: false
                nullable: false
                references: core_user(id)
              name: creator_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_dashboard_ref_organization_id
                initiallyDeferred: false
                nullable: false
                references: core_organization(id)
              name: organization_id
              type: int
          tableName: report_dashboard
      - createIndex:
          columns:
          - column:
              name: creator_id
          indexName: idx_dashboard_creator_id
          tableName: report_dashboard
      - createIndex:
          columns:
          - column:
              name: organization_id
          indexName: idx_dashboard_organization_id
          tableName: report_dashboard
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: sizeX
              type: int
          - column:
              constraints:
                nullable: false
              name: sizeY
              type: int
          - column:
              name: row
              type: int
          - column:
              name: col
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_dashboardcard_ref_card_id
                initiallyDeferred: false
                nullable: false
                references: report_card(id)
              name: card_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_dashboardcard_ref_dashboard_id
                initiallyDeferred: false
                nullable: false
                references: report_dashboard(id)
              name: dashboard_id
              type: int
          tableName: report_dashboardcard
      - createIndex:
          columns:
          - column:
              name: card_id
          indexName: idx_dashboardcard_card_id
          tableName: report_dashboardcard
      - createIndex:
          columns:
          - column:
              name: dashboard_id
          indexName: idx_dashboardcard_dashboard_id
          tableName: report_dashboardcard
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_dashboardsubscription_ref_dashboard_id
                initiallyDeferred: false
                nullable: false
                references: report_dashboard(id)
              name: dashboard_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_dashboardsubscription_ref_user_id
                initiallyDeferred: false
                nullable: false
                references: core_user(id)
              name: user_id
              type: int
          tableName: report_dashboardsubscription
      - addUniqueConstraint:
          columnNames: dashboard_id, user_id
          constraintName: idx_uniq_dashsubscrip_dashboard_id_user_id
          tableName: report_dashboardsubscription
      - createIndex:
          columns:
          - column:
              name: dashboard_id
          indexName: idx_dashboardsubscription_dashboard_id
          tableName: report_dashboardsubscription
      - createIndex:
          columns:
          - column:
              name: user_id
          indexName: idx_dashboardsubscription_user_id
          tableName: report_dashboardsubscription
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: name
              type: varchar(254)
          - column:
              name: description
              type: text
          - column:
              constraints:
                nullable: false
              name: public_perms
              type: int
          - column:
              constraints:
                nullable: false
              name: mode
              type: int
          - column:
              constraints:
                nullable: false
              name: version
              type: int
          - column:
              constraints:
                nullable: false
              name: dataset_query
              type: text
          - column:
              name: email_addresses
              type: text
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_emailreport_ref_user_id
                initiallyDeferred: false
                nullable: false
                references: core_user(id)
              name: creator_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_emailreport_ref_organization_id
                initiallyDeferred: false
                nullable: false
                references: core_organization(id)
              name: organization_id
              type: int
          - column:
              constraints:
                nullable: false
              name: schedule
              type: text
          tableName: report_emailreport
      - createIndex:
          columns:
          - column:
              name: creator_id
          indexName: idx_emailreport_creator_id
          tableName: report_emailreport
      - createIndex:
          columns:
          - column:
              name: organization_id
          indexName: idx_emailreport_organization_id
          tableName: report_emailreport
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_emailreport_recipients_ref_emailreport_id
                initiallyDeferred: false
                nullable: false
                references: report_emailreport(id)
              name: emailreport_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_emailreport_recipients_ref_user_id
                initiallyDeferred: false
                nullable: false
                references: core_user(id)
              name: user_id
              type: int
          tableName: report_emailreport_recipients
      - addUniqueConstraint:
          columnNames: emailreport_id, user_id
          constraintName: idx_uniq_emailreportrecip_emailreport_id_user_id
          tableName: report_emailreport_recipients
      - createIndex:
          columns:
          - column:
              name: emailreport_id
          indexName: idx_emailreport_recipients_emailreport_id
          tableName: report_emailreport_recipients
      - createIndex:
          columns:
          - column:
              name: user_id
          indexName: idx_emailreport_recipients_user_id
          tableName: report_emailreport_recipients
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: details
              type: text
          - column:
              constraints:
                nullable: false
              name: status
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              name: started_at
              type: DATETIME
          - column:
              name: finished_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: error
              type: text
          - column:
              constraints:
                nullable: false
              name: sent_email
              type: text
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_emailreportexecutions_ref_organization_id
                initiallyDeferred: false
                nullable: false
                references: core_organization(id)
              name: organization_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_emailreportexecutions_ref_report_id
                initiallyDeferred: false
                nullable: true
                references: report_emailreport(id)
              name: report_id
              type: int
          tableName: report_emailreportexecutions
      - createIndex:
          columns:
          - column:
              name: organization_id
          indexName: idx_emailreportexecutions_organization_id
          tableName: report_emailreportexecutions
      - createIndex:
          columns:
          - column:
              name: report_id
          indexName: idx_emailreportexecutions_report_id
          tableName: report_emailreportexecutions
      - createTable:
          columns:
          - column:
              autoIncrement: true
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: updated_at
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: start
              type: DATETIME
          - column:
              constraints:
                nullable: false
              name: end
              type: DATETIME
          - column:
              name: title
              type: TEXT
          - column:
              constraints:
                nullable: false
              name: body
              type: TEXT
          - column:
              constraints:
                nullable: false
              name: annotation_type
              type: int
          - column:
              constraints:
                nullable: false
              name: edit_count
              type: int
          - column:
              constraints:
                nullable: false
              name: object_type_id
              type: int
          - column:
              constraints:
                nullable: false
              name: object_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_annotation_ref_user_id
                initiallyDeferred: false
                nullable: false
                references: core_user(id)
              name: author_id
              type: int
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_annotation_ref_organization_id
                initiallyDeferred: false
                nullable: false
                references: core_organization(id)
              name: organization_id
              type: int
          tableName: annotation_annotation
      - createIndex:
          columns:
          - column:
              name: author_id
          indexName: idx_annotation_author_id
          tableName: annotation_annotation
      - createIndex:
          columns:
          - column:
              name: organization_id
          indexName: idx_annotation_organization_id
          tableName: annotation_annotation
      - createIndex:
          columns:
          - column:
              name: object_type_id
          indexName: idx_annotation_object_type_id
          tableName: annotation_annotation
      - createIndex:
          columns:
          - column:
              name: object_id
          indexName: idx_annotation_object_id
          tableName: annotation_annotation
      - modifySql:
          dbms: postgresql
          replace:
            replace: WITHOUT
            with: WITH
  - changeSet:
      id: '2'
      author: agilliland
      changes:
      - createTable:
          columns:
          - column:
              constraints:
                nullable: false
                primaryKey: true
              name: id
              type: varchar(254)
          - column:
              constraints:
                deferrable: false
                foreignKeyName: fk_session_ref_user_id
                initiallyDeferred: false
                nullable: false
                references: core_user(id)
              name: user_id
              type: int
          - column:
              constraints:
                nullable: false
              name: created_at
              type: DATETIME
          tableName: core_session
      - modifySql:
          dbms: postgresql
          replace:
            replace: WITHOUT
            with: WITH
  - changeSet:
      id: '4'
      author: cammsaul
      changes:
      - createTable:
          columns:
          - column:
              constraints:
                nullable: false
                primaryKey: true
              name: key
              type: varchar(254)
          - column:
              constraints:
                nullable: false
              name: value
              type: varchar(254)
          tableName: setting
  - changeSet:
      id: '5'
      author: agilliland
      changes:
      - addColumn:
          columns:
          - column:
              name: report_timezone
              type: varchar(254)
          tableName: core_organization
  - changeSet:
      id: '6'
      author: agilliland
      changes:
      - dropNotNullConstraint:
          columnDataType: int
          columnName: organization_id
          tableName: metabase_database
      - dropForeignKeyConstraint:
          baseTableName: metabase_database
          constraintName: fk_database_ref_organization_id
      - dropNotNullConstraint:
          columnDataType: int
          columnName: organization_id
          tableName: report_card
      - dropForeignKeyConstraint:
          baseTableName: report_card
          constraintName: fk_card_ref_organization_id
      - dropNotNullConstraint:
          columnDataType: int
          columnName: organization_id
          tableName: report_dashboard
      - dropForeignKeyConstraint:
          baseTableName: report_dashboard
          constraintName: fk_dashboard_ref_organization_id
      - dropNotNullConstraint:
          columnDataType: int
          columnName: organization_id
          tableName: report_emailreport
      - dropForeignKeyConstraint:
          baseTableName: report_emailreport
          constraintName: fk_emailreport_ref_organization_id
      - dropNotNullConstraint:
          columnDataType: int
          columnName: organization_id
          tableName: report_emailreportexecutions
      - dropForeignKeyConstraint:
          baseTableName: report_emailreportexecutions
          constraintName: fk_emailreportexecutions_ref_organization_id
      - dropNotNullConstraint:
          columnDataType: int
          columnName: organization_id
          tableName: annotation_annotation
      - dropForeignKeyConstraint:
          baseTableName: annotation_annotation
          constraintName: fk_annotation_ref_organization_id
  - changeSet:
      id: '7'
      author: cammsaul
      changes:
      - addColumn:
          columns:
          - column:
              constraints:
                foreignKeyName: fk_field_parent_ref_field_id
                nullable: true
                references: metabase_field(id)
              name: parent_id
              type: int
          tableName: metabase_field
  - changeSet:
      id: '8'
      author: tlrobinson
      changes:
      - addColumn:
          columns:
          - column:
              name: display_name
              type: varchar(254)
          tableName: metabase_table
      - addColumn:
          columns:
          - column:
              name: display_name
              type: varchar(254)
          tableName: metabase_field
  - changeSet:
      id: '9'
      author: tlrobinson
      changes:
      - addColumn:
          columns:
          - column:
              name: visibility_type
              type: varchar(254)
          tableName: metabase_table
  - changeSet:
      id: 10
      author: cammsaul
      validCheckSum:
        - 7:3b90e2fe0ac8e617a1f30ef95d39319b
        - 7:97fec69516d0dfe424ea7365f51bb87e
        - 8:2e03a495932b4a9aebb9d58a6ad87ca9
        - 8:431360d062cb82d8b27960b3a0abb98c
        - 8:5297214d1788d964675d8c6336ac9b6d
        - 8:532075ff1717d4a16bb9f27c606db46b
        - 8:96e54d9100db3f9cdcc00eaeccc200a3
        - 8:9f03a236be31f54e8e5c894fe5fc7f00
      changes:
        - createTable:
            tableName: revision
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: model
                  type: varchar(16)
                  constraints:
                    nullable: false
              - column:
                  name: model_id
                  type: int
                  constraints:
                    nullable: false
              - column:
                  name: user_id
                  type: int
                  constraints:
                    nullable: false
                    references: core_user(id)
                    foreignKeyName: fk_revision_ref_user_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: timestamp
                  type: DATETIME
                  constraints:
                    nullable: false
              - column:
                  name: object
                  type: varchar
                  constraints:
                    nullable: false
              - column:
                  name: is_reversion
                  type: boolean
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
        - createIndex:
            tableName: revision
            indexName: idx_revision_model_model_id
            columns:
              - column:
                  name: model
              - column:
                  name: model_id
        - modifySql:
            dbms: postgresql
            replace:
              replace: WITHOUT
              with: WITH
        - modifySql:
            dbms: mysql,mariadb
            replace:
              replace: object VARCHAR
              with: object TEXT
  - changeSet:
      id: 11
      author: agilliland
      changes:
        - sql:
            sql: update report_dashboard set public_perms = 2 where public_perms = 1
  - changeSet:
      id: 12
      author: agilliland
      validCheckSum:
        - 8:bedbea570e5dfc694b4cf5a8f6a4f445
        - 8:e862a199cba5b4ce0cba713110f66cfb
      changes:
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: database_id
                  type: int
                  constraints:
                    nullable: true
                    references: metabase_database(id)
                    foreignKeyName: fk_report_card_ref_database_id
                    deferrable: false
                    initiallyDeferred: false
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: table_id
                  type: int
                  constraints:
                    nullable: true
                    references: metabase_table(id)
                    foreignKeyName: fk_report_card_ref_table_id
                    deferrable: false
                    initiallyDeferred: false
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: query_type
                  type: varchar(16)
                  constraints:
                    nullable: true
  - changeSet:
      id: 13
      author: agilliland
      validCheckSum:
        - 7:f27286894439bef33ff93761f9b32bc4
        - 7:1bc8ccc9b1803cda5651f144029be40c
      changes:
        - createTable:
            tableName: activity
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: topic
                  type: varchar(32)
                  constraints:
                    nullable: false
              - column:
                  name: timestamp
                  type: DATETIME
                  constraints:
                    nullable: false
              - column:
                  name: user_id
                  type: int
                  constraints:
                    nullable: true
                    references: core_user(id)
                    foreignKeyName: fk_activity_ref_user_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: model
                  type: varchar(16)
                  constraints:
                    nullable: true
              - column:
                  name: model_id
                  type: int
                  constraints:
                    nullable: true
              - column:
                  name: database_id
                  type: int
                  constraints:
                    nullable: true
              - column:
                  name: table_id
                  type: int
                  constraints:
                    nullable: true
              - column:
                  name: custom_id
                  type: varchar(48)
                  constraints:
                    nullable: true
              - column:
                  name: details
                  type: varchar
                  constraints:
                    nullable: false
        - createIndex:
            tableName: activity
            indexName: idx_activity_timestamp
            columns:
              column:
                name: timestamp
        - createIndex:
            tableName: activity
            indexName: idx_activity_user_id
            columns:
              column:
                name: user_id
        - createIndex:
            tableName: activity
            indexName: idx_activity_custom_id
            columns:
              column:
                name: custom_id
        - modifySql:
            dbms: postgresql
            replace:
              replace: WITHOUT
              with: WITH
        - modifySql:
            dbms: mysql,mariadb
            replace:
              replace: details VARCHAR
              with: details TEXT
  - changeSet:
      id: 14
      author: agilliland
      changes:
        - createTable:
            tableName: view_log
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: user_id
                  type: int
                  constraints:
                    nullable: true
                    references: core_user(id)
                    foreignKeyName: fk_view_log_ref_user_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: model
                  type: varchar(16)
                  constraints:
                    nullable: false
              - column:
                  name: model_id
                  type: int
                  constraints:
                    nullable: false
              - column:
                  name: timestamp
                  type: DATETIME
                  constraints:
                    nullable: false
        - createIndex:
            tableName: view_log
            indexName: idx_view_log_user_id
            columns:
              column:
                name: user_id
        - createIndex:
            tableName: view_log
            indexName: idx_view_log_timestamp
            columns:
              column:
                name: model_id
        - modifySql:
            dbms: postgresql
            replace:
              replace: WITHOUT
              with: WITH
  - changeSet:
      id: 15
      author: agilliland
      objectQuotingStrategy: ${quote_strategy}
      changes:
        - addColumn:
            tableName: revision
            columns:
              - column:
                  name: is_creation
                  type: boolean
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
  - changeSet:
      id: 16
      author: agilliland
      changes:
        - dropNotNullConstraint:
            tableName: core_user
            columnName: last_login
            columnDataType: DATETIME
        - modifySql:
            dbms: postgresql
            replace:
              replace: WITHOUT
              with: WITH
  - changeSet:
      id: 17
      author: agilliland
      changes:
        - addColumn:
            tableName: metabase_database
            columns:
              - column:
                  name: is_sample
                  type: boolean
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
        - sql:
            sql: update metabase_database set is_sample = true where name = 'Sample Dataset'
  - changeSet:
      id: 18
      author: camsaul
      validCheckSum:
        - 7:07d501a6e52c14691f7f895d137e565f
        - 7:329d897d44ba9893fdafc9ce7e876d73
      changes:
        - createTable:
            tableName: data_migrations
            columns:
              - column:
                  name: id
                  type: VARCHAR(254)
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: timestamp
                  type: DATETIME
                  constraints:
                    nullable: false
        - createIndex:
            tableName: data_migrations
            indexName: idx_data_migrations_id
            columns:
              column:
                name: id
  - changeSet:
      id: 19
      author: camsaul
      changes:
        - addColumn:
            tableName: metabase_table
            columns:
              - column:
                  name: schema
                  type: VARCHAR(256)
  - changeSet:
      id: 20
      author: agilliland
      changes:
        - createTable:
            tableName: pulse
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: creator_id
                  type: int
                  constraints:
                    nullable: false
                    references: core_user(id)
                    foreignKeyName: fk_pulse_ref_creator_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: name
                  type: varchar(254)
                  constraints:
                    nullable: false
              - column:
                  name: public_perms
                  type: int
                  constraints:
                    nullable: false
              - column:
                  name: created_at
                  type: DATETIME
                  constraints:
                    nullable: false
              - column:
                  name: updated_at
                  type: DATETIME
                  constraints:
                    nullable: false
        - createIndex:
            tableName: pulse
            indexName: idx_pulse_creator_id
            columns:
              column:
                name: creator_id
        - createTable:
            tableName: pulse_card
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: pulse_id
                  type: int
                  constraints:
                    nullable: false
                    references: pulse(id)
                    foreignKeyName: fk_pulse_card_ref_pulse_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: card_id
                  type: int
                  constraints:
                    nullable: false
                    references: report_card(id)
                    foreignKeyName: fk_pulse_card_ref_card_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: position
                  type: int
                  constraints:
                    nullable: false
        - createIndex:
            tableName: pulse_card
            indexName: idx_pulse_card_pulse_id
            columns:
              column:
                name: pulse_id
        - createIndex:
            tableName: pulse_card
            indexName: idx_pulse_card_card_id
            columns:
              column:
                name: card_id
        - createTable:
            tableName: pulse_channel
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: pulse_id
                  type: int
                  constraints:
                    nullable: false
                    references: pulse(id)
                    foreignKeyName: fk_pulse_channel_ref_pulse_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: channel_type
                  type: varchar(32)
                  constraints:
                    nullable: false
              - column:
                  name: details
                  type: text
                  constraints:
                    nullable: false
              - column:
                  name: schedule_type
                  type: varchar(32)
                  constraints:
                    nullable: false
              - column:
                  name: schedule_hour
                  type: int
                  constraints:
                    nullable: true
              - column:
                  name: schedule_day
                  type: varchar(64)
                  constraints:
                    nullable: true
              - column:
                  name: created_at
                  type: DATETIME
                  constraints:
                    nullable: false
              - column:
                  name: updated_at
                  type: DATETIME
                  constraints:
                    nullable: false
        - createIndex:
            tableName: pulse_channel
            indexName: idx_pulse_channel_pulse_id
            columns:
              column:
                name: pulse_id
        - createIndex:
            tableName: pulse_channel
            indexName: idx_pulse_channel_schedule_type
            columns:
              column:
                name: schedule_type
        - createTable:
            tableName: pulse_channel_recipient
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: pulse_channel_id
                  type: int
                  constraints:
                    nullable: false
                    references: pulse_channel(id)
                    foreignKeyName: fk_pulse_channel_recipient_ref_pulse_channel_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: user_id
                  type: int
                  constraints:
                    nullable: false
                    references: core_user(id)
                    foreignKeyName: fk_pulse_channel_recipient_ref_user_id
                    deferrable: false
                    initiallyDeferred: false
        - modifySql:
            dbms: postgresql
            replace:
              replace: WITHOUT
              with: WITH
  - changeSet:
      id: 21
      author: agilliland
      changes:
        - createTable:
            tableName: segment
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: table_id
                  type: int
                  constraints:
                    nullable: false
                    references: metabase_table(id)
                    foreignKeyName: fk_segment_ref_table_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: creator_id
                  type: int
                  constraints:
                    nullable: false
                    references: core_user(id)
                    foreignKeyName: fk_segment_ref_creator_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: name
                  type: varchar(254)
                  constraints:
                    nullable: false
              - column:
                  name: description
                  type: text
                  constraints:
                    nullable: true
              - column:
                  name: is_active
                  type: boolean
                  defaultValueBoolean: true
                  constraints:
                    nullable: false
              - column:
                  name: definition
                  type: text
                  constraints:
                    nullable: false
              - column:
                  name: created_at
                  type: DATETIME
                  constraints:
                    nullable: false
              - column:
                  name: updated_at
                  type: DATETIME
                  constraints:
                    nullable: false
        - createIndex:
            tableName: segment
            indexName: idx_segment_creator_id
            columns:
              column:
                name: creator_id
        - createIndex:
            tableName: segment
            indexName: idx_segment_table_id
            columns:
              column:
                name: table_id
        - modifySql:
            dbms: postgresql
            replace:
              replace: WITHOUT
              with: WITH
  - changeSet:
      id: 22
      author: agilliland
      changes:
        - addColumn:
            tableName: revision
            columns:
              - column:
                  name: message
                  type: text
                  constraints:
                    nullable: true
  - changeSet:
      id: 23
      author: agilliland
      objectQuotingStrategy: ${quote_strategy}
      changes:
        - modifyDataType:
            tableName: metabase_table
            columnName: rows
            newDataType: BIGINT
  - changeSet:
      id: 24
      author: agilliland
      changes:
        - createTable:
            tableName: dependency
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: model
                  type: varchar(32)
                  constraints:
                    nullable: false
              - column:
                  name: model_id
                  type: int
                  constraints:
                    nullable: false
              - column:
                  name: dependent_on_model
                  type: varchar(32)
                  constraints:
                    nullable: false
              - column:
                  name: dependent_on_id
                  type: int
                  constraints:
                    nullable: false
              - column:
                  name: created_at
                  type: DATETIME
                  constraints:
                    nullable: false
        - createIndex:
            tableName: dependency
            indexName: idx_dependency_model
            columns:
              column:
                name: model
        - createIndex:
            tableName: dependency
            indexName: idx_dependency_model_id
            columns:
              column:
                name: model_id
        - createIndex:
            tableName: dependency
            indexName: idx_dependency_dependent_on_model
            columns:
              column:
                name: dependent_on_model
        - createIndex:
            tableName: dependency
            indexName: idx_dependency_dependent_on_id
            columns:
              column:
                name: dependent_on_id
        - modifySql:
            dbms: postgresql
            replace:
              replace: WITHOUT
              with: WITH
  - changeSet:
      id: 25
      author: agilliland
      changes:
        - createTable:
            tableName: metric
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: table_id
                  type: int
                  constraints:
                    nullable: false
                    references: metabase_table(id)
                    foreignKeyName: fk_metric_ref_table_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: creator_id
                  type: int
                  constraints:
                    nullable: false
                    references: core_user(id)
                    foreignKeyName: fk_metric_ref_creator_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: name
                  type: varchar(254)
                  constraints:
                    nullable: false
              - column:
                  name: description
                  type: text
                  constraints:
                    nullable: true
              - column:
                  name: is_active
                  type: boolean
                  defaultValueBoolean: true
                  constraints:
                    nullable: false
              - column:
                  name: definition
                  type: text
                  constraints:
                    nullable: false
              - column:
                  name: created_at
                  type: DATETIME
                  constraints:
                    nullable: false
              - column:
                  name: updated_at
                  type: DATETIME
                  constraints:
                    nullable: false
        - createIndex:
            tableName: metric
            indexName: idx_metric_creator_id
            columns:
              column:
                name: creator_id
        - createIndex:
            tableName: metric
            indexName: idx_metric_table_id
            columns:
              column:
                name: table_id
        - modifySql:
            dbms: postgresql
            replace:
              replace: WITHOUT
              with: WITH
  - changeSet:
      id: 26
      author: agilliland
      changes:
        - addColumn:
            tableName: metabase_database
            columns:
              - column:
                  name: is_full_sync
                  type: boolean
                  defaultValueBoolean: true
                  constraints:
                    nullable: false
        - sql:
            sql: update metabase_database set is_full_sync = true
  - changeSet:
      id: 27
      author: agilliland
      changes:
        - createTable:
            tableName: dashboardcard_series
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: dashboardcard_id
                  type: int
                  constraints:
                    nullable: false
                    references: report_dashboardcard(id)
                    foreignKeyName: fk_dashboardcard_series_ref_dashboardcard_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: card_id
                  type: int
                  constraints:
                    nullable: false
                    references: report_card(id)
                    foreignKeyName: fk_dashboardcard_series_ref_card_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: position
                  type: int
                  constraints:
                    nullable: false
        - createIndex:
            tableName: dashboardcard_series
            indexName: idx_dashboardcard_series_dashboardcard_id
            columns:
              column:
                name: dashboardcard_id
        - createIndex:
            tableName: dashboardcard_series
            indexName: idx_dashboardcard_series_card_id
            columns:
              column:
                name: card_id
        - modifySql:
            dbms: postgresql
            replace:
              replace: WITHOUT
              with: WITH
  - changeSet:
      id: 28
      author: agilliland
      changes:
        - addColumn:
            tableName: core_user
            columns:
              - column:
                  name: is_qbnewb
                  type: boolean
                  defaultValueBoolean: true
                  constraints:
                    nullable: false
  - changeSet:
      id: 29
      author: agilliland
      changes:
        - addColumn:
            tableName: pulse_channel
            columns:
              - column:
                  name: schedule_frame
                  type: varchar(32)
                  constraints:
                    nullable: true
  - changeSet:
      id: 30
      author: agilliland
      changes:
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: visibility_type
                  type: varchar(32)
                  constraints:
                    nullable: true
                    deferrable: false
                    initiallyDeferred: false
        - addNotNullConstraint:
            columnDataType: varchar(32)
            columnName: visibility_type
            defaultNullValue: unset
            tableName: metabase_field
  - changeSet:
      id: 31
      author: agilliland
      changes:
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: fk_target_field_id
                  type: int
                  constraints:
                    nullable: true
                    deferrable: false
                    initiallyDeferred: false
  - changeSet:
      id: 32
      author: camsaul
      changes:
        ######################################## label table ########################################
        - createTable:
            tableName: label
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: name
                  type: VARCHAR(254)
                  constraints:
                    nullable: false
              - column:
                  name: slug
                  type: VARCHAR(254)
                  constraints:
                    nullable: false
                    unique: true
              - column:
                  name: icon
                  type: VARCHAR(128)
        - createIndex:
            tableName: label
            indexName: idx_label_slug
            columns:
              column:
                name: slug
        ######################################## card_label table ########################################
        - createTable:
            tableName: card_label
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: card_id
                  type: int
                  constraints:
                    nullable: false
                    references: report_card(id)
                    foreignKeyName: fk_card_label_ref_card_id
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: label_id
                  type: int
                  constraints:
                    nullable: false
                    references: label(id)
                    foreignKeyName: fk_card_label_ref_label_id
                    deferrable: false
                    initiallyDeferred: false
        - addUniqueConstraint:
            tableName: card_label
            columnNames: card_id, label_id
            constraintName: unique_card_label_card_id_label_id
        - createIndex:
            tableName: card_label
            indexName: idx_card_label_card_id
            columns:
              column:
                name: card_id
        - createIndex:
            tableName: card_label
            indexName: idx_card_label_label_id
            columns:
              column:
                name: label_id
        ######################################## add archived column to report_card ########################################
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: archived
                  type: boolean
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
  - changeSet:
      id: 32
      author: agilliland
      changes:
        - createTable:
            tableName: raw_table
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: database_id
                  type: int
                  constraints:
                    nullable: false
                    references: metabase_database(id)
                    foreignKeyName: fk_rawtable_ref_database
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: active
                  type: boolean
                  constraints:
                    nullable: false
              - column:
                  name: schema
                  type: varchar(255)
                  constraints:
                    nullable: true
              - column:
                  name: name
                  type: varchar(255)
                  constraints:
                    nullable: false
              - column:
                  name: details
                  type: text
                  constraints:
                    nullable: false
              - column:
                  name: created_at
                  type: DATETIME
                  constraints:
                    nullable: false
              - column:
                  name: updated_at
                  type: DATETIME
                  constraints:
                    nullable: false
        - createIndex:
            tableName: raw_table
            indexName: idx_rawtable_database_id
            columns:
              column:
                name: database_id
        - addUniqueConstraint:
            tableName: raw_table
            columnNames: database_id, schema, name
            constraintName: uniq_raw_table_db_schema_name
        - createTable:
            tableName: raw_column
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: raw_table_id
                  type: int
                  constraints:
                    nullable: false
                    references: raw_table(id)
                    foreignKeyName: fk_rawcolumn_tableid_ref_rawtable
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: active
                  type: boolean
                  constraints:
                    nullable: false
              - column:
                  name: name
                  type: varchar(255)
                  constraints:
                    nullable: false
              - column:
                  name: column_type
                  type: varchar(128)
                  constraints:
                    nullable: true
              - column:
                  name: is_pk
                  type: boolean
                  constraints:
                    nullable: false
              - column:
                  name: fk_target_column_id
                  type: int
                  constraints:
                    nullable: true
                    references: raw_column(id)
                    foreignKeyName: fk_rawcolumn_fktarget_ref_rawcolumn
                    deferrable: false
                    initiallyDeferred: false
              - column:
                  name: details
                  type: text
                  constraints:
                    nullable: false
              - column:
                  name: created_at
                  type: DATETIME
                  constraints:
                    nullable: false
              - column:
                  name: updated_at
                  type: DATETIME
                  constraints:
                    nullable: false
        - createIndex:
            tableName: raw_column
            indexName: idx_rawcolumn_raw_table_id
            columns:
              column:
                name: raw_table_id
        - addUniqueConstraint:
            tableName: raw_column
            columnNames: raw_table_id, name
            constraintName: uniq_raw_column_table_name
        - addColumn:
            tableName: metabase_table
            columns:
              - column:
                  name: raw_table_id
                  type: int
                  constraints:
                    nullable: true
                    deferrable: false
                    initiallyDeferred: false
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: raw_column_id
                  type: int
                  constraints:
                    nullable: true
                    deferrable: false
                    initiallyDeferred: false
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: last_analyzed
                  type: DATETIME
                  constraints:
                    nullable: true
                    deferrable: false
                    initiallyDeferred: false
        - modifySql:
            dbms: postgresql
            replace:
              replace: WITHOUT
              with: WITH
  - changeSet:
      id: 34
      author: tlrobinson
      changes:
        ######################################## add enabled column to pulse_channel ########################################
        - addColumn:
            tableName: pulse_channel
            columns:
              - column:
                  name: enabled
                  type: boolean
                  defaultValueBoolean: true
                  constraints:
                    nullable: false
  - changeSet:
      id: 35
      author: agilliland
      changes:
        - modifyDataType:
            tableName: setting
            columnName: value
            newDataType: TEXT
        - addNotNullContstraint:
            tableName: setting
            columnNames: value
  - changeSet:
      id: 36
      author: agilliland
      changes:
        - addColumn:
            tableName: report_dashboard
            columns:
              - column:
                  name: parameters
                  type: text
                  constraints:
                    nullable: true
                    deferrable: false
                    initiallyDeferred: false
        - addNotNullConstraint:
            columnDataType: text
            columnName: parameters
            defaultNullValue: '[]'
            tableName: report_dashboard
        - addColumn:
            tableName: report_dashboardcard
            columns:
              - column:
                  name: parameter_mappings
                  type: text
                  constraints:
                    nullable: true
                    deferrable: false
                    initiallyDeferred: false
        - addNotNullConstraint:
            columnDataType: text
            columnName: parameter_mappings
            defaultNullValue: '[]'
            tableName: report_dashboardcard
  - changeSet:
      id: 37
      author: tlrobinson
      changes:
        - addColumn:
            tableName: query_queryexecution
            columns:
              - column:
                  name: query_hash
                  type: int
                  constraints:
                    nullable: true
        - addNotNullConstraint:
            tableName: query_queryexecution
            columnName: query_hash
            columnDataType: int
            defaultNullValue: 0
        - createIndex:
            tableName: query_queryexecution
            indexName: idx_query_queryexecution_query_hash
            columns:
              column:
                name: query_hash
        - createIndex:
            tableName: query_queryexecution
            indexName: idx_query_queryexecution_started_at
            columns:
              column:
                name: started_at
  - changeSet:
      id: 38
      author: camsaul
      changes:
        ######################################## Add "points_of_interest" metadata column to various models ########################################
        - addColumn:
            tableName: metabase_database
            columns:
              - column:
                  name: points_of_interest
                  type: text
        - addColumn:
            tableName: metabase_table
            columns:
              - column:
                  name: points_of_interest
                  type: text
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: points_of_interest
                  type: text
        - addColumn:
            tableName: report_dashboard
            columns:
              - column:
                  name: points_of_interest
                  type: text
        - addColumn:
            tableName: metric
            columns:
              - column:
                  name: points_of_interest
                  type: text
        - addColumn:
            tableName: segment
            columns:
              - column:
                  name: points_of_interest
                  type: text
        ######################################## Add "caveats" metadata column to various models ########################################
        - addColumn:
            tableName: metabase_database
            columns:
              - column:
                  name: caveats
                  type: text
        - addColumn:
            tableName: metabase_table
            columns:
              - column:
                  name: caveats
                  type: text
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: caveats
                  type: text
        - addColumn:
            tableName: report_dashboard
            columns:
              - column:
                  name: caveats
                  type: text
        - addColumn:
            tableName: metric
            columns:
              - column:
                  name: caveats
                  type: text
        - addColumn:
            tableName: segment
            columns:
              - column:
                  name: caveats
                  type: text
        ######################################## Add "how_is_this_calculated" to metric ########################################
        - addColumn:
            tableName: metric
            columns:
              - column:
                  name: how_is_this_calculated
                  type: text
        ######################################## Add "most important dashboard" (0 or 1 dashboards) ########################################
        - addColumn:
            tableName: report_dashboard
            columns:
              - column:
                  name: show_in_getting_started
                  type: boolean
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
        - createIndex:
            tableName: report_dashboard
            indexName: idx_report_dashboard_show_in_getting_started
            columns:
              column:
                name: show_in_getting_started
        ######################################## Add "most important metrics" (0+ metrics) ########################################
        - addColumn:
            tableName: metric
            columns:
              - column:
                  name: show_in_getting_started
                  type: boolean
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
        - createIndex:
            tableName: metric
            indexName: idx_metric_show_in_getting_started
            columns:
              column:
                name: show_in_getting_started
        ######################################## Add "most important tables (0+ tables) ########################################
        - addColumn:
            tableName: metabase_table
            columns:
              - column:
                  name: show_in_getting_started
                  type: boolean
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
        - createIndex:
            tableName: metabase_table
            indexName: idx_metabase_table_show_in_getting_started
            columns:
              column:
                name: show_in_getting_started
        ######################################## Add "most important segments" (0+ segments) ########################################
        - addColumn:
            tableName: segment
            columns:
              - column:
                  name: show_in_getting_started
                  type: boolean
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
        - createIndex:
            tableName: segment
            indexName: idx_segment_show_in_getting_started
            columns:
              column:
                name: show_in_getting_started
        ######################################## Add "metric_important_field" table ########################################
        - createTable:
            tableName: metric_important_field
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: metric_id
                  type: int
                  constraints:
                    nullable: false
                    references: metric(id)
                    foreignKeyName: fk_metric_important_field_metric_id
              - column:
                  name: field_id
                  type: int
                  constraints:
                    nullable: false
                    references: metabase_field(id)
                    foreignKeyName: fk_metric_important_field_metabase_field_id
        - addUniqueConstraint:
            tableName: metric_important_field
            columnNames: metric_id, field_id
            constraintName: unique_metric_important_field_metric_id_field_id
        - createIndex:
            tableName: metric_important_field
            indexName: idx_metric_important_field_metric_id
            columns:
              column:
                name: metric_id
        - createIndex:
            tableName: metric_important_field
            indexName: idx_metric_important_field_field_id
            columns:
              column:
                name: field_id
  - changeSet:
      id: 39
      author: camsaul
      changes:
        - addColumn:
            tableName: core_user
            columns:
              - column:
                  name: google_auth
                  type: boolean
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
  - changeSet:
      id: 40
      author: camsaul
      validCheckSum:
        - 8:231d66cf27fc4b4bc066172b435439b5
        - 8:ee7f50a264d6cf8d891bd01241eebd2c
      changes:
        ############################################################ add PermissionsGroup table ############################################################
        - createTable:
            tableName: permissions_group
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              # TODO - it would be nice to make this a case-insensitive unique constraint / index?
              - column:
                  name: name
                  type: varchar(255)
                  constraints:
                    nullable: false
                    unique: true
                    uniqueConstraintName: unique_permissions_group_name
        - createIndex:
            tableName: permissions_group
            indexName: idx_permissions_group_name
            columns:
              column:
                name: name
        ############################################################ add PermissionsGroupMembership table ############################################################
        - createTable:
            tableName: permissions_group_membership
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: user_id
                  type: int
                  constraints:
                    nullable: false
                    references: core_user(id)
                    foreignKeyName: fk_permissions_group_membership_user_id
              - column:
                  name: group_id
                  type: int
                  constraints:
                    nullable: false
                    references: permissions_group(id)
                    foreignKeyName: fk_permissions_group_group_id
        - addUniqueConstraint:
            tableName: permissions_group_membership
            columnNames: user_id, group_id
            constraintName: unique_permissions_group_membership_user_id_group_id
        # for things like all users in a given group
        - createIndex:
            tableName: permissions_group_membership
            indexName: idx_permissions_group_membership_group_id
            columns:
              column:
                name: group_id
        # for things like all groups a user belongs to
        - createIndex:
            tableName: permissions_group_membership
            indexName: idx_permissions_group_membership_user_id
            columns:
              column:
                name: user_id
        # for things like is given user a member of a given group (TODO - not sure we need this)
        - createIndex:
            tableName: permissions_group_membership
            indexName: idx_permissions_group_membership_group_id_user_id
            columns:
              - column:
                  name: group_id
              - column:
                  name: user_id
        ############################################################ add Permissions table ############################################################
        - createTable:
            tableName: permissions
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: object
                  type: varchar(254)
                  constraints:
                    nullable: false
              - column:
                  name: group_id
                  type: int
                  constraints:
                    nullable: false
                    references: permissions_group(id)
                    foreignKeyName: fk_permissions_group_id
        - createIndex:
            tableName: permissions
            indexName: idx_permissions_group_id
            columns:
              column:
                name: group_id
        - createIndex:
            tableName: permissions
            indexName: idx_permissions_object
            columns:
              column:
                name: object
        - createIndex:
            tableName: permissions
            indexName: idx_permissions_group_id_object
            columns:
              - column:
                  name: group_id
              - column:
                  name: object
        - addUniqueConstraint:
            tableName: permissions
            columnNames: group_id, object
        ############################################################ Tweaks to metabase_table ############################################################
        # Modify the length of metabase_table.schema from 256 -> 254
        # It turns out MySQL InnoDB indices have to be 767 bytes or less (at least for older versions of MySQL)
        # and 'utf8' text columns can use up to 3 bytes per character in MySQL -- see http://stackoverflow.com/a/22515986/1198455
        # So 256 * 3 = 768 bytes (too large to index / add unique constraints)
        # Drop this to 254; 254 * 3 = 762, which should give us room to index it along with a 4-byte integer as well if need be
        # Hoping this doesn't break anyone's existing databases. Hopefully there aren't any schemas that are 255 or 256 bytes long out there; any longer
        # and it would have already broke; any shorter and there's not problem.
        # Anyway, better to break it now than to leave it as-is and have and break permissions where the columns have to be 254 characters wide
        - modifyDataType:
            tableName: metabase_table
            columnName: schema
            newDataType: varchar(254)
        # Add index: this is for doing things like getting all the tables that belong to a given schema
        - createIndex:
            tableName: metabase_table
            indexName: idx_metabase_table_db_id_schema
            columns:
              - column:
                  name: db_id
              - column:
                  name: schema
  - changeSet:
      id: 41
      author: camsaul
      changes:
        - dropColumn:
            tableName: metabase_field
            columnName: field_type
        - addDefaultValue:
            tableName: metabase_field
            columnName: active
            defaultValueBoolean: true
        - addDefaultValue:
            tableName: metabase_field
            columnName: preview_display
            defaultValueBoolean: true
        - addDefaultValue:
            tableName: metabase_field
            columnName: position
            defaultValueNumeric: 0
        - addDefaultValue:
            tableName: metabase_field
            columnName: visibility_type
            defaultValue: "normal"
  - changeSet:
      id: 42
      author: camsaul
      changes:
        - dropForeignKeyConstraint:
            baseTableName: query_queryexecution
            constraintName: fk_queryexecution_ref_query_id
        - dropColumn:
            tableName: query_queryexecution
            columnName: query_id
        - dropColumn:
            tableName: core_user
            columnName: is_staff
        - dropColumn:
            tableName: metabase_database
            columnName: organization_id
        - dropColumn:
            tableName: report_card
            columnName: organization_id
        - dropColumn:
            tableName: report_dashboard
            columnName: organization_id
        - dropTable:
            tableName: annotation_annotation
        - dropTable:
            tableName: core_permissionsviolation
        - dropTable:
            tableName: core_userorgperm
        - dropTable:
            tableName: core_organization
        - dropTable:
            tableName: metabase_foreignkey
        - dropTable:
            tableName: metabase_tablesegment
        - dropTable:
            tableName: query_query
        - dropTable:
            tableName: report_dashboardsubscription
        - dropTable:
            tableName: report_emailreport_recipients
        - dropTable:
            tableName: report_emailreportexecutions
        - dropTable:
            tableName: report_emailreport
  - changeSet:
      id: 43
      author: camsaul
      validCheckSum:
        - 7:b20750a949504e93efced32877a4488f
        - 7:dbc18c8ca697fc335869f0ed0eb5f4cb
      changes:
        - createTable:
            tableName: permissions_revision
            remarks: 'Used to keep track of changes made to permissions.'
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: before
                  type: text
                  remarks: 'Serialized JSON of the permissions before the changes.'
                  constraints:
                    nullable: false
              - column:
                  name: after
                  type: text
                  remarks: 'Serialized JSON of the permissions after the changes.'
                  constraints:
                    nullable: false
              - column:
                  name: user_id
                  type: int
                  remarks: 'The ID of the admin who made this set of changes.'
                  constraints:
                    nullable: false
                    references: core_user(id)
                    foreignKeyName: fk_permissions_revision_user_id
              - column:
                  name: created_at
                  type: datetime
                  remarks: 'The timestamp of when these changes were made.'
                  constraints:
                    nullable: false
              - column:
                  name: remark
                  type: text
                  remarks: 'Optional remarks explaining why these changes were made.'
  - changeSet:
      id: 44
      author: camsaul
      changes:
        - dropColumn:
            tableName: report_card
            columnName: public_perms
        - dropColumn:
            tableName: report_dashboard
            columnName: public_perms
        - dropColumn:
            tableName: pulse
            columnName: public_perms
  - changeSet:
      id: 45
      author: tlrobinson
      changes:
        - addColumn:
            tableName: report_dashboardcard
            columns:
              - column:
                  name: visualization_settings
                  type: text
        - addNotNullConstraint:
            tableName: report_dashboardcard
            columnName: visualization_settings
            columnDataType: text
            defaultNullValue: '{}'
  - changeSet:
      id: 46
      author: camsaul
      objectQuotingStrategy: ${quote_strategy}
      changes:
        - addNotNullConstraint:
            tableName: report_dashboardcard
            columnName: row
            columnDataType: integer
            defaultNullValue: 0
        - addNotNullConstraint:
            tableName: report_dashboardcard
            columnName: col
            columnDataType: integer
            defaultNullValue: 0
        - addDefaultValue:
            tableName: report_dashboardcard
            columnName: row
            defaultValueNumeric: 0
        - addDefaultValue:
            tableName: report_dashboardcard
            columnName: col
            defaultValueNumeric: 0
  - changeSet:
      id: 47
      author: camsaul
      changes:
        ######################################## collection table ########################################
        - createTable:
            tableName: collection
            remarks: 'Collections are an optional way to organize Cards and handle permissions for them.'
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: name
                  type: text
                  remarks: 'The unique, user-facing name of this Collection.'
                  constraints:
                    nullable: false
              - column:
                  name: slug
                  type: varchar(254)
                  remarks: 'URL-friendly, sluggified, indexed version of name.'
                  constraints:
                    nullable: false
                    unique: true
              - column:
                  name: description
                  type: text
                  remarks: 'Optional description for this Collection.'
              - column:
                  name: color
                  type: char(7)
                  remarks: 'Seven-character hex color for this Collection, including the preceding hash sign.'
                  constraints:
                    nullable: false
              - column:
                  name: archived
                  type: boolean
                  remarks: 'Whether this Collection has been archived and should be hidden from users.'
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
        - createIndex:
            tableName: collection
            indexName: idx_collection_slug
            columns:
              column:
                name: slug
        ######################################## add collection_id to report_card ########################################
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: collection_id
                  type: int
                  remarks: 'Optional ID of Collection this Card belongs to.'
                  constraints:
                    references: collection(id)
                    foreignKeyName: fk_card_collection_id
        - createIndex:
            tableName: report_card
            indexName: idx_card_collection_id
            columns:
              column:
                name: collection_id
  - changeSet:
      id: 48
      author: camsaul
      changes:
        - createTable:
            tableName: collection_revision
            remarks: 'Used to keep track of changes made to collections.'
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: before
                  type: text
                  remarks: 'Serialized JSON of the collections graph before the changes.'
                  constraints:
                    nullable: false
              - column:
                  name: after
                  type: text
                  remarks: 'Serialized JSON of the collections graph after the changes.'
                  constraints:
                    nullable: false
              - column:
                  name: user_id
                  type: int
                  remarks: 'The ID of the admin who made this set of changes.'
                  constraints:
                    nullable: false
                    references: core_user(id)
                    foreignKeyName: fk_collection_revision_user_id
              - column:
                  name: created_at
                  type: datetime
                  remarks: 'The timestamp of when these changes were made.'
                  constraints:
                    nullable: false
              - column:
                  name: remark
                  type: text
                  remarks: 'Optional remarks explaining why these changes were made.'
  - changeSet:
      id: 49
      author: camsaul
      validCheckSum:
        - 8:56dcab086b21de1df002561efeac8bb6
        - 8:4508e7d5f6d4da3c4a2de3bf5e3c5851
      changes:
        ######################################## Card public_uuid & indices ########################################
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: public_uuid
                  type: char(36)
                  remarks: 'Unique UUID used to in publically-accessible links to this Card.'
                  constraints:
                    unique: true
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: made_public_by_id
                  type: int
                  remarks: 'The ID of the User who first publically shared this Card.'
                  constraints:
                    references: core_user(id)
                    foreignKeyName: fk_card_made_public_by_id
        - createIndex:
            tableName: report_card
            indexName: idx_card_public_uuid
            columns:
              column:
                name: public_uuid
        ######################################## Dashboard public_uuid & indices ########################################
        - addColumn:
            tableName: report_dashboard
            columns:
              - column:
                  name: public_uuid
                  type: char(36)
                  remarks: 'Unique UUID used to in publically-accessible links to this Dashboard.'
                  constraints:
                    unique: true
        - addColumn:
            tableName: report_dashboard
            columns:
              - column:
                  name: made_public_by_id
                  type: int
                  remarks: 'The ID of the User who first publically shared this Dashboard.'
                  constraints:
                    references: core_user(id)
                    foreignKeyName: fk_dashboard_made_public_by_id
        - createIndex:
            tableName: report_dashboard
            indexName: idx_dashboard_public_uuid
            columns:
              column:
                name: public_uuid
        ######################################## make query_queryexecution.executor_id nullable ########################################
        - dropNotNullConstraint:
            tableName: query_queryexecution
            columnName: executor_id
            columnDataType: int
  - changeSet:
      id: 50
      author: camsaul
      validCheckSum:
        - 8:388da4c48984aad647709514e4ba9204
        - 8:98a6ab6428ea7a589507464e34ade58a
      changes:
        ######################################## new Card columns ########################################
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: enable_embedding
                  type: boolean
                  remarks: 'Is this Card allowed to be embedded in different websites (using a signed JWT)?'
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: embedding_params
                  type: text
                  remarks: 'Serialized JSON containing information about required parameters that must be supplied when embedding this Card.'
          ######################################## new Card columns ########################################
        - addColumn:
            tableName: report_dashboard
            columns:
              - column:
                  name: enable_embedding
                  type: boolean
                  remarks: 'Is this Dashboard allowed to be embedded in different websites (using a signed JWT)?'
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
        - addColumn:
            tableName: report_dashboard
            columns:
              - column:
                  name: embedding_params
                  type: text
                  remarks: 'Serialized JSON containing information about required parameters that must be supplied when embedding this Dashboard.'
  - changeSet:
      id: 51
      author: camsaul
      validCheckSum:
        - 8:8491a72bd30aac2565c97daf8b84e515
        - 8:676d3f95358dcd572ccce47c950e8ed9
      changes:
        - createTable:
            tableName: query_execution
            remarks: 'A log of executed queries, used for calculating historic execution times, auditing, and other purposes.'
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: hash
                  type: binary(32)
                  remarks: 'The hash of the query dictionary. This is a 256-bit SHA3 hash of the query.'
                  constraints:
                    nullable: false
              - column:
                  name: started_at
                  type: datetime
                  remarks: 'Timestamp of when this query started running.'
                  constraints:
                    nullable: false
              - column:
                  name: running_time
                  type: integer
                  remarks: 'The time, in milliseconds, this query took to complete.'
                  constraints:
                    nullable: false
              - column:
                  name: result_rows
                  type: integer
                  remarks: 'Number of rows in the query results.'
                  constraints:
                    nullable: false
              - column:
                  name: native
                  type: boolean
                  remarks: 'Whether the query was a native query, as opposed to an MBQL one (e.g., created with the GUI).'
                  constraints:
                    nullable: false
              - column:
                  name: context
                  type: varchar(32)
                  remarks: 'Short string specifying how this query was executed, e.g. in a Dashboard or Pulse.'
              - column:
                  name: error
                  type: text
                  remarks: 'Error message returned by failed query, if any.'
              # The following columns are foreign keys, but we don't keep FK constraints on them for a few reasons:
              # - We don't want to keep indexes on these columns since they wouldn't be generally useful and for size and performance reasons
              # - If a related object (e.g. a Dashboard) is deleted, we don't want to delete the related entries in the QueryExecution log.
              #   We could do something like make the constraint ON DELETE SET NULL, but that would require a full table scan to handle;
              #   If the QueryExecution log became tens of millions of rows large it would take a very long time to scan and update records
              - column:
                  name: executor_id
                  type: integer
                  remarks: 'The ID of the User who triggered this query execution, if any.'
              - column:
                  name: card_id
                  type: integer
                  remarks: 'The ID of the Card (Question) associated with this query execution, if any.'
              - column:
                  name: dashboard_id
                  type: integer
                  remarks: 'The ID of the Dashboard associated with this query execution, if any.'
              - column:
                  name: pulse_id
                  type: integer
                  remarks: 'The ID of the Pulse associated with this query execution, if any.'
        # For things like auditing recently executed queries
        - createIndex:
            tableName: query_execution
            indexName: idx_query_execution_started_at
            columns:
              column:
                name: started_at
        # For things like seeing the 10 most recent executions of a certain query
        - createIndex:
            tableName: query_execution
            indexName: idx_query_execution_query_hash_started_at
            columns:
              - column:
                  name: hash
              - column:
                  name: started_at
  - property:
        name: blob.type
        value: blob
        dbms: mysql,h2,mariadb
  - property:
      name: blob.type
      value: bytea
      dbms: postgresql
  - changeSet:
      id: 52
      author: camsaul
      changes:
        - createTable:
            tableName: query_cache
            remarks: 'Cached results of queries are stored here when using the DB-based query cache.'
            columns:
              - column:
                  name: query_hash
                  type: binary(32)
                  remarks: 'The hash of the query dictionary. (This is a 256-bit SHA3 hash of the query dict).'
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: updated_at
                  type: datetime
                  remarks: 'The timestamp of when these query results were last refreshed.'
                  constraints:
                    nullable: false
              - column:
                  name: results
                  type: ${blob.type}
                  remarks: 'Cached, compressed results of running the query with the given hash.'
                  constraints:
                    nullable: false
        - createIndex:
            tableName: query_cache
            indexName: idx_query_cache_updated_at
            columns:
              column:
                name: updated_at
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: cache_ttl
                  type: int
                  remarks: 'The maximum time, in seconds, to return cached results for this Card rather than running a new query.'
  - changeSet:
      id: 53
      author: camsaul
      changes:
        - createTable:
            tableName: query
            remarks: 'Information (such as average execution time) for different queries that have been previously ran.'
            columns:
              - column:
                  name: query_hash
                  type: binary(32)
                  remarks: 'The hash of the query dictionary. (This is a 256-bit SHA3 hash of the query dict.)'
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: average_execution_time
                  type: int
                  remarks: 'Average execution time for the query, round to nearest number of milliseconds. This is updated as a rolling average.'
                  constraints:
                    nullable: false
  - changeSet:
      id: 54
      author: tlrobinson
      validCheckSum:
        - 7:695b12a78e897c62c21d41bfb04ab44b
        - 7:0857800db71a4757e7202aad4eaed48d
      changes:
        - addColumn:
            tableName: pulse
            columns:
              - column:
                  name: skip_if_empty
                  type: boolean
                  remarks: 'Skip a scheduled Pulse if none of its questions have any results'
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
  - changeSet:
      id: 55
      author: camsaul
      validCheckSum:
        - 8:87c4becde5fe208ba2c356128df86fba
        - 8:11bbd199bfa57b908ea3b1a470197de9
      changes:
        - addColumn:
            tableName: report_dashboard
            columns:
              - column:
                  name: archived
                  type: boolean
                  remarks: 'Is this Dashboard archived (effectively treated as deleted?)'
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
        - addColumn:
            tableName: report_dashboard
            columns:
              - column:
                  name: position
                  type: integer
                  remarks: 'The position this Dashboard should appear in the Dashboards list, lower-numbered positions appearing before higher numbered ones.'
        - createTable:
            tableName: dashboard_favorite
            remarks: 'Presence of a row here indicates a given User has favorited a given Dashboard.'
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: user_id
                  type: int
                  remarks: 'ID of the User who favorited the Dashboard.'
                  constraints:
                    nullable: false
                    references: core_user(id)
                    foreignKeyName: fk_dashboard_favorite_user_id
                    deleteCascade: true
              - column:
                  name: dashboard_id
                  type: int
                  remarks: 'ID of the Dashboard favorited by the User.'
                  constraints:
                    nullable: false
                    references: report_dashboard(id)
                    foreignKeyName: fk_dashboard_favorite_dashboard_id
                    deleteCascade: true
        - addUniqueConstraint:
            tableName: dashboard_favorite
            columnNames: user_id, dashboard_id
            constraintName: unique_dashboard_favorite_user_id_dashboard_id
        - createIndex:
            tableName: dashboard_favorite
            indexName: idx_dashboard_favorite_user_id
            columns:
              - column:
                  name: user_id
        - createIndex:
            tableName: dashboard_favorite
            indexName: idx_dashboard_favorite_dashboard_id
            columns:
              - column:
                  name: dashboard_id
  - changeSet:
      id: 56
      author: wwwiiilll
      comment: 'Added 0.25.0'
      changes:
        - addColumn:
            tableName: core_user
            columns:
              - column:
                  name: ldap_auth
                  type: boolean
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
  - changeSet:
      id: 57
      author: camsaul
      comment: 'Added 0.25.0'
      changes:
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: result_metadata
                  type: text
                  remarks: 'Serialized JSON containing metadata about the result columns from running the query.'
  - changeSet:
      id: 58
      author: senior
      comment: 'Added 0.25.0'
      changes:
        - createTable:
            tableName: dimension
            remarks: 'Stores references to alternate views of existing fields, such as remapping an integer to a description, like an enum'
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: field_id
                  type: int
                  remarks: 'ID of the field this dimension row applies to'
                  constraints:
                    deferrable: false
                    foreignKeyName: fk_dimension_ref_field_id
                    initiallyDeferred: false
                    nullable: false
                    references: metabase_field(id)
                    deleteCascade: true
              - column:
                  name: name
                  type: VARCHAR(254)
                  remarks: 'Short description used as the display name of this new column'
                  constraints:
                    nullable: false
              - column:
                  name: type
                  type: varchar(254)
                  remarks: 'Either internal for a user defined remapping or external for a foreign key based remapping'
                  constraints:
                    nullable: false
              - column:
                  name: human_readable_field_id
                  type: int
                  remarks: 'Only used with external type remappings. Indicates which field on the FK related table to use for display'
                  constraints:
                    deferrable: false
                    foreignKeyName: fk_dimension_displayfk_ref_field_id
                    initiallyDeferred: false
                    nullable: true
                    references: metabase_field(id)
                    deleteCascade: true
              - column:
                  name: created_at
                  type: DATETIME
                  remarks: 'The timestamp of when the dimension was created.'
                  constraints:
                    nullable: false
              - column:
                  name: updated_at
                  type: DATETIME
                  remarks: 'The timestamp of when these dimension was last updated.'
                  constraints:
                    nullable: false
        - addUniqueConstraint:
            tableName: dimension
            columnNames: field_id, name
            constraintName: unique_dimension_field_id_name
        - createIndex:
            tableName: dimension
            indexName: idx_dimension_field_id
            columns:
              - column:
                  name: field_id
  - changeSet:
      id: 59
      author: camsaul
      comment: 'Added 0.26.0'
      changes:
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: fingerprint
                  type: text
                  remarks: 'Serialized JSON containing non-identifying information about this Field, such as min, max, and percent JSON. Used for classification.'
  - changeSet:
      id: 60
      author: camsaul
      validCheckSum:
        - 8:4f997b2cd3309882e900493892381f38
        - 8:2141162a1c99a5dd95e5a67c5595e6d7
      comment: 'Added 0.26.0'
      changes:
        - addColumn:
            tableName: metabase_database
            columns:
              - column:
                  name: metadata_sync_schedule
                  type: varchar(254)
                  remarks: 'The cron schedule string for when this database should undergo the metadata sync process (and analysis for new fields).'
                  defaultValue: '0 50 * * * ? *' # run at the end of every hour
                  constraints:
                    nullable: false
        - addColumn:
            tableName: metabase_database
            columns:
              - column:
                  name: cache_field_values_schedule
                  type: varchar(254)
                  remarks: 'The cron schedule string for when FieldValues for eligible Fields should be updated.'
                  defaultValue: '0 50 0 * * ? *' # run at 12:50 AM
                  constraints:
                    nullable: false
  - changeSet:
      id: 61
      author: camsaul
      comment: 'Added 0.26.0'
      changes:
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: fingerprint_version
                  type: int
                  remarks: 'The version of the fingerprint for this Field. Used so we can keep track of which Fields need to be analyzed again when new things are added to fingerprints.'
                  defaultValue: 0
                  constraints:
                    nullable: false
  - changeSet:
      id: 62
      author: senior
      comment: 'Added 0.26.0'
      changes:
        - addColumn:
            tableName: metabase_database
            columns:
              - column:
                  name: timezone
                  type: VARCHAR(254)
                  remarks: 'Timezone identifier for the database, set by the sync process'
  - changeSet:
      id: 63
      author: camsaul
      comment: 'Added 0.26.0'
      changes:
        - addColumn:
            tableName: metabase_database
            columns:
              - column:
                  name: is_on_demand
                  type: boolean
                  remarks: 'Whether we should do On-Demand caching of FieldValues for this DB. This means FieldValues are updated when their Field is used in a Dashboard or Card param.'
                  defaultValue: false
                  constraints:
                    nullable: false
  - changeSet:
      id: 64
      author: senior
      comment: 'Added 0.26.0'
      changes:
      - dropForeignKeyConstraint:
          baseTableName: raw_table
          constraintName: fk_rawtable_ref_database
          remarks: 'This FK prevents deleting databases even though RAW_TABLE is no longer used. The table is still around to support downgrades, but the FK reference is no longer needed.'
# Changeset 65 was accidentally released in 0.26.0.RC2. The changeset has been removed from the migrations list so that
# users that haven't ran the migration (i.e. they didn't run 0.26.0.RC2) won't waste time running it just to have it
# reversed. For 0.26.0.RC2 users, the below changeset will remove those tables if they are present
  - changeSet:
      id: 66
      author: senior
      comment: 'Added 0.26.0'
      validCheckSum:
        - 7:e494c2c90fe5c377526da7a6e5ad63a2
        - 7:76d06b44a544105c2a613603b8bdf25f
      changes:
        - sql:
            sql: drop table if exists computation_job_result cascade
        - sql:
            sql: drop table if exists computation_job cascade
# NOTE Atte Keinänen 9/28/17: This was originally in changeset 65 as explained above
  - changeSet:
      id: 67
      author: attekei
      comment: 'Added 0.27.0'
      changes:
        - createTable:
            tableName: computation_job
            remarks: 'Stores submitted async computation jobs.'
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  constraints:
                    deferrable: false
                    foreignKeyName: fk_computation_job_ref_user_id
                    initiallyDeferred: false
                    references: core_user(id)
                  name: creator_id
                  type: int
              - column:
                  name: created_at
                  type: DATETIME
                  constraints:
                    nullable: false
              - column:
                  name: updated_at
                  type: DATETIME
                  constraints:
                    nullable: false
              - column:
                  name: type
                  type: varchar(254)
                  constraints:
                    nullable: false
              - column:
                  name: status
                  type: varchar(254)
                  constraints:
                    nullable: false
        - createTable:
            tableName: computation_job_result
            remarks: 'Stores results of async computation jobs.'
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  constraints:
                    deferrable: false
                    foreignKeyName: fk_computation_result_ref_job_id
                    initiallyDeferred: false
                    nullable: false
                    references: computation_job(id)
                  name: job_id
                  type: int
              - column:
                  name: created_at
                  type: DATETIME
                  constraints:
                    nullable: false
              - column:
                  name: updated_at
                  type: DATETIME
                  constraints:
                    nullable: false
              - column:
                  name: permanence
                  type: varchar(254)
                  constraints:
                    nullable: false
              - column:
                  name: payload
                  type: text
                  constraints:
                    nullable: false
  - changeSet:
      id: 68
      author: sbelak
      comment: 'Added 0.27.0'
      validCheckSum:
        - 8:ca201aeb20c1719a46c6bcc3fc95c81d
        - 8:b4ac06d133dfbdc6567d992c7e18c6ec
      changes:
        - addColumn:
            tableName: computation_job
            columns:
              - column:
                  name: context
                  type: text
        - addColumn:
            tableName: computation_job
            columns:
              - column:
                  name: ended_at
                  type: DATETIME
  - changeSet:
      id: 69
      author: senior
      validCheckSum:
        - 8:97b7768436b9e8d695bae984020d754c
        - 8:eadbe00e97eb53df4b3df60462f593f6
      comment: 'Added 0.27.0'
      remarks: 'Add columns to the pulse table for alerts'
      changes:
        - addColumn:
            tableName: pulse
            columns:
              - column:
                  name: alert_condition
                  type: varchar(254)
                  remarks: 'Condition (i.e. "rows" or "goal") used as a guard for alerts'
        - addColumn:
            tableName: pulse
            columns:
              - column:
                  name: alert_first_only
                  type: boolean
                  remarks: 'True if the alert should be disabled after the first notification'
        - addColumn:
            tableName: pulse
            columns:
              - column:
                  name: alert_above_goal
                  type: boolean
                  remarks: 'For a goal condition, alert when above the goal'
        # There is no name for an alert, so this column is only required for pulses
        - dropNotNullConstraint:
            tableName: pulse
            columnName: name
            columnDataType: varchar(254)
  - changeSet:
      id: 70
      author: camsaul
      comment: 'Added 0.28.0'
      changes:
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: database_type
                  type: varchar(255)
                  remarks: 'The actual type of this column in the database. e.g. VARCHAR or TEXT.'
        # We want to enforce NOT NULL right away for all columns going forward so just put some sort of
        # placeholder in place for existing columns.
        - addNotNullConstraint:
            tableName: metabase_field
            columnName: database_type
            columnDataType: varchar(255)
            defaultNullValue: '?'
  - changeSet:
      id: 71
      author: camsaul
      comment: 'Added 0.28.0'
      changes:
        # drop the NOT NULL constraint on DashboardCard.card_id since we're now letting you add things other than Cards
        # to Dashboards, for example static text cards
        - dropNotNullConstraint:
            tableName: report_dashboardcard
            columnName: card_id
            columnDataType: int
  - changeSet:
      id: 72
      author: senior
      validCheckSum:
        - 8:ed16046dfa04c139f48e9068eb4faee4
        - 8:4dc6debdf779ab9273cf2158a84bb154
      comment: 'Added 0.28.0'
      changes:
        - addColumn:
            tableName: pulse_card
            columns:
              - column:
                  name: include_csv
                  type: boolean
                  defaultValueBoolean: false
                  remarks: 'True if a CSV of the data should be included for this pulse card'
                  constraints:
                    nullable: false
        - addColumn:
            tableName: pulse_card
            columns:
              - column:
                  name: include_xls
                  type: boolean
                  defaultValueBoolean: false
                  remarks: 'True if a XLS of the data should be included for this pulse card'
                  constraints:
                    nullable: false
  - changeSet:
      id: 73
      author: camsaul
      comment: 'Added 0.29.0'
      changes:
        # add a new 'options' (serialized JSON) column to Database to store things like whether we should default to
        # making string searches case-insensitive
        - addColumn:
            tableName: metabase_database
            columns:
              - column:
                  name: options
                  type: text
                  remarks: 'Serialized JSON containing various options like QB behavior.'
  - changeSet:
      id: 74
      author: camsaul
      comment: 'Added 0.29.0'
      changes:
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: has_field_values
                  type: text
                  remarks: 'Whether we have FieldValues ("list"), should ad-hoc search ("search"), disable entirely ("none"), or infer dynamically (null)"'
  - changeSet:
      id: 75
      author: camsaul
      comment: 'Added 0.28.2'
      changes:
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: read_permissions
                  type: text
                  remarks: 'Permissions required to view this Card and run its query.'
  - changeSet:
      id: 76
      author: senior
      comment: 'Added 0.30.0'
      changes:
        - addColumn:
            tableName: metabase_table
            columns:
              - column:
                  name: fields_hash
                  type: text
                  remarks: 'Computed hash of all of the fields associated to this table'
  - changeSet:
      id: 77
      author: senior
      comment: 'Added 0.30.0'
      changes:
        - addColumn:
            tableName: core_user
            columns:
              - column:
                  name: login_attributes
                  type: text
                  remarks: 'JSON serialized map with attributes used for row level permissions'
  - changeSet:
      id: 78
      author: camsaul
      comment: 'Added 0.30.0'
      changes:
        - createTable:
            tableName: group_table_access_policy
            remarks: 'Records that a given Card (Question) should automatically replace a given Table as query source for a given a Perms Group.'
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: group_id
                  type: int
                  remarks: 'ID of the Permissions Group this policy affects.'
                  constraints:
                    nullable: false
                    references: permissions_group(id)
                    foreignKeyName: fk_gtap_group_id
                    deleteCascade: true
              - column:
                  name: table_id
                  type: int
                  remarks: 'ID of the Table that should get automatically replaced as query source for the Permissions Group.'
                  constraints:
                    nullable: false
                    references: metabase_table(id)
                    foreignKeyName: fk_gtap_table_id
                    deleteCascade: true
              - column:
                  name: card_id
                  type: int
                  remarks: 'ID of the Card (Question) to be used to replace the Table.'
                  constraints:
                    nullable: false
                    references: report_card(id)
                    foreignKeyName: fk_gtap_card_id
              - column:
                  name: attribute_remappings
                  type: text
                  remarks: 'JSON-encoded map of user attribute identifier to the param name used in the Card.'
              # TODO - do we also want to include `created_at` and `updated_at` columns here? We can add them later if needed
        # Add an index on table_id + group_id since that is what the Query Processor is going to be looking up 99% of
        # the time in order to get the corresponding Card ID for query-rewriting purposes
        #
        # TODO - do we want indexes on any of the other FKs? Are we going to be looking up all the GTAPs for a given
        # Table or for a given Group with enough regularity we would want to put indexes on those columns?
        - createIndex:
            indexName: idx_gtap_table_id_group_id
            tableName: group_table_access_policy
            columns:
              - column:
                  name: table_id
              - column:
                  name: group_id
        # There should only ever be one GTAP entry for a give Group + Table combination.
        - addUniqueConstraint:
            tableName: group_table_access_policy
            columnNames: table_id, group_id
            constraintName: unique_gtap_table_id_group_id
  - changeSet:
      id: 79
      author: camsaul
      comment: 'Added 0.30.0'
      changes:
        - addColumn:
            tableName: report_dashboard
            columns:
              - column:
                  name: collection_id
                  type: int
                  remarks: 'Optional ID of Collection this Dashboard belongs to.'
                  constraints:
                    references: collection(id)
                    foreignKeyName: fk_dashboard_collection_id
              # TODO - if someone deletes a collection, what should happen to the Dashboards that are in it? Should they
              # get deleted as well? Or should collection_id be cleared, effectively putting them in the so-called
              # "root" collection?
        - createIndex:
            tableName: report_dashboard
            indexName: idx_dashboard_collection_id
            columns:
              - column:
                  name: collection_id
        - addColumn:
            tableName: pulse
            columns:
              - column:
                  name: collection_id
                  type: int
                  remarks: 'Options ID of Collection this Pulse belongs to.'
                  constraints:
                    references: collection(id)
                    foreignKeyName: fk_pulse_collection_id
        - createIndex:
            tableName: pulse
            indexName: idx_pulse_collection_id
            columns:
              - column:
                  name: collection_id
  - changeSet:
      id: 80
      author: camsaul
      changes:
        - addColumn:
            tableName: collection
            columns:
              - column:
                  name: location
                  type: varchar(254)
                  remarks: 'Directory-structure path of ancestor Collections. e.g. "/1/2/" means our Parent is Collection 2, and their parent is Collection 1.'
                  constraints:
                    nullable: false
                  defaultValue: "/"
        - createIndex:
            tableName: collection
            indexName: idx_collection_location
            columns:
              - column:
                  name: location
  - changeSet:
      id: 81
      author: camsaul
      comment: 'Added 0.30.0'
      changes:
        - addColumn:
            tableName: report_dashboard
            columns:
              - column:
                  name: collection_position
                  type: smallint
                  remarks: 'Optional pinned position for this item in its Collection. NULL means item is not pinned.'
        - addColumn:
            tableName: report_card
            columns:
              - column:
                  name: collection_position
                  type: smallint
                  remarks: 'Optional pinned position for this item in its Collection. NULL means item is not pinned.'
        - addColumn:
            tableName: pulse
            columns:
              - column:
                  name: collection_position
                  type: smallint
                  remarks: 'Optional pinned position for this item in its Collection. NULL means item is not pinned.'
  - changeSet:
      id: 82
      author: senior
      comment: 'Added 0.30.0'
      changes:
        - addColumn:
            tableName: core_user
            columns:
              - column:
                  name: updated_at
                  type: datetime
                  remarks: 'When was this User last updated?'
        - sql:
            sql: update core_user set updated_at=date_joined
# Remove the GTAP card_id constraint. When not included, will default to querying against the GTAP table_id.
  - changeSet:
      id: 83
      author: senior
      comment: 'Added 0.30.0'
      changes:
        - dropNotNullConstraint:
            tableName: group_table_access_policy
            columnName: card_id
            columnDataType: int
# Switch the logic for metric/segment archiving to be more consistent with other entities in the model.
# Similarly, add the archived flag to pulses which doesn't have one.
  - changeSet:
      id: 84
      author: senior
      comment: 'Added 0.30.0'
      changes:
        - renameColumn:
            tableName: metric
            columnDataType: boolean
            newColumnName: archived
            oldColumnName: is_active
        - addDefaultValue:
            tableName: metric
            columnDataType: boolean
            columnName: archived
            defaultValueBoolean: false
        - renameColumn:
            tableName: segment
            columnDataType: boolean
            newColumnName: archived
            oldColumnName: is_active
        - addDefaultValue:
            tableName: segment
            columnDataType: boolean
            columnName: archived
            defaultValueBoolean: false
        - addColumn:
            tableName: pulse
            columns:
              - column:
                  name: archived
                  type: boolean
                  remarks: 'Has this pulse been archived?'
                  defaultValueBoolean: false
        # Before this change, metrics/segments had opposite logic, rather than marking something as archived
        # it was marked as active. Since the column is now an archived column, flip the boolean value
        #
        # As you may have noticed, we're not flipping the value for Metric here. @senior originally intended to do so,
        # but the YAML was off slightly. We have corrected this issue at a later date -- see migration #100
        - sql:
            sql: update segment set archived = not(archived)
  # Personal Collections, and removing Collection's unique constraint and index on slug
  - changeSet:
      id: 85
      author: camsaul
      comment: 'Added 0.30.0'
      changes:
        - addColumn:
            tableName: collection
            columns:
              - column:
                  name: personal_owner_id
                  type: int
                  remarks: 'If set, this Collection is a personal Collection, for exclusive use of the User with this ID.'
                  constraints:
                    references: core_user(id)
                    foreignKeyName: fk_collection_personal_owner_id
                    unique: true
                    uniqueConstraintName: unique_collection_personal_owner_id
                    deleteCascade: true
        # Needed so we can efficiently look up the Collection belonging to a User, and so we can efficiently enforce the
        # unique constraint
        - createIndex:
            tableName: collection
            indexName: idx_collection_personal_owner_id
            columns:
              - column:
                  name: personal_owner_id
        # We're no longer enforcing unique constraints on Collection slugs or using them directly in the URLs, so let's
        # go ahead and remove stuff related to that...
        #
        # It's easier to just copy the value of slug to a new column and drop the old one than to try to deduce what the
        # unique constraint is named locally across all of our different DBMSes
        # (For example see https://stackoverflow.com/questions/10008476/dropping-unique-constraint-for-column-in-h2)
        #
        # Here's the plan: add new column _slug; copy values of slug into _slug; remove slug; rename _slug to slug
        - addColumn:
            tableName: collection
            columns:
              - column:
                  name: _slug
                  type: varchar(254)
                  remarks: 'Sluggified version of the Collection name. Used only for display purposes in URL; not unique or indexed.'
        # I don't know of an easy way to copy existing values of slug to _slug with Liquibase as we create the column so
        # just have to do it this way instead
        - sql:
            sql: UPDATE collection SET _slug = slug
        - addNotNullConstraint:
            tableName: collection
            columnName: _slug
            columnDataType: varchar(254)
        - dropColumn:
            tableName: collection
            columnName: slug
        - renameColumn:
            tableName: collection
            oldColumnName: _slug
            newColumnName: slug
            columnDataType: varchar(254)
        # Let's try to make sure the comments on the name column of Collection actually reflect reality
        - sql:
            dbms: postgresql,h2
            sql: "COMMENT ON COLUMN collection.name IS 'The user-facing name of this Collection.'"
        - sql:
            dbms: mysql,mariadb
            sql: "ALTER TABLE `collection` CHANGE `name` `name` TEXT NOT NULL COMMENT 'The user-facing name of this Collection.'"

# In 0.30.0 we finally removed the long-deprecated native read permissions. Since they're no longer considered valid by
# our permissions code, remove any entries for them so they don't cause problems.
  - changeSet:
      id: 86
      author: camsaul
      comment: 'Added 0.30.0'
      changes:
        - sql:
            sql: DELETE FROM permissions WHERE object LIKE '%/native/read/'

# Time to finally get rid of the RawTable and RawColumn tables. Bye Felicia!
  - changeSet:
      id: 87
      author: camsaul
      comment: 'Added 0.30.0'
      changes:
        - dropTable:
            tableName: raw_column
        - dropTable:
            tableName: raw_table
  - changeSet:
      id: 88
      author: senior
      comment: 'Added 0.30.0'
      changes:
        - addColumn:
            tableName: core_user
            columns:
              - column:
                  name: saml_auth
                  type: boolean
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
                  remarks: 'Boolean to indicate if this user is authenticated via SAML'

# The Quartz Task Scheduler can use a DB to 'cluster' tasks and make sure they are only ran by a single instance where
# using a multi-instance Metabase setup.

  - changeSet:
      id: 89
      author: camsaul
      comment: 'Added 0.30.0'
      changes:
        - createTable:
            tableName: QRTZ_JOB_DETAILS
            remarks: 'Used for Quartz scheduler.'
            columns:
              - column:
                  name: SCHED_NAME
                  type: varchar(120)
                  constraints:
                    nullable: false
              - column:
                  name: JOB_NAME
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: JOB_GROUP
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: DESCRIPTION
                  type: varchar(250)
              - column:
                  name: JOB_CLASS_NAME
                  type: varchar(250)
                  constraints:
                    nullable: false
              - column:
                  name: IS_DURABLE
                  type: bool
                  constraints:
                    nullable: false
              - column:
                  name: IS_NONCONCURRENT
                  type: bool
                  constraints:
                    nullable: false
              - column:
                  name: IS_UPDATE_DATA
                  type: bool
                  constraints:
                    nullable: false
              - column:
                  name: REQUESTS_RECOVERY
                  type: bool
                  constraints:
                    nullable: false
              - column:
                  name: JOB_DATA
                  type: ${blob.type}
        - addPrimaryKey:
            tableName: QRTZ_JOB_DETAILS
            columnNames: SCHED_NAME, JOB_NAME, JOB_GROUP
            constraintName: PK_QRTZ_JOB_DETAILS
        - createTable:
            tableName: QRTZ_TRIGGERS
            remarks: 'Used for Quartz scheduler.'
            columns:
              - column:
                  name: SCHED_NAME
                  type: varchar(120)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_NAME
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_GROUP
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: JOB_NAME
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: JOB_GROUP
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: DESCRIPTION
                  type: varchar(250)
              - column:
                  name: NEXT_FIRE_TIME
                  type: bigint
              - column:
                  name: PREV_FIRE_TIME
                  type: bigint
              - column:
                  name: PRIORITY
                  type: integer
              - column:
                  name: TRIGGER_STATE
                  type: varchar(16)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_TYPE
                  type: varchar(8)
                  constraints:
                    nullable: false
              - column:
                  name: START_TIME
                  type: bigint
                  constraints:
                    nullable: false
              - column:
                  name: END_TIME
                  type: bigint
              - column:
                  name: CALENDAR_NAME
                  type: varchar(200)
              - column:
                  name: MISFIRE_INSTR
                  type: smallint
              - column:
                  name: JOB_DATA
                  type: ${blob.type}
        - addPrimaryKey:
            tableName: QRTZ_TRIGGERS
            columnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            constraintName: PK_QRTZ_TRIGGERS
        - addForeignKeyConstraint:
            baseTableName: QRTZ_TRIGGERS
            baseColumnNames: SCHED_NAME, JOB_NAME, JOB_GROUP
            referencedTableName: QRTZ_JOB_DETAILS
            referencedColumnNames: SCHED_NAME, JOB_NAME, JOB_GROUP
            constraintName: FK_QRTZ_TRIGGERS_JOB_DETAILS
        - createTable:
            tableName: QRTZ_SIMPLE_TRIGGERS
            remarks: 'Used for Quartz scheduler.'
            columns:
              - column:
                  name: SCHED_NAME
                  type: varchar(120)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_NAME
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_GROUP
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: REPEAT_COUNT
                  type: bigint
                  constraints:
                    nullable: false
              - column:
                  name: REPEAT_INTERVAL
                  type: bigint
                  constraints:
                    nullable: false
              - column:
                  name: TIMES_TRIGGERED
                  type: bigint
                  constraints:
                    nullable: false
        - addPrimaryKey:
            tableName: QRTZ_SIMPLE_TRIGGERS
            columnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            constraintName: PK_QRTZ_SIMPLE_TRIGGERS
        - addForeignKeyConstraint:
            baseTableName: QRTZ_SIMPLE_TRIGGERS
            baseColumnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            referencedTableName: QRTZ_TRIGGERS
            referencedColumnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            constraintName: FK_QRTZ_SIMPLE_TRIGGERS_TRIGGERS
        - createTable:
            tableName: QRTZ_CRON_TRIGGERS
            remarks: 'Used for Quartz scheduler.'
            columns:
              - column:
                  name: SCHED_NAME
                  type: varchar(120)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_NAME
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_GROUP
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: CRON_EXPRESSION
                  type: varchar(120)
                  constraints:
                    nullable: false
              - column:
                  name: TIME_ZONE_ID
                  type: varchar(80)
        - addPrimaryKey:
            tableName: QRTZ_CRON_TRIGGERS
            columnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            constraintName: PK_QRTZ_CRON_TRIGGERS
        - addForeignKeyConstraint:
            baseTableName: QRTZ_CRON_TRIGGERS
            baseColumnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            referencedTableName: QRTZ_TRIGGERS
            referencedColumnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            constraintName: FK_QRTZ_CRON_TRIGGERS_TRIGGERS
        - createTable:
            tableName: QRTZ_SIMPROP_TRIGGERS
            remarks: 'Used for Quartz scheduler.'
            columns:
              - column:
                  name: SCHED_NAME
                  type: varchar(120)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_NAME
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_GROUP
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: STR_PROP_1
                  type: varchar(512)
              - column:
                  name: STR_PROP_2
                  type: varchar(512)
              - column:
                  name: STR_PROP_3
                  type: varchar(512)
              - column:
                  name: INT_PROP_1
                  type: int
              - column:
                  name: INT_PROP_2
                  type: int
              - column:
                  name: LONG_PROP_1
                  type: bigint
              - column:
                  name: LONG_PROP_2
                  type: bigint
              - column:
                  name: DEC_PROP_1
                  type: numeric(13,4)
              - column:
                  name: DEC_PROP_2
                  type: numeric(13,4)
              - column:
                  name: BOOL_PROP_1
                  type: bool
              - column:
                  name: BOOL_PROP_2
                  type: bool
        - addPrimaryKey:
            tableName: QRTZ_SIMPROP_TRIGGERS
            columnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            constraintName: PK_QRTZ_SIMPROP_TRIGGERS
        - addForeignKeyConstraint:
            baseTableName: QRTZ_SIMPROP_TRIGGERS
            baseColumnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            referencedTableName: QRTZ_TRIGGERS
            referencedColumnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            constraintName: FK_QRTZ_SIMPROP_TRIGGERS_TRIGGERS
        - createTable:
            tableName: QRTZ_BLOB_TRIGGERS
            remarks: 'Used for Quartz scheduler.'
            columns:
              - column:
                  name: SCHED_NAME
                  type: varchar(120)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_NAME
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_GROUP
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: BLOB_DATA
                  type: ${blob.type}
        - addPrimaryKey:
            tableName: QRTZ_BLOB_TRIGGERS
            columnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            constraintName: PK_QRTZ_BLOB_TRIGGERS
        - addForeignKeyConstraint:
            baseTableName: QRTZ_BLOB_TRIGGERS
            baseColumnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            referencedTableName: QRTZ_TRIGGERS
            referencedColumnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
            constraintName: FK_QRTZ_BLOB_TRIGGERS_TRIGGERS
        - createTable:
            tableName: QRTZ_CALENDARS
            remarks: 'Used for Quartz scheduler.'
            columns:
              - column:
                  name: SCHED_NAME
                  type: varchar(120)
                  constraints:
                    nullable: false
              - column:
                  name: CALENDAR_NAME
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: CALENDAR
                  type: ${blob.type}
                  constraints:
                    nullable: false
        - addPrimaryKey:
            tableName: QRTZ_CALENDARS
            columnNames: SCHED_NAME, CALENDAR_NAME
            constraintName: PK_QRTZ_CALENDARS
        - createTable:
            tableName: QRTZ_PAUSED_TRIGGER_GRPS
            remarks: 'Used for Quartz scheduler.'
            columns:
              - column:
                  name: SCHED_NAME
                  type: varchar(120)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_GROUP
                  type: varchar(200)
                  constraints:
                    nullable: false
        - addPrimaryKey:
            tableName: QRTZ_PAUSED_TRIGGER_GRPS
            columnNames: SCHED_NAME, TRIGGER_GROUP
            constraintName: PK_SCHED_NAME
        - createTable:
            tableName: QRTZ_FIRED_TRIGGERS
            remarks: 'Used for Quartz scheduler.'
            columns:
              - column:
                  name: SCHED_NAME
                  type: varchar(120)
                  constraints:
                    nullable: false
              - column:
                  name: ENTRY_ID
                  type: varchar(95)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_NAME
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: TRIGGER_GROUP
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: INSTANCE_NAME
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: FIRED_TIME
                  type: bigint
                  constraints:
                    nullable: false
# Note: this column is not used on Quartz 2.1.x; it is used in 2.2.x, which recommends making it NOT NULL. I've made it
# nullable since at the time of this migration we're still using 2.1.7; including it gives us an easy upgrade path in
# the future.
              - column:
                  name: SCHED_TIME
                  type: bigint
              - column:
                  name: PRIORITY
                  type: integer
                  constraints:
                    nullable: false
              - column:
                  name: STATE
                  type: varchar(16)
                  constraints:
                    nullable: false
              - column:
                  name: JOB_NAME
                  type: varchar(200)
              - column:
                  name: JOB_GROUP
                  type: varchar(200)
              - column:
                  name: IS_NONCONCURRENT
                  type: bool
              - column:
                  name: REQUESTS_RECOVERY
                  type: bool
        - addPrimaryKey:
            tableName: QRTZ_FIRED_TRIGGERS
            columnNames: SCHED_NAME, ENTRY_ID
            constraintName: PK_QRTZ_FIRED_TRIGGERS
        - createTable:
            tableName: QRTZ_SCHEDULER_STATE
            remarks: 'Used for Quartz scheduler.'
            columns:
              - column:
                  name: SCHED_NAME
                  type: varchar(120)
                  constraints:
                    nullable: false
              - column:
                  name: INSTANCE_NAME
                  type: varchar(200)
                  constraints:
                    nullable: false
              - column:
                  name: LAST_CHECKIN_TIME
                  type: bigint
                  constraints:
                    nullable: false
              - column:
                  name: CHECKIN_INTERVAL
                  type: bigint
                  constraints:
                    nullable: false
        - addPrimaryKey:
            tableName: QRTZ_SCHEDULER_STATE
            columnNames: SCHED_NAME, INSTANCE_NAME
            constraintName: PK_QRTZ_SCHEDULER_STATE
        - createTable:
            tableName: QRTZ_LOCKS
            remarks: 'Used for Quartz scheduler.'
            columns:
              - column:
                  name: SCHED_NAME
                  type: varchar(120)
                  constraints:
                    nullable: false
              - column:
                  name: LOCK_NAME
                  type: varchar(40)
                  constraints:
                    nullable: false
        - addPrimaryKey:
            tableName: QRTZ_LOCKS
            columnNames: SCHED_NAME, LOCK_NAME
            constraintName: PK_QRTZ_LOCKS
        - createIndex:
            indexName: IDX_QRTZ_J_REQ_RECOVERY
            tableName: QRTZ_JOB_DETAILS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: REQUESTS_RECOVERY
        - createIndex:
            indexName: IDX_QRTZ_J_GRP
            tableName: QRTZ_JOB_DETAILS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: JOB_GROUP
        - createIndex:
            indexName: IDX_QRTZ_T_J
            tableName: QRTZ_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: JOB_NAME
              - column:
                  name: JOB_GROUP
        - createIndex:
            indexName: IDX_QRTZ_T_JG
            tableName: QRTZ_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: JOB_GROUP
        - createIndex:
            indexName: IDX_QRTZ_T_C
            tableName: QRTZ_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: CALENDAR_NAME
        - createIndex:
            indexName: IDX_QRTZ_T_G
            tableName: QRTZ_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: TRIGGER_GROUP
        - createIndex:
            indexName: IDX_QRTZ_T_STATE
            tableName: QRTZ_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: TRIGGER_STATE
        - createIndex:
            indexName: IDX_QRTZ_T_N_STATE
            tableName: QRTZ_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: TRIGGER_NAME
              - column:
                  name: TRIGGER_GROUP
              - column:
                  name: TRIGGER_STATE
        - createIndex:
            indexName: IDX_QRTZ_T_N_G_STATE
            tableName: QRTZ_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: TRIGGER_GROUP
              - column:
                  name: TRIGGER_STATE
        - createIndex:
            indexName: IDX_QRTZ_T_NEXT_FIRE_TIME
            tableName: QRTZ_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: NEXT_FIRE_TIME
        - createIndex:
            indexName: IDX_QRTZ_T_NFT_ST
            tableName: QRTZ_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: TRIGGER_STATE
              - column:
                  name: NEXT_FIRE_TIME
        - createIndex:
            indexName: IDX_QRTZ_T_NFT_MISFIRE
            tableName: QRTZ_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: MISFIRE_INSTR
              - column:
                  name: NEXT_FIRE_TIME
        - createIndex:
            indexName: IDX_QRTZ_T_NFT_ST_MISFIRE
            tableName: QRTZ_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: MISFIRE_INSTR
              - column:
                  name: NEXT_FIRE_TIME
              - column:
                  name: TRIGGER_STATE
        - createIndex:
            indexName: IDX_QRTZ_T_NFT_ST_MISFIRE_GRP
            tableName: QRTZ_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: MISFIRE_INSTR
              - column:
                  name: NEXT_FIRE_TIME
              - column:
                  name: TRIGGER_GROUP
              - column:
                  name: TRIGGER_STATE
        - createIndex:
            indexName: IDX_QRTZ_FT_TRIG_INST_NAME
            tableName: QRTZ_FIRED_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: INSTANCE_NAME
        - createIndex:
            indexName: IDX_QRTZ_FT_INST_JOB_REQ_RCVRY
            tableName: QRTZ_FIRED_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: INSTANCE_NAME
              - column:
                  name: REQUESTS_RECOVERY
        - createIndex:
            indexName: IDX_QRTZ_FT_J_G
            tableName: QRTZ_FIRED_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: JOB_NAME
              - column:
                  name: JOB_GROUP
        - createIndex:
            indexName: IDX_QRTZ_FT_JG
            tableName: QRTZ_FIRED_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: JOB_GROUP
        - createIndex:
            indexName: IDX_QRTZ_FT_T_G
            tableName: QRTZ_FIRED_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: TRIGGER_NAME
              - column:
                  name: TRIGGER_GROUP
        - createIndex:
            indexName: IDX_QRTZ_FT_TG
            tableName: QRTZ_FIRED_TRIGGERS
            columns:
              - column:
                  name: SCHED_NAME
              - column:
                  name: TRIGGER_GROUP

  - changeSet:
      id: 90
      author: senior
      comment: 'Added 0.30.0'
      changes:
        - addColumn:
            tableName: core_user
            columns:
              - column:
                  name: sso_source
                  type: varchar(254)
                  remarks: 'String to indicate the SSO backend the user is from'
        - sql:
            sql: update core_user set sso_source='saml' where saml_auth=true
        - dropColumn:
            tableName: core_user
            columnName: saml_auth

# Forgot to get rid of the raw_table_id and raw_column_id columns when we dropped the tables they referenced in migration 87.

  - changeSet:
      id: 91
      author: camsaul
      comment: 'Added 0.30.0'
      changes:
        - dropColumn:
            tableName: metabase_table
            columnName: raw_table_id
        - dropColumn:
            tableName: metabase_field
            columnName: raw_column_id

# Add database_id column to query_execution

  - changeSet:
      id: 92
      author: camsaul
      comment: 'Added 0.31.0'
      validCheckSum:
        - 8:a875945f36824a0667c740888c00c37f
        - 8:83ded48e18fe8f70d6ec09add042124d
        - 8:1e5bc2d66778316ea640a561862c23b4
      changes:
        - addColumn:
            tableName: query_execution
            columns:
              - column:
                  name: database_id
                  type: integer
                  remarks: 'ID of the database this query was ran against.'

# Start recording the actual query dictionary that's been executed

  - changeSet:
      id: 93
      author: camsaul
      comment: 'Added 0.31.0'
      changes:
        - addColumn:
            tableName: query
            columns:
              - column:
                  name: query
                  type: text
                  remarks: 'The actual "query dictionary" for this query.'

# Create the TaskHistory table, intended to provide debugging info on our background/quartz processes
  - changeSet:
      id: 94
      author: senior
      comment: 'Added 0.31.0'
      changes:
        - createTable:
            tableName: task_history
            remarks: 'Timing and metadata info about background/quartz processes'
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: task
                  type: VARCHAR(254)
                  remarks: 'Name of the task'
                  constraints:
                    nullable: false
              # The sync tasks all have a db_id, but there are others that won't, such as the pulses
              # task or task history cleanup. The way around this is to create a join table between
              # TASK_HISTORY and METABASE_DATABASE, but that doesn't seem worth it right now.
              - column:
                  name: db_id
                  type: integer
              - column:
                  name: started_at
                  type: datetime
                  constraints:
                    nullable: false
              - column:
                  name: ended_at
                  type: datetime
                  constraints:
                    nullable: false
              - column:
                  name: duration
                  type: int
                  constraints:
                    nullable: false
              - column:
                  name: task_details
                  remarks: 'JSON string with additional info on the task'
                  type: text
        - createIndex:
            indexName: idx_task_history_end_time
            tableName: task_history
            columns:
              - column:
                  name: ended_at
        - createIndex:
            indexName: idx_task_history_db_id
            tableName: task_history
            columns:
              - column:
                  name: db_id
# Before this changeset, the databasechangelog table didn't include any uniqueness constraing for the databasechangelog
# table. Not having anything that uniquely identifies a row can cause issues for database replication. In earlier
# versions of Liquibase the uniquenes constraint was (ID, AUTHOR, FILENAME) but that was dropped
# (https://liquibase.jira.com/browse/CORE-1909) as some as the combination of the three columns caused issues on some
# databases. We only support PostgreSQL, MySQL and H2 which doesn't have that issue. This changeset puts back that
# uniqueness constraint since the issue shouldn't affect us and it will allow replication without the user needed to
# add their own constraint.
  - changeSet:
      id: 95
      author: senior
      comment: 'Added 0.31.0'
      # Don't add the constraint if there are already duplicates in the database change log! Migrations will fail!
      # See #8909
      preConditions:
        - onFail: MARK_RAN
        # If we're dumping the migration as a SQL file or trying to force-migrate we can't check the preconditions
        # so just go ahead and skip the entire thing. This is a non-critical migration
        - onUpdateSQL: IGNORE
        - sqlCheck:
            expectedResult: 0
            sql: SELECT count(*) FROM (SELECT count(*) FROM DATABASECHANGELOG GROUP BY ID, AUTHOR, FILENAME HAVING count(*) > 1) t1
      changes:
        - addUniqueConstraint:
            columnNames: id, author, filename
            constraintName: idx_databasechangelog_id_author_filename
            tableName: DATABASECHANGELOG
#
# ADD Field.settings COLUMN
#
  - changeSet:
      id: 96
      author: camsaul
      comment: 'Added 0.31.0'
      changes:
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: settings
                  type: text
                  remarks: 'Serialized JSON FE-specific settings like formatting, etc. Scope of what is stored here may increase in future.'
#
# Change MySQL/Maria's blob type to LONGBLOB to more closely match what H2 and PostgreSQL support for size limits
#
  - changeSet:
      id: 97
      author: senior
      comment: 'Added 0.32.0'
      preConditions:
        - onFail: MARK_RAN
        - dbms: mysql, mariadb
      changes:
        - modifyDataType:
            tableName: query_cache
            columnName: results
            newDataType: longblob

#
# Add unique constraints for (Field name + table_id + parent_id) and for (Table name + schema + db_id) unless for one
# reason or another those would-be constraints are already violated. This is to fix issue where sometimes the same Field
# or Table is synced more than once (see #669, #8950, #9048)
#
# Note that the SQL standard says unique constraints should not apply to columns with NULL values. Consider the following:
#
# INSERT INTO metabase_table (db_id, schema, name) VALUES (1, 'PUBLIC', 'my_table');
# INSERT INTO metabase_table (db_id, schema, name) VALUES (1, 'PUBLIC', 'my_table'); -- fails: violates UNIQUE constraint
#
# INSERT INTO metabase_table (db_id, schema, name) VALUES (1, NULL, 'my_table');
# INSERT INTO metabase_table (db_id, schema, name) VALUES (1, NULL, 'my_table'); -- succeeds: because schema is NULL constraint does not apply
#
# Thus these constraints won't work if the data warehouse DB in question doesn't use schemas (e.g. MySQL or MongoDB). It
# will work for other data warehouse types.
#
# Luckily Postgres (but not H2 or MySQL) supports constraints that only apply to columns matching conditions, so we can
# add additional constraints to properly handle those cases.
  - changeSet:
      id: 98
      author: camsaul
      comment: 'Added 0.32.0'
      preConditions:
        - onFail: MARK_RAN
        - onUpdateSQL: IGNORE
        - or:
            - and:
                - dbms:
                    type: mysql,mariadb
                - sqlCheck:
                    expectedResult: 0
                    sql: SELECT count(*) FROM (SELECT count(*) FROM `metabase_table` GROUP BY `db_id`, `schema`, `name` HAVING count(*) > 1) t1
            - and:
                - dbms:
                    type: h2,postgresql
                - sqlCheck:
                    expectedResult: 0
                    sql: SELECT count(*) FROM (SELECT count(*) FROM METABASE_TABLE GROUP BY DB_ID, SCHEMA, NAME HAVING count(*) > 1) t1
      changes:
        - addUniqueConstraint:
            tableName: metabase_table
            columnNames: db_id, schema, name
            constraintName: idx_uniq_table_db_id_schema_name
        # For Postgres, add additional constraint to apply if schema is NULL
        - sql:
            dbms: postgresql
            sql: CREATE UNIQUE INDEX idx_uniq_table_db_id_schema_name_2col ON "metabase_table" ("db_id", "name") WHERE "schema" IS NULL

  - changeSet:
      id: 99
      author: camsaul
      comment: 'Added 0.32.0'
      preConditions:
        - onFail: MARK_RAN
        - onUpdateSQL: IGNORE
        - or:
            - and:
                - dbms:
                    type: mysql,mariadb
                - sqlCheck:
                    expectedResult: 0
                    sql: SELECT count(*) FROM (SELECT count(*) FROM `metabase_field` GROUP BY `table_id`, `parent_id`, `name` HAVING count(*) > 1) t1
            - and:
                - dbms:
                    type: h2,postgresql
                - sqlCheck:
                    expectedResult: 0
                    sql: SELECT count(*) FROM (SELECT count(*) FROM METABASE_FIELD GROUP BY TABLE_ID, PARENT_ID, NAME HAVING count(*) > 1) t1
      changes:
        - addUniqueConstraint:
            tableName: metabase_field
            columnNames: table_id, parent_id, name
            constraintName: idx_uniq_field_table_id_parent_id_name
        # For Postgres, add additional constraint to apply if schema is NULL
        - sql:
            dbms: postgresql
            sql: CREATE UNIQUE INDEX idx_uniq_field_table_id_parent_id_name_2col ON "metabase_field" ("table_id", "name") WHERE "parent_id" IS NULL

#
# Migration 84 was written slightly incorrectly and did not correctly migrate the values of is_active -> archived for
# METRICS. If you look at the migration you will notice the raw SQL part is a `sql` map with 2 `sql` keys. The first key
# is ignored, and that statement was never ran.
#
# To fix this we will migrate any metrics that haven't been updated since that migration ran and fix their archived
# status
  - changeSet:
      id: 100
      author: camsaul
      comment: 'Added 0.32.0'
      preConditions:
        - onFail: MARK_RAN
        - onUpdateSQL: RUN
        - tableExists:
            tableName: databasechangelog
      changes:
        - sql:
            sql: >-
              UPDATE metric
              SET archived = NOT archived
              WHERE EXISTS (
                SELECT *
                FROM databasechangelog dbcl
                WHERE dbcl.id = '84'
                  AND metric.updated_at < dbcl.dateexecuted
              )

# Very helpful for performance reasons. See #9519
  - changeSet:
      id: 101
      author: camsaul
      comment: 'Added 0.32.0'
      changes:
        - createIndex:
            indexName: idx_field_parent_id
            tableName: metabase_field
            columns:
              - column:
                  name: parent_id

# A per-Database setting for the new Query Builder 3.0.
  - changeSet:
      id: 103
      author: camsaul
      comment: 'Added 0.32.10'
      changes:
        - addColumn:
            tableName: metabase_database
            columns:
              - column:
                  name: auto_run_queries
                  remarks: 'Whether to automatically run queries when doing simple filtering and summarizing in the Query Builder.'
                  type: boolean
                  constraints:
                    nullable: false
                  defaultValueBoolean: true


  # To fix EE full-app embedding without compromising security. Full-app embed sessions cannot have `SameSite` attributes in their cookies.
  - changeSet:
      id: 104
      author: camsaul
      comment: 'Added EE 1.1.6/CE 0.33.0'
      changes:
        - addColumn:
            tableName: core_session
            columns:
              - column:
                  name: anti_csrf_token
                  type: text
                  remarks: 'Anti-CSRF token for full-app embed sessions.'

#
# Change `metabase_field.database_type` to `text` to accomodate more exotic field types (enums in Clickhouse, rows in Presto, ...)
#
  - changeSet:
      id: 106
      author: sb
      comment: 'Added 0.33.5'
      changes:
        - modifyDataType:
            tableName: metabase_field
            columnName: database_type
            newDataType: text

#
#  Migrations 107-160 are used to convert a MySQL or MariaDB database to utf8mb4 on launch -- see #11753 for a detailed explanation of these migrations
#

  - changeSet:
        id: 107
        author: camsaul
        comment: Added 0.34.2
        # If this migration fails for any reason continue with the next migration; do not fail the entire process if this one fails
        failOnError: false
        preConditions:
          # If preconditions fail (i.e., dbms is not mysql or mariadb) then mark this migration as 'ran'
          - onFail: MARK_RAN
          # If we're generating SQL output for migrations instead of running via liquibase, fail the preconditions which means these migrations will be skipped
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER DATABASE CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
  - changeSet:
        id: 108
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `DATABASECHANGELOG` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 109
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `DATABASECHANGELOGLOCK` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 110
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `QRTZ_CALENDARS` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 111
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `QRTZ_FIRED_TRIGGERS` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 112
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `QRTZ_JOB_DETAILS` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 113
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `QRTZ_LOCKS` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 114
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `QRTZ_PAUSED_TRIGGER_GRPS` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 115
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `QRTZ_SCHEDULER_STATE` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 116
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `core_user` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 117
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `data_migrations` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 118
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `dependency` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 119
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `label` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 120
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `metabase_database` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 121
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `permissions_group` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 122
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `query` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 123
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `query_cache` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 124
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `query_execution` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 125
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `setting` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 126
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `task_history` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 127
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `QRTZ_TRIGGERS` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 128
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `activity` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 129
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `collection` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 130
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `collection_revision` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 131
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `computation_job` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 132
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `core_session` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 133
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `metabase_table` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 134
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `permissions` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 135
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `permissions_revision` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 136
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `revision` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 137
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `view_log` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 138
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `QRTZ_BLOB_TRIGGERS` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 139
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `QRTZ_CRON_TRIGGERS` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 140
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `QRTZ_SIMPLE_TRIGGERS` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 141
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `QRTZ_SIMPROP_TRIGGERS` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 142
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `computation_job_result` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 143
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `metabase_field` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 144
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `permissions_group_membership` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 145
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `pulse` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 146
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `report_dashboard` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 147
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `dashboard_favorite` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 148
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `dimension` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 149
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `metabase_fieldvalues` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 150
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `metric` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 151
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `pulse_channel` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 152
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `segment` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 153
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `pulse_channel_recipient` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 154
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `report_card` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 155
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `metric_important_field` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 156
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `report_cardfavorite` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 157
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `card_label` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 158
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `pulse_card` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 159
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `report_dashboardcard` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  - changeSet:
        id: 160
        author: camsaul
        comment: Added 0.34.2
        failOnError: false
        preConditions:
          - onFail: MARK_RAN
          - onSqlOutput: FAIL
          - or:
              - dbms:
                    type: mysql
              - dbms:
                    type: mariadb
        changes:
          - sql:
                sql: ALTER TABLE `dashboardcard_series` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

# [161 has been removed. Superceded by 166]

# Drop the old query_queryexecution table if present. This was replaced by query_execution in 0.23.0. This was
# formerly a data migration but was converted to a Liquibase migration so people running migrations manually will
# still have the Table dropped.

  - changeSet:
      id: 162
      author: camsaul
      comment: 'Added 0.23.0 as a data migration; converted to Liquibase migration in 0.35.0'
      preConditions:
        - onFail: MARK_RAN
        - tableExists:
            tableName: query_queryexecution
      changes:
        - dropTable:
            tableName: query_queryexecution

# Drop Card.read_permissions. Prior to 0.30.0 Card permissions were always based on the Database/Table(s) being
# queried (i.e., the permissions model we use for ad-hoc queries). These permissions were calculated and stored in
# `read_permissions` for performance reasons. In 0.30.0, we switched to having Card permissions always be inherited
# from their parent Collection, and the column hasn't been used since then. Time to let it go.

  - changeSet:
      id: 163
      author: camsaul
      comment: 'Added 0.35.0'
      changes:
        - dropColumn:
            tableName: report_card
            columnName: read_permissions

# Add User `locale` -- when set, this User will see the Metabase in this Locale rather than the system default Locale
# (the `site-locale` Setting).

  - changeSet:
      id: 164
      author: camsaul
      comment: 'Added 0.35.0'
      changes:
        - addColumn:
            tableName: core_user
            columns:
              - column:
                  name: locale
                  remarks: 'Preferred ISO locale (language/country) code, e.g "en" or "en-US", for this User. Overrides site default.'
                  type: varchar(5)

# Add Field `database_position` to keep the order in which fields are ordered in the DB, `custom_position` for custom
# position; and Table `field_order` setting.

  - changeSet:
      id: 165
      author: sb
      comment: 'Added field_order to Table and database_position to Field'
      validCheckSum:
        - 8:474a357368a665d5e0701b9eb5f313f9
        - 8:8848644da9dd9e40924ae71ac4c7c370
      changes:
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: database_position
                  type: int
                  defaultValueNumeric: 0
                  constraints:
                    nullable: false
        - addColumn:
            tableName: metabase_field
            columns:
              - column:
                  name: custom_position
                  type: int
                  defaultValueNumeric: 0
                  constraints:
                    nullable: false
        - addColumn:
            tableName: metabase_table
            columns:
              - column:
                  name: field_order
                  type: varchar(254)
                  defaultValue: database
                  constraints:
                    nullable: false
        - sql:
            sql: update metabase_field set database_position = id

# Change field_values.updated_at and query_cache.updated_at from datetime to timestamp [with time zone] to get >
# second resolution on MySQL.
#
# query_cache.updated_at was originally converted to a timestamp in 161, but we used `timestamp` instead of
# `timestamp(6)`. It is converted correctly here.

  - changeSet:
      id: 166
      author: camsaul
      comment: Added 0.36.0/1.35.4
      changes:
        - modifyDataType:
            tableName: metabase_fieldvalues
            columnName: updated_at
            newDataType: ${timestamp_type}
        - modifyDataType:
            tableName: query_cache
            columnName: updated_at
            newDataType: ${timestamp_type}

# Create the native query snippets table, intended to store snippets and their metadata
  - changeSet:
      id: 167
      author: walterl, camsaul
      comment: 'Added 0.36.0'
      changes:
        # If an older version of this Table was created locally (during dev) drop it, we have an updated definition
        - sql:
            sql: drop table if exists native_query_snippet
        - createTable:
            tableName: native_query_snippet
            remarks: 'Query snippets (raw text) to be substituted in native queries'
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: name
                  type: VARCHAR(254)
                  remarks: 'Name of the query snippet'
                  constraints:
                    nullable: false
                    unique: true
              - column:
                  name: description
                  type: text
              - column:
                  name: content
                  type: text
                  remarks: 'Raw query snippet'
                  constraints:
                    nullable: false
              - column:
                  name: creator_id
                  type: int
                  constraints:
                    nullable: false
                    references: core_user(id)
                    foreignKeyName: fk_snippet_creator_id
                    # This primarily affects tests because under normal
                    # circumstances we don't delete Users, we just archive them
                    deleteCascade: true
              - column:
                  name: archived
                  type: boolean
                  defaultValueBoolean: false
                  constraints:
                    nullable: false
              - column:
                  name: created_at
                  type: ${timestamp_type}
                  # it seems like defaultValueComputed actaully just ends
                  # getting ignored anyway -- see
                  # https://stackoverflow.com/questions/58816496/force-liquibase-to-current-timestamp-instead-of-now
                  # We set a custom value for MySQL/MariaDB in MetabaseMySqlCreateTableSqlGenerator.java
                  defaultValueComputed: current_timestamp
                  constraints:
                    nullable: false
              - column:
                  name: updated_at
                  type: ${timestamp_type}
                  defaultValueComputed: current_timestamp
                  constraints:
                    nullable: false
        # Needed to efficiently enforce the unique constraint on name and so we can lookup by name as well.
        - createIndex:
            tableName: native_query_snippet
            indexName: idx_snippet_name
            columns:
              - column:
                  name: name

# Convert query execution from DATETIME to TIMESTAMP(6) so have normalize TZ
# offset and so MySQL/MariaDB has better than second precision

  - changeSet:
      id: 168
      author: camsaul
      comment: Added 0.36.0
      changes:
        - modifyDataType:
            tableName: query_execution
            columnName: started_at
            newDataType: ${timestamp_type}

# Remove `Table.rows`, which hasn't been used for years now. Older versions of Metabase used to store the row count in
# this column but we disabled it a long time ago for performance reasons. Now it's time to remove it entirely.

  - changeSet:
      id: 169
      author: camsaul
      comment: Added 0.36.0
      objectQuotingStrategy: ${quote_strategy}
      changes:
        - dropColumn:
            tableName: metabase_table
            columnName: rows

# Remove fields_hash from Table model, as we no longer skip sync steps if metadata
# hash hasn't changed.

  - changeSet:
      id: 170
      author: sb
      comment: Added 0.36.0
      changes:
        - dropColumn:
            tableName: metabase_table
            columnName: fields_hash

# In EE, NativeQuerySnippets have a permissions system based on "snippet folders" which are Collections under the
# hood. However, these Collections live in a separate "namespace" -- a completely separate hierarchy of Collections.

  - changeSet:
      id: 171
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addColumn:
            tableName: native_query_snippet
            columns:
              - column:
                  name: collection_id
                  type: int
                  remarks: 'ID of the Snippet Folder (Collection) this Snippet is in, if any'
                  constraints:
                    nullable: true
                    references: collection(id)
                    foreignKeyName: fk_snippet_collection_id
                    deleteCascade: true
        - createIndex:
            tableName: native_query_snippet
            indexName: idx_snippet_collection_id
            columns:
              - column:
                  name: collection_id

  - changeSet:
      id: 172
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addColumn:
            tableName: collection
            columns:
              - column:
                  name: namespace
                  type: varchar(254)
                  remarks: 'The namespace (hierachy) this Collection belongs to. NULL means the Collection is in the default namespace.'
                  constraints:
                    nullable: true

# These migrations convert various FK constraints in the DB to ones with ON DELETE CASCADE so the DB can handle this
# instead of relying on Toucan pre-delete methods to do it, which are subject to race conditions.

  # activity.user_id -> core_user.id
  - changeSet:
      id: 173
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: activity
            constraintName: fk_activity_ref_user_id

  - changeSet:
      id: 174
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: activity
            baseColumnNames: user_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_activity_ref_user_id
            onDelete: CASCADE

  # card_label.card_id -> report_card.id
  - changeSet:
      id: 175
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: card_label
            constraintName: fk_card_label_ref_card_id

  - changeSet:
      id: 176
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: card_label
            baseColumnNames: card_id
            referencedTableName: report_card
            referencedColumnNames: id
            constraintName: fk_card_label_ref_card_id
            onDelete: CASCADE

  # card_label.label_id -> label.id
  - changeSet:
      id: 177
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: card_label
            constraintName: fk_card_label_ref_label_id

  - changeSet:
      id: 178
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: card_label
            baseColumnNames: label_id
            referencedTableName: label
            referencedColumnNames: id
            constraintName: fk_card_label_ref_label_id
            onDelete: CASCADE

  # collection.personal_owner_id -> core_user.id
  - changeSet:
      id: 179
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: collection
            constraintName: fk_collection_personal_owner_id

  - changeSet:
      id: 180
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: collection
            baseColumnNames: personal_owner_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_collection_personal_owner_id
            onDelete: CASCADE

  # collection_revision.user_id -> core_user.id
  - changeSet:
      id: 181
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: collection_revision
            constraintName: fk_collection_revision_user_id

  - changeSet:
      id: 182
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: collection_revision
            baseColumnNames: user_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_collection_revision_user_id
            onDelete: CASCADE

  # computation_job.creator_id -> core_user.id
  - changeSet:
      id: 183
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: computation_job
            constraintName: fk_computation_job_ref_user_id

  - changeSet:
      id: 184
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: computation_job
            baseColumnNames: creator_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_computation_job_ref_user_id
            onDelete: CASCADE

  # computation_job_result.job_id -> computation_job.id
  - changeSet:
      id: 185
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: computation_job_result
            constraintName: fk_computation_result_ref_job_id

  - changeSet:
      id: 186
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: computation_job_result
            baseColumnNames: job_id
            referencedTableName: computation_job
            referencedColumnNames: id
            constraintName: fk_computation_result_ref_job_id
            onDelete: CASCADE

  # core_session.user_id -> core_user.id
  - changeSet:
      id: 187
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: core_session
            constraintName: fk_session_ref_user_id

  - changeSet:
      id: 188
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: core_session
            baseColumnNames: user_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_session_ref_user_id
            onDelete: CASCADE

  # dashboardcard_series.card_id -> report_card.id
  - changeSet:
      id: 189
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: dashboardcard_series
            constraintName: fk_dashboardcard_series_ref_card_id

  - changeSet:
      id: 190
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: dashboardcard_series
            baseColumnNames: card_id
            referencedTableName: report_card
            referencedColumnNames: id
            constraintName: fk_dashboardcard_series_ref_card_id
            onDelete: CASCADE

  # dashboardcard_series.dashboardcard_id -> report_dashboardcard.id
  - changeSet:
      id: 191
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: dashboardcard_series
            constraintName: fk_dashboardcard_series_ref_dashboardcard_id

  - changeSet:
      id: 192
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: dashboardcard_series
            baseColumnNames: dashboardcard_id
            referencedTableName: report_dashboardcard
            referencedColumnNames: id
            constraintName: fk_dashboardcard_series_ref_dashboardcard_id
            onDelete: CASCADE

  # group_table_access_policy.card_id -> report_card.id
  - changeSet:
      id: 193
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: group_table_access_policy
            constraintName: fk_gtap_card_id

  - changeSet:
      id: 194
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: group_table_access_policy
            baseColumnNames: card_id
            referencedTableName: report_card
            referencedColumnNames: id
            constraintName: fk_gtap_card_id
            onDelete: CASCADE

  # metabase_field.parent_id -> metabase_field.id
  - changeSet:
      id: 195
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: metabase_field
            constraintName: fk_field_parent_ref_field_id

  - changeSet:
      id: 196
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: metabase_field
            baseColumnNames: parent_id
            referencedTableName: metabase_field
            referencedColumnNames: id
            constraintName: fk_field_parent_ref_field_id
            onDelete: CASCADE

  # metabase_field.table_id -> metabase_table.id
  - changeSet:
      id: 197
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: metabase_field
            constraintName: fk_field_ref_table_id

  - changeSet:
      id: 198
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: metabase_field
            baseColumnNames: table_id
            referencedTableName: metabase_table
            referencedColumnNames: id
            constraintName: fk_field_ref_table_id
            onDelete: CASCADE

  # metabase_fieldvalues.field_id -> metabase_field.id
  - changeSet:
      id: 199
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: metabase_fieldvalues
            constraintName: fk_fieldvalues_ref_field_id

  - changeSet:
      id: 200
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: metabase_fieldvalues
            baseColumnNames: field_id
            referencedTableName: metabase_field
            referencedColumnNames: id
            constraintName: fk_fieldvalues_ref_field_id
            onDelete: CASCADE

  # metabase_table.db_id -> metabase_database.id
  - changeSet:
      id: 201
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: metabase_table
            constraintName: fk_table_ref_database_id

  - changeSet:
      id: 202
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: metabase_table
            baseColumnNames: db_id
            referencedTableName: metabase_database
            referencedColumnNames: id
            constraintName: fk_table_ref_database_id
            onDelete: CASCADE

  # metric.creator_id -> core_user.id
  - changeSet:
      id: 203
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: metric
            constraintName: fk_metric_ref_creator_id

  - changeSet:
      id: 204
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: metric
            baseColumnNames: creator_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_metric_ref_creator_id
            onDelete: CASCADE

  # metric.table_id -> metabase_table.id
  - changeSet:
      id: 205
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: metric
            constraintName: fk_metric_ref_table_id

  - changeSet:
      id: 206
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: metric
            baseColumnNames: table_id
            referencedTableName: metabase_table
            referencedColumnNames: id
            constraintName: fk_metric_ref_table_id
            onDelete: CASCADE

  # metric_important_field.field_id -> metabase_field.id
  - changeSet:
      id: 207
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: metric_important_field
            constraintName: fk_metric_important_field_metabase_field_id

  - changeSet:
      id: 208
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: metric_important_field
            baseColumnNames: field_id
            referencedTableName: metabase_field
            referencedColumnNames: id
            constraintName: fk_metric_important_field_metabase_field_id
            onDelete: CASCADE

  # metric_important_field.metric_id -> metric.id
  - changeSet:
      id: 209
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: metric_important_field
            constraintName: fk_metric_important_field_metric_id

  - changeSet:
      id: 210
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: metric_important_field
            baseColumnNames: metric_id
            referencedTableName: metric
            referencedColumnNames: id
            constraintName: fk_metric_important_field_metric_id
            onDelete: CASCADE

  # native_query_snippet.collection_id -> collection.id
  - changeSet:
      id: 211
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: native_query_snippet
            constraintName: fk_snippet_collection_id

  - changeSet:
      id: 212
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: native_query_snippet
            baseColumnNames: collection_id
            referencedTableName: collection
            referencedColumnNames: id
            constraintName: fk_snippet_collection_id
            onDelete: SET NULL

  # permissions.group_id -> permissions_group.id
  - changeSet:
      id: 213
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: permissions
            constraintName: fk_permissions_group_id

  - changeSet:
      id: 214
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: permissions
            baseColumnNames: group_id
            referencedTableName: permissions_group
            referencedColumnNames: id
            constraintName: fk_permissions_group_id
            onDelete: CASCADE

  # permissions_group_membership.group_id -> permissions_group.id
  - changeSet:
      id: 215
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: permissions_group_membership
            constraintName: fk_permissions_group_group_id

  - changeSet:
      id: 216
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: permissions_group_membership
            baseColumnNames: group_id
            referencedTableName: permissions_group
            referencedColumnNames: id
            constraintName: fk_permissions_group_group_id
            onDelete: CASCADE

  # permissions_group_membership.user_id -> core_user.id
  - changeSet:
      id: 217
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: permissions_group_membership
            constraintName: fk_permissions_group_membership_user_id

  - changeSet:
      id: 218
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: permissions_group_membership
            baseColumnNames: user_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_permissions_group_membership_user_id
            onDelete: CASCADE

  # permissions_revision.user_id -> core_user.id
  - changeSet:
      id: 219
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: permissions_revision
            constraintName: fk_permissions_revision_user_id

  - changeSet:
      id: 220
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: permissions_revision
            baseColumnNames: user_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_permissions_revision_user_id
            onDelete: CASCADE

  # pulse.collection_id -> collection.id
  - changeSet:
      id: 221
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: pulse
            constraintName: fk_pulse_collection_id

  - changeSet:
      id: 222
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: pulse
            baseColumnNames: collection_id
            referencedTableName: collection
            referencedColumnNames: id
            constraintName: fk_pulse_collection_id
            onDelete: SET NULL

  # pulse.creator_id -> core_user.id
  - changeSet:
      id: 223
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: pulse
            constraintName: fk_pulse_ref_creator_id

  - changeSet:
      id: 224
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: pulse
            baseColumnNames: creator_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_pulse_ref_creator_id
            onDelete: CASCADE

  # pulse_card.card_id -> report_card.id
  - changeSet:
      id: 225
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: pulse_card
            constraintName: fk_pulse_card_ref_card_id

  - changeSet:
      id: 226
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: pulse_card
            baseColumnNames: card_id
            referencedTableName: report_card
            referencedColumnNames: id
            constraintName: fk_pulse_card_ref_card_id
            onDelete: CASCADE

  # pulse_card.pulse_id -> pulse.id
  - changeSet:
      id: 227
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: pulse_card
            constraintName: fk_pulse_card_ref_pulse_id

  - changeSet:
      id: 228
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: pulse_card
            baseColumnNames: pulse_id
            referencedTableName: pulse
            referencedColumnNames: id
            constraintName: fk_pulse_card_ref_pulse_id
            onDelete: CASCADE

  # pulse_channel.pulse_id -> pulse.id
  - changeSet:
      id: 229
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: pulse_channel
            constraintName: fk_pulse_channel_ref_pulse_id

  - changeSet:
      id: 230
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: pulse_channel
            baseColumnNames: pulse_id
            referencedTableName: pulse
            referencedColumnNames: id
            constraintName: fk_pulse_channel_ref_pulse_id
            onDelete: CASCADE

  # pulse_channel_recipient.pulse_channel_id -> pulse_channel.id
  - changeSet:
      id: 231
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: pulse_channel_recipient
            constraintName: fk_pulse_channel_recipient_ref_pulse_channel_id

  - changeSet:
      id: 232
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: pulse_channel_recipient
            baseColumnNames: pulse_channel_id
            referencedTableName: pulse_channel
            referencedColumnNames: id
            constraintName: fk_pulse_channel_recipient_ref_pulse_channel_id
            onDelete: CASCADE

  # pulse_channel_recipient.user_id -> core_user.id
  - changeSet:
      id: 233
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: pulse_channel_recipient
            constraintName: fk_pulse_channel_recipient_ref_user_id

  - changeSet:
      id: 234
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: pulse_channel_recipient
            baseColumnNames: user_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_pulse_channel_recipient_ref_user_id
            onDelete: CASCADE

  # report_card.collection_id -> collection.id
  - changeSet:
      id: 235
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: report_card
            constraintName: fk_card_collection_id

  - changeSet:
      id: 236
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: report_card
            baseColumnNames: collection_id
            referencedTableName: collection
            referencedColumnNames: id
            constraintName: fk_card_collection_id
            onDelete: SET NULL

  # report_card.made_public_by_id -> core_user.id
  - changeSet:
      id: 237
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: report_card
            constraintName: fk_card_made_public_by_id

  - changeSet:
      id: 238
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: report_card
            baseColumnNames: made_public_by_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_card_made_public_by_id
            onDelete: CASCADE

  # report_card.creator_id -> core_user.id
  - changeSet:
      id: 239
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: report_card
            constraintName: fk_card_ref_user_id

  - changeSet:
      id: 240
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: report_card
            baseColumnNames: creator_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_card_ref_user_id
            onDelete: CASCADE

  # report_card.database_id -> metabase_database.id
  - changeSet:
      id: 241
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: report_card
            constraintName: fk_report_card_ref_database_id

  - changeSet:
      id: 242
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: report_card
            baseColumnNames: database_id
            referencedTableName: metabase_database
            referencedColumnNames: id
            constraintName: fk_report_card_ref_database_id
            onDelete: CASCADE

  # report_card.table_id -> metabase_table.id
  - changeSet:
      id: 243
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: report_card
            constraintName: fk_report_card_ref_table_id

  - changeSet:
      id: 244
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: report_card
            baseColumnNames: table_id
            referencedTableName: metabase_table
            referencedColumnNames: id
            constraintName: fk_report_card_ref_table_id
            onDelete: CASCADE

  # report_cardfavorite.card_id -> report_card.id
  - changeSet:
      id: 245
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: report_cardfavorite
            constraintName: fk_cardfavorite_ref_card_id

  - changeSet:
      id: 246
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: report_cardfavorite
            baseColumnNames: card_id
            referencedTableName: report_card
            referencedColumnNames: id
            constraintName: fk_cardfavorite_ref_card_id
            onDelete: CASCADE

  # report_cardfavorite.owner_id -> core_user.id
  - changeSet:
      id: 247
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: report_cardfavorite
            constraintName: fk_cardfavorite_ref_user_id

  - changeSet:
      id: 248
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: report_cardfavorite
            baseColumnNames: owner_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_cardfavorite_ref_user_id
            onDelete: CASCADE

  # report_dashboard.collection_id -> collection.id
  - changeSet:
      id: 249
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: report_dashboard
            constraintName: fk_dashboard_collection_id

  - changeSet:
      id: 250
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: report_dashboard
            baseColumnNames: collection_id
            referencedTableName: collection
            referencedColumnNames: id
            constraintName: fk_dashboard_collection_id
            onDelete: SET NULL

  # report_dashboard.made_public_by_id -> core_user.id
  - changeSet:
      id: 251
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: report_dashboard
            constraintName: fk_dashboard_made_public_by_id

  - changeSet:
      id: 252
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: report_dashboard
            baseColumnNames: made_public_by_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_dashboard_made_public_by_id
            onDelete: CASCADE

  # report_dashboard.creator_id -> core_user.id
  - changeSet:
      id: 253
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: report_dashboard
            constraintName: fk_dashboard_ref_user_id

  - changeSet:
      id: 254
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: report_dashboard
            baseColumnNames: creator_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_dashboard_ref_user_id
            onDelete: CASCADE

  # report_dashboardcard.card_id -> report_card.id
  - changeSet:
      id: 255
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: report_dashboardcard
            constraintName: fk_dashboardcard_ref_card_id

  - changeSet:
      id: 256
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: report_dashboardcard
            baseColumnNames: card_id
            referencedTableName: report_card
            referencedColumnNames: id
            constraintName: fk_dashboardcard_ref_card_id
            onDelete: CASCADE

  # report_dashboardcard.dashboard_id -> report_dashboard.id
  - changeSet:
      id: 257
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: report_dashboardcard
            constraintName: fk_dashboardcard_ref_dashboard_id

  - changeSet:
      id: 258
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: report_dashboardcard
            baseColumnNames: dashboard_id
            referencedTableName: report_dashboard
            referencedColumnNames: id
            constraintName: fk_dashboardcard_ref_dashboard_id
            onDelete: CASCADE

  # revision.user_id -> core_user.id
  - changeSet:
      id: 259
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: revision
            constraintName: fk_revision_ref_user_id

  - changeSet:
      id: 260
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: revision
            baseColumnNames: user_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_revision_ref_user_id
            onDelete: CASCADE

  # segment.creator_id -> core_user.id
  - changeSet:
      id: 261
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: segment
            constraintName: fk_segment_ref_creator_id

  - changeSet:
      id: 262
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: segment
            baseColumnNames: creator_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_segment_ref_creator_id
            onDelete: CASCADE

  # segment.table_id -> metabase_table.id
  - changeSet:
      id: 263
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: segment
            constraintName: fk_segment_ref_table_id

  - changeSet:
      id: 264
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: segment
            baseColumnNames: table_id
            referencedTableName: metabase_table
            referencedColumnNames: id
            constraintName: fk_segment_ref_table_id
            onDelete: CASCADE

  # view_log.user_id -> core_user.id
  - changeSet:
      id: 265
      author: camsaul
      comment: Added 0.36.0
      changes:
        - dropForeignKeyConstraint:
            baseTableName: view_log
            constraintName: fk_view_log_ref_user_id

  - changeSet:
      id: 266
      author: camsaul
      comment: Added 0.36.0
      changes:
        - addForeignKeyConstraint:
            baseTableName: view_log
            baseColumnNames: user_id
            referencedTableName: core_user
            referencedColumnNames: id
            constraintName: fk_view_log_ref_user_id
            onDelete: CASCADE

# changesets 268-272 allow for handling user account emails in lowercase (GH issue 3047)
  - changeSet:
      id: 268
      author: rlotun
      comment: Added 0.37.0  # create index on lower(email), for performance reasons (not availble on h2 and only on more recent versions of mysql)
      failOnError: false
      preConditions:
        - onFail: MARK_RAN
        - and:
            - dbms:
                type: postgresql,mysql,mariadb
      changes:
        - createIndex:
            columns:
             - column:
                 name: lower(email)
                 type: varchar(254)
            tableName: core_user
            indexName: idx_lower_email
  - changeSet:
      id: 269
      author: rlotun
      comment: Added 0.37.0  # set email values to lower(email) but do so defensively and in a way that works on postgres and mysql - skip over those that would introduce duplicates (e.g. Reza@email.com and reza@email.com)
      changes:
        - sql :
            sql : UPDATE core_user SET email = lower(email) WHERE lower(email) NOT IN (SELECT * FROM (SELECT lower(email) FROM core_user GROUP BY lower(email) HAVING count(email) > 1) as e)
  - changeSet:
      id: 270
      author: rlotun
      comment: Added 0.37.0 # try to install citext extension on posgres (user requires privileges on postgres)
      failOnError: false
      preConditions:
        - onFail: MARK_RAN
        - or:
            - dbms:
                type: postgresql
      changes:
        - sql :
            sql : CREATE EXTENSION IF NOT EXISTS citext
  - changeSet:
      id: 271
      author: rlotun
      comment: Added 0.37.0 # try to convert email column to citext on postgres, if citext extension installed
      failOnError: false
      preConditions:
        - onFail: MARK_RAN
        - and:
            - dbms:
                type: postgresql
            - sqlCheck:
                expectedResult: 1
                sql: SELECT count(*) FROM pg_extension WHERE extname = 'citext'
      changes:
        - modifyDataType:
            tableName: core_user
            columnName: email
            newDataType: citext
  - changeSet:
      id: 272
      author: rlotun
      comment: Added 0.37.0 # for H2 convert column to VARCHAR_IGNORECASE
      failOnError: false
      preConditions:
         - or:
             - dbms:
                   type: h2
      changes:
        - modifyDataType:
            tableName: core_user
            columnName: email
            newDataType: varchar_ignorecase(254)

  - changeSet:
      id: 273
      author: camsaul
      comment: Added 0.37.1
      changes:
        - addDefaultValue:
            tableName: core_user
            columnName: is_superuser
            columnDataType: boolean
            defaultValueBoolean: false

  - changeSet:
      id: 274
      author: camsaul
      comment: Added 0.37.1
      changes:
        - addDefaultValue:
            tableName: core_user
            columnName: is_active
            columnDataType: boolean
            defaultValueBoolean: true

 # Add refingerprint to database to mark if fingerprinting or
 # not. Nullable in first pass so can be opt in and then in a
 # subsequent pass can be globally turned on where null, respecting
 # people who turned it on and then off.

  - changeSet:
      id: 275
      author: dpsutton
      comment: 'Added 0.38.0 refingerprint to Database'
      validCheckSum:
        - 8:b976d49f4eb84664649119f5f63465dd
        - 8:447d9e294f59dd1058940defec7e0f40
      changes:
        - addColumn:
            tableName: metabase_database
            columns:
              - column:
                  name: refingerprint
                  type: boolean
                  remarks: 'Whether or not to enable periodic refingerprinting for this Database.'
                  constraints:
                    nullable: true
  - changeSet:
      id: 276
      author: robroland
      comment: Added 0.38.0 - Dashboard subscriptions
      validCheckSum:
        - 8:dfe9b8333b600c739306caa85d95ad55
        - 8:59dd1fb0732c7a9b78bce896c0cff3c0
      changes:
        - addColumn:
            tableName: pulse_card
            columns:
            - column:
                name: dashboard_card_id
                type: int
                remarks: 'If this Pulse is a Dashboard subscription, the ID of the DashboardCard that corresponds to this PulseCard.'
                constraints:
                  nullable: true
                  references: report_dashboardcard(id)
                  foreignKeyName: fk_pulse_card_ref_pulse_card_id
                  deferrable: false
                  initiallyDeferred: false

  - changeSet:
      id: 277
      author: tsmacdonald
      comment: Added 0.38.0 - Dashboard subscriptions
      changes:
        - dropForeignKeyConstraint:
            baseTableName: pulse_card
            constraintName: fk_pulse_card_ref_pulse_card_id

  - changeSet:
      id: 278
      author: tsmacdonald
      comment: Added 0.38.0 - Dashboard subscrptions
      changes:
        - addForeignKeyConstraint:
            baseTableName: pulse_card
            baseColumnNames: dashboard_card_id
            referencedTableName: report_dashboardcard
            referencedColumnNames: id
            constraintName: fk_pulse_card_ref_pulse_card_id
            onDelete: CASCADE

  - changeSet:
      id: 279
      author: camsaul
      comment: Added 0.38.0 - Dashboard subscriptions
      changes:
        - addColumn:
            tableName: pulse
            columns:
              - column:
                  name: dashboard_id
                  type: int
                  remarks: 'ID of the Dashboard if this Pulse is a Dashboard Subscription.'

  # FK constraint is added separately because deleteCascade doesn't work in addColumn -- see #14321
  - changeSet:
      id: 280
      author: camsaul
      comment: Added 0.38.0 - Dashboard subscriptions
      changes:
        - addForeignKeyConstraint:
            baseTableName: pulse
            baseColumnNames: dashboard_id
            referencedTableName: report_dashboard
            referencedColumnNames: id
            constraintName: fk_pulse_ref_dashboard_id
            onDelete: CASCADE


# >>>>>>>>>> DO NOT ADD NEW MIGRATIONS BELOW THIS LINE! ADD THEM ABOVE <<<<<<<<<<

########################################################################################################################
#
# ADVICE:
#
# 1) Run ./bin/lint-migrations-file.sh to run core.spec checks against any changes you make here. Liquibase is pretty
#    forgiving and won't complain if you accidentally mix up things like deleteCascade and onDelete: CASCADE. CI runs
#    this check but it's nicer to know now instead of waiting for CI.
#
# 2) Please post a message in the Metabase Slack #migrations channel to let others know you are creating a new
#    migration so someone else doesn't steal your ID number
#
# PLEASE KEEP THIS MESSAGE AT THE BOTTOM OF THIS FILE!!!!! Add new migrations above the message.
#
########################################################################################################################
