in src/backend/utils/adt/age_vle.c [1987:2120]
Datum age_match_vle_edge_to_id_qual(PG_FUNCTION_ARGS)
{
int nargs = 0;
Datum *args = NULL;
bool *nulls = NULL;
Oid *types = NULL;
agtype *agt_arg_vpc = NULL;
agtype *edge_id = NULL;
agtype *pos_agt = NULL;
agtype_value *id, *position;
VLE_path_container *vle_path = NULL;
graphid *array = NULL;
bool vle_is_on_left = false;
graphid gid = 0;
/* extract argument values */
nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
if (nargs != 3)
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("age_match_vle_edge_to_id_qual() invalid number of arguments")));
}
/* the arguments cannot be NULL */
if (nulls[0] || nulls[1] || nulls[2])
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("age_match_vle_edge_to_id_qual() arguments must be non NULL")));
}
/* get the VLE_path_container argument */
agt_arg_vpc = DATUM_GET_AGTYPE_P(args[0]);
if (!AGT_ROOT_IS_BINARY(agt_arg_vpc) ||
AGT_ROOT_BINARY_FLAGS(agt_arg_vpc) != AGT_FBINARY_TYPE_VLE_PATH)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("argument 1 of age_match_vle_edge_to_edge_qual must be a VLE_Path_Container")));
}
/* cast argument as a VLE_Path_Container and extract graphid array */
vle_path = (VLE_path_container *)agt_arg_vpc;
array = GET_GRAPHID_ARRAY_FROM_CONTAINER(vle_path);
if (types[1] == AGTYPEOID)
{
/* Get the edge id we are checking the end of the list too */
edge_id = AG_GET_ARG_AGTYPE_P(1);
if (!AGT_ROOT_IS_SCALAR(edge_id))
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("argument 2 of age_match_vle_edge_to_edge_qual must be an integer")));
}
id = get_ith_agtype_value_from_container(&edge_id->root, 0);
if (id->type != AGTV_INTEGER)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("argument 2 of age_match_vle_edge_to_edge_qual must be an integer")));
}
gid = id->val.int_value;
}
else if (types[1] == GRAPHIDOID)
{
gid = DATUM_GET_GRAPHID(args[1]);
}
else
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("match_vle_terminal_edge() argument 1 must be an agtype integer or a graphid")));
}
pos_agt = AG_GET_ARG_AGTYPE_P(2);
if (!AGT_ROOT_IS_SCALAR(pos_agt))
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("argument 3 of age_match_vle_edge_to_edge_qual must be an integer")));
}
position = get_ith_agtype_value_from_container(&pos_agt->root, 0);
if (position->type != AGTV_BOOL)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("argument 3 of age_match_vle_edge_to_edge_qual must be an integer")));
}
vle_is_on_left = position->val.boolean;
if (vle_is_on_left)
{
int array_size = vle_path->graphid_array_size;
/*
* Path is like ...[vle_edge]-()-[regular_edge]... Get the graphid of
* the vertex at the endof the path and check that it matches the id
* that was passed in the second arg. The transform logic is responsible
* for making that the start or end id, depending on its direction.
*/
if (gid != array[array_size - 1])
{
PG_RETURN_BOOL(false);
}
PG_RETURN_BOOL(true);
}
else
{
/*
* Path is like ...[edge]-()-[vle_edge]... Get the vertex at the start
* of the vle edge and check against id.
*/
if (gid != array[0])
{
PG_RETURN_BOOL(false);
}
PG_RETURN_BOOL(true);
}
}