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

Commitee9ccbc

Browse files
committed
improve type handling in function spawn_partitions_val() (issue #65)
1 parent4827d9f commitee9ccbc

File tree

4 files changed

+126
-19
lines changed

4 files changed

+126
-19
lines changed

‎expected/pathman_basic.out

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,51 @@ SELECT count(*) FROM test.insert_into_select_copy;
320320

321321
DROP TABLE test.insert_into_select_copy, test.insert_into_select CASCADE;
322322
NOTICE: drop cascades to 5 other objects
323+
/* Test INSERT hooking with DATE type */
324+
CREATE TABLE test.insert_date_test(val DATE NOT NULL);
325+
SELECT pathman.create_partitions_from_range('test.insert_date_test', 'val',
326+
date '20161001', date '20170101', interval '1 month');
327+
NOTICE: sequence "insert_date_test_seq" does not exist, skipping
328+
create_partitions_from_range
329+
------------------------------
330+
4
331+
(1 row)
332+
333+
INSERT INTO test.insert_date_test VALUES ('20161201'); /* just insert the date */
334+
SELECT count(*) FROM pathman.pathman_partition_list WHERE parent = 'test.insert_date_test'::REGCLASS;
335+
count
336+
-------
337+
4
338+
(1 row)
339+
340+
INSERT INTO test.insert_date_test VALUES ('20170311'); /* append new partitions */
341+
SELECT count(*) FROM pathman.pathman_partition_list WHERE parent = 'test.insert_date_test'::REGCLASS;
342+
count
343+
-------
344+
6
345+
(1 row)
346+
347+
INSERT INTO test.insert_date_test VALUES ('20160812'); /* prepend new partitions */
348+
SELECT count(*) FROM pathman.pathman_partition_list WHERE parent = 'test.insert_date_test'::REGCLASS;
349+
count
350+
-------
351+
8
352+
(1 row)
353+
354+
SELECT min(val) FROM test.insert_date_test; /* check first date */
355+
min
356+
------------
357+
08-12-2016
358+
(1 row)
359+
360+
SELECT max(val) FROM test.insert_date_test; /* check last date */
361+
max
362+
------------
363+
03-11-2017
364+
(1 row)
365+
366+
DROP TABLE test.insert_date_test CASCADE;
367+
NOTICE: drop cascades to 8 other objects
323368
/* Test special case: ONLY statement with not-ONLY for partitioned table */
324369
CREATE TABLE test.from_only_test(val INT NOT NULL);
325370
INSERT INTO test.from_only_test SELECT generate_series(1, 20);
@@ -1982,6 +2027,6 @@ EXPLAIN (COSTS OFF) SELECT * FROM test.index_on_childs WHERE c1 > 100 AND c1 < 2
19822027
(12 rows)
19832028

19842029
DROP SCHEMA test CASCADE;
1985-
NOTICE: drop cascades to48 other objects
2030+
NOTICE: drop cascades to49 other objects
19862031
DROP EXTENSION pg_pathman CASCADE;
19872032
DROP SCHEMA pathman CASCADE;

‎sql/pathman_basic.sql

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,26 @@ SELECT count(*) FROM test.insert_into_select_copy;
101101
DROPTABLEtest.insert_into_select_copy,test.insert_into_select CASCADE;
102102

103103

104+
/* Test INSERT hooking with DATE type*/
105+
CREATETABLEtest.insert_date_test(valDATENOT NULL);
106+
SELECTpathman.create_partitions_from_range('test.insert_date_test','val',
107+
date'20161001',date'20170101', interval'1 month');
108+
109+
INSERT INTOtest.insert_date_testVALUES ('20161201');/* just insert the date*/
110+
SELECTcount(*)FROMpathman.pathman_partition_listWHERE parent='test.insert_date_test'::REGCLASS;
111+
112+
INSERT INTOtest.insert_date_testVALUES ('20170311');/* append new partitions*/
113+
SELECTcount(*)FROMpathman.pathman_partition_listWHERE parent='test.insert_date_test'::REGCLASS;
114+
115+
INSERT INTOtest.insert_date_testVALUES ('20160812');/* prepend new partitions*/
116+
SELECTcount(*)FROMpathman.pathman_partition_listWHERE parent='test.insert_date_test'::REGCLASS;
117+
118+
SELECTmin(val)FROMtest.insert_date_test;/* check first date*/
119+
SELECTmax(val)FROMtest.insert_date_test;/* check last date*/
120+
121+
DROPTABLEtest.insert_date_test CASCADE;
122+
123+
104124
/* Test special case: ONLY statement with not-ONLY for partitioned table*/
105125
CREATETABLEtest.from_only_test(valINTNOT NULL);
106126
INSERT INTOtest.from_only_testSELECT generate_series(1,20);

‎src/partition_creation.c

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ static Datum extract_binary_interval_from_text(Datum interval_text,
4141
Oidpart_atttype,
4242
Oid*interval_type);
4343

44+
staticvoidextract_op_func_and_ret_type(char*opname,Oidtype1,Oidtype2,
45+
Oid*move_bound_op_func,
46+
Oid*move_bound_op_ret_type);
47+
4448
staticOidspawn_partitions_val(Oidparent_relid,
4549
Datumrange_bound_min,
4650
Datumrange_bound_max,
@@ -353,6 +357,29 @@ extract_binary_interval_from_text(Datum interval_text,/* interval as TEXT */
353357
returninterval_binary;
354358
}
355359

360+
/*
361+
* Fetch binary operator by name and return it's function and ret type.
362+
*/
363+
staticvoid
364+
extract_op_func_and_ret_type(char*opname,Oidtype1,Oidtype2,
365+
Oid*move_bound_op_func,/* returned value #1 */
366+
Oid*move_bound_op_ret_type)/* returned value #2 */
367+
{
368+
Operatorop;
369+
370+
/* Get "move bound operator" descriptor */
371+
op=get_binary_operator(opname,type1,type2);
372+
if (!op)
373+
elog(ERROR,"missing %s operator for types %s and %s",
374+
opname,format_type_be(type1),format_type_be(type2));
375+
376+
*move_bound_op_func=oprfuncid(op);
377+
*move_bound_op_ret_type=get_operator_ret_type(op);
378+
379+
/* Don't forget to release system cache */
380+
ReleaseSysCache(op);
381+
}
382+
356383
/*
357384
* Append\prepend partitions if there's no partition to store 'value'.
358385
*
@@ -373,8 +400,8 @@ spawn_partitions_val(Oid parent_relid,/* parent's Oid */
373400
{
374401
boolshould_append;/* append or prepend? */
375402

376-
Operatormove_bound_op;/*descriptor */
377-
Oidmove_bound_optype;/* operator's ret type */
403+
Oidmove_bound_op_func,/*operator's function */
404+
move_bound_op_ret_type;/* operator's ret type */
378405

379406
FmgrInfocmp_value_bound_finfo,/* exec 'value (>=|<) bound' */
380407
move_bound_finfo;/* exec 'bound + interval' */
@@ -404,36 +431,45 @@ spawn_partitions_val(Oid parent_relid,/* parent's Oid */
404431
/* There's a gap, halt and emit ERROR */
405432
elseelog(ERROR,"cannot spawn a partition inside a gap");
406433

407-
/* Get "move bound operator" descriptor */
408-
move_bound_op=get_binary_operator(should_append ?"+" :"-",
409-
range_bound_type,
410-
interval_type);
411-
/* Get operator's ret type */
412-
move_bound_optype=get_operator_ret_type(move_bound_op);
413-
414-
/* Get operator's underlying function */
415-
fmgr_info(oprfuncid(move_bound_op),&move_bound_finfo);
416-
417-
/* Don't forget to release system cache */
418-
ReleaseSysCache(move_bound_op);
434+
/* Fetch operator's underlying function and ret type */
435+
extract_op_func_and_ret_type(should_append ?"+" :"-",
436+
range_bound_type,
437+
interval_type,
438+
&move_bound_op_func,
439+
&move_bound_op_ret_type);
419440

420-
/* Performsomecasts if types don't match */
421-
if (move_bound_optype!=range_bound_type)
441+
/* Perform casts if types don't match (e.g. date + interval = timestamp) */
442+
if (move_bound_op_ret_type!=range_bound_type)
422443
{
444+
/* Cast 'cur_leading_bound' to 'move_bound_op_ret_type' */
423445
cur_leading_bound=perform_type_cast(cur_leading_bound,
424446
range_bound_type,
425-
move_bound_optype,
447+
move_bound_op_ret_type,
426448
NULL);/* might emit ERROR */
427449

428450
/* Update 'range_bound_type' */
429-
range_bound_type=move_bound_optype;
451+
range_bound_type=move_bound_op_ret_type;
430452

431453
/* Fetch new comparison function */
432454
fill_type_cmp_fmgr_info(&cmp_value_bound_finfo,
433455
value_type,
434456
range_bound_type);
457+
458+
/* Since type has changed, fetch another operator */
459+
extract_op_func_and_ret_type(should_append ?"+" :"-",
460+
range_bound_type,
461+
interval_type,
462+
&move_bound_op_func,
463+
&move_bound_op_ret_type);
464+
465+
/* What, again? Don't want to deal with this nightmare */
466+
if (move_bound_op_ret_type!=range_bound_type)
467+
elog(ERROR,"error in spawn_partitions_val()");
435468
}
436469

470+
/* Get operator's underlying function */
471+
fmgr_info(move_bound_op_func,&move_bound_finfo);
472+
437473
/* Execute comparison function cmp(value, cur_leading_bound) */
438474
while (should_append ?
439475
check_ge(&cmp_value_bound_finfo,value,cur_leading_bound) :

‎src/utils.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ fill_type_cmp_fmgr_info(FmgrInfo *finfo, Oid type1, Oid type2)
6666
Oidcmp_proc_oid;
6767
TypeCacheEntry*tce;
6868

69+
if (IsBinaryCoercible(type1,type2))
70+
type1=type2;
71+
72+
elseif (IsBinaryCoercible(type2,type1))
73+
type2=type1;
74+
6975
tce=lookup_type_cache(type1,TYPECACHE_BTREE_OPFAMILY);
7076

7177
cmp_proc_oid=get_opfamily_proc(tce->btree_opf,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp