You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@age.apache.org by jg...@apache.org on 2021/04/03 00:24:44 UTC

[incubator-age] branch master updated: Add operator overload for agtype int operations

This is an automated email from the ASF dual-hosted git repository.

jgemignani pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-age.git


The following commit(s) were added to refs/heads/master by this push:
     new 2980634  Add operator overload for agtype int operations
2980634 is described below

commit 298063451252aeb473ad48ec4c722210339034cb
Author: John Gemignani <jr...@gmail.com>
AuthorDate: Fri Apr 2 16:14:07 2021 -0700

    Add operator overload for agtype int operations
    
    Overloaded operators for agtype and int operations to bypass
    implicit float casting.
    
    Added regression tests
---
 age--0.3.0.sql                     | 145 ++++++++++++++++++
 regress/expected/agtype.out        | 291 +++++++++++++++++++++++++++++++++++++
 regress/expected/expr.out          |  22 +--
 regress/sql/agtype.sql             |  68 +++++++++
 src/backend/utils/adt/agtype.c     |   4 +-
 src/backend/utils/adt/agtype_ops.c |  92 +++++++++++-
 src/include/utils/agtype.h         |   2 +
 7 files changed, 610 insertions(+), 14 deletions(-)

diff --git a/age--0.3.0.sql b/age--0.3.0.sql
index 0ff5dda..c35d6d3 100644
--- a/age--0.3.0.sql
+++ b/age--0.3.0.sql
@@ -364,6 +364,36 @@ CREATE OPERATOR + (
   COMMUTATOR = +
 );
 
+CREATE FUNCTION ag_catalog.agtype_bigint_add(agtype, bigint)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR + (
+  FUNCTION = ag_catalog.agtype_bigint_add,
+  LEFTARG = agtype,
+  RIGHTARG =  bigint,
+  COMMUTATOR = +
+);
+
+CREATE FUNCTION ag_catalog.agtype_bigint_add(bigint, agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR + (
+  FUNCTION = ag_catalog.agtype_bigint_add,
+  LEFTARG = bigint,
+  RIGHTARG =  agtype,
+  COMMUTATOR = +
+);
+
 CREATE FUNCTION ag_catalog.agtype_sub(agtype, agtype)
 RETURNS agtype
 LANGUAGE c
@@ -378,6 +408,34 @@ CREATE OPERATOR - (
   RIGHTARG = agtype
 );
 
+CREATE FUNCTION ag_catalog.agtype_bigint_sub(agtype, bigint)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR - (
+  FUNCTION = ag_catalog.agtype_bigint_sub,
+  LEFTARG = agtype,
+  RIGHTARG =  bigint
+);
+
+CREATE FUNCTION ag_catalog.agtype_bigint_sub(bigint, agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR - (
+  FUNCTION = ag_catalog.agtype_bigint_sub,
+  LEFTARG = bigint,
+  RIGHTARG =  agtype
+);
+
 CREATE FUNCTION ag_catalog.agtype_neg(agtype)
 RETURNS agtype
 LANGUAGE c
@@ -406,6 +464,36 @@ CREATE OPERATOR * (
   COMMUTATOR = *
 );
 
+CREATE FUNCTION ag_catalog.agtype_bigint_mul(agtype, bigint)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR * (
+  FUNCTION = ag_catalog.agtype_bigint_mul,
+  LEFTARG = agtype,
+  RIGHTARG =  bigint,
+  COMMUTATOR = *
+);
+
+CREATE FUNCTION ag_catalog.agtype_bigint_mul(bigint, agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR * (
+  FUNCTION = ag_catalog.agtype_bigint_mul,
+  LEFTARG = bigint,
+  RIGHTARG =  agtype,
+  COMMUTATOR = *
+);
+
 CREATE FUNCTION ag_catalog.agtype_div(agtype, agtype)
 RETURNS agtype
 LANGUAGE c
@@ -420,6 +508,34 @@ CREATE OPERATOR / (
   RIGHTARG = agtype
 );
 
+CREATE FUNCTION ag_catalog.agtype_bigint_div(agtype, bigint)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR / (
+  FUNCTION = ag_catalog.agtype_bigint_div,
+  LEFTARG = agtype,
+  RIGHTARG =  bigint
+);
+
+CREATE FUNCTION ag_catalog.agtype_bigint_div(bigint, agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR / (
+  FUNCTION = ag_catalog.agtype_bigint_div,
+  LEFTARG = bigint,
+  RIGHTARG =  agtype
+);
+
 CREATE FUNCTION ag_catalog.agtype_mod(agtype, agtype)
 RETURNS agtype
 LANGUAGE c
@@ -434,6 +550,35 @@ CREATE OPERATOR % (
   RIGHTARG = agtype
 );
 
+CREATE FUNCTION ag_catalog.agtype_bigint_mod(agtype, bigint)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR % (
+  FUNCTION = ag_catalog.agtype_bigint_mod,
+  LEFTARG = agtype,
+  RIGHTARG =  bigint
+);
+
+CREATE FUNCTION ag_catalog.agtype_bigint_mod(bigint, agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR % (
+  FUNCTION = ag_catalog.agtype_bigint_mod,
+  LEFTARG = bigint,
+  RIGHTARG =  agtype
+);
+
+
 CREATE FUNCTION ag_catalog.agtype_pow(agtype, agtype)
 RETURNS agtype
 LANGUAGE c
diff --git a/regress/expected/agtype.out b/regress/expected/agtype.out
index 779faf3..b3b113d 100644
--- a/regress/expected/agtype.out
+++ b/regress/expected/agtype.out
@@ -394,6 +394,106 @@ SELECT agtype_pow('2.0::numeric', '-1.0::numeric');
 (1 row)
 
 --
+-- Test overloaded agtype bigint mathematical operator functions
+-- +, -, *, /, and %
+--
+SELECT agtype_bigint_add('1', -1);
+ agtype_bigint_add 
+-------------------
+ 0
+(1 row)
+
+SELECT agtype_bigint_add('1.0', -1);
+ agtype_bigint_add 
+-------------------
+ 0.0
+(1 row)
+
+SELECT agtype_bigint_add('1::numeric', 1);
+ agtype_bigint_add 
+-------------------
+ 2::numeric
+(1 row)
+
+SELECT agtype_bigint_add('1.0::numeric', 1);
+ agtype_bigint_add 
+-------------------
+ 2.0::numeric
+(1 row)
+
+SELECT agtype_bigint_sub('1', -1);
+ agtype_bigint_sub 
+-------------------
+ 2
+(1 row)
+
+SELECT agtype_bigint_sub('1.0', -1);
+ agtype_bigint_sub 
+-------------------
+ 2.0
+(1 row)
+
+SELECT agtype_bigint_sub('1::numeric', 1);
+ agtype_bigint_sub 
+-------------------
+ 0::numeric
+(1 row)
+
+SELECT agtype_bigint_sub('1.0::numeric', 1);
+ agtype_bigint_sub 
+-------------------
+ 0.0::numeric
+(1 row)
+
+SELECT agtype_bigint_mul('-2', 3);
+ agtype_bigint_mul 
+-------------------
+ -6
+(1 row)
+
+SELECT agtype_bigint_mul('2.0', -3);
+ agtype_bigint_mul 
+-------------------
+ -6.0
+(1 row)
+
+SELECT agtype_bigint_mul('-2::numeric', 3);
+ agtype_bigint_mul 
+-------------------
+ -6::numeric
+(1 row)
+
+SELECT agtype_bigint_mul('-2.0::numeric', 3);
+ agtype_bigint_mul 
+-------------------
+ -6.0::numeric
+(1 row)
+
+SELECT agtype_bigint_div('-4', 3);
+ agtype_bigint_div 
+-------------------
+ -1
+(1 row)
+
+SELECT agtype_bigint_div('4.0', -3);
+ agtype_bigint_div 
+-------------------
+ -1.33333333333333
+(1 row)
+
+SELECT agtype_bigint_div('-4::numeric', 3);
+      agtype_bigint_div       
+------------------------------
+ -1.3333333333333333::numeric
+(1 row)
+
+SELECT agtype_bigint_div('-4.0::numeric', 3);
+      agtype_bigint_div       
+------------------------------
+ -1.3333333333333333::numeric
+(1 row)
+
+--
 -- Should fail with divide by zero
 --
 SELECT agtype_div('1', '0');
@@ -414,6 +514,14 @@ SELECT agtype_div('1::numeric', '0.0');
 ERROR:  division by zero
 SELECT agtype_div('1::numeric', '0::numeric');
 ERROR:  division by zero
+SELECT agtype_bigint_div('1', 0);
+ERROR:  division by zero
+SELECT agtype_bigint_div('1.0', 0);
+ERROR:  division by zero
+SELECT agtype_bigint_div('-1::numeric', 0);
+ERROR:  division by zero
+SELECT agtype_bigint_div('-1.0::numeric', 0);
+ERROR:  division by zero
 --
 -- Should get Infinity
 --
@@ -518,6 +626,189 @@ SELECT '3.14::numeric'::agtype + '3.14::numeric'::agtype;
 (1 row)
 
 --
+-- Test overloaded bigint operators +, -, *, /, %
+--
+SELECT '3'::agtype + 3;
+ ?column? 
+----------
+ 6
+(1 row)
+
+SELECT '3.14'::agtype + 3;
+ ?column? 
+----------
+ 6.14
+(1 row)
+
+SELECT '3.14::numeric'::agtype + 3;
+   ?column?    
+---------------
+ 6.14::numeric
+(1 row)
+
+SELECT 3 + '3'::agtype;
+ ?column? 
+----------
+ 6
+(1 row)
+
+SELECT 3 + '3.14'::agtype;
+ ?column? 
+----------
+ 6.14
+(1 row)
+
+SELECT 3 + '3.14::numeric'::agtype;
+   ?column?    
+---------------
+ 6.14::numeric
+(1 row)
+
+SELECT '3'::agtype - 3;
+ ?column? 
+----------
+ 0
+(1 row)
+
+SELECT '3.14'::agtype - 3;
+ ?column? 
+----------
+ 0.14
+(1 row)
+
+SELECT '3.14::numeric'::agtype - 3;
+   ?column?    
+---------------
+ 0.14::numeric
+(1 row)
+
+SELECT 3 - '3'::agtype;
+ ?column? 
+----------
+ 0
+(1 row)
+
+SELECT 3 - '3.14'::agtype;
+ ?column? 
+----------
+ -0.14
+(1 row)
+
+SELECT 3 - '3.14::numeric'::agtype;
+    ?column?    
+----------------
+ -0.14::numeric
+(1 row)
+
+SELECT '3'::agtype * 3;
+ ?column? 
+----------
+ 9
+(1 row)
+
+SELECT '3.14'::agtype * 3;
+ ?column? 
+----------
+ 9.42
+(1 row)
+
+SELECT '3.14::numeric'::agtype * 3;
+   ?column?    
+---------------
+ 9.42::numeric
+(1 row)
+
+SELECT 3 * '3'::agtype;
+ ?column? 
+----------
+ 9
+(1 row)
+
+SELECT 3 * '3.14'::agtype;
+ ?column? 
+----------
+ 9.42
+(1 row)
+
+SELECT 3 * '3.14::numeric'::agtype;
+   ?column?    
+---------------
+ 9.42::numeric
+(1 row)
+
+SELECT '3'::agtype / 3;
+ ?column? 
+----------
+ 1
+(1 row)
+
+SELECT '3.14'::agtype / 3;
+     ?column?     
+------------------
+ 1.04666666666667
+(1 row)
+
+SELECT '3.14::numeric'::agtype / 3;
+            ?column?             
+---------------------------------
+ 1.04666666666666666667::numeric
+(1 row)
+
+SELECT 3 / '3'::agtype;
+ ?column? 
+----------
+ 1
+(1 row)
+
+SELECT 3 / '3.14'::agtype;
+     ?column?      
+-------------------
+ 0.955414012738854
+(1 row)
+
+SELECT 3 / '3.14::numeric'::agtype;
+            ?column?             
+---------------------------------
+ 0.95541401273885350318::numeric
+(1 row)
+
+SELECT '3'::agtype % 3;
+ ?column? 
+----------
+ 0
+(1 row)
+
+SELECT '3.14'::agtype % 3;
+ ?column? 
+----------
+ 0.14
+(1 row)
+
+SELECT '3.14::numeric'::agtype % 3;
+   ?column?    
+---------------
+ 0.14::numeric
+(1 row)
+
+SELECT 3 % '3'::agtype;
+ ?column? 
+----------
+ 0
+(1 row)
+
+SELECT 3 % '3.14'::agtype;
+ ?column? 
+----------
+ 3.0
+(1 row)
+
+SELECT 3 % '3.14::numeric'::agtype;
+   ?column?    
+---------------
+ 3.00::numeric
+(1 row)
+
+--
 -- Test orderability of comparison operators =, <>, <, >, <=, >=
 -- These should all return true
 -- Integer
diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index 90be50b..a9f0c5a 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -4885,16 +4885,16 @@ SELECT * FROM cypher('group_by', $$MATCH (x:L) RETURN x.a, x.b, x.c, x.a + count
 AS (a agtype, b agtype, c agtype, result agtype);
  a | b | c | result 
 ---+---+---+--------
- 3 | 1 | 2 | 8.0
- 2 | 3 | 1 | 8.0
- 1 | 2 | 3 | 8.0
+ 3 | 1 | 2 | 8
+ 2 | 3 | 1 | 8
+ 1 | 2 | 3 | 8
 (3 rows)
 
 SELECT * FROM cypher('group_by', $$MATCH (x:L) RETURN x.a + x.b + x.c, x.a + x.b + x.c + count(*) + count(*) $$)
 AS (a_b_c agtype,  result agtype);
  a_b_c | result 
 -------+--------
- 6     | 12.0
+ 6     | 12
 (1 row)
 
 -- with WITH clause
@@ -4902,25 +4902,25 @@ SELECT * FROM cypher('group_by', $$MATCH(x:L) WITH x, count(x) AS c RETURN x.a +
 AS (result agtype);
  result 
 --------
- 7.0
- 7.0
- 7.0
+ 7
+ 7
+ 7
 (3 rows)
 
 SELECT * FROM cypher('group_by', $$MATCH(x:L) WITH x, count(x) AS c RETURN x.a + x.b + x.c + c + c$$)
 AS (result agtype);
  result 
 --------
- 8.0
- 8.0
- 8.0
+ 8
+ 8
+ 8
 (3 rows)
 
 SELECT * FROM cypher('group_by', $$MATCH(x:L) WITH x.a + x.b + x.c AS v, count(x) as c RETURN v + c + c $$)
 AS (result agtype);
  result 
 --------
- 12.0
+ 12
 (1 row)
 
 -- should fail
diff --git a/regress/sql/agtype.sql b/regress/sql/agtype.sql
index d9e67a0..be1edd3 100644
--- a/regress/sql/agtype.sql
+++ b/regress/sql/agtype.sql
@@ -145,6 +145,30 @@ SELECT agtype_pow('2.0', '-1.0::numeric');
 SELECT agtype_pow('2.0::numeric', '-1.0::numeric');
 
 --
+-- Test overloaded agtype bigint mathematical operator functions
+-- +, -, *, /, and %
+--
+
+SELECT agtype_bigint_add('1', -1);
+SELECT agtype_bigint_add('1.0', -1);
+SELECT agtype_bigint_add('1::numeric', 1);
+SELECT agtype_bigint_add('1.0::numeric', 1);
+
+SELECT agtype_bigint_sub('1', -1);
+SELECT agtype_bigint_sub('1.0', -1);
+SELECT agtype_bigint_sub('1::numeric', 1);
+SELECT agtype_bigint_sub('1.0::numeric', 1);
+
+SELECT agtype_bigint_mul('-2', 3);
+SELECT agtype_bigint_mul('2.0', -3);
+SELECT agtype_bigint_mul('-2::numeric', 3);
+SELECT agtype_bigint_mul('-2.0::numeric', 3);
+
+SELECT agtype_bigint_div('-4', 3);
+SELECT agtype_bigint_div('4.0', -3);
+SELECT agtype_bigint_div('-4::numeric', 3);
+SELECT agtype_bigint_div('-4.0::numeric', 3);
+--
 -- Should fail with divide by zero
 --
 SELECT agtype_div('1', '0');
@@ -157,6 +181,11 @@ SELECT agtype_div('1::numeric', '0');
 SELECT agtype_div('1::numeric', '0.0');
 SELECT agtype_div('1::numeric', '0::numeric');
 
+SELECT agtype_bigint_div('1', 0);
+SELECT agtype_bigint_div('1.0', 0);
+SELECT agtype_bigint_div('-1::numeric', 0);
+SELECT agtype_bigint_div('-1.0::numeric', 0);
+
 --
 -- Should get Infinity
 --
@@ -189,6 +218,45 @@ SELECT '3.14'::agtype + '3.14::numeric'::agtype;
 SELECT '3.14::numeric'::agtype + '3.14::numeric'::agtype;
 
 --
+-- Test overloaded bigint operators +, -, *, /, %
+--
+
+SELECT '3'::agtype + 3;
+SELECT '3.14'::agtype + 3;
+SELECT '3.14::numeric'::agtype + 3;
+SELECT 3 + '3'::agtype;
+SELECT 3 + '3.14'::agtype;
+SELECT 3 + '3.14::numeric'::agtype;
+
+SELECT '3'::agtype - 3;
+SELECT '3.14'::agtype - 3;
+SELECT '3.14::numeric'::agtype - 3;
+SELECT 3 - '3'::agtype;
+SELECT 3 - '3.14'::agtype;
+SELECT 3 - '3.14::numeric'::agtype;
+
+SELECT '3'::agtype * 3;
+SELECT '3.14'::agtype * 3;
+SELECT '3.14::numeric'::agtype * 3;
+SELECT 3 * '3'::agtype;
+SELECT 3 * '3.14'::agtype;
+SELECT 3 * '3.14::numeric'::agtype;
+
+SELECT '3'::agtype / 3;
+SELECT '3.14'::agtype / 3;
+SELECT '3.14::numeric'::agtype / 3;
+SELECT 3 / '3'::agtype;
+SELECT 3 / '3.14'::agtype;
+SELECT 3 / '3.14::numeric'::agtype;
+
+SELECT '3'::agtype % 3;
+SELECT '3.14'::agtype % 3;
+SELECT '3.14::numeric'::agtype % 3;
+SELECT 3 % '3'::agtype;
+SELECT 3 % '3.14'::agtype;
+SELECT 3 % '3.14::numeric'::agtype;
+
+--
 -- Test orderability of comparison operators =, <>, <, >, <=, >=
 -- These should all return true
 -- Integer
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index b78c37d..b6ac788 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -151,7 +151,7 @@ static Numeric get_numeric_compatible_arg(Datum arg, Oid type, char *funcname,
                                        bool *is_null,
                                        enum agtype_value_type *ag_type);
 static agtype_value *string_to_agtype_value(char *s);
-static agtype *get_one_agtype_from_variadic_args(FunctionCallInfo fcinfo,
+agtype *get_one_agtype_from_variadic_args(FunctionCallInfo fcinfo,
                                                  int variadic_offset,
                                                  int expected_nargs);
 PG_FUNCTION_INFO_V1(agtype_in);
@@ -7370,7 +7370,7 @@ agtype_value *alter_property_value(agtype_value *properties, char *var_name, agt
  * If the datum cannot be converted, the function will error out in
  * extract_variadic_args.
  */
-static agtype *get_one_agtype_from_variadic_args(FunctionCallInfo fcinfo,
+agtype *get_one_agtype_from_variadic_args(FunctionCallInfo fcinfo,
                                                  int variadic_offset,
                                                  int expected_nargs)
 {
diff --git a/src/backend/utils/adt/agtype_ops.c b/src/backend/utils/adt/agtype_ops.c
index 5571837..8d3448f 100644
--- a/src/backend/utils/adt/agtype_ops.c
+++ b/src/backend/utils/adt/agtype_ops.c
@@ -172,7 +172,7 @@ Datum agtype_add(PG_FUNCTION_ARGS)
 
     /*
      * One or both values is a string OR one is a string and the other is
-     * either an integer, float, or numeric. If so, concatinate them.
+     * either an integer, float, or numeric. If so, concatenate them.
      */
     if ((agtv_lhs->type == AGTV_STRING || agtv_rhs->type == AGTV_STRING) &&
         (agtv_lhs->type == AGTV_INTEGER || agtv_lhs->type == AGTV_FLOAT ||
@@ -235,6 +235,24 @@ Datum agtype_add(PG_FUNCTION_ARGS)
     AG_RETURN_AGTYPE_P(agtype_value_to_agtype(&agtv_result));
 }
 
+PG_FUNCTION_INFO_V1(agtype_bigint_add);
+
+/* agtype addition between bigint and agtype */
+Datum agtype_bigint_add(PG_FUNCTION_ARGS)
+{
+    agtype *lhs;
+    agtype *rhs;
+    Datum result;
+
+    lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
+    rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+
+    result = DirectFunctionCall2(agtype_add, AGTYPE_P_GET_DATUM(lhs),
+                                             AGTYPE_P_GET_DATUM(rhs));
+
+    AG_RETURN_AGTYPE_P(DATUM_GET_AGTYPE_P(result));
+}
+
 PG_FUNCTION_INFO_V1(agtype_sub);
 
 /*
@@ -302,6 +320,24 @@ Datum agtype_sub(PG_FUNCTION_ARGS)
     AG_RETURN_AGTYPE_P(agtype_value_to_agtype(&agtv_result));
 }
 
+PG_FUNCTION_INFO_V1(agtype_bigint_sub);
+
+/* agtype subtraction between bigint and agtype */
+Datum agtype_bigint_sub(PG_FUNCTION_ARGS)
+{
+    agtype *lhs;
+    agtype *rhs;
+    Datum result;
+
+    lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
+    rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+
+    result = DirectFunctionCall2(agtype_sub, AGTYPE_P_GET_DATUM(lhs),
+                                             AGTYPE_P_GET_DATUM(rhs));
+
+    AG_RETURN_AGTYPE_P(DATUM_GET_AGTYPE_P(result));
+}
+
 PG_FUNCTION_INFO_V1(agtype_neg);
 
 /*
@@ -417,6 +453,24 @@ Datum agtype_mul(PG_FUNCTION_ARGS)
     AG_RETURN_AGTYPE_P(agtype_value_to_agtype(&agtv_result));
 }
 
+PG_FUNCTION_INFO_V1(agtype_bigint_mul);
+
+/* agtype multiplication between bigint and agtype */
+Datum agtype_bigint_mul(PG_FUNCTION_ARGS)
+{
+    agtype *lhs;
+    agtype *rhs;
+    Datum result;
+
+    lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
+    rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+
+    result = DirectFunctionCall2(agtype_mul, AGTYPE_P_GET_DATUM(lhs),
+                                             AGTYPE_P_GET_DATUM(rhs));
+
+    AG_RETURN_AGTYPE_P(DATUM_GET_AGTYPE_P(result));
+}
+
 PG_FUNCTION_INFO_V1(agtype_div);
 
 /*
@@ -512,6 +566,24 @@ Datum agtype_div(PG_FUNCTION_ARGS)
      AG_RETURN_AGTYPE_P(agtype_value_to_agtype(&agtv_result));
 }
 
+PG_FUNCTION_INFO_V1(agtype_bigint_div);
+
+/* agtype division between bigint and agtype */
+Datum agtype_bigint_div(PG_FUNCTION_ARGS)
+{
+    agtype *lhs;
+    agtype *rhs;
+    Datum result;
+
+    lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
+    rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+
+    result = DirectFunctionCall2(agtype_div, AGTYPE_P_GET_DATUM(lhs),
+                                             AGTYPE_P_GET_DATUM(rhs));
+
+    AG_RETURN_AGTYPE_P(DATUM_GET_AGTYPE_P(result));
+}
+
 PG_FUNCTION_INFO_V1(agtype_mod);
 
 /*
@@ -579,6 +651,24 @@ Datum agtype_mod(PG_FUNCTION_ARGS)
     AG_RETURN_AGTYPE_P(agtype_value_to_agtype(&agtv_result));
 }
 
+PG_FUNCTION_INFO_V1(agtype_bigint_mod);
+
+/* agtype modulo between bigint and agtype */
+Datum agtype_bigint_mod(PG_FUNCTION_ARGS)
+{
+    agtype *lhs;
+    agtype *rhs;
+    Datum result;
+
+    lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
+    rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+
+    result = DirectFunctionCall2(agtype_mod, AGTYPE_P_GET_DATUM(lhs),
+                                             AGTYPE_P_GET_DATUM(rhs));
+
+    AG_RETURN_AGTYPE_P(DATUM_GET_AGTYPE_P(result));
+}
+
 PG_FUNCTION_INFO_V1(agtype_pow);
 
 /*
diff --git a/src/include/utils/agtype.h b/src/include/utils/agtype.h
index e7be887..134653e 100644
--- a/src/include/utils/agtype.h
+++ b/src/include/utils/agtype.h
@@ -464,6 +464,8 @@ bool is_decimal_needed(char *numstr);
 int compare_agtype_scalar_values(agtype_value *a, agtype_value *b);
 agtype_value *alter_property_value(agtype_value *properties, char *var_name, agtype *new_v, bool remove_property);
 
+agtype *get_one_agtype_from_variadic_args(FunctionCallInfo fcinfo, int variadic_offset, int expected_nargs);
+
 Datum make_vertex(Datum id, Datum label, Datum properties);
 Datum make_edge(Datum id, Datum startid, Datum endid, Datum label,
                    Datum properties);