int compare_agtype_scalar_values()

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;
}