How to ALTER TABLE [X] ADD COLUMN [Y] [type] NOT NULL in clickhouse? - clickhouse

When creating a table in Clickhouse DB you can do :
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|EPHEMERAL|ALIAS expr1] [compression_codec] [TTL expr1],
name2 [type2] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|EPHEMERAL|ALIAS expr2] [compression_codec] [TTL expr2],
...
) ENGINE = engine
For adding a new column with ALTER
ADD COLUMN [IF NOT EXISTS] name [type] [default_expr] [codec] [AFTER name_after | FIRST]
It seems to not be working when for example I do
ALTER TABLE product_stock_history_analytics
ADD COLUMN IF NOT EXISTS product_id STRING NOT NULL;
Is there a way to set a new column to NOT NULL in a pre-existing table? Do I have to set a default value in order to achieve the desired effect ?

ClickHouse columns are not Nullable by default. At the moment the standard SQL NOT NULL is not supported in ALTER TABLE statements, but it's also not necessary.
ALTER TABLE product_stock_history_analytics ADD COLUMN IF NOT EXISTS product_id String;
will create a not nullable String column using the standard (non ANSI SQL) ClickHouse syntax.

Related

Is there any order of columns while creating Hive table that needs to be pairtitioned dynamically?

I am trying to load an RDBMS table into Hive. I need to partition the table dynamically based on a column data. I have the schema of the Greenplum table as below:
forecast_id:bigint
period_year:numeric(15,0)
period_num:numeric(15,0)
period_name:character varying(15)
drm_org:character varying(10)
ledger_id:bigint
currency_code:character varying(15)
source_system_name:character varying(30)
source_record_type:character varying(30)
xx_last_update_log_id:integer
xx_data_hash_code:character varying(32)
xx_data_hash_id:bigint
xx_pk_id:bigint
When I checked for the schema of the same table on Hive (which is usually replicated on Hive), I did describe extended tablename and got the below schema:
forecast_id bigint
period_year bigint
period_num bigint
period_name string
drm_org string
ledger_id bigint
currency_code string
source_record_type string
xx_last_update_log_id int
xx_data_hash_code string
xx_data_hash_id bigint
xx_pk_id bigint
source_system_name String
so I asked my lead why is the column: source_system_name given at the end in Hive table and I got an answer: "The columns that are used to partition the hive table dynamically, comes at the end of the table"
Is it true that the columns on which the hive table is dynamically partitioned should come at the end of the schema ?
The order of the columns matter when you are dynamic partition in Hive. You can find more details here. From the documentation
In INSERT ... SELECT ... queries, the dynamic partition columns must
be specified last among the columns in the SELECT statement and in the
same order in which they appear in the PARTITION() clause.

How to alter column (Changing datasize), if table was created with partitions?

I have created table with a partition:
CREATE TABLE edw_src.pageviewlog_dev
(
accessurl character varying(1000),
msisdn character varying(1000),
customerid integer
)
WITH (
OIDS=FALSE
)
DISTRIBUTED BY (msisdn)
PARTITION BY RANGE(customerid)
(
PARTITION customerid START (0) END (200)
)
Now I want to change the datasize of accessurl from 1000 to 3000.I am not able to change the datasize,Whenever I am trying I am getting the error.
ERROR: "pageviewlog_dev_1_prt_customerid" is a member of a partitioning configurationHINT: Perform the operation on the master table.
I am able to change If I change the datatype from pg_attribute.If there any other way to change the datasize of existing column other than pg_attribute
I have found the Solution for the same .Sorry for the replying late .Below is the way to do ,whenever we face this kind of problem in "Post grel and greenplum"
UPDATE pg_attribute SET atttypmod = 300+4
WHERE attrelid = 'edw_src.ivs_hourly_applog_events'::regclass
AND attname = 'adtransactionid';
Greenplum isn't Postgresql so please don't confuse people by asking a Greenplum question with PostgreSQL in the title.
Don't modify catalog objects like pg_attribute. That will cause lots of problems and isn't supported.
The Admin Guide has the syntax for changing column datatypes and this is all you need to do:
ALTER TABLE edw_src.pageviewlog_dev
ALTER COLUMN accessurl TYPE character varying(3000);
Here is the working example with your table:
CREATE SCHEMA edw_src;
CREATE TABLE edw_src.pageviewlog_dev
(
accessurl character varying(1000),
msisdn character varying(1000),
customerid integer
)
WITH (
OIDS=FALSE
)
DISTRIBUTED BY (msisdn)
PARTITION BY RANGE(customerid)
(
PARTITION customerid START (0) END (200)
);
Output:
NOTICE: CREATE TABLE will create partition "pageviewlog_dev_1_prt_customerid" for table "pageviewlog_dev"
Query returned successfully with no result in 47 ms.
And now alter the table:
ALTER TABLE edw_src.pageviewlog_dev
ALTER COLUMN accessurl TYPE character varying(3000);
Output:
Query returned successfully with no result in 62 ms.
Proof in psql:
\d edw_src.pageviewlog_dev
Table "edw_src.pageviewlog_dev"
Column | Type | Modifiers
------------+-------------------------+-----------
accessurl | character varying(3000) |
msisdn | character varying(1000) |
customerid | integer |
Number of child tables: 1 (Use \d+ to list them.)
Distributed by: (msisdn)
If you are unable to alter the table it is probably because the catalog is corrupted after you updated pg_attribute directly. You can try dropping the table and recreating it or you can open a support ticket to have them attempt to correct the catalog corruption.

date Not null , error ora_01758

why I am getting this error ?
In the table DDL I only have 2 columns , id (number) and name (varchar)
ALTER TABLE mytable ADD SUSPEND date NOT NULL
ORA-01758: table must be empty to add mandatory (NOT NULL) column
ORA-06512: at line 7
ORA-01758: table must be empty to add mandatory (NOT NULL) column ORA-06512: at line 7
And is your table empty? I think not.
There's probably a way around this involving adding the column as nullable, then populating every row with a non-NULL value, the altering the column to be not null.
Alternatively, since the problem is that these current rows will be given NULL as a default value, and the column is not allowed to be NULL, you can also get around it with a default value. From the Oracle docs:
However, a column with a NOT NULL constraint can be added to an existing table if you give a default value; otherwise, an exception is thrown when the ALTER TABLE statement is executed.
Here is a fiddle, how you could do it
Would a date in the future be acceptable as a temporary default? If so, this would work:
ALTER TABLE MYTABLE ADD (SUSPEND_DATE DATE DEFAULT(TO_DATE('21000101', 'YYYYMMDD'))
CONSTRAINT SUSPEND_DATE_NOT_NULL NOT NULL);
If table already contain the records then table won't allowes to add "Not null" column.
If you need same then set default value for the column or truncate the table then try.

Can not set Sorted ASC Index on primary key field in oracle

When I try to add a sorted ASC index on the field MyId the oracle sql developer tool says:
Index MyIdSortedIndex is defined identically to constraint PK_MyTable
CREATE TABLE MyTable
( "MyId" NVARCHAR2(50),
"DESCRIPTION" NVARCHAR2(200),
CONSTRAINT "PK_MyTable" PRIMARY KEY ("MyId")
)
How can I set a sorted ASC index on my tables Primary Key MyId in Oracle ?
It is telling you that you don't need a new index, because you already have an index called "PK_MyTable" on "MyId" in ascending order. When you add a primary key constraint to a table Oracle automatically adds an index of the same name to help enforce it, indexing the columns of the constraint in ascending order (since ascending is the default direction).
If you don't want to use the index Oracle created automatically you can do this:
CREATE TABLE MyTable
( "MyId" NVARCHAR2(50),
"DESCRIPTION" NVARCHAR2(200),
);
CREATE INDEX MyIdSortedIndex ON MyTable ("MyId" ASC);
ALTER TABLE MyTable Add CONSTRAINT "PK_MyTable" PRIMARY KEY ("MyId");
Since your index already exists when the primary key is added Oracle will use that instead of creating its own.

How to set default value for column of new created table from select statement in 11g

I create a table in Oracle 11g with the default value for one of the columns. Syntax is:
create table xyz(emp number,ename varchar2(100),salary number default 0);
This created successfully. For some reasons I need to create another table with same old table structure and data. So I created a new table with name abc as
create table abc as select * from xyz.
Here "abc" created successfully with same structure and data as old table xyz. But for the column "salary" in old table "xyz" default value was set to "0". But in the newly created table "abc" the default value is not set.
This is all in Oracle 11g. Please tell me the reason why the default value was not set and how we can set this using select statement.
You can specify the constraints and defaults in a CREATE TABLE AS SELECT, but the syntax is as follows
create table t1 (id number default 1 not null);
insert into t1 (id) values (2);
create table t2 (id default 1 not null)
as select * from t1;
That is, it won't inherit the constraints from the source table/select. Only the data type (length/precision/scale) is determined by the select.
The reason is that CTAS (Create table as select) does not copy any metadata from the source to the target table, namely
no primary key
no foreign keys
no grants
no indexes
...
To achieve what you want, I'd either
use dbms_metadata.get_ddl to get the complete table structure, replace the table name with the new name, execute this statement, and do an INSERT afterward to copy the data
or keep using CTAS, extract the not null constraints for the source table from user_constraints and add them to the target table afterwards
You will need to alter table abc modify (salary default 0);
new table inherits only "not null" constraint and no other constraint.
Thus you can alter the table after creating it with "create table as" command
or you can define all constraint that you need by following the
create table t1 (id number default 1 not null);
insert into t1 (id) values (2);
create table t2 as select * from t1;
This will create table t2 with not null constraint.
But for some other constraint except "not null" you should use the following syntax
create table t1 (id number default 1 unique);
insert into t1 (id) values (2);
create table t2 (id default 1 unique)
as select * from t1;

Resources