in src/backend/utils/adt/agtype_util.c [1732:1873]
int compare_agtype_scalar_values(agtype_value *a, agtype_value *b)
{
if (a->type == b->type)
{
switch (a->type)
{
case AGTV_NULL:
return 0;
case AGTV_STRING:
{
/* varstr_cmp isn't guaranteed to return 1, 0, -1 */
int result = varstr_cmp(a->val.string.val, a->val.string.len,
b->val.string.val, b->val.string.len,
DEFAULT_COLLATION_OID);
if (result > 0)
{
return 1;
}
else if (result < 0)
{
return -1;
}
else
{
return 0;
}
}
case AGTV_NUMERIC:
return DatumGetInt32(DirectFunctionCall2(
numeric_cmp, PointerGetDatum(a->val.numeric),
PointerGetDatum(b->val.numeric)));
case AGTV_BOOL:
if (a->val.boolean == b->val.boolean)
{
return 0;
}
else if (a->val.boolean > b->val.boolean)
{
return 1;
}
else
{
return -1;
}
case AGTV_INTEGER:
if (a->val.int_value == b->val.int_value)
{
return 0;
}
else if (a->val.int_value > b->val.int_value)
{
return 1;
}
else
{
return -1;
}
case AGTV_FLOAT:
return compare_two_floats_orderability(a->val.float_value,
b->val.float_value);
case AGTV_VERTEX:
case AGTV_EDGE:
{
agtype_value *a_id, *b_id;
graphid a_graphid, b_graphid;
a_id = GET_AGTYPE_VALUE_OBJECT_VALUE(a, "id");
b_id = GET_AGTYPE_VALUE_OBJECT_VALUE(b, "id");
a_graphid = a_id->val.int_value;
b_graphid = b_id->val.int_value;
if (a_graphid == b_graphid)
{
return 0;
}
else if (a_graphid > b_graphid)
{
return 1;
}
else
{
return -1;
}
}
case AGTV_PATH:
{
int i;
if (a->val.array.num_elems != b->val.array.num_elems)
return a->val.array.num_elems > b->val.array.num_elems ? 1 : -1;
for (i = 0; i < a->val.array.num_elems; i++)
{
agtype_value a_elem, b_elem;
int res;
a_elem = a->val.array.elems[i];
b_elem = b->val.array.elems[i];
res = compare_agtype_scalar_values(&a_elem, &b_elem);
if (res)
{
return res;
}
}
return 0;
}
default:
ereport(ERROR, (errmsg("invalid agtype scalar type %d for compare",
a->type)));
}
}
/* check for integer compared to float */
if (a->type == AGTV_INTEGER && b->type == AGTV_FLOAT)
{
return compare_two_floats_orderability((float8)a->val.int_value,
b->val.float_value);
}
/* check for float compared to integer */
if (a->type == AGTV_FLOAT && b->type == AGTV_INTEGER)
{
return compare_two_floats_orderability(a->val.float_value,
(float8)b->val.int_value);
}
/* check for integer or float compared to numeric */
if (is_numeric_result(a, b))
{
Datum numd, lhsd, rhsd;
lhsd = get_numeric_datum_from_agtype_value(a);
rhsd = get_numeric_datum_from_agtype_value(b);
numd = DirectFunctionCall2(numeric_cmp, lhsd, rhsd);
return DatumGetInt32(numd);
}
ereport(ERROR, (errmsg("agtype input scalar type mismatch")));
return -1;
}