Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit687e6ca

Browse files
committed
[WIP] introduce 'partition_creation' subsystem
1 parentf603e6c commit687e6ca

File tree

3 files changed

+268
-1
lines changed

3 files changed

+268
-1
lines changed

‎Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ OBJS = src/init.o src/relation_info.o src/utils.o src/partition_filter.o \
55
src/runtimeappend.o src/runtime_merge_append.o src/pg_pathman.o src/rangeset.o\
66
src/pl_funcs.o src/pl_range_funcs.o src/pl_hash_funcs.o src/pathman_workers.o\
77
src/hooks.o src/nodes_common.o src/xact_handling.o src/copy_stmt_hooking.o\
8-
src/pg_compat.o$(WIN32RES)
8+
src/partition_creation.o src/pg_compat.o$(WIN32RES)
99

1010
EXTENSION = pg_pathman
1111
EXTVERSION = 1.1

‎src/partition_creation.c

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
#include"pathman.h"
2+
#include"init.h"
3+
#include"partition_creation.h"
4+
#include"relation_info.h"
5+
6+
#include"access/reloptions.h"
7+
#include"access/xact.h"
8+
#include"catalog/heap.h"
9+
#include"catalog/toasting.h"
10+
#include"commands/defrem.h"
11+
#include"commands/event_trigger.h"
12+
#include"commands/tablecmds.h"
13+
#include"nodes/makefuncs.h"
14+
#include"parser/parse_expr.h"
15+
#include"parser/parse_node.h"
16+
#include"parser/parse_relation.h"
17+
#include"utils/lsyscache.h"
18+
#include"utils/syscache.h"
19+
20+
21+
/* TODO: comment */
22+
Oid
23+
create_single_range_partition(Oidparent_relid,
24+
Datumstart_value,
25+
Datumend_value,
26+
Oidvalue_type,
27+
RangeVar*partition_rv,
28+
char*tablespace)
29+
{
30+
CreateStmtcreate_stmt;
31+
ObjectAddresspartition_addr;
32+
Oidchild_relid;
33+
Relationchild_relation;
34+
Datumtoast_options;
35+
TableLikeClauselike_clause;
36+
Constraint*check_constr;
37+
RangeVar*parent_rv;
38+
Oidparent_nsp;
39+
char*parent_name,
40+
*parent_nsp_name,
41+
partitioned_column;
42+
Datumconfig_values[Natts_pathman_config];
43+
boolconfig_nulls[Natts_pathman_config];
44+
staticchar*validnsps[]=HEAP_RELOPT_NAMESPACES;
45+
46+
/* Lock parent and check if it exists */
47+
LockRelationOid(parent_relid,ShareUpdateExclusiveLock);
48+
if (!SearchSysCacheExists1(RELOID,ObjectIdGetDatum(parent_relid)))
49+
elog(ERROR,"relation %u does not exist",parent_relid);
50+
51+
/* Check that table is registered in PATHMAN_CONFIG */
52+
if (!pathman_config_contains_relation(parent_relid,
53+
config_values,config_nulls,NULL))
54+
elog(ERROR,"table \"%s\" is not partitioned",
55+
get_rel_name_or_relid(parent_relid));
56+
57+
/* Cache parent's namespace and name */
58+
parent_name=get_rel_name(parent_relid);
59+
parent_nsp=get_rel_namespace(parent_relid);
60+
parent_nsp_name=get_namespace_name(parent_nsp);
61+
62+
/* Make up parent's RangeVar */
63+
parent_rv=makeRangeVar(parent_nsp_name,parent_name,-1);
64+
65+
/* Generate a name if asked to */
66+
if (!partition_rv)
67+
{
68+
char*part_name;
69+
70+
/* Make up a name for the partition */
71+
part_name=ChooseRelationName(parent_name,NULL,"part",parent_nsp);
72+
73+
/* Make RangeVar for the partition */
74+
partition_rv=makeRangeVar(parent_nsp_name,part_name,-1);
75+
}
76+
77+
/* Initialize TableLikeClause structure */
78+
NodeSetTag(&like_clause,T_TableLikeClause);
79+
like_clause.relation=copyObject(parent_rv);
80+
like_clause.options=CREATE_TABLE_LIKE_ALL;
81+
82+
/* Initialize CreateStmt structure */
83+
NodeSetTag(&create_stmt,T_CreateStmt);
84+
create_stmt.relation=copyObject(partition_rv);
85+
create_stmt.tableElts=list_make1(&like_clause);
86+
create_stmt.inhRelations=list_make1(copyObject(parent_rv));
87+
create_stmt.ofTypename=NULL;
88+
create_stmt.constraints=list_make1(&check_constr);
89+
create_stmt.options=NIL;
90+
create_stmt.oncommit=ONCOMMIT_NOOP;
91+
create_stmt.tablespacename=tablespace;
92+
create_stmt.if_not_exists= false;
93+
94+
/* Create new partition owned by parent's posessor */
95+
partition_addr=DefineRelation(&create_stmt,RELKIND_RELATION,
96+
get_rel_owner(parent_relid),NULL);
97+
98+
/* Save data about a simple DDL command that was just executed */
99+
EventTriggerCollectSimpleCommand(partition_addr,
100+
InvalidObjectAddress,
101+
(Node*)&create_stmt);
102+
103+
/* Save partition's Oid */
104+
child_relid=partition_addr.objectId;
105+
106+
/*
107+
* Let NewRelationCreateToastTable decide if this
108+
* one needs a secondary relation too.
109+
*/
110+
CommandCounterIncrement();
111+
112+
/* Parse and validate reloptions for the toast table */
113+
toast_options=transformRelOptions((Datum)0,create_stmt.options,
114+
"toast",validnsps, true, false);
115+
116+
/* Parse options for a new toast table */
117+
(void)heap_reloptions(RELKIND_TOASTVALUE,toast_options, true);
118+
119+
/* Now create the toast table if needed */
120+
NewRelationCreateToastTable(child_relid,toast_options);
121+
122+
/* Update config one more time */
123+
CommandCounterIncrement();
124+
125+
/* Fetch partitioned column's name */
126+
partitioned_column=config_values[Anum_pathman_config_attname-1];
127+
128+
/* Build check constraint for RANGE partition */
129+
check_constr=build_range_check_constraint(partitioned_column,
130+
start_value,
131+
end_value,
132+
value_type);
133+
134+
/* Open the relation and add new check constraint */
135+
child_relation=heap_openrv(partition_rv,AccessExclusiveLock);
136+
AddRelationNewConstraints(child_relation,NIL,
137+
list_make1(check_constr),
138+
false, true, true);
139+
heap_close(child_relation,NoLock);
140+
141+
/* Invoke init_callback on partition */
142+
invoke_init_callback(parent_relid,child_relid,InvalidOid,
143+
start_value,end_value,value_type);
144+
145+
returnchild_relid;
146+
}
147+
148+
Node*
149+
raw_range_check_tree(char*attname,
150+
Datumstart_value,
151+
Datumend_value,
152+
Oidvalue_type)
153+
{
154+
BoolExpr*and_oper=makeNode(BoolExpr);
155+
A_Expr*left_arg=makeNode(A_Expr),
156+
*right_arg=makeNode(A_Expr);
157+
A_Const*left_const=makeNode(A_Const),
158+
*right_const=makeNode(A_Const);
159+
ColumnRef*col_ref=makeNode(ColumnRef);
160+
161+
/* Partitioned column */
162+
col_ref->fields=list_make1(makeString(attname));
163+
col_ref->location=-1;
164+
165+
/* Left boundary */
166+
left_const->val=*makeString(datum_to_cstring(start_value,value_type));
167+
left_const->location=-1;
168+
169+
/* Right boundary */
170+
right_const->val=*makeString(datum_to_cstring(end_value,value_type));
171+
right_const->location=-1;
172+
173+
/* Left comparison (VAR >= start_value) */
174+
left_arg->name=list_make1(makeString(">="));
175+
left_arg->kind=AEXPR_OP;
176+
left_arg->lexpr= (Node*)col_ref;
177+
left_arg->rexpr= (Node*)left_const;
178+
left_arg->location=-1;
179+
180+
/* Right comparision (VAR < end_value) */
181+
right_arg->name=list_make1(makeString("<"));
182+
right_arg->kind=AEXPR_OP;
183+
right_arg->lexpr= (Node*)col_ref;
184+
right_arg->rexpr= (Node*)right_const;
185+
right_arg->location=-1;
186+
187+
and_oper->boolop=AND_EXPR;
188+
and_oper->args=list_make2(left_arg,right_arg);
189+
and_oper->location=-1;
190+
191+
return (Node*)and_oper;
192+
}
193+
194+
Node*
195+
good_range_check_tree(RangeVar*partition,
196+
char*attname,
197+
Datumstart_value,
198+
Datumend_value,
199+
Oidvalue_type)
200+
{
201+
ParseState*pstate=make_parsestate(NULL);
202+
RangeTblEntry*partition_rte;
203+
Node*expression,
204+
*raw_expression;
205+
ParseNamespaceItempni;
206+
207+
/* Required for transformExpr() */
208+
partition_rte=addRangeTableEntry(pstate,partition,NULL, false, false);
209+
210+
memset((void*)&pni,0,sizeof(ParseNamespaceItem));
211+
pni.p_rte=partition_rte;
212+
pni.p_rel_visible= true;
213+
pni.p_cols_visible= true;
214+
215+
pstate->p_namespace=list_make1(&pni);
216+
pstate->p_rtable=list_make1(partition_rte);
217+
218+
/* Transform raw check constraint expression into Constraint */
219+
raw_expression=raw_range_check_tree(attname,start_value,end_value,value_type);
220+
expression=transformExpr(pstate,raw_expression,EXPR_KIND_CHECK_CONSTRAINT);
221+
222+
return (Node*)expression;
223+
}
224+
225+
Constraint*
226+
build_range_check_constraint(char*attname,
227+
Datumstart_value,
228+
Datumend_value,
229+
Oidvalue_type)
230+
{
231+
Constraint*range_constr;
232+
233+
range_constr=makeNode(Constraint);
234+
range_constr->conname=NULL;
235+
range_constr->deferrable= false;
236+
range_constr->initdeferred= false;
237+
range_constr->location=-1;
238+
range_constr->contype=CONSTR_CHECK;
239+
range_constr->is_no_inherit= true;
240+
241+
range_constr->raw_expr=raw_range_check_tree(attname,
242+
start_value,
243+
end_value,
244+
value_type);
245+
246+
returnrange_constr;
247+
}
248+
249+
/* TODO: comment */
250+
void
251+
invoke_init_callback(Oidparent_relid,
252+
Oidchild_relid,
253+
Oidinit_callback,
254+
Datumstart_value,
255+
Datumend_value,
256+
Oidvalue_type)
257+
{
258+
259+
}

‎src/partition_creation.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
#include"postgres.h"
3+
#include"nodes/parsenodes.h"
4+
5+
Constraint*build_range_check_constraint(char*attname,
6+
Datumstart_value,
7+
Datumend_value,
8+
Oidvalue_type);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp