Explain behavior of ADD COLUMN xxx varchar(255) DEFAULT FALSE; - sql

I've faced a strange SQL query like
ALTER TABLE some_db.some_table
ADD COLUMN metadata_labels varchar(255) DEFAULT FALSE;
I'd expect it to fail because I'm adding a Boolean default value for the varchar column. But at least at Postgres, it is executed successfully and I see the following:
Looks like some weird type coercion to me
Why this query does not fail due to a type mismatch?

Postgres does implicit type conversion. It's documented here:
https://www.postgresql.org/docs/current/typeconv.html
So your SQL Statement is perfectly valid, as false::bool can be perfectly converted into 'bool'::text.

There is an assignment cast from boolean to text, so it must be that DEFAULT values are acceptable if there is an assignment cast to the target data type.
Looking at the adbin column in the pg_attrdef catalog, I can see the the actual default expression that is stored is
"varchar"(text(FALSE), 259, FALSE)
where the outer function is the conversion to varchar(255).

Related

Cannot create stored procedure to insert data: type mismatch for serial column

CREATE TABLE test ( id serial primary key, name text );
CREATE OR REPLACE PROCEDURE test_insert_data( "name" text)
LANGUAGE SQL
AS $$
INSERT INTO public.test values("name")
$$;
Error & Hint:
column "id" is of type integer but expression is of type character varying
LINE 4: INSERT INTO public.test values("name")
^
HINT: You will need to rewrite or cast the expression.
I followed this tutorial: https://www.enterprisedb.com/postgres-tutorials/10-examples-postgresql-stored-procedures.
Obviously, I don't need to attach the column id for inserting.
There is no quoting issue, like comments would suggest.
And the linked tutorial is not incorrect. (But still bad advise.)
The missing target column list is the problem.
This would work:
CREATE OR REPLACE PROCEDURE test_insert_data("name" text)
LANGUAGE sql AS
$proc$
INSERT INTO public.test(name) -- !! target column list !!
VALUES ("name");
$proc$;
(For the record, since "name" is a valid identifier, all double quotes are just noise and can (should) be omitted.)
If you don't specify the target column(s), Postgres starts to fill in columns from left to right, starting with id in your case - which triggers the reported error message.
(The linked tutorial also provides an ID value, so it does not raise the same exception.)
Even if it would work without explicit target column list, it's typically still advisable to add one for persisted INSERT commands. Else, later modifications to the table structure can break your code silently. With any bad luck in a way you'll only notice much later - like filling in the wrong columns without raising an error.
See:
SQL INSERT without specifying columns. What happens?
Inserting into Postgres within a trigger function
Aside: I would never use "name" as column name. Not even in a generic tutorial. That's not helpful. Any column name is a "name". Use meaningful identifiers instead.

Is it possible to set current time as default value in a column with data type time in PostgreSQL?

I was trying to create a column with data type time and trying to set the default value as the current time using HeidiSql. Below is the altered code.
ALTER TABLE "user"
ADD "user" TIME NULL DEFAULT CURRENT_TIME();
But it output an error as below.
syntax error at or near ")"
LINE 2: ADD "created_time" TIME NULL DEFAULT CURRENT_TIME()
Any idea about my mess?
This works fine:
create table users (user_id serial);
ALTER TABLE users
ADD create_Time TIME NULL DEFAULT CURRENT_TIME;
You don't need parentheses around CURRENT_TIME.
Some other things:
The error in your question is not generated by the SQL in the question; the column names are different.
It is highly unusual to put the time in without the date. Are you sure you don't want now()/CURRENT_TIMESTAMP?
Don't use escapes around names. They are just cumbersome to read and clunky to write.

Cannot find data type user defined data type

I am getting Column, parameter, or variable #1: Cannot find data type dbo.SUBSYSTEM_CODE. error on user datatype.
CREATE TABLE #PREDEFINED_SUBSYSTEMS
(
SUBSYSTEM_CODE dbo.SUBSYSTEM_CODE PRIMARY KEY
);
After I checked user defined datatype I can see. I am using SQL 2012 and also I applied set compatibility_level = 110 on datatype still didn't work.
What other alternatives I have to fix this?
Probably you need to define type inside tempdb:
USE tempdb;
GO
CREATE TYPE dbo.SUBSYSTEM_CODE ...
Our problem was with schema
we moved table type from dbo to hub schema, and after that we got this error,
you need to use schema before table name for it to work
and dont forget about dynamic sqls which you might have

How to add a 'Boolean' column to ms-access via SQL in vb.net

I am trying to add a Boolean column to a table in ms-access using SQL. I am using JET, here are the the SQL queries I have tried.
Query = "ALTER TABLE tabDatafiveMinutely ADD CON0001 BOOLEAN DEFAULT FALSE"
Query = "ALTER TABLE tabDatafiveMinutely ADD CON0001 BOOLEAN"
The error I am getting is 'Syntax error in field definition'
Thanks for your help
EDIT:
I would now like to make the default null rather than false. I have tried default null and this still gives me false, can anyone help with this?
RESULT:
An ms-access database can only take true and false and not null. Therefore I have decided to use and integer instead.
The equivalent SQL type of a Yes/No column is BIT
ALTER TABLE tabDatafiveMinutely
ADD COLUMN CON0001 BIT DEFAULT 0 NOT NULL
Microsoft's documentation says
Note
The DEFAULT statement can be executed only through the Jet OLE DB provider and ADO. It will return an error message if used through the Access SQL View user interface.
As #Pere points out, Jet Engine (Access' query engine) does not apply the DEFAULT value to existing rows. You must run an UPDATE statement after altering the table.
UPDATE tabDatafiveMinutely SET CON0001 = 0 WHERE CON0001 IS NULL
You should use the BIT datatype rather than BOOLEAN.
Access data types.
I'm not sure where you're reading the syntax from, but you need a better source.
ALTER TABLE tabDatafiveMinutely
ADD COLUMN CON0001 <datatype>
For a Boolean type, I think you'll need to pick from BIT, INTEGER, or CHAR(1). It's application-dependent. For example, legacy systems often use 't' and 'f' in a CHAR(1) column.

how to create calculated field in mysql?

i have a table like below:
create table info (username varchar(30),otherinfo varchar(100));
now i want to alter this table to have new field and this field has to have default value as
md5(username)
something like below:
alter table info add NewField varchar(100) default md5(username);
how to do so?
Thanks for your help
Per MySQL docs (emphasis added) you cannot have an expression in a default value:
10.1.4. Data Type Default Values
The DEFAULT value clause in a data
type specification indicates a default
value for a column. With one
exception, the default value must be a
constant; it cannot be a function or
an expression. This means, for
example, that you cannot set the
default for a date column to be the
value of a function such as NOW() or
CURRENT_DATE. The exception is that
you can specify CURRENT_TIMESTAMP as
the default for a TIMESTAMP column.
I've tested that the following trigger works for your intent:
CREATE TRIGGER MyTriggerName
BEFORE INSERT ON info
FOR EACH ROW
SET NEW.NewField = md5(NEW.username);
You should write a Trigger to achieve this functionality, given that MySQL has a md5 function built in or you are capable to either write or find a md5 algorithm for MySQL :)
Take a look # http://dev.mysql.com/doc/refman/5.0/en/triggers.html
for the md5 function take a look here
http://dev.mysql.com/doc/refman/5.0/en/encryption-functions.html
Also, you should know that MD5 is not a secure algorithm anymore.