@@ -2832,14 +2832,9 @@ check_new_partition_bound(char *relname, Relation parent,
28322832
28332833 if (partdesc -> nparts > 0 )
28342834 {
2835- Datum * * datums = boundinfo -> datums ;
2836- int ndatums = boundinfo -> ndatums ;
28372835 int greatest_modulus ;
28382836 int remainder ;
28392837 int offset ;
2840- bool valid_modulus = true;
2841- int prev_modulus , /* Previous largest modulus */
2842- next_modulus ; /* Next largest modulus */
28432838
28442839 /*
28452840 * Check rule that every modulus must be a factor of the
@@ -2849,7 +2844,9 @@ check_new_partition_bound(char *relname, Relation parent,
28492844 * modulus 15, but you cannot add both a partition with
28502845 * modulus 10 and a partition with modulus 15, because 10
28512846 * is not a factor of 15.
2852- *
2847+ */
2848+
2849+ /*
28532850 * Get the greatest (modulus, remainder) pair contained in
28542851 * boundinfo->datums that is less than or equal to the
28552852 * (spec->modulus, spec->remainder) pair.
@@ -2859,26 +2856,55 @@ check_new_partition_bound(char *relname, Relation parent,
28592856 spec -> remainder );
28602857 if (offset < 0 )
28612858 {
2862- next_modulus = DatumGetInt32 (datums [0 ][0 ]);
2863- valid_modulus = (next_modulus % spec -> modulus ) == 0 ;
2859+ int next_modulus ;
2860+
2861+ /*
2862+ * All existing moduli are greater or equal, so the
2863+ * new one must be a factor of the smallest one, which
2864+ * is first in the boundinfo.
2865+ */
2866+ next_modulus = DatumGetInt32 (boundinfo -> datums [0 ][0 ]);
2867+ if (next_modulus % spec -> modulus != 0 )
2868+ ereport (ERROR ,
2869+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
2870+ errmsg ("every hash partition modulus must be a factor of the next larger modulus" ),
2871+ errdetail ("The new modulus %d is not a factor of %d, the modulus of existing partition \"%s\"." ,
2872+ spec -> modulus , next_modulus ,
2873+ get_rel_name (partdesc -> oids [boundinfo -> indexes [0 ]]))));
28642874 }
28652875 else
28662876 {
2867- prev_modulus = DatumGetInt32 (datums [offset ][0 ]);
2868- valid_modulus = (spec -> modulus % prev_modulus ) == 0 ;
2877+ int prev_modulus ;
2878+
2879+ /* We found the largest modulus less than or equal to ours. */
2880+ prev_modulus = DatumGetInt32 (boundinfo -> datums [offset ][0 ]);
2881+
2882+ if (spec -> modulus % prev_modulus != 0 )
2883+ ereport (ERROR ,
2884+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
2885+ errmsg ("every hash partition modulus must be a factor of the next larger modulus" ),
2886+ errdetail ("The new modulus %d is not divisible by %d, the modulus of existing partition \"%s\"." ,
2887+ spec -> modulus ,
2888+ prev_modulus ,
2889+ get_rel_name (partdesc -> oids [boundinfo -> indexes [offset ]]))));
28692890
2870- if (valid_modulus && ( offset + 1 ) < ndatums )
2891+ if (offset + 1 < boundinfo -> ndatums )
28712892 {
2872- next_modulus = DatumGetInt32 (datums [offset + 1 ][0 ]);
2873- valid_modulus = (next_modulus % spec -> modulus ) == 0 ;
2893+ int next_modulus ;
2894+
2895+ /* Look at the next higher modulus */
2896+ next_modulus = DatumGetInt32 (boundinfo -> datums [offset + 1 ][0 ]);
2897+
2898+ if (next_modulus % spec -> modulus != 0 )
2899+ ereport (ERROR ,
2900+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
2901+ errmsg ("every hash partition modulus must be a factor of the next larger modulus" ),
2902+ errdetail ("The new modulus %d is not factor of %d, the modulus of existing partition \"%s\"." ,
2903+ spec -> modulus , next_modulus ,
2904+ get_rel_name (partdesc -> oids [boundinfo -> indexes [offset + 1 ]]))));
28742905 }
28752906 }
28762907
2877- if (!valid_modulus )
2878- ereport (ERROR ,
2879- (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
2880- errmsg ("every hash partition modulus must be a factor of the next larger modulus" )));
2881-
28822908 greatest_modulus = boundinfo -> nindexes ;
28832909 remainder = spec -> remainder ;
28842910
0 commit comments