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 9ab41bc  Add openCypher pi function
9ab41bc is described below

commit 9ab41bcf54dfb5c61ffc120b119cd24a507d1847
Author: John Gemignani <[email protected]>
AuthorDate: Fri Sep 4 14:10:50 2020 -0700

    Add openCypher pi function
    
    Added the openCypher pi() function.
    
    Added a field in the function definitions in cypher_expr.c to state
    whether the function is in the pg_catalog, or not.
    
    Added a cast from float8 to agtype.
    Added a cast from agtype (integer and float) to float8.
    
    Added regression tests.
---
 age--0.2.0.sql                     | 27 ++++++++++++
 regress/expected/expr.out          | 64 +++++++++++++++++++++++++++
 regress/sql/expr.sql               | 29 +++++++++++++
 src/backend/catalog/ag_namespace.c |  5 +++
 src/backend/parser/cypher_expr.c   | 89 +++++++++++++++++++++-----------------
 src/backend/parser/cypher_gram.y   |  4 ++
 src/backend/utils/adt/agtype.c     | 53 +++++++++++++++++++++++
 src/backend/utils/ag_func.c        | 32 +++++++++++++-
 src/include/catalog/ag_namespace.h |  1 +
 src/include/utils/ag_func.h        |  1 +
 10 files changed, 265 insertions(+), 40 deletions(-)

diff --git a/age--0.2.0.sql b/age--0.2.0.sql
index 98ab451..9348931 100644
--- a/age--0.2.0.sql
+++ b/age--0.2.0.sql
@@ -694,6 +694,33 @@ AS 'MODULE_PATHNAME';
 CREATE CAST (boolean AS agtype)
 WITH FUNCTION bool_to_agtype(boolean);
 
+-- float8 -> agtype (explicit)
+
+CREATE FUNCTION float8_to_agtype(float8)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE CAST (float8 AS agtype)
+WITH FUNCTION float8_to_agtype(float8);
+
+-- agtype -> float8 (implicit)
+
+CREATE FUNCTION agtype_to_float8(agtype)
+RETURNS float8
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE CAST (agtype AS float8)
+WITH FUNCTION agtype_to_float8(agtype)
+AS IMPLICIT;
+
 --
 -- agtype - access operators
 --
diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index af28b22..b735d00 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -3401,6 +3401,70 @@ HINT:  No function matches the given name and argument 
types. You might need to
 SELECT * FROM r_atan2(1);
 ERROR:  atan2() invalid number of arguments
 --
+-- pi
+--
+SELECT * FROM cypher('expr', $$
+    RETURN pi()
+$$) AS (results agtype);
+     results      
+------------------
+ 3.14159265358979
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN sin(pi())
+$$) AS (results agtype);
+       results        
+----------------------
+ 1.22464679914735e-16
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN sin(pi()/4)
+$$) AS (results agtype);
+      results      
+-------------------
+ 0.707106781186547
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN cos(pi())
+$$) AS (results agtype);
+ results 
+---------
+ -1.0
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN cos(pi()/2)
+$$) AS (results agtype);
+       results        
+----------------------
+ 6.12323399573677e-17
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN sin(pi()/2)
+$$) AS (results agtype);
+ results 
+---------
+ 1.0
+(1 row)
+
+-- should fail
+SELECT * FROM cypher('expr', $$
+    RETURN pi(null)
+$$) AS (results agtype);
+ERROR:  invalid number of input parameters for pi()
+LINE 1: SELECT * FROM cypher('expr', $$
+                                      ^
+SELECT * FROM cypher('expr', $$
+    RETURN pi(1)
+$$) AS (results agtype);
+ERROR:  invalid number of input parameters for pi()
+LINE 1: SELECT * FROM cypher('expr', $$
+                                      ^
+--
 -- Cleanup
 --
 SELECT * FROM drop_graph('expr', true);
diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql
index 246f0f4..a689c8d 100644
--- a/regress/sql/expr.sql
+++ b/regress/sql/expr.sql
@@ -1438,6 +1438,35 @@ SELECT * FROM r_atan2();
 SELECT * FROM r_atan2(1);
 
 --
+-- pi
+--
+SELECT * FROM cypher('expr', $$
+    RETURN pi()
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN sin(pi())
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN sin(pi()/4)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN cos(pi())
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN cos(pi()/2)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN sin(pi()/2)
+$$) AS (results agtype);
+-- should fail
+SELECT * FROM cypher('expr', $$
+    RETURN pi(null)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN pi(1)
+$$) AS (results agtype);
+
+--
 -- Cleanup
 --
 SELECT * FROM drop_graph('expr', true);
diff --git a/src/backend/catalog/ag_namespace.c 
b/src/backend/catalog/ag_namespace.c
index 1c95a8e..4416aaf 100644
--- a/src/backend/catalog/ag_namespace.c
+++ b/src/backend/catalog/ag_namespace.c
@@ -24,3 +24,8 @@ Oid ag_catalog_namespace_id(void)
 {
     return get_namespace_oid("ag_catalog", false);
 }
+
+Oid pg_catalog_namespace_id(void)
+{
+    return get_namespace_oid("pg_catalog", false);
+}
diff --git a/src/backend/parser/cypher_expr.c b/src/backend/parser/cypher_expr.c
index d313d02..359136a 100644
--- a/src/backend/parser/cypher_expr.c
+++ b/src/backend/parser/cypher_expr.c
@@ -43,41 +43,42 @@
 #include "utils/agtype.h"
 
 /* supported function definitions */
-#define FUNC_ENDNODE    {"endNode",    "endnode",    AGTYPEOID, AGTYPEOID, 0, 
AGTYPEOID, 1, 2, true}
-#define FUNC_HEAD       {"head",       "head",       AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_ID         {"id",         "id",         AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_STARTID    {"start_id",   "start_id",   AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_ENDID      {"end_id",     "end_id",     AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_LAST       {"last",       "last",       AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_LENGTH     {"length",     "length",     AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_PROPERTIES {"properties", "properties", AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_SIZE       {"size",       "size",       ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_STARTNODE  {"startNode",  "startnode",  AGTYPEOID, AGTYPEOID, 0, 
AGTYPEOID, 1, 2, true}
-#define FUNC_TOBOOLEAN  {"toBoolean",  "toboolean",  ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_TOFLOAT    {"toFloat",    "tofloat",    ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_TOINTEGER  {"toInteger",  "tointeger",  ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_TYPE       {"type",       "type",       AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_EXISTS     {"exists",     "exists_property", AGTYPEOID, 0, 0, 
BOOLOID, 1, 1, false}
-#define FUNC_TOSTRING   {"toString",   "tostring",   ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_REVERSE    {"reverse",    "reverse",    ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_TOUPPER    {"toUpper",    "touppercase", ANYOID,   0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_TOLOWER    {"toLower",    "tolowercase", ANYOID,   0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_LTRIM      {"lTrim",      "l_trim",     ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_RTRIM      {"rTrim",      "r_trim",     ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_BTRIM      {"trim",       "b_trim",     ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_RSUBSTR    {"right",      "r_substr",   ANYOID,    ANYOID, 0, 
AGTYPEOID, 2, 1, false}
-#define FUNC_LSUBSTR    {"left",       "l_substr",   ANYOID,    ANYOID, 0, 
AGTYPEOID, 2, 1, false}
-#define FUNC_BSUBSTR    {"substring",  "b_substr",   ANYOID,    ANYOID, 
ANYOID, AGTYPEOID, -1, 1, false}
-#define FUNC_SPLIT      {"split",      "split",      ANYOID,    ANYOID, 0, 
AGTYPEOID, 2, 1, false}
-#define FUNC_REPLACE    {"replace",    "replace",    ANYOID,    ANYOID, 0, 
AGTYPEOID, 3, 1, false}
-#define FUNC_RSIN       {"sin",        "r_sin",      ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_RCOS       {"cos",        "r_cos",      ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_RTAN       {"tan",        "r_tan",      ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_RCOT       {"cot",        "r_cot",      ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_RASIN      {"asin",        "r_asin",    ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_RACOS      {"acos",        "r_acos",    ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_RATAN      {"atan",        "r_atan",    ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-#define FUNC_RATAN2     {"atan2",       "r_atan2",   ANYOID,    0, 0, 
AGTYPEOID, 2, 1, false}
+#define FUNC_ENDNODE    {"endNode",    "endnode",    AGTYPEOID, AGTYPEOID, 0, 
AGTYPEOID, 1, 2, true, false}
+#define FUNC_HEAD       {"head",       "head",       AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_ID         {"id",         "id",         AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_STARTID    {"start_id",   "start_id",   AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_ENDID      {"end_id",     "end_id",     AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_LAST       {"last",       "last",       AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_LENGTH     {"length",     "length",     AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_PROPERTIES {"properties", "properties", AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_SIZE       {"size",       "size",       ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_STARTNODE  {"startNode",  "startnode",  AGTYPEOID, AGTYPEOID, 0, 
AGTYPEOID, 1, 2, true, false}
+#define FUNC_TOBOOLEAN  {"toBoolean",  "toboolean",  ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_TOFLOAT    {"toFloat",    "tofloat",    ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_TOINTEGER  {"toInteger",  "tointeger",  ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_TYPE       {"type",       "type",       AGTYPEOID, 0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_EXISTS     {"exists",     "exists_property", AGTYPEOID, 0, 0, 
BOOLOID, 1, 1, false, false}
+#define FUNC_TOSTRING   {"toString",   "tostring",   ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_REVERSE    {"reverse",    "reverse",    ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_TOUPPER    {"toUpper",    "touppercase", ANYOID,   0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_TOLOWER    {"toLower",    "tolowercase", ANYOID,   0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_LTRIM      {"lTrim",      "l_trim",     ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_RTRIM      {"rTrim",      "r_trim",     ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_BTRIM      {"trim",       "b_trim",     ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_RSUBSTR    {"right",      "r_substr",   ANYOID,    ANYOID, 0, 
AGTYPEOID, 2, 1, false, false}
+#define FUNC_LSUBSTR    {"left",       "l_substr",   ANYOID,    ANYOID, 0, 
AGTYPEOID, 2, 1, false, false}
+#define FUNC_BSUBSTR    {"substring",  "b_substr",   ANYOID,    ANYOID, 
ANYOID, AGTYPEOID, -1, 1, false, false}
+#define FUNC_SPLIT      {"split",      "split",      ANYOID,    ANYOID, 0, 
AGTYPEOID, 2, 1, false, false}
+#define FUNC_REPLACE    {"replace",    "replace",    ANYOID,    ANYOID, 0, 
AGTYPEOID, 3, 1, false, false}
+#define FUNC_RSIN       {"sin",        "r_sin",      ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_RCOS       {"cos",        "r_cos",      ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_RTAN       {"tan",        "r_tan",      ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_RCOT       {"cot",        "r_cot",      ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_RASIN      {"asin",       "r_asin",     ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_RACOS      {"acos",       "r_acos",     ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_RATAN      {"atan",       "r_atan",     ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_RATAN2     {"atan2",      "r_atan2",    ANYOID,    0, 0, 
AGTYPEOID, 2, 1, false, false}
+#define FUNC_PI         {"pi",         "pi",         0,         0, 0, 
FLOAT8OID, 0, 0, false, true}
 
 /* supported functions */
 #define SUPPORTED_FUNCTIONS {FUNC_TYPE, FUNC_ENDNODE, FUNC_HEAD, FUNC_ID, \
@@ -90,7 +91,7 @@
                              FUNC_LSUBSTR, FUNC_BSUBSTR, FUNC_SPLIT, \
                              FUNC_REPLACE, FUNC_RSIN, FUNC_RCOS, FUNC_RTAN, \
                              FUNC_RCOT, FUNC_RASIN, FUNC_RACOS, FUNC_RATAN, \
-                             FUNC_RATAN2}
+                             FUNC_RATAN2, FUNC_PI}
 
 /* structure for supported function signatures */
 typedef struct function_signature
@@ -115,6 +116,8 @@ typedef struct function_signature
     int nargs;
     /* needs graph name passed */
     bool needs_graph_name;
+    /* is the function listed in pg_catalog */
+    bool in_pg_catalog;
 } function_signature;
 
 static Node *transform_cypher_expr_recurse(cypher_parsestate *cpstate,
@@ -804,9 +807,17 @@ static Node *transform_cypher_function(cypher_parsestate 
*cpstate,
         fs = &supported_functions[i];
         if (strcmp(funcname, fs->parsed_name) == 0)
         {
-            func_operator_oid = get_ag_func_oid(fs->actual_name, fs->nargs,
-                                                fs->input1_oid, fs->input2_oid,
-                                                fs->input3_oid);
+            /* is the function listed in pg_catalog */
+            if (fs->in_pg_catalog)
+                func_operator_oid = get_pg_func_oid(fs->actual_name, fs->nargs,
+                                                    fs->input1_oid,
+                                                    fs->input2_oid,
+                                                    fs->input3_oid);
+            else
+                func_operator_oid = get_ag_func_oid(fs->actual_name, fs->nargs,
+                                                    fs->input1_oid,
+                                                    fs->input2_oid,
+                                                    fs->input3_oid);
             break;
         }
     }
diff --git a/src/backend/parser/cypher_gram.y b/src/backend/parser/cypher_gram.y
index afd76ac..7f20d6b 100644
--- a/src/backend/parser/cypher_gram.y
+++ b/src/backend/parser/cypher_gram.y
@@ -1453,6 +1453,10 @@ static Node *make_immediate_no_arg_function_expr(char 
*funcname, int location)
 
         return (Node *)node;
     }
+    else if (pg_strcasecmp(funcname, "pi") == 0)
+    {
+        return make_function_expr(funcname, NIL, location);
+    }
     else
         ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR),
                 errmsg("unrecognized or unsupported function")));
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index 8ee02dd..4b165f4 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -2159,6 +2159,49 @@ Datum agtype_to_bool(PG_FUNCTION_ARGS)
     PG_RETURN_BOOL(agtv.val.boolean);
 }
 
+PG_FUNCTION_INFO_V1(agtype_to_float8);
+
+/*
+ * Cast agtype to float8.
+ */
+Datum agtype_to_float8(PG_FUNCTION_ARGS)
+{
+    agtype *agtype_in = AG_GET_ARG_AGTYPE_P(0);
+    agtype_value agtv;
+    float8 result;
+
+    if (!agtype_extract_scalar(&agtype_in->root, &agtv) ||
+        (agtv.type != AGTV_FLOAT && agtv.type != AGTV_INTEGER))
+        cannot_cast_agtype_value(agtv.type, "float");
+
+    PG_FREE_IF_COPY(agtype_in, 0);
+
+    if (agtv.type == AGTV_FLOAT)
+        result = agtv.val.float_value;
+
+    if (agtv.type == AGTV_INTEGER)
+    {
+        /*
+         * Get the string representation of the integer because it could be
+         * too large to fit in a float. Let the float routine determine
+         * what to do with it.
+         */
+        char *string = DatumGetCString(DirectFunctionCall1(int8out,
+                           Int64GetDatum(agtv.val.int_value)));
+        bool is_valid = false;
+        /* turn it into a float */
+        result = float8in_internal_null(string, NULL, "double precision",
+                                     string, &is_valid);
+
+        /* return null if it was not a invalid float */
+        if (!is_valid)
+            ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+                            errmsg("cannot cast to float8, integer value out 
of range")));
+    }
+
+    PG_RETURN_FLOAT8(result);
+}
+
 PG_FUNCTION_INFO_V1(bool_to_agtype);
 
 /*
@@ -2169,6 +2212,16 @@ Datum bool_to_agtype(PG_FUNCTION_ARGS)
     return boolean_to_agtype(PG_GETARG_BOOL(0));
 }
 
+PG_FUNCTION_INFO_V1(float8_to_agtype);
+
+/*
+ * Cast float8 to agtype.
+ */
+Datum float8_to_agtype(PG_FUNCTION_ARGS)
+{
+    return float_to_agtype(PG_GETARG_FLOAT8(0));
+}
+
 /*
  * Helper function for agtype_access_operator map access.
  * Note: This function expects that a map and a scalar key are being passed.
diff --git a/src/backend/utils/ag_func.c b/src/backend/utils/ag_func.c
index 27a04a8..bd78f12 100644
--- a/src/backend/utils/ag_func.c
+++ b/src/backend/utils/ag_func.c
@@ -78,7 +78,37 @@ Oid get_ag_func_oid(const char *func_name, const int nargs, 
...)
                                ObjectIdGetDatum(ag_catalog_namespace_id()));
     if (!OidIsValid(func_oid))
     {
-        ereport(ERROR, (errmsg_internal("function does not exist"),
+        ereport(ERROR, (errmsg_internal("ag function does not exist"),
+                        errdetail_internal("%s(%d)", func_name, nargs)));
+    }
+
+    return func_oid;
+}
+
+Oid get_pg_func_oid(const char *func_name, const int nargs, ...)
+{
+    Oid oids[FUNC_MAX_ARGS];
+    va_list ap;
+    int i;
+    oidvector *arg_types;
+    Oid func_oid;
+
+    AssertArg(func_name);
+    AssertArg(nargs >= 0 && nargs <= FUNC_MAX_ARGS);
+
+    va_start(ap, nargs);
+    for (i = 0; i < nargs; i++)
+        oids[i] = va_arg(ap, Oid);
+    va_end(ap);
+
+    arg_types = buildoidvector(oids, nargs);
+
+    func_oid = GetSysCacheOid3(PROCNAMEARGSNSP, CStringGetDatum(func_name),
+                               PointerGetDatum(arg_types),
+                               ObjectIdGetDatum(pg_catalog_namespace_id()));
+    if (!OidIsValid(func_oid))
+    {
+        ereport(ERROR, (errmsg_internal("pg function does not exist"),
                         errdetail_internal("%s(%d)", func_name, nargs)));
     }
 
diff --git a/src/include/catalog/ag_namespace.h 
b/src/include/catalog/ag_namespace.h
index 94248f1..17269d0 100644
--- a/src/include/catalog/ag_namespace.h
+++ b/src/include/catalog/ag_namespace.h
@@ -20,5 +20,6 @@
 #include "postgres.h"
 
 Oid ag_catalog_namespace_id(void);
+Oid pg_catalog_namespace_id(void);
 
 #endif
diff --git a/src/include/utils/ag_func.h b/src/include/utils/ag_func.h
index 18fd201..e20afeb 100644
--- a/src/include/utils/ag_func.h
+++ b/src/include/utils/ag_func.h
@@ -21,5 +21,6 @@
 
 bool is_oid_ag_func(Oid func_oid, const char *func_name);
 Oid get_ag_func_oid(const char *func_name, const int nargs, ...);
+Oid get_pg_func_oid(const char *func_name, const int nargs, ...);
 
 #endif

Reply via email to