PostgreSQL: changing a column of enum type - postgresql

This is the definition of the enumerated type:
CREATE TYPE khstate AS ENUM ('none', 'form', 'test', 'finished');
Now, in a database table I have a row with columns 'id' (type SERIAL) and 'state' (type khstate). The value of the 'id' column is 100004, and the value of the 'state' column is 'none'. How do I change it to, say, 'form'? The table definition is as follows.
CREATE TABLE IF NOT EXISTS khs (
id SERIAL UNIQUE,
state khstate DEFAULT 'none',
PRIMARY KEY (id)
);
I have tried queries such as
UPDATE tablename SET state = 'form' WHERE id = 100004;
ERROR: invalid input value for enum khstate: "form"
UPDATE tablename SET state = 'form'::khstate WHERE id = 100004;
ERROR: invalid input value for enum khstate: "form"
but without success. I am using the latest BitNami LAPPstack, so the version of PostgreSQL is 9.1.1.
I havent added any RULE or TRIGGER constraints, nor have I used transactions explicitly.
I tried to google for a solution, but all I could find were questions how to change the enum type itself, rather than the value of a column.

The error message indicates that 'form' is not a registered value for your enum type khstate.
I also notice that in your question you create a table named khs, but the UPDATE example uses tablename instead.
There may be a mixup of tables, schemas or databases. Diagnose your problem by running this query in the same session that gives you the error message:
SELECT enum_range(NULL::khstate)
Do you see form in the array of values? I expect, you don't.
More about enum support functions in the manual.

Related

How can generic functions can be used for computed fields in hasura?

I've a logs table, which is it contains all the actions (updated, created) taken by operators (admin users).
On this table 2 of these columns (indexed as hash) target_entity and target_id Which respectively stores
table name: table name of the action taken on.
record id added or updated record's id in the target table.
So, what I am trying to achieve;
I would like to add a computed field named eg:logs which depends on a function;
FUNCTION public."fetchLogs"(
referenceId integer,
referenceName TEXT
)
First parameter is the current table's primary key.
I'm not sure if I can automatically send primary key as first argument
So probably it should be something like table_row table
Second parameter is a static value which is table's name, planning to statically pass as argument.
This function returns a JSON object;
RETURNS json LANGUAGE plpgsql STABLE
AS $function$
It should return log records related to this record.
At this point I have 2 things needs to be tackled with;
Since the first parameter is the reference (primary) key, I don't know If I can just use primary key as an argument. I'm guessing I need to use as table_row (anytable if that's a thing) then table_row.id
In the Hasura console, Add Computed Field > Function Name selector does not list this function, guessing because it doesn't explicitly indicated in the function which table is this action for.
Answers I'm looking for if this is achievable or is there a better practice for this kind of things?
Maybe I need a encapsulating function for each table needs this computed column. But I'm not sure is it possible or how can be done.
P.S. In case if you are wondering all primary keys are same type and name yes. All tables (will be using this computed column) has a primary key named as id and type is integer.

Postegresql: update all rows in table setting STRING column to new UUID?

I am trying to do what I see in this question:
UPDATE in PostgreSQL generates same UUID
I have a car table with a STRING column named uuid. uuid is unique, so each row needs a different value set.
I want to set a new uuid on all car rows, and so I tried this:
UPDATE table_name
SET uuid = uuid_generate_v4();
However, when I run that I get this ERROR:
[42883] ERROR: function uuid_generate_v4() does not exist Hint: No function matches the given name and argument types. You might need to add explicit type casts.
So, I thought the uuid_generate_v4() function was something available within Postgres but I am obviously wrong.
How can I fix the error? How can I declare I function I can call in the update call so that a new unique uuid is generate and set in each row into uuid?

How change a column type in Firebird 3

Since Firebird 3, I can't modify a column type.
Before I use this kind of update:
update RDB$RELATION_FIELDS set
RDB$FIELD_SOURCE = 'MYTEXT'
where (RDB$FIELD_NAME = 'JXML') and
(RDB$RELATION_NAME = 'XMLTABLE')
because I get ISC error 335545030 ("UPDATE operation is not allowed for system table RDB$RELATION_FIELDS").
Maybe there is another way in Firebird 3?
Firebird 3 no longer allows direct updates to the system tables, as that was a way to potentially corrupt a database. See also System Tables are Now Read-only in the release notes. You will need to use DDL statements to do the modification.
It looks like you want to change the data type of a column to a domain. You will need to use alter table ... alter column ... for that. Specifically you will need to do:
alter table XMLTABLE
alter column JXML type MYTEXT;
This does come with some restrictions:
Changing the Data Type of a Column: the TYPE Keyword
The keyword TYPE changes the data type of an existing column to
another, allowable type. A type change that might result in data loss
will be disallowed. As an example, the number of characters in the new
type for a CHAR or VARCHAR column cannot be smaller than the existing
specification for it.
If the column was declared as an array, no change to its type or its
number of dimensions is permitted.
The data type of a column that is involved in a foreign key, primary
key or unique constraint cannot be changed at all.
This statement has been available since before Firebird 1 (InterBase 6.0).
Firebird 2.5 manual, chapter Data Definition (DDL) Statement, section TABLE:
ALTER TABLE tabname ALTER COLUMN colname TYPE typename

Upgrading enum type column to varchar in postgresql

I have an enum type column in my table . I have now decided to make it a varchar type and put some constraint.
Q1) Which is a good practice : to have enums or to put constarint on the column.
Q2) How to change my enum type column to varchar. Just opposite to this question question .
I tried using this:
ALTER TABLE tablename ALTER COLUMN columnname TYPE VARCHAR
But this gives me the error : No operator matches the given name and argument type(s). You might need to add explicit type casts.
This is the table definition:
CREATE TABLE tablename (
id1 TEXT NOT NULL,
id2 VARCHAR(100) NOT NULL,
enum_field table_enum,
modified_on TIMESTAMP NOT NULL DEFAULT NOW(),
modified_by VARCHAR(100),
PRIMARY key (id1, id2)
);
For future reference: I had the similar issue with altering enum type and I got the same error message as the one above. In my case, the issue was caused by having a partial index that referenced a column that was using that enum type.
As for best practice, it is best if you define a separate table of possible values, and make your column a foreign key to this table. This has the following benefits:
The new table can not only have the specific key as a type, it can have additional columns with details such as a friendly name, meaning of the type or more information
Changing the possible values is a matter of manipulating data rows (INSERT,UPDATE or DELETE) which is more accessible and manageable than changing constraints or enum values.

How to create a enum field with default value?

types = { # add your custom types here
'attendance': ('Notconfirmed','Coming', 'Notcoming', 'Maycome',),
}
CREATE TYPE attendance AS ENUM types;
The above query creates enum type attendance with enumlabels mentioned in types. How to create a type with default label? In this case the I want to create attendance type with default value Notconfirmed.
I was trying the same as you, and I got answer in stackoverflow only, It is possible to create ENUM with default value. Here is what I got for you.
CREATE TYPE status AS ENUM ('Notconfirmed','Coming', 'Notcoming', 'Maycome');
CREATE TABLE t (
id serial,
s status default 'Notconfirmed' -- <==== default value
);
INSERT INTO t(id) VALUES (default) RETURNING *;
This worked for me like a charm.
In addition to Sudarshan's words...
In case someone needs an example in different schema:
CREATE TABLE schema_name.table_name ( --
id serial,
s schema_name.type_name default 'Notconfirmed'::schema_name.type_name
);
I am not sure why we need to have below query in our table. I have tried without this line still works.
INSERT INTO t(id) VALUES (default) RETURNING *;