From 7be1f1c90805dc6c1845434fc215f9f07199db75 Mon Sep 17 00:00:00 2001 From: "mkanat%kerio.com" <> Date: Fri, 15 Apr 2005 09:31:35 +0000 Subject: Bug 290405: bz_add_column needs a way to specify an initial value Patch By Max Kanat-Alexander r=Tomas.Kopal, a=justdave --- Bugzilla/DB.pm | 23 ++++++++++++++++------- Bugzilla/DB/Schema.pm | 18 +++++++++++++----- Bugzilla/DB/Schema/Pg.pm | 10 +++++++--- 3 files changed, 36 insertions(+), 15 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm index 6cd938aa6..d72cd5e82 100644 --- a/Bugzilla/DB.pm +++ b/Bugzilla/DB.pm @@ -331,20 +331,26 @@ sub bz_setup_database { ##################################################################### sub bz_add_column { - my ($self, $table, $name, $new_def) = @_; + my ($self, $table, $name, $new_def, $init_value) = @_; # You can't add a NOT NULL column to a table with - # no DEFAULT statement. - if ($new_def->{NOTNULL} && !exists $new_def->{DEFAULT}) { + # no DEFAULT statement, unless you have an init_value. + # SERIAL types are an exception, though, because they can + # auto-populate. + if ( $new_def->{NOTNULL} && !exists $new_def->{DEFAULT} + && !defined $init_value && $new_def->{TYPE} !~ /SERIAL/) + { die "Failed adding the column ${table}.${name}:\n You cannot add" - . " a NOT NULL column with no default to an existing table.\n"; + . " a NOT NULL column with no default to an existing table,\n" + . " unless you specify something for \$init_value." } my $current_def = $self->bz_column_info($table, $name); if (!$current_def) { my @statements = $self->_bz_real_schema->get_add_column_ddl( - $table, $name, $new_def); + $table, $name, $new_def, + defined $init_value ? $self->quote($init_value) : undef); print "Adding new column $name to table $table ...\n"; foreach my $sql (@statements) { $self->do($sql); @@ -898,7 +904,7 @@ Bugzilla::DB - Database access routines, using L my @result = $sth->fetchrow_array; # Schema Modification - $dbh->bz_add_column($table, $name, \%definition); + $dbh->bz_add_column($table, $name, \%definition, $init_value); $dbh->bz_add_index($table, $name, $definition); $dbh->bz_drop_index($table, $name); $dbh->bz_alter_column($table, $name, \%new_def); @@ -1211,7 +1217,7 @@ C. =over 4 -=item C +=item C Description: Adds a new column to a table in the database. Prints out a brief statement that it did so, to stdout. @@ -1221,6 +1227,9 @@ C. Params: $table = the table where the column is being added $name = the name of the new column \%definition = Abstract column definition for the new column + $init_value = (optional) An initial value to set the column + to. Required if your column is NOT NULL and has + no DEFAULT set. Returns: nothing =item C diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm index 9ef1f6214..99127ff69 100644 --- a/Bugzilla/DB/Schema.pm +++ b/Bugzilla/DB/Schema.pm @@ -1359,22 +1359,30 @@ sub _get_create_index_ddl { sub get_add_column_ddl { -=item C +=item C Description: Generate SQL to add a column to a table. Params: $table - The table containing the column. $column - The name of the column being added. \%definition - The new definition for the column, in standard C format. + $init_value - (optional) An initial value to set + the column to. Should already be SQL-quoted + if necessary. Returns: An array of SQL statements. =cut - my ($self, $table, $column, $definition) = @_; + my ($self, $table, $column, $definition, $init_value) = @_; + my @statements; + push(@statements, "ALTER TABLE $table ADD COLUMN $column " . + $self->get_type_ddl($definition)); - my $statement = "ALTER TABLE $table ADD COLUMN $column " . - $self->get_type_ddl($definition); + # XXX - Note that although this works for MySQL, most databases will fail + # before this point, if we haven't set a default. + (push(@statements, "UPDATE $table SET $column = $init_value")) + if defined $init_value; - return ($statement); + return (@statements); } sub get_add_index_ddl { diff --git a/Bugzilla/DB/Schema/Pg.pm b/Bugzilla/DB/Schema/Pg.pm index d88bc520c..14c98308a 100644 --- a/Bugzilla/DB/Schema/Pg.pm +++ b/Bugzilla/DB/Schema/Pg.pm @@ -91,7 +91,7 @@ sub _initialize { # Overridden because Pg has such weird ALTER TABLE problems. sub get_add_column_ddl { - my ($self, $table, $column, $definition) = @_; + my ($self, $table, $column, $definition, $init_value) = @_; my @statements; my $specific = $self->{db_specific}; @@ -109,13 +109,17 @@ sub get_add_column_ddl { . " SET DEFAULT $default"); } + if (defined $init_value) { + push(@statements, "UPDATE $table SET $column = $init_value"); + } + if ($definition->{NOTNULL}) { # Handle rows that were NULL when we added the column. # We *must* have a DEFAULT. This check is usually handled # at a higher level than this code, but I figure it can't # hurt to have it here. - die "NOT NULL columns must have a DEFAULT" - unless exists $definition->{DEFAULT}; + die "NOT NULL columns must have a DEFAULT or an init_value." + unless (exists $definition->{DEFAULT} || defined $init_value); push(@statements, "UPDATE $table SET $column = $default"); push(@statements, "ALTER TABLE $table ALTER COLUMN $column " . " SET NOT NULL"); -- cgit v1.2.3-24-g4f1b