/*
 * For PostgreSQL Database Management System:
 * (formerly known as Postgres, then as Postgres95)
 *
 * Portions Copyright (c) 1996-2010, The PostgreSQL Global Development Group
 *
 * Portions Copyright (c) 1994, The Regents of the University of California
 *
 * Permission to use, copy, modify, and distribute this software and its documentation for any purpose,
 * without fee, and without a written agreement is hereby granted, provided that the above copyright notice
 * and this paragraph and the following two paragraphs appear in all copies.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT,
 * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
 * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA
 * HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */

/*
 * I/O routines for agtype type
 *
 * Portions Copyright (c) 2014-2018, PostgreSQL Global Development Group
 */

#include "postgres.h"

#include <math.h>
#include <float.h>

#include "catalog/pg_type.h"
#include "catalog/namespace.h"
#include "catalog/pg_collation_d.h"
#include "catalog/pg_operator_d.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "parser/parse_coerce.h"
#include "utils/builtins.h"
#include "utils/rel.h"
#include "utils/int8.h"
#include "utils/lsyscache.h"
#include "utils/snapmgr.h"
#include "utils/typcache.h"
#include "utils/age_vle.h"
#include "utils/agtype_parser.h"
#include "utils/ag_float8_supp.h"
#include "utils/agtype_raw.h"
#include "catalog/ag_graph.h"
#include "catalog/ag_label.h"

/* State structure for Percentile aggregate functions */
typedef struct PercentileGroupAggState
{
    /* percentile value */
    float8 percentile;
    /* Sort object we're accumulating data in: */
    Tuplesortstate *sortstate;
    /* Number of normal rows inserted into sortstate: */
    int64 number_of_rows;
    /* Have we already done tuplesort_performsort? */
    bool sort_done;
} PercentileGroupAggState;

typedef enum /* type categories for datum_to_agtype */
{
    AGT_TYPE_NULL, /* null, so we didn't bother to identify */
    AGT_TYPE_BOOL, /* boolean (built-in types only) */
    AGT_TYPE_INTEGER, /* Cypher Integer type */
    AGT_TYPE_FLOAT, /* Cypher Float type */
    AGT_TYPE_NUMERIC, /* numeric (ditto) */
    AGT_TYPE_DATE, /* we use special formatting for datetimes */
    AGT_TYPE_TIMESTAMP, /* we use special formatting for timestamp */
    AGT_TYPE_TIMESTAMPTZ, /* ... and timestamptz */
    AGT_TYPE_AGTYPE, /* AGTYPE */
    AGT_TYPE_JSON, /* JSON */
    AGT_TYPE_JSONB, /* JSONB */
    AGT_TYPE_ARRAY, /* array */
    AGT_TYPE_COMPOSITE, /* composite */
    AGT_TYPE_JSONCAST, /* something with an explicit cast to JSON */
    AGT_TYPE_VERTEX,
    AGT_TYPE_OTHER /* all else */
} agt_type_category;

static inline Datum agtype_from_cstring(char *str, int len);
size_t check_string_length(size_t len);
static void agtype_in_agtype_annotation(void *pstate, char *annotation);
static void agtype_in_object_start(void *pstate);
static void agtype_in_object_end(void *pstate);
static void agtype_in_array_start(void *pstate);
static void agtype_in_array_end(void *pstate);
static void agtype_in_object_field_start(void *pstate, char *fname,
                                         bool isnull);
static void agtype_put_escaped_value(StringInfo out, agtype_value *scalar_val);
static void escape_agtype(StringInfo buf, const char *str);
bool is_decimal_needed(char *numstr);
static void agtype_in_scalar(void *pstate, char *token,
                             agtype_token_type tokentype,
                             char *annotation);
static void agtype_categorize_type(Oid typoid, agt_type_category *tcategory,
                                   Oid *outfuncoid);
static void composite_to_agtype(Datum composite, agtype_in_state *result);
static void array_dim_to_agtype(agtype_in_state *result, int dim, int ndims,
                                int *dims, Datum *vals, bool *nulls,
                                int *valcount, agt_type_category tcategory,
                                Oid outfuncoid);
static void array_to_agtype_internal(Datum array, agtype_in_state *result);
static void datum_to_agtype(Datum val, bool is_null, agtype_in_state *result,
                            agt_type_category tcategory, Oid outfuncoid,
                            bool key_scalar);
static char *agtype_to_cstring_worker(StringInfo out, agtype_container *in,
                                      int estimated_len, bool indent);
static text *agtype_value_to_text(agtype_value *scalar_val,
                                  bool err_not_scalar);
static void add_indent(StringInfo out, bool indent, int level);
static void cannot_cast_agtype_value(enum agtype_value_type type,
                                     const char *sqltype);
static bool agtype_extract_scalar(agtype_container *agtc, agtype_value *res);
static agtype_value *execute_array_access_operator(agtype *array,
                                                   agtype_value *array_value,
                                                   agtype *array_index);
static agtype_value *execute_array_access_operator_internal(agtype *array,
                                                            agtype_value *array_value,
                                                            int64 array_index);
static agtype_value *execute_map_access_operator(agtype *map,
                                                 agtype_value* map_value,
                                                 agtype *key);
static agtype_value *execute_map_access_operator_internal(agtype *map,
                                                          agtype_value *map_value,
                                                          char *key,
                                                          int key_len);
static Datum agtype_object_field_impl(FunctionCallInfo fcinfo,
                                      agtype *agtype_in,
                                      char *key, int key_len, bool as_text);
static Datum agtype_array_element_impl(FunctionCallInfo fcinfo,
                                       agtype *agtype_in, int element,
                                       bool as_text);
static Datum process_access_operator_result(FunctionCallInfo fcinfo,
                                            agtype_value *agtv,
                                            bool as_text);
/* typecast functions */
static void agtype_typecast_object(agtype_in_state *state, char *annotation);
static void agtype_typecast_array(agtype_in_state *state, char *annotation);
/* validation functions */
static bool is_object_vertex(agtype_value *agtv);
static bool is_object_edge(agtype_value *agtv);
static bool is_array_path(agtype_value *agtv);
/* graph entity retrieval */
static Datum get_vertex(const char *graph, const char *vertex_label,
                        int64 graphid);
static char *get_label_name(const char *graph_name, int64 graph_id);
static float8 get_float_compatible_arg(Datum arg, Oid type, char *funcname,
                                       bool *is_null);
static Numeric get_numeric_compatible_arg(Datum arg, Oid type, char *funcname,
                                       bool *is_null,
                                       enum agtype_value_type *ag_type);
agtype *get_one_agtype_from_variadic_args(FunctionCallInfo fcinfo,
                                                 int variadic_offset,
                                                 int expected_nargs);

static int64 get_int64_from_int_datums(Datum d, Oid type, char *funcname,
                                       bool *is_agnull);

static agtype_iterator *get_next_object_key(agtype_iterator *it,
                                            agtype_container *agtc,
                                            agtype_value *key);
static int extract_variadic_args_min(FunctionCallInfo fcinfo,
                                     int variadic_start, bool convert_unknown,
                                     Datum **args, Oid **types, bool **nulls,
                                     int min_num_args);
static agtype_value* agtype_build_map_as_agtype_value(FunctionCallInfo fcinfo);
agtype_value *agtype_composite_to_agtype_value_binary(agtype *a);
static agtype_value *tostring_helper(Datum arg, Oid type, char *msghdr);

/* global storage of  OID for agtype and _agtype */
static Oid g_AGTYPEOID = InvalidOid;
static Oid g_AGTYPEARRAYOID = InvalidOid;

/* helper function to quickly set, if necessary, and retrieve AGTYPEOID */
Oid get_AGTYPEOID(void)
{
    if (g_AGTYPEOID == InvalidOid)
    {
        g_AGTYPEOID = GetSysCacheOid2(TYPENAMENSP, CStringGetDatum("agtype"),
                                      ObjectIdGetDatum(ag_catalog_namespace_id()));
    }

    return g_AGTYPEOID;
}

/* helper function to quickly set, if necessary, and retrieve AGTYPEARRAYOID */
Oid get_AGTYPEARRAYOID(void)
{
    if (g_AGTYPEARRAYOID == InvalidOid)
    {
        g_AGTYPEARRAYOID = GetSysCacheOid2(TYPENAMENSP,
                                           CStringGetDatum("_agtype"),
                                           ObjectIdGetDatum(ag_catalog_namespace_id()));
    }

    return g_AGTYPEARRAYOID;
}

/* helper function to clear the AGTYPEOIDs after a drop extension */
void clear_global_Oids_AGTYPE(void)
{
    g_AGTYPEOID = InvalidOid;
    g_AGTYPEARRAYOID = InvalidOid;
}

/* fast helper function to test for AGTV_NULL in an agtype */
bool is_agtype_null(agtype *agt_arg)
{
    agtype_container *agtc = &agt_arg->root;

    if (AGTYPE_CONTAINER_IS_SCALAR(agtc) &&
            AGTE_IS_NULL(agtc->children[0]))
    {
        return true;
    }
    return false;
}

/*
 * graphid_recv - converts external binary format to a graphid.
 *
 * Copied from PGs int8recv as a graphid is an int64.
 */

PG_FUNCTION_INFO_V1(graphid_recv);

Datum graphid_recv(PG_FUNCTION_ARGS)
{
    StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);

    PG_RETURN_INT64(pq_getmsgint64(buf));
}

/*
 * graphid_send - converts a graphid to binary format.
 *
 * Copied from PGs int8send as a graphid is an int64.
 */

PG_FUNCTION_INFO_V1(graphid_send);

Datum graphid_send(PG_FUNCTION_ARGS)
{
    int64 arg1 = PG_GETARG_INT64(0);
    StringInfoData buf;

    pq_begintypsend(&buf);
    pq_sendint64(&buf, arg1);
    PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

/*
 * agtype recv function copied from PGs jsonb_recv as agtype is based
 * off of jsonb
 *
 * The type is sent as text in binary mode, so this is almost the same
 * as the input function, but it's prefixed with a version number so we
 * can change the binary format sent in future if necessary. For now,
 * only version 1 is supported.
 */
PG_FUNCTION_INFO_V1(agtype_recv);

Datum agtype_recv(PG_FUNCTION_ARGS)
{
    StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
    int version = pq_getmsgint(buf, 1);
    char *str = NULL;
    int nbytes = 0;

    if (version == 1)
    {
        str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
    }
    else
    {
        elog(ERROR, "unsupported agtype version number %d", version);
    }

    return agtype_from_cstring(str, nbytes);
}

/*
 * agtype send function copied from PGs jsonb_send as agtype is based
 * off of jsonb
 *
 * Just send agtype as a version number, then a string of text
 */
PG_FUNCTION_INFO_V1(agtype_send);

Datum agtype_send(PG_FUNCTION_ARGS)
{
    agtype *agt = AG_GET_ARG_AGTYPE_P(0);
    StringInfoData buf;
    StringInfo agtype_text = makeStringInfo();
    int version = 1;

    (void) agtype_to_cstring(agtype_text, &agt->root, VARSIZE(agt));

    pq_begintypsend(&buf);
    pq_sendint8(&buf, version);
    pq_sendtext(&buf, agtype_text->data, agtype_text->len);
    pfree(agtype_text->data);
    pfree(agtype_text);

    PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

PG_FUNCTION_INFO_V1(agtype_in);

/*
 * agtype type input function
 */
Datum agtype_in(PG_FUNCTION_ARGS)
{
    char *str = PG_GETARG_CSTRING(0);

    return agtype_from_cstring(str, strlen(str));
}

PG_FUNCTION_INFO_V1(agtype_out);

/*
 * agtype type output function
 */
Datum agtype_out(PG_FUNCTION_ARGS)
{
    agtype *agt = NULL;
    char *out = NULL;

    agt = AG_GET_ARG_AGTYPE_P(0);

    out = agtype_to_cstring(NULL, &agt->root, VARSIZE(agt));

    PG_RETURN_CSTRING(out);
}

/*
 * agtype_value_from_cstring
 *
 * Helper function to turn an agtype string into an agtype_value.
 *
 * Uses the agtype parser (with hooks) to construct an agtype.
 */

agtype_value *agtype_value_from_cstring(char *str, int len)
{
    agtype_lex_context *lex;
    agtype_in_state state;
    agtype_sem_action sem;

    memset(&state, 0, sizeof(state));
    memset(&sem, 0, sizeof(sem));
    lex = make_agtype_lex_context_cstring_len(str, len, true);

    sem.semstate = (void *)&state;

    sem.object_start = agtype_in_object_start;
    sem.array_start = agtype_in_array_start;
    sem.object_end = agtype_in_object_end;
    sem.array_end = agtype_in_array_end;
    sem.scalar = agtype_in_scalar;
    sem.object_field_start = agtype_in_object_field_start;
    /* callback for annotation (typecasts) */
    sem.agtype_annotation = agtype_in_agtype_annotation;

    parse_agtype(lex, &sem);

    /* after parsing, the item member has the composed agtype structure */
    return state.res;
}

/*
 * agtype_from_cstring
 *
 * Turns agtype string into a Datum of agtype.
 *
 * Calls helper function
 */
static inline Datum agtype_from_cstring(char *str, int len)
{
    agtype_value *agtv = agtype_value_from_cstring(str, len);

    PG_RETURN_POINTER(agtype_value_to_agtype(agtv));
}

size_t check_string_length(size_t len)
{
    if (len > AGTENTRY_OFFLENMASK)
    {
        ereport(ERROR,
                (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                 errmsg("string too long to represent as agtype string"),
                 errdetail("Due to an implementation restriction, agtype strings cannot exceed %d bytes.",
                           AGTENTRY_OFFLENMASK)));
    }

    return len;
}

static void agtype_in_object_start(void *pstate)
{
    agtype_in_state *_state = (agtype_in_state *)pstate;

    _state->res = push_agtype_value(&_state->parse_state, WAGT_BEGIN_OBJECT,
                                    NULL);
}

static void agtype_in_object_end(void *pstate)
{
    agtype_in_state *_state = (agtype_in_state *)pstate;

    _state->res = push_agtype_value(&_state->parse_state, WAGT_END_OBJECT,
                                    NULL);
}

static void agtype_in_array_start(void *pstate)
{
    agtype_in_state *_state = (agtype_in_state *)pstate;

    _state->res = push_agtype_value(&_state->parse_state, WAGT_BEGIN_ARRAY,
                                    NULL);
}

static void agtype_in_array_end(void *pstate)
{
    agtype_in_state *_state = (agtype_in_state *)pstate;

    _state->res = push_agtype_value(&_state->parse_state, WAGT_END_ARRAY,
                                    NULL);
}

static void agtype_in_object_field_start(void *pstate, char *fname,
                                         bool isnull)
{
    agtype_in_state *_state = (agtype_in_state *)pstate;
    agtype_value v;

    Assert(fname != NULL);
    v.type = AGTV_STRING;
    v.val.string.len = check_string_length(strlen(fname));
    v.val.string.val = fname;

    _state->res = push_agtype_value(&_state->parse_state, WAGT_KEY, &v);
}

/* main in function to process annotations */
static void agtype_in_agtype_annotation(void *pstate, char *annotation)
{
    agtype_in_state *_state = (agtype_in_state *)pstate;

    /* verify that our required params are not null */
    Assert(pstate != NULL);
    Assert(annotation != NULL);

    /* pass to the appropriate typecast routine */
    switch (_state->res->type)
    {
    case AGTV_OBJECT:
        agtype_typecast_object(_state, annotation);
        break;
    case AGTV_ARRAY:
        agtype_typecast_array(_state, annotation);
        break;

    /*
     * Maybe we need to eventually move scalar annotations here. However,
     * we need to think about how an actual scalar value may be incorporated
     * into another object. Remember, the scalar is copied in on close, before
     * we would apply the annotation.
     */
    default:
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("unsupported type to annotate")));
        break;
    }
}

/* function to handle object typecasts */
static void agtype_typecast_object(agtype_in_state *state, char *annotation)
{
    agtype_value *agtv = NULL;
    agtype_value *last_updated_value = NULL;
    int len;
    bool top = true;

    /* verify that our required params are not null */
    Assert(annotation != NULL);
    Assert(state != NULL);

    len = strlen(annotation);
    agtv = state->res;

    /*
     * If the parse_state is not NULL, then we are not at the top level
     * and the following must be valid for a nested object with a typecast
     * at the end.
     */
    if (state->parse_state != NULL)
    {
        top = false;
        last_updated_value = state->parse_state->last_updated_value;
        /* make sure there is a value just copied in */
        Assert(last_updated_value != NULL);
        /* and that it is of type object */
        Assert(last_updated_value->type == AGTV_OBJECT);
    }

    /* check for a cast to a vertex */
    if (len == 6 && pg_strncasecmp(annotation, "vertex", len) == 0)
    {
        /* verify that the structure conforms to a valid vertex */
        if (is_object_vertex(agtv))
        {
            agtv->type = AGTV_VERTEX;
            /* if it isn't the top, we need to adjust the copied value */
            if (!top)
                last_updated_value->type = AGTV_VERTEX;
        }
        else
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("object is not a vertex")));
        }

    }
    /* check for a cast to an edge */
    else if (len == 4 && pg_strncasecmp(annotation, "edge", len) == 0)
    {
        /* verify that the structure conforms to a valid edge */
        if (is_object_edge(agtv))
        {
            agtv->type = AGTV_EDGE;
            /* if it isn't the top, we need to adjust the copied value */
            if (!top)
                last_updated_value->type = AGTV_EDGE;
        }
        else
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("object is not a edge")));
        }
    }
    /* otherwise this isn't a supported typecast */
    else
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("invalid annotation value for object")));
    }
}

/* function to handle array typecasts */
static void agtype_typecast_array(agtype_in_state *state, char *annotation)
{
    agtype_value *agtv = NULL;
    agtype_value *last_updated_value = NULL;
    int len;
    bool top = true;

    /* verify that our required params are not null */
    Assert(annotation != NULL);
    Assert(state != NULL);

    len = strlen(annotation);
    agtv = state->res;

    /*
     * If the parse_state is not NULL, then we are not at the top level
     * and the following must be valid for a nested array with a typecast
     * at the end.
     */
    if (state->parse_state != NULL)
    {
        top = false;
        last_updated_value = state->parse_state->last_updated_value;
        /* make sure there is a value just copied in */
        Assert(last_updated_value != NULL);
        /* and that it is of type object */
        Assert(last_updated_value->type == AGTV_ARRAY);
    }

    /* check for a cast to a path */
    if (len == 4 && pg_strncasecmp(annotation, "path", len) == 0)
    {
        /* verify that the array conforms to a valid path */
        if (is_array_path(agtv))
        {
            agtv->type = AGTV_PATH;
            /* if it isn't the top, we need to adjust the copied value */
            if (!top)
                last_updated_value->type = AGTV_PATH;
        }
        else
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("array is not a valid path")));
        }
    }
    /* otherwise this isn't a supported typecast */
    else
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("invalid annotation value for object")));
    }
}

/* helper function to check if an object fits a vertex */
static bool is_object_vertex(agtype_value *agtv)
{
    bool has_id = false;
    bool has_label = false;
    bool has_properties = false;
    int i;

    /* we require a valid object */
    Assert(agtv != NULL);
    Assert(agtv->type == AGTV_OBJECT);

    /* we need 3 pairs for a vertex */
    if (agtv->val.object.num_pairs != 3)
    {
        return false;
    }

    /* iterate through all pairs */
    for (i = 0; i < agtv->val.object.num_pairs; i++)
    {
        agtype_value *key = &agtv->val.object.pairs[i].key;
        agtype_value *value = &agtv->val.object.pairs[i].value;

        char *key_val = key->val.string.val;
        int key_len = key->val.string.len;

        Assert(key->type == AGTV_STRING);

        /* check for an id of type integer */
        if (key_len == 2 &&
            pg_strncasecmp(key_val, "id", key_len) == 0 &&
            value->type == AGTV_INTEGER)
        {
            has_id = true;
        }
        /* check for a label of type string */
        else if (key_len == 5 &&
                 pg_strncasecmp(key_val, "label", key_len) == 0 &&
                 value->type == AGTV_STRING)
        {
            has_label = true;
        }
        /* check for properties of type object */
        else if (key_len == 10 &&
                 pg_strncasecmp(key_val, "properties", key_len) == 0 &&
                 value->type == AGTV_OBJECT)
        {
            has_properties = true;
        }
        /* if it gets to this point, it can't be a vertex */
        else
        {
            return false;
        }
    }
    return (has_id && has_label && has_properties);
}

/* helper function to check if an object fits an edge */
static bool is_object_edge(agtype_value *agtv)
{
    bool has_id = false;
    bool has_label = false;
    bool has_properties = false;
    bool has_start_id = false;
    bool has_end_id = false;
    int i;

    /* we require a valid object */
    Assert(agtv != NULL);
    Assert(agtv->type == AGTV_OBJECT);

    /* we need 5 pairs for an edge */
    if (agtv->val.object.num_pairs != 5)
    {
        return false;
    }

    /* iterate through the pairs */
    for (i = 0; i < agtv->val.object.num_pairs; i++)
    {
        agtype_value *key = &agtv->val.object.pairs[i].key;
        agtype_value *value = &agtv->val.object.pairs[i].value;

        char *key_val = key->val.string.val;
        int key_len = key->val.string.len;

        Assert(key->type == AGTV_STRING);

        /* check for an id of type integer */
        if (key_len == 2 &&
            pg_strncasecmp(key_val, "id", key_len) == 0 &&
            value->type == AGTV_INTEGER)
        {
            has_id = true;
        }
        /* check for a label of type string */
        else if (key_len == 5 &&
                 pg_strncasecmp(key_val, "label", key_len) == 0 &&
                 value->type == AGTV_STRING)
        {
            has_label = true;
        }
        /* check for properties of type object */
        else if (key_len == 10 &&
                 pg_strncasecmp(key_val, "properties", key_len) == 0 &&
                 value->type == AGTV_OBJECT)
        {
            has_properties = true;
        }
        /* check for a start_id of type integer */
        else if (key_len == 8 &&
                 pg_strncasecmp(key_val, "start_id", key_len) == 0 &&
                 value->type == AGTV_INTEGER)
        {
            has_start_id = true;
        }
        /* check for an end_id of type integer */
        else if (key_len == 6 &&
                 pg_strncasecmp(key_val, "end_id", key_len) == 0 &&
                 value->type == AGTV_INTEGER)
        {
            has_end_id = true;
        }
        /* if it gets to this point, it can't be an edge */
        else
        {
            return false;
        }
    }
    return (has_id && has_label && has_properties &&
            has_start_id && has_end_id);
}

/* helper function to check if an array fits a path */
static bool is_array_path(agtype_value *agtv)
{
    agtype_value *element = NULL;
    int i;

    /* we require a valid array */
    Assert(agtv != NULL);
    Assert(agtv->type == AGTV_ARRAY);

    /* the array needs to have an odd number of elements */
    if (agtv->val.array.num_elems < 1 ||
        (agtv->val.array.num_elems - 1) % 2 != 0)
        return false;

    /* iterate through all elements */
    for (i = 0; (i + 1) < agtv->val.array.num_elems; i+=2)
    {
        element = &agtv->val.array.elems[i];
        if (element->type != AGTV_VERTEX)
            return false;

        element = &agtv->val.array.elems[i+1];
        if (element->type != AGTV_EDGE)
            return false;
    }

    /* check the last element */
    element = &agtv->val.array.elems[i];
    if (element->type != AGTV_VERTEX)
        return false;

    return true;
}

static void agtype_put_escaped_value(StringInfo out, agtype_value *scalar_val)
{
    char *numstr;

    switch (scalar_val->type)
    {
    case AGTV_NULL:
        appendBinaryStringInfo(out, "null", 4);
        break;
    case AGTV_STRING:
        escape_agtype(out, pnstrdup(scalar_val->val.string.val,
                                    scalar_val->val.string.len));
        break;
    case AGTV_NUMERIC:
        appendStringInfoString(
            out, DatumGetCString(DirectFunctionCall1(
                     numeric_out, PointerGetDatum(scalar_val->val.numeric))));
        appendBinaryStringInfo(out, "::numeric", 9);
        break;
    case AGTV_INTEGER:
        appendStringInfoString(
            out, DatumGetCString(DirectFunctionCall1(
                     int8out, Int64GetDatum(scalar_val->val.int_value))));
        break;
    case AGTV_FLOAT:
        numstr = DatumGetCString(DirectFunctionCall1(
            float8out, Float8GetDatum(scalar_val->val.float_value)));
        appendStringInfoString(out, numstr);

        if (is_decimal_needed(numstr))
            appendBinaryStringInfo(out, ".0", 2);
        break;
    case AGTV_BOOL:
        if (scalar_val->val.boolean)
            appendBinaryStringInfo(out, "true", 4);
        else
            appendBinaryStringInfo(out, "false", 5);
        break;
    case AGTV_VERTEX:
    {
        agtype *prop;
        scalar_val->type = AGTV_OBJECT;
        prop = agtype_value_to_agtype(scalar_val);
        agtype_to_cstring_worker(out, &prop->root, prop->vl_len_, false);
        appendBinaryStringInfo(out, "::vertex", 8);
        break;
    }
    case AGTV_EDGE:
    {
        agtype *prop;
        scalar_val->type = AGTV_OBJECT;
        prop = agtype_value_to_agtype(scalar_val);
        agtype_to_cstring_worker(out, &prop->root, prop->vl_len_, false);
        appendBinaryStringInfo(out, "::edge", 6);
        break;
    }
    case AGTV_PATH:
    {
        agtype *prop;
        scalar_val->type = AGTV_ARRAY;
        prop = agtype_value_to_agtype(scalar_val);
        agtype_to_cstring_worker(out, &prop->root, prop->vl_len_, false);
        appendBinaryStringInfo(out, "::path", 6);
        break;
    }

    default:
        elog(ERROR, "unknown agtype scalar type");
    }
}

/*
 * Produce an agtype string literal, properly escaping characters in the text.
 */
static void escape_agtype(StringInfo buf, const char *str)
{
    const char *p;

    appendStringInfoCharMacro(buf, '"');
    for (p = str; *p; p++)
    {
        switch (*p)
        {
        case '\b':
            appendStringInfoString(buf, "\\b");
            break;
        case '\f':
            appendStringInfoString(buf, "\\f");
            break;
        case '\n':
            appendStringInfoString(buf, "\\n");
            break;
        case '\r':
            appendStringInfoString(buf, "\\r");
            break;
        case '\t':
            appendStringInfoString(buf, "\\t");
            break;
        case '"':
            appendStringInfoString(buf, "\\\"");
            break;
        case '\\':
            appendStringInfoString(buf, "\\\\");
            break;
        default:
            if ((unsigned char)*p < ' ')
                appendStringInfo(buf, "\\u%04x", (int)*p);
            else
                appendStringInfoCharMacro(buf, *p);
            break;
        }
    }
    appendStringInfoCharMacro(buf, '"');
}

bool is_decimal_needed(char *numstr)
{
    int i;

    Assert(numstr);

    i = (numstr[0] == '-') ? 1 : 0;

    while (numstr[i] != '\0')
    {
        if (numstr[i] < '0' || numstr[i] > '9')
            return false;

        i++;
    }

    return true;
}

/*
 * For agtype we always want the de-escaped value - that's what's in token
 */
static void agtype_in_scalar(void *pstate, char *token,
                             agtype_token_type tokentype,
                             char *annotation)
{
    agtype_in_state *_state = (agtype_in_state *)pstate;
    agtype_value v;
    Datum numd;

    /*
     * Process the scalar typecast annotations, if present, but not if the
     * argument is a null. Typecasting a null is a null.
     */
    if (annotation != NULL && tokentype != AGTYPE_TOKEN_NULL)
    {
        int len = strlen(annotation);

        if (len == 7 && pg_strcasecmp(annotation, "numeric") == 0)
            tokentype = AGTYPE_TOKEN_NUMERIC;
        else if (len == 7 && pg_strcasecmp(annotation, "integer") == 0)
            tokentype = AGTYPE_TOKEN_INTEGER;
        else if (len == 5 && pg_strcasecmp(annotation, "float") == 0)
            tokentype = AGTYPE_TOKEN_FLOAT;
        else
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("invalid annotation value for scalar")));
    }

    switch (tokentype)
    {
    case AGTYPE_TOKEN_STRING:
        Assert(token != NULL);
        v.type = AGTV_STRING;
        v.val.string.len = check_string_length(strlen(token));
        v.val.string.val = token;
        break;
    case AGTYPE_TOKEN_INTEGER:
        Assert(token != NULL);
        v.type = AGTV_INTEGER;
        scanint8(token, false, &v.val.int_value);
        break;
    case AGTYPE_TOKEN_FLOAT:
        Assert(token != NULL);
        v.type = AGTV_FLOAT;
        v.val.float_value = float8in_internal(token, NULL, "double precision",
                                              token);
        break;
    case AGTYPE_TOKEN_NUMERIC:
        Assert(token != NULL);
        v.type = AGTV_NUMERIC;
        numd = DirectFunctionCall3(numeric_in,
                                   CStringGetDatum(token),
                                   ObjectIdGetDatum(InvalidOid),
                                   Int32GetDatum(-1));
        v.val.numeric = DatumGetNumeric(numd);
        break;

    case AGTYPE_TOKEN_TRUE:
        v.type = AGTV_BOOL;
        v.val.boolean = true;
        break;
    case AGTYPE_TOKEN_FALSE:
        v.type = AGTV_BOOL;
        v.val.boolean = false;
        break;
    case AGTYPE_TOKEN_NULL:
        v.type = AGTV_NULL;
        break;
    default:
        /* should not be possible */
        elog(ERROR, "invalid agtype token type");
        break;
    }

    if (_state->parse_state == NULL)
    {
        /* single scalar */
        agtype_value va;

        va.type = AGTV_ARRAY;
        va.val.array.raw_scalar = true;
        va.val.array.num_elems = 1;

        _state->res = push_agtype_value(&_state->parse_state, WAGT_BEGIN_ARRAY,
                                        &va);
        _state->res = push_agtype_value(&_state->parse_state, WAGT_ELEM, &v);
        _state->res = push_agtype_value(&_state->parse_state, WAGT_END_ARRAY,
                                        NULL);
    }
    else
    {
        agtype_value *o = &_state->parse_state->cont_val;

        switch (o->type)
        {
        case AGTV_ARRAY:
            _state->res = push_agtype_value(&_state->parse_state, WAGT_ELEM,
                                            &v);
            break;
        case AGTV_OBJECT:
            _state->res = push_agtype_value(&_state->parse_state, WAGT_VALUE,
                                            &v);
            break;
        default:
            elog(ERROR, "unexpected parent of nested structure");
        }
    }
}

/*
 * agtype_to_cstring
 *     Converts agtype value to a C-string.
 *
 * If 'out' argument is non-null, the resulting C-string is stored inside the
 * StringBuffer.  The resulting string is always returned.
 *
 * A typical case for passing the StringInfo in rather than NULL is where the
 * caller wants access to the len attribute without having to call strlen, e.g.
 * if they are converting it to a text* object.
 */
char *agtype_to_cstring(StringInfo out, agtype_container *in,
                        int estimated_len)
{
    return agtype_to_cstring_worker(out, in, estimated_len, false);
}

/*
 * same thing but with indentation turned on
 */
char *agtype_to_cstring_indent(StringInfo out, agtype_container *in,
                               int estimated_len)
{
    return agtype_to_cstring_worker(out, in, estimated_len, true);
}

/*
 * common worker for above two functions
 */
static char *agtype_to_cstring_worker(StringInfo out, agtype_container *in,
                                      int estimated_len, bool indent)
{
    bool first = true;
    agtype_iterator *it;
    agtype_value v;
    agtype_iterator_token type = WAGT_DONE;
    int level = 0;
    bool redo_switch = false;

    /* If we are indenting, don't add a space after a comma */
    int ispaces = indent ? 1 : 2;

    /*
     * Don't indent the very first item. This gets set to the indent flag at
     * the bottom of the loop.
     */
    bool use_indent = false;
    bool raw_scalar = false;
    bool last_was_key = false;

    if (out == NULL)
        out = makeStringInfo();

    enlargeStringInfo(out, (estimated_len >= 0) ? estimated_len : 64);

    it = agtype_iterator_init(in);

    while (redo_switch ||
           ((type = agtype_iterator_next(&it, &v, false)) != WAGT_DONE))
    {
        redo_switch = false;
        switch (type)
        {
        case WAGT_BEGIN_ARRAY:
            if (!first)
                appendBinaryStringInfo(out, ", ", ispaces);

            if (!v.val.array.raw_scalar)
            {
                add_indent(out, use_indent && !last_was_key, level);
                appendStringInfoCharMacro(out, '[');
            }
            else
            {
                raw_scalar = true;
            }

            first = true;
            level++;
            break;
        case WAGT_BEGIN_OBJECT:
            if (!first)
                appendBinaryStringInfo(out, ", ", ispaces);

            add_indent(out, use_indent && !last_was_key, level);
            appendStringInfoCharMacro(out, '{');

            first = true;
            level++;
            break;
        case WAGT_KEY:
            if (!first)
                appendBinaryStringInfo(out, ", ", ispaces);
            first = true;

            add_indent(out, use_indent, level);

            /* agtype rules guarantee this is a string */
            agtype_put_escaped_value(out, &v);
            appendBinaryStringInfo(out, ": ", 2);

            type = agtype_iterator_next(&it, &v, false);
            if (type == WAGT_VALUE)
            {
                first = false;
                agtype_put_escaped_value(out, &v);
            }
            else
            {
                Assert(type == WAGT_BEGIN_OBJECT || type == WAGT_BEGIN_ARRAY);

                /*
                 * We need to rerun the current switch() since we need to
                 * output the object which we just got from the iterator
                 * before calling the iterator again.
                 */
                redo_switch = true;
            }
            break;
        case WAGT_ELEM:
            if (!first)
                appendBinaryStringInfo(out, ", ", ispaces);
            first = false;

            if (!raw_scalar)
                add_indent(out, use_indent, level);
            agtype_put_escaped_value(out, &v);
            break;
        case WAGT_END_ARRAY:
            level--;
            if (!raw_scalar)
            {
                add_indent(out, use_indent, level);
                appendStringInfoCharMacro(out, ']');
            }
            first = false;
            break;
        case WAGT_END_OBJECT:
            level--;
            add_indent(out, use_indent, level);
            appendStringInfoCharMacro(out, '}');
            first = false;
            break;
        default:
            elog(ERROR, "unknown agtype iterator token type");
        }
        use_indent = indent;
        last_was_key = redo_switch;
    }

    Assert(level == 0);

    return out->data;
}

/*
 * Convert agtype_value(scalar) to text
 */
static text *agtype_value_to_text(agtype_value *scalar_val,
                                  bool err_not_scalar)
{
    text *result = NULL;
    switch (scalar_val->type)
    {
    case AGTV_INTEGER:
        result = cstring_to_text(DatumGetCString(DirectFunctionCall1(
            int8out, Int64GetDatum(scalar_val->val.int_value))));
        break;
    case AGTV_FLOAT:
        result = cstring_to_text(DatumGetCString(DirectFunctionCall1(
            float8out, Float8GetDatum(scalar_val->val.float_value))));
        break;
    case AGTV_STRING:
        result = cstring_to_text_with_len(scalar_val->val.string.val,
                                          scalar_val->val.string.len);
        break;
    case AGTV_NUMERIC:
        result = cstring_to_text(DatumGetCString(DirectFunctionCall1(
            numeric_out, PointerGetDatum(scalar_val->val.numeric))));
        break;
    case AGTV_BOOL:
        result = cstring_to_text((scalar_val->val.boolean) ? "true" : "false");
        break;
    case AGTV_NULL:
        result = NULL;
        break;
    default:
        if (err_not_scalar)
        {
            ereport(
                ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("agtype_value_to_text: unsupported argument agtype %d",
                        scalar_val->type)));
        }
    }
    return result;
}

static void add_indent(StringInfo out, bool indent, int level)
{
    if (indent)
    {
        int i;

        appendStringInfoCharMacro(out, '\n');
        for (i = 0; i < level; i++)
            appendBinaryStringInfo(out, "    ", 4);
    }
}

Datum integer_to_agtype(int64 i)
{
    agtype_value agtv;
    agtype *agt;

    agtv.type = AGTV_INTEGER;
    agtv.val.int_value = i;
    agt = agtype_value_to_agtype(&agtv);

    return AGTYPE_P_GET_DATUM(agt);
}

Datum float_to_agtype(float8 f)
{
    agtype_value agtv;
    agtype *agt;

    agtv.type = AGTV_FLOAT;
    agtv.val.float_value = f;
    agt = agtype_value_to_agtype(&agtv);

    return AGTYPE_P_GET_DATUM(agt);
}

/*
 * s must be a UTF-8 encoded, unescaped, and null-terminated string which is
 * a valid string for internal storage of agtype.
 */
Datum string_to_agtype(char *s)
{
    agtype_value agtv;
    agtype *agt;

    agtv.type = AGTV_STRING;
    agtv.val.string.len = check_string_length(strlen(s));
    agtv.val.string.val = s;
    agt = agtype_value_to_agtype(&agtv);

    return AGTYPE_P_GET_DATUM(agt);
}

Datum boolean_to_agtype(bool b)
{
    agtype_value agtv;
    agtype *agt;

    agtv.type = AGTV_BOOL;
    agtv.val.boolean = b;
    agt = agtype_value_to_agtype(&agtv);

    return AGTYPE_P_GET_DATUM(agt);
}

/*
 * Determine how we want to render values of a given type in datum_to_agtype.
 *
 * Given the datatype OID, return its agt_type_category, as well as the type's
 * output function OID.  If the returned category is AGT_TYPE_JSONCAST,
 * we return the OID of the relevant cast function instead.
 */
static void agtype_categorize_type(Oid typoid, agt_type_category *tcategory,
                                   Oid *outfuncoid)
{
    bool typisvarlena;

    /* Look through any domain */
    typoid = getBaseType(typoid);

    *outfuncoid = InvalidOid;

    /*
     * We need to get the output function for everything except date and
     * timestamp types, booleans, array and composite types, json and jsonb,
     * and non-builtin types where there's a cast to json. In this last case
     * we return the oid of the cast function instead.
     */

    switch (typoid)
    {
    case BOOLOID:
        *tcategory = AGT_TYPE_BOOL;
        break;

    case INT2OID:
    case INT4OID:
    case INT8OID:
        getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
        *tcategory = AGT_TYPE_INTEGER;
        break;

    case FLOAT8OID:
        getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
        *tcategory = AGT_TYPE_FLOAT;
        break;

    case FLOAT4OID:
    case NUMERICOID:
        getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
        *tcategory = AGT_TYPE_NUMERIC;
        break;

    case DATEOID:
        *tcategory = AGT_TYPE_DATE;
        break;

    case TIMESTAMPOID:
        *tcategory = AGT_TYPE_TIMESTAMP;
        break;

    case TIMESTAMPTZOID:
        *tcategory = AGT_TYPE_TIMESTAMPTZ;
        break;

    case JSONBOID:
        *tcategory = AGT_TYPE_JSONB;
        break;

    case JSONOID:
        *tcategory = AGT_TYPE_JSON;
        break;

    default:
        /* Check for arrays and composites */
        if (typoid == AGTYPEOID)
        {
            *tcategory = AGT_TYPE_AGTYPE;
        }
        else if (OidIsValid(get_element_type(typoid)) ||
                 typoid == ANYARRAYOID || typoid == RECORDARRAYOID)
        {
            *tcategory = AGT_TYPE_ARRAY;
        }
        else if (type_is_rowtype(typoid)) /* includes RECORDOID */
        {
            *tcategory = AGT_TYPE_COMPOSITE;
        }
        else if (typoid == GRAPHIDOID)
        {
            getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
            *tcategory = AGT_TYPE_INTEGER;
        }
        else
        {
            /* It's probably the general case ... */
            *tcategory = AGT_TYPE_OTHER;

            /*
             * but first let's look for a cast to json (note: not to
             * jsonb) if it's not built-in.
             */
            if (typoid >= FirstNormalObjectId)
            {
                Oid castfunc;
                CoercionPathType ctype;

                ctype = find_coercion_pathway(JSONOID, typoid,
                                              COERCION_EXPLICIT, &castfunc);
                if (ctype == COERCION_PATH_FUNC && OidIsValid(castfunc))
                {
                    *tcategory = AGT_TYPE_JSONCAST;
                    *outfuncoid = castfunc;
                }
                else
                {
                    /* not a cast type, so just get the usual output func */
                    getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
                }
            }
            else
            {
                /* any other builtin type */
                getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
            }
            break;
        }
    }
}

/*
 * Turn a Datum into agtype, adding it to the result agtype_in_state.
 *
 * tcategory and outfuncoid are from a previous call to agtype_categorize_type,
 * except that if is_null is true then they can be invalid.
 *
 * If key_scalar is true, the value is stored as a key, so insist
 * it's of an acceptable type, and force it to be a AGTV_STRING.
 */
static void datum_to_agtype(Datum val, bool is_null, agtype_in_state *result,
                            agt_type_category tcategory, Oid outfuncoid,
                            bool key_scalar)
{
    char *outputstr;
    bool numeric_error;
    agtype_value agtv;
    bool scalar_agtype = false;

    check_stack_depth();

    /* Convert val to an agtype_value in agtv (in most cases) */
    if (is_null)
    {
        Assert(!key_scalar);
        agtv.type = AGTV_NULL;
    }
    else if (key_scalar &&
             (tcategory == AGT_TYPE_ARRAY || tcategory == AGT_TYPE_COMPOSITE ||
              tcategory == AGT_TYPE_JSON || tcategory == AGT_TYPE_JSONB ||
              tcategory == AGT_TYPE_AGTYPE || tcategory == AGT_TYPE_JSONCAST))
    {
        ereport(
            ERROR,
            (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
             errmsg(
                 "key value must be scalar, not array, composite, or json")));
    }
    else
    {
        if (tcategory == AGT_TYPE_JSONCAST)
            val = OidFunctionCall1(outfuncoid, val);

        switch (tcategory)
        {
        case AGT_TYPE_ARRAY:
            array_to_agtype_internal(val, result);
            break;
        case AGT_TYPE_COMPOSITE:
            composite_to_agtype(val, result);
            break;
        case AGT_TYPE_BOOL:
            if (key_scalar)
            {
                outputstr = DatumGetBool(val) ? "true" : "false";
                agtv.type = AGTV_STRING;
                agtv.val.string.len = strlen(outputstr);
                agtv.val.string.val = outputstr;
            }
            else
            {
                agtv.type = AGTV_BOOL;
                agtv.val.boolean = DatumGetBool(val);
            }
            break;
        case AGT_TYPE_INTEGER:
            outputstr = OidOutputFunctionCall(outfuncoid, val);
            if (key_scalar)
            {
                agtv.type = AGTV_STRING;
                agtv.val.string.len = strlen(outputstr);
                agtv.val.string.val = outputstr;
            }
            else
            {
                Datum intd;

                intd = DirectFunctionCall1(int8in, CStringGetDatum(outputstr));
                agtv.type = AGTV_INTEGER;
                agtv.val.int_value = DatumGetInt64(intd);
                pfree(outputstr);
            }
            break;
        case AGT_TYPE_FLOAT:
            outputstr = OidOutputFunctionCall(outfuncoid, val);
            if (key_scalar)
            {
                agtv.type = AGTV_STRING;
                agtv.val.string.len = strlen(outputstr);
                agtv.val.string.val = outputstr;
            }
            else
            {
                agtv.type = AGTV_FLOAT;
                agtv.val.float_value = DatumGetFloat8(val);
            }
            break;
        case AGT_TYPE_NUMERIC:
            outputstr = OidOutputFunctionCall(outfuncoid, val);
            if (key_scalar)
            {
                /* always quote keys */
                agtv.type = AGTV_STRING;
                agtv.val.string.len = strlen(outputstr);
                agtv.val.string.val = outputstr;
            }
            else
            {
                /*
                 * Make it numeric if it's a valid agtype number, otherwise
                 * a string. Invalid numeric output will always have an
                 * 'N' or 'n' in it (I think).
                 */
                numeric_error = (strchr(outputstr, 'N') != NULL ||
                                 strchr(outputstr, 'n') != NULL);
                if (!numeric_error)
                {
                    Datum numd;

                    agtv.type = AGTV_NUMERIC;
                    numd = DirectFunctionCall3(numeric_in,
                                               CStringGetDatum(outputstr),
                                               ObjectIdGetDatum(InvalidOid),
                                               Int32GetDatum(-1));
                    agtv.val.numeric = DatumGetNumeric(numd);
                    pfree(outputstr);
                }
                else
                {
                    agtv.type = AGTV_STRING;
                    agtv.val.string.len = strlen(outputstr);
                    agtv.val.string.val = outputstr;
                }
            }
            break;
        case AGT_TYPE_DATE:
            agtv.type = AGTV_STRING;
            agtv.val.string.val = agtype_encode_date_time(NULL, val, DATEOID);
            agtv.val.string.len = strlen(agtv.val.string.val);
            break;
        case AGT_TYPE_TIMESTAMP:
            agtv.type = AGTV_STRING;
            agtv.val.string.val = agtype_encode_date_time(NULL, val,
                                                          TIMESTAMPOID);
            agtv.val.string.len = strlen(agtv.val.string.val);
            break;
        case AGT_TYPE_TIMESTAMPTZ:
            agtv.type = AGTV_STRING;
            agtv.val.string.val = agtype_encode_date_time(NULL, val,
                                                          TIMESTAMPTZOID);
            agtv.val.string.len = strlen(agtv.val.string.val);
            break;
        case AGT_TYPE_JSONCAST:
        case AGT_TYPE_JSON:
        {
            /*
             * Parse the json right into the existing result object.
             * We can handle it as an agtype because agtype is currently an
             * extension of json.
             * Unlike AGT_TYPE_JSONB, numbers will be stored as either
             * an integer or a float, not a numeric.
             */
            agtype_lex_context *lex;
            agtype_sem_action sem;
            text *json = DatumGetTextPP(val);

            lex = make_agtype_lex_context(json, true);

            memset(&sem, 0, sizeof(sem));

            sem.semstate = (void *)result;

            sem.object_start = agtype_in_object_start;
            sem.array_start = agtype_in_array_start;
            sem.object_end = agtype_in_object_end;
            sem.array_end = agtype_in_array_end;
            sem.scalar = agtype_in_scalar;
            sem.object_field_start = agtype_in_object_field_start;

            parse_agtype(lex, &sem);
        }
        break;
        case AGT_TYPE_AGTYPE:
        case AGT_TYPE_JSONB:
        {
            agtype *jsonb = DATUM_GET_AGTYPE_P(val);
            agtype_iterator *it;

            /*
             * val is actually jsonb datum but we can handle it as an agtype
             * datum because agtype is currently an extension of jsonb.
             */

            it = agtype_iterator_init(&jsonb->root);

            if (AGT_ROOT_IS_SCALAR(jsonb))
            {
                agtype_iterator_next(&it, &agtv, true);
                Assert(agtv.type == AGTV_ARRAY);
                agtype_iterator_next(&it, &agtv, true);
                scalar_agtype = true;
            }
            else
            {
                agtype_iterator_token type;

                while ((type = agtype_iterator_next(&it, &agtv, false)) !=
                       WAGT_DONE)
                {
                    if (type == WAGT_END_ARRAY || type == WAGT_END_OBJECT ||
                        type == WAGT_BEGIN_ARRAY || type == WAGT_BEGIN_OBJECT)
                    {
                        result->res = push_agtype_value(&result->parse_state,
                                                        type, NULL);
                    }
                    else
                    {
                        result->res = push_agtype_value(&result->parse_state,
                                                        type, &agtv);
                    }
                }
            }
        }
        break;
        default:
            outputstr = OidOutputFunctionCall(outfuncoid, val);
            agtv.type = AGTV_STRING;
            agtv.val.string.len = check_string_length(strlen(outputstr));
            agtv.val.string.val = outputstr;
            break;
        }
    }

    /* Now insert agtv into result, unless we did it recursively */
    if (!is_null && !scalar_agtype && tcategory >= AGT_TYPE_AGTYPE &&
        tcategory <= AGT_TYPE_JSONCAST)
    {
        /* work has been done recursively */
        return;
    }
    else if (result->parse_state == NULL)
    {
        /* single root scalar */
        agtype_value va;

        va.type = AGTV_ARRAY;
        va.val.array.raw_scalar = true;
        va.val.array.num_elems = 1;

        result->res = push_agtype_value(&result->parse_state, WAGT_BEGIN_ARRAY,
                                        &va);
        result->res = push_agtype_value(&result->parse_state, WAGT_ELEM,
                                        &agtv);
        result->res = push_agtype_value(&result->parse_state, WAGT_END_ARRAY,
                                        NULL);
    }
    else
    {
        agtype_value *o = &result->parse_state->cont_val;

        switch (o->type)
        {
        case AGTV_ARRAY:
            result->res = push_agtype_value(&result->parse_state, WAGT_ELEM,
                                            &agtv);
            break;
        case AGTV_OBJECT:
            result->res = push_agtype_value(&result->parse_state,
                                            key_scalar ? WAGT_KEY : WAGT_VALUE,
                                            &agtv);
            break;
        default:
            elog(ERROR, "unexpected parent of nested structure");
        }
    }
}

/*
 * Process a single dimension of an array.
 * If it's the innermost dimension, output the values, otherwise call
 * ourselves recursively to process the next dimension.
 */
static void array_dim_to_agtype(agtype_in_state *result, int dim, int ndims,
                                int *dims, Datum *vals, bool *nulls,
                                int *valcount, agt_type_category tcategory,
                                Oid outfuncoid)
{
    int i;

    Assert(dim < ndims);

    result->res = push_agtype_value(&result->parse_state, WAGT_BEGIN_ARRAY,
                                    NULL);

    for (i = 1; i <= dims[dim]; i++)
    {
        if (dim + 1 == ndims)
        {
            datum_to_agtype(vals[*valcount], nulls[*valcount], result,
                            tcategory, outfuncoid, false);
            (*valcount)++;
        }
        else
        {
            array_dim_to_agtype(result, dim + 1, ndims, dims, vals, nulls,
                                valcount, tcategory, outfuncoid);
        }
    }

    result->res = push_agtype_value(&result->parse_state, WAGT_END_ARRAY,
                                    NULL);
}

/*
 * Turn an array into agtype.
 */
static void array_to_agtype_internal(Datum array, agtype_in_state *result)
{
    ArrayType *v = DatumGetArrayTypeP(array);
    Oid element_type = ARR_ELEMTYPE(v);
    int *dim;
    int ndim;
    int nitems;
    int count = 0;
    Datum *elements;
    bool *nulls;
    int16 typlen;
    bool typbyval;
    char typalign;
    agt_type_category tcategory;
    Oid outfuncoid;

    ndim = ARR_NDIM(v);
    dim = ARR_DIMS(v);
    nitems = ArrayGetNItems(ndim, dim);

    if (nitems <= 0)
    {
        result->res = push_agtype_value(&result->parse_state, WAGT_BEGIN_ARRAY,
                                        NULL);
        result->res = push_agtype_value(&result->parse_state, WAGT_END_ARRAY,
                                        NULL);
        return;
    }

    get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign);

    agtype_categorize_type(element_type, &tcategory, &outfuncoid);

    deconstruct_array(v, element_type, typlen, typbyval, typalign, &elements,
                      &nulls, &nitems);

    array_dim_to_agtype(result, 0, ndim, dim, elements, nulls, &count,
                        tcategory, outfuncoid);

    pfree(elements);
    pfree(nulls);
}

/*
 * Turn a composite / record into agtype.
 */
static void composite_to_agtype(Datum composite, agtype_in_state *result)
{
    HeapTupleHeader td;
    Oid tup_type;
    int32 tup_typmod;
    TupleDesc tupdesc;
    HeapTupleData tmptup, *tuple;
    int i;

    td = DatumGetHeapTupleHeader(composite);

    /* Extract rowtype info and find a tupdesc */
    tup_type = HeapTupleHeaderGetTypeId(td);
    tup_typmod = HeapTupleHeaderGetTypMod(td);
    tupdesc = lookup_rowtype_tupdesc(tup_type, tup_typmod);

    /* Build a temporary HeapTuple control structure */
    tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
    tmptup.t_data = td;
    tuple = &tmptup;

    result->res = push_agtype_value(&result->parse_state, WAGT_BEGIN_OBJECT,
                                    NULL);

    for (i = 0; i < tupdesc->natts; i++)
    {
        Datum val;
        bool isnull;
        char *attname;
        agt_type_category tcategory;
        Oid outfuncoid;
        agtype_value v;
        Form_pg_attribute att = TupleDescAttr(tupdesc, i);

        if (att->attisdropped)
            continue;

        attname = NameStr(att->attname);

        v.type = AGTV_STRING;
        /*
         * don't need check_string_length here
         * - can't exceed maximum name length
         */
        v.val.string.len = strlen(attname);
        v.val.string.val = attname;

        result->res = push_agtype_value(&result->parse_state, WAGT_KEY, &v);

        val = heap_getattr(tuple, i + 1, tupdesc, &isnull);

        if (isnull)
        {
            tcategory = AGT_TYPE_NULL;
            outfuncoid = InvalidOid;
        }
        else
        {
            agtype_categorize_type(att->atttypid, &tcategory, &outfuncoid);
        }

        datum_to_agtype(val, isnull, result, tcategory, outfuncoid, false);
    }

    result->res = push_agtype_value(&result->parse_state, WAGT_END_OBJECT,
                                    NULL);
    ReleaseTupleDesc(tupdesc);
}

/*
 * Removes properties with null value from the given agtype object.
 */
void remove_null_from_agtype_object(agtype_value *object)
{
    agtype_pair *avail; // next available position
    agtype_pair *ptr;

    if (object->type != AGTV_OBJECT)
    {
        ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                        errmsg("a map is expected")));
    }

    avail = object->val.object.pairs;
    ptr = object->val.object.pairs;

    while (ptr - object->val.object.pairs < object->val.object.num_pairs)
    {
        if (ptr->value.type != AGTV_NULL)
        {
            if (ptr != avail)
            {
                memcpy(avail, ptr, sizeof(agtype_pair));
            }
            avail++;
        }
        ptr++;
    }

    object->val.object.num_pairs = avail - object->val.object.pairs;
}

/*
 * Append agtype text for "val" to "result".
 *
 * This is just a thin wrapper around datum_to_agtype.  If the same type
 * will be printed many times, avoid using this; better to do the
 * agtype_categorize_type lookups only once.
 */
void add_agtype(Datum val, bool is_null, agtype_in_state *result,
                       Oid val_type, bool key_scalar)
{
    agt_type_category tcategory;
    Oid outfuncoid;

    if (val_type == InvalidOid)
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("could not determine input data type")));
    }

    if (is_null)
    {
        tcategory = AGT_TYPE_NULL;
        outfuncoid = InvalidOid;
    }
    else
    {
        agtype_categorize_type(val_type, &tcategory, &outfuncoid);
    }

    datum_to_agtype(val, is_null, result, tcategory, outfuncoid, key_scalar);
}

agtype_value *string_to_agtype_value(char *s)
{
    agtype_value *agtv = palloc0(sizeof(agtype_value));

    agtv->type = AGTV_STRING;
    agtv->val.string.len = check_string_length(strlen(s));
    agtv->val.string.val = s;

    return agtv;
}

/* helper function to create an agtype_value integer from an integer */
agtype_value *integer_to_agtype_value(int64 int_value)
{
    agtype_value *agtv = palloc0(sizeof(agtype_value));

    agtv->type = AGTV_INTEGER;
    agtv->val.int_value = int_value;

    return agtv;
}

PG_FUNCTION_INFO_V1(_agtype_build_path);

/*
 * SQL function agtype_build_path(VARIADIC agtype)
 */
Datum _agtype_build_path(PG_FUNCTION_ARGS)
{
    agtype_in_state result;
    Datum *args = NULL;
    bool *nulls = NULL;
    Oid *types = NULL;
    int nargs = 0;
    int i = 0;
    bool is_zero_boundary_case = false;

    /* build argument values to build the object */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    if (nargs < 1)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("paths require at least 1 vertex")));
    }

    /*
     * If this path is only 1 to 3 elements in length, check to see if the
     * contained edge is actually a path (made by the VLE). If so, just
     * materialize the vle path because it already contains the two outside
     * vertices.
     */
    if (nargs >= 1 && nargs <= 3)
    {
        int i = 0;

        for (i = 0; i < nargs; i++)
        {
            agtype *agt = NULL;

            if (nulls[i] || types[i] != AGTYPEOID)
            {
                break;
            }

            agt = DATUM_GET_AGTYPE_P(args[i]);

            if (AGT_ROOT_IS_BINARY(agt) &&
                AGT_ROOT_BINARY_FLAGS(agt) == AGT_FBINARY_TYPE_VLE_PATH)
            {
                agtype *path = agt_materialize_vle_path(agt);
                PG_RETURN_POINTER(path);
            }
        }
    }

    if (nargs % 2 == 0)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("a path is of the form: [vertex, (edge, vertex)*i] where i >= 0")));
    }

    /* initialize the result */
    memset(&result, 0, sizeof(agtype_in_state));

    /* push in the beginning of the agtype array */
    result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_ARRAY, NULL);

    /* loop through the path components */
    for (i = 0; i < nargs; i++)
    {
        agtype *agt = NULL;

        if (nulls[i])
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("argument %d must not be null", i + 1)));
        }
        else if (types[i] != AGTYPEOID)
        {

            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("argument %d must be an agtype", i + 1)));
        }

        /* get the agtype pointer */
        agt = DATUM_GET_AGTYPE_P(args[i]);

        /* is this a VLE path edge */
        if (i % 2 == 1 &&
            AGT_ROOT_IS_BINARY(agt) &&
            AGT_ROOT_BINARY_FLAGS(agt) == AGT_FBINARY_TYPE_VLE_PATH)
        {
            agtype_value *agtv_path = NULL;
            int j = 0;

            /* get the VLE path from the container as an agtype_value */
            agtv_path = agtv_materialize_vle_path(agt);

            /* it better be an AGTV_PATH */
            Assert(agtv_path->type == AGTV_PATH);

            /*
             * If the VLE path is the zero boundary case, there isn't an edge to
             * process. Additionally, the start and end vertices are the same.
             * We need to flag this condition so that we can skip processing the
             * following vertex.
             */
            if (agtv_path->val.array.num_elems == 1)
            {
                is_zero_boundary_case = true;
                continue;
            }

            /*
             * Add in the interior path - excluding the start and end vertices.
             * The other iterations of the for loop has handled start and will
             * handle end.
             */
            for (j = 1; j <= agtv_path->val.array.num_elems - 2; j++)
            {
                result.res = push_agtype_value(&result.parse_state, WAGT_ELEM,
                                               &agtv_path->val.array.elems[j]);
            }
        }
        else if (i % 2 == 1 && (!AGTE_IS_AGTYPE(agt->root.children[0]) ||
                                agt->root.children[1] != AGT_HEADER_EDGE))
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("paths consist of alternating vertices and edges"),
                     errhint("argument %d must be an edge", i + 1)));
        }
        else if (i % 2 == 0 && (!AGTE_IS_AGTYPE(agt->root.children[0]) ||
                                agt->root.children[1] != AGT_HEADER_VERTEX))
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("paths consist of alternating vertices and edges"),
                     errhint("argument %d must be an vertex", i + 1)));
        }
        /*
         * This will always add in vertices or edges depending on the loop
         * iteration. However, when it is a vertex, there is the possibility
         * that the previous iteration flagged a zero boundary case. We can only
         * add it if this is not the case. If this is an edge, it is not
         * possible to be a zero boundary case.
         */
        else if (is_zero_boundary_case == false)
        {
            add_agtype(AGTYPE_P_GET_DATUM(agt), false, &result, types[i],
                       false);
        }
        /* If we got here, we had a zero boundary case. So, clear it */
        else
        {
            is_zero_boundary_case = false;
        }
    }

    /* push the end of the array */
    result.res = push_agtype_value(&result.parse_state, WAGT_END_ARRAY, NULL);

    /* set it to a path type */
    result.res->type = AGTV_PATH;

    PG_RETURN_POINTER(agtype_value_to_agtype(result.res));
}

Datum make_path(List *path)
{
    ListCell *lc;
    agtype_in_state result;
    int i = 1;

    memset(&result, 0, sizeof(agtype_in_state));

    result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_ARRAY, NULL);

    if (list_length(path) < 1)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("paths require at least 1 vertex")));
    }

    if (list_length(path) % 2 != 1)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("a path is of the form: [vertex, (edge, vertex)*i] where i >= 0")));
    }


    foreach (lc, path)
    {
        agtype *agt= DATUM_GET_AGTYPE_P(PointerGetDatum(lfirst(lc)));
        agtype_value *elem;
        elem = get_ith_agtype_value_from_container(&agt->root, 0);

        if (!agt)
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("argument must not be null")));
        }
        else if (i % 2 == 1 && elem->type != AGTV_VERTEX)
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("argument %i must be a vertex", i)));
        }
        else if (i % 2 == 0 && elem->type != AGTV_EDGE)
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("argument %i must be an edge", i)));
        }

        add_agtype((Datum)agt, false, &result, AGTYPEOID, false);

        i++;
    }

    result.res = push_agtype_value(&result.parse_state, WAGT_END_ARRAY, NULL);

    result.res->type = AGTV_PATH;

    PG_RETURN_POINTER(agtype_value_to_agtype(result.res));
}

PG_FUNCTION_INFO_V1(_agtype_build_vertex);

/*
 * SQL function agtype_build_vertex(graphid, cstring, agtype)
 */
Datum _agtype_build_vertex(PG_FUNCTION_ARGS)
{
    graphid id;
    char *label;
    agtype *properties;
    agtype_build_state *bstate;
    agtype *rawscalar;
    agtype *vertex;

    /* handles null */
    if (fcinfo->argnull[0])
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("_agtype_build_vertex() graphid cannot be NULL")));
    }

    if (fcinfo->argnull[1])
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("_agtype_build_vertex() label cannot be NULL")));
    }

    id = AG_GETARG_GRAPHID(0);
    label = PG_GETARG_CSTRING(1);

    if (fcinfo->argnull[2])
    {
        agtype_build_state *bstate = init_agtype_build_state(0, AGT_FOBJECT);
        properties = build_agtype(bstate);
        pfree_agtype_build_state(bstate);
    }
    else
    {
        properties = AG_GET_ARG_AGTYPE_P(2);

        if (!AGT_ROOT_IS_OBJECT(properties))
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("_agtype_build_vertex() properties argument must be an object")));
        }
    }

    bstate = init_agtype_build_state(3, AGT_FOBJECT);
    write_string(bstate, "id");
    write_string(bstate, "label");
    write_string(bstate, "properties");
    write_graphid(bstate, id);
    write_string(bstate, label);
    write_container(bstate, properties);
    vertex = build_agtype(bstate);
    pfree_agtype_build_state(bstate);

    bstate = init_agtype_build_state(1, AGT_FARRAY | AGT_FSCALAR);
    write_extended(bstate, vertex, AGT_HEADER_VERTEX);
    rawscalar = build_agtype(bstate);
    pfree_agtype_build_state(bstate);

    PG_RETURN_POINTER(rawscalar);
}

Datum make_vertex(Datum id, Datum label, Datum properties)
{
    return DirectFunctionCall3(_agtype_build_vertex, id, label, properties);
}

PG_FUNCTION_INFO_V1(_agtype_build_edge);

/*
 * SQL function agtype_build_edge(graphid, graphid, graphid, cstring, agtype)
 */
Datum _agtype_build_edge(PG_FUNCTION_ARGS)
{
    agtype_build_state *bstate;
    agtype *edge, *rawscalar;
    graphid id, start_id, end_id;
    char *label;
    agtype *properties;

    /* process graph id */
    if (fcinfo->argnull[0])
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("_agtype_build_edge() graphid cannot be NULL")));
    }

    id = AG_GETARG_GRAPHID(0);

    /* process label */
    if (fcinfo->argnull[3])
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("_agtype_build_vertex() label cannot be NULL")));
    }

    label = PG_GETARG_CSTRING(3);

    /* process end_id */
    if (fcinfo->argnull[2])
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("_agtype_build_edge() endid cannot be NULL")));
    }

    end_id = AG_GETARG_GRAPHID(2);

    /* process start_id */
    if (fcinfo->argnull[1])
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("_agtype_build_edge() startid cannot be NULL")));
    }

    start_id = AG_GETARG_GRAPHID(1);

    /* process properties */

    /* if the properties object is null, push an empty object */
    if (fcinfo->argnull[4])
    {
        agtype_build_state *bstate = init_agtype_build_state(0, AGT_FOBJECT);
        properties = build_agtype(bstate);
        pfree_agtype_build_state(bstate);
    }
    else
    {
        properties = AG_GET_ARG_AGTYPE_P(4);

        if (!AGT_ROOT_IS_OBJECT(properties))
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("_agtype_build_edge() properties argument must be an object")));
        }
    }

    bstate = init_agtype_build_state(5, AGT_FOBJECT);
    write_string(bstate, "id");
    write_string(bstate, "label");
    write_string(bstate, "end_id");
    write_string(bstate, "start_id");
    write_string(bstate, "properties");
    write_graphid(bstate, id);
    write_string(bstate, label);
    write_graphid(bstate, end_id);
    write_graphid(bstate, start_id);
    write_container(bstate, properties);
    edge = build_agtype(bstate);
    pfree_agtype_build_state(bstate);

    bstate = init_agtype_build_state(1, AGT_FARRAY | AGT_FSCALAR);
    write_extended(bstate, edge, AGT_HEADER_EDGE);
    rawscalar = build_agtype(bstate);
    pfree_agtype_build_state(bstate);
    PG_RETURN_POINTER(rawscalar);
}

Datum make_edge(Datum id, Datum startid, Datum endid, Datum label,
                Datum properties)
{
    return DirectFunctionCall5(_agtype_build_edge, id, startid, endid, label,
                               properties);
}

static agtype_value* agtype_build_map_as_agtype_value(FunctionCallInfo fcinfo)
{
    int nargs;
    int i;
    agtype_in_state result;
    Datum *args;
    bool *nulls;
    Oid *types;

    /* build argument values to build the object */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    if (nargs < 0)
    {
        return NULL;
    }

    if (nargs % 2 != 0)
    {
        ereport(
            ERROR,
            (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
             errmsg("argument list must have been even number of elements"),
             errhint("The arguments of agtype_build_map() must consist of alternating keys and values.")));
    }

    memset(&result, 0, sizeof(agtype_in_state));

    result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
                                   NULL);

    /* iterate through the arguments and build the object */
    for (i = 0; i < nargs; i += 2)
    {
        /* process key */
        if (nulls[i])
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("argument %d: key must not be null", i + 1)));
        }

        /*
         * If the key is agtype, we need to extract it as an agtype string and
         * push the value.
         */
        if (types[i] == AGTYPEOID)
        {
            agtype_value *agtv = NULL;

            agtv = tostring_helper(args[i], types[i],
                                   "agtype_build_map_as_agtype_value");
            result.res = push_agtype_value(&result.parse_state, WAGT_KEY, agtv);

            /* free the agtype_value from tostring_helper */
            pfree(agtv);
        }
        else
        {
            add_agtype(args[i], false, &result, types[i], true);
        }

        /* process value */
        add_agtype(args[i + 1], nulls[i + 1], &result, types[i + 1], false);
    }

    result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT, NULL);
    return result.res;
}

PG_FUNCTION_INFO_V1(agtype_build_map);

/*
 * SQL function agtype_build_map(variadic "any")
 */
Datum agtype_build_map(PG_FUNCTION_ARGS)
{
    agtype_value *result = agtype_build_map_as_agtype_value(fcinfo);

    if (result == NULL)
    {
        PG_RETURN_NULL();
    }

    PG_RETURN_POINTER(agtype_value_to_agtype(result));
}

PG_FUNCTION_INFO_V1(agtype_build_map_noargs);

/*
 * degenerate case of agtype_build_map where it gets 0 arguments.
 */
Datum agtype_build_map_noargs(PG_FUNCTION_ARGS)
{
    agtype_in_state result;

    memset(&result, 0, sizeof(agtype_in_state));

    push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT, NULL);
    result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT, NULL);

    PG_RETURN_POINTER(agtype_value_to_agtype(result.res));
}

PG_FUNCTION_INFO_V1(agtype_build_map_nonull);

/*
 * Similar to agtype_build_map except null properties are removed.
 */
Datum agtype_build_map_nonull(PG_FUNCTION_ARGS)
{
    agtype_value *result = agtype_build_map_as_agtype_value(fcinfo);

    if (result == NULL)
    {
        PG_RETURN_NULL();
    }

    remove_null_from_agtype_object(result);

    PG_RETURN_POINTER(agtype_value_to_agtype(result));
}

PG_FUNCTION_INFO_V1(agtype_build_list);

/*
 * SQL function agtype_build_list(variadic "any")
 */
Datum agtype_build_list(PG_FUNCTION_ARGS)
{
    int nargs;
    int i;
    agtype_in_state result;
    Datum *args;
    bool *nulls;
    Oid *types;

    /*build argument values to build the array */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    if (nargs < 0)
        PG_RETURN_NULL();

    memset(&result, 0, sizeof(agtype_in_state));

    result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_ARRAY,
                                   NULL);

    for (i = 0; i < nargs; i++)
        add_agtype(args[i], nulls[i], &result, types[i], false);

    result.res = push_agtype_value(&result.parse_state, WAGT_END_ARRAY, NULL);

    PG_RETURN_POINTER(agtype_value_to_agtype(result.res));
}

PG_FUNCTION_INFO_V1(agtype_build_list_noargs);

/*
 * degenerate case of agtype_build_list where it gets 0 arguments.
 */
Datum agtype_build_list_noargs(PG_FUNCTION_ARGS)
{
    agtype_in_state result;

    memset(&result, 0, sizeof(agtype_in_state));

    push_agtype_value(&result.parse_state, WAGT_BEGIN_ARRAY, NULL);
    result.res = push_agtype_value(&result.parse_state, WAGT_END_ARRAY, NULL);

    PG_RETURN_POINTER(agtype_value_to_agtype(result.res));
}

/*
 * Extract scalar value from raw-scalar pseudo-array agtype.
 */
static bool agtype_extract_scalar(agtype_container *agtc, agtype_value *res)
{
    agtype_iterator *it;
    agtype_iterator_token tok PG_USED_FOR_ASSERTS_ONLY;
    agtype_value tmp;

    if (!AGTYPE_CONTAINER_IS_ARRAY(agtc) || !AGTYPE_CONTAINER_IS_SCALAR(agtc))
    {
        /* inform caller about actual type of container */
        res->type = AGTYPE_CONTAINER_IS_ARRAY(agtc) ? AGTV_ARRAY : AGTV_OBJECT;
        return false;
    }

    /*
     * A root scalar is stored as an array of one element, so we get the array
     * and then its first (and only) member.
     */
    it = agtype_iterator_init(agtc);

    tok = agtype_iterator_next(&it, &tmp, true);
    Assert(tok == WAGT_BEGIN_ARRAY);
    Assert(tmp.val.array.num_elems == 1 && tmp.val.array.raw_scalar);

    tok = agtype_iterator_next(&it, res, true);
    Assert(tok == WAGT_ELEM);
    Assert(IS_A_AGTYPE_SCALAR(res));

    tok = agtype_iterator_next(&it, &tmp, true);
    Assert(tok == WAGT_END_ARRAY);

    tok = agtype_iterator_next(&it, &tmp, true);
    Assert(tok == WAGT_DONE);

    return true;
}

/*
 * Emit correct, translatable cast error message
 */
static void cannot_cast_agtype_value(enum agtype_value_type type,
                                     const char *sqltype)
{
    static const struct
    {
        enum agtype_value_type type;
        const char *msg;
    } messages[] = {
        {AGTV_NULL, gettext_noop("cannot cast agtype null to type %s")},
        {AGTV_STRING, gettext_noop("cannot cast agtype string to type %s")},
        {AGTV_NUMERIC, gettext_noop("cannot cast agtype numeric to type %s")},
        {AGTV_INTEGER, gettext_noop("cannot cast agtype integer to type %s")},
        {AGTV_FLOAT, gettext_noop("cannot cast agtype float to type %s")},
        {AGTV_BOOL, gettext_noop("cannot cast agtype boolean to type %s")},
        {AGTV_ARRAY, gettext_noop("cannot cast agtype array to type %s")},
        {AGTV_OBJECT, gettext_noop("cannot cast agtype object to type %s")},
        {AGTV_VERTEX, gettext_noop("cannot cast agtype vertex to type %s")},
        {AGTV_EDGE, gettext_noop("cannot cast agtype edge to type %s")},
        {AGTV_PATH, gettext_noop("cannot cast agtype path to type %s")},
        {AGTV_BINARY,
         gettext_noop("cannot cast agtype array or object to type %s")}};
    int i;

    for (i = 0; i < lengthof(messages); i++)
    {
        if (messages[i].type == type)
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg(messages[i].msg, sqltype)));
        }
    }

    /* should be unreachable */
    elog(ERROR, "unknown agtype type: %d", (int)type);
}

PG_FUNCTION_INFO_V1(agtype_to_bool);

/*
 * Cast agtype to boolean. From jsonb_bool().
 */
Datum agtype_to_bool(PG_FUNCTION_ARGS)
{
    agtype *agtype_in = AG_GET_ARG_AGTYPE_P(0);
    agtype_value agtv;

    if (!agtype_extract_scalar(&agtype_in->root, &agtv) ||
        agtv.type != AGTV_BOOL)
    {
        cannot_cast_agtype_value(agtv.type, "boolean");
    }

    PG_FREE_IF_COPY(agtype_in, 0);

    PG_RETURN_BOOL(agtv.val.boolean);
}

PG_FUNCTION_INFO_V1(agtype_to_int8);
/*
 * Cast agtype to int8.
 */
Datum agtype_to_int8(PG_FUNCTION_ARGS)
{
    agtype_value agtv;
    agtype_value *agtv_p = NULL;
    agtype_value *container = NULL;
    int64 result = 0x0;
    agtype *arg_agt = NULL;

    /* get the agtype equivalence of any convertable input type */
    arg_agt = get_one_agtype_from_variadic_args(fcinfo, 0, 1);

    /* Return null if arg_agt is null. This covers SQL and Agtype NULLS */
    if (arg_agt == NULL)
    {
        PG_RETURN_NULL();
    }

    if (!agtype_extract_scalar(&arg_agt->root, &agtv) ||
        (agtv.type != AGTV_FLOAT &&
         agtv.type != AGTV_INTEGER &&
         agtv.type != AGTV_NUMERIC &&
         agtv.type != AGTV_STRING &&
         agtv.type != AGTV_BOOL))
    {
        cannot_cast_agtype_value(agtv.type, "int");
    }

    agtv_p = &agtv;

    /*
     * If it is an agtype string, we need to convert the string component first.
     * We need to do this because the string could be any type of value. Fx,
     * integer, float, boolean, numeric, object, or array. Once converted, we
     * need to remember scalar values are returned as a scalar array. We only
     * care about scalar arrays.
     */
    if (agtv_p->type == AGTV_STRING)
    {
        agtype_value *temp = NULL;

        /*
         * Convert the string to an agtype_value. Remember that a returned
         * scalar value is returned in a one element array.
         */
        temp = agtype_value_from_cstring(agtv_p->val.string.val,
                                         agtv_p->val.string.len);

        /* this will catch anything that isn't an array and isn't a scalar */
        if (temp->type != AGTV_ARRAY ||
            !temp->val.array.raw_scalar)
        {
            ereport(ERROR,
                   (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                    errmsg("invalid agtype string to int8 type: %d",
                           (int)temp->type)));
        }

        /* save the top agtype_value */
        container = temp;
        /* get the wrapped agtype_value */
        temp = &temp->val.array.elems[0];

        /* these we expect */
        if (temp->type == AGTV_FLOAT ||
            temp->type == AGTV_INTEGER ||
            temp->type == AGTV_NUMERIC ||
            temp->type == AGTV_BOOL)
        {
            agtv_p = temp;
        }
        else
        {
            elog(ERROR, "unexpected string type: %d in agtype_to_int8",
                        (int)temp->type);
        }
    }

    /* now check the rest */
    if (agtv_p->type == AGTV_INTEGER)
    {
        result = agtv_p->val.int_value;
    }
    else if (agtv_p->type == AGTV_FLOAT)
    {
        result = DatumGetInt64(DirectFunctionCall1(dtoi8,
                     Float8GetDatum(agtv_p->val.float_value)));
    }
    else if (agtv_p->type == AGTV_NUMERIC)
    {
        result = DatumGetInt64(DirectFunctionCall1(numeric_int8,
                     NumericGetDatum(agtv_p->val.numeric)));
    }
    else if(agtv_p->type == AGTV_BOOL)
    {
        result = (agtv_p->val.boolean) ? 1 : 0;
    }
    else
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("invalid conversion type in agtype_to_int8: %d",
                        (int)agtv_p->type)));
    }

    /* free the container, if it was used */
    if (container)
    {
        pfree(container);
    }

    PG_FREE_IF_COPY(arg_agt, 0);

    PG_RETURN_INT64(result);
}

PG_FUNCTION_INFO_V1(agtype_to_int4);

/*
 * Cast agtype to int4.
 */
Datum agtype_to_int4(PG_FUNCTION_ARGS)
{
    agtype_value agtv;
    agtype_value *agtv_p = NULL;
    agtype_value *container = NULL;
    int32 result = 0x0;
    agtype *arg_agt = NULL;

    /* get the agtype equivalence of any convertable input type */
    arg_agt = get_one_agtype_from_variadic_args(fcinfo, 0, 1);

    /* Return null if arg_agt is null. This covers SQL and Agtype NULLS */
    if (arg_agt == NULL)
    {    
        PG_RETURN_NULL();
    }

    if (!agtype_extract_scalar(&arg_agt->root, &agtv) ||
        (agtv.type != AGTV_FLOAT &&
         agtv.type != AGTV_INTEGER &&
         agtv.type != AGTV_NUMERIC &&
         agtv.type != AGTV_STRING &&
         agtv.type != AGTV_BOOL))
    {    
        cannot_cast_agtype_value(agtv.type, "int");
    }

    agtv_p = &agtv;

    /*
     * If it is an agtype string, we need to convert the string component first.
     * We need to do this because the string could be any type of value. Fx,
     * integer, float, boolean, numeric, object, or array. Once converted, we
     * need to remember scalar values are returned as a scalar array. We only
     * care about scalar arrays.
     */
    if (agtv_p->type == AGTV_STRING)
    {
        agtype_value *temp = NULL;

        /*
         * Convert the string to an agtype_value. Remember that a returned
         * scalar value is returned in a one element array.
         */
        temp = agtype_value_from_cstring(agtv_p->val.string.val,
                                         agtv_p->val.string.len);

        /* this will catch anything that isn't an array and isn't a scalar */
        if (temp->type != AGTV_ARRAY ||
            !temp->val.array.raw_scalar)
        {
            ereport(ERROR,
                   (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                    errmsg("invalid agtype string to int4 type: %d",
                           (int)temp->type)));
        }

        /* save the top agtype_value */
        container = temp;
        /* get the wrapped agtype_value */
        temp = &temp->val.array.elems[0];

        /* these we expect */
        if (temp->type == AGTV_FLOAT ||
            temp->type == AGTV_INTEGER ||
            temp->type == AGTV_NUMERIC ||
            temp->type == AGTV_BOOL)
        {
            agtv_p = temp;
        }
        else
        {
            elog(ERROR, "unexpected string type: %d in agtype_to_int4",
                        (int)temp->type);
        }
    }

    /* now check the rest */
    if (agtv_p->type == AGTV_INTEGER)
    {
        result = DatumGetInt32(DirectFunctionCall1(int84,
                     Int64GetDatum(agtv_p->val.int_value)));
    }
    else if (agtv_p->type == AGTV_FLOAT)
    {
        result = DatumGetInt32(DirectFunctionCall1(dtoi4,
                     Float8GetDatum(agtv_p->val.float_value)));
    }
    else if (agtv_p->type == AGTV_NUMERIC)
    {
        result = DatumGetInt32(DirectFunctionCall1(numeric_int4,
                     NumericGetDatum(agtv_p->val.numeric)));
    }
    else if (agtv_p->type == AGTV_BOOL)
    {
        result = (agtv_p->val.boolean) ? 1 : 0;
    }
    else
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("invalid conversion type in agtype_to_int4: %d",
                        (int)agtv_p->type)));
    }

    /* free the container, if it was used */
    if (container)
    {
        pfree(container);
    }

    PG_FREE_IF_COPY(arg_agt, 0);

    PG_RETURN_INT32(result);
}

PG_FUNCTION_INFO_V1(agtype_to_int2);

/*
 * Cast agtype to int2.
 */
Datum agtype_to_int2(PG_FUNCTION_ARGS)
{
    agtype_value agtv;
    agtype_value *agtv_p = NULL;
    agtype_value *container = NULL;
    int16 result = 0x0;
    agtype *arg_agt = NULL;

    /* get the agtype equivalence of any convertable input type */
    arg_agt = get_one_agtype_from_variadic_args(fcinfo, 0, 1);

    /* Return null if arg_agt is null. This covers SQL and Agtype NULLS */
    if (arg_agt == NULL)
    {
        PG_RETURN_NULL();
    }

    if (!agtype_extract_scalar(&arg_agt->root, &agtv) ||
        (agtv.type != AGTV_FLOAT &&
         agtv.type != AGTV_INTEGER &&
         agtv.type != AGTV_NUMERIC &&
         agtv.type != AGTV_STRING &&
         agtv.type != AGTV_BOOL))
    {
        cannot_cast_agtype_value(agtv.type, "int");
    }

    agtv_p = &agtv;

    /*
     * If it is an agtype string, we need to convert the string component first.
     * We need to do this because the string could be any type of value. Fx,
     * integer, float, boolean, numeric, object, or array. Once converted, we
     * need to remember scalar values are returned as a scalar array. We only
     * care about scalar arrays.
     */
    if (agtv_p->type == AGTV_STRING)
    {
        agtype_value *temp = NULL;

        /*
         * Convert the string to an agtype_value. Remember that a returned
         * scalar value is returned in a one element array.
         */
        temp = agtype_value_from_cstring(agtv_p->val.string.val,
                                         agtv_p->val.string.len);

        /* this will catch anything that isn't an array and isn't a scalar */
        if (temp->type != AGTV_ARRAY ||
            !temp->val.array.raw_scalar)
        {
            ereport(ERROR,
                   (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                    errmsg("invalid agtype string to int2 type: %d",
                           (int)temp->type)));
        }

        /* save the top agtype_value */
        container = temp;
        /* get the wrapped agtype_value */
        temp = &temp->val.array.elems[0];

        /* these we expect */
        if (temp->type == AGTV_FLOAT ||
            temp->type == AGTV_INTEGER ||
            temp->type == AGTV_NUMERIC ||
            temp->type == AGTV_BOOL)
        {
            agtv_p = temp;
        }
        else
        {
            elog(ERROR, "unexpected string type: %d in agtype_to_int2",
                        (int)temp->type);
        }
    }

    /* now check the rest */
    if (agtv_p->type == AGTV_INTEGER)
    {
        result = DatumGetInt16(DirectFunctionCall1(int82,
                     Int64GetDatum(agtv_p->val.int_value)));
    }
    else if (agtv_p->type == AGTV_FLOAT)
    {
        result = DatumGetInt16(DirectFunctionCall1(dtoi2,
                     Float8GetDatum(agtv_p->val.float_value)));
    }
    else if (agtv_p->type == AGTV_NUMERIC)
    {
        result = DatumGetInt16(DirectFunctionCall1(numeric_int2,
                     NumericGetDatum(agtv_p->val.numeric)));
    }
    else if (agtv_p->type == AGTV_BOOL)
    {
        result = (agtv_p->val.boolean) ? 1 : 0;
    }
    else
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("invalid conversion type in agtype_to_int2: %d",
                        (int)agtv_p->type)));

    }

    /* free the container, if it was used */
    if (container)
    {
        pfree(container);
    }

    PG_FREE_IF_COPY(arg_agt, 0);

    PG_RETURN_INT16(result);
}

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 &&
         agtv.type != AGTV_NUMERIC &&
         agtv.type != AGTV_STRING))
    {
        cannot_cast_agtype_value(agtv.type, "float");
    }
    
    PG_FREE_IF_COPY(agtype_in, 0);

    if (agtv.type == AGTV_FLOAT)
    {
        result = agtv.val.float_value;
    }
    else 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")));
    }
    else if (agtv.type == AGTV_NUMERIC)
    {    
        result = DatumGetFloat8(DirectFunctionCall1(numeric_float8,
                     NumericGetDatum(agtv.val.numeric)));
    }
    else if (agtv.type == AGTV_STRING)
    {
        result = DatumGetFloat8(DirectFunctionCall1(float8in,
                                                    CStringGetDatum(agtv.val.string.val)));
    }
    else
    {    
        elog(ERROR, "invalid agtype type: %d", (int)agtv.type);
    }
    
    PG_RETURN_FLOAT8(result);
}

PG_FUNCTION_INFO_V1(agtype_to_text);

/*
 * Cast agtype to text.
 */
Datum agtype_to_text(PG_FUNCTION_ARGS)
{
    agtype *arg_agt;
    agtype_value *arg_value;
    text *text_value;

    /* get the agtype equivalence of any convertable input type */
    arg_agt = get_one_agtype_from_variadic_args(fcinfo, 0, 1);

    /* Return null if arg_agt is null. This covers SQL and Agtype NULLS */
    if (arg_agt == NULL)
        PG_RETURN_NULL();

    /* check that we have a scalar value */
    if (!AGT_ROOT_IS_SCALAR(arg_agt))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("agtype argument must resolve to a scalar value")));

    /* get the arg parameter */
    arg_value = get_ith_agtype_value_from_container(&arg_agt->root, 0);

    text_value = agtype_value_to_text(arg_value, true);
    if (text_value == NULL)
    {
        PG_RETURN_NULL();
    }

    PG_RETURN_TEXT_P(text_value);
}

PG_FUNCTION_INFO_V1(bool_to_agtype);

/*
 * Cast boolean to agtype.
 */
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));
}

PG_FUNCTION_INFO_V1(int8_to_agtype);

/*
 * Cast float8 to agtype.
 */
Datum int8_to_agtype(PG_FUNCTION_ARGS)
{
    return integer_to_agtype(PG_GETARG_INT64(0));
}

PG_FUNCTION_INFO_V1(agtype_to_int4_array);

/*
 * Cast agtype to int4[].
 *
 * TODO:
 *
 * We either need to change the function definition in age--x.x.x.sql
 * to something like agtype[] or we need to make this function work
 * for "any" type input. Right now it only works for an agtype array but
 * it takes "any" input. Hence the additional code added to block anything
 * other than agtype.
 */
Datum agtype_to_int4_array(PG_FUNCTION_ARGS)
{
    agtype_iterator *agtype_iterator = NULL;
    agtype *agtype_in = NULL;
    agtype_value agtv;
    agtype_iterator_token agtv_token;
    Datum *array_value;
    ArrayType *result;
    Oid arg_type = InvalidOid;
    int element_size;
    int i;

    /* get the input data type */
    arg_type = get_fn_expr_argtype(fcinfo->flinfo, 0);

    /* verify the input is agtype */
    if (arg_type != AGTYPEOID)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("argument must resolve to agtype")));
    }

    agtype_in = AG_GET_ARG_AGTYPE_P(0);

    agtype_iterator = agtype_iterator_init(&agtype_in->root);
    agtv_token = agtype_iterator_next(&agtype_iterator, &agtv, false);

    if (agtv.type != AGTV_ARRAY)
    {
        cannot_cast_agtype_value(agtv.type, "int4[]");
    }

    element_size = agtv.val.array.num_elems;
    array_value = (Datum *) palloc(sizeof(Datum) * element_size);

    i = 0;
    while ((agtv_token = agtype_iterator_next(&agtype_iterator, &agtv, true)) != WAGT_END_ARRAY)
    {
        int32 element_value = 0;
        if (agtv.type == AGTV_INTEGER)
            element_value = DatumGetInt32(DirectFunctionCall1(int84,
                                                              Int64GetDatum(agtv.val.int_value)));
        else if (agtv.type == AGTV_FLOAT)
            element_value = DatumGetInt32(DirectFunctionCall1(dtoi4,
                                                              Float8GetDatum(agtv.val.float_value)));
        else if (agtv.type == AGTV_NUMERIC)
            element_value = DatumGetInt32(DirectFunctionCall1(numeric_int4,
                                                              NumericGetDatum(agtv.val.numeric)));
        else if (agtv.type == AGTV_STRING)
            element_value = DatumGetInt32(DirectFunctionCall1(int4in,
                                                              CStringGetDatum(agtv.val.string.val)));
        array_value[i++] = element_value;
    }

    result = construct_array(array_value, element_size, INT4OID, 4, true, 'i');

    PG_RETURN_ARRAYTYPE_P(result);
}

/*
 * Helper function for agtype_access_operator map access.
 * Note: This function expects that a map and a scalar key are being passed.
 */
static agtype_value *execute_map_access_operator(agtype *map,
                                                 agtype_value *map_value,
                                                 agtype *key)
{
    agtype_value *key_value;
    char *key_str;
    int key_len = 0;

    /* get the key from the container */
    key_value = get_ith_agtype_value_from_container(&key->root, 0);

    switch (key_value->type)
    {
    case AGTV_NULL:
        return NULL;

    case AGTV_INTEGER:
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("AGTV_INTEGER is not a valid key type")));
    case AGTV_FLOAT:
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("AGTV_FLOAT is not a valid key type")));
    case AGTV_NUMERIC:
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("AGTV_NUMERIC is not a valid key type")));
    case AGTV_BOOL:
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("AGTV_BOOL is not a valid key type")));
    case AGTV_STRING:
        key_str = key_value->val.string.val;
        key_len = key_value->val.string.len;
        break;
    default:
        ereport(ERROR, (errmsg("unknown agtype scalar type")));
        break;
    }

    return execute_map_access_operator_internal(map, map_value, key_str,
                                                key_len);
}

static agtype_value *execute_map_access_operator_internal(
    agtype *map, agtype_value *map_value, char *key, int key_len)
{
    agtype_value new_key_value;
    new_key_value.type = AGTV_STRING;
    new_key_value.val.string.val = key;
    new_key_value.val.string.len = key_len;
    /* if we were passed an agtype */
    if (map_value == NULL)
    {
        map_value = find_agtype_value_from_container(&map->root, AGT_FOBJECT,
                                                     &new_key_value);
    }
    /* if we were passed an agtype_value OBJECT (BINARY) */
    else if (map_value != NULL && map_value->type == AGTV_BINARY)
    {
        map_value = find_agtype_value_from_container(map_value->val.binary.data,
                                                     AGT_FOBJECT,
                                                     &new_key_value);
    }
    /* if we were passed an agtype_value OBJECT */
    else if (map_value != NULL && map_value->type == AGTV_OBJECT)
    {
        map_value = get_agtype_value_object_value(map_value, key, key_len);
    }
    /* otherwise, we don't know how to process it */
    else
    {
        ereport(ERROR, (errmsg("unknown map_value type")));
    }

    /* return the agtype_value */
    return map_value;
}

/*
 * Helper function for agtype_access_operator array access.
 * Note: This function expects that an array and a scalar int are being passed.
 */
static agtype_value *execute_array_access_operator(agtype *array,
                                                   agtype_value *array_value,
                                                   agtype *array_index)
{
    agtype_value *array_index_value = NULL;

    /* unpack the array index value */
    array_index_value = get_ith_agtype_value_from_container(&array_index->root,
                                                            0);

    /* if AGTV_NULL return NULL */
    if (array_index_value->type == AGTV_NULL)
    {
        return NULL;
    }

    /* index must be an integer */
    if (array_index_value->type != AGTV_INTEGER)
    {
        ereport(ERROR,
                (errmsg("array index must resolve to an integer value")));
    }

    return execute_array_access_operator_internal(
        array, array_value, array_index_value->val.int_value);
}

static agtype_value *execute_array_access_operator_internal(agtype *array,
                                                            agtype_value *array_value,
                                                            int64 array_index)
{
    agtype_value *array_element_value = NULL;
    uint32 size = 0;

    /* get the size of the array, given the type of the input */
    if (array_value == NULL)
    {
        size = AGT_ROOT_COUNT(array);
    }
    else if (array_value->type == AGTV_ARRAY)
    {
        size = array_value->val.array.num_elems;
    }
    else if (array_value->type == AGTV_BINARY)
    {
        size = AGTYPE_CONTAINER_SIZE(array_value->val.binary.data);
    }
    else
    {
        elog(ERROR, "execute_array_access_operator_internal: unexpected type");
    }

    /* adjust for negative index values */
    if (array_index < 0)
    {
        array_index = size + array_index;
    }

    /* check array bounds */
    if ((array_index >= size) || (array_index < 0))
    {
        return NULL;
    }

    /* if we were passed an agtype */
    if (array_value == NULL)
    {
        array_element_value = get_ith_agtype_value_from_container(&array->root,
                                                                  array_index);
    }
    /* if we were passed an agtype_value ARRAY (BINARY) */
    else if (array_value != NULL && array_value->type == AGTV_BINARY)
    {
        array_element_value = get_ith_agtype_value_from_container(
            array_value->val.binary.data, array_index);
    }
    /* if we were passed an agtype_value ARRAY */
    else if (array_value != NULL && array_value->type == AGTV_ARRAY)
    {
        array_element_value = &array_value->val.array.elems[array_index];
    }
    /* otherwise, we don't know how to process it */
    else
    {
        ereport(ERROR, (errmsg("unknown array_value type")));
    }

    return array_element_value;
}

/*
 * Helper function to do a binary search through an object's key/value pairs,
 * looking for a specific key. It will return the key or NULL if not found.
 */
agtype_value *get_agtype_value_object_value(const agtype_value *agtv_object,
                                            char *search_key,
                                            int search_key_length)
{
    agtype_value *agtv_key = NULL;
    int current_key_length = 0;
    int middle = 0;
    int num_pairs = 0;
    int left = 0;
    int right = 0;
    int result = 0;

    if (agtv_object == NULL || search_key == NULL || search_key_length <= 0)
    {
        return NULL;
    }

    /* get the number of object pairs */
    num_pairs = agtv_object->val.object.num_pairs;

    /* do a binary search through the pairs */
    right = num_pairs - 1;
    middle = num_pairs / 2;

    /* while middle is within the constraints */
    while (middle >= left && middle <= right)
    {
        /* get the current key length */
        agtv_key = &agtv_object->val.object.pairs[middle].key;
        current_key_length = agtv_key->val.string.len;

        /* if not the same length, divide the search space and continue */
        if (current_key_length != search_key_length)
        {
            /* if we need to search in the lower half */
            if (search_key_length < current_key_length)
            {
                middle -= 1;
                right = middle;
                middle = ((middle - left) / 2) + left;
            }
            /* else we need to search in the upper half */
            else
            {
                middle += 1;
                left = middle;
                middle = ((right - middle) / 2) + left;
            }
            continue;
        }

        /* they are the same length so compare the keys */
        result = strncmp(search_key, agtv_key->val.string.val,
                         search_key_length);

        /* if they don't match */
        if (result != 0)
        {
            /* if smaller */
            if (result < 0)
            {
                middle -= 1;
                right = middle;
                middle = ((middle - left) / 2) + left;
            }
            /* if larger */
            else
            {
                middle += 1;
                left = middle;
                middle = ((right - middle) / 2) + left;
            }
            continue;
        }

        /* they match */
        return (&agtv_object->val.object.pairs[middle].value);
    }

    /* they don't match */
    return NULL;
}

/*
 * From PG's extract_variadic_args
 *
 * This function allows you to pass the minimum number of required arguments
 * so that you can have it bail out early (without allocating and building
 * the output arrays). In this case, the returned number of args will be 0
 * and the args array will be NULL.
 */
static int extract_variadic_args_min(FunctionCallInfo fcinfo,
                                     int variadic_start, bool convert_unknown,
                                     Datum **args, Oid **types, bool **nulls,
                                     int min_num_args)
{
    bool variadic = get_fn_expr_variadic(fcinfo->flinfo);
    Datum *args_res = NULL;
    bool *nulls_res = NULL;
    Oid *types_res = NULL;
    int nargs = 0;
    int i = 0;

    *args = NULL;
    *types = NULL;
    *nulls = NULL;

    if (variadic)
    {
        ArrayType *array_in = NULL;
        Oid element_type = InvalidOid;
        bool typbyval = false;
        char typalign = 0;
        int16 typlen = 0;

        Assert(PG_NARGS() == variadic_start + 1);

        if (PG_ARGISNULL(variadic_start))
        {
            return -1;
        }

        /* get the array */
        array_in = PG_GETARG_ARRAYTYPE_P(variadic_start);

        /* verify that we have the minimum number of args */
        if (ArrayGetNItems(ARR_NDIM(array_in), ARR_DIMS(array_in)) <
            min_num_args)
        {
            return 0;
        }

        /* get the element type */
        element_type = ARR_ELEMTYPE(array_in);

        get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign);
        deconstruct_array(array_in, element_type, typlen, typbyval, typalign,
                          &args_res, &nulls_res, &nargs);

        /* All the elements of the array have the same type */
        types_res = (Oid *) palloc0(nargs * sizeof(Oid));
        for (i = 0; i < nargs; i++)
        {
            types_res[i] = element_type;
        }
    }
    else
    {
        /* get the number of arguments */
        nargs = PG_NARGS() - variadic_start;
        Assert(nargs > 0);

        /* verify that we have the minimum number of args */
        if (nargs < min_num_args)
        {
            return 0;
        }

        /* allocate result memory */
        nulls_res = (bool *) palloc0(nargs * sizeof(bool));
        args_res = (Datum *) palloc0(nargs * sizeof(Datum));
        types_res = (Oid *) palloc0(nargs * sizeof(Oid));

        for (i = 0; i < nargs; i++)
        {
            nulls_res[i] = PG_ARGISNULL(i + variadic_start);
            types_res[i] = get_fn_expr_argtype(fcinfo->flinfo, i + variadic_start);

            /*
             * Turn a constant (more or less literal) value that's of unknown
             * type into text if required. Unknowns come in as a cstring
             * pointer. Note: for functions declared as taking type "any", the
             * parser will not do any type conversion on unknown-type literals
             * (that is, undecorated strings or NULLs).
             */
            if (convert_unknown &&
                types_res[i] == UNKNOWNOID &&
                get_fn_expr_arg_stable(fcinfo->flinfo, i + variadic_start))
            {
                types_res[i] = TEXTOID;

                if (PG_ARGISNULL(i + variadic_start))
                {
                    args_res[i] = (Datum) 0;
                }
                else
                {
                    args_res[i] = CStringGetTextDatum(PG_GETARG_POINTER(i + variadic_start));
                }
            }
            else
            {
                /* no conversion needed, just take the datum as given */
                args_res[i] = PG_GETARG_DATUM(i + variadic_start);
            }

            if (!OidIsValid(types_res[i]) ||
                (convert_unknown && types_res[i] == UNKNOWNOID))
            {
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                         errmsg("could not determine data type for argument %d",
                                i + 1)));
            }
        }
    }

    /* Fill in results */
    *args = args_res;
    *nulls = nulls_res;
    *types = types_res;

    return nargs;
}

static Datum process_access_operator_result(FunctionCallInfo fcinfo,
                                            agtype_value *agtv,
                                            bool as_text)
{
    if (agtv != NULL)
    {
        if (as_text)
        {
            text *result;

            if (agtv->type == AGTV_BINARY)
            {
                StringInfo out = makeStringInfo();
                agtype_container *agtc =
                    (agtype_container *)agtv->val.binary.data;
                char *str;

                str = agtype_to_cstring_worker(out, agtc,
                                               agtv->val.binary.len,
                                               false);
                result = cstring_to_text(str);
            }
            else
            {
                result = agtype_value_to_text(agtv, false);
            }

            if (result)
            {
                PG_RETURN_TEXT_P(result);
            }
        }
        else
        {
            AG_RETURN_AGTYPE_P(agtype_value_to_agtype(agtv));
        }
    }

    PG_RETURN_NULL();
}

Datum agtype_array_element_impl(FunctionCallInfo fcinfo, agtype *agtype_in,
                                int element, bool as_text)
{
    agtype_value *v;

    if (!AGT_ROOT_IS_ARRAY(agtype_in))
    {
        PG_RETURN_NULL();
    }

    v = execute_array_access_operator_internal(agtype_in, NULL, element);

    return process_access_operator_result(fcinfo, v, as_text);
}

Datum agtype_object_field_impl(FunctionCallInfo fcinfo, agtype *agtype_in,
                               char *key, int key_len, bool as_text)
{
    agtype_value *v;
    agtype* process_agtype;

    if (AGT_ROOT_IS_SCALAR(agtype_in))
    {
        process_agtype =
            agtype_value_to_agtype(extract_entity_properties(agtype_in,
                                                             false));
    }
    else
    {
        process_agtype = agtype_in;
    }

    if (!AGT_ROOT_IS_OBJECT(process_agtype))
    {
        PG_RETURN_NULL();
    }

    v = execute_map_access_operator_internal(process_agtype, NULL,
                                             key, key_len);

    return process_access_operator_result(fcinfo, v, as_text);
}

PG_FUNCTION_INFO_V1(agtype_object_field_agtype);

Datum agtype_object_field_agtype(PG_FUNCTION_ARGS)
{
    agtype *agt = AG_GET_ARG_AGTYPE_P(0);
    agtype *key = AG_GET_ARG_AGTYPE_P(1);
    agtype_value *key_value;

    if (!AGT_ROOT_IS_SCALAR(key))
    {
        PG_RETURN_NULL();
    }

    key_value = get_ith_agtype_value_from_container(&key->root, 0);

    if (key_value->type == AGTV_INTEGER)
    {
        PG_RETURN_TEXT_P(agtype_array_element_impl(fcinfo, agt,
                                                   key_value->val.int_value,
                                                   false));
    }
    else if (key_value->type == AGTV_STRING)
    {
        AG_RETURN_AGTYPE_P(agtype_object_field_impl(fcinfo, agt,
                                                    key_value->val.string.val,
                                                    key_value->val.string.len,
                                                    false));
    }
    else
    {
        PG_RETURN_NULL();
    }
}

PG_FUNCTION_INFO_V1(agtype_object_field_text_agtype);

Datum agtype_object_field_text_agtype(PG_FUNCTION_ARGS)
{
    agtype *agt = AG_GET_ARG_AGTYPE_P(0);
    agtype *key = AG_GET_ARG_AGTYPE_P(1);
    agtype_value *key_value;

    if (!AGT_ROOT_IS_SCALAR(key))
    {
        PG_RETURN_NULL();
    }

    key_value = get_ith_agtype_value_from_container(&key->root, 0);

    if (key_value->type == AGTV_INTEGER)
    {
        PG_RETURN_TEXT_P(agtype_array_element_impl(fcinfo, agt,
                                                   key_value->val.int_value,
                                                   true));
    }
    else if (key_value->type == AGTV_STRING)
    {
        AG_RETURN_AGTYPE_P(agtype_object_field_impl(fcinfo, agt,
                                                    key_value->val.string.val,
                                                    key_value->val.string.len,
                                                    true));
    }
    else
    {
        PG_RETURN_NULL();
    }
}

PG_FUNCTION_INFO_V1(agtype_object_field);

Datum agtype_object_field(PG_FUNCTION_ARGS)
{
    agtype *agt = AG_GET_ARG_AGTYPE_P(0);
    text *key = PG_GETARG_TEXT_PP(1);

    AG_RETURN_AGTYPE_P(agtype_object_field_impl(fcinfo, agt, VARDATA_ANY(key),
                                                VARSIZE_ANY_EXHDR(key),
                                                false));
}

PG_FUNCTION_INFO_V1(agtype_object_field_text);

Datum agtype_object_field_text(PG_FUNCTION_ARGS)
{
    agtype *agt = AG_GET_ARG_AGTYPE_P(0);
    text *key = PG_GETARG_TEXT_PP(1);

    PG_RETURN_TEXT_P(agtype_object_field_impl(fcinfo, agt, VARDATA_ANY(key),
                                              VARSIZE_ANY_EXHDR(key), true));
}

PG_FUNCTION_INFO_V1(agtype_array_element);

Datum agtype_array_element(PG_FUNCTION_ARGS)
{
    agtype *agt = AG_GET_ARG_AGTYPE_P(0);
    int elem = PG_GETARG_INT32(1);

    AG_RETURN_AGTYPE_P(agtype_array_element_impl(fcinfo, agt, elem, false));
}

PG_FUNCTION_INFO_V1(agtype_array_element_text);

Datum agtype_array_element_text(PG_FUNCTION_ARGS)
{
    agtype *agt = AG_GET_ARG_AGTYPE_P(0);
    int elem = PG_GETARG_INT32(1);

    PG_RETURN_TEXT_P(agtype_array_element_impl(fcinfo, agt, elem, true));
}

PG_FUNCTION_INFO_V1(agtype_access_operator);
/*
 * Execution function for object.property, object["property"],
 * and array[element]
 */
Datum agtype_access_operator(PG_FUNCTION_ARGS)
{
    Datum *args = NULL;
    bool *nulls = NULL;
    Oid *types = NULL;
    int nargs = 0;
    agtype *container = NULL;
    agtype_value *container_value = NULL;
    int i = 0;

    /* extract our args, we need at least 2 */
    nargs = extract_variadic_args_min(fcinfo, 0, true, &args, &types, &nulls,
                                      2);
    /*
     * Return NULL if -
     *
     *     1) Our args are all null - nothing passed at all.
     *     2) We don't have the minimum number of args. We require an object or
     *        an array along with either a key or element number. Note that the
     *        function extract_variadic_args_min will return 0 (nargs) if we
     *        don't have at least 2 args.
     *
     */
    if (args == NULL || nargs == 0 || nulls[0] == true)
    {
        PG_RETURN_NULL();
    }

    /* check for individual NULLs */
    for (i = 0; i < nargs; i++)
    {
        /* if we have a NULL, return NULL */
        if (nulls[i] == true)
        {
            PG_RETURN_NULL();
        }
    }

    /* get the container argument. It could be an object or array */
    container = DATUM_GET_AGTYPE_P(args[0]);

    /* if it is a binary container, check for a VLE vpc */
    if (AGT_ROOT_IS_BINARY(container))
    {
        if (AGT_ROOT_BINARY_FLAGS(container) == AGT_FBINARY_TYPE_VLE_PATH)
        {
            /* retrieve an array of edges from the vpc */
            container_value = agtv_materialize_vle_edges(container);
            /* clear the container reference */
            container = NULL;
        }
        else
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("binary container must be a VLE vpc")));
        }
    }
    /* if it is a scalar, open it and pull out the value */
    else if (AGT_ROOT_IS_SCALAR(container))
    {
        container_value = get_ith_agtype_value_from_container(&container->root,
                                                              0);

        /* it must be either a vertex or an edge */
        if (container_value->type != AGTV_EDGE &&
            container_value->type != AGTV_VERTEX)
        {
                ereport(ERROR,(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                               errmsg("scalar object must be a vertex or edge")));
        }

        /* clear the container reference */
        container = NULL;
    }

    /* iterate through the keys (object fields or array elements) */
    for (i = 1; i < nargs; i++)
    {
        agtype *key = NULL;

        /* get the key */
        key = DATUM_GET_AGTYPE_P(args[i]);

        /* the key must be a scalar */
        if (!(AGT_ROOT_IS_SCALAR(key)))
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("key must resolve to a scalar value")));
        }

        /*
         * Check for a vertex or edge container_value and extract the properties
         * object.
         */
        if ((container_value != NULL &&
             (container_value->type == AGTV_EDGE ||
              container_value->type == AGTV_VERTEX)))
        {
            /* both are objects, get the properties object */
            container_value = (container_value->type == AGTV_EDGE)
                ? &container_value->val.object.pairs[4].value
                : &container_value->val.object.pairs[2].value;
        }

        /*
         * If we are dealing with a type of object, which can be an -
         * agtype OBJECT, an agtype_value OBJECT serialized (BINARY), or an
         * agtype_value OBJECT deserialized.
         */
        if ((container_value != NULL &&
             (container_value->type == AGTV_OBJECT ||
              (container_value->type == AGTV_BINARY &&
               AGTYPE_CONTAINER_IS_OBJECT(container_value->val.binary.data)))) ||
            (container != NULL && AGT_ROOT_IS_OBJECT(container)))
        {
            container_value = execute_map_access_operator(container,
                                                          container_value, key);
        }
        /*
         * If we are dealing with a type of array, which can be an -
         * agtype ARRAY, an agtype_value ARRAY serialized (BINARY), or an
         * agtype_value ARRAY deserialized.
         */
        else if ((container_value != NULL &&
                  (container_value->type == AGTV_ARRAY ||
                   (container_value->type == AGTV_BINARY &&
                    AGTYPE_CONTAINER_IS_ARRAY(container_value->val.binary.data)))) ||
                 (container != NULL && AGT_ROOT_IS_ARRAY(container)))
        {
            container_value = execute_array_access_operator(container,
                                                            container_value,
                                                            key);
        }
        else
        {
            /* this is unexpected */
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("container must be an array or object")));
        }

        /* for NULL values return NULL */
        if (container_value == NULL || container_value->type == AGTV_NULL)
        {
            PG_RETURN_NULL();
        }

        /* clear the container reference */
        container = NULL;
    }

    /* serialize and return the result */
    return AGTYPE_P_GET_DATUM(agtype_value_to_agtype(container_value));
}

PG_FUNCTION_INFO_V1(agtype_access_slice);
/*
 * Execution function for list slices
 */
Datum agtype_access_slice(PG_FUNCTION_ARGS)
{
    agtype_value *lidx_value = NULL;
    agtype_value *uidx_value = NULL;
    agtype_in_state result;
    agtype *agt_array = NULL;
    agtype_value *agtv_array = NULL;
    int64 upper_index = 0;
    int64 lower_index = 0;
    uint32 array_size = 0;
    int64 i = 0;

    /* return null if the array to slice is null */
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }

    /* return an error if both indices are NULL */
    if (PG_ARGISNULL(1) && PG_ARGISNULL(2))
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("slice start and/or end is required")));
    }

    /* get the array parameter and verify that it is a list */
    agt_array = AG_GET_ARG_AGTYPE_P(0);

    if ((!AGT_ROOT_IS_ARRAY(agt_array) && !AGT_ROOT_IS_VPC(agt_array)) || AGT_ROOT_IS_SCALAR(agt_array))
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("slice must access a list")));
    }

    /* If we have a vpc, decode it and get AGTV_ARRAY agtype_value */
    if (AGT_ROOT_IS_VPC(agt_array))
    {
        agtv_array = agtv_materialize_vle_edges(agt_array);

        /* get the size of array */
        array_size = agtv_array->val.array.num_elems;
    }
    else
    {
        array_size = AGT_ROOT_COUNT(agt_array);
    }

    /* if we don't have a lower bound, make it 0 */
    if (PG_ARGISNULL(1))
    {
        lower_index = 0;
    }
    else
    {
        lidx_value = get_ith_agtype_value_from_container(
            &(AG_GET_ARG_AGTYPE_P(1))->root, 0);
        /* adjust for AGTV_NULL */
        if (lidx_value->type == AGTV_NULL)
        {
            lower_index = 0;
            lidx_value = NULL;
        }
    }

    /* if we don't have an upper bound, make it the size of the array */
    if (PG_ARGISNULL(2))
    {
        upper_index = array_size;
    }
    else
    {
        uidx_value = get_ith_agtype_value_from_container(
            &(AG_GET_ARG_AGTYPE_P(2))->root, 0);
        /* adjust for AGTV_NULL */
        if (uidx_value->type == AGTV_NULL)
        {
            upper_index = array_size;
            uidx_value = NULL;
        }
    }

    /* if both indices are NULL (AGTV_NULL) return an error */
    if (lidx_value == NULL && uidx_value == NULL)
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("slice start and/or end is required")));
    }

    /* key must be an integer or NULL */
    if ((lidx_value != NULL && lidx_value->type != AGTV_INTEGER) ||
        (uidx_value != NULL && uidx_value->type != AGTV_INTEGER))
    {
        ereport(ERROR,
                (errmsg("array slices must resolve to an integer value")));
    }

    /* set indices if not already set */
    if (lidx_value)
    {
        lower_index = lidx_value->val.int_value;
    }
    if (uidx_value)
    {
        upper_index = uidx_value->val.int_value;
    }

    /* adjust for negative and out of bounds index values */
    if (lower_index < 0)
    {
        lower_index = array_size + lower_index;
    }
    if (lower_index < 0)
    {
        lower_index = 0;
    }
    if (lower_index > array_size)
    {
        lower_index = array_size;
    }
    if (upper_index < 0)
    {
        upper_index = array_size + upper_index;
    }
    if (upper_index < 0)
    {
        upper_index = 0;
    }
    if (upper_index > array_size)
    {
        upper_index = array_size;
    }

    /* build our result array */
    memset(&result, 0, sizeof(agtype_in_state));

    result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_ARRAY,
                                   NULL);

    /* if we have agtype_value, we need to iterate through the array */
    if (agtv_array)
    {
        for (i = lower_index; i < upper_index; i++)
        {
            result.res = push_agtype_value(&result.parse_state, WAGT_ELEM,
                                           &agtv_array->val.array.elems[i]);
        }
    }
    else
    {
        /* get array elements from agtype_container */
        for (i = lower_index; i < upper_index; i++)
        {
            result.res = push_agtype_value(&result.parse_state, WAGT_ELEM,
                get_ith_agtype_value_from_container(&agt_array->root, i));
        }
    }

    result.res = push_agtype_value(&result.parse_state, WAGT_END_ARRAY, NULL);

    PG_RETURN_POINTER(agtype_value_to_agtype(result.res));
}

PG_FUNCTION_INFO_V1(agtype_in_operator);
/*
 * Execute function for IN operator
 */
Datum agtype_in_operator(PG_FUNCTION_ARGS)
{
    agtype *agt_arg, *agt_item;
    agtype_iterator *it_array, *it_item;
    agtype_value *agtv_arg, agtv_item, agtv_elem;
    uint32 array_size = 0;
    bool result = false;
    uint32 i = 0;

    /* return null if the array is null */
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }

    /* get the array parameter and verify that it is a list */
    agt_arg = AG_GET_ARG_AGTYPE_P(0);

    if ((!AGT_ROOT_IS_ARRAY(agt_arg) && !AGT_ROOT_IS_VPC(agt_arg)) || AGT_ROOT_IS_SCALAR(agt_arg))
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("object of IN must be a list")));
    }
    /* If we have vpc as arg, get the agtype_value AGTV_ARRAY of edges */
    if (AGT_ROOT_IS_VPC(agt_arg))
    {
        agtv_arg = agtv_materialize_vle_edges(agt_arg);
        array_size = agtv_arg->val.array.num_elems;

        /* return null if the item to find is null */
        if (PG_ARGISNULL(1))
        {
            PG_RETURN_NULL();
        }
        /* get the item to search for */
        agt_item = AG_GET_ARG_AGTYPE_P(1);

        /* init item iterator */
        it_item = agtype_iterator_init(&agt_item->root);

        /* get value of item */
        agtype_iterator_next(&it_item, &agtv_item, false);
        if (agtv_item.type == AGTV_ARRAY && agtv_item.val.array.raw_scalar)
        {
            agtype_iterator_next(&it_item, &agtv_item, false);
            /* check for AGTYPE NULL */
            if (agtv_item.type == AGTV_NULL)
            {
                PG_RETURN_NULL();
            }
        }

        /* iterate through the array, but stop if we find it */
        for (i = 0; i < array_size && !result; i++)
        {
            agtv_elem = agtv_arg->val.array.elems[i];

            /* if both are containers, compare containers */
            if (!IS_A_AGTYPE_SCALAR(&agtv_item) && !IS_A_AGTYPE_SCALAR(&agtv_elem))
            {
                result = (compare_agtype_containers_orderability(
                            &agt_item->root, agtv_elem.val.binary.data) == 0);
            }
            /* if both are scalars and of the same type, compare scalars */
            else if (IS_A_AGTYPE_SCALAR(&agtv_item) &&
                    IS_A_AGTYPE_SCALAR(&agtv_elem) &&
                    agtv_item.type == agtv_elem.type)
            {
                result = (compare_agtype_scalar_values(&agtv_item, &agtv_elem) ==
                        0);
            }
        }
    }
    /* Else we need to iterate agtype_container */
    else
    {
        /* init array iterator */
        it_array = agtype_iterator_init(&agt_arg->root);
        /* open array container */
        agtype_iterator_next(&it_array, &agtv_elem, false);
        /* check for an array scalar value */
        if (agtv_elem.type == AGTV_ARRAY && agtv_elem.val.array.raw_scalar)
        {
            agtype_iterator_next(&it_array, &agtv_elem, false);
            /* check for AGTYPE NULL */
            if (agtv_elem.type == AGTV_NULL)
            {
                PG_RETURN_NULL();
            }
            /* if it is a scalar, but not AGTV_NULL, error out */
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("object of IN must be a list")));
        }

        array_size = AGT_ROOT_COUNT(agt_arg);

        /* return null if the item to find is null */
        if (PG_ARGISNULL(1))
        {
            PG_RETURN_NULL();
        }
        /* get the item to search for */
        agt_item = AG_GET_ARG_AGTYPE_P(1);

        /* init item iterator */
        it_item = agtype_iterator_init(&agt_item->root);

        /* get value of item */
        agtype_iterator_next(&it_item, &agtv_item, false);
        if (agtv_item.type == AGTV_ARRAY && agtv_item.val.array.raw_scalar)
        {
            agtype_iterator_next(&it_item, &agtv_item, false);
            /* check for AGTYPE NULL */
            if (agtv_item.type == AGTV_NULL)
            {
                PG_RETURN_NULL();
            }
        }

        /* iterate through the array, but stop if we find it */
        for (i = 0; i < array_size && !result; i++)
        {
            /* get next element */
            agtype_iterator_next(&it_array, &agtv_elem, true);
            /* if both are containers, compare containers */
            if (!IS_A_AGTYPE_SCALAR(&agtv_item) && !IS_A_AGTYPE_SCALAR(&agtv_elem))
            {
                result = (compare_agtype_containers_orderability(
                            &agt_item->root, agtv_elem.val.binary.data) == 0);
            }
            /* if both are scalars and of the same type, compare scalars */
            else if (IS_A_AGTYPE_SCALAR(&agtv_item) &&
                    IS_A_AGTYPE_SCALAR(&agtv_elem) &&
                    agtv_item.type == agtv_elem.type)
            {
                result = (compare_agtype_scalar_values(&agtv_item, &agtv_elem) ==
                        0);
            }
        }        
    }

    return boolean_to_agtype(result);
}

PG_FUNCTION_INFO_V1(agtype_string_match_starts_with);
/*
 * Execution function for STARTS WITH
 */
Datum agtype_string_match_starts_with(PG_FUNCTION_ARGS)
{
    agtype *lhs = AG_GET_ARG_AGTYPE_P(0);
    agtype *rhs = AG_GET_ARG_AGTYPE_P(1);

    if (AGT_ROOT_IS_SCALAR(lhs) && AGT_ROOT_IS_SCALAR(rhs))
    {
        agtype_value *lhs_value;
        agtype_value *rhs_value;

        lhs_value = get_ith_agtype_value_from_container(&lhs->root, 0);
        rhs_value = get_ith_agtype_value_from_container(&rhs->root, 0);

        if (lhs_value->type == AGTV_STRING && rhs_value->type == AGTV_STRING)
        {
            if (lhs_value->val.string.len < rhs_value->val.string.len)
                return boolean_to_agtype(false);

            if (strncmp(lhs_value->val.string.val, rhs_value->val.string.val,
                        rhs_value->val.string.len) == 0)
                return boolean_to_agtype(true);
            else
                return boolean_to_agtype(false);
        }
    }
    ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                    errmsg("agtype string values expected")));
}

PG_FUNCTION_INFO_V1(agtype_string_match_ends_with);
/*
 * Execution function for ENDS WITH
 */
Datum agtype_string_match_ends_with(PG_FUNCTION_ARGS)
{
    agtype *lhs = AG_GET_ARG_AGTYPE_P(0);
    agtype *rhs = AG_GET_ARG_AGTYPE_P(1);

    if (AGT_ROOT_IS_SCALAR(lhs) && AGT_ROOT_IS_SCALAR(rhs))
    {
        agtype_value *lhs_value;
        agtype_value *rhs_value;

        lhs_value = get_ith_agtype_value_from_container(&lhs->root, 0);
        rhs_value = get_ith_agtype_value_from_container(&rhs->root, 0);

        if (lhs_value->type == AGTV_STRING && rhs_value->type == AGTV_STRING)
        {
            if (lhs_value->val.string.len < rhs_value->val.string.len)
                return boolean_to_agtype(false);

            if (strncmp(lhs_value->val.string.val + lhs_value->val.string.len -
                            rhs_value->val.string.len,
                        rhs_value->val.string.val,
                        rhs_value->val.string.len) == 0)
                return boolean_to_agtype(true);
            else
                return boolean_to_agtype(false);
        }
    }
    ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                    errmsg("agtype string values expected")));
}

PG_FUNCTION_INFO_V1(agtype_string_match_contains);
/*
 * Execution function for CONTAINS
 */
Datum agtype_string_match_contains(PG_FUNCTION_ARGS)
{
    agtype *lhs = AG_GET_ARG_AGTYPE_P(0);
    agtype *rhs = AG_GET_ARG_AGTYPE_P(1);

    if (AGT_ROOT_IS_SCALAR(lhs) && AGT_ROOT_IS_SCALAR(rhs))
    {
        agtype_value *lhs_value;
        agtype_value *rhs_value;

        lhs_value = get_ith_agtype_value_from_container(&lhs->root, 0);
        rhs_value = get_ith_agtype_value_from_container(&rhs->root, 0);

        if (lhs_value->type == AGTV_STRING && rhs_value->type == AGTV_STRING)
        {
            char *l;
            char *r;

            if (lhs_value->val.string.len < rhs_value->val.string.len)
                return boolean_to_agtype(false);

            l = pnstrdup(lhs_value->val.string.val, lhs_value->val.string.len);
            r = pnstrdup(rhs_value->val.string.val, rhs_value->val.string.len);

            if (strstr(l, r) == NULL)
                return boolean_to_agtype(false);
            else
                return boolean_to_agtype(true);
        }
    }
    ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                    errmsg("agtype string values expected")));
}

#define LEFT_ROTATE(n, i) ((n << i) | (n >> (64 - i)))
#define RIGHT_ROTATE(n, i)  ((n >> i) | (n << (64 - i)))

//Hashing Function for Hash Indexes
PG_FUNCTION_INFO_V1(agtype_hash_cmp);

Datum agtype_hash_cmp(PG_FUNCTION_ARGS)
{
    uint64 hash = 0;
    agtype *agt;
    agtype_iterator *it;
    agtype_iterator_token tok;
    agtype_value *r;
    uint64 seed = 0xF0F0F0F0;

    if (PG_ARGISNULL(0))
        PG_RETURN_INT16(0);

    agt = AG_GET_ARG_AGTYPE_P(0);

    r = palloc0(sizeof(agtype_value));

    it = agtype_iterator_init(&agt->root);
    while ((tok = agtype_iterator_next(&it, r, false)) != WAGT_DONE)
    {
        if (IS_A_AGTYPE_SCALAR(r) && AGTYPE_ITERATOR_TOKEN_IS_HASHABLE(tok))
            agtype_hash_scalar_value_extended(r, &hash, seed);
        else if (tok == WAGT_BEGIN_ARRAY && !r->val.array.raw_scalar)
            seed = LEFT_ROTATE(seed, 4);
        else if (tok == WAGT_BEGIN_OBJECT)
            seed = LEFT_ROTATE(seed, 6);
        else if (tok == WAGT_END_ARRAY && !r->val.array.raw_scalar)
            seed = RIGHT_ROTATE(seed, 4);
        else if (tok == WAGT_END_OBJECT)
            seed = RIGHT_ROTATE(seed, 4);

        seed = LEFT_ROTATE(seed, 1);
    }

    PG_RETURN_INT16(hash);
}

// Comparison function for btree Indexes
PG_FUNCTION_INFO_V1(agtype_btree_cmp);

Datum agtype_btree_cmp(PG_FUNCTION_ARGS)
{
    agtype *agtype_lhs;
    agtype *agtype_rhs;

    if (PG_ARGISNULL(0) && PG_ARGISNULL(1))
        PG_RETURN_INT16(0);
    else if (PG_ARGISNULL(0))
        PG_RETURN_INT16(1);
    else if (PG_ARGISNULL(1))
        PG_RETURN_INT16(-1);

    agtype_lhs = AG_GET_ARG_AGTYPE_P(0);
    agtype_rhs = AG_GET_ARG_AGTYPE_P(1);

    PG_RETURN_INT16(compare_agtype_containers_orderability(&agtype_lhs->root,
                                                     &agtype_rhs->root));
}

PG_FUNCTION_INFO_V1(agtype_typecast_numeric);
/*
 * Execute function to typecast an agtype to an agtype numeric
 */
Datum agtype_typecast_numeric(PG_FUNCTION_ARGS)
{
    agtype *arg_agt;
    agtype_value *arg_value;
    agtype_value result_value;
    Datum numd;
    char *string = NULL;

    /* get the agtype equivalence of any convertable input type */
    arg_agt = get_one_agtype_from_variadic_args(fcinfo, 0, 1);

    /* Return null if arg_agt is null. This covers SQL and Agtype NULLS */
    if (arg_agt == NULL)
        PG_RETURN_NULL();

    /* check that we have a scalar value */
    if (!AGT_ROOT_IS_SCALAR(arg_agt))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("typecast argument must resolve to a scalar value")));

    /* get the arg parameter */
    arg_value = get_ith_agtype_value_from_container(&arg_agt->root, 0);

    /* the input type drives the casting */
    switch(arg_value->type)
    {
    case AGTV_INTEGER:
        numd = DirectFunctionCall1(int8_numeric,
                                   Int64GetDatum(arg_value->val.int_value));
        break;
    case AGTV_FLOAT:
        numd = DirectFunctionCall1(float8_numeric,
                                   Float8GetDatum(arg_value->val.float_value));
        break;
    case AGTV_NUMERIC:
        /* it is already a numeric so just return it */
        PG_RETURN_POINTER(agtype_value_to_agtype(arg_value));
        break;
    /* this allows string numbers and NaN */
    case AGTV_STRING:
        /* we need a null terminated string */
        string = (char *) palloc0(sizeof(char)*arg_value->val.string.len + 1);
        string = strncpy(string, arg_value->val.string.val,
                         arg_value->val.string.len);
        string[arg_value->val.string.len] = '\0';
        /* pass the string to the numeric in function for conversion */
        numd = DirectFunctionCall3(numeric_in,
                                   CStringGetDatum(string),
                                   ObjectIdGetDatum(InvalidOid),
                                   Int32GetDatum(-1));
        /* free the string */
        pfree(string);
        string = NULL;
        break;
    /* what was given doesn't cast to a numeric */
    default:
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("typecast expression must be a number or a string")));
        break;
    }

    /* fill in and return our result */
    result_value.type = AGTV_NUMERIC;
    result_value.val.numeric = DatumGetNumeric(numd);

    PG_RETURN_POINTER(agtype_value_to_agtype(&result_value));
}

PG_FUNCTION_INFO_V1(agtype_typecast_int);
/*
 * Execute function to typecast an agtype to an agtype int
 */
Datum agtype_typecast_int(PG_FUNCTION_ARGS)
{
    agtype *arg_agt;
    agtype_value *arg_value;
    agtype_value result_value;
    Datum d;
    char *string = NULL;

    /* get the agtype equivalence of any convertable input type */
    arg_agt = get_one_agtype_from_variadic_args(fcinfo, 0, 1);

    /* Return null if arg_agt is null. This covers SQL and Agtype NULLS */
    if (arg_agt == NULL)
    {    
        PG_RETURN_NULL();
    }

    /* check that we have a scalar value */
    if (!AGT_ROOT_IS_SCALAR(arg_agt))
    {    
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("typecast argument must be a scalar value")));
    }

    /* get the arg parameter */
    arg_value = get_ith_agtype_value_from_container(&arg_agt->root, 0);

    /* check for agtype null */
    if (arg_value->type == AGTV_NULL)
    {    
        PG_RETURN_NULL();
    }

    /* the input type drives the casting */
    switch(arg_value->type)
    {
    case AGTV_INTEGER:
        PG_RETURN_POINTER(agtype_value_to_agtype(arg_value));
        break;
    case AGTV_FLOAT:
        d = DirectFunctionCall1(dtoi8,
                                Float8GetDatum(arg_value->val.float_value));
        break;
    case AGTV_NUMERIC:
        d = DirectFunctionCall1(numeric_int8,
                                NumericGetDatum(arg_value->val.numeric));
        break;
    case AGTV_BOOL:
        d = DirectFunctionCall1(bool_int4, 
                                BoolGetDatum(arg_value->val.boolean));
        break;
    case AGTV_STRING:
        /* we need a null terminated string */
        string = (char *) palloc0(sizeof(char)*arg_value->val.string.len + 1);
        string = strncpy(string, arg_value->val.string.val,
                         arg_value->val.string.len);
        string[arg_value->val.string.len] = '\0';

        d = DirectFunctionCall1(int8in, CStringGetDatum(string));
        /* free the string */
        pfree(string);
        string = NULL;
        break;
    /* what was given doesn't cast to an int */
    default:
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("typecast expression must be a number or a string")));
        break;
    }

    /* set the result type and return our result */
    result_value.type = AGTV_INTEGER;
    result_value.val.int_value = DatumGetInt64(d);

    PG_RETURN_POINTER(agtype_value_to_agtype(&result_value));
}

PG_FUNCTION_INFO_V1(agtype_typecast_bool);
/*
 * Execute function to typecast an agtype to an agtype bool
 */
Datum agtype_typecast_bool(PG_FUNCTION_ARGS)
{
    agtype *arg_agt;
    agtype_value *arg_value;
    agtype_value result_value;
    Datum d;

    /* get the agtype equivalence of any convertable input type */
    arg_agt = get_one_agtype_from_variadic_args(fcinfo, 0, 1);

    /* Return null if arg_agt is null. This covers SQL and Agtype NULLS */
    if (arg_agt == NULL)
    {    
        PG_RETURN_NULL();
    }

    /* check that we have a scalar value */
    if (!AGT_ROOT_IS_SCALAR(arg_agt))
    {    
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("typecast argument must be a scalar value")));
    }

    /* get the arg parameter */
    arg_value = get_ith_agtype_value_from_container(&arg_agt->root, 0);

    /* check for agtype null */
    if (arg_value->type == AGTV_NULL)
    {    
        PG_RETURN_NULL();
    }

    /* the input type drives the casting */
    switch(arg_value->type)
    {
    case AGTV_BOOL:
        PG_RETURN_POINTER(agtype_value_to_agtype(arg_value));
        break;
    case AGTV_INTEGER:
        d = DirectFunctionCall1(int4_bool,
                                Int64GetDatum(arg_value->val.int_value));
        break;
    /* what was given doesn't cast to a bool */
    default:
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("typecast expression must be an integer or a boolean")));
        break;
    }

    /* set the result type and return our result */
    result_value.type = AGTV_BOOL;
    result_value.val.boolean = DatumGetBool(d);

    PG_RETURN_POINTER(agtype_value_to_agtype(&result_value));
}

PG_FUNCTION_INFO_V1(agtype_typecast_float);
/*
 * Execute function to typecast an agtype to an agtype float
 */
Datum agtype_typecast_float(PG_FUNCTION_ARGS)
{
    agtype *arg_agt;
    agtype_value *arg_value;
    agtype_value result_value;
    Datum d;
    char *string = NULL;

    /* get the agtype equivalence of any convertable input type */
    arg_agt = get_one_agtype_from_variadic_args(fcinfo, 0, 1);

    /* Return null if arg_agt is null. This covers SQL and Agtype NULLS */
    if (arg_agt == NULL)
        PG_RETURN_NULL();

    /* check that we have a scalar value */
    if (!AGT_ROOT_IS_SCALAR(arg_agt))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("typecast argument must be a scalar value")));

    /* get the arg parameter */
    arg_value = get_ith_agtype_value_from_container(&arg_agt->root, 0);
    /* check for agtype null */
    if (arg_value->type == AGTV_NULL)
        PG_RETURN_NULL();

    /* the input type drives the casting */
    switch(arg_value->type)
    {
    case AGTV_INTEGER:
        d = DirectFunctionCall1(int8out,
                                Int64GetDatum(arg_value->val.int_value));
        d = DirectFunctionCall1(float8in, d);
        break;
    case AGTV_FLOAT:
        /* it is already a float so just return it */
        PG_RETURN_POINTER(agtype_value_to_agtype(arg_value));
        break;
    case AGTV_NUMERIC:
        d = DirectFunctionCall1(numeric_float8,
                                NumericGetDatum(arg_value->val.numeric));
        break;
    /* this allows string numbers, NaN, Infinity, and -Infinity */
    case AGTV_STRING:
        /* we need a null terminated string */
        string = (char *) palloc0(sizeof(char)*arg_value->val.string.len + 1);
        string = strncpy(string, arg_value->val.string.val,
                         arg_value->val.string.len);
        string[arg_value->val.string.len] = '\0';

        d = DirectFunctionCall1(float8in, CStringGetDatum(string));
        /* free the string */
        pfree(string);
        string = NULL;
        break;
    /* what was given doesn't cast to a float */
    default:
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("typecast expression must be a number or a string")));
        break;
    }

    /* set the result type and return our result */
    result_value.type = AGTV_FLOAT;
    result_value.val.float_value = DatumGetFloat8(d);

    PG_RETURN_POINTER(agtype_value_to_agtype(&result_value));
}

PG_FUNCTION_INFO_V1(agtype_typecast_vertex);
/*
 * Execute function for typecast to vertex
 */
Datum agtype_typecast_vertex(PG_FUNCTION_ARGS)
{
    agtype *arg_agt;
    agtype_value agtv_key;
    agtype_value *agtv_graphid, *agtv_label, *agtv_properties;
    Datum result;
    int count;

    /* get the agtype equivalence of any convertable input type */
    arg_agt = get_one_agtype_from_variadic_args(fcinfo, 0, 1);

    /* Return null if arg_agt is null. This covers SQL and Agtype NULLS */
    if (arg_agt == NULL)
        PG_RETURN_NULL();

    /* A vertex is an object so the arg needs to be one too */
    if (!AGT_ROOT_IS_OBJECT(arg_agt))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("vertex typecast argument must resolve to an object")));

    /* A vertex object has 3 key/value pairs */
    count = AGTYPE_CONTAINER_SIZE(&arg_agt->root);
    if (count != 3)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("typecast object is not a vertex")));

    /*
     * The 3 key/value pairs need to each exist and their names need to match
     * the names used for a vertex.
     */
    agtv_key.type = AGTV_STRING;
    agtv_key.val.string.val = "id";
    agtv_key.val.string.len = 2;
    agtv_graphid = find_agtype_value_from_container(&arg_agt->root,
                                                    AGT_FOBJECT, &agtv_key);
    if (agtv_graphid == NULL || agtv_graphid->type != AGTV_INTEGER)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("vertex typecast object has invalid or missing id")));

    agtv_key.val.string.val = "label";
    agtv_key.val.string.len = 5;
    agtv_label = find_agtype_value_from_container(&arg_agt->root,
                                                  AGT_FOBJECT, &agtv_key);
    if (agtv_label == NULL || agtv_label->type != AGTV_STRING)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("vertex typecast object has invalid or missing label")));

    agtv_key.val.string.val = "properties";
    agtv_key.val.string.len = 10;
    agtv_properties = find_agtype_value_from_container(&arg_agt->root,
                                                       AGT_FOBJECT, &agtv_key);
    if (agtv_properties == NULL ||
        (agtv_properties->type != AGTV_OBJECT &&
         agtv_properties->type != AGTV_BINARY))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("vertex typecast object has invalid or missing properties")));

    /* Hand it off to the build vertex routine */
    result = DirectFunctionCall3(_agtype_build_vertex,
                 Int64GetDatum(agtv_graphid->val.int_value),
                 CStringGetDatum(agtv_label->val.string.val),
                 PointerGetDatum(agtype_value_to_agtype(agtv_properties)));
    return result;
}

PG_FUNCTION_INFO_V1(agtype_typecast_edge);
/*
 * Execute function for typecast to edge
 */
Datum agtype_typecast_edge(PG_FUNCTION_ARGS)
{
    agtype *arg_agt;
    agtype_value agtv_key;
    agtype_value *agtv_graphid, *agtv_label, *agtv_properties,
                 *agtv_startid, *agtv_endid;
    Datum result;
    int count;

    /* get the agtype equivalence of any convertable input type */
    arg_agt = get_one_agtype_from_variadic_args(fcinfo, 0, 1);

    /* Return null if arg_agt is null. This covers SQL and Agtype NULLS */
    if (arg_agt == NULL)
        PG_RETURN_NULL();

    /* An edge is an object, so the arg needs to be one too */
    if (!AGT_ROOT_IS_OBJECT(arg_agt))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("edge typecast argument must resolve to an object")));

    /* An edge has 5 key/value pairs */
    count = AGTYPE_CONTAINER_SIZE(&arg_agt->root);
    if (count != 5)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("typecast object is not an edge")));

    /*
     * The 5 key/value pairs need to each exist and their names need to match
     * the names used for an edge.
     */
    agtv_key.type = AGTV_STRING;
    agtv_key.val.string.val = "id";
    agtv_key.val.string.len = 2;
    agtv_graphid = find_agtype_value_from_container(&arg_agt->root,
                                                    AGT_FOBJECT, &agtv_key);
    if (agtv_graphid == NULL || agtv_graphid->type != AGTV_INTEGER)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("edge typecast object has an invalid or missing id")));

    agtv_key.val.string.val = "label";
    agtv_key.val.string.len = 5;
    agtv_label = find_agtype_value_from_container(&arg_agt->root,
                                                  AGT_FOBJECT, &agtv_key);
    if (agtv_label == NULL || agtv_label->type != AGTV_STRING)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("edge typecast object has an invalid or missing label")));

    agtv_key.val.string.val = "properties";
    agtv_key.val.string.len = 10;
    agtv_properties = find_agtype_value_from_container(&arg_agt->root,
                                                 AGT_FOBJECT, &agtv_key);
    if (agtv_properties == NULL ||
        (agtv_properties->type != AGTV_OBJECT &&
         agtv_properties->type != AGTV_BINARY))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("edge typecast object has invalid or missing properties")));

    agtv_key.val.string.val = "start_id";
    agtv_key.val.string.len = 8;
    agtv_startid = find_agtype_value_from_container(&arg_agt->root,
                                                    AGT_FOBJECT, &agtv_key);
    if (agtv_startid == NULL || agtv_startid->type != AGTV_INTEGER)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("edge typecast object has an invalid or missing start_id")));

    agtv_key.val.string.val = "end_id";
    agtv_key.val.string.len = 6;
    agtv_endid = find_agtype_value_from_container(&arg_agt->root,
                                                    AGT_FOBJECT, &agtv_key);
    if (agtv_endid == NULL || agtv_endid->type != AGTV_INTEGER)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("edge typecast object has an invalid or missing end_id")));

    /* Hand it off to the build edge routine */
    result = DirectFunctionCall5(_agtype_build_edge,
                 Int64GetDatum(agtv_graphid->val.int_value),
                 Int64GetDatum(agtv_startid->val.int_value),
                 Int64GetDatum(agtv_endid->val.int_value),
                 CStringGetDatum(agtv_label->val.string.val),
                 PointerGetDatum(agtype_value_to_agtype(agtv_properties)));
    return result;
}

PG_FUNCTION_INFO_V1(agtype_typecast_path);
/*
 * Execute function for typecast to path
 */
Datum agtype_typecast_path(PG_FUNCTION_ARGS)
{
    agtype *arg_agt = NULL;
    agtype_in_state path;
    agtype_value *agtv_element = NULL;
    int count = 0;
    int i = 0;

    /* get the agtype equivalence of any convertable input type */
    arg_agt = get_one_agtype_from_variadic_args(fcinfo, 0, 1);

    /* Return null if arg_agt is null. This covers SQL and Agtype NULLS */
    if (arg_agt == NULL)
        PG_RETURN_NULL();

    /* path needs to be an array */
    if (!AGT_ROOT_IS_ARRAY(arg_agt))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("path typecast argument must resolve to an array")));

    count = AGT_ROOT_COUNT(arg_agt);

    /* quick check for valid path lengths */
    if (count < 3 || (count-1) % 2 != 0)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("typecast argument is not a valid path")));

    /* create an agtype array */
    memset(&path, 0, sizeof(agtype_in_state));
    path.res = push_agtype_value(&path.parse_state, WAGT_BEGIN_ARRAY, NULL);

    /*
     * Iterate through the provided list, check that each value conforms, and
     * then add it if it does. Otherwise error out.
     */
    for (i = 0; i+1 < count; i+=2)
    {
        /* get a potential vertex, check it, then add it */
        agtv_element = get_ith_agtype_value_from_container(&arg_agt->root, i);
        if (agtv_element == NULL || agtv_element->type != AGTV_VERTEX)
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("typecast argument is not a valid path")));
        push_agtype_value(&path.parse_state, WAGT_ELEM, agtv_element);

        /* get a potential edge, check it, then add it */
        agtv_element = get_ith_agtype_value_from_container(&arg_agt->root, i+1);
        if (agtv_element == NULL || agtv_element->type != AGTV_EDGE)
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("typecast argument is not a valid path")));
        push_agtype_value(&path.parse_state, WAGT_ELEM, agtv_element);
    }

    /* validate the last element is a vertex, add it if it is, fail otherwise */
    agtv_element = get_ith_agtype_value_from_container(&arg_agt->root, i);
    if (agtv_element == NULL || agtv_element->type != AGTV_VERTEX)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("typecast argument is not a valid path")));
    push_agtype_value(&path.parse_state, WAGT_ELEM, agtv_element);

    /* close the array */
    path.res = push_agtype_value(&path.parse_state, WAGT_END_ARRAY, NULL);
    /* set it to a path */
    path.res->type = AGTV_PATH;

    PG_RETURN_POINTER(agtype_value_to_agtype(path.res));
}

PG_FUNCTION_INFO_V1(age_id);

Datum age_id(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_object = NULL;
    agtype_value *agtv_result = NULL;

    /* check for null */
    if (PG_ARGISNULL(0))
        PG_RETURN_NULL();

    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for a scalar object */
    if (!AGT_ROOT_IS_SCALAR(agt_arg))
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("id() argument must resolve to a scalar value")));

    /* get the object out of the array */
    agtv_object = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    /* is it an agtype null? */
    if (agtv_object->type == AGTV_NULL)
            PG_RETURN_NULL();

    /* check for proper agtype */
    if (agtv_object->type != AGTV_VERTEX && agtv_object->type != AGTV_EDGE)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("id() argument must be a vertex, an edge or null")));

    agtv_result = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_object, "id");

    Assert(agtv_result != NULL);
    Assert(agtv_result->type = AGTV_INTEGER);

    PG_RETURN_POINTER(agtype_value_to_agtype(agtv_result));
}

PG_FUNCTION_INFO_V1(age_start_id);

Datum age_start_id(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_object = NULL;
    agtype_value *agtv_result = NULL;

    /* check for null */
    if (PG_ARGISNULL(0))
        PG_RETURN_NULL();

    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for a scalar object */
    if (!AGT_ROOT_IS_SCALAR(agt_arg))
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("start_id() argument must resolve to a scalar value")));

    /* get the object out of the array */
    agtv_object = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    /* is it an agtype null? */
    if (agtv_object->type == AGTV_NULL)
            PG_RETURN_NULL();

    /* check for proper agtype */
    if (agtv_object->type != AGTV_EDGE)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("start_id() argument must be an edge or null")));

    agtv_result = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_object, "start_id");

    Assert(agtv_result != NULL);
    Assert(agtv_result->type = AGTV_INTEGER);

    PG_RETURN_POINTER(agtype_value_to_agtype(agtv_result));
}

PG_FUNCTION_INFO_V1(age_end_id);

Datum age_end_id(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_object = NULL;
    agtype_value *agtv_result = NULL;

    /* check for null */
    if (PG_ARGISNULL(0))
        PG_RETURN_NULL();

    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for a scalar object */
    if (!AGT_ROOT_IS_SCALAR(agt_arg))
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("end_id() argument must resolve to a scalar value")));

    /* get the object out of the array */
    agtv_object = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    /* is it an agtype null? */
    if (agtv_object->type == AGTV_NULL)
            PG_RETURN_NULL();

    /* check for proper agtype */
    if (agtv_object->type != AGTV_EDGE)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("end_id() argument must be an edge or null")));

    agtv_result = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_object, "end_id");

    Assert(agtv_result != NULL);
    Assert(agtv_result->type = AGTV_INTEGER);

    PG_RETURN_POINTER(agtype_value_to_agtype(agtv_result));
}

/*
 * Helper function to return the Datum value of a column (attribute) in a heap
 * tuple (row) given the column number (starting from 0), attribute name, typid,
 * and whether it can be null. The function is designed to extract and validate
 * that the data (attribute) is what is expected. The function will error on any
 * issues.
 */
Datum column_get_datum(TupleDesc tupdesc, HeapTuple tuple, int column,
                       const char *attname, Oid typid, bool isnull)
{
    Form_pg_attribute att;
    HeapTupleHeader hth;
    HeapTupleData tmptup, *htd;
    Datum result;
    bool _isnull = true;

    /* build the heap tuple data */
    hth = tuple->t_data;
    tmptup.t_len = HeapTupleHeaderGetDatumLength(hth);
    tmptup.t_data = hth;
    htd = &tmptup;

    /* get the description for the column from the tuple descriptor */
    att = TupleDescAttr(tupdesc, column);
    /* get the datum (attribute) for that column*/
    result = heap_getattr(htd, column + 1, tupdesc, &_isnull);
    /* verify that the attribute typid is as expected */
    if (att->atttypid != typid)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_TABLE),
                 errmsg("Invalid attribute typid. Expected %d, found %d", typid,
                        att->atttypid)));
    /* verify that the attribute name is as expected */
    if (strcmp(att->attname.data, attname) != 0)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_TABLE),
                 errmsg("Invalid attribute name. Expected %s, found %s",
                        attname, att->attname.data)));
    /* verify that if it is null, it is allowed to be null */
    if (isnull == false && _isnull == true)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_TABLE),
                 errmsg("Attribute was found to be null when null is not allowed.")));

    return result;
}

/*
 * Function to retrieve a label name, given the graph name and graphid. The
 * function returns a pointer to a duplicated string that needs to be freed
 * when you are finished using it.
 */
static char *get_label_name(const char *graph_name, int64 graphid)
{
    ScanKeyData scan_keys[2];
    Relation ag_label;
    SysScanDesc scan_desc;
    HeapTuple tuple;
    TupleDesc tupdesc;
    char *result = NULL;

    Oid graphoid = get_graph_oid(graph_name);

    /* scankey for first match in ag_label, column 2, graphoid, BTEQ, OidEQ */
    ScanKeyInit(&scan_keys[0], Anum_ag_label_graph, BTEqualStrategyNumber,
                F_OIDEQ, ObjectIdGetDatum(graphoid));
    /* scankey for second match in ag_label, column 3, label id, BTEQ, Int4EQ */
    ScanKeyInit(&scan_keys[1], Anum_ag_label_id, BTEqualStrategyNumber,
                F_INT4EQ, Int32GetDatum(get_graphid_label_id(graphid)));

    ag_label = heap_open(ag_relation_id("ag_label", "table"), ShareLock);
    scan_desc = systable_beginscan(ag_label,
                                   ag_relation_id("ag_label_graph_id_index",
                                                  "index"), true, NULL, 2,
                                   scan_keys);

    tuple = systable_getnext(scan_desc);
    if (!HeapTupleIsValid(tuple))
    {
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_SCHEMA),
                 errmsg("graphid %lu does not exist", graphid)));
    }

    /* get the tupdesc - we don't need to release this one */
    tupdesc = RelationGetDescr(ag_label);

    /* bail if the number of columns differs */
    if (tupdesc->natts != 6)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_TABLE),
                 errmsg("Invalid number of attributes for ag_catalog.ag_label")));

    /* get the label name */
    result = NameStr(*DatumGetName(column_get_datum(tupdesc, tuple, 0, "name",
                                                    NAMEOID, true)));
    /* duplicate it */
    result = strdup(result);

    /* end the scan and close the relation */
    systable_endscan(scan_desc);
    heap_close(ag_label, ShareLock);

    return result;
}

static Datum get_vertex(const char *graph, const char *vertex_label,
                        int64 graphid)
{
    ScanKeyData scan_keys[1];
    Relation graph_vertex_label;
    HeapScanDesc scan_desc;
    HeapTuple tuple;
    TupleDesc tupdesc;
    Datum id, properties, result;

    /* get the specific graph namespace (schema) */
    Oid graph_namespace_oid = get_namespace_oid(graph, false);
    /* get the specific vertex label table (schema.vertex_label) */
    Oid vertex_label_table_oid = get_relname_relid(vertex_label,
                                                 graph_namespace_oid);
    /* get the active snapshot */
    Snapshot snapshot = GetActiveSnapshot();

    /* initialize the scan key */
    ScanKeyInit(&scan_keys[0], 1, BTEqualStrategyNumber, F_OIDEQ,
                Int64GetDatum(graphid));

    /* open the relation (table), begin the scan, and get the tuple  */
    graph_vertex_label = heap_open(vertex_label_table_oid, ShareLock);
    scan_desc = heap_beginscan(graph_vertex_label, snapshot, 1, scan_keys);
    tuple = heap_getnext(scan_desc, ForwardScanDirection);

    /* bail if the tuple isn't valid */
    if (!HeapTupleIsValid(tuple))
    {
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_TABLE),
                 errmsg("graphid %lu does not exist", graphid)));
    }

    /* get the tupdesc - we don't need to release this one */
    tupdesc = RelationGetDescr(graph_vertex_label);
    /* bail if the number of columns differs */
    if (tupdesc->natts != 2)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_TABLE),
                 errmsg("Invalid number of attributes for %s.%s", graph,
                        vertex_label )));

    /* get the id */
    id = column_get_datum(tupdesc, tuple, 0, "id", GRAPHIDOID, true);
    /* get the properties */
    properties = column_get_datum(tupdesc, tuple, 1, "properties",
                                  AGTYPEOID, true);
    /* reconstruct the vertex */
    result = DirectFunctionCall3(_agtype_build_vertex, id,
                                 CStringGetDatum(vertex_label), properties);
    /* end the scan and close the relation */
    heap_endscan(scan_desc);
    heap_close(graph_vertex_label, ShareLock);
    /* return the vertex datum */
    return result;
}

PG_FUNCTION_INFO_V1(age_startnode);

Datum age_startnode(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_object = NULL;
    agtype_value *agtv_value = NULL;
    char *graph_name = NULL;
    char *label_name = NULL;
    graphid graph_id;
    Datum result;

    /* we need the graph name */
    Assert(PG_ARGISNULL(0) == false);

    /* check for null */
    if (PG_ARGISNULL(1))
        PG_RETURN_NULL();

    /* get the graph name */
    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* it must be a scalar and must be a string */
    Assert(AGT_ROOT_IS_SCALAR(agt_arg));
    agtv_object = get_ith_agtype_value_from_container(&agt_arg->root, 0);
    Assert(agtv_object->type == AGTV_STRING);
    graph_name = strndup(agtv_object->val.string.val,
                         agtv_object->val.string.len);

    /* get the edge */
    agt_arg = AG_GET_ARG_AGTYPE_P(1);
    /* check for a scalar object */
    if (!AGT_ROOT_IS_SCALAR(agt_arg))
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("startNode() argument must resolve to a scalar value")));
    /* get the object */
    agtv_object = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    /* is it an agtype null, return null if it is */
    if (agtv_object->type == AGTV_NULL)
            PG_RETURN_NULL();

    /* check for proper agtype */
    if (agtv_object->type != AGTV_EDGE)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("startNode() argument must be an edge or null")));

    /* get the graphid for start_id */
    agtv_value = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_object, "start_id");
    /* it must not be null and must be an integer */
    Assert(agtv_value != NULL);
    Assert(agtv_value->type = AGTV_INTEGER);
    graph_id = agtv_value->val.int_value;

    /* get the label */
    label_name = get_label_name(graph_name, graph_id);
    /* it must not be null and must be a string */
    Assert(label_name != NULL);

    result = get_vertex(graph_name, label_name, graph_id);

    free(label_name);

    return result;
}

PG_FUNCTION_INFO_V1(age_endnode);

Datum age_endnode(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_object = NULL;
    agtype_value *agtv_value = NULL;
    char *graph_name = NULL;
    char *label_name = NULL;
    graphid graph_id;
    Datum result;

    /* we need the graph name */
    Assert(PG_ARGISNULL(0) == false);

    /* check for null */
    if (PG_ARGISNULL(1))
        PG_RETURN_NULL();

    /* get the graph name */
    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* it must be a scalar and must be a string */
    Assert(AGT_ROOT_IS_SCALAR(agt_arg));
    agtv_object = get_ith_agtype_value_from_container(&agt_arg->root, 0);
    Assert(agtv_object->type == AGTV_STRING);
    graph_name = strndup(agtv_object->val.string.val,
                         agtv_object->val.string.len);

    /* get the edge */
    agt_arg = AG_GET_ARG_AGTYPE_P(1);
    /* check for a scalar object */
    if (!AGT_ROOT_IS_SCALAR(agt_arg))
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("endNode() argument must resolve to a scalar value")));
    /* get the object */
    agtv_object = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    /* is it an agtype null, return null if it is */
    if (agtv_object->type == AGTV_NULL)
            PG_RETURN_NULL();

    /* check for proper agtype */
    if (agtv_object->type != AGTV_EDGE)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("endNode() argument must be an edge or null")));

    /* get the graphid for the end_id */
    agtv_value = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_object, "end_id");
    /* it must not be null and must be an integer */
    Assert(agtv_value != NULL);
    Assert(agtv_value->type = AGTV_INTEGER);
    graph_id = agtv_value->val.int_value;

    /* get the label */
    label_name = get_label_name(graph_name, graph_id);
    /* it must not be null and must be a string */
    Assert(label_name != NULL);

    result = get_vertex(graph_name, label_name, graph_id);

    free(label_name);

    return result;
}

PG_FUNCTION_INFO_V1(age_head);

Datum age_head(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_arg = NULL;
    agtype_value *agtv_result = NULL;

    /* check for null */
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }

    agt_arg = AG_GET_ARG_AGTYPE_P(0);
 
    /* check for an array */
    if ((!AGT_ROOT_IS_ARRAY(agt_arg) && !AGT_ROOT_IS_VPC(agt_arg)) || AGT_ROOT_IS_SCALAR(agt_arg))
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("head() argument must resolve to a list or null")));
    }

    /*
     * If we have a vpc, materialize the edges to get AGTV_ARRAY
     * agtype_value, process it and return the result.
     */
    if (AGT_ROOT_IS_VPC(agt_arg))
    {
        agtv_arg = agtv_materialize_vle_edges(agt_arg);

        /* if we have an empty list, return a null */
        if (agtv_arg->val.array.num_elems == 0)
        {
            PG_RETURN_NULL();
        }

        /* get the first element of the array */
        agtv_result = &agtv_arg->val.array.elems[0];
    }
    else
    {
        /* if we have an empty list, return a null */
        if (AGT_ROOT_COUNT(agt_arg) == 0)
        {
            PG_RETURN_NULL();
        }

        /* get the first element of the array */
        agtv_result = get_ith_agtype_value_from_container(&agt_arg->root, 0);
    }

    /* if it is AGTV_NULL, return null */
    if (agtv_result->type == AGTV_NULL)
    {
        PG_RETURN_NULL();
    }

    PG_RETURN_POINTER(agtype_value_to_agtype(agtv_result));
}

PG_FUNCTION_INFO_V1(age_last);

Datum age_last(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_arg = NULL;
    agtype_value *agtv_result = NULL;
    int size;

    /* check for null */
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }

    agt_arg = AG_GET_ARG_AGTYPE_P(0);

    /* check for an array */
    if ((!AGT_ROOT_IS_ARRAY(agt_arg) && !AGT_ROOT_IS_VPC(agt_arg)) || AGT_ROOT_IS_SCALAR(agt_arg))
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("last() argument must resolve to a list or null")));
    }

    /*
     * If we have a vpc, materialize the edges to get AGTV_ARRAY
     * agtype_value, process it and return the result.
     */
    if (AGT_ROOT_IS_VPC(agt_arg))
    {
        agtv_arg = agtv_materialize_vle_edges(agt_arg);

        size = agtv_arg->val.array.num_elems;

        /* if we have an empty list, return a null */
        if (size == 0)
        {
            PG_RETURN_NULL();
        }

        /* get the first element of the array */
        agtv_result = &agtv_arg->val.array.elems[size-1];
    }
    else
    {
        size = AGT_ROOT_COUNT(agt_arg);

        /* if we have an empty list, return a null */
        if (size == 0)
        {
            PG_RETURN_NULL();
        }

        /* get the first element of the array */
        agtv_result = get_ith_agtype_value_from_container(&agt_arg->root, size-1);
    }

    /* if it is AGTV_NULL, return null */
    if (agtv_result->type == AGTV_NULL)
    {
        PG_RETURN_NULL();
    }

    PG_RETURN_POINTER(agtype_value_to_agtype(agtv_result));
}

PG_FUNCTION_INFO_V1(age_tail);
/*
 * Returns a list  containing all the elements, excluding the first one, from a list.
 */
Datum age_tail(PG_FUNCTION_ARGS)
{
    Oid arg_type;
    agtype *agt_arg = NULL;
    agtype *agt_result = NULL;
    agtype_in_state agis_result;
    int count;
    int i;

    /* check number of arguments */
    if (PG_NARGS() < 1 || PG_NARGS() > 1)
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("age_tail() requires only one argument")));
    }

    /* get the data type */
    arg_type = get_fn_expr_argtype(fcinfo->flinfo, 0);

    /* check the data type */
    if (arg_type != AGTYPEOID)
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("age_tail() argument must be of type agtype")));
    }

    /* check for null */
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }

    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for an array */
    if (!AGT_ROOT_IS_ARRAY(agt_arg) || AGT_ROOT_IS_SCALAR(agt_arg))
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("tail() argument must resolve to a list or null")));
    }

    count = AGT_ROOT_COUNT(agt_arg);

    /* if we have an empty list or only one element in the list, return null */
    if (count <= 1)
    {
        PG_RETURN_NULL();
    }

    /* clear the result structure */
    MemSet(&agis_result, 0, sizeof(agtype_in_state));

    /* push the beginning of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_BEGIN_ARRAY, NULL);

    /* iterate through the list beginning with the second item */
    for (i = 1; i < count; i++)
    {
        agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM,
                                            get_ith_agtype_value_from_container(&agt_arg->root, i));
    }

    /* push the end of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_END_ARRAY, NULL);

    agt_result = agtype_value_to_agtype(agis_result.res);
    pfree_agtype_value(agis_result.res);

    PG_RETURN_POINTER(agt_result);
}


PG_FUNCTION_INFO_V1(age_properties);

Datum age_properties(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_object = NULL;
    agtype_value *agtv_result = NULL;

    /* check for null */
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }

    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for a scalar or regular object */

    if (!AGT_ROOT_IS_SCALAR(agt_arg) && !AGT_ROOT_IS_OBJECT(agt_arg))
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("properties() argument must resolve to an object")));
    }

    /*
     * If it isn't an array (wrapped scalar) and is an object, just return it.
     * This is necessary for some cases where an object may be passed in. For
     * example, SET v={blah}.
     */
    if (!AGT_ROOT_IS_ARRAY(agt_arg) && AGT_ROOT_IS_OBJECT(agt_arg))
    {
        PG_RETURN_POINTER(agt_arg);
    }

    /* get the object out of the array */
    agtv_object = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    /* is it an agtype null? */
    if (agtv_object->type == AGTV_NULL)
    {
        PG_RETURN_NULL();
    }

    /* check for proper agtype */
    if (agtv_object->type != AGTV_VERTEX && agtv_object->type != AGTV_EDGE)
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("properties() argument must be a vertex, an edge or null")));
    }

    agtv_result = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_object, "properties");

    Assert(agtv_result != NULL);
    Assert(agtv_result->type = AGTV_OBJECT);

    PG_RETURN_POINTER(agtype_value_to_agtype(agtv_result));
}

PG_FUNCTION_INFO_V1(age_length);

Datum age_length(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_path = NULL;
    agtype_value agtv_result;

    /* check for null */
    if (PG_ARGISNULL(0))
        PG_RETURN_NULL();

    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for a scalar */
    if (!AGT_ROOT_IS_SCALAR(agt_arg))
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("length() argument must resolve to a scalar")));

    /* get the path array */
    agtv_path = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    /* if it is AGTV_NULL, return null */
    if (agtv_path->type == AGTV_NULL)
        PG_RETURN_NULL();

    /* check for a path */
    if (agtv_path ->type != AGTV_PATH)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("length() argument must resolve to a path or null")));

    agtv_result.type = AGTV_INTEGER;
    agtv_result.val.int_value = (agtv_path->val.array.num_elems - 1) /2;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_toboolean);

Datum age_toboolean(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    Oid type;
    agtype_value agtv_result;
    char *string = NULL;
    bool result = false;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs > 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("toBoolean() only supports one argument")));

    /* check for null */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * toBoolean() supports bool, text, cstring, or the agtype bool, and string
     * input.
     */
    arg = args[0];
    type = types[0];

    if (type != AGTYPEOID)
    {
        if (type == BOOLOID)
            result = DatumGetBool(arg);
        else if (type == CSTRINGOID || type == TEXTOID)
        {
            if (type == CSTRINGOID)
                string = DatumGetCString(arg);
            else
                string = text_to_cstring(DatumGetTextPP(arg));

            if (pg_strcasecmp(string, "true") == 0)
                result = true;
            else if (pg_strcasecmp(string, "false") == 0)
                result = false;
            else
                PG_RETURN_NULL();
        }
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toBoolean() unsupported argument type %d",
                                   type)));
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toBoolean() only supports scalar arguments")));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        if (agtv_value->type == AGTV_BOOL)
            result = agtv_value->val.boolean;
        else if (agtv_value->type == AGTV_STRING)
        {
            int len = agtv_value->val.string.len;

            string = agtv_value->val.string.val;

            if (len == 4 && pg_strncasecmp(string, "true", len) == 0)
                result = true;
            else if (len == 5 && pg_strncasecmp(string, "false", len) == 0)
                result = false;
            else
                PG_RETURN_NULL();
        }
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toBoolean() unsupported argument agtype %d",
                                   agtv_value->type)));
    }

    /* build the result */
    agtv_result.type = AGTV_BOOL;
    agtv_result.val.boolean = result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_tobooleanlist);
/*
 * Converts a list of values and returns a list of boolean values. 
 * If any values are not convertible to boolean they will be null in the list returned.
 */
Datum age_tobooleanlist(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_in_state agis_result;
    agtype_value *elem;
    agtype_value bool_elem;
    char *string = NULL;
    int count;
    int i;

    /* check for null */
    if (PG_ARGISNULL(0))
        PG_RETURN_NULL();

    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for an array */
    if (!AGT_ROOT_IS_ARRAY(agt_arg) || AGT_ROOT_IS_SCALAR(agt_arg))
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("toBooleanList() argument must resolve to a list or null")));

    count = AGT_ROOT_COUNT(agt_arg);

    /* if we have an empty list or only one element in the list, return null */
    if (count == 0)
        PG_RETURN_NULL();
    
    /* clear the result structure */
    MemSet(&agis_result, 0, sizeof(agtype_in_state));

    /* push the beginning of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_BEGIN_ARRAY, NULL);

    /* iterate through the list */
    for (i = 0; i < count; i++)
    {
        // TODO: check element's type, it's value, and convert it to boolean if possible.
        elem = get_ith_agtype_value_from_container(&agt_arg->root, i);
        bool_elem.type = AGTV_BOOL;

        switch (elem->type)
        {
        case AGTV_STRING:
            
            string = elem->val.string.val;

            if (pg_strcasecmp(string, "true") == 0)
            {
                bool_elem.val.boolean = true;
                agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &bool_elem);
            }
            else if (pg_strcasecmp(string, "false") == 0)
            {
                bool_elem.val.boolean = false;
                agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &bool_elem);
            }
            else
            {
                bool_elem.type = AGTV_NULL;
                agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &bool_elem);
            }
            
            break;
        
        case AGTV_BOOL:
            
            bool_elem.val.boolean = elem->val.boolean;
            agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &bool_elem);

            break;
        
        default:
            
            bool_elem.type = AGTV_NULL;
            agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &bool_elem);
            
            break;
        }
    }

    /* push the end of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_END_ARRAY, NULL);

    PG_RETURN_POINTER(agtype_value_to_agtype(agis_result.res));
}

PG_FUNCTION_INFO_V1(age_tofloat);

Datum age_tofloat(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    char *string = NULL;
    bool is_valid = false;
    Oid type;
    float8 result;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs > 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("toFloat() only supports one argument")));

    /* check for null */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * toFloat() supports integer, float, numeric, text, cstring, or the
     * agtype integer, float, numeric, and string input
     */
    arg = args[0];
    type = types[0];

    if (type != AGTYPEOID)
    {
        if (type == INT2OID)
            result = (float8) DatumGetInt16(arg);
        else if (type == INT4OID)
            result = (float8) DatumGetInt32(arg);
        else if (type == INT8OID)
        {
            /*
             * 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.
             */
            string = DatumGetCString(DirectFunctionCall1(int8out, arg));
            /* 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)
                PG_RETURN_NULL();
        }
        else if (type == FLOAT4OID)
            result = (float8) DatumGetFloat4(arg);
        else if (type == FLOAT8OID)
            result = DatumGetFloat8(arg);
        else if (type == NUMERICOID)
            result = DatumGetFloat8(DirectFunctionCall1(
                numeric_float8_no_overflow, arg));
        else if (type == CSTRINGOID || type == TEXTOID)
        {
            if (type == CSTRINGOID)
                string = DatumGetCString(arg);
            else
                string = text_to_cstring(DatumGetTextPP(arg));

            result = float8in_internal_null(string, NULL, "double precision",
                                            string, &is_valid);
            if (!is_valid)
                PG_RETURN_NULL();
        }
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toFloat() unsupported argument type %d",
                                   type)));
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toFloat() only supports scalar arguments")));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        if (agtv_value->type == AGTV_INTEGER)
        {
            /* get the string representation of the integer */
            string = DatumGetCString(DirectFunctionCall1(int8out,
                         Int64GetDatum(agtv_value->val.int_value)));
            /* turn it into a float */
            result = float8in_internal_null(string, NULL, "double precision",
                                            string, &is_valid);
            /* return null if it was an invalid float */
            if (!is_valid)
                PG_RETURN_NULL();
        }
        else if (agtv_value->type == AGTV_FLOAT)
            result = agtv_value->val.float_value;
        else if (agtv_value->type == AGTV_NUMERIC)
            result = DatumGetFloat8(DirectFunctionCall1(
                numeric_float8_no_overflow,
                NumericGetDatum(agtv_value->val.numeric)));
        else if (agtv_value->type == AGTV_STRING)
        {
            string = strndup(agtv_value->val.string.val,
                             agtv_value->val.string.len);
            result = float8in_internal_null(string, NULL, "double precision",
                                            string, &is_valid);
            free(string);
            if (!is_valid)
                PG_RETURN_NULL();
        }
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toFloat() unsupported argument agtype %d",
                                   agtv_value->type)));
    }

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_tofloatlist);
/*
 * toFloatList() converts a list of values and returns a list of floating point values. 
 * If any values are not convertible to floating point they will be null in the list returned.
 */
Datum age_tofloatlist(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_in_state agis_result;
    agtype_value *elem;
    agtype_value float_elem;
    char *string = NULL;
    int count;
    int i;
    bool is_valid = false;
    float float_num;
    char buffer[64];

    /* check for null */
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }
    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for an array */
    if (!AGT_ROOT_IS_ARRAY(agt_arg) || AGT_ROOT_IS_SCALAR(agt_arg))
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("toFloatList() argument must resolve to a list or null")));

    count = AGT_ROOT_COUNT(agt_arg);

    /* if we have an empty list or only one element in the list, return null */
    if (count == 0)
        PG_RETURN_NULL();

    /* clear the result structure */
    MemSet(&agis_result, 0, sizeof(agtype_in_state));

    /* push the beginning of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_BEGIN_ARRAY, NULL);

    /* iterate through the list */
    for (i = 0; i < count; i++)
    {
        // TODO: check element's type, it's value, and convert it to float if possible.
        elem = get_ith_agtype_value_from_container(&agt_arg->root, i);
        float_elem.type = AGTV_FLOAT;

        switch (elem->type)
        {
        case AGTV_STRING:

            string = elem->val.string.val;
            if (atof(string))
            {
                float_elem.type = AGTV_FLOAT;
                float_elem.val.float_value = float8in_internal_null(string, NULL, "double precision",
                                            string, &is_valid); 
                agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &float_elem);
            }
            else 
            {
                float_elem.type = AGTV_NULL;
                agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &float_elem);
            }

            break;

        case AGTV_FLOAT:

            float_elem.type = AGTV_FLOAT;
            float_num = elem->val.float_value;
            sprintf(buffer, "%f", float_num);
            string = buffer;
            float_elem.val.float_value = float8in_internal_null(string, NULL, "double precision", string, &is_valid);
            agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &float_elem);

            break;

        default:

            float_elem.type = AGTV_NULL;
            agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &float_elem);

            break;
        }
    }
    agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_END_ARRAY, NULL);

    PG_RETURN_POINTER(agtype_value_to_agtype(agis_result.res));
}

PG_FUNCTION_INFO_V1(age_tointeger);

Datum age_tointeger(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    char *string = NULL;
    bool is_valid = false;
    Oid type;
    int64 result;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs > 1)
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("toInteger() only supports one argument")));
    }

    /* check for null */
    if (nargs < 0 || nulls[0])
    {
        PG_RETURN_NULL();
    }

    /*
     * toInteger() supports integer, float, numeric, text, cstring, or the
     * agtype integer, float, numeric, and string input
     */
    arg = args[0];
    type = types[0];

    if (type != AGTYPEOID)
    {
        if (type == INT2OID)
        {
            result = (int64) DatumGetInt16(arg);
        }
        else if (type == INT4OID)
        {
            result = (int64) DatumGetInt32(arg);
        }
        else if (type == INT8OID)
        {
            result = (int64) DatumGetInt64(arg);
        }
        else if (type == FLOAT4OID)
        {
            float4 f = DatumGetFloat4(arg);

            if (isnan(f) || isinf(f) ||
                f < (float4)PG_INT64_MIN || f > (float4)PG_INT64_MAX)
            {
                PG_RETURN_NULL();
            }

            result = (int64)f;
        }
        else if (type == FLOAT8OID)
        {
            float8 f = DatumGetFloat8(arg);

            if (isnan(f) || isinf(f) ||
                f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX)
            {
                PG_RETURN_NULL();
            }

            result = (int64)f;
        }
        else if (type == NUMERICOID)
        {
            float8 f;

            f = DatumGetFloat8(DirectFunctionCall1(
                numeric_float8_no_overflow, arg));

            if (isnan(f) || isinf(f) ||
                f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX)
            {
                PG_RETURN_NULL();
            }

            result = (int64)f;
        }
        else if (type == CSTRINGOID || type == TEXTOID)
        {
            if (type == CSTRINGOID)
            {
                string = DatumGetCString(arg);
            }
            else
            {
                string = text_to_cstring(DatumGetTextPP(arg));
            }

            /* convert it if it is a regular integer string */
            is_valid = scanint8(string, true, &result);

            /*
             * If it isn't an integer string, try converting it as a float
             * string.
             */
            if (!is_valid)
            {
                float8 f;

                f = float8in_internal_null(string, NULL, "double precision",
                                           string, &is_valid);
                /*
                 * If the conversions failed or it's a special float value,
                 * return null.
                 */
                if (!is_valid || isnan(f) || isinf(f) ||
                    f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX)
                {
                    PG_RETURN_NULL();
                }

                result = (int64)f;
            }
        }
        else
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toInteger() unsupported argument type %d",
                                   type)));
        }
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toInteger() only supports scalar arguments")));
        }

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        if (agtv_value->type == AGTV_INTEGER)
        {
            result = agtv_value->val.int_value;
        }
        else if (agtv_value->type == AGTV_FLOAT)
        {
            float8 f = agtv_value->val.float_value;

            if (isnan(f) || isinf(f) ||
                f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX)
            {
                PG_RETURN_NULL();
            }

            result = (int64)f;
        }
        else if (agtv_value->type == AGTV_NUMERIC)
        {
            float8 f;
            Datum num = NumericGetDatum(agtv_value->val.numeric);

            f = DatumGetFloat8(DirectFunctionCall1(
                numeric_float8_no_overflow, num));

            if (isnan(f) || isinf(f) ||
                f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX)
            {
                PG_RETURN_NULL();
            }

            result = (int64)f;
        }
        else if (agtv_value->type == AGTV_STRING)
        {
            /* we need a null terminated cstring */
            string = strndup(agtv_value->val.string.val,
                             agtv_value->val.string.len);
            /* convert it if it is a regular integer string */
            is_valid = scanint8(string, true, &result);
            /*
             * If it isn't an integer string, try converting it as a float
             * string.
             */
            if (!is_valid)
            {
                float8 f;

                f = float8in_internal_null(string, NULL, "double precision",
                                           string, &is_valid);
                free(string);
                /*
                 * If the conversions failed or it's a special float value,
                 * return null.
                 */
                if (!is_valid || isnan(f) || isinf(f) ||
                    f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX)
                {
                    PG_RETURN_NULL();
                }

                result = (int64)f;
            }
            else
            {
                free(string);
            }
        }
        else
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toInteger() unsupported argument agtype %d",
                                   agtv_value->type)));
        }
    }

    /* build the result */
    agtv_result.type = AGTV_INTEGER;
    agtv_result.val.int_value = result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_tointegerlist);
/*
 * toIntegerList() converts a list of values and returns a list of integers point values. 
 * If any values are not convertible to integer they will be null in the list returned.
 */
Datum age_tointegerlist(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_in_state agis_result;
    agtype_value *elem;
    agtype_value integer_elem;
    int count;
    int i;
    char *string = NULL;
    int integer_num;
    float float_num;
    int is_float;

    /* check for null */
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }
    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for an array */
    if (!AGT_ROOT_IS_ARRAY(agt_arg) || AGT_ROOT_IS_SCALAR(agt_arg))
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("toIntegerList() argument must resolve to a list or null")));

    count = AGT_ROOT_COUNT(agt_arg);

    /* if we have an empty list or only one element in the list, return null */
    if (count == 0)
        PG_RETURN_NULL();

    /* clear the result structure */
    MemSet(&agis_result, 0, sizeof(agtype_in_state));

    /* push the beginning of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_BEGIN_ARRAY, NULL);

    /* iterate through the list */
    for (i = 0; i < count; i++)
    {
        // TODO: check element's type, it's value, and convert it to integer if possible.
        elem = get_ith_agtype_value_from_container(&agt_arg->root, i);
        integer_elem.type = AGTV_INTEGER;

        switch (elem->type)
        {
        case AGTV_STRING:

            string = elem->val.string.val;
            integer_elem.type = AGTV_INTEGER;
            integer_elem.val.int_value = atoi(string);
            
            if (*string == '+' || *string == '-' || (*string >= '0' && *string <= '9'))
            {
                is_float = 1;
                while (*(++string))
                {

                    if(!(*string >= '0' && *string <= '9'))
                    {
                        if(*string == '.' && is_float)
                        {
                            is_float--;
                        }
                        else
                        {
                            integer_elem.type = AGTV_NULL;
                            break;
                        }
                    }
                }   
            }
            else
            {

                integer_elem.type = AGTV_NULL;
            }

            agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &integer_elem);
           
            break;

        case AGTV_FLOAT:

            integer_elem.type = AGTV_INTEGER;
            float_num = elem->val.float_value;
            integer_elem.val.int_value = (int)float_num;
            agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &integer_elem);

            break;

        case AGTV_INTEGER:

            integer_elem.type = AGTV_INTEGER;
            integer_num = elem->val.int_value;
            integer_elem.val.int_value = integer_num;
            agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &integer_elem);

            break;

        default:

            integer_elem.type = AGTV_NULL;
            agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &integer_elem);

            break;
        }
    }
    agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_END_ARRAY, NULL);

    PG_RETURN_POINTER(agtype_value_to_agtype(agis_result.res));
}

PG_FUNCTION_INFO_V1(age_size);

Datum age_size(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    char *string = NULL;
    Oid type;
    int64 result;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs > 1)
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("size() only supports one argument")));
    }

    /* check for null */
    if (nargs < 0 || nulls[0])
    {
        PG_RETURN_NULL();
    }

    /*
     * size() supports cstring, text, or the agtype string or list input
     */
    arg = args[0];
    type = types[0];

    if (type == CSTRINGOID)
    {
        string = DatumGetCString(arg);
        result = strlen(string);
    }
    else if (type == TEXTOID)
    {
        string = text_to_cstring(DatumGetTextPP(arg));
        result = strlen(string);
    }
    else if (type == AGTYPEOID)
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (AGT_ROOT_IS_SCALAR(agt_arg))
        {
            agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

            if (agtv_value->type == AGTV_STRING)
            {
                result = agtv_value->val.string.len;
            }
            else
            {
                ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                        errmsg("size() unsupported argument")));
            }
        }
        else if (AGT_ROOT_IS_VPC(agt_arg))
        {
            agtv_value = agtv_materialize_vle_edges(agt_arg);
            result = agtv_value->val.array.num_elems;
        }
        else if (AGT_ROOT_IS_ARRAY(agt_arg))
        {
            result = AGT_ROOT_COUNT(agt_arg);
        }
        else
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("size() unsupported argument")));
        }
    }
    else
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("size() unsupported argument")));
    }

    /* build the result */
    agtv_result.type = AGTV_INTEGER;
    agtv_result.val.int_value = result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(graphid_to_agtype);

Datum graphid_to_agtype(PG_FUNCTION_ARGS)
{
    PG_RETURN_POINTER(integer_to_agtype(AG_GETARG_GRAPHID(0)));
}

PG_FUNCTION_INFO_V1(agtype_to_graphid);

Datum agtype_to_graphid(PG_FUNCTION_ARGS)
{
    agtype *agtype_in = AG_GET_ARG_AGTYPE_P(0);
    agtype_value agtv;

    if (!agtype_extract_scalar(&agtype_in->root, &agtv) ||
        agtv.type != AGTV_INTEGER)
        cannot_cast_agtype_value(agtv.type, "graphid");

    PG_FREE_IF_COPY(agtype_in, 0);

    PG_RETURN_INT16(agtv.val.int_value);
}

PG_FUNCTION_INFO_V1(age_type);

Datum age_type(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_object = NULL;
    agtype_value *agtv_result = NULL;

    /* check for null */
    if (PG_ARGISNULL(0))
        PG_RETURN_NULL();

    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for a scalar object */
    if (!AGT_ROOT_IS_SCALAR(agt_arg))
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("type() argument must resolve to a scalar value")));

    /* get the object out of the array */
    agtv_object = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    /* is it an agtype null? */
    if (agtv_object->type == AGTV_NULL)
            PG_RETURN_NULL();

    /* check for proper agtype */
    if (agtv_object->type != AGTV_EDGE)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("type() argument must be an edge or null")));

    agtv_result = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_object, "label");

    Assert(agtv_result != NULL);
    Assert(agtv_result->type = AGTV_STRING);

    PG_RETURN_POINTER(agtype_value_to_agtype(agtv_result));
}

PG_FUNCTION_INFO_V1(age_exists);
/*
 * Executor function for EXISTS(property).
 *
 * Note: For most executor functions we want to return SQL NULL for NULL input.
 *       However, in this case, NULL means false - it was not found.
 */
Datum age_exists(PG_FUNCTION_ARGS)
{
    /* check for NULL, NULL is FALSE */
    if (PG_ARGISNULL(0))
        PG_RETURN_BOOL(false);

    /* otherwise, we have something, and something is TRUE */
    PG_RETURN_BOOL(true);
}

PG_FUNCTION_INFO_V1(age_isempty);
/*
 * Executor function for isEmpty(property).
 */

Datum age_isempty(PG_FUNCTION_ARGS)
{
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    char *string = NULL;
    Oid type;
    int64 result;

    /* extract argument values */
    extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /*
     * isEmpty() supports cstring, text, or the agtype string or list input
     */
    arg = args[0];
    type = types[0];

    if (type == CSTRINGOID)
    {
        string = DatumGetCString(arg);
        result = strlen(string);
    }
    else if (type == TEXTOID)
    {
        string = text_to_cstring(DatumGetTextPP(arg));
        result = strlen(string);
    }
    else if (type == AGTYPEOID)
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (AGT_ROOT_IS_SCALAR(agt_arg))
        {
            agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

            if (agtv_value->type == AGTV_STRING)
            {
                result = agtv_value->val.string.len;
            }
            else
            {
                ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                        errmsg("isEmpty() unsupported argument, expected a List, Map, or String")));
            }
        }
        else if (AGT_ROOT_IS_VPC(agt_arg))
        {
            agtv_value = agtv_materialize_vle_edges(agt_arg);
            result = agtv_value->val.array.num_elems;
        }
        else if (AGT_ROOT_IS_ARRAY(agt_arg))
        {
            result = AGT_ROOT_COUNT(agt_arg);
        }
        else if (AGT_ROOT_IS_OBJECT(agt_arg))
        {
            result = AGT_ROOT_COUNT(agt_arg);
        }
        else
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("isEmpty() unsupported argument, expected a List, Map, or String")));
        }
    }
    else
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("isEmpty() unsupported argument, expected a List, Map, or String")));
    }

    /* build the result */
    PG_RETURN_BOOL(result == 0);
}

PG_FUNCTION_INFO_V1(age_label);
/*
 * Executor function for label(edge/vertex).
 */
Datum age_label(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_value = NULL;
    agtype_value *label = NULL;

    /* check for NULL, NULL is FALSE */
    if (PG_ARGISNULL(0))
        PG_RETURN_NULL();

    /* get the argument */
    agt_arg = AG_GET_ARG_AGTYPE_P(0);

    // edges and vertices are considered scalars
    if (!AGT_ROOT_IS_SCALAR(agt_arg))
    {
        if (AGTE_IS_NULL(agt_arg->root.children[0]))
            PG_RETURN_NULL();

        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("label() argument must resolve to an edge or vertex")));

    }

    agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    // fail if agtype value isn't an edge or vertex
    if (agtv_value->type != AGTV_VERTEX && agtv_value->type != AGTV_EDGE)
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("label() argument must resolve to an edge or vertex")));

    }

    // extract the label agtype value from the vertex or edge
    label = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_value, "label");

    PG_RETURN_POINTER(agtype_value_to_agtype(label));
}

PG_FUNCTION_INFO_V1(age_tostring);

Datum age_tostring(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum arg;
    Oid type = InvalidOid;
    agtype *agt = NULL;
    agtype_value *agtv = NULL;

    nargs = PG_NARGS();

    /* check number of args */
    if (nargs > 1)
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("toString() only supports one argument")));
    }

    /* check for null */
    if (nargs < 1 || PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }

    /* get the argument and type */
    arg = PG_GETARG_DATUM(0);
    type = get_fn_expr_argtype(fcinfo->flinfo, 0);

    /* verify that if the type is UNKNOWNOID it can be converted */
    if (type == UNKNOWNOID && !get_fn_expr_arg_stable(fcinfo->flinfo, 0))
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("toString() UNKNOWNOID and not stable")));
    }

    /*
     * toString() supports integer, float, numeric, text, cstring, boolean,
     * regtype or the agtypes: integer, float, numeric, string, boolean input
     */
    agtv = tostring_helper(arg, type, "toString()");

    /* if we get a NULL back we need to return NULL */
    if (agtv == NULL)
    {
        PG_RETURN_NULL();
    }

    /* convert to agtype and free the agtype_value */
    agt = agtype_value_to_agtype(agtv);
    pfree(agtv);

    PG_RETURN_POINTER(agt);
}

/*
 * Helper function to take any valid type and convert it to an agtype string.
 * Returns NULL for NULL output.
 */
static agtype_value *tostring_helper(Datum arg, Oid type, char *msghdr)
{
    agtype_value *agtv_result = NULL;
    char *string = NULL;

    agtv_result = palloc0(sizeof(agtype_value));

    /*
     * toString() supports: unknown, integer, float, numeric, text, cstring,
     * boolean, regtype or the agtypes: integer, float, numeric, string, and
     * boolean input.
     */

    /*
     * If the type is UNKNOWNOID convert it to a cstring. Prior to passing an
     * UNKNOWNOID it should be verified to be stable.
     */
    if (type == UNKNOWNOID)
    {
        char *str = DatumGetPointer(arg);

        string = pnstrdup(str, strlen(str));
    }
    /* if it is not an AGTYPEOID */
    else if (type != AGTYPEOID)
    {
        if (type == INT2OID)
        {
            string = DatumGetCString(DirectFunctionCall1(int8out,
                Int64GetDatum((int64) DatumGetInt16(arg))));
        }
        else if (type == INT4OID)
        {
            string = DatumGetCString(DirectFunctionCall1(int8out,
                Int64GetDatum((int64) DatumGetInt32(arg))));
        }
        else if (type == INT8OID)
        {
            string = DatumGetCString(DirectFunctionCall1(int8out, arg));
        }
        else if (type == FLOAT4OID)
        {
            string = DatumGetCString(DirectFunctionCall1(float8out, arg));
        }
        else if (type == FLOAT8OID)
        {
            string = DatumGetCString(DirectFunctionCall1(float8out, arg));
        }
        else if (type == NUMERICOID)
        {
            string = DatumGetCString(DirectFunctionCall1(numeric_out, arg));
        }
        else if (type == CSTRINGOID)
        {
            string = DatumGetCString(arg);
        }
        else if (type == TEXTOID)
        {
            string = text_to_cstring(DatumGetTextPP(arg));
        }
        else if (type == BOOLOID)
        {
            string = DatumGetBool(arg) ? "true" : "false";
        }
        else if (type == REGTYPEOID)
        {
            string = DatumGetCString(DirectFunctionCall1(regtypeout, arg));
        }
        else
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("%s unsupported argument type %d",
                                   msghdr, type)));
        }
    }
    /* if it is an AGTYPEOID */
    else if (type == AGTYPEOID)
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("%s only supports scalar arguments",
                                   msghdr)));
        }

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        if (agtv_value->type == AGTV_NULL)
        {
            return NULL;
        }
        else if (agtv_value->type == AGTV_INTEGER)
        {
            string = DatumGetCString(DirectFunctionCall1(int8out,
                Int64GetDatum(agtv_value->val.int_value)));
        }
        else if (agtv_value->type == AGTV_FLOAT)
        {
            string = DatumGetCString(DirectFunctionCall1(float8out,
                Float8GetDatum(agtv_value->val.float_value)));
        }
        else if (agtv_value->type == AGTV_STRING)
        {
            string = pnstrdup(agtv_value->val.string.val,
                              agtv_value->val.string.len);
        }
        else if (agtv_value->type == AGTV_NUMERIC)
        {
            string = DatumGetCString(DirectFunctionCall1(numeric_out,
                PointerGetDatum(agtv_value->val.numeric)));
        }
        else if (agtv_value->type == AGTV_BOOL)
        {
            string = (agtv_value->val.boolean) ? "true" : "false";
        }
        else
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("%s unsupported argument agtype %d",
                                   msghdr, agtv_value->type)));
        }
    }
    /* it is an unknown type */
    else
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("%s unknown argument agtype %d",
                                   msghdr, type)));
    }

    /* build the result */
    agtv_result->type = AGTV_STRING;
    agtv_result->val.string.val = string;
    agtv_result->val.string.len = strlen(string);

    return agtv_result;
}

PG_FUNCTION_INFO_V1(age_tostringlist);
/*
 * toStringList() converts a list of values and returns a list of String values. 
 * If any values are not convertible to string point they will be null in the list returned.
 */
Datum age_tostringlist(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_in_state agis_result;
    agtype_value *elem;
    agtype_value string_elem;
    int count;
    int i;
    char buffer[64];

    /* check for null */
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }
    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for an array */
    if (!AGT_ROOT_IS_ARRAY(agt_arg) || AGT_ROOT_IS_SCALAR(agt_arg))
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("toStringList() argument must resolve to a list or null")));

    count = AGT_ROOT_COUNT(agt_arg);

    /* if we have an empty list or only one element in the list, return null */
    if (count == 0)
        PG_RETURN_NULL();

    /* clear the result structure */
    MemSet(&agis_result, 0, sizeof(agtype_in_state));

    /* push the beginning of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_BEGIN_ARRAY, NULL);

    /* iterate through the list */
    for (i = 0; i < count; i++)
    {
        // TODO: check element's type, it's value, and convert it to string if possible.
        elem = get_ith_agtype_value_from_container(&agt_arg->root, i);
        string_elem.type = AGTV_STRING;

        switch (elem->type)
        {
        case AGTV_STRING:

            if(!elem)
            {
                string_elem.type = AGTV_NULL;

                agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &string_elem);
            }

            string_elem.val.string.val = elem->val.string.val;
            string_elem.val.string.len = elem->val.string.len;

            agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &string_elem);

            break;

        case AGTV_FLOAT:

            sprintf(buffer, "%.*g", DBL_DIG, elem->val.float_value);
            string_elem.val.string.val = pstrdup(buffer);
            string_elem.val.string.len = strlen(buffer);

            agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &string_elem);

            break; 

        case AGTV_INTEGER:

            sprintf(buffer, "%ld", elem->val.int_value);
            string_elem.val.string.val = pstrdup(buffer);
            string_elem.val.string.len = strlen(buffer);

            agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &string_elem);

            break;

        default:

            string_elem.type = AGTV_NULL;
            agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &string_elem);

            break;
        }
    }
    agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_END_ARRAY, NULL);

    PG_RETURN_POINTER(agtype_value_to_agtype(agis_result.res));
}

agtype_iterator *get_next_list_element(agtype_iterator *it,
                           agtype_container *agtc, agtype_value *elem)
{
    agtype_iterator_token itok;
    agtype_value tmp;

    /* verify input params */
    Assert(agtc != NULL);
    Assert(elem != NULL);

    /* check to see if the container is empty */
    if (AGTYPE_CONTAINER_SIZE(agtc) == 0)
    {
       return NULL;
    }

    /* if the passed iterator is NULL, this is the first time, create it */
    if (it == NULL)
    {
        /* initial the iterator */
        it = agtype_iterator_init(agtc);
        /* get the first token */
        itok = agtype_iterator_next(&it, &tmp, true);
        /* it should be WAGT_BEGIN_ARRAY */
        Assert(itok == WAGT_BEGIN_ARRAY);
    }

    /* the next token should be an element or the end of the array */
    itok = agtype_iterator_next(&it, &tmp, true);
    Assert(itok == WAGT_ELEM || WAGT_END_ARRAY);

    /* if this is the end of the array return NULL */
    if (itok == WAGT_END_ARRAY)
    {
        return NULL;
    }

    /* this should be the element, copy it */
    if (itok == WAGT_ELEM)
    {
        *elem = tmp;
    }

    return it;
}

PG_FUNCTION_INFO_V1(age_reverse);

Datum age_reverse(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    text *text_string = NULL;
    char *string = NULL;
    int string_len;
    Oid type;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs > 1)
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("reverse() only supports one argument")));
    }

    /* check for null */
    if (nargs < 0 || nulls[0])
    {
        PG_RETURN_NULL();
    }

    /* reverse() supports text, cstring, or the agtype string input */
    arg = args[0];
    type = types[0];

    if (type != AGTYPEOID)
    {
        if (type == CSTRINGOID)
        {
            text_string = cstring_to_text(DatumGetCString(arg));
        }
        else if (type == TEXTOID)
        {
            text_string = DatumGetTextPP(arg);
        }
        else
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("reverse() unsupported argument type %d",
                                   type)));
        }
    }
    else
    {
        agtype *agt_arg = NULL;
        agtype_value *agtv_value = NULL;
        agtype_in_state result;
        agtype_parse_state *parse_state = NULL;
        agtype_value elem = {0};
        agtype_iterator *it = NULL;
        agtype_value tmp;
        agtype_value *elems = NULL;
        int num_elems;
        int i;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (AGT_ROOT_IS_SCALAR(agt_arg))
        {
            agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

            /* check for agtype null */
            if (agtv_value->type == AGTV_NULL)
            {
                PG_RETURN_NULL();
            }
            if (agtv_value->type == AGTV_STRING)
            {
                text_string = cstring_to_text_with_len(agtv_value->val.string.val,
                                                    agtv_value->val.string.len);
            }
            else
            {
                ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                errmsg("reverse() unsupported argument agtype %d",
                                    agtv_value->type)));
            }
        }
        else if (AGT_ROOT_IS_ARRAY(agt_arg))
        {
            agtv_value = push_agtype_value(&parse_state, WAGT_BEGIN_ARRAY, NULL);

            while ((it = get_next_list_element(it, &agt_arg->root, &elem)))
            {
                agtv_value = push_agtype_value(&parse_state, WAGT_ELEM, &elem);
            }

            /* now reverse the list */
            elems = parse_state->cont_val.val.array.elems;
            num_elems = parse_state->cont_val.val.array.num_elems;

            for(i = 0; i < num_elems/2; i++)
            {
                tmp = elems[i];
                elems[i] = elems[num_elems - 1 - i];
                elems[num_elems - 1 - i] = tmp;
            }
            /* reverse done*/

            elems = NULL;

            agtv_value = push_agtype_value(&parse_state, WAGT_END_ARRAY, NULL);

            Assert(agtv_value != NULL);
            Assert(agtv_value->type = AGTV_ARRAY);

            PG_RETURN_POINTER(agtype_value_to_agtype(agtv_value));

        }
        else if (AGT_ROOT_IS_VPC(agt_arg))
        {
            elems = agtv_materialize_vle_edges(agt_arg);
            num_elems = elems->val.array.num_elems;

            /* build our result array */
            memset(&result, 0, sizeof(agtype_in_state));

            result.res = push_agtype_value(&result.parse_state,
                                            WAGT_BEGIN_ARRAY, NULL);

            for (i = num_elems-1; i >= 0; i--)
            {
                result.res = push_agtype_value(&result.parse_state, WAGT_ELEM,
                                               &elems->val.array.elems[i]);
            }

            result.res = push_agtype_value(&result.parse_state, WAGT_END_ARRAY, NULL);

            PG_RETURN_POINTER(agtype_value_to_agtype(result.res));
        }
        else
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("reverse() unsupported argument agtype")));
        }
    }

    /*
     * We need the string as a text string so that we can let PG deal with
     * multibyte characters in reversing the string.
     */
    text_string = DatumGetTextPP(DirectFunctionCall1(text_reverse,
                                                     PointerGetDatum(text_string)));

    /* convert it back to a cstring */
    string = text_to_cstring(text_string);
    string_len = strlen(string);

    /* if we have an empty string, return null */
    if (string_len == 0)
    {
        PG_RETURN_NULL();
    }

    /* build the result */
    agtv_result.type = AGTV_STRING;
    agtv_result.val.string.val = string;
    agtv_result.val.string.len = string_len;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_toupper);

Datum age_toupper(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    char *string = NULL;
    char *result = NULL;
    int string_len;
    Oid type;
    int i;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs > 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("toUpper() only supports one argument")));

    /* check for null */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /* toUpper() supports text, cstring, or the agtype string input */
    arg = args[0];
    type = types[0];
    if (type != AGTYPEOID)
    {
        if (type == CSTRINGOID)
            string = DatumGetCString(arg);
        else if (type == TEXTOID)
            string = text_to_cstring(DatumGetTextPP(arg));
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toUpper() unsupported argument type %d",
                                   type)));
        string_len = strlen(string);
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toUpper() only supports scalar arguments")));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* check for agtype null */
        if (agtv_value->type == AGTV_NULL)
            PG_RETURN_NULL();
        if (agtv_value->type == AGTV_STRING)
        {
            string = agtv_value->val.string.val;
            string_len = agtv_value->val.string.len;
        }
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toUpper() unsupported argument agtype %d",
                                   agtv_value->type)));
    }

    /* if we have an empty string, return null */
    if (string_len == 0)
        PG_RETURN_NULL();

    /* allocate the new string */
    result = palloc0(string_len);

    /* upcase the string */
    for (i = 0; i < string_len; i++)
        result[i] = pg_toupper(string[i]);

    /* build the result */
    agtv_result.type = AGTV_STRING;
    agtv_result.val.string.val = result;
    agtv_result.val.string.len = string_len;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_tolower);

Datum age_tolower(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    char *string = NULL;
    char *result = NULL;
    int string_len;
    Oid type;
    int i;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs > 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("toLower() only supports one argument")));

    /* check for null */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /* toLower() supports text, cstring, or the agtype string input */
    arg = args[0];
    type = types[0];
    if (type != AGTYPEOID)
    {
        if (type == CSTRINGOID)
            string = DatumGetCString(arg);
        else if (type == TEXTOID)
            string = text_to_cstring(DatumGetTextPP(arg));
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toLower() unsupported argument type %d",
                                   type)));
        string_len = strlen(string);
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toLower() only supports scalar arguments")));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* check for agtype null */
        if (agtv_value->type == AGTV_NULL)
            PG_RETURN_NULL();
        if (agtv_value->type == AGTV_STRING)
        {
            string = agtv_value->val.string.val;
            string_len = agtv_value->val.string.len;
        }
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("toLower() unsupported argument agtype %d",
                                   agtv_value->type)));
    }

    /* if we have an empty string, return null */
    if (string_len == 0)
        PG_RETURN_NULL();

    /* allocate the new string */
    result = palloc0(string_len);

    /* downcase the string */
    for (i = 0; i < string_len; i++)
        result[i] = pg_tolower(string[i]);

    /* build the result */
    agtv_result.type = AGTV_STRING;
    agtv_result.val.string.val = result;
    agtv_result.val.string.len = string_len;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_rtrim);

Datum age_rtrim(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    text *text_string = NULL;
    char *string = NULL;
    int string_len;
    Oid type;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs > 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("rTrim() only supports one argument")));

    /* check for null */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /* rTrim() supports text, cstring, or the agtype string input */
    arg = args[0];
    type = types[0];

    if (type != AGTYPEOID)
    {
        if (type == CSTRINGOID)
            text_string = cstring_to_text(DatumGetCString(arg));
        else if (type == TEXTOID)
            text_string = DatumGetTextPP(arg);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("rTrim() unsupported argument type %d",
                                   type)));
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("rTrim() only supports scalar arguments")));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* check for agtype null */
        if (agtv_value->type == AGTV_NULL)
            PG_RETURN_NULL();
        if (agtv_value->type == AGTV_STRING)
            text_string = cstring_to_text_with_len(agtv_value->val.string.val,
                                                   agtv_value->val.string.len);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("rTrim() unsupported argument agtype %d",
                                   agtv_value->type)));
    }

    /*
     * We need the string as a text string so that we can let PG deal with
     * multibyte characters in trimming the string.
     */
    text_string = DatumGetTextPP(DirectFunctionCall1(rtrim1,
                                                     PointerGetDatum(text_string)));

    /* convert it back to a cstring */
    string = text_to_cstring(text_string);
    string_len = strlen(string);

    /* if we have an empty string, return null */
    if (string_len == 0)
        PG_RETURN_NULL();

    /* build the result */
    agtv_result.type = AGTV_STRING;
    agtv_result.val.string.val = string;
    agtv_result.val.string.len = string_len;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_ltrim);

Datum age_ltrim(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    text *text_string = NULL;
    char *string = NULL;
    int string_len;
    Oid type;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs > 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("lTrim() only supports one argument")));

    /* check for null */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /* rTrim() supports text, cstring, or the agtype string input */
    arg = args[0];
    type = types[0];

    if (type != AGTYPEOID)
    {
        if (type == CSTRINGOID)
            text_string = cstring_to_text(DatumGetCString(arg));
        else if (type == TEXTOID)
            text_string = DatumGetTextPP(arg);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("lTrim() unsupported argument type %d",
                                   type)));
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("lTrim() only supports scalar arguments")));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* check for agtype null */
        if (agtv_value->type == AGTV_NULL)
            PG_RETURN_NULL();
        if (agtv_value->type == AGTV_STRING)
            text_string = cstring_to_text_with_len(agtv_value->val.string.val,
                                                   agtv_value->val.string.len);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("lTrim() unsupported argument agtype %d",
                                   agtv_value->type)));
    }

    /*
     * We need the string as a text string so that we can let PG deal with
     * multibyte characters in trimming the string.
     */
    text_string = DatumGetTextPP(DirectFunctionCall1(ltrim1,
                                                     PointerGetDatum(text_string)));

    /* convert it back to a cstring */
    string = text_to_cstring(text_string);
    string_len = strlen(string);

    /* if we have an empty string, return null */
    if (string_len == 0)
        PG_RETURN_NULL();

    /* build the result */
    agtv_result.type = AGTV_STRING;
    agtv_result.val.string.val = string;
    agtv_result.val.string.len = string_len;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_trim);

Datum age_trim(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    text *text_string = NULL;
    char *string = NULL;
    int string_len;
    Oid type;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs > 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("trim() only supports one argument")));

    /* check for null */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /* trim() supports text, cstring, or the agtype string input */
    arg = args[0];
    type = types[0];

    if (type != AGTYPEOID)
    {
        if (type == CSTRINGOID)
            text_string = cstring_to_text(DatumGetCString(arg));
        else if (type == TEXTOID)
            text_string = DatumGetTextPP(arg);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("trim() unsupported argument type %d",
                                   type)));
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("trim() only supports scalar arguments")));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* check for agtype null */
        if (agtv_value->type == AGTV_NULL)
            PG_RETURN_NULL();
        if (agtv_value->type == AGTV_STRING)
            text_string = cstring_to_text_with_len(agtv_value->val.string.val,
                                                   agtv_value->val.string.len);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("trim() unsupported argument agtype %d",
                                   agtv_value->type)));
    }

    /*
     * We need the string as a text string so that we can let PG deal with
     * multibyte characters in trimming the string.
     */
    text_string = DatumGetTextPP(DirectFunctionCall1(btrim1,
                                                     PointerGetDatum(text_string)));

    /* convert it back to a cstring */
    string = text_to_cstring(text_string);
    string_len = strlen(string);

    /* if we have an empty string, return null */
    if (string_len == 0)
        PG_RETURN_NULL();

    /* build the result */
    agtv_result.type = AGTV_STRING;
    agtv_result.val.string.val = string;
    agtv_result.val.string.len = string_len;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_right);

Datum age_right(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    text *text_string = NULL;
    char *string = NULL;
    int string_len;
    Oid type;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 2)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("right() invalid number of arguments")));

    /* check for a null string */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /* check for a null length */
    if (nulls[1])
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("right() length parameter cannot be null")));

    /* right() supports text, cstring, or the agtype string input */
    arg = args[0];
    type = types[0];

    if (type != AGTYPEOID)
    {
        if (type == CSTRINGOID)
            text_string = cstring_to_text(DatumGetCString(arg));
        else if (type == TEXTOID)
            text_string = DatumGetTextPP(arg);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("right() unsupported argument type %d",
                                   type)));
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("right() only supports scalar arguments")));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* check for agtype null */
        if (agtv_value->type == AGTV_NULL)
            PG_RETURN_NULL();
        if (agtv_value->type == AGTV_STRING)
            text_string = cstring_to_text_with_len(agtv_value->val.string.val,
                                                   agtv_value->val.string.len);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("right() unsupported argument agtype %d",
                                   agtv_value->type)));
    }

    /* right() only supports integer and agtype integer for the second parameter. */
    arg = args[1];
    type = types[1];

    if (type != AGTYPEOID)
    {
        if (type == INT2OID)
            string_len = (int64) DatumGetInt16(arg);
        else if (type == INT4OID)
            string_len = (int64) DatumGetInt32(arg);
        else if (type == INT8OID)
            string_len = (int64) DatumGetInt64(arg);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("right() unsupported argument type %d", type)));
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("right() only supports scalar arguments")));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* no need to check for agtype null because it is an error if found */
        if (agtv_value->type != AGTV_INTEGER)
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("right() unsupported argument agtype %d",
                                   agtv_value->type)));

        string_len = agtv_value->val.int_value;
    }

    /* negative values are not supported in the opencypher spec */
    if (string_len < 0)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("right() negative values are not supported for length")));

    /*
     * We need the string as a text string so that we can let PG deal with
     * multibyte characters in the string.
     */
    text_string = DatumGetTextPP(DirectFunctionCall2(text_right,
                                                     PointerGetDatum(text_string),
                                                     Int64GetDatum(string_len)));

    /* convert it back to a cstring */
    string = text_to_cstring(text_string);
    string_len = strlen(string);

    /* if we have an empty string, return null */
    if (string_len == 0)
        PG_RETURN_NULL();

    /* build the result */
    agtv_result.type = AGTV_STRING;
    agtv_result.val.string.val = string;
    agtv_result.val.string.len = string_len;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_left);

Datum age_left(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    text *text_string = NULL;
    char *string = NULL;
    int string_len;
    Oid type;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 2)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("left() invalid number of arguments")));

    /* check for a null string */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /* check for a null length */
    if (nulls[1])
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("left() length parameter cannot be null")));

    /* left() supports text, cstring, or the agtype string input */
    arg = args[0];
    type = types[0];

    if (type != AGTYPEOID)
    {
        if (type == CSTRINGOID)
            text_string = cstring_to_text(DatumGetCString(arg));
        else if (type == TEXTOID)
            text_string = DatumGetTextPP(arg);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("left() unsupported argument type %d",
                                   type)));
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("left() only supports scalar arguments")));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* check for agtype null */
        if (agtv_value->type == AGTV_NULL)
            PG_RETURN_NULL();
        if (agtv_value->type == AGTV_STRING)
            text_string = cstring_to_text_with_len(agtv_value->val.string.val,
                                                   agtv_value->val.string.len);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("left() unsupported argument agtype %d",
                                   agtv_value->type)));
    }

    /* left() only supports integer and agtype integer for the second parameter. */
    arg = args[1];
    type = types[1];

    if (type != AGTYPEOID)
    {
        if (type == INT2OID)
            string_len = (int64) DatumGetInt16(arg);
        else if (type == INT4OID)
            string_len = (int64) DatumGetInt32(arg);
        else if (type == INT8OID)
            string_len = (int64) DatumGetInt64(arg);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("left() unsupported argument type %d", type)));
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("left() only supports scalar arguments")));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* no need to check for agtype null because it is an error if found */
        if (agtv_value->type != AGTV_INTEGER)
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("left() unsupported argument agtype %d",
                                   agtv_value->type)));

        string_len = agtv_value->val.int_value;
    }

    /* negative values are not supported in the opencypher spec */
    if (string_len < 0)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("left() negative values are not supported for length")));

    /*
     * We need the string as a text string so that we can let PG deal with
     * multibyte characters in the string.
     */
    text_string = DatumGetTextPP(DirectFunctionCall2(text_left,
                                                     PointerGetDatum(text_string),
                                                     Int64GetDatum(string_len)));

    /* convert it back to a cstring */
    string = text_to_cstring(text_string);
    string_len = strlen(string);

    /* if we have an empty string, return null */
    if (string_len == 0)
        PG_RETURN_NULL();

    /* build the result */
    agtv_result.type = AGTV_STRING;
    agtv_result.val.string.val = string;
    agtv_result.val.string.len = string_len;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_substring);

Datum age_substring(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    text *text_string = NULL;
    char *string = NULL;
    int param;
    int string_start = 0;
    int string_len = 0;
    int i;
    Oid type;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs < 2 || nargs > 3)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("substring() invalid number of arguments")));

    /* check for null */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /* neither offset or length can be null if there is a valid string */
    if ((nargs == 2 && nulls[1]) ||
        (nargs == 3 && nulls[2]))
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("substring() offset or length cannot be null")));

    /* substring() supports text, cstring, or the agtype string input */
    arg = args[0];
    type = types[0];

    if (type != AGTYPEOID)
    {
        if (type == CSTRINGOID)
            text_string = cstring_to_text(DatumGetCString(arg));
        else if (type == TEXTOID)
            text_string = DatumGetTextPP(arg);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("substring() unsupported argument type %d",
                                   type)));
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("substring() only supports scalar arguments")));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* check for agtype null */
        if (agtv_value->type == AGTV_NULL)
            PG_RETURN_NULL();
        if (agtv_value->type == AGTV_STRING)
            text_string = cstring_to_text_with_len(agtv_value->val.string.val,
                                                   agtv_value->val.string.len);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("substring() unsupported argument agtype %d",
                                   agtv_value->type)));
    }

    /*
     * substring() only supports integer and agtype integer for the second and
     * third parameters values.
     */
    for (i = 1; i < nargs; i++)
    {
        arg = args[i];
        type = types[i];

        if (type != AGTYPEOID)
        {
            if (type == INT2OID)
                param = (int64) DatumGetInt16(arg);
            else if (type == INT4OID)
                param = (int64) DatumGetInt32(arg);
            else if (type == INT8OID)
                param = (int64) DatumGetInt64(arg);
            else
                ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                errmsg("substring() unsupported argument type %d",
                                       type)));
        }
        else
        {
            agtype *agt_arg;
            agtype_value *agtv_value;

            /* get the agtype argument */
            agt_arg = DATUM_GET_AGTYPE_P(arg);

            if (!AGT_ROOT_IS_SCALAR(agt_arg))
                ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                errmsg("substring() only supports scalar arguments")));

            agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

            /* no need to check for agtype null because it is an error if found */
            if (agtv_value->type != AGTV_INTEGER)
                ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                errmsg("substring() unsupported argument agtype %d",
                                       agtv_value->type)));

            param = agtv_value->val.int_value;
        }

        if (i == 1)
            string_start = param;
        if (i == 2)
            string_len = param;
    }

    /* negative values are not supported in the opencypher spec */
    if (string_start < 0 || string_len < 0)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("substring() negative values are not supported for offset or length")));

    /* cypher substring is 0 based while PG's is 1 based */
    string_start += 1;

    /*
     * We need the string as a text string so that we can let PG deal with
     * multibyte characters in the string.
     */

    /* if optional length is left out */
    if (nargs == 2)
         text_string = DatumGetTextPP(DirectFunctionCall2(text_substr_no_len,
                                                          PointerGetDatum(text_string),
                                                          Int64GetDatum(string_start)));
    /* if length is given */
    else
        text_string = DatumGetTextPP(DirectFunctionCall3(text_substr,
                                                         PointerGetDatum(text_string),
                                                         Int64GetDatum(string_start),
                                                         Int64GetDatum(string_len)));

    /* convert it back to a cstring */
    string = text_to_cstring(text_string);
    string_len = strlen(string);

    /* if we have an empty string, return null */
    if (string_len == 0)
        PG_RETURN_NULL();

    /* build the result */
    agtv_result.type = AGTV_STRING;
    agtv_result.val.string.val = string;
    agtv_result.val.string.len = string_len;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_split);

Datum age_split(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value *agtv_result;
    text *param = NULL;
    text *text_string = NULL;
    text *text_delimiter = NULL;
    Datum text_array;
    Oid type;
    int i;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 2)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("split() invalid number of arguments")));

    /* check for a null string and delimiter */
    if (nargs < 0 || nulls[0] || nulls[1])
        PG_RETURN_NULL();

    /*
     * split() supports text, cstring, or the agtype string input for the
     * string and delimiter values
     */

    for (i = 0; i < 2; i++)
    {
        arg = args[i];
        type = types[i];

        if (type != AGTYPEOID)
        {
            if (type == CSTRINGOID)
                param = cstring_to_text(DatumGetCString(arg));
            else if (type == TEXTOID)
                param = DatumGetTextPP(arg);
            else
                ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                errmsg("split() unsupported argument type %d",
                                       type)));
        }
        else
        {
            agtype *agt_arg;
            agtype_value *agtv_value;

            /* get the agtype argument */
            agt_arg = DATUM_GET_AGTYPE_P(arg);

            if (!AGT_ROOT_IS_SCALAR(agt_arg))
                ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                errmsg("split() only supports scalar arguments")));

            agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

            /* check for agtype null */
            if (agtv_value->type == AGTV_NULL)
                PG_RETURN_NULL();
            if (agtv_value->type == AGTV_STRING)
                param = cstring_to_text_with_len(agtv_value->val.string.val,
                                                 agtv_value->val.string.len);
            else
                ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                errmsg("split() unsupported argument agtype %d",
                                       agtv_value->type)));
        }
        if (i == 0)
            text_string = param;
        if (i == 1)
            text_delimiter = param;
    }

    /*
     * We need the strings as a text strings so that we can let PG deal with
     * multibyte characters in the string. The result is an ArrayType
     */
    text_array = DirectFunctionCall2Coll(regexp_split_to_array,
                                         DEFAULT_COLLATION_OID,
                                         PointerGetDatum(text_string),
                                         PointerGetDatum(text_delimiter));

    /* now build an agtype array of strings */
    if (PointerIsValid(DatumGetPointer(text_array)))
    {
        ArrayType *array = DatumGetArrayTypeP(text_array);
        agtype_in_state result;
        Datum *elements;
        int nelements;

        /* zero the state and deconstruct the ArrayType to TEXTOID */
        memset(&result, 0, sizeof(agtype_in_state));
        deconstruct_array(array, TEXTOID, -1, false, 'i', &elements, NULL,
                          &nelements);

        /* open the agtype array */
        result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_ARRAY,
                                       NULL);
        /* add the values */
        for (i = 0; i < nelements; i++)
        {
            char *string;
            int string_len;
            char *string_copy;
            agtype_value agtv_string;
            Datum d;

            /* get the string element from the array */
            string = VARDATA(elements[i]);
            string_len = VARSIZE(elements[i]) - VARHDRSZ;

            /* make a copy */
            string_copy = palloc0(string_len);
            memcpy(string_copy, string, string_len);

            /* build the agtype string */
            agtv_string.type = AGTV_STRING;
            agtv_string.val.string.val = string_copy;
            agtv_string.val.string.len = string_len;

            /* get the datum */
            d = PointerGetDatum(agtype_value_to_agtype(&agtv_string));

            /* add the value */
            add_agtype(d, false, &result, AGTYPEOID, false);
        }

        /* close the array */
        result.res = push_agtype_value(&result.parse_state, WAGT_END_ARRAY, NULL);

        agtv_result = result.res;
    }
    else
    {
        elog(ERROR, "split() unexpected error");
    }

    PG_RETURN_POINTER(agtype_value_to_agtype(agtv_result));
}

PG_FUNCTION_INFO_V1(age_replace);

Datum age_replace(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    Datum arg;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    text *param = NULL;
    text *text_string = NULL;
    text *text_search = NULL;
    text *text_replace = NULL;
    text *text_result = NULL;
    char *string = NULL;
    int string_len;
    Oid type;
    int i;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 3)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("replace() invalid number of arguments")));

    /* check for a null string, search, and replace */
    if (nargs < 0 || nulls[0] || nulls[1] || nulls[2])
        PG_RETURN_NULL();

    /*
     * replace() supports text, cstring, or the agtype string input for the
     * string and delimiter values
     */

    for (i = 0; i < 3; i++)
    {
        arg = args[i];
        type = types[i];

        if (type != AGTYPEOID)
        {
            if (type == CSTRINGOID)
                param = cstring_to_text(DatumGetCString(arg));
            else if (type == TEXTOID)
                param = DatumGetTextPP(arg);
            else
                ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                errmsg("replace() unsupported argument type %d",
                                       type)));
        }
        else
        {
            agtype *agt_arg;
            agtype_value *agtv_value;

            /* get the agtype argument */
            agt_arg = DATUM_GET_AGTYPE_P(arg);

            if (!AGT_ROOT_IS_SCALAR(agt_arg))
                ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                errmsg("replace() only supports scalar arguments")));

            agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

            /* check for agtype null */
            if (agtv_value->type == AGTV_NULL)
                PG_RETURN_NULL();
            if (agtv_value->type == AGTV_STRING)
                param = cstring_to_text_with_len(agtv_value->val.string.val,
                                                 agtv_value->val.string.len);
            else
                ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                errmsg("replace() unsupported argument agtype %d",
                                       agtv_value->type)));
        }
        if (i == 0)
            text_string = param;
        if (i == 1)
            text_search = param;
        if (i == 2)
            text_replace = param;
    }

    /*
     * We need the strings as a text strings so that we can let PG deal with
     * multibyte characters in the string.
     */
    text_result = DatumGetTextPP(DirectFunctionCall3(replace_text,
                                                     PointerGetDatum(text_string),
                                                     PointerGetDatum(text_search),
                                                     PointerGetDatum(text_replace)));

    /* convert it back to a cstring */
    string = text_to_cstring(text_result);
    string_len = strlen(string);

    /* if we have an empty string, return null */
    if (string_len == 0)
        PG_RETURN_NULL();

    /* build the result */
    agtv_result.type = AGTV_STRING;
    agtv_result.val.string.val = string;
    agtv_result.val.string.len = string_len;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

/*
 * Helper function to extract one float8 compatible value from a variadic any.
 * It supports integer2/4/8, float4/8, and numeric or the agtype integer, float,
 * and numeric for the argument. It does not support a character based float,
 * otherwise we would just use tofloat. It returns a float on success or fails
 * with a message stating the funcname that called it and a specific message
 * stating the error.
 */
static float8 get_float_compatible_arg(Datum arg, Oid type, char *funcname,
                                       bool *is_null)
{
    float8 result;

    /* Assume the value is null. Although, this is only necessary for agtypes */
    *is_null = true;

    if (type != AGTYPEOID)
    {
        if (type == INT2OID)
            result = (float8) DatumGetInt16(arg);
        else if (type == INT4OID)
            result = (float8) DatumGetInt32(arg);
        else if (type == INT8OID)
        {
            /*
             * 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, arg));
            bool is_valid = false;
            /* turn it into a float */
            result = float8in_internal_null(string, NULL, "double precision",
                                            string, &is_valid);

            /* return 0 if it was an invalid float */
            if (!is_valid)
                return 0;
        }
        else if (type == FLOAT4OID)
            result = (float8) DatumGetFloat4(arg);
        else if (type == FLOAT8OID)
            result = DatumGetFloat8(arg);
        else if (type == NUMERICOID)
            result = DatumGetFloat8(DirectFunctionCall1(
                numeric_float8_no_overflow, arg));
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("%s() unsupported argument type %d", funcname,
                                   type)));
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("%s() only supports scalar arguments",
                                   funcname)));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* check for agtype null */
        if (agtv_value->type == AGTV_NULL)
            return 0;

        if (agtv_value->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.
             */
            bool is_valid = false;
            char *string = DatumGetCString(DirectFunctionCall1(int8out,
                                                               Int64GetDatum(agtv_value->val.int_value)));
            /* turn it into a float */
            result = float8in_internal_null(string, NULL, "double precision",
                                            string, &is_valid);

            /* return null if it was not a valid float */
            if (!is_valid)
                return 0;
        }
        else if (agtv_value->type == AGTV_FLOAT)
            result = agtv_value->val.float_value;
        else if (agtv_value->type == AGTV_NUMERIC)
            result = DatumGetFloat8(DirectFunctionCall1(
                numeric_float8_no_overflow,
                NumericGetDatum(agtv_value->val.numeric)));
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("%s() unsupported argument agtype %d",
                                   funcname, agtv_value->type)));
    }

    /* there is a valid non null value */
    *is_null = false;

    return result;
}

/*
 * Helper function to extract one numeric compatible value from a variadic any.
 * It supports integer2/4/8, float4/8, and numeric or the agtype integer, float,
 * and numeric for the argument. It does not support a character based numeric,
 * otherwise we would just cast it to numeric. It returns a numeric on success
 * or fails with a message stating the funcname that called it and a specific
 * message stating the error.
 */
static Numeric get_numeric_compatible_arg(Datum arg, Oid type, char *funcname,
                                          bool *is_null,
                                          enum agtype_value_type *ag_type)
{
    Numeric result;

    /* Assume the value is null. Although, this is only necessary for agtypes */
    *is_null = true;

    if (ag_type != NULL)
        *ag_type = AGTV_NULL;

    if (type != AGTYPEOID)
    {
        if (type == INT2OID)
            result = DatumGetNumeric(DirectFunctionCall1(int2_numeric, arg));
        else if (type == INT4OID)
            result = DatumGetNumeric(DirectFunctionCall1(int4_numeric, arg));
        else if (type == INT8OID)
            result = DatumGetNumeric(DirectFunctionCall1(int8_numeric, arg));
        else if (type == FLOAT4OID)
            result = DatumGetNumeric(DirectFunctionCall1(float4_numeric, arg));
        else if (type == FLOAT8OID)
            result = DatumGetNumeric(DirectFunctionCall1(float8_numeric, arg));
        else if (type == NUMERICOID)
            result = DatumGetNumeric(arg);
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("%s() unsupported argument type %d", funcname,
                                   type)));
    }
    else
    {
        agtype *agt_arg;
        agtype_value *agtv_value;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(arg);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("%s() only supports scalar arguments",
                                   funcname)));

        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* check for agtype null */
        if (agtv_value->type == AGTV_NULL)
            return 0;

        if (agtv_value->type == AGTV_INTEGER)
        {
            result = DatumGetNumeric(DirectFunctionCall1(
                int8_numeric, Int64GetDatum(agtv_value->val.int_value)));
            if (ag_type != NULL)
                *ag_type = AGTV_INTEGER;
        }
        else if (agtv_value->type == AGTV_FLOAT)
        {
            result = DatumGetNumeric(DirectFunctionCall1(
                float8_numeric, Float8GetDatum(agtv_value->val.float_value)));
            if (ag_type != NULL)
                *ag_type = AGTV_FLOAT;
        }
        else if (agtv_value->type == AGTV_NUMERIC)
        {
            result = agtv_value->val.numeric;
            if (ag_type != NULL)
                *ag_type = AGTV_NUMERIC;
        }
        else
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                            errmsg("%s() unsupported argument agtype %d",
                                   funcname, agtv_value->type)));
    }

    /* there is a valid non null value */
    *is_null = false;

    return result;
}

PG_FUNCTION_INFO_V1(age_sin);

Datum age_sin(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    float8 angle;
    float8 result;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("sin() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * sin() supports integer, float, and numeric or the agtype integer, float,
     * and numeric for the angle
     */

    angle = get_float_compatible_arg(args[0], types[0], "sin", &is_null);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the numeric input as a float8 so that we can pass it off to PG */
    result = DatumGetFloat8(DirectFunctionCall1(dsin,
                                                Float8GetDatum(angle)));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_cos);

Datum age_cos(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    float8 angle;
    float8 result;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("cos() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * cos() supports integer, float, and numeric or the agtype integer, float,
     * and numeric for the angle
     */

    angle = get_float_compatible_arg(args[0], types[0], "cos", &is_null);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the numeric input as a float8 so that we can pass it off to PG */
    result = DatumGetFloat8(DirectFunctionCall1(dcos,
                                                Float8GetDatum(angle)));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_tan);

Datum age_tan(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    float8 angle;
    float8 result;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("tan() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * tan() supports integer, float, and numeric or the agtype integer, float,
     * and numeric for the angle
     */

    angle = get_float_compatible_arg(args[0], types[0], "tan", &is_null);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the numeric input as a float8 so that we can pass it off to PG */
    result = DatumGetFloat8(DirectFunctionCall1(dtan,
                                                Float8GetDatum(angle)));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_cot);

Datum age_cot(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    float8 angle;
    float8 result;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("cot() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * cot() supports integer, float, and numeric or the agtype integer, float,
     * and numeric for the angle
     */

    angle = get_float_compatible_arg(args[0], types[0], "cot", &is_null);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the numeric input as a float8 so that we can pass it off to PG */
    result = DatumGetFloat8(DirectFunctionCall1(dcot,
                                                Float8GetDatum(angle)));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_asin);

Datum age_asin(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    float8 x;
    float8 angle;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("asin() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * asin() supports integer, float, and numeric or the agtype integer, float,
     * and numeric for the input expression.
     */

    x = get_float_compatible_arg(args[0], types[0], "asin", &is_null);

    /* verify that x is within range */
    if (x < -1 || x > 1)
        PG_RETURN_NULL();

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the numeric input as a float8 so that we can pass it off to PG */
    angle = DatumGetFloat8(DirectFunctionCall1(dasin,
                                               Float8GetDatum(x)));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = angle;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_acos);

Datum age_acos(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    float8 x;
    float8 angle;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("acos() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * acos() supports integer, float, and numeric or the agtype integer, float,
     * and numeric for the input expression.
     */

    x = get_float_compatible_arg(args[0], types[0], "acos", &is_null);

    /* verify that x is within range */
    if (x < -1 || x > 1)
        PG_RETURN_NULL();

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the numeric input as a float8 so that we can pass it off to PG */
    angle = DatumGetFloat8(DirectFunctionCall1(dacos,
                                               Float8GetDatum(x)));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = angle;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_atan);

Datum age_atan(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    float8 x;
    float8 angle;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("atan() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * atan() supports integer, float, and numeric or the agtype integer, float,
     * and numeric for the input expression.
     */

    x = get_float_compatible_arg(args[0], types[0], "atan", &is_null);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the numeric input as a float8 so that we can pass it off to PG */
    angle = DatumGetFloat8(DirectFunctionCall1(datan,
                                               Float8GetDatum(x)));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = angle;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_atan2);

Datum age_atan2(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    float8 x, y;
    float8 angle;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 2)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("atan2() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0] || nulls[1])
        PG_RETURN_NULL();

    /*
     * atan2() supports integer, float, and numeric or the agtype integer,
     * float, and numeric for the input expressions.
     */

    y = get_float_compatible_arg(args[0], types[0], "atan2", &is_null);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    x = get_float_compatible_arg(args[1], types[1], "atan2", &is_null);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the numeric input as a float8 so that we can pass it off to PG */
    angle = DatumGetFloat8(DirectFunctionCall2(datan2,
                                               Float8GetDatum(y),
                                               Float8GetDatum(x)));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = angle;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_degrees);

Datum age_degrees(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    float8 angle_degrees;
    float8 angle_radians;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("degrees() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * degrees_from_radians() supports integer, float, and numeric or the agtype
     * integer, float, and numeric for the input expression.
     */

    angle_radians = get_float_compatible_arg(args[0], types[0], "degrees",
                                             &is_null);
    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the numeric input as a float8 so that we can pass it off to PG */
    angle_degrees = DatumGetFloat8(DirectFunctionCall1(degrees,
                                                       Float8GetDatum(angle_radians)));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = angle_degrees;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_radians);

Datum age_radians(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    float8 angle_degrees;
    float8 angle_radians;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("radians() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * radians_from_degrees() supports integer, float, and numeric or the agtype
     * integer, float, and numeric for the input expression.
     */

    angle_degrees = get_float_compatible_arg(args[0], types[0], "radians",
                                             &is_null);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the numeric input as a float8 so that we can pass it off to PG */
    angle_radians = DatumGetFloat8(DirectFunctionCall1(radians,
                                                       Float8GetDatum(angle_degrees)));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = angle_radians;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_round);

Datum age_round(PG_FUNCTION_ARGS)
{
    Datum *args = NULL;
    bool *nulls = NULL;
    Oid *types = NULL;
    int nargs = 0;
    agtype_value agtv_result;
    Numeric arg, arg_precision;
    Numeric numeric_result;
    float8 float_result;
    bool is_null = true;
    int precision = 0;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1 && nargs != 2)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("round() invalid number of arguments")));
    }

    /* check for a null input */
    if (nargs < 0 || nulls[0])
    {
        PG_RETURN_NULL();
    }

    /*
     * round() supports integer, float, and numeric or the agtype integer,
     * float, and numeric for the input expression.
     */
    arg = get_numeric_compatible_arg(args[0], types[0], "round", &is_null,
                                     NULL);

    /* check for a agtype null input */
    if (is_null)
    {
        PG_RETURN_NULL();
    }

    /* We need the input as a numeric so that we can pass it off to PG */
    if (nargs == 2 && !nulls[1])
    {
        arg_precision = get_numeric_compatible_arg(args[1], types[1], "round",
                                                   &is_null, NULL);
        if (!is_null)
        {
            precision = DatumGetInt64(DirectFunctionCall1(numeric_int8,
                                      NumericGetDatum(arg_precision)));
            numeric_result = DatumGetNumeric(DirectFunctionCall2(numeric_round,
                                             NumericGetDatum(arg),
                                             Int32GetDatum(precision)));
        }
        else
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("round() invalid NULL precision value")));
        }
    }
    else
    {
        numeric_result = DatumGetNumeric(DirectFunctionCall2(numeric_round,
                                         NumericGetDatum(arg),
                                         Int32GetDatum(0)));
    }

    float_result = DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow,
                                               NumericGetDatum(numeric_result)));
    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = float_result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_ceil);

Datum age_ceil(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    Numeric arg;
    Numeric numeric_result;
    float8 float_result;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("ceil() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * ceil() supports integer, float, and numeric or the agtype integer,
     * float, and numeric for the input expression.
     */
    arg = get_numeric_compatible_arg(args[0], types[0], "ceil", &is_null, NULL);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the input as a numeric so that we can pass it off to PG */
    numeric_result = DatumGetNumeric(DirectFunctionCall1(numeric_ceil,
                                                         NumericGetDatum(arg)));

    float_result = DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow,
                                                      NumericGetDatum(numeric_result)));
    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = float_result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_floor);

Datum age_floor(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    Numeric arg;
    Numeric numeric_result;
    float8 float_result;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("floor() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * floor() supports integer, float, and numeric or the agtype integer,
     * float, and numeric for the input expression.
     */
    arg = get_numeric_compatible_arg(args[0], types[0], "floor", &is_null,
                                     NULL);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the input as a numeric so that we can pass it off to PG */
    numeric_result = DatumGetNumeric(DirectFunctionCall1(numeric_floor,
                                                         NumericGetDatum(arg)));

    float_result = DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow,
                                                      NumericGetDatum(numeric_result)));
    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = float_result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_abs);

Datum age_abs(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    Numeric arg;
    Numeric numeric_result;
    bool is_null = true;
    enum agtype_value_type type = AGTV_NULL;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("abs() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * abs() supports integer, float, and numeric or the agtype integer,
     * float, and numeric for the input expression.
     */
    arg = get_numeric_compatible_arg(args[0], types[0], "abs", &is_null, &type);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the input as a numeric so that we can pass it off to PG */
    numeric_result = DatumGetNumeric(DirectFunctionCall1(numeric_abs,
                                                         NumericGetDatum(arg)));

    /* build the result, based on the type */
    if (types[0] == INT2OID || types[0] == INT4OID || types[0] == INT8OID ||
        (types[0] == AGTYPEOID && type == AGTV_INTEGER))
    {
        int64 int_result;

        int_result = DatumGetInt64(DirectFunctionCall1(numeric_int8,
                                                       NumericGetDatum(numeric_result)));

        agtv_result.type = AGTV_INTEGER;
        agtv_result.val.int_value = int_result;
    }
    if (types[0] == FLOAT4OID || types[0] == FLOAT8OID ||
        (types[0] == AGTYPEOID && type == AGTV_FLOAT))
    {
        float8 float_result;

        float_result = DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow,
                           NumericGetDatum(numeric_result)));

        agtv_result.type = AGTV_FLOAT;
        agtv_result.val.float_value = float_result;
    }
    if (types[0] == NUMERICOID ||
        (types[0] == AGTYPEOID && type == AGTV_NUMERIC))
    {
        agtv_result.type = AGTV_NUMERIC;
        agtv_result.val.numeric = numeric_result;
    }

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_sign);

Datum age_sign(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    Numeric arg;
    Numeric numeric_result;
    int int_result;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("sign() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * sign() supports integer, float, and numeric or the agtype integer,
     * float, and numeric for the input expression.
     */
    arg = get_numeric_compatible_arg(args[0], types[0], "sign", &is_null, NULL);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the input as a numeric so that we can pass it off to PG */
    numeric_result = DatumGetNumeric(DirectFunctionCall1(numeric_sign,
                                                         NumericGetDatum(arg)));

    int_result = DatumGetInt64(DirectFunctionCall1(numeric_int8,
                                                   NumericGetDatum(numeric_result)));

    /* build the result */
    agtv_result.type = AGTV_INTEGER;
    agtv_result.val.int_value = int_result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_log);

Datum age_log(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    Numeric arg;
    Numeric zero;
    Numeric numeric_result;
    float8 float_result;
    bool is_null = true;
    int test;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("log() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * log() supports integer, float, and numeric or the agtype integer,
     * float, and numeric for the input expression.
     */
    arg = get_numeric_compatible_arg(args[0], types[0], "log", &is_null, NULL);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* get a numeric 0 as a datum to test <= 0 log args */
    zero = DatumGetNumeric(DirectFunctionCall1(int8_numeric, Int64GetDatum(0)));

    test = DatumGetInt32(DirectFunctionCall2(numeric_cmp, NumericGetDatum(arg),
                                             NumericGetDatum(zero)));

    /* return null if the argument is <= 0; these are invalid args for logs */
    if (test <= 0)
        PG_RETURN_NULL();

    /* We need the input as a numeric so that we can pass it off to PG */
    numeric_result = DatumGetNumeric(DirectFunctionCall1(numeric_ln,
                                                         NumericGetDatum(arg)));

    float_result = DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow,
                                                      NumericGetDatum(numeric_result)));
    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = float_result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_log10);

Datum age_log10(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    Numeric arg;
    Numeric zero;
    Numeric numeric_result;
    float8 float_result;
    Datum base;
    bool is_null = true;
    int test;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("log() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * log10() supports integer, float, and numeric or the agtype integer,
     * float, and numeric for the input expression.
     */
    arg = get_numeric_compatible_arg(args[0], types[0], "log10", &is_null, NULL);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* get a numeric 0 as a datum to test <= 0 log args */
    zero = DatumGetNumeric(DirectFunctionCall1(int8_numeric, Int64GetDatum(0)));

    test = DatumGetInt32(DirectFunctionCall2(numeric_cmp, NumericGetDatum(arg),
                                             NumericGetDatum(zero)));

    /* return null if the argument is <= 0; these are invalid args for logs */
    if (test <= 0)
        PG_RETURN_NULL();

    /* get a numeric 10 as a datum for the base */
    base = DirectFunctionCall1(float8_numeric, Float8GetDatum(10.0));

    /* We need the input as a numeric so that we can pass it off to PG */
    numeric_result = DatumGetNumeric(DirectFunctionCall2(numeric_log, base,
                                                         NumericGetDatum(arg)));

    float_result = DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow,
                                                      NumericGetDatum(numeric_result)));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = float_result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_e);

Datum age_e(PG_FUNCTION_ARGS)
{
    agtype_value agtv_result;
    float8 float_result;

    /* get e by raising e to 1 - no, they don't have a constant e :/ */
    float_result = DatumGetFloat8(DirectFunctionCall1(dexp, Float8GetDatum(1)));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = float_result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_pi);

Datum age_pi(PG_FUNCTION_ARGS)
{
    agtype_value agtv_result;
    float8 float_result;

    float_result = DatumGetFloat8(DirectFunctionCall1(dpi, 0));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = float_result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_rand);

Datum age_rand(PG_FUNCTION_ARGS)
{
    agtype_value agtv_result;
    float8 float_result;

    float_result = DatumGetFloat8(DirectFunctionCall1(drandom, 0));

    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = float_result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_exp);

Datum age_exp(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    Numeric arg;
    Numeric numeric_result;
    float8 float_result;
    bool is_null = true;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("exp() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * exp() supports integer, float, and numeric or the agtype integer,
     * float, and numeric for the input expression.
     */
    arg = get_numeric_compatible_arg(args[0], types[0], "exp", &is_null, NULL);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* We need the input as a numeric so that we can pass it off to PG */
    numeric_result = DatumGetNumeric(DirectFunctionCall1(numeric_exp,
                                                         NumericGetDatum(arg)));

    float_result = DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow,
                                                      NumericGetDatum(numeric_result)));
    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = float_result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_sqrt);

Datum age_sqrt(PG_FUNCTION_ARGS)
{
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    agtype_value agtv_result;
    Numeric arg;
    Numeric zero;
    Numeric numeric_result;
    float8 float_result;
    bool is_null = true;
    int test;

    /* extract argument values */
    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);

    /* check number of args */
    if (nargs != 1)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("sqrt() invalid number of arguments")));

    /* check for a null input */
    if (nargs < 0 || nulls[0])
        PG_RETURN_NULL();

    /*
     * sqrt() supports integer, float, and numeric or the agtype integer,
     * float, and numeric for the input expression.
     */
    arg = get_numeric_compatible_arg(args[0], types[0], "sqrt", &is_null, NULL);

    /* check for a agtype null input */
    if (is_null)
        PG_RETURN_NULL();

    /* get a numeric 0 as a datum to test < 0 sqrt args */
    zero = DatumGetNumeric(DirectFunctionCall1(int8_numeric, Int64GetDatum(0)));

    test = DatumGetInt32(DirectFunctionCall2(numeric_cmp, NumericGetDatum(arg),
                                             NumericGetDatum(zero)));

    /* return null if the argument is < 0; these are invalid args for sqrt */
    if (test < 0)
        PG_RETURN_NULL();

    /* We need the input as a numeric so that we can pass it off to PG */
    numeric_result = DatumGetNumeric(DirectFunctionCall1(numeric_sqrt,
                                                         NumericGetDatum(arg)));

    float_result = DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow,
                                                      NumericGetDatum(numeric_result)));
    /* build the result */
    agtv_result.type = AGTV_FLOAT;
    agtv_result.val.float_value = float_result;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

PG_FUNCTION_INFO_V1(age_timestamp);

Datum age_timestamp(PG_FUNCTION_ARGS)
{
    agtype_value agtv_result;
    struct timespec ts;
    long ms = 0;

    /* get the system time and convert it to milliseconds */
    clock_gettime(CLOCK_REALTIME, &ts);
    ms += (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);

    /* build the result */
    agtv_result.type = AGTV_INTEGER;
    agtv_result.val.int_value = ms;

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

/*
 * Converts an agtype object or array to a binary agtype_value.
 */
agtype_value *agtype_composite_to_agtype_value_binary(agtype *a)
{
    agtype_value *result;

    if (AGTYPE_CONTAINER_IS_SCALAR(&a->root))
    {
        ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                        errmsg("cannot convert agtype scalar objects to binary agtype_value objects")));
    }

    result = palloc(sizeof(agtype_value));

    // convert the agtype to a binary agtype_value
    result->type = AGTV_BINARY;
    result->val.binary.len = AGTYPE_CONTAINER_SIZE(&a->root);
    result->val.binary.data = &a->root;

    return result;
}

/*
 * For the given properties, update the property with the key equal
 * to var_name with the value defined in new_v. If the remove_property
 * flag is set, simply remove the property with the given property
 * name instead.
 */
agtype_value *alter_property_value(agtype_value *properties, char *var_name,
                                   agtype *new_v, bool remove_property)
{
    agtype_iterator *it;
    agtype_iterator_token tok = WAGT_DONE;
    agtype_parse_state *parse_state = NULL;
    agtype_value *r;
    agtype *prop_agtype;
    agtype_value *parsed_agtype_value = NULL;
    bool found;

    // if no properties, return NULL
    if (properties == NULL)
    {
        return NULL;
    }

    // if properties is not an object, throw an error
    if (properties->type != AGTV_OBJECT)
    {
        ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                        errmsg("can only update objects")));
    }

    r = palloc0(sizeof(agtype_value));

    prop_agtype = agtype_value_to_agtype(properties);
    it = agtype_iterator_init(&prop_agtype->root);
    tok = agtype_iterator_next(&it, r, true);

    parsed_agtype_value = push_agtype_value(&parse_state, tok, tok < WAGT_BEGIN_ARRAY ? r : NULL);

    /*
     * If the new value is NULL, this is equivalent to the remove_property
     * flag set to true.
     */
    if (new_v == NULL)
    {
        remove_property = true;
    }

    found = false;
    while (true)
    {
        char *str;

        tok = agtype_iterator_next(&it, r, true);

        if (tok == WAGT_DONE || tok == WAGT_END_OBJECT)
        {
            break;
        }

        str = pnstrdup(r->val.string.val, r->val.string.len);

        /*
         * Check the key value, if it is equal to the passed in
         * var_name, replace the value for this key with the passed
         * in agtype. Otherwise pass the existing value to the
         * new properties agtype_value.
         */
        if (strcmp(str, var_name))
        {
            // push the key
            parsed_agtype_value = push_agtype_value(
                &parse_state, tok, tok < WAGT_BEGIN_ARRAY ? r : NULL);

            // get the value and push the value
            tok = agtype_iterator_next(&it, r, true);
            parsed_agtype_value = push_agtype_value(&parse_state, tok, r);
        }
        else
        {
            agtype_value *new_agtype_value_v;

            // if the remove flag is set, don't push the key or any value
            if(remove_property)
            {
                // skip the value
                tok = agtype_iterator_next(&it, r, true);
                continue;
            }

            // push the key
            parsed_agtype_value = push_agtype_value(
                &parse_state, tok, tok < WAGT_BEGIN_ARRAY ? r : NULL);

            // skip the existing value for the key
            tok = agtype_iterator_next(&it, r, true);

            /*
             * If the new agtype is scalar, push the agtype_value to the
             * parse state. If the agtype is an object or array convert the
             * agtype to a binary agtype_value to pass to the parse_state.
             * This will save unnecessary deserialization and serialization
             * logic from running.
             */
            if (AGTYPE_CONTAINER_IS_SCALAR(&new_v->root))
            {
                //get the scalar value and push as the value
                new_agtype_value_v = get_ith_agtype_value_from_container(&new_v->root, 0);

                parsed_agtype_value = push_agtype_value(&parse_state, WAGT_VALUE, new_agtype_value_v);
            }
            else
            {
                agtype_value *result = agtype_composite_to_agtype_value_binary(new_v);

                parsed_agtype_value = push_agtype_value(&parse_state, WAGT_VALUE, result);
            }

            found = true;
        }
    }

    /*
     * If we have not found the property and we aren't trying to remove it,
     * add the key/value pair now.
     */
    if (!found && !remove_property)
    {
        agtype_value *new_agtype_value_v;
        agtype_value *key = string_to_agtype_value(var_name);

        // push the new key
        parsed_agtype_value = push_agtype_value(
            &parse_state, WAGT_KEY, key);

        /*
         * If the new agtype is scalar, push the agtype_value to the
         * parse state. If the agtype is an object or array convert the
         * agtype to a binary agtype_value to pass to the parse_state.
         * This will save unnecessary deserialization and serialization
         * logic from running.
         */
        if (AGTYPE_CONTAINER_IS_SCALAR(&new_v->root))
        {
            new_agtype_value_v = get_ith_agtype_value_from_container(&new_v->root, 0);

            // convert the agtype array or object to a binary agtype_value
            parsed_agtype_value = push_agtype_value(&parse_state, WAGT_VALUE, new_agtype_value_v);
        }
        else
        {
            agtype_value *result = agtype_composite_to_agtype_value_binary(new_v);

            parsed_agtype_value = push_agtype_value(&parse_state, WAGT_VALUE, result);
        }
    }

    // push the end object token to parse state
    parsed_agtype_value = push_agtype_value(&parse_state, WAGT_END_OBJECT, NULL);

    return parsed_agtype_value;
}

/*
 * Appends new_properties into a copy of original_properties. If the
 * original_properties is NULL, returns new_properties.
 *
 * This is a helper function used by the SET clause executor for
 * updating properties with the equal, or plus-equal operator and a map.
 */
agtype_value *alter_properties(agtype_value *original_properties,
                               agtype *new_properties)
{
    agtype_iterator *it;
    agtype_iterator_token tok = WAGT_DONE;
    agtype_parse_state *parse_state = NULL;
    agtype_value *key;
    agtype_value *value;
    agtype_value *parsed_agtype_value = NULL;

    parsed_agtype_value = push_agtype_value(&parse_state, WAGT_BEGIN_OBJECT,
                                            NULL);

    // Copy original properties.
    if (original_properties)
    {
        if (original_properties->type != AGTV_OBJECT)
        {
            ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                            errmsg("a map is expected")));
        }

        copy_agtype_value(parse_state, original_properties,
                          &parsed_agtype_value, true);
    }

    // Append new properties.
    key = palloc0(sizeof(agtype_value));
    value = palloc0(sizeof(agtype_value));
    it = agtype_iterator_init(&new_properties->root);
    tok = agtype_iterator_next(&it, key, true);

    if (tok != WAGT_BEGIN_OBJECT)
    {
        ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                        errmsg("a map is expected")));
    }

    while (true)
    {
        tok = agtype_iterator_next(&it, key, true);

        if (tok == WAGT_DONE || tok == WAGT_END_OBJECT)
        {
            break;
        }

        agtype_iterator_next(&it, value, true);

        parsed_agtype_value = push_agtype_value(&parse_state, WAGT_KEY,
                                                key);
        parsed_agtype_value = push_agtype_value(&parse_state, WAGT_VALUE,
                                                value);
    }

    parsed_agtype_value = push_agtype_value(&parse_state, WAGT_END_OBJECT,
                                            NULL);
    return parsed_agtype_value;
}

/*
 * Helper function to extract 1 datum from a variadic "any" and convert, if
 * possible, to an agtype, if it isn't already.
 *
 * If the value is a NULL or agtype NULL, the function returns NULL.
 * If the datum cannot be converted, the function will error out in
 * extract_variadic_args.
 */
agtype *get_one_agtype_from_variadic_args(FunctionCallInfo fcinfo,
                                          int variadic_offset,
                                          int expected_nargs)
{
    int nargs;
    Datum *args = NULL;
    bool *nulls = NULL;
    Oid *types = NULL;
    agtype *agtype_result = NULL;

    nargs = extract_variadic_args(fcinfo, variadic_offset, false, &args, &types,
                                  &nulls);
    /* throw an error if the number of args is not the expected number */
    if (nargs != expected_nargs)
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("number of args %d does not match expected %d",
                               nargs, expected_nargs)));
    }
    /* if null, return null */
    if (nulls[0])
    {
        return NULL;
    }

    /* if type is AGTYPEOID, we don't need to convert it */
    if (types[0] == AGTYPEOID)
    {
        agtype_container *agtc;

        agtype_result = DATUM_GET_AGTYPE_P(args[0]);
        agtc = &agtype_result->root;

        /*
         * Is this a scalar (scalars are stored as one element arrays)? If so,
         * test for agtype NULL.
         */
        if (AGTYPE_CONTAINER_IS_SCALAR(agtc) &&
            AGTE_IS_NULL(agtc->children[0]))
        {
            return NULL;
        }
    }
    /* otherwise, try to convert it to an agtype */
    else
    {
        agtype_in_state state;
        agt_type_category tcategory;
        Oid outfuncoid;

        /* we need an empty state */
        state.parse_state = NULL;
        state.res = NULL;
        /* get the category for the datum */
        agtype_categorize_type(types[0], &tcategory, &outfuncoid);
        /* convert it to an agtype_value */
        datum_to_agtype(args[0], false, &state, tcategory, outfuncoid, false);
        /* convert it to an agtype */
        agtype_result = agtype_value_to_agtype(state.res);
    }
    return agtype_result;
}

/*
 * Transfer function for age_sum(agtype, agtype).
 *
 * Note: that the running sum will change type depending on the
 * precision of the input. The most precise value determines the
 * result type.
 *
 * Note: The sql definition is STRICT so no input NULLs need to
 * be dealt with except for agtype.
 */
PG_FUNCTION_INFO_V1(age_agtype_sum);

Datum age_agtype_sum(PG_FUNCTION_ARGS)
{
    agtype *agt_arg0 = AG_GET_ARG_AGTYPE_P(0);
    agtype *agt_arg1 = AG_GET_ARG_AGTYPE_P(1);
    agtype_value *agtv_lhs;
    agtype_value *agtv_rhs;
    agtype_value agtv_result;

    /* get our args */
    agt_arg0 = AG_GET_ARG_AGTYPE_P(0);
    agt_arg1 = AG_GET_ARG_AGTYPE_P(1);

    /* only scalars are allowed */
    if (!AGT_ROOT_IS_SCALAR(agt_arg0) || !AGT_ROOT_IS_SCALAR(agt_arg1))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("arguments must resolve to a scalar")));

    /* get the values */
    agtv_lhs = get_ith_agtype_value_from_container(&agt_arg0->root, 0);
    agtv_rhs = get_ith_agtype_value_from_container(&agt_arg1->root, 0);

    /* only numbers are allowed */
    if ((agtv_lhs->type != AGTV_INTEGER && agtv_lhs->type != AGTV_FLOAT &&
         agtv_lhs->type != AGTV_NUMERIC) || (agtv_rhs->type != AGTV_INTEGER &&
        agtv_rhs->type != AGTV_FLOAT && agtv_rhs->type != AGTV_NUMERIC))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("arguments must resolve to a number")));

    /* check for agtype null */
    if (agtv_lhs->type == AGTV_NULL)
        PG_RETURN_POINTER(agt_arg1);
    if (agtv_rhs->type == AGTV_NULL)
        PG_RETURN_POINTER(agt_arg0);

    /* we want to maintain the precision of the most precise input */
    if (agtv_lhs->type == AGTV_NUMERIC || agtv_rhs->type == AGTV_NUMERIC)
    {
        agtv_result.type = AGTV_NUMERIC;
    }
    else if (agtv_lhs->type == AGTV_FLOAT || agtv_rhs->type == AGTV_FLOAT)
    {
        agtv_result.type = AGTV_FLOAT;
    }
    else
    {
        agtv_result.type = AGTV_INTEGER;
    }

    /* switch on the type to perform the correct addition */
    switch(agtv_result.type)
    {
        /* if the type is integer, they are obviously both ints */
        case AGTV_INTEGER:
            agtv_result.val.int_value = DatumGetInt64(
                DirectFunctionCall2(int8pl,
                                    Int64GetDatum(agtv_lhs->val.int_value),
                                    Int64GetDatum(agtv_rhs->val.int_value)));
            break;
        /* for float it can be either, float + float or float + int */
        case AGTV_FLOAT:
        {
            Datum dfl;
            Datum dfr;
            Datum dresult;
            /* extract and convert the values as necessary */
            /* float + float */
            if (agtv_lhs->type == AGTV_FLOAT && agtv_rhs->type == AGTV_FLOAT)
            {
                dfl = Float8GetDatum(agtv_lhs->val.float_value);
                dfr = Float8GetDatum(agtv_rhs->val.float_value);
            }
            /* float + int */
            else
            {
                int64 ival;
                float8 fval;
                bool is_null;

                ival = (agtv_lhs->type == AGTV_INTEGER) ?
                    agtv_lhs->val.int_value : agtv_rhs->val.int_value;
                fval = (agtv_lhs->type == AGTV_FLOAT) ?
                    agtv_lhs->val.float_value : agtv_rhs->val.float_value;

                dfl = Float8GetDatum(get_float_compatible_arg(Int64GetDatum(ival),
                                                              INT8OID, "",
                                                              &is_null));
                dfr = Float8GetDatum(fval);
            }
            /* add the floats and set the result */
            dresult = DirectFunctionCall2(float8pl, dfl, dfr);
            agtv_result.val.float_value = DatumGetFloat8(dresult);
        }
            break;
        /*
         * For numeric it can be either, numeric + numeric or numeric + float or
         * numeric + int
         */
        case AGTV_NUMERIC:
        {
            Datum dnl;
            Datum dnr;
            Datum dresult;
            /* extract and convert the values as necessary */
            /* numeric + numeric */
            if (agtv_lhs->type == AGTV_NUMERIC && agtv_rhs->type == AGTV_NUMERIC)
            {
                dnl = NumericGetDatum(agtv_lhs->val.numeric);
                dnr = NumericGetDatum(agtv_rhs->val.numeric);
            }
            /* numeric + float */
            else if (agtv_lhs->type == AGTV_FLOAT || agtv_rhs->type == AGTV_FLOAT)
            {
                float8 fval;
                Numeric nval;

                fval = (agtv_lhs->type == AGTV_FLOAT) ?
                    agtv_lhs->val.float_value : agtv_rhs->val.float_value;
                nval = (agtv_lhs->type == AGTV_NUMERIC) ?
                    agtv_lhs->val.numeric : agtv_rhs->val.numeric;

                dnl = DirectFunctionCall1(float8_numeric, Float8GetDatum(fval));
                dnr = NumericGetDatum(nval);
            }
            /* numeric + int */
            else
            {
                int64 ival;
                Numeric nval;

                ival = (agtv_lhs->type == AGTV_INTEGER) ?
                    agtv_lhs->val.int_value : agtv_rhs->val.int_value;
                nval = (agtv_lhs->type == AGTV_NUMERIC) ?
                    agtv_lhs->val.numeric : agtv_rhs->val.numeric;

                dnl = DirectFunctionCall1(int8_numeric, Int64GetDatum(ival));
                dnr = NumericGetDatum(nval);
            }
            /* add the numerics and set the result */
            dresult = DirectFunctionCall2(numeric_add, dnl, dnr);
            agtv_result.val.numeric = DatumGetNumeric(dresult);
        }
            break;

        default:
            elog(ERROR, "unexpected agtype");
            break;
    }
    /* return the result */
    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
}

/*
 * Wrapper function for float8_accum to take an agtype input.
 * This function is defined as STRICT so it does not need to check
 * for NULL input parameters
 */
PG_FUNCTION_INFO_V1(age_agtype_float8_accum);

Datum age_agtype_float8_accum(PG_FUNCTION_ARGS)
{
    Datum dfloat;
    Datum result;

    /* convert to a float8 datum, if possible */
    dfloat = DirectFunctionCall1(agtype_to_float8, PG_GETARG_DATUM(1));
    /* pass the arguments off to float8_accum */
    result = DirectFunctionCall2(float8_accum, PG_GETARG_DATUM(0), dfloat);

    PG_RETURN_DATUM(result);
}

/* Wrapper for stdDev function. */
PG_FUNCTION_INFO_V1(age_float8_stddev_samp_aggfinalfn);

Datum age_float8_stddev_samp_aggfinalfn(PG_FUNCTION_ARGS)
{
    Datum result;
    PGFunction func;
    agtype_value agtv_float;

    /* we can't use DirectFunctionCall1 as it errors for NULL values */
    func = float8_stddev_samp;
    result = (*func) (fcinfo);

    agtv_float.type = AGTV_FLOAT;

    /*
     * Check to see if float8_stddev_samp returned null. If so, we need to
     * return a agtype float 0.
     */
    if (fcinfo->isnull)
    {
        /* we need to clear the flag */
        fcinfo->isnull = false;
        agtv_float.val.float_value = 0.0;
    }
    else
    {
        agtv_float.val.float_value = DatumGetFloat8(result);
    }

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_float));
}

PG_FUNCTION_INFO_V1(age_float8_stddev_pop_aggfinalfn);

Datum age_float8_stddev_pop_aggfinalfn(PG_FUNCTION_ARGS)
{
    Datum result;
    PGFunction func;
    agtype_value agtv_float;

    /* we can't use DirectFunctionCall1 as it errors for NULL values */
    func = float8_stddev_pop;
    result = (*func) (fcinfo);

    agtv_float.type = AGTV_FLOAT;

    /*
     * Check to see if float8_stddev_pop returned null. If so, we need to
     * return a agtype float 0.
     */
    if (fcinfo->isnull)
    {
        /* we need to clear the flag */
        fcinfo->isnull = false;
        agtv_float.val.float_value = 0.0;
    }
    else
    {
        agtv_float.val.float_value = DatumGetFloat8(result);
    }

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_float));
}

PG_FUNCTION_INFO_V1(age_agtype_larger_aggtransfn);

Datum age_agtype_larger_aggtransfn(PG_FUNCTION_ARGS)
{
    agtype *agtype_arg1;
    agtype *agtype_arg2;
    agtype *agtype_larger;
    int test;

    /* for max we need to ignore NULL values */
    /* extract the args as agtype */
    agtype_arg1 = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
    agtype_arg2 = get_one_agtype_from_variadic_args(fcinfo, 1, 1);

    /* return NULL if both are NULL */
    if (agtype_arg1 == NULL && agtype_arg2 == NULL)
        PG_RETURN_NULL();
    /* if one is NULL, return the other */
    if (agtype_arg1 != NULL && agtype_arg2 == NULL)
        PG_RETURN_POINTER(agtype_arg1);
    if (agtype_arg1 == NULL && agtype_arg2 != NULL)
        PG_RETURN_POINTER(agtype_arg2);

    /* test for max value */
    test = compare_agtype_containers_orderability(&agtype_arg1->root,
                                                  &agtype_arg2->root);

    agtype_larger = (test >= 0) ? agtype_arg1 : agtype_arg2;

    PG_RETURN_POINTER(agtype_larger);
}

PG_FUNCTION_INFO_V1(age_agtype_smaller_aggtransfn);

Datum age_agtype_smaller_aggtransfn(PG_FUNCTION_ARGS)
{
    agtype *agtype_arg1 = NULL;
    agtype *agtype_arg2 = NULL;
    agtype *agtype_smaller;
    int test;

    /* for min we need to ignore NULL values */
    /* extract the args as agtype */
    agtype_arg1 = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
    agtype_arg2 = get_one_agtype_from_variadic_args(fcinfo, 1, 1);

    /* return NULL if both are NULL */
    if (agtype_arg1 == NULL && agtype_arg2 == NULL)
        PG_RETURN_NULL();
    /* if one is NULL, return the other */
    if (agtype_arg1 != NULL && agtype_arg2 == NULL)
        PG_RETURN_POINTER(agtype_arg1);
    if (agtype_arg1 == NULL && agtype_arg2 != NULL)
        PG_RETURN_POINTER(agtype_arg2);

    /* test for min value */
    test = compare_agtype_containers_orderability(&agtype_arg1->root,
                                                  &agtype_arg2->root);

    agtype_smaller = (test <= 0) ? agtype_arg1 : agtype_arg2;

    PG_RETURN_POINTER(agtype_smaller);
}

/* borrowed from PGs float8 routines for percentile_cont */
static Datum float8_lerp(Datum lo, Datum hi, double pct)
{
    double loval = DatumGetFloat8(lo);
    double hival = DatumGetFloat8(hi);

    return Float8GetDatum(loval + (pct * (hival - loval)));
}

/* Code borrowed and adjusted from PG's ordered_set_transition function */
PG_FUNCTION_INFO_V1(age_percentile_aggtransfn);

Datum age_percentile_aggtransfn(PG_FUNCTION_ARGS)
{
    PercentileGroupAggState *pgastate;

    /* verify we are in an aggregate context */
    Assert(AggCheckCallContext(fcinfo, NULL) == AGG_CONTEXT_AGGREGATE);

    /* if this is the first invocation, create the state */
    if (PG_ARGISNULL(0))
    {
        MemoryContext old_mcxt;
        float8 percentile;

        /* validate the percentile */
        if (PG_ARGISNULL(2))
            ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                errmsg("percentile value NULL is not a valid numeric value")));

        percentile = DatumGetFloat8(DirectFunctionCall1(agtype_to_float8,
                         PG_GETARG_DATUM(2)));

        if (percentile < 0 || percentile > 1 || isnan(percentile))
        ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                        errmsg("percentile value %g is not between 0 and 1",
                               percentile)));

        /* switch to the correct aggregate context */
        old_mcxt = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
        /* create and initialize the state */
        pgastate = palloc0(sizeof(PercentileGroupAggState));
        pgastate->percentile = percentile;
        /*
         * Percentiles need to be calculated from a sorted set. We are only
         * using float8 values, using the less than operator, and flagging
         * randomAccess to true - as we can potentially be reusing this
         * sort multiple times in the same query.
         */
        pgastate->sortstate = tuplesort_begin_datum(FLOAT8OID,
                                                    Float8LessOperator,
                                                    InvalidOid, false, work_mem,
                                                    NULL, true);
        pgastate->number_of_rows = 0;
        pgastate->sort_done = false;

        /* restore the old context */
        MemoryContextSwitchTo(old_mcxt);
    }
    /* otherwise, retrieve the state */
    else
        pgastate = (PercentileGroupAggState *) PG_GETARG_POINTER(0);

    /* Load the datum into the tuplesort object, but only if it's not null */
    if (!PG_ARGISNULL(1))
    {
        Datum dfloat = DirectFunctionCall1(agtype_to_float8, PG_GETARG_DATUM(1));

        tuplesort_putdatum(pgastate->sortstate, dfloat, false);
        pgastate->number_of_rows++;
    }
    /* return the state */
    PG_RETURN_POINTER(pgastate);
}

/* Code borrowed and adjusted from PG's percentile_cont_final function */
PG_FUNCTION_INFO_V1(age_percentile_cont_aggfinalfn);

Datum age_percentile_cont_aggfinalfn(PG_FUNCTION_ARGS)
{
    PercentileGroupAggState *pgastate;
    float8 percentile;
    int64 first_row = 0;
    int64 second_row = 0;
    Datum val;
    Datum first_val;
    Datum second_val;
    double proportion;
    bool isnull;
    agtype_value agtv_float;

    /* verify we are in an aggregate context */
    Assert(AggCheckCallContext(fcinfo, NULL) == AGG_CONTEXT_AGGREGATE);

    /* If there were no regular rows, the result is NULL */
    if (PG_ARGISNULL(0))
        PG_RETURN_NULL();

    /* retrieve the state and percentile */
    pgastate = (PercentileGroupAggState *) PG_GETARG_POINTER(0);
    percentile = pgastate->percentile;

    /* number_of_rows could be zero if we only saw NULL input values */
    if (pgastate->number_of_rows == 0)
        PG_RETURN_NULL();

    /* Finish the sort, or rescan if we already did */
    if (!pgastate->sort_done)
    {
        tuplesort_performsort(pgastate->sortstate);
        pgastate->sort_done = true;
    }
    else
        tuplesort_rescan(pgastate->sortstate);

    /* calculate the percentile cont*/
    first_row = floor(percentile * (pgastate->number_of_rows - 1));
    second_row = ceil(percentile * (pgastate->number_of_rows - 1));

    Assert(first_row < pgastate->number_of_rows);

    if (!tuplesort_skiptuples(pgastate->sortstate, first_row, true))
        elog(ERROR, "missing row in percentile_cont");

    if (!tuplesort_getdatum(pgastate->sortstate, true, &first_val, &isnull, NULL))
        elog(ERROR, "missing row in percentile_cont");
    if (isnull)
        PG_RETURN_NULL();

    if (first_row == second_row)
    {
        val = first_val;
    }
    else
    {
        if (!tuplesort_getdatum(pgastate->sortstate, true, &second_val, &isnull, NULL))
            elog(ERROR, "missing row in percentile_cont");

        if (isnull)
            PG_RETURN_NULL();

        proportion = (percentile * (pgastate->number_of_rows - 1)) - first_row;
        val = float8_lerp(first_val, second_val, proportion);
    }

    /* convert to an agtype float and return the result */
    agtv_float.type = AGTV_FLOAT;
    agtv_float.val.float_value = DatumGetFloat8(val);

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_float));
}

/* Code borrowed and adjusted from PG's percentile_disc_final function */
PG_FUNCTION_INFO_V1(age_percentile_disc_aggfinalfn);

Datum age_percentile_disc_aggfinalfn(PG_FUNCTION_ARGS)
{
    PercentileGroupAggState *pgastate;
    double percentile;
    Datum val;
    bool isnull;
    int64 rownum;
    agtype_value agtv_float;

    Assert(AggCheckCallContext(fcinfo, NULL) == AGG_CONTEXT_AGGREGATE);

    /* If there were no regular rows, the result is NULL */
    if (PG_ARGISNULL(0))
        PG_RETURN_NULL();

    pgastate = (PercentileGroupAggState *) PG_GETARG_POINTER(0);
    percentile = pgastate->percentile;

    /* number_of_rows could be zero if we only saw NULL input values */
    if (pgastate->number_of_rows == 0)
        PG_RETURN_NULL();

    /* Finish the sort, or rescan if we already did */
    if (!pgastate->sort_done)
    {
        tuplesort_performsort(pgastate->sortstate);
        pgastate->sort_done = true;
    }
    else
        tuplesort_rescan(pgastate->sortstate);

    /*----------
     * We need the smallest K such that (K/N) >= percentile.
     * N>0, therefore K >= N*percentile, therefore K = ceil(N*percentile).
     * So we skip K-1 rows (if K>0) and return the next row fetched.
     *----------
     */
    rownum = (int64) ceil(percentile * pgastate->number_of_rows);
    Assert(rownum <= pgastate->number_of_rows);

    if (rownum > 1)
    {
        if (!tuplesort_skiptuples(pgastate->sortstate, rownum - 1, true))
            elog(ERROR, "missing row in percentile_disc");
    }

    if (!tuplesort_getdatum(pgastate->sortstate, true, &val, &isnull, NULL))
        elog(ERROR, "missing row in percentile_disc");

    /* We shouldn't have stored any nulls, but do the right thing anyway */
    if (isnull)
        PG_RETURN_NULL();

    /* convert to an agtype float and return the result */
    agtv_float.type = AGTV_FLOAT;
    agtv_float.val.float_value = DatumGetFloat8(val);

    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_float));
}

/* functions to support the aggregate function COLLECT() */
PG_FUNCTION_INFO_V1(age_collect_aggtransfn);

Datum age_collect_aggtransfn(PG_FUNCTION_ARGS)
{
    agtype_in_state *castate;
    int nargs;
    Datum *args;
    bool *nulls;
    Oid *types;
    MemoryContext old_mcxt;

    /* verify we are in an aggregate context */
    Assert(AggCheckCallContext(fcinfo, NULL) == AGG_CONTEXT_AGGREGATE);

    /*
     * Switch to the correct aggregate context. Otherwise, the data added to the
     * array will be lost.
     */
    old_mcxt = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);

    /* if this is the first invocation, create the state */
    if (PG_ARGISNULL(0))
    {
        /* create and initialize the state */
        castate = palloc0(sizeof(agtype_in_state));
        memset(castate, 0, sizeof(agtype_in_state));

        /* start the array */
        castate->res = push_agtype_value(&castate->parse_state,
                                         WAGT_BEGIN_ARRAY, NULL);
    }
    /* otherwise, retrieve the state */
    else
    {
        castate = (agtype_in_state *) PG_GETARG_POINTER(0);
    }

    /*
     * Extract the variadic args, of which there should only be one.
     * Insert the arg into the array, unless it is null. Nulls are
     * skipped over.
     */
    if (PG_ARGISNULL(1))
    {
        nargs = 0;
    }
    else
    {
        nargs = extract_variadic_args(fcinfo, 1, true, &args, &types, &nulls);
    }

    if (nargs == 1)
    {
        /* only add non null values */
        if (nulls[0] == false)
        {
            agtype_value *agtv_value = NULL;

            /* we need to check for agtype null and skip it, if found */
            if (types[0] == AGTYPEOID)
            {
                agtype *agt_arg;

                /* get the agtype argument */
                agt_arg = DATUM_GET_AGTYPE_P(args[0]);

                /* get the scalar value */
                if (AGTYPE_CONTAINER_IS_SCALAR(&agt_arg->root))
                {
                    agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);
                }
            }

            /* skip the arg if agtype null */
            if (agtv_value == NULL || agtv_value->type != AGTV_NULL)
            {
                add_agtype(args[0], nulls[0], castate, types[0], false);
            }
        }
    }
    else if (nargs > 1)
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("collect() invalid number of arguments")));
    }

    /* restore the old context */
    MemoryContextSwitchTo(old_mcxt);

    /* return the state */
    PG_RETURN_POINTER(castate);
}

PG_FUNCTION_INFO_V1(age_collect_aggfinalfn);

Datum age_collect_aggfinalfn(PG_FUNCTION_ARGS)
{
    agtype_in_state *castate;
    MemoryContext old_mcxt;

    /* verify we are in an aggregate context */
    Assert(AggCheckCallContext(fcinfo, NULL) == AGG_CONTEXT_AGGREGATE);
    /*
     * Get the state. There are cases where the age_collect_aggtransfn never
     * gets called. So, check to see if this is one.
     */
    if (PG_ARGISNULL(0))
    {
        /* create and initialize the state */
        castate = palloc0(sizeof(agtype_in_state));
        memset(castate, 0, sizeof(agtype_in_state));
        /* start the array */
        castate->res = push_agtype_value(&castate->parse_state,
                                         WAGT_BEGIN_ARRAY, NULL);
    }
    else
    {
        castate = (agtype_in_state *) PG_GETARG_POINTER(0);
    }
    /* switch to the correct aggregate context */
    old_mcxt = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
    /* Finish/close the array */
    castate->res = push_agtype_value(&castate->parse_state, WAGT_END_ARRAY,
                                     NULL);
    /* restore the old context */
    MemoryContextSwitchTo(old_mcxt);
    /* return the agtype array */
    PG_RETURN_POINTER(agtype_value_to_agtype(castate->res));
}

/* helper function to quickly build an agtype_value vertex */
agtype_value *agtype_value_build_vertex(graphid id, char *label,
                                        Datum properties)
{
    agtype_in_state result;

    /* the label can't be NULL */
    Assert(label != NULL);

    memset(&result, 0, sizeof(agtype_in_state));

    /* push in the object beginning */
    result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
                                   NULL);

    /* push the graph id key/value pair */
    result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
                                   string_to_agtype_value("id"));
    result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
                                   integer_to_agtype_value(id));

    /* push the label key/value pair */
    result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
                                   string_to_agtype_value("label"));
    result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
                                   string_to_agtype_value(label));

    /* push the properties key/value pair */
    result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
                                   string_to_agtype_value("properties"));
    add_agtype((Datum)properties, false, &result, AGTYPEOID, false);

    /* push in the object end */
    result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT, NULL);

    /* set it as an edge */
    result.res->type = AGTV_VERTEX;

    /* return the result that was build (allocated) inside the result */
    return result.res;
}

/* helper function to quickly build an agtype_value edge */
agtype_value *agtype_value_build_edge(graphid id, char *label, graphid end_id,
                                      graphid start_id, Datum properties)
{
    agtype_in_state result;

    /* the label can't be NULL */
    Assert(label != NULL);

    memset(&result, 0, sizeof(agtype_in_state));

    /* push in the object beginning */
    result.res = push_agtype_value(&result.parse_state, WAGT_BEGIN_OBJECT,
                                   NULL);
    /* push the graph id key/value pair */
    result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
                                   string_to_agtype_value("id"));
    result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
                                   integer_to_agtype_value(id));

    /* push the label key/value pair */
    result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
                                   string_to_agtype_value("label"));
    result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
                                   string_to_agtype_value(label));

    /* push the end_id key/value pair */
    result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
                                   string_to_agtype_value("end_id"));
    result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
                                   integer_to_agtype_value(end_id));

    /* push the start_id key/value pair */
    result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
                                   string_to_agtype_value("start_id"));
    result.res = push_agtype_value(&result.parse_state, WAGT_VALUE,
                                   integer_to_agtype_value(start_id));

    /* push the properties key/value pair */
    result.res = push_agtype_value(&result.parse_state, WAGT_KEY,
                                   string_to_agtype_value("properties"));
    add_agtype((Datum)properties, false, &result, AGTYPEOID, false);

    /* push in the object end */
    result.res = push_agtype_value(&result.parse_state, WAGT_END_OBJECT, NULL);

    /* set it as an edge */
    result.res->type = AGTV_EDGE;

    /* return the result that was build (allocated) inside the result */
    return result.res;
}

/*
 * Extract an agtype_value from an agtype and optionally verify that it is of
 * the correct type. It will always complain if the passed argument is not a
 * scalar.
 *
 * Optionally, the function will throw an error, stating the calling function
 * name, for invalid values - including AGTV_NULL
 *
 * Note: This only works for scalars wrapped in an array container, not
 * in objects.
 */
agtype_value *get_agtype_value(char *funcname, agtype *agt_arg,
                               enum agtype_value_type type, bool error)
{
    agtype_value *agtv_value = NULL;

    /* we need these */
    Assert(funcname != NULL);
    Assert(agt_arg != NULL);

    /* error if the argument is not a scalar */
    if (!AGTYPE_CONTAINER_IS_SCALAR(&agt_arg->root))
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("%s: agtype argument must be a scalar",
                        funcname)));
    }

    /* is it AGTV_NULL? */
    if (error && is_agtype_null(agt_arg))
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("%s: agtype argument must not be AGTV_NULL",
                        funcname)));
    }

    /* get the agtype value */
    agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    /* is it the correct type? */
    if (error && agtv_value->type != type)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("%s: agtype argument of wrong type",
                        funcname)));
    }
    return agtv_value;
}

/*
 * Returns properties of an entity (vertex or edge) or NULL if there are none.
 * If the object passed is not a scalar, an error is thrown.
 * If the object is a scalar and error_on_scalar is false, the scalar is
 * returned, otherwise an error is thrown.
 */
agtype_value *extract_entity_properties(agtype *object, bool error_on_scalar)
{
    agtype_value *scalar_value = NULL;
    agtype_value *return_value = NULL;

    if (!AGT_ROOT_IS_SCALAR(object))
    {
        ereport(ERROR,(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                       errmsg("expected a scalar value")));
    }

    /* unpack the scalar */
    scalar_value = get_ith_agtype_value_from_container(&object->root, 0);

    /* get the properties depending on the type or fail */
    if (scalar_value->type == AGTV_VERTEX)
    {
        return_value = &scalar_value->val.object.pairs[2].value;
    }
    else if (scalar_value->type == AGTV_EDGE)
    {
        return_value = &scalar_value->val.object.pairs[4].value;
    }
    else if (scalar_value->type == AGTV_PATH)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("cannot extract properties from an agtype path")));
    }
    else if (error_on_scalar)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("scalar object must be a vertex or edge")));
    }
    else
    {
        return_value = scalar_value;
    }

    /* if the properties are NULL, return NULL */
    if (return_value == NULL || return_value->type == AGTV_NULL)
    {
        return NULL;
    }

    /* set the object_value to the property_value. */
    return return_value;
}

PG_FUNCTION_INFO_V1(age_eq_tilde);
/*
 * Execution function for =~ aka regular expression comparisons
 *
 * Note: Everything must resolve to 2 agtype strings. All others types are
 * errors.
 */
Datum age_eq_tilde(PG_FUNCTION_ARGS)
{
    agtype *agt_string = NULL;
    agtype *agt_pattern = NULL;

    /* if either are NULL return NULL */
    if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
    {
        PG_RETURN_NULL();
    }

    /* extract the input */
    agt_string = AG_GET_ARG_AGTYPE_P(0);
    agt_pattern = AG_GET_ARG_AGTYPE_P(1);

    /* they both need to scalars */
    if (AGT_ROOT_IS_SCALAR(agt_string) && AGT_ROOT_IS_SCALAR(agt_pattern))
    {
        agtype_value *agtv_string;
        agtype_value *agtv_pattern;

        /* get the contents of each container */
        agtv_string = get_ith_agtype_value_from_container(&agt_string->root, 0);
        agtv_pattern = get_ith_agtype_value_from_container(&agt_pattern->root,
                                                           0);
        /* if either are agtype null, return NULL */
        if (agtv_string->type == AGTV_NULL ||
            agtv_pattern->type == AGTV_NULL)
        {
            PG_RETURN_NULL();
        }

        /* only strings can be compared, all others are errors */
        if (agtv_string->type == AGTV_STRING &&
            agtv_pattern->type == AGTV_STRING)
        {
            text *string = NULL;
            text *pattern = NULL;
            Datum result;

            string = cstring_to_text_with_len(agtv_string->val.string.val,
                                              agtv_string->val.string.len);
            pattern = cstring_to_text_with_len(agtv_pattern->val.string.val,
                                               agtv_pattern->val.string.len);

            result = (DirectFunctionCall2Coll(textregexeq, C_COLLATION_OID,
                                              PointerGetDatum(string),
                                              PointerGetDatum(pattern)));
            return boolean_to_agtype(DatumGetBool(result));
        }
    }
    /* if we got here we have values that are invalid */
    ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                    errmsg("agtype string values expected")));
}

/*
 * Helper function to step through and retrieve keys from an object.
 * borrowed and modified from get_next_object_pair() in agtype_vle.c
 */
static agtype_iterator *get_next_object_key(agtype_iterator *it,
                                             agtype_container *agtc,
                                             agtype_value *key)
{
    agtype_iterator_token itok;
    agtype_value tmp;

    /* verify input params */
    Assert(agtc != NULL);
    Assert(key != NULL);

    /* check to see if the container is empty */
    if (AGTYPE_CONTAINER_SIZE(agtc) == 0)
    {
        return NULL;
    }

    /* if the passed iterator is NULL, this is the first time, create it */
    if (it == NULL)
    {
        /* initial the iterator */
        it = agtype_iterator_init(agtc);
        /* get the first token */
        itok = agtype_iterator_next(&it, &tmp, false);
        /* it should be WAGT_BEGIN_OBJECT */
        Assert(itok == WAGT_BEGIN_OBJECT);
    }

    /* the next token should be a key or the end of the object */
    itok = agtype_iterator_next(&it, &tmp, false);
    Assert(itok == WAGT_KEY || WAGT_END_OBJECT);
    /* if this is the end of the object return NULL */
    if (itok == WAGT_END_OBJECT)
    {
        return NULL;
    }

    /* this should be the key, copy it */
    if (itok == WAGT_KEY)
    {
        *key = tmp;
    }

    /*
     * The next token should be a value but, it could be a begin tokens for
     * arrays or objects. For those we just return NULL to ignore them.
     */
    itok = agtype_iterator_next(&it, &tmp, true);
    Assert(itok == WAGT_VALUE);

    /* return the iterator */
    return it;
}

PG_FUNCTION_INFO_V1(age_keys);
/*
 * Execution function to implement openCypher keys() function
 */
Datum age_keys(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_result = NULL;
    agtype_value obj_key = {0};
    agtype_iterator *it = NULL;
    agtype_parse_state *parse_state = NULL;

    /* check for null */
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }

    //needs to be a map, node, or relationship
    agt_arg = AG_GET_ARG_AGTYPE_P(0);

    /*
     * check for a scalar object. edges and vertexes are scalar, objects are not
     * scalar and will be handled separately
     */
    if (AGT_ROOT_IS_SCALAR(agt_arg))
    {
        agtv_result = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* is it an agtype null, return null if it is */
        if (agtv_result->type == AGTV_NULL)
            PG_RETURN_NULL();

        /* check for proper agtype and extract the properties field */
        if (agtv_result->type == AGTV_EDGE ||
            agtv_result->type == AGTV_VERTEX)
        {
            agtv_result = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_result,
                                                        "properties");

            Assert(agtv_result != NULL);
            Assert(agtv_result->type = AGTV_OBJECT);
        }
        else
        {
            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                    errmsg("keys() argument must be a vertex, edge, object or null")));
        }

        agt_arg = agtype_value_to_agtype(agtv_result);
        agtv_result = NULL;
    }
    else if (!AGT_ROOT_IS_OBJECT(agt_arg))
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                errmsg("keys() argument must be a vertex, edge, object or null")));
    }

    /* push the beginning of the array */
    agtv_result = push_agtype_value(&parse_state, WAGT_BEGIN_ARRAY, NULL);

    /* populate the array with keys */
    while ((it = get_next_object_key(it, &agt_arg->root, &obj_key)))
    {
        agtv_result = push_agtype_value(&parse_state, WAGT_ELEM, &obj_key);
    }

    /* push the end of the array*/
    agtv_result = push_agtype_value(&parse_state, WAGT_END_ARRAY, NULL);

    Assert(agtv_result != NULL);
    Assert(agtv_result->type = AGTV_ARRAY);

    PG_RETURN_POINTER(agtype_value_to_agtype(agtv_result));
}

PG_FUNCTION_INFO_V1(age_nodes);
/*
 * Execution function to implement openCypher nodes() function
 */
Datum age_nodes(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_path = NULL;
    agtype_in_state agis_result;
    int i = 0;

    /* check for null */
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }

    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for a scalar object */
    if (!AGT_ROOT_IS_SCALAR(agt_arg))
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("nodes() argument must resolve to a scalar value")));
    }

    /* get the potential path out of the array */
    agtv_path = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    /* is it an agtype null? */
    if (agtv_path->type == AGTV_NULL)
    {
            PG_RETURN_NULL();
    }

    /* verify that it is an agtype path */
    if (agtv_path->type != AGTV_PATH)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("nodes() argument must be a path")));

    /* clear the result structure */
    MemSet(&agis_result, 0, sizeof(agtype_in_state));

    /* push the beginning of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_BEGIN_ARRAY, NULL);
    /* push in each vertex (every other entry) from the path */
    for (i = 0; i < agtv_path->val.array.num_elems; i += 2)
    {
        agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM,
                                            &agtv_path->val.array.elems[i]);
    }

    /* push the end of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_END_ARRAY, NULL);

    /* convert the agtype_value to a datum to return to the caller */
    PG_RETURN_POINTER(agtype_value_to_agtype(agis_result.res));
}

PG_FUNCTION_INFO_V1(age_labels);
/*
 * Execution function to implement openCypher labels() function
 *
 * NOTE:
 *
 * This function is defined to return NULL on NULL input. So, no need to check
 * for SQL NULL input.
 */
Datum age_labels(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_temp = NULL;
    agtype_value *agtv_label = NULL;
    agtype_in_state agis_result;

    /* get the vertex argument */
    agt_arg = AG_GET_ARG_AGTYPE_P(0);

    /* verify it is a scalar */
    if (!AGT_ROOT_IS_SCALAR(agt_arg))
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("labels() argument must resolve to a scalar value")));
    }

    /* is it an agtype null? */
    if (AGTYPE_CONTAINER_IS_SCALAR(&agt_arg->root) &&
        AGTE_IS_NULL((&agt_arg->root)->children[0]))
    {
        PG_RETURN_NULL();
    }

    /* get the potential vertex */
    agtv_temp = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    /* verify that it is an agtype vertex */
    if (agtv_temp->type != AGTV_VERTEX)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("labels() argument must be a vertex")));
    }

    /* get the label from the vertex */
    agtv_label = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_temp, "label");
    /* it cannot be NULL */
    Assert(agtv_label != NULL);

    /* clear the result structure */
    MemSet(&agis_result, 0, sizeof(agtype_in_state));

    /* push the beginning of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_BEGIN_ARRAY, NULL);

    /* push in the label */
    agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM,
                                        agtv_label);

    /* push the end of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_END_ARRAY, NULL);

    /* convert the agtype_value to a datum to return to the caller */
    PG_RETURN_POINTER(agtype_value_to_agtype(agis_result.res));
}

PG_FUNCTION_INFO_V1(age_relationships);
/*
 * Execution function to implement openCypher relationships() function
 */
Datum age_relationships(PG_FUNCTION_ARGS)
{
    agtype *agt_arg = NULL;
    agtype_value *agtv_path = NULL;
    agtype_in_state agis_result;
    int i = 0;

    /* check for null */
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }

    agt_arg = AG_GET_ARG_AGTYPE_P(0);
    /* check for a scalar object */
    if (!AGT_ROOT_IS_SCALAR(agt_arg))
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("relationships() argument must resolve to a scalar value")));
    }

    /* get the potential path out of the array */
    agtv_path = get_ith_agtype_value_from_container(&agt_arg->root, 0);

    /* is it an agtype null? */
    if (agtv_path->type == AGTV_NULL)
    {
            PG_RETURN_NULL();
    }

    /* verify that it is an agtype path */
    if (agtv_path->type != AGTV_PATH)
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("relationships() argument must be a path")));

    /* clear the result structure */
    MemSet(&agis_result, 0, sizeof(agtype_in_state));

    /* push the beginning of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_BEGIN_ARRAY, NULL);
    /* push in each edge (every other entry) from the path */
    for (i = 1; i < agtv_path->val.array.num_elems; i += 2)
    {
        agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM,
                                            &agtv_path->val.array.elems[i]);
    }

    /* push the end of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_END_ARRAY, NULL);

    /* convert the agtype_value to a datum to return to the caller */
    PG_RETURN_POINTER(agtype_value_to_agtype(agis_result.res));
}

/*
 * Helper function to convert an integer type (PostgreSQL or agtype) datum into
 * an int64. The function will flag if an agtype null was found. The function
 * will error out on invalid information, printing out the funcname passed.
 */
static int64 get_int64_from_int_datums(Datum d, Oid type, char *funcname,
                                       bool *is_agnull)
{
    int64 result = 0;

    /* test for PG integer types */
    if (type == INT2OID)
    {
        result = (int64) DatumGetInt16(d);
    }
    else if (type == INT4OID)
    {
        result = (int64) DatumGetInt32(d);
    }
    else if (type == INT8OID)
    {
        result = (int64) DatumGetInt64(d);
    }
    /* test for agtype integer */
    else if (type == AGTYPEOID)
    {
        agtype *agt_arg = NULL;
        agtype_value *agtv_value = NULL;
        agtype_container *agtc = NULL;

        /* get the agtype argument */
        agt_arg = DATUM_GET_AGTYPE_P(d);

        if (!AGT_ROOT_IS_SCALAR(agt_arg))
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("%s() only supports scalar arguments", funcname)));
        }
        /* check for agtype null*/
        agtc = &agt_arg->root;
        if (AGTE_IS_NULL(agtc->children[0]))
        {
            *is_agnull = true;
            return 0;
        }

        /* extract it from the scalar array */
        agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);

        /* check for agtype integer */
        if (agtv_value->type == AGTV_INTEGER)
        {
            result = agtv_value->val.int_value;
        }
        else
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("%s() unsupported argument type", funcname)));
        }
    }
    else
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("%s() unsupported argument type", funcname)));
    }

    /* return the result */
    *is_agnull = false;
    return result;
}

PG_FUNCTION_INFO_V1(age_range);
/*
 * Execution function to implement openCypher range() function
 */
Datum age_range(PG_FUNCTION_ARGS)
{
    Datum *args = NULL;
    bool *nulls = NULL;
    Oid *types = NULL;
    int nargs;
    int64 start_idx = 0;
    int64 end_idx = 0;
    /* step defaults to 1 */
    int64 step = 1;
    bool is_agnull = false;
    agtype_in_state agis_result;
    int64 i = 0;

    /* get the arguments */
    nargs = extract_variadic_args(fcinfo, 0, false, &args, &types, &nulls);

    /* throw an error if the number of args is not the expected number */
    if (nargs != 2 && nargs != 3)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("range(): invalid number of input parameters")));
    }

    /* check for NULL start and end input */
    if (nulls[0] || nulls[1])
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("range(): neither start or end can be NULL")));
    }

    /* get the start index */
    start_idx = get_int64_from_int_datums(args[0], types[0], "range",
                                          &is_agnull);
    if (is_agnull)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("range(): start cannot be NULL")));
    }

    /* get the end index */
    end_idx = get_int64_from_int_datums(args[1], types[1], "range", &is_agnull);
    if (is_agnull)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("range(): end cannot be NULL")));
    }

    /* get the step */
    if (nargs == 3 && !nulls[2])
    {
        step = get_int64_from_int_datums(args[2], types[2], "range",
                                         &is_agnull);
        if (is_agnull)
        {
            step = 1;
        }
    }

    /* the step cannot be zero */
    if (step == 0)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("range(): step cannot be zero")));
    }

    /* clear the result structure */
    MemSet(&agis_result, 0, sizeof(agtype_in_state));

    /* push the beginning of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_BEGIN_ARRAY, NULL);

    /* push in each agtype integer in the range */
    for (i = start_idx;
         (step > 0 && i <= end_idx) || (step < 0 && i >= end_idx);
         i += step)
    {
        agtype_value agtv;

        /* build the integer */
        agtv.type = AGTV_INTEGER;
        agtv.val.int_value = i;
        /* add the value to the array */
        agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM,
                                            &agtv);
    }

    /* push the end of the array */
    agis_result.res = push_agtype_value(&agis_result.parse_state,
                                        WAGT_END_ARRAY, NULL);

    /* convert the agtype_value to a datum to return to the caller */
    PG_RETURN_POINTER(agtype_value_to_agtype(agis_result.res));
}

PG_FUNCTION_INFO_V1(age_unnest);
/*
 * Function to convert the Array type of Agtype into each row. It is used for
 * Cypher `UNWIND` clause.
 */
Datum age_unnest(PG_FUNCTION_ARGS)
{
    agtype *agtype_arg = NULL;
    ReturnSetInfo *rsi;
    Tuplestorestate *tuple_store;
    TupleDesc tupdesc;
    TupleDesc ret_tdesc;
    MemoryContext old_cxt, tmp_cxt;
    bool skipNested = false;
    agtype_iterator *it;
    agtype_value v;
    agtype_iterator_token r;

    // check for null
    if (PG_ARGISNULL(0))
    {
        PG_RETURN_NULL();
    }

    agtype_arg = AG_GET_ARG_AGTYPE_P(0);
    if (!AGT_ROOT_IS_ARRAY(agtype_arg))
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("cannot extract elements from an object")));
    }

    rsi = (ReturnSetInfo *) fcinfo->resultinfo;

    rsi->returnMode = SFRM_Materialize;

    /* it's a simple type, so don't use get_call_result_type() */
    tupdesc = rsi->expectedDesc;

    old_cxt = MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory);

    ret_tdesc = CreateTupleDescCopy(tupdesc);
    BlessTupleDesc(ret_tdesc);
    tuple_store =
            tuplestore_begin_heap(rsi->allowedModes & SFRM_Materialize_Random,
                                  false, work_mem);

    MemoryContextSwitchTo(old_cxt);

    tmp_cxt = AllocSetContextCreate(CurrentMemoryContext,
                                    "age_unnest temporary cxt",
                                    ALLOCSET_DEFAULT_SIZES);

    it = agtype_iterator_init(&agtype_arg->root);

    while ((r = agtype_iterator_next(&it, &v, skipNested)) != WAGT_DONE)
    {
        skipNested = true;

        if (r == WAGT_ELEM)
        {
            HeapTuple tuple;
            Datum values[1];
            bool nulls[1] = {false};
            agtype *val = agtype_value_to_agtype(&v);

            /* use the tmp context so we can clean up after each tuple is done */
            old_cxt = MemoryContextSwitchTo(tmp_cxt);

            values[0] = PointerGetDatum(val);

            tuple = heap_form_tuple(ret_tdesc, values, nulls);

            tuplestore_puttuple(tuple_store, tuple);

            /* clean up and switch back */
            MemoryContextSwitchTo(old_cxt);
            MemoryContextReset(tmp_cxt);
        }
    }

    MemoryContextDelete(tmp_cxt);

    rsi->setResult = tuple_store;
    rsi->setDesc = ret_tdesc;

    PG_RETURN_NULL();
}

/*
 * Volatile wrapper replacement. The previous version was PL/SQL
 * and could only handle AGTYPE input and returned AGTYPE output.
 * This version will create the appropriate AGTYPE based off of
 * the input type.
 */
PG_FUNCTION_INFO_V1(agtype_volatile_wrapper);

Datum agtype_volatile_wrapper(PG_FUNCTION_ARGS)
{
    int nargs = PG_NARGS();
    Oid type = InvalidOid;
    bool isnull = PG_ARGISNULL(0);

    /* check for null and pass it through */
    if (isnull)
    {
        PG_RETURN_NULL();
    }

    /* check for more than one argument */
    if (nargs > 1)
    {
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("agtype_volatile_wrapper: too many args")));

    }

    /* get the type of the input argument */
    type = get_fn_expr_argtype(fcinfo->flinfo, 0);

    /* if it is NOT an AGTYPE, we need convert it to one, if possible */
    if (type != AGTYPEOID)
    {
        agtype_value agtv_result;
        Datum arg = PG_GETARG_DATUM(0);

        /* check for PG types that easily translate to AGTYPE */
        if (type == BOOLOID)
        {
            agtv_result.type = AGTV_BOOL;
            agtv_result.val.boolean = DatumGetBool(arg);
        }
        else if (type == INT2OID || type == INT4OID || type == INT8OID)
        {
            agtv_result.type = AGTV_INTEGER;

            if (type == INT8OID)
            {
                agtv_result.val.int_value = DatumGetInt64(arg);
            }
            else if (type == INT4OID)
            {
                agtv_result.val.int_value = (int64) DatumGetInt32(arg);
            }
            else if (type == INT2OID)
            {
                agtv_result.val.int_value = (int64) DatumGetInt16(arg);
            }
        }
        else if (type == FLOAT4OID || type == FLOAT8OID)
        {
            agtv_result.type = AGTV_FLOAT;

            if (type == FLOAT8OID)
            {
                agtv_result.val.float_value = DatumGetFloat8(arg);
            }
            else if (type == FLOAT4OID)
            {
                agtv_result.val.float_value = (float8) DatumGetFloat4(arg);
            }
        }
        else if (type == NUMERICOID)
        {
            agtv_result.type = AGTV_NUMERIC;
            agtv_result.val.numeric = DatumGetNumeric(arg);
        }
        else if (type == CSTRINGOID)
        {
            agtv_result.type = AGTV_STRING;
            agtv_result.val.string.val = DatumGetCString(arg);
            agtv_result.val.string.len = strlen(agtv_result.val.string.val);
        }
        else if (type == TEXTOID)
        {
            agtv_result.type = AGTV_STRING;
            agtv_result.val.string.val = text_to_cstring(DatumGetTextPP(arg));
            agtv_result.val.string.len = strlen(agtv_result.val.string.val);
        }
        else
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("agtype_volatile_wrapper: unsupported arg type")));
        }

        /* return the built result */
        PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
    }

    /* otherwise, just pass it through */
    PG_RETURN_POINTER(PG_GETARG_DATUM(0));
}
