diff --git a/contrib/pgbench/pgbench.c b/contrib/pgbench/pgbench.c
index ad55c3c..377cc9b 100644
--- a/contrib/pgbench/pgbench.c
+++ b/contrib/pgbench/pgbench.c
@@ -1570,6 +1570,27 @@ top:
 					}
 					snprintf(res, sizeof(res), INT64_FORMAT, ope1 / ope2);
 				}
+				else if (strcmp(argv[3], "%") == 0 || strcmp(argv[3], "mod") == 0 ||
+						 strcmp(argv[3], "fmod") == 0 || strcmp(argv[3], "emod") == 0)
+				{
+					int64_t remainder;
+					if (ope2 == 0)
+					{
+						fprintf(stderr, "%s: division by zero in modulo\n", argv[0]);
+						st->ecnt++;
+						return true;
+					}
+					/* remainder probably keeps the dividend sign in C */
+					remainder = ope1 % ope2;
+					/* floor modulo: adjust remainder sign wrt divisor sign */
+					if (strcmp(argv[3], "fmod") == 0 &&
+						((ope2 < 0 && remainder > 0) || (ope2 > 0 && remainder < 0)))
+						remainder += ope2;
+					/* euclidian modulo: ensure positive remainder */
+					if (strcmp(argv[3], "emod") == 0 && remainder < 0)
+						remainder += llabs(ope2);
+					snprintf(res, sizeof(res), INT64_FORMAT, remainder);
+				}
 				else
 				{
 					fprintf(stderr, "%s: unsupported operator %s\n", argv[0], argv[3]);
diff --git a/doc/src/sgml/pgbench.sgml b/doc/src/sgml/pgbench.sgml
index b7d88f3..4b73911 100644
--- a/doc/src/sgml/pgbench.sgml
+++ b/doc/src/sgml/pgbench.sgml
@@ -735,7 +735,9 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
       Each <replaceable>operand</> is either an integer constant or a
       <literal>:</><replaceable>variablename</> reference to a variable
       having an integer value.  The <replaceable>operator</> can be
-      <literal>+</>, <literal>-</>, <literal>*</>, or <literal>/</>.
+      <literal>+</>, <literal>-</>, <literal>*</>, <literal>/</>, <literal>%</>,
+      <literal>mod</> (dividend sign modulo), <literal>fmod</> (divisor sign modulo)
+      or <literal>emod</> (Euclidian modulo).
      </para>
 
      <para>
