@@ -628,9 +628,6 @@ validate_interval_value(PG_FUNCTION_ARGS)
628628 Datum interval_value ;
629629 Oid interval_type ;
630630
631- char * attname_cstr ;
632- Oid atttype ; /* type of partitioned attribute */
633-
634631 if (PG_ARGISNULL (0 ))
635632 elog (ERROR , "'partrel' should not be NULL" );
636633
@@ -640,34 +637,43 @@ validate_interval_value(PG_FUNCTION_ARGS)
640637 if (PG_ARGISNULL (2 ))
641638 elog (ERROR , "'parttype' should not be NULL" );
642639
643- /* it's OK if interval is NULL and table is HASH-partitioned */
644- if (PG_ARGISNULL (3 ))
645- PG_RETURN_BOOL (parttype == PT_HASH );
640+ /*
641+ * NULL interval is fine for both HASH and RANGE. But for RANGE we need
642+ * to make some additional checks
643+ */
644+ if (!PG_ARGISNULL (3 ))
645+ {
646+ char * attname_cstr ;
647+ Oid atttype ; /* type of partitioned attribute */
648+
649+ if (parttype == PT_HASH )
650+ elog (ERROR , "interval must be NULL for HASH partitioned table" );
646651
647- /* Convert attname to CSTRING and fetch column's type */
648- attname_cstr = text_to_cstring (attname );
649- atttype = get_attribute_type (partrel , attname_cstr , false);
652+ /* Convert attname to CSTRING and fetch column's type */
653+ attname_cstr = text_to_cstring (attname );
654+ atttype = get_attribute_type (partrel , attname_cstr , false);
650655
651- /* Try converting textual representation */
652- interval_value = extract_binary_interval_from_text (interval_text ,
653- atttype ,
654- & interval_type );
656+ /* Try converting textual representation */
657+ interval_value = extract_binary_interval_from_text (interval_text ,
658+ atttype ,
659+ & interval_type );
655660
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" );
661+ /* Check that interval isn't trivial */
662+ if (interval_is_trivial (atttype , interval_value , interval_type ))
663+ elog (ERROR , "interval must not be trivial" );
664+ }
659665
660666 PG_RETURN_BOOL (true);
661667}
662668
663669
664670/*
665- * Check that interval is somehow significant to avoid of infinite loops while
666- * adding new partitions
671+ * Check if interval is insignificant to avoid infinite loops while adding
672+ * new partitions
667673 *
668674 * 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.
675+ * default value (zero for numeric types and current date/timestamp for datetime
676+ * types) and look if it is changed. If it is then return true.
671677 */
672678static bool
673679interval_is_trivial (Oid atttype , Datum interval , Oid interval_type )
@@ -727,7 +733,13 @@ interval_is_trivial(Oid atttype, Datum interval, Oid interval_type)
727733
728734 /*
729735 * If operator result type isn't the same as original value then
730- * convert it
736+ * convert it. We need this to make sure that specified interval would
737+ * change the _origianal_ value somehow. For example, if we add one second
738+ * to a date then we'll get a timestamp which is one second later than
739+ * original date (obviously). But when we convert it back to a date we will
740+ * get the same original value meaning that one second interval wouldn't
741+ * change original value anyhow. We should consider such interval
742+ * as trivial
731743 */
732744 if (op_result_type != atttype )
733745 {
0 commit comments