mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-18 03:23:37 +08:00
Fix bug with alter table add/drop column if exists
Previously, an ALTER TABLE ADD COLUMN IF NOT EXISTS on a hypertable caused an error if the column already did exist. The reversed problem with DROP COLUMN is also fixed. Resolves issue #42.
This commit is contained in:
parent
f960c24cd4
commit
13d3acbcfa
3
Makefile
3
Makefile
@ -35,7 +35,8 @@ SRCS = \
|
||||
src/process_utility.c \
|
||||
src/sort_transform.c \
|
||||
src/insert_chunk_state.c \
|
||||
src/insert_statement_state.c
|
||||
src/insert_statement_state.c \
|
||||
src/ddl_utils.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
DEPS = $(SRCS:.c=.d)
|
||||
|
9
sql/common/ddl_utils.sql
Normal file
9
sql/common/ddl_utils.sql
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
CREATE OR REPLACE FUNCTION ddl_is_add_column(pg_ddl_command)
|
||||
RETURNS bool IMMUTABLE STRICT
|
||||
AS '$libdir/timescaledb' LANGUAGE C;
|
||||
|
||||
CREATE OR REPLACE FUNCTION ddl_is_drop_column(pg_ddl_command)
|
||||
RETURNS bool IMMUTABLE STRICT
|
||||
AS '$libdir/timescaledb' LANGUAGE C;
|
||||
|
@ -47,3 +47,4 @@ sql/main/ddl.sql
|
||||
sql/main/ddl_triggers.sql
|
||||
sql/main/setup_main.sql
|
||||
sql/common/permissions.sql
|
||||
sql/common/ddl_utils.sql
|
||||
|
@ -158,28 +158,34 @@ BEGIN
|
||||
found_action = FALSE;
|
||||
|
||||
--was a column added?
|
||||
FOR att_row IN
|
||||
SELECT *
|
||||
FROM pg_attribute att
|
||||
WHERE attrelid = info.objid AND
|
||||
|
||||
IF ddl_is_add_column(info.command) THEN
|
||||
FOR att_row IN
|
||||
SELECT *
|
||||
FROM pg_attribute att
|
||||
WHERE attrelid = info.objid AND
|
||||
attnum > 0 AND
|
||||
NOT attisdropped AND
|
||||
att.attnum NOT IN (SELECT c.attnum FROM _timescaledb_catalog.hypertable_column c WHERE hypertable_id = hypertable_row.id)
|
||||
LOOP
|
||||
PERFORM _timescaledb_internal.create_column_from_attribute(hypertable_row.id, att_row);
|
||||
found_action = TRUE;
|
||||
END LOOP;
|
||||
|
||||
found_action = TRUE;
|
||||
END IF;
|
||||
|
||||
--was a column deleted
|
||||
FOR rec IN
|
||||
SELECT name
|
||||
FROM _timescaledb_catalog.hypertable_column c
|
||||
INNER JOIN pg_attribute att ON (attrelid = info.objid AND att.attnum = c.attnum AND attisdropped) --do not match on att.attname here. it gets mangled
|
||||
WHERE hypertable_id = hypertable_row.id
|
||||
LOOP
|
||||
PERFORM _timescaledb_meta_api.drop_column(hypertable_row.id, rec.name);
|
||||
found_action = TRUE;
|
||||
END LOOP;
|
||||
IF ddl_is_drop_column(info.command) THEN
|
||||
FOR rec IN
|
||||
SELECT name
|
||||
FROM _timescaledb_catalog.hypertable_column c
|
||||
INNER JOIN pg_attribute att ON (attrelid = info.objid AND att.attnum = c.attnum AND attisdropped) --do not match on att.attname here. it gets mangled
|
||||
WHERE hypertable_id = hypertable_row.id
|
||||
LOOP
|
||||
PERFORM _timescaledb_meta_api.drop_column(hypertable_row.id, rec.name);
|
||||
END LOOP;
|
||||
found_action = TRUE;
|
||||
END IF;
|
||||
|
||||
--was a column renamed
|
||||
FOR rec IN
|
||||
|
62
src/ddl_utils.c
Normal file
62
src/ddl_utils.c
Normal file
@ -0,0 +1,62 @@
|
||||
#include <postgres.h>
|
||||
#include <tcop/deparse_utility.h>
|
||||
|
||||
enum ddl_cmd_type
|
||||
{
|
||||
DDL_DROP_COLUMN, DDL_ADD_COLUMN, DDL_OTHER
|
||||
};
|
||||
|
||||
static enum ddl_cmd_type
|
||||
ddl_type_from_cmd(CollectedCommand *cmd)
|
||||
{
|
||||
ListCell *cell;
|
||||
|
||||
if (cmd->type == SCT_AlterTable)
|
||||
{
|
||||
foreach(cell, cmd->d.alterTable.subcmds)
|
||||
{
|
||||
CollectedATSubcmd *sub = lfirst(cell);
|
||||
AlterTableCmd *subcmd = (AlterTableCmd *) sub->parsetree;
|
||||
|
||||
Assert(IsA(subcmd, AlterTableCmd));
|
||||
|
||||
switch (subcmd->subtype)
|
||||
{
|
||||
case AT_AddColumn:
|
||||
case AT_AddColumnRecurse:
|
||||
return DDL_ADD_COLUMN;
|
||||
case AT_DropColumn:
|
||||
case AT_DropColumnRecurse:
|
||||
return DDL_DROP_COLUMN;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DDL_OTHER;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test if ddl command is an alter table add column
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(ddl_is_add_column);
|
||||
Datum
|
||||
ddl_is_add_column(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bool is_add_column = DDL_ADD_COLUMN == ddl_type_from_cmd((CollectedCommand *) PG_GETARG_POINTER(0));
|
||||
|
||||
PG_RETURN_BOOL(is_add_column);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test if ddl command is an alter table drop column
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(ddl_is_drop_column);
|
||||
Datum
|
||||
ddl_is_drop_column(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bool is_drop_column = DDL_DROP_COLUMN == ddl_type_from_cmd((CollectedCommand *) PG_GETARG_POINTER(0));
|
||||
|
||||
PG_RETURN_BOOL(is_drop_column);
|
||||
}
|
@ -185,6 +185,91 @@ psql:include/ddl_ops_1.sql:61: ERROR: UPDATE ONLY not supported on hypertables
|
||||
DELETE FROM ONLY PUBLIC."Hypertable_1" WHERE "Device_id" = 'dev1';
|
||||
psql:include/ddl_ops_1.sql:62: ERROR: DELETE ONLY not currently supported on hypertables
|
||||
\set ON_ERROR_STOP 1
|
||||
CREATE TABLE my_ht (time bigint, val integer);
|
||||
SELECT * FROM create_hypertable('my_ht', 'time');
|
||||
create_hypertable
|
||||
-------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE my_ht ADD COLUMN val2 integer;
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
-- Should error when adding again
|
||||
\set ON_ERROR_STOP 0
|
||||
ALTER TABLE my_ht ADD COLUMN val2 integer;
|
||||
psql:include/ddl_ops_1.sql:73: ERROR: column "val2" of relation "my_ht" already exists
|
||||
\set ON_ERROR_STOP 1
|
||||
-- Should create
|
||||
ALTER TABLE my_ht ADD COLUMN IF NOT EXISTS val3 integer;
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
val3 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
-- Should skip and not error
|
||||
ALTER TABLE my_ht ADD COLUMN IF NOT EXISTS val3 integer;
|
||||
psql:include/ddl_ops_1.sql:81: NOTICE: column "val3" of relation "my_ht" already exists, skipping
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
val3 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
-- Should drop
|
||||
ALTER TABLE my_ht DROP COLUMN IF EXISTS val3;
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
-- Should skip and not error
|
||||
ALTER TABLE my_ht DROP COLUMN IF EXISTS val3;
|
||||
psql:include/ddl_ops_1.sql:89: NOTICE: column "val3" of relation "my_ht" does not exist, skipping
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
\ir include/ddl_ops_2.sql
|
||||
ALTER TABLE PUBLIC."Hypertable_1" ADD COLUMN temp_f INTEGER NOT NULL DEFAULT 31;
|
||||
ALTER TABLE PUBLIC."Hypertable_1" DROP COLUMN temp_c;
|
||||
@ -217,3 +302,4 @@ psql:include/ddl_ops_2.sql:26: ERROR: CREATE TRIGGER not supported on hypertabl
|
||||
ALTER TABLE PUBLIC."Hypertable_1" ADD COLUMN sensor_3 BIGINT NOT NULL DEFAULT 131;
|
||||
--create column with same name as previously dropped one
|
||||
ALTER TABLE PUBLIC."Hypertable_1" ADD COLUMN sensor_4 BIGINT NOT NULL DEFAULT 131;
|
||||
|
||||
|
@ -100,6 +100,91 @@ psql:include/ddl_ops_1.sql:61: ERROR: UPDATE ONLY not supported on hypertables
|
||||
DELETE FROM ONLY PUBLIC."Hypertable_1" WHERE "Device_id" = 'dev1';
|
||||
psql:include/ddl_ops_1.sql:62: ERROR: DELETE ONLY not currently supported on hypertables
|
||||
\set ON_ERROR_STOP 1
|
||||
CREATE TABLE my_ht (time bigint, val integer);
|
||||
SELECT * FROM create_hypertable('my_ht', 'time');
|
||||
create_hypertable
|
||||
-------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE my_ht ADD COLUMN val2 integer;
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
-- Should error when adding again
|
||||
\set ON_ERROR_STOP 0
|
||||
ALTER TABLE my_ht ADD COLUMN val2 integer;
|
||||
psql:include/ddl_ops_1.sql:73: ERROR: column "val2" of relation "my_ht" already exists
|
||||
\set ON_ERROR_STOP 1
|
||||
-- Should create
|
||||
ALTER TABLE my_ht ADD COLUMN IF NOT EXISTS val3 integer;
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
val3 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
-- Should skip and not error
|
||||
ALTER TABLE my_ht ADD COLUMN IF NOT EXISTS val3 integer;
|
||||
psql:include/ddl_ops_1.sql:81: NOTICE: column "val3" of relation "my_ht" already exists, skipping
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
val3 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
-- Should drop
|
||||
ALTER TABLE my_ht DROP COLUMN IF EXISTS val3;
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
-- Should skip and not error
|
||||
ALTER TABLE my_ht DROP COLUMN IF EXISTS val3;
|
||||
psql:include/ddl_ops_1.sql:89: NOTICE: column "val3" of relation "my_ht" does not exist, skipping
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
SELECT * FROM PUBLIC."Hypertable_1";
|
||||
time | Device_id | temp_c | humidity | sensor_1 | sensor_2 | sensor_3 | sensor_4
|
||||
---------------------+-----------+--------+----------+----------+----------+----------+----------
|
||||
@ -191,7 +276,8 @@ SELECT * FROM _timescaledb_catalog.default_replica_node;
|
||||
---------------+---------------+------------
|
||||
single | 1 | 0
|
||||
single | 2 | 0
|
||||
(2 rows)
|
||||
single | 3 | 0
|
||||
(3 rows)
|
||||
|
||||
\ir include/ddl_ops_2.sql
|
||||
ALTER TABLE PUBLIC."Hypertable_1" ADD COLUMN temp_f INTEGER NOT NULL DEFAULT 31;
|
||||
@ -225,6 +311,7 @@ psql:include/ddl_ops_2.sql:26: ERROR: CREATE TRIGGER not supported on hypertabl
|
||||
ALTER TABLE PUBLIC."Hypertable_1" ADD COLUMN sensor_3 BIGINT NOT NULL DEFAULT 131;
|
||||
--create column with same name as previously dropped one
|
||||
ALTER TABLE PUBLIC."Hypertable_1" ADD COLUMN sensor_4 BIGINT NOT NULL DEFAULT 131;
|
||||
|
||||
\d+ PUBLIC."Hypertable_1"
|
||||
Table "public.Hypertable_1"
|
||||
Column | Type | Modifiers | Storage | Stats target | Description
|
||||
|
@ -100,6 +100,91 @@ psql:include/ddl_ops_1.sql:61: ERROR: UPDATE ONLY not supported on hypertables
|
||||
DELETE FROM ONLY PUBLIC."Hypertable_1" WHERE "Device_id" = 'dev1';
|
||||
psql:include/ddl_ops_1.sql:62: ERROR: DELETE ONLY not currently supported on hypertables
|
||||
\set ON_ERROR_STOP 1
|
||||
CREATE TABLE my_ht (time bigint, val integer);
|
||||
SELECT * FROM create_hypertable('my_ht', 'time');
|
||||
create_hypertable
|
||||
-------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE my_ht ADD COLUMN val2 integer;
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
-- Should error when adding again
|
||||
\set ON_ERROR_STOP 0
|
||||
ALTER TABLE my_ht ADD COLUMN val2 integer;
|
||||
psql:include/ddl_ops_1.sql:73: ERROR: column "val2" of relation "my_ht" already exists
|
||||
\set ON_ERROR_STOP 1
|
||||
-- Should create
|
||||
ALTER TABLE my_ht ADD COLUMN IF NOT EXISTS val3 integer;
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
val3 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
-- Should skip and not error
|
||||
ALTER TABLE my_ht ADD COLUMN IF NOT EXISTS val3 integer;
|
||||
psql:include/ddl_ops_1.sql:81: NOTICE: column "val3" of relation "my_ht" already exists, skipping
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
val3 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
-- Should drop
|
||||
ALTER TABLE my_ht DROP COLUMN IF EXISTS val3;
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
-- Should skip and not error
|
||||
ALTER TABLE my_ht DROP COLUMN IF EXISTS val3;
|
||||
psql:include/ddl_ops_1.sql:89: NOTICE: column "val3" of relation "my_ht" does not exist, skipping
|
||||
\d my_ht
|
||||
Table "public.my_ht"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
time | bigint |
|
||||
val | integer |
|
||||
val2 | integer |
|
||||
Triggers:
|
||||
_timescaledb_main_after_insert_trigger AFTER INSERT ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.main_table_after_insert_trigger()
|
||||
_timescaledb_main_insert_trigger BEFORE INSERT ON my_ht FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.main_table_insert_trigger()
|
||||
_timescaledb_modify_trigger BEFORE DELETE OR UPDATE ON my_ht FOR EACH STATEMENT EXECUTE PROCEDURE _timescaledb_internal.on_unsupported_main_table()
|
||||
|
||||
SELECT * FROM PUBLIC."Hypertable_1";
|
||||
time | Device_id | temp_c | humidity | sensor_1 | sensor_2 | sensor_3 | sensor_4
|
||||
---------------------+-----------+--------+----------+----------+----------+----------+----------
|
||||
@ -120,7 +205,8 @@ SELECT * FROM _timescaledb_catalog.default_replica_node;
|
||||
---------------+---------------+------------
|
||||
single | 1 | 0
|
||||
single | 2 | 0
|
||||
(2 rows)
|
||||
single | 3 | 0
|
||||
(3 rows)
|
||||
|
||||
\ir include/ddl_ops_2.sql
|
||||
ALTER TABLE PUBLIC."Hypertable_1" ADD COLUMN temp_f INTEGER NOT NULL DEFAULT 31;
|
||||
@ -154,6 +240,7 @@ psql:include/ddl_ops_2.sql:26: ERROR: CREATE TRIGGER not supported on hypertabl
|
||||
ALTER TABLE PUBLIC."Hypertable_1" ADD COLUMN sensor_3 BIGINT NOT NULL DEFAULT 131;
|
||||
--create column with same name as previously dropped one
|
||||
ALTER TABLE PUBLIC."Hypertable_1" ADD COLUMN sensor_4 BIGINT NOT NULL DEFAULT 131;
|
||||
|
||||
\d+ PUBLIC."Hypertable_1"
|
||||
Table "public.Hypertable_1"
|
||||
Column | Type | Modifiers | Storage | Stats target | Description
|
||||
|
@ -61,3 +61,30 @@ CREATE UNIQUE INDEX "Unique2" ON PUBLIC."Hypertable_1" (sensor_1);
|
||||
UPDATE ONLY PUBLIC."Hypertable_1" SET time = 0 WHERE TRUE;
|
||||
DELETE FROM ONLY PUBLIC."Hypertable_1" WHERE "Device_id" = 'dev1';
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
|
||||
CREATE TABLE my_ht (time bigint, val integer);
|
||||
SELECT * FROM create_hypertable('my_ht', 'time');
|
||||
ALTER TABLE my_ht ADD COLUMN val2 integer;
|
||||
\d my_ht
|
||||
|
||||
-- Should error when adding again
|
||||
\set ON_ERROR_STOP 0
|
||||
ALTER TABLE my_ht ADD COLUMN val2 integer;
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
-- Should create
|
||||
ALTER TABLE my_ht ADD COLUMN IF NOT EXISTS val3 integer;
|
||||
\d my_ht
|
||||
|
||||
-- Should skip and not error
|
||||
ALTER TABLE my_ht ADD COLUMN IF NOT EXISTS val3 integer;
|
||||
\d my_ht
|
||||
|
||||
-- Should drop
|
||||
ALTER TABLE my_ht DROP COLUMN IF EXISTS val3;
|
||||
\d my_ht
|
||||
|
||||
-- Should skip and not error
|
||||
ALTER TABLE my_ht DROP COLUMN IF EXISTS val3;
|
||||
\d my_ht
|
||||
|
@ -30,5 +30,4 @@ FOR EACH STATEMENT EXECUTE PROCEDURE empty_trigger_func();
|
||||
ALTER TABLE PUBLIC."Hypertable_1" ADD COLUMN sensor_3 BIGINT NOT NULL DEFAULT 131;
|
||||
--create column with same name as previously dropped one
|
||||
ALTER TABLE PUBLIC."Hypertable_1" ADD COLUMN sensor_4 BIGINT NOT NULL DEFAULT 131;
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user