Alter column default value is not working in postgres - postgresql

I tried to update column's default value with the below queries in postgres. But seems its not working. May be I am missing something. Could you help?
ALTER TABLE tableName ADD COLUMN newColumn INTEGER DEFAULT 0;
ALTER TABLE tableName ALTER COLUMN newColumn DROP DEFAULT;
or
ALTER TABLE tableName ALTER COLUMN newColumn SET DEFAULT NULL;
SELECT * FROM tableName;
Here I still find 0.

The change only applies to new records. After the modification you have to heal all the previous data with a migration like this:
UPDATE tableName SET newColumn = NULL WHERE newColumn = 0

Related

alter varchar field to super returns " ERROR: target data type "super" is not supported"

I have a varchar field in super/json format:
select detail
from mytable
limit 1;
{"child_category":"organize","gallery_id":"123456","detail":"[\"789876"]"}
I know that detail is currently varchar because inspecting the table in my client shows it as varchar(32768)
I want alter this field to be super:
ALTER TABLE mytable ALTER COLUMN detail TYPE super;
Returns:
[0A000] ERROR: target data type "super" is not supported
How can I cast the detail field as a super field?
From the doc https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html
with alter column you can only change varchar size.
As a suggestion, you can add new temp column, drop first, and rename temp column
alter table mytable add column temp_super super;
update mytable set temp_super = json_parse(detail);
alter table mytable drop column detail;
alter table mytable rename column temp_super to detail;

I'm getting column "my_column" contains null values' when adding a composite primary key

Is it not supposed to delete null values before altering the table? I'm confused...
My query looks roughly like this:
BEGIN;
DELETE FROM my_table
WHERE my_column IS NULL;
ALTER TABLE my_table DROP CONSTRAINT my_table_pk;
ALTER TABLE my_table ADD PRIMARY KEY (id, my_column);
-- this is to repopulate the data afterwards
INSERT INTO my_table (name, other_table_id, my_column)
SELECT
ya.name,
ot.id,
my_column
FROM other_table ot
LEFT JOIN yet_another ya
ON ya.id = ot."fileId"
WHERE NOT EXISTS (
SELECT
1
FROM my_table mt
WHERE ot.id = mt.other_table_id AND ot.my_column = mt.my_column
) AND my_column IS NOT NULL;
COMMIT;
sorry for naming
There are two possible explanations:
A concurrent session inserted a new row with a NULL value between the start of the DELETE and the start of ALTER TABLE.
To avoid that, lock the table in SHARE mode before you DELETE.
There is a row where id has a NULL value.

Unable to change field type to not null with default value

I have a simple SQL statement, which looks like so:
alter table my_table alter column my_field set data type numeric(12,4) not null default 0;
But I get an error message, that points to not. What is wrong with that?
Use separate ALTER COLUMN clauses for the type, null behavior, and default value:
ALTER TABLE my_table
ALTER COLUMN my_field TYPE numeric(12,4),
ALTER COLUMN my_field SET DEFAULT 0,
ALTER COLUMN my_field SET NOT NULL;

Changing primary key int type to serial

Is there a way to change existing primary key type from int to serial without dropping the table? I already have a lot of data in the table and I don't want to delete it.
Converting an int to a serial more or less only means adding a sequence default to the value, so to make it a serial;
Pick a starting value for the serial, greater than any existing value in the table
SELECT MAX(id)+1 FROM mytable
Create a sequence for the serial (tablename_columnname_seq is a good name)
CREATE SEQUENCE test_id_seq MINVALUE 3 (assuming you want to start at 3)
Alter the default of the column to use the sequence
ALTER TABLE test ALTER id SET DEFAULT nextval('test_id_seq')
Alter the sequence to be owned by the table/column;
ALTER SEQUENCE test_id_seq OWNED BY test.id
A very simple SQLfiddle demo.
And as always, make a habit of running a full backup before running altering SQL queries from random people on the Internet ;-)
-- temp schema for testing
-- ----------------------------
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;
CREATE TABLE bagger
( id INTEGER NOT NULL PRIMARY KEY
, tralala varchar
);
INSERT INTO bagger(id,tralala)
SELECT gs, 'zzz_' || gs::text
FROM generate_series(1,100) gs
;
DELETE FROM bagger WHERE random() <0.9;
-- SELECT * FROM bagger;
-- CREATE A sequence and tie it to bagger.id
-- -------------------------------------------
CREATE SEQUENCE bagger_id_seq;
ALTER TABLE bagger
ALTER COLUMN id SET NOT NULL
, ALTER COLUMN id SET DEFAULT nextval('player_id_seq')
;
ALTER SEQUENCE bagger_id_seq
OWNED BY bagger.id
;
SELECT setval('bagger_id_seq', MAX(ba.id))
FROM bagger ba
;
-- Check the result
-- ------------------
SELECT * FROM bagger;
\d bagger
\d bagger_id_seq

Change column type and set not null

How do you change the column type and also set that column to not null together?
I am trying:
ALTER TABLE mytable ALTER COLUMN col TYPE character varying(15) SET NOT NULL
This returns an error.
What is the right syntax?
This should be correct:
ALTER TABLE mytable
ALTER COLUMN col TYPE character varying(15),
ALTER COLUMN col SET NOT NULL
Also, if you want to REMOVE NOT NULL constrain in postgresql:
ALTER TABLE mytable
ALTER COLUMN email DROP NOT NULL;