Datum _ag_enforce_edge_uniqueness()

in src/backend/utils/adt/age_vle.c [2437:2618]


Datum _ag_enforce_edge_uniqueness(PG_FUNCTION_ARGS)
{
    HTAB *exists_hash = NULL;
    HASHCTL exists_ctl;
    Datum *args = NULL;
    bool *nulls = NULL;
    Oid *types = NULL;
    int nargs = 0;
    int i = 0;

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

    /* verify the arguments */
    for (i = 0; i < nargs; i++)
    {
        if (nulls[i])
        {
             ereport(ERROR,
                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                      errmsg("_ag_enforce_edge_uniqueness argument %d must not be NULL",
                             i)));
        }
        if (types[i] != AGTYPEOID &&
            types[i] != INT8OID &&
            types[i] != GRAPHIDOID)
        {
             ereport(ERROR,
                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                      errmsg("_ag_enforce_edge_uniqueness argument %d must be AGTYPE, INT8, or GRAPHIDOID",
                             i)));
        }
    }

    /* configure the hash table */
    MemSet(&exists_ctl, 0, sizeof(exists_ctl));
    exists_ctl.keysize = sizeof(int64);
    exists_ctl.entrysize = sizeof(int64);
    exists_ctl.hash = tag_hash;

    /* create exists_hash table */
    exists_hash = hash_create(EXISTS_HTAB_NAME, EXISTS_HTAB_NAME_INITIAL_SIZE,
                              &exists_ctl, HASH_ELEM | HASH_FUNCTION);

    /* insert arguments into hash table */
    for (i = 0; i < nargs; i++)
    {
        /* if it is an INT8OID or a GRAPHIDOID */
        if (types[i] == INT8OID || types[i] == GRAPHIDOID)
        {
            graphid edge_id = 0;
            bool found = false;
            int64 *value = NULL;

            edge_id = DatumGetInt64(args[i]);

            /* insert the edge_id */
            value = (int64 *)hash_search(exists_hash, (void *)&edge_id,
                                         HASH_ENTER, &found);

            /* if we found it, we're done, we have a duplicate */
            if (found)
            {
                hash_destroy(exists_hash);
                PG_RETURN_BOOL(false);
            }
            /* otherwise, add it to the returned bucket */
            else
            {
                *value = edge_id;
            }

            continue;
        }
        else if (types[i] == AGTYPEOID)
        {
            /* get the argument */
            agtype *agt_i = DATUM_GET_AGTYPE_P(args[i]);

            /* if the argument is an AGTYPE VLE_path_container */
            if (AGT_ROOT_IS_BINARY(agt_i) &&
                AGT_ROOT_BINARY_FLAGS(agt_i) == AGT_FBINARY_TYPE_VLE_PATH)
            {
                VLE_path_container *vpc = NULL;
                graphid *graphid_array = NULL;
                int64 graphid_array_size = 0;
                int64 j = 0;

                /* cast to VLE_path_container */
                vpc = (VLE_path_container *)agt_i;

                /* get the graphid array */
                graphid_array = GET_GRAPHID_ARRAY_FROM_CONTAINER(vpc);

                /* get the graphid array size */
                graphid_array_size = vpc->graphid_array_size;

                /* insert all the edges in the vpc, into the hash table */
                for (j = 1; j < graphid_array_size - 1; j+=2)
                {
                    int64 *value = NULL;
                    bool found = false;
                    graphid edge_id = 0;

                    /* get the edge id */
                    edge_id = graphid_array[j];

                    /* insert the edge id */
                    value = (int64 *)hash_search(exists_hash, (void *)&edge_id,
                                                 HASH_ENTER, &found);

                    /* if we found it, we're done, we have a duplicate */
                    if (found)
                    {
                        hash_destroy(exists_hash);
                        PG_RETURN_BOOL(false);
                    }
                    /* otherwise, add it to the returned bucket */
                    else
                    {
                        *value = edge_id;
                    }
                }
            }
            /* if it is a regular AGTYPE scalar */
            else if (AGT_ROOT_IS_SCALAR(agt_i))
            {
                agtype_value *agtv_id = NULL;
                int64 *value = NULL;
                bool found = false;
                graphid edge_id = 0;

                agtv_id = get_ith_agtype_value_from_container(&agt_i->root, 0);

                if (agtv_id->type != AGTV_INTEGER)
                {
                    ereport(ERROR,
                            (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                             errmsg("_ag_enforce_edge_uniqueness parameter %d must resolve to an agtype integer",
                                    i)));
                }

                edge_id = agtv_id->val.int_value;

                /* insert the edge_id */
                value = (int64 *)hash_search(exists_hash, (void *)&edge_id,
                                             HASH_ENTER, &found);

                /* if we found it, we're done, we have a duplicate */
                if (found)
                {
                    hash_destroy(exists_hash);
                    PG_RETURN_BOOL(false);
                }
                /* otherwise, add it to the returned bucket */
                else
                {
                    *value = edge_id;
                }
            }
            else
            {
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                         errmsg("_ag_enforce_edge_uniqueness invalid parameter type %d",
                                i)));
            }
        }
        /* it is neither a VLE_path_container, AGTYPE, INT8, or a GRAPHIDOID */
        else
        {
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("_ag_enforce_edge_uniqueness invalid parameter type %d",
                            i)));
        }
    }

    /* if all entries were successfully inserted, we have no duplicates */
    hash_destroy(exists_hash);
    PG_RETURN_BOOL(true);
}