/**
  * Outputs commands for addition, removal and modifications of
  * table columns.
  *
  * @param stage1 output file segmenter
  * @param stage3 output file segmenter
  * @param old_table original table
  * @param new_table new table
  */
 protected static function update_table_columns($ofs1, $ofs3, $old_table, $new_schema, $new_table)
 {
     $commands = array();
     $drop_defaults_columns = array();
     mssql10_diff_tables::add_drop_table_columns($commands, $old_table, $new_table);
     mssql10_diff_tables::add_create_table_columns($commands, $old_table, $new_schema, $new_table, $drop_defaults_columns);
     mssql10_diff_tables::add_modify_table_columns($commands, $old_table, $new_schema, $new_table, $drop_defaults_columns);
     if (count($commands) > 0) {
         // do 'pre' 'entire' statements before aggregate table alterations
         for ($i = 0; $i < count($commands); $i++) {
             if ($commands[$i]['stage'] == 'BEFORE1') {
                 $ofs1->write($commands[$i]['command'] . "\n");
             } else {
                 if ($commands[$i]['stage'] == 'BEFORE3') {
                     $ofs3->write($commands[$i]['command'] . "\n");
                 }
             }
         }
         $quotedTableName = mssql10::get_quoted_schema_name($new_schema['name']) . '.' . mssql10::get_quoted_table_name($new_table['name']);
         $stage1_sql = '';
         $stage3_sql = '';
         for ($i = 0; $i < count($commands); $i++) {
             if (!isset($commands[$i]['stage']) || !isset($commands[$i]['command'])) {
                 var_dump($commands[$i]);
                 throw new exception("bad command format");
             }
             if ($commands[$i]['stage'] == '1') {
                 // we have a stage 1 alteration to make
                 // unlike pgsql8_diff_tables, each alteration statement is on its own line
                 // this is because ADD column and ALTER COLUMN statements can't be added to n
                 $stage1_sql .= "ALTER TABLE " . $quotedTableName . "\n" . $commands[$i]['command'] . ";\n";
             } else {
                 if ($commands[$i]['stage'] == '3') {
                     // we have a stage 3 alteration to make
                     // unlike pgsql8_diff_tables, each alteration statement is on its own line
                     // this is because ADD column and ALTER COLUMN statements can't be added to n
                     $stage3_sql .= "ALTER TABLE " . $quotedTableName . "\n" . $commands[$i]['command'] . ";\n";
                 }
             }
         }
         if (strlen($stage1_sql) > 0) {
             $ofs1->write($stage1_sql);
         }
         if (strlen($stage3_sql) > 0) {
             $ofs3->write($stage3_sql);
         }
         if (count($drop_defaults_columns) > 0) {
             $ofs1->write("\n");
             $ofs1->write("ALTER TABLE " . $quotedTableName . "\n");
             for ($i = 0; $i < count($drop_defaults_columns); $i++) {
                 $ofs1->write("\tALTER COLUMN " . mssql10::get_quoted_column_name($drop_defaults_columns[$i]['name']) . " DROP DEFAULT");
                 if ($i < count($drop_defaults_columns) - 1) {
                     $ofs1->write(",\n");
                 } else {
                     $ofs1->write(";\n");
                 }
             }
         }
         // do 'post' 'entire' statements immediately following aggregate table alterations
         for ($i = 0; $i < count($commands); $i++) {
             if ($commands[$i]['stage'] == 'BEFORE1') {
                 // already taken care of in earlier entire command output loop
             } else {
                 if ($commands[$i]['stage'] == 'BEFORE3') {
                     // already taken care of in earlier entire command output loop
                 } else {
                     if ($commands[$i]['stage'] == '1') {
                         // already taken care of in earlier command aggregate loop
                     } else {
                         if ($commands[$i]['stage'] == '3') {
                             // already taken care of in earlier command aggregate loop
                         } else {
                             if ($commands[$i]['stage'] == 'AFTER1') {
                                 $ofs1->write($commands[$i]['command'] . "\n");
                             } else {
                                 if ($commands[$i]['stage'] == 'AFTER3') {
                                     $ofs3->write($commands[$i]['command'] . "\n");
                                 } else {
                                     throw new exception("Unknown stage " . $commands[$i]['stage'] . " during table " . $quotedTableName . " updates");
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }