1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
/*-------------------------------------------------------------------------
*
* groupmgr.c
* Routines to support manipulation of the pgxc_group catalog
* This includes support for DDL on objects NODE GROUP
*
* Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 2010-2012 Postgres-XC Development Group
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "miscadmin.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "catalog/catalog.h"
#include "catalog/indexing.h"
#include "catalog/pg_type.h"
#include "catalog/pgxc_node.h"
#include "catalog/pgxc_group.h"
#include "nodes/parsenodes.h"
#include "nodes/pg_list.h"
#include "utils/builtins.h"
#include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/lsyscache.h"
#include "utils/array.h"
#include "pgxc/groupmgr.h"
/*
* PgxcGroupCreate
*
* Create a PGXC node group
*/
void
PgxcGroupCreate(CreateGroupStmt *stmt)
{
const char *group_name = stmt->group_name;
List *nodes = stmt->nodes;
oidvector *nodes_array;
Oid *inTypes;
Relation rel;
HeapTuple tup;
bool nulls[Natts_pgxc_group];
Datum values[Natts_pgxc_group];
int member_count = list_length(stmt->nodes);
ListCell *lc;
int i = 0;
/* Only a DB administrator can add cluster node groups */
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to create cluster node groups")));
/* Check if given group already exists */
if (OidIsValid(get_pgxc_groupoid(group_name)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("PGXC Group %s: group already defined",
group_name)));
inTypes = (Oid *) palloc(member_count * sizeof(Oid));
/* Build list of Oids for each node listed */
foreach(lc, nodes)
{
char *node_name = strVal(lfirst(lc));
Oid noid = get_pgxc_nodeoid(node_name);
if (!OidIsValid(noid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("PGXC Node %s: object not defined",
node_name)));
if (get_pgxc_nodetype(noid) != PGXC_NODE_DATANODE)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("PGXC node %s: only Datanodes can be group members",
node_name)));
/* OK to pick up Oid of this node */
inTypes[i] = noid;
i++;
}
/* Build array of Oids to be inserted */
nodes_array = buildoidvector(inTypes, member_count);
/* Iterate through all attributes initializing nulls and values */
for (i = 0; i < Natts_pgxc_group; i++)
{
nulls[i] = false;
values[i] = (Datum) 0;
}
/* Insert Data correctly */
values[Anum_pgxc_group_name - 1] =
DirectFunctionCall1(namein, CStringGetDatum(group_name));
values[Anum_pgxc_group_members - 1] = PointerGetDatum(nodes_array);
/* Open the relation for insertion */
rel = heap_open(PgxcGroupRelationId, RowExclusiveLock);
tup = heap_form_tuple(rel->rd_att, values, nulls);
CatalogTupleInsert(rel, tup);
heap_close(rel, RowExclusiveLock);
}
/*
* PgxcNodeGroupsRemove():
*
* Remove a PGXC node group
*/
void
PgxcGroupRemove(DropGroupStmt *stmt)
{
Relation relation;
HeapTuple tup;
const char *group_name = stmt->group_name;
Oid group_oid = get_pgxc_groupoid(group_name);
/* Only a DB administrator can remove cluster node groups */
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to remove cluster node groups")));
/* Check if group exists */
if (!OidIsValid(group_oid))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("PGXC Group %s: group not defined",
group_name)));
/* Delete the pgxc_group tuple */
relation = heap_open(PgxcGroupRelationId, RowExclusiveLock);
tup = SearchSysCache(PGXCGROUPOID, ObjectIdGetDatum(group_oid), 0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "PGXC Group %s: group not defined", group_name);
simple_heap_delete(relation, &tup->t_self);
ReleaseSysCache(tup);
heap_close(relation, RowExclusiveLock);
}
|