What do "constant", "expression", and "sequence" represent in a DEFAULT clause? - postgresql

Currently creating my PostgreSQL tables through Postico, and I came across this field for when creating new columns. It is called DEFAULT and its default value is no default. You can select constant, expression, and sequence as options, though.
What exactly do these mean?

The manual on CREATE TABLE:
DEFAULT default_expr
The DEFAULT clause assigns a default data value for the column whose column definition it appears within. The value is any
variable-free expression (subqueries and cross-references to other
columns in the current table are not allowed). The data type of the
default expression must match the data type of the column.
The default expression will be used in any insert operation that does
not specify a value for the column. If there is no default for a
column, then the default is null.
constant and expression should be clear now. sequence is a special feature to make it a serial column:
Creating a PostgreSQL sequence to a field (which is not the ID of the record)
More details on the page #mu provided:
https://www.postgresql.org/docs/current/static/ddl.html

Related

cannot use column reference in DEFAULT expression in postgresql

CREATE temp TABLE demo1(
col_a int,
col_b int DEFAULT (col_a)
);
PostgreSQL have generated columns, triggers. But why cannot use column reference in DEFAULT expression.
since the manual ddl-default page mention:
The default value can be an expression, which will be evaluated
whenever the default value is inserted (not when the table is
created). A common example is for a timestamp column to have a default
of CURRENT_TIMESTAMP, so that it gets set to the time of row
insertion.
Obviously, column references is value expression.
https://www.postgresql.org/docs/current/sql-expressions.html#SQL-EXPRESSIONS-COLUMN-REFS
A value expression is one of the following:
* A constant or literal value
The documentation states:
DEFAULT default_expr
The DEFAULT clause assigns a default data value for the column whose column definition it appears within. The value is any variable-free expression (in particular, cross-references to other columns in the current table are not allowed). Subqueries are not allowed either. The data type of the default expression must match the data type of the column.
So the restriction is clearly documented.
But it is fairly easy to see that it would pose problems to allow a column reference in a DEFAULT expression: For one, the value specified in the INSERT statement could be overridden by BEFORE INSERT triggers. In that case, should the value before or after the trigger execution be used? Also, what if the DEFAULT for column a references column b and vice versa? There may be other difficulties that I didn't think of.

How can I enter empty records into a postgres table

I have a table in postgres that basically just serves to collect multiple object in a bag. Think like a shopping cart. It only has a uuid that is generated automatically.
How can I insert an empty record into such a table?
INSERT INTO cart() values();
Doesn't work
From the fine INSERT manual:
This section covers parameters that may be used when only inserting new rows. [...]
DEFAULT VALUES
All columns will be filled with their default values, as if DEFAULT were explicitly specified for each column. (An OVERRIDING clause is not permitted in this form.)
[...]
DEFAULT
The corresponding column will be filled with its default value. An identity column will be filled with a new value generated by the associated sequence. For a generated column, specifying this is permitted but merely specifies the normal behavior of computing the column from its generation expression.
So you can use DEFAULT as a value to explicitly use the column's default value:
INSERT INTO cart(your_uuid_column) values(default);
or you can say:
INSERT INTO cart default values;
to use defaults for all the columns.

Why can't Update set change data type Postgres

I have a CSV which contains numbers stored as strings example: 1,200 when loading in these are stored as VARCHAR
I'd like to store these as integers. So tested the below;
update data
set stringy_number = replace (stringy_number,',','')::integer
This runs and removes the , from the number but doesn't change the character type. I then tried;
update data
set stringy_number::integer = replace (stringy_number,',','')::integer
Which threw a syntax error. At which point I switched to the below which worked, but I don't understand why I can't set a data type along with an update
alter table data
alter column stringy_number type integer using replace(stringy_number,',','')::integer;
update works on the values. You can cast from a datatype to another, but the result is still cast to to underlying column type.
--> you can save a "number" in a text column because it is easy to cast a number to a text. You cannot save a letter in a numerical column because the cast cannot (easily) be done.
alter column works on the entire column type. When changing the type, you can supply a custom transformation method allowing the old data to match the new data type.

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

db2- Set the default value with the next sequence value

How I can set the default value for an attribute to be the next value of a squeuence
I tried the following :
ALTER TABLE Person ADD COLUMN ccn VARCHAR(254) default (next value for KAP.CCN_SEQ );
And this cause a syntax error
Could you please advice is this doable and if yes what is the correct syntax ?
Thanks in advance.
Your column is of type Varchar - I assume this is a bit unusual for a sequence number. You also need to determine whether you want to create an Identity or a Sequence. For difference between the two and how to create each see: ID vs Sequence in DB2. Some of the points to note are (as quoted from the ref.):
An identity column has the following characteristics:
• An identity column can be defined as part of a table only when the table is created. Once a table is created, you cannot alter it to add an identity column. (However, existing identity column characteristics may be altered.)
• An identity column automatically generates values for a single table.
• When an identity column is defined as GENERATED ALWAYS, the values used are always generated by the database manager. Applications are not allowed to provide their own values during the modification of the contents of the table.
A sequence object has the following characteristics:
• A sequence object is a database object that is not tied to any one table.
• A sequence object generates sequential values that can be used in any SQL statement.
• Since a sequence object can be used by any application, there are two expressions used to control the retrieval of the next value in the specified sequence and the value generated previous to the statement being executed. The PREVVAL expression returns the most recently generated value for the specified sequence for a previous statement within the current session. The NEXTVAL expression returns the next value for the specified sequence. The use of these expressions allows the same value to be used across several SQL statements within several tables.
To create a sequence (example):
CREATE SEQUENCE ccn
START WITH 1
INCREMENT BY 1
NOMAXVALUE
NOCYCLE
CACHE 24