Merge "Add dropSequence to postgres"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 14 Dec 2017 21:57:45 +0000 (21:57 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 14 Dec 2017 21:57:46 +0000 (21:57 +0000)
1  2 
includes/installer/PostgresUpdater.php

@@@ -452,37 -452,6 +452,37 @@@ class PostgresUpdater extends DatabaseU
                        [ 'addPgIndex', 'externallinks', 'el_from_index_60', '( el_from, el_index_60, el_id )' ],
                        [ 'addPgField', 'user_groups', 'ug_expiry', "TIMESTAMPTZ NULL" ],
                        [ 'addPgIndex', 'user_groups', 'user_groups_expiry', '( ug_expiry )' ],
 +
 +                      // 1.30
 +                      [ 'addPgEnumValue', 'media_type', '3D' ],
 +                      [ 'setDefault', 'revision', 'rev_comment', '' ],
 +                      [ 'changeNullableField', 'revision', 'rev_comment', 'NOT NULL', true ],
 +                      [ 'setDefault', 'archive', 'ar_comment', '' ],
 +                      [ 'changeNullableField', 'archive', 'ar_comment', 'NOT NULL', true ],
 +                      [ 'addPgField', 'archive', 'ar_comment_id', 'INTEGER NOT NULL DEFAULT 0' ],
 +                      [ 'setDefault', 'ipblocks', 'ipb_reason', '' ],
 +                      [ 'addPgField', 'ipblocks', 'ipb_reason_id', 'INTEGER NOT NULL DEFAULT 0' ],
 +                      [ 'setDefault', 'image', 'img_description', '' ],
 +                      [ 'setDefault', 'oldimage', 'oi_description', '' ],
 +                      [ 'changeNullableField', 'oldimage', 'oi_description', 'NOT NULL', true ],
 +                      [ 'addPgField', 'oldimage', 'oi_description_id', 'INTEGER NOT NULL DEFAULT 0' ],
 +                      [ 'setDefault', 'filearchive', 'fa_deleted_reason', '' ],
 +                      [ 'changeNullableField', 'filearchive', 'fa_deleted_reason', 'NOT NULL', true ],
 +                      [ 'addPgField', 'filearchive', 'fa_deleted_reason_id', 'INTEGER NOT NULL DEFAULT 0' ],
 +                      [ 'setDefault', 'filearchive', 'fa_description', '' ],
 +                      [ 'addPgField', 'filearchive', 'fa_description_id', 'INTEGER NOT NULL DEFAULT 0' ],
 +                      [ 'setDefault', 'recentchanges', 'rc_comment', '' ],
 +                      [ 'changeNullableField', 'recentchanges', 'rc_comment', 'NOT NULL', true ],
 +                      [ 'addPgField', 'recentchanges', 'rc_comment_id', 'INTEGER NOT NULL DEFAULT 0' ],
 +                      [ 'setDefault', 'logging', 'log_comment', '' ],
 +                      [ 'changeNullableField', 'logging', 'log_comment', 'NOT NULL', true ],
 +                      [ 'addPgField', 'logging', 'log_comment_id', 'INTEGER NOT NULL DEFAULT 0' ],
 +                      [ 'setDefault', 'protected_titles', 'pt_reason', '' ],
 +                      [ 'changeNullableField', 'protected_titles', 'pt_reason', 'NOT NULL', true ],
 +                      [ 'addPgField', 'protected_titles', 'pt_reason_id', 'INTEGER NOT NULL DEFAULT 0' ],
 +                      [ 'addTable', 'comment', 'patch-comment-table.sql' ],
 +                      [ 'addIndex', 'site_stats', 'site_stats_pkey', 'patch-site_stats-pk.sql' ],
 +                      [ 'addTable', 'ip_changes', 'patch-ip_changes.sql' ],
                ];
        }
  
@@@ -657,6 -626,13 +657,13 @@@ END
                }
        }
  
+       protected function dropSequence( $table, $ns ) {
+               if ( $this->db->sequenceExists( $ns ) ) {
+                       $this->output( "Dropping sequence $ns\n" );
+                       $this->db->query( "DROP SEQUENCE $ns CASCADE" );
+               }
+       }
        protected function renameSequence( $old, $new ) {
                if ( $this->db->sequenceExists( $new ) ) {
                        $this->output( "...sequence $new already exists.\n" );
        }
  
        protected function setDefault( $table, $field, $default ) {
 -
                $info = $this->db->fieldInfo( $table, $field );
                if ( $info->defaultValue() !== $default ) {
                        $this->output( "Changing '$table.$field' default value\n" );
 -                      $this->db->query( "ALTER TABLE $table ALTER $field SET DEFAULT " . $default );
 +                      $this->db->query( "ALTER TABLE $table ALTER $field SET DEFAULT "
 +                              . $this->db->addQuotes( $default ) );
                }
        }
  
 -      protected function changeNullableField( $table, $field, $null ) {
 +      protected function changeNullableField( $table, $field, $null, $update = false ) {
                $fi = $this->db->fieldInfo( $table, $field );
                if ( is_null( $fi ) ) {
                        $this->output( "...ERROR: expected column $table.$field to exist\n" );
                        # # It's NULL - does it need to be NOT NULL?
                        if ( 'NOT NULL' === $null ) {
                                $this->output( "Changing '$table.$field' to not allow NULLs\n" );
 +                              if ( $update ) {
 +                                      $this->db->query( "UPDATE $table SET $field = DEFAULT WHERE $field IS NULL" );
 +                              }
                                $this->db->query( "ALTER TABLE $table ALTER $field SET NOT NULL" );
                        } else {
                                $this->output( "...column '$table.$field' is already set as NULL\n" );
                }
        }
  
 +      /**
 +       * Add a value to an existing PostgreSQL enum type
 +       * @since 1.31
 +       * @param string $type Type name. Must be in the core schema.
 +       * @param string $value Value to add.
 +       */
 +      public function addPgEnumValue( $type, $value ) {
 +              $row = $this->db->selectRow(
 +                      [
 +                              't' => 'pg_catalog.pg_type',
 +                              'n' => 'pg_catalog.pg_namespace',
 +                              'e' => 'pg_catalog.pg_enum',
 +                      ],
 +                      [ 't.typname', 't.typtype', 'e.enumlabel' ],
 +                      [
 +                              't.typname' => $type,
 +                              'n.nspname' => $this->db->getCoreSchema(),
 +                      ],
 +                      __METHOD__,
 +                      [],
 +                      [
 +                              'n' => [ 'JOIN', 't.typnamespace = n.oid' ],
 +                              'e' => [ 'LEFT JOIN', [ 'e.enumtypid = t.oid', 'e.enumlabel' => $value ] ],
 +                      ]
 +              );
 +
 +              if ( !$row ) {
 +                      $this->output( "...Type $type does not exist, skipping modify enum.\n" );
 +              } elseif ( $row->typtype !== 'e' ) {
 +                      $this->output( "...Type $type does not seem to be an enum, skipping modify enum.\n" );
 +              } elseif ( $row->enumlabel === $value ) {
 +                      $this->output( "...Enum type $type already contains value '$value'.\n" );
 +              } else {
 +                      $this->output( "...Adding value '$value' to enum type $type.\n" );
 +                      $etype = $this->db->addIdentifierQuotes( $type );
 +                      $evalue = $this->db->addQuotes( $value );
 +                      $this->db->query( "ALTER TYPE $etype ADD VALUE $evalue" );
 +              }
 +      }
 +
        protected function dropFkey( $table, $field ) {
                $fi = $this->db->fieldInfo( $table, $field );
                if ( is_null( $fi ) ) {