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

Commit3b9590b

Browse files
committed
check that interval isnt trivial
1 parentc0a1bb8 commit3b9590b

File tree

1 file changed

+103
-3
lines changed

1 file changed

+103
-3
lines changed

‎src/pl_range_funcs.c

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
#include"utils/array.h"
2727
#include"utils/builtins.h"
2828
#include"utils/lsyscache.h"
29+
#include"utils/numeric.h"
2930
#include"utils/ruleutils.h"
31+
#include"utils/syscache.h"
3032

3133

3234
staticchar*deparse_constraint(Oidrelid,Node*expr);
@@ -48,7 +50,9 @@ static void modify_range_constraint(Oid child_relid,
4850
constBound*upper);
4951
staticchar*get_qualified_rel_name(Oidrelid);
5052
staticvoiddrop_table_by_oid(Oidrelid);
51-
53+
staticboolinterval_is_trivial(Oidatttype,
54+
Datuminterval,
55+
Oidinterval_type);
5256

5357
/* Function declarations */
5458

@@ -620,7 +624,9 @@ validate_interval_value(PG_FUNCTION_ARGS)
620624
Oidpartrel=PG_GETARG_OID(0);
621625
text*attname=PG_GETARG_TEXT_P(1);
622626
PartTypeparttype=DatumGetPartType(PG_GETARG_DATUM(2));
623-
Datumrange_interval=PG_GETARG_DATUM(3);
627+
Datuminterval_text=PG_GETARG_DATUM(3);
628+
Datuminterval_value;
629+
Oidinterval_type;
624630

625631
char*attname_cstr;
626632
Oidatttype;/* type of partitioned attribute */
@@ -643,12 +649,106 @@ validate_interval_value(PG_FUNCTION_ARGS)
643649
atttype=get_attribute_type(partrel,attname_cstr, false);
644650

645651
/* Try converting textual representation */
646-
extract_binary_interval_from_text(range_interval,atttype,NULL);
652+
interval_value=extract_binary_interval_from_text(interval_text,
653+
atttype,
654+
&interval_type);
655+
656+
/* Check that interval isn't trivial */
657+
if (interval_is_trivial(atttype,interval_value,interval_type))
658+
elog(ERROR,"Interval must not be trivial");
647659

648660
PG_RETURN_BOOL(true);
649661
}
650662

651663

664+
/*
665+
* Check that interval is somehow significant to avoid of infinite loops while
666+
* adding new partitions
667+
*
668+
* The main idea behind this function is to add specified interval to some
669+
* default value (zero for numeric types and '1970-01-01' for datetime types)
670+
* and look if it is changed. If it is then return true.
671+
*/
672+
staticbool
673+
interval_is_trivial(Oidatttype,Datuminterval,Oidinterval_type)
674+
{
675+
Datumdefault_value;
676+
Datumop_result;
677+
Oidop_result_type;
678+
Operatorop;
679+
Oidop_func;
680+
FmgrInfocmp_func;
681+
682+
/* Generate default value */
683+
switch(atttype)
684+
{
685+
caseINT2OID:
686+
caseINT4OID:
687+
caseINT8OID:
688+
default_value=Int16GetDatum(0);
689+
break;
690+
caseFLOAT4OID:
691+
default_value=Float4GetDatum(0);
692+
break;
693+
caseFLOAT8OID:
694+
default_value=Float8GetDatum(0);
695+
break;
696+
caseNUMERICOID:
697+
default_value=NumericGetDatum(0);
698+
break;
699+
caseTIMESTAMPOID:
700+
caseTIMESTAMPTZOID:
701+
default_value=TimestampGetDatum(GetCurrentTimestamp());
702+
break;
703+
caseDATEOID:
704+
{
705+
Datumts=TimestampGetDatum(GetCurrentTimestamp());
706+
707+
default_value=perform_type_cast(ts,TIMESTAMPTZOID,DATEOID,NULL);
708+
}
709+
break;
710+
default:
711+
return false;
712+
}
713+
714+
/* Find suitable addition operator for default value and interval */
715+
op=get_binary_operator("+",atttype,interval_type);
716+
if (!op)
717+
elog(ERROR,"missing \"+\" operator for types %s and %s",
718+
format_type_be(atttype),
719+
format_type_be(interval_type));
720+
721+
op_func=oprfuncid(op);
722+
op_result_type=get_operator_ret_type(op);
723+
ReleaseSysCache(op);
724+
725+
/* Invoke addition operator and get a result*/
726+
op_result=OidFunctionCall2(op_func,default_value,interval);
727+
728+
/*
729+
* If operator result type isn't the same as original value then
730+
* convert it
731+
*/
732+
if (op_result_type!=atttype)
733+
{
734+
op_result=perform_type_cast(op_result,op_result_type,atttype,NULL);
735+
op_result_type=atttype;
736+
}
737+
738+
/*
739+
* Compare it to the default_value. If they are the same then obviously
740+
* interval is trivial
741+
*/
742+
fill_type_cmp_fmgr_info(&cmp_func,
743+
getBaseType(atttype),
744+
getBaseType(op_result_type));
745+
if (DatumGetInt32(FunctionCall2(&cmp_func,default_value,op_result))==0)
746+
return true;
747+
748+
return false;
749+
}
750+
751+
652752
/*
653753
* ------------------
654754
* Helper functions

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp