Ejemplo n.º 1
0
fs_value fn_less_than_equal(fs_query *q, fs_value a, fs_value b)
{
#if 0
fs_value_print(a);
printf(" <= ");
fs_value_print(b);
printf("\n");
#endif
    if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return a;
    }
    if (b.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return b;
    }

    /* URIs and bNodes don't compare */
    if (FS_IS_URI_BN(a.rid) || FS_IS_URI_BN(b.rid)) {
        return fs_value_boolean(0);
    }

    /* If it's simply the same term it must be <= itsself */
    fs_value term_eq = fn_rdfterm_equal(q, a, b);
    if (term_eq.in == 1) {
        return term_eq;
    }

    if (a.attr == fs_c.xsd_datetime && b.attr == fs_c.xsd_datetime) return fn_not(q, fn_datetime_greater_than(q, a, b));
    if (fs_is_numeric(&a) && fs_is_numeric(&b)) return fn_logical_or(q, fn_numeric_less_than(q, a, b), fn_numeric_equal(q, a, b));

    if (a.lex && b.lex)
        return fn_not(q, fn_numeric_equal(q, fn_compare(q, a, b), fs_value_integer(1)));

    return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
}
Ejemplo n.º 2
0
fs_value fn_equal(fs_query *q, fs_value a, fs_value b)
{
#if 0
fs_value_print(a);
printf(" = ");
fs_value_print(b);
printf("\n");
#endif
    if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return a;
    }
    if (b.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return b;
    }

    fs_value term_equal = fn_rdfterm_equal(q, a, b);
    if (term_equal.in == 1) {
        return term_equal;
    }

    if (a.attr == fs_c.xsd_datetime)
        return fn_datetime_equal(q, a, b);
    if (fs_is_numeric(&a) && fs_is_numeric(&b))
        return fn_numeric_equal(q, a, b);

    if (FS_IS_LITERAL(a.rid) && FS_IS_LITERAL(b.rid) &&
        (a.attr == fs_c.empty || a.attr == fs_c.xsd_string) &&
        (b.attr == fs_c.empty || b.attr == fs_c.xsd_string)) {
        return fs_value_boolean(!strcmp(a.lex, b.lex));
    }

    return fs_value_boolean(0);
}
Ejemplo n.º 3
0
fs_value fs_value_promote(fs_query *q, fs_value a, fs_value b)
{
    if (!fs_is_numeric(&a) || !fs_is_numeric(&b)) {
        return fs_value_error(FS_ERROR_INVALID_TYPE,
                                "cannot promote non-numeric value");
    }
    if (a.attr == b.attr) {
	return a;
    }

    if (a.attr == fs_c.xsd_double || b.attr == fs_c.xsd_double) {
	if (a.attr != fs_c.xsd_double) {
	    a = fn_cast_intl(q, a, fs_c.xsd_double);
	}

	return a;
    }
    if (a.attr == fs_c.xsd_float || b.attr == fs_c.xsd_float) {
	if (a.attr != fs_c.xsd_float) {
	    a = fn_cast_intl(q, a, fs_c.xsd_float);
	}

	return a;
    }
    if (a.attr == fs_c.xsd_decimal || b.attr == fs_c.xsd_decimal) {
	if (a.attr != fs_c.xsd_decimal) {
	    a.valid |= fs_valid_bit(FS_V_DE);
	    if (a.attr == fs_c.xsd_integer || a.attr == fs_c.xsd_boolean) {
                fs_decimal_init_from_int64(&a.de, a.in);
	    } else {
		fs_error(LOG_ERR, "cannot convert type for dt %lld", a.attr);
                fs_decimal_init_from_int64(&a.de, 0);
	    }
	    a.attr = fs_c.xsd_decimal;
	}

	return a;
    }
    if (a.attr == fs_c.xsd_integer || b.attr == fs_c.xsd_integer) {
	if (a.attr != fs_c.xsd_integer) {
            if (a.valid & fs_valid_bit(FS_V_IN)) {
                a.attr = fs_c.xsd_integer;
            } else {
                fs_error(LOG_ERR, "cannot convert type for dt %lld", a.attr);
                a.in = 0;
            }
        }

	return a;
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
}
Ejemplo n.º 4
0
fs_value fn_numeric_abs(fs_query *q, fs_value a)
{
    if (!fs_is_numeric(&a)) {
        return fs_value_error(FS_ERROR_INVALID_TYPE, "non-numeric arguments to fn:abs");
    }

    if (a.attr == fs_c.xsd_double || a.attr == fs_c.xsd_float) {
        a.fp = fabs(a.fp);
    } else if (a.attr == fs_c.xsd_decimal) {
        if (fs_decimal_less_than(&a.de, fs_decimal_zero)) {
            fs_decimal_negate(&a.de, &a.de);
        }
    } else if (a.attr == fs_c.xsd_integer) {
        if (a.in < 0) {
            a.in = -a.in;
        }
    } else {
        return fs_value_error(FS_ERROR_INVALID_TYPE, "bad arguments to fn:abs");
    }

    if (a.lex != NULL) {
        a.lex = NULL;
    }

    return a;
}
Ejemplo n.º 5
0
fs_value fn_not_equal(fs_query *q, fs_value a, fs_value b)
{
#if 0
fs_value_print(a);
printf(" != ");
fs_value_print(b);
printf("\n");
#endif
    if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return a;
    }
    if (b.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return b;
    }

    if (a.attr == fs_c.xsd_datetime)
        return fn_not(q, fn_datetime_equal(q, a, b));

    if (fs_is_numeric(&a) && fs_is_numeric(&b))
        return fn_not(q, fn_numeric_equal(q, a, b));

    if ((a.attr == fs_c.empty || a.attr == fs_c.xsd_string) &&
        (b.attr == fs_c.empty || b.attr == fs_c.xsd_string)) {
        return fs_value_boolean(strcmp(a.lex, b.lex));
    }

    if ((FS_IS_URI_BN(a.rid) && FS_IS_LITERAL(b.rid)) ||
        (FS_IS_LITERAL(a.rid) && FS_IS_URI_BN(b.rid))) {
        /* ones a URI/bNode and ones a literal, definatly different */
        return fs_value_boolean(1);
    }

    if ((!FS_IS_URI(a.rid) && a.attr != fs_c.empty && FS_IS_LITERAL(a.attr) &&
         !FS_IS_LITERAL(b.attr)) ||
        (!FS_IS_URI(a.rid) && !FS_IS_LITERAL(a.attr) && b.attr != fs_c.empty &&
         FS_IS_LITERAL(b.attr))) {
        /* one has a lang tag and one doesn't, definatly different */
        return fs_value_boolean(1);
    }

    if (FS_IS_URI(a.attr) || FS_IS_URI(b.attr)) {
        /* at least one argument has an unknown datatype */
        return fs_value_boolean(0);
    }

    return fn_not(q, fn_rdfterm_equal(q, a, b));
}
Ejemplo n.º 6
0
fs_value fn_greater_than(fs_query *q, fs_value a, fs_value b)
{
    if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return a;
    }
    if (b.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return b;
    }

    if (a.attr == fs_c.xsd_datetime && b.attr == fs_c.xsd_datetime)
        return fn_datetime_greater_than(q, a, b);
    if (fs_is_numeric(&a) && fs_is_numeric(&b)) 
        return fn_numeric_greater_than(q, a, b);
    if (a.lex && b.lex)
        return fn_numeric_equal(q, fn_compare(q, a, b), fs_value_integer(1));

    return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
}
Ejemplo n.º 7
0
fs_value fn_substring(fs_query *q, fs_value str, fs_value start, fs_value length)
{
    if (!fs_is_plain_or_string(str)) {
        return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
    }
    if (!fs_is_numeric(&start)) {
        return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
    }
    start = cast_integer(start);
    /* 2 arg form */
    if (length.rid == FS_RID_NULL) {
        length = fs_value_integer(INT_MAX);
    } else {
        if (!fs_is_numeric(&length)) {
            return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
        }
        length = cast_integer(length);
    }
    str = fs_value_fill_lexical(q, str);
    const int slen = g_utf8_strlen(str.lex, -1);
    if (start.in > slen || length.in <= 0) {
        fs_value ret = fs_value_plain("");
        ret.attr = str.attr;

        return ret;
    }
    gchar *spos = g_utf8_offset_to_pointer(str.lex, start.in - 1);
    int retlen_utf8 = g_utf8_strlen(spos, -1);
    if (retlen_utf8 > length.in) {
        retlen_utf8 = length.in;
    }
    gchar *epos = g_utf8_offset_to_pointer(spos, retlen_utf8);
    int retlen_bytes = epos - spos + 1;
    char *retstr = g_malloc(retlen_bytes+1);
    retstr[retlen_bytes] = '\0';
    g_utf8_strncpy(retstr, spos, retlen_utf8);
    fs_query_add_freeable(q, retstr);
    fs_value ret = fs_value_plain(retstr);
    ret.attr = str.attr;

    return ret;
}
Ejemplo n.º 8
0
fs_value fn_plus(fs_query *q, fs_value a)
{
#if 0
fs_value_print(a);
#endif
    if (fs_is_numeric(&a)) {
        return a;
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, "bad arguments to fn:plus");
}
Ejemplo n.º 9
0
fs_value fn_less_than(fs_query *q, fs_value a, fs_value b)
{
    if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return a;
    }
    if (b.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return b;
    }
#if 0
fs_value_print(a);
printf(" < ");
fs_value_print(b);
printf("\n");
#endif

    if (a.attr == fs_c.xsd_datetime && b.attr == fs_c.xsd_datetime) return fn_datetime_less_than(q, a, b);
    if (fs_is_numeric(&a) && fs_is_numeric(&b))
        return fn_numeric_less_than(q, a, b);
    if (a.lex && b.lex) return fn_numeric_equal(q, fn_compare(q, a, b), fs_value_integer(-1));

    return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
}
Ejemplo n.º 10
0
Archivo: filter.c Proyecto: rafl/4store
fs_value fn_minus(fs_query *q, fs_value a)
{
    if (fs_is_numeric(&a)) {
	if (a.attr == fs_c.xsd_double || a.attr == fs_c.xsd_float) {
	    a.fp = -a.fp;
	} else if (a.attr == fs_c.xsd_decimal) {
            fs_decimal_negate(&a.de, &a.de);
	} else if (a.attr == fs_c.xsd_integer) {
	    a.in = -a.in;
	} else {
	    return fs_value_error(FS_ERROR_INVALID_TYPE, "bad arguments to fn:minus");
	}

	return a;
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, "non-numeric arguments to fn:minus");
}