Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add if_attached argument to detach_data_node() #2515

Merged
merged 1 commit into from Oct 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions sql/ddl_api.sql
Expand Up @@ -179,6 +179,7 @@ AS '@MODULE_PATHNAME@', 'ts_data_node_attach' LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION detach_data_node(
node_name NAME,
hypertable REGCLASS = NULL,
if_attached BOOLEAN = FALSE,
force BOOLEAN = FALSE,
repartition BOOLEAN = TRUE
) RETURNS INTEGER
Expand Down
2 changes: 2 additions & 0 deletions sql/updates/latest-dev.sql
@@ -0,0 +1,2 @@

DROP FUNCTION IF EXISTS detach_data_node(name,regclass,boolean,boolean);
39 changes: 27 additions & 12 deletions tsl/src/data_node.c
Expand Up @@ -1133,14 +1133,14 @@ data_node_detach_hypertable_data_nodes(const char *node_name, List *hypertable_d
}

static HypertableDataNode *
get_hypertable_data_node(Oid table_id, const char *node_name, bool ownercheck)
get_hypertable_data_node(Oid table_id, const char *node_name, bool owner_check, bool attach_check)
{
HypertableDataNode *hdn = NULL;
Cache *hcache = ts_hypertable_cache_pin();
Hypertable *ht = ts_hypertable_cache_get_entry(hcache, table_id, CACHE_FLAG_NONE);
ListCell *lc;

if (ownercheck)
if (owner_check)
ts_hypertable_permissions_check(table_id, GetUserId());

foreach (lc, ht->data_nodes)
Expand All @@ -1153,11 +1153,21 @@ get_hypertable_data_node(Oid table_id, const char *node_name, bool ownercheck)
}

if (hdn == NULL)
ereport(ERROR,
(errcode(ERRCODE_TS_DATA_NODE_NOT_ATTACHED),
errmsg("data node \"%s\" is not attached to hypertable \"%s\"",
node_name,
get_rel_name(table_id))));
{
if (attach_check)
ereport(ERROR,
(errcode(ERRCODE_TS_DATA_NODE_NOT_ATTACHED),
errmsg("data node \"%s\" is not attached to hypertable \"%s\"",
node_name,
get_rel_name(table_id))));
else
ereport(NOTICE,
(errcode(ERRCODE_TS_DATA_NODE_NOT_ATTACHED),
errmsg("data node \"%s\" is not attached to hypertable \"%s\", "
"skipping",
node_name,
get_rel_name(table_id))));
}

ts_cache_release(hcache);

Expand All @@ -1180,7 +1190,7 @@ data_node_block_or_allow_new_chunks(const char *node_name, Oid const table_id, b
/* Early abort on missing hypertable permissions */
ts_hypertable_permissions_check(table_id, GetUserId());
hypertable_data_nodes =
list_make1(get_hypertable_data_node(table_id, server->servername, true));
list_make1(get_hypertable_data_node(table_id, server->servername, true, true));
}
else
{
Expand Down Expand Up @@ -1226,8 +1236,9 @@ data_node_detach(PG_FUNCTION_ARGS)
const char *node_name = PG_ARGISNULL(0) ? NULL : NameStr(*PG_GETARG_NAME(0));
Oid table_id = PG_ARGISNULL(1) ? InvalidOid : PG_GETARG_OID(1);
bool all_hypertables = PG_ARGISNULL(1);
bool force = PG_ARGISNULL(2) ? InvalidOid : PG_GETARG_OID(2);
bool repartition = PG_ARGISNULL(3) ? false : PG_GETARG_BOOL(3);
bool if_attached = PG_ARGISNULL(2) ? false : PG_GETARG_BOOL(2);
bool force = PG_ARGISNULL(3) ? InvalidOid : PG_GETARG_OID(3);
bool repartition = PG_ARGISNULL(4) ? false : PG_GETARG_BOOL(4);
int removed = 0;
List *hypertable_data_nodes = NIL;
ForeignServer *server;
Expand All @@ -1239,10 +1250,14 @@ data_node_detach(PG_FUNCTION_ARGS)

if (OidIsValid(table_id))
{
HypertableDataNode *node;

/* Early abort on missing hypertable permissions */
ts_hypertable_permissions_check(table_id, GetUserId());
hypertable_data_nodes =
list_make1(get_hypertable_data_node(table_id, server->servername, true));

node = get_hypertable_data_node(table_id, server->servername, true, !if_attached);
if (node)
hypertable_data_nodes = list_make1(node);
}
else
{
Expand Down
12 changes: 11 additions & 1 deletion tsl/test/expected/data_node.out
Expand Up @@ -1026,13 +1026,23 @@ ERROR: detaching data node "data_node_1" failed because it contains chunks for
-- can't detach already detached data node
SELECT * FROM detach_data_node('data_node_2', 'disttable_2');
ERROR: data node "data_node_2" is not attached to hypertable "disttable_2"
SELECT * FROM detach_data_node('data_node_2', 'disttable_2', if_attached => false);
ERROR: data node "data_node_2" is not attached to hypertable "disttable_2"
-- can't detach b/c of replication factor for disttable_2
SELECT * FROM detach_data_node('data_node_3', 'disttable_2');
ERROR: detaching data node "data_node_3" risks making new data for hypertable "disttable_2" under-replicated
-- can't detach non hypertable
SELECT * FROM detach_data_node('data_node_3', 'devices');
ERROR: table "devices" is not a hypertable
\set ON_ERROR_STOP 1
-- do nothing if node is not attached
SELECT * FROM detach_data_node('data_node_2', 'disttable_2', if_attached => true);
NOTICE: data node "data_node_2" is not attached to hypertable "disttable_2", skipping
detach_data_node
------------------
0
(1 row)

-- force detach data node to become under-replicated for new data
SELECT * FROM detach_data_node('data_node_3', 'disttable_2', force => true);
WARNING: new data for hypertable "disttable_2" will be under-replicated due to detaching data node "data_node_3"
Expand Down Expand Up @@ -1127,7 +1137,7 @@ ORDER BY foreign_table_name;
--------------------+---------------------
(0 rows)

SELECT * FROM detach_data_node('data_node_2', 'disttable', true);
SELECT * FROM detach_data_node('data_node_2', 'disttable', force => true);
WARNING: new data for hypertable "disttable" will be under-replicated due to detaching data node "data_node_2"
NOTICE: the number of partitions in dimension "device" was decreased to 1
detach_data_node
Expand Down
6 changes: 5 additions & 1 deletion tsl/test/sql/data_node.sql
Expand Up @@ -508,12 +508,16 @@ SELECT * FROM detach_data_node(NULL, 'disttable');
SELECT * FROM detach_data_node('data_node_1');
-- can't detach already detached data node
SELECT * FROM detach_data_node('data_node_2', 'disttable_2');
SELECT * FROM detach_data_node('data_node_2', 'disttable_2', if_attached => false);
-- can't detach b/c of replication factor for disttable_2
SELECT * FROM detach_data_node('data_node_3', 'disttable_2');
-- can't detach non hypertable
SELECT * FROM detach_data_node('data_node_3', 'devices');
\set ON_ERROR_STOP 1

-- do nothing if node is not attached
SELECT * FROM detach_data_node('data_node_2', 'disttable_2', if_attached => true);

-- force detach data node to become under-replicated for new data
SELECT * FROM detach_data_node('data_node_3', 'disttable_2', force => true);

Expand Down Expand Up @@ -547,7 +551,7 @@ SELECT foreign_table_name, foreign_server_name
FROM information_schema.foreign_tables
ORDER BY foreign_table_name;

SELECT * FROM detach_data_node('data_node_2', 'disttable', true);
SELECT * FROM detach_data_node('data_node_2', 'disttable', force => true);

-- Let's add more data nodes
SET ROLE :ROLE_CLUSTER_SUPERUSER;
Expand Down