Thread: alter column appears to work, but doesn't?

alter column appears to work, but doesn't?

From
Ron Peterson
Date:
I just updated a table to have a larger column size as follows.

alter table attributes_log alter column attribute_name type varchar(48);

The size was previously 24.

iddb=> \d attributes
                                               Table "iddb.attributes"
     Column     |         Type          |                                  Modifiers
----------------+-----------------------+-----------------------------------------------------------------------------
 attribute_id   | uuid                  | not null default (encode(pgcrypto.gen_random_bytes(16), 'hex'::text))::uuid
 attribute_name | character varying(48) | not null
 management     | character varying(24) | not null default 'by_value'::character varying

iddb=> insert into attributes ( attribute_name ) values ( 'abcdefghijklmnopqrstuvwxyz' );
ERROR:  value too long for type character varying(24)

I'm using PostgreSQL 9.0.4

I tried to replicate this with a new database and a simple table, but
could not.

I had to drop (and then recreate) three rules and a view on this table
before altering the column.

This is a production database, so I need to treat it gently.

--
Ron Peterson
Network & Systems Administrator
Mount Holyoke College
http://www.mtholyoke.edu/~rpeterso

Re: alter column appears to work, but doesn't?

From
Tom Lane
Date:
Ron Peterson <rpeterso@mtholyoke.edu> writes:
> I just updated a table to have a larger column size as follows.

> alter table attributes_log alter column attribute_name type varchar(48);

How come this refers to "attributes_log" while your failing command is
an insert into "attributes"?

            regards, tom lane

Re: alter column appears to work, but doesn't?

From
Ron Peterson
Date:
2011-09-05_15:03:00-0400 Tom Lane <tgl@sss.pgh.pa.us>:
> Ron Peterson <rpeterso@mtholyoke.edu> writes:
> > I just updated a table to have a larger column size as follows.
>
> > alter table attributes_log alter column attribute_name type varchar(48);
>
> How come this refers to "attributes_log" while your failing command is
> an insert into "attributes"?

That was a typo, sorry.  Did do the same thing on original table.  I did
the same thing to attributes_log because I have rules that log data
there from my original table on insert/update/delete.

I just dropped my logging rules, stopped the database and restarted it,
put my rules back in place, and now it works.  Not sure why.  Cached
query plan?

--
Ron Peterson
Network & Systems Administrator
Mount Holyoke College
http://www.mtholyoke.edu/~rpeterso

Re: alter column appears to work, but doesn't?

From
Tom Lane
Date:
Ron Peterson <rpeterso@mtholyoke.edu> writes:
> I just dropped my logging rules, stopped the database and restarted it,
> put my rules back in place, and now it works.  Not sure why.  Cached
> query plan?

Maybe.  We'd need a reproducible test case to do more than speculate
though.

            regards, tom lane

Re: alter column appears to work, but doesn't?

From
Ron Peterson
Date:
2011-09-05_16:14:00-0400 Tom Lane <tgl@sss.pgh.pa.us>:
> Ron Peterson <rpeterso@mtholyoke.edu> writes:
> > I just dropped my logging rules, stopped the database and restarted it,
> > put my rules back in place, and now it works.  Not sure why.  Cached
> > query plan?
>
> Maybe.  We'd need a reproducible test case to do more than speculate
> though.

Hi Tom,

I was able to reproduce this.  DDL below.  Probably more DDL than
necessary, but not sure what is or isn't relevant.

postgres=# drop rule attribute_insert_rule on attributes;
postgres=# drop rule attribute_update_rule on attributes;
postgres=# drop rule attribute_delete_rule on attributes;
postgres=# alter table attributes_log alter column attribute_name type varchar(50);
...then recreate rules below
postgres=# insert into attributes values ( repeat( 'x', 49 ) );
ERROR:  value too long for type character varying(48)


CREATE TABLE attributes (
  attribute_name
    VARCHAR(48)
    UNIQUE
    NOT NULL
);

-- Attribute names can be inserted or deleted, but not changed.
CREATE OR REPLACE FUNCTION attribute_name_freeze_tf()
RETURNS TRIGGER
AS $$
BEGIN
  IF (TG_OP = 'INSERT') THEN
    IF NEW.attribute_name = OLD.attribute_name THEN
      RETURN NEW;
    END IF;
  END IF;
  RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER attribute_name_freeze_t
BEFORE UPDATE ON attributes
FOR EACH ROW EXECUTE PROCEDURE attribute_name_freeze_tf();

CREATE TABLE attributes_log (
  attribute_name
    VARCHAR(48),
  action
    CHAR(6)
    NOT NULL
    CHECK( action IN ('insert', 'delete','update') ),
  changed
    TIMESTAMP WITH TIME ZONE
    NOT NULL
    DEFAULT CURRENT_TIMESTAMP
);

CREATE RULE attribute_insert_rule AS
ON INSERT TO attributes
DO
(
  INSERT INTO attributes_log (
    attribute_name,
    action )
  VALUES (
    new.attribute_name,
    'insert' );
);

CREATE RULE attribute_update_rule AS
ON UPDATE TO attributes
DO
(
  INSERT INTO attributes_log (
    attribute_name,
    action )
  VALUES (
    new.attribute_name,
    'update' );
);

CREATE RULE attribute_delete_rule AS
ON DELETE TO attributes
DO
(
  INSERT INTO attributes_log (
    attribute_name,
    action )
  VALUES (
    old.attribute_name,
    'delete' );
);
------------------------------------------------------------------------


--
Ron Peterson
Network & Systems Administrator
Mount Holyoke College
http://www.mtholyoke.edu/~rpeterso

Re: alter column appears to work, but doesn't?

From
Adrian Klaver
Date:
On Monday, September 05, 2011 1:48:58 pm Ron Peterson wrote:
> 2011-09-05_16:14:00-0400 Tom Lane <tgl@sss.pgh.pa.us>:
> > Ron Peterson <rpeterso@mtholyoke.edu> writes:
> > > I just dropped my logging rules, stopped the database and restarted it,
> > > put my rules back in place, and now it works.  Not sure why.  Cached
> > > query plan?
> >
> > Maybe.  We'd need a reproducible test case to do more than speculate
> > though.
>
> Hi Tom,
>
> I was able to reproduce this.  DDL below.  Probably more DDL than
> necessary, but not sure what is or isn't relevant.
>
> postgres=# drop rule attribute_insert_rule on attributes;
> postgres=# drop rule attribute_update_rule on attributes;
> postgres=# drop rule attribute_delete_rule on attributes;
> postgres=# alter table attributes_log alter column attribute_name type
> varchar(50); ...then recreate rules below
> postgres=# insert into attributes values ( repeat( 'x', 49 ) );
> ERROR:  value too long for type character varying(48)
>
>

I am not seeing where you change the varchar length in the table attributes.
That is where the error is coming from.

--
Adrian Klaver
adrian.klaver@gmail.com

Re: alter column appears to work, but doesn't?

From
Ron Peterson
Date:
Phghght.  Sorry, no, that didn't do it, I was typing too fast and
skipped updating the attributes table.  That was definitely not the case
w/ my original database.  Wasn't working.  The table definition reported
the update I made.  Insert did not work.  Dropping rules, restarting
database, and recreating rules got it working.  Dunno.

-Ron-