Postgresql - change the size of a varchar column to lower length

alter command to increase column size in postgres
postgres alter column
postgres increase column length
cannot alter type of a column used by a view or rule
postgres varchar max length
postgres alter column integer to varchar
postgres add column
how to change column value in postgres

I have a question about the ALTER TABLE command on a really large table (almost 30 millions rows). One of its columns is a varchar(255) and I would like to resize it to a varchar(40). Basically, I would like to change my column by running the following command:

ALTER TABLE mytable ALTER COLUMN mycolumn TYPE varchar(40);

I have no problem if the process is very long but it seems my table is no more readable during the ALTER TABLE command. Is there a smarter way? Maybe add a new column, copy values from the old column, drop the old column and finally rename the new one?

Any clue will be greatly appreciated! Thanks in advance,

Note: I use PostgreSQL 9.0.

There's a description of how to do this at Resize a column in a PostgreSQL table without changing data. You have to hack the database catalog data. The only way to do this officially is with ALTER TABLE, and as you've noted that change will lock and rewrite the entire table while it's running.

Make sure you read the Character Types section of the docs before changing this. All sorts of weird cases to be aware of here. The length check is done when values are stored into the rows. If you hack a lower limit in there, that will not reduce the size of existing values at all. You would be wise to do a scan over the whole table looking for rows where the length of the field is >40 characters after making the change. You'll need to figure out how to truncate those manually--so you're back some locks just on oversize ones--because if someone tries to update anything on that row it's going to reject it as too big now, at the point it goes to store the new version of the row. Hilarity ensues for the user.

VARCHAR is a terrible type that exists in PostgreSQL only to comply with its associated terrible part of the SQL standard. If you don't care about multi-database compatibility, consider storing your data as TEXT and add a constraint to limits its length. Constraints you can change around without this table lock/rewrite problem, and they can do more integrity checking than just the weak length check.

Postgres alter column problems and solutions, One can change the data type, or more commonly, only the size Reduce need to rebuild tables and indexes for certain ALTER TABLE . Increasing the length limit for a varchar or varbit column, or removing the limit  Changing the Column Size in Postgresql 9.1 version. During the Column chainging the varchar size to higher values, table re write is required during this lock will be held on table and user table not able access till table re-write is done. Table Name :- userdata Column Name:- acc_no. ALTER TABLE userdata ALTER COLUMN acc_no TYPE varchar(250);

In PostgreSQL 9.1 there is an easier way

http://www.postgresql.org/message-id/162867790801110710g3c686010qcdd852e721e7a559@mail.gmail.com

CREATE TABLE foog(a varchar(10));

ALTER TABLE foog ALTER COLUMN a TYPE varchar(30);

postgres=# \d foog

 Table "public.foog"
 Column |         Type          | Modifiers
--------+-----------------------+-----------
 a      | character varying(30) |

Re: alter varchar() column length?, Hello. CREATE TABLE foog(a varchar(10)); ALTER TABLE foog ALTER COLUMN a TYPE varchar(30);. postgres=# \d foog. Table "public.foog" > size of an existing column with varchar type, and it has been running for > more than 12 hours. > > > > We’re using: ALTER TABLE Property ALTER COLUMN "situs-number" TYPE > varchar(30); > it's not better to have the field beign type text and don't worry about length but just in check constraints if really necesary? >

Ok, I'm probably late to the party, BUT...

THERE'S NO NEED TO RESIZE THE COLUMN IN YOUR CASE!

Postgres, unlike some other databases, is smart enough to only use just enough space to fit the string (even using compression for longer strings), so even if your column is declared as VARCHAR(255) - if you store 40-character strings in the column, the space usage will be 40 bytes + 1 byte of overhead.

The storage requirement for a short string (up to 126 bytes) is 1 byte plus the actual string, which includes the space padding in the case of character. Longer strings have 4 bytes of overhead instead of 1. Long strings are compressed by the system automatically, so the physical requirement on disk might be less. Very long values are also stored in background tables so that they do not interfere with rapid access to shorter column values.

(http://www.postgresql.org/docs/9.0/interactive/datatype-character.html)

The size specification in VARCHAR is only used to check the size of the values which are inserted, it does not affect the disk layout. In fact, VARCHAR and TEXT fields are stored in the same way in Postgres.

How to increase the length of a character varying datatype in , This will extend the character varying column field size to 120. Remember to change TABLE_NAME to the relevant table name and  Changing the column size in postgresql. I currently have a table in postgresql named companies. companies has a column name whose length is 30, but now I want to reduce the length of column upto 20 characters, but unfortunately I have some entries in that column of upto length 25-30.

I was facing the same problem trying to truncate a VARCHAR from 32 to 8 and getting the ERROR: value too long for type character varying(8). I want to stay as close to SQL as possible because I'm using a self-made JPA-like structure that we might have to switch to different DBMS according to customer's choices (PostgreSQL being the default one). Hence, I don't want to use the trick of altering System tables.

I ended using the USING statement in the ALTER TABLE:

ALTER TABLE "MY_TABLE" ALTER COLUMN "MyColumn" TYPE varchar(8)
USING substr("MyColumn", 1, 8)

As @raylu noted, ALTER acquires an exclusive lock on the table so all other operations will be delayed until it completes.

Does changing the length limit (type-modifier) of varchar() result in a , However, increasing the length constraint on a varchar column still Reduce need to rebuild tables and indexes for certain ALTER TABLE . It indicates the legal length of this varchar column (whose full legal name is “character varying”, but everyone calls it varchar). In the case of Postgres, there is also 4 characters of overhead. So VARCHAR(32) shows up as 36 in the atttypmod column. Thus, if we want to change it to a VARCHAR(64), we add 4 to 64 and get a number of 68.

if you put the alter into a transaction the table should not be locked:

BEGIN;
  ALTER TABLE "public"."mytable" ALTER COLUMN "mycolumn" TYPE varchar(40);
COMMIT;

this worked for me blazing fast, few seconds on a table with more than 400k rows.

How to increase length of existing VARCHAR column in SQL Server, When we alter the length of a field, would this automatically also take up more space? i.e. would the size change? Reply  In most situation, you should use text or varchar, and varchar(n) if you want PostgreSQL to check for the length limit. PostgreSQL character type example. Let’s take a look at an example to see how the char, varchar, and text data types work. First, we create a new table for the demonstration.

Common mistakes in PostgreSQL, IMO its better to set the length if it might be indexed to let everyone know ahead of you are likely to be deleting data if you lower a limit, which is a tough pill to swallow). That's easier to change later than a varchar column. The notations varchar (n) and char (n) are aliases for character varying (n) and character (n) , respectively. character without length specifier is equivalent to character (1). If character varying is used without length specifier, the type accepts strings of any size. The latter is a PostgreSQL extension.

12.5 Limits on Table Column Count and Row Size, MySQL Differences from Standard SQL This section describes limits on the number of columns in tables and the size of individual rows. For example, a VARCHAR(255) CHARACTER SET utf8mb3 column takes two bytes to store the Reducing the column length to 65,533 or less permits the statement to succeed​. If you’re using SQL Server, and you want to use T-SQL to change the size of an existing column, this article can help. By “changing the size of an existing column”, I mean changing the data size. For example, say you have a varchar(255) but you want to increase its size to varchar(500). Here’s what you need to do in that case.

pg_field_size - Manual, G: Scroll to bottom; g g: Scroll to top; g h: Goto homepage; g s: Goto search Change language: pg_field_size() returns the internal storage size (in bytes) of the field number in PostgreSQL query result resource, returned by pg_query(), printed length: 6 characters storage length: -1 bytes field type: varchar column​  BUT, on the other hand, reducing the size of a variable-length field, even to something that will more than obviously work, is not a simple meta-data change because SQL Server doesn't know, prior to scanning all of the rows, that the newly requested size is valid.

Comments
  • Just to be clear: You know, that resizing will not make the table occupy less space?
  • even in my case?I mean the column will have a max size of 40 char (so octets) instead of 255?
  • If you say varchar(255) to PostgreSQL then it will not allocate 255 bytes for a value which real length is 40 bytes. It will allocate 40 bytes (plus some internal overhead). The only thing which will be changed by the ALTER TABLE` is the maximum number of bytes you can store in that column without getting an error from PG.
  • About the overhead A.H. mentioned: What is the overhead for varchar(n)?
  • Check out the answer here for an update dba.stackexchange.com/questions/189890/…
  • Thank you for the answer. I will check your link. I'm not worry about the manual size check because all my content has a max size of 40 chars. I need to read more about constraint on TEXT because I believed that VARCHAR was better to check lentgh :)
  • Change varchar length does not rewrite the table. It just check the constraint length against the entire table exactly as CHECK CONSTRAINT. If you increase length there is nothing to do, just next insert or updates will accept bigger length. If you decrease length and all rows pass the new smaller constraint, Pg doesn't take any further action besides to allow next inserts or updates to write just the new length.
  • @bigown, just to clarify, your statement is only true for PostgreSQL 9.2+, not the old ones.
  • The link is now dead.
  • For more information about how this works check out dba.stackexchange.com/questions/189890/…
  • Note that it works only because you're specifying a bigger size (30 > 10). If the size is smaller, you'll get the same error than I had.
  • Postgres should not throw an error if you lower the varchar size via an ALTER TABLE query unless one of more rows contains a value that exceeds the new size.