Пример #1
0
fs_value fn_greater_than_equal(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;
    }

    /* 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_less_than(q, a, b));

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

    if (FS_IS_URI_BN(a.rid) || FS_IS_URI_BN(b.rid))
        return fs_value_boolean(0);

    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);
}
Пример #2
0
fs_value fn_numeric_equal(fs_query *q, fs_value a, fs_value b)
{
#if 0
fs_value_print(a);
printf(" ");
fs_value_print(b);
printf("\n");
#endif
    a = fs_value_promote(q, a, b);
    b = fs_value_promote(q, b, a);

    if (a.attr == b.attr && a.attr != FS_RID_NULL && a.attr != fs_c.empty) {
	if (a.attr == fs_c.xsd_double || a.attr == fs_c.xsd_float) {
	    return fs_value_boolean(a.fp == b.fp);
	}
	if (a.attr == fs_c.xsd_decimal) {
	    return fs_value_boolean(fs_decimal_equal(&a.de, &b.de));
	}
	if (a.attr == fs_c.xsd_integer) {
	    return fs_value_boolean(a.in == b.in);
	}
	if (a.attr == fs_c.xsd_boolean) {
	    return fs_value_boolean((a.in ? 1 : 0) == (b.in ? 1 : 0));
	}
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, "non-numeric arguments to fn:numeric-equal");
}
Пример #3
0
fs_value fs_value_resource(fs_query *q, fs_resource *r)
{
    fs_value v = fs_value_blank();

    v.lex = r->lex;

    if (r->rid == FS_RID_NULL) {
	return fs_value_rid(FS_RID_NULL);
    } if (r->attr == fs_c.xsd_integer) {
        v = fn_cast_intl(q, v, fs_c.xsd_integer);
    } else if (r->attr == fs_c.xsd_float || r->attr == fs_c.xsd_double) {
        v = fn_cast_intl(q, v, fs_c.xsd_double);
    } else if (r->attr == fs_c.xsd_decimal) {
        v = fn_cast_intl(q, v, fs_c.xsd_decimal);
    } else if (r->attr == fs_c.xsd_boolean) {
	if (!strcmp(r->lex, "true") || !strcmp(r->lex, "1")) {
	    v = fs_value_boolean(1);
	} else {
	    v = fs_value_boolean(0);
	}
    } else if (r->attr == fs_c.xsd_datetime) {
	v = fs_value_datetime_from_string(r->lex);
    }
    if (fs_is_error(v)) {
        v = fs_value_blank();
        v.lex = r->lex;
    }

    v.rid = r->rid;
    v.attr = r->attr;
    v.valid |= fs_valid_bit(FS_V_RID) | fs_valid_bit(FS_V_ATTR);

    return v;
}
Пример #4
0
fs_value fn_lang_matches(fs_query *q, fs_value l, fs_value p)
{
    if (fs_is_error(l)) {
	return l;
    }
    if (fs_is_error(p)) {
	return p;
    }
    if (l.valid & fs_valid_bit(FS_V_RID) && l.rid == FS_RID_NULL) {
        return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
    }

    if (l.lex && l.lex[0] == '\0') {
        return fs_value_boolean(0);
    }

    if (p.lex && p.lex[0] == '*' && p.lex[1] == '\0') {
	return fs_value_boolean(1);
    }

    if (l.lex && p.lex) {
        /* TODO implement RFC3066 */
        return fs_value_boolean(!strncasecmp(l.lex, p.lex, strlen(p.lex)));
    }

    return fs_value_boolean(0);
}
Пример #5
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);
}
Пример #6
0
fs_value fn_numeric_less_than(fs_query *q, fs_value a, fs_value b)
{
    a = fs_value_promote(q, a, b);
    b = fs_value_promote(q, b, a);
#if 0
fs_value_print(a);
printf(" < ");
fs_value_print(b);
printf("\n");
#endif

    if (a.attr == b.attr && a.attr != FS_RID_NULL && a.attr != fs_c.empty) {
	if (a.attr == fs_c.xsd_double || a.attr == fs_c.xsd_float) {
	    return fs_value_boolean(a.fp < b.fp);
	}
	if (a.attr == fs_c.xsd_decimal) {
	    return fs_value_boolean(fs_decimal_less_than(&a.de, &b.de));
	}
	if (a.attr == fs_c.xsd_integer) {
	    return fs_value_boolean(a.in < b.in);
	}
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, "non-numeric arguments to fn:numeric-less-than");
}
Пример #7
0
fs_value fn_is_literal(fs_query *q, fs_value a)
{
    if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return a;
    }
    if (a.valid & fs_valid_bit(FS_V_RID)) {
	return fs_value_boolean(FS_IS_LITERAL(a.rid));
    }

    return fs_value_boolean(a.attr != FS_RID_NULL);
}
Пример #8
0
fs_value fn_bound(fs_query *q, fs_value a)
{
    if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return a;
    }
    if (a.valid & fs_valid_bit(FS_V_RID)) {
	return fs_value_boolean(a.rid != FS_RID_NULL);
    }

    return fs_value_boolean(1);
}
Пример #9
0
fs_value fn_datetime_greater_than(fs_query *q, fs_value a, fs_value b)
{
    if (a.attr == fs_c.xsd_datetime && b.attr == fs_c.xsd_datetime &&
        (a.in != -1 || b.in != -1))
	return fs_value_boolean(a.in > b.in);

    if (a.lex && b.lex) {
        return fs_value_boolean(iso8601_compare(a.lex, b.lex) == 1);
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, "bad arguments to fn:datetime-greater-than");
}
Пример #10
0
fs_value fn_is_blank(fs_query *q, fs_value a)
{
    if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return a;
    }
    if (a.valid & fs_valid_bit(FS_V_RID)) {
	if (a.rid == FS_RID_NULL) return fs_value_boolean(0);
	
	return fs_value_boolean(FS_IS_BNODE(a.rid));
    }

    return fs_value_boolean(0);
}
Пример #11
0
fs_value fn_is_iri(fs_query *q, fs_value a)
{
    if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return a;
    }
    if (a.valid & fs_valid_bit(FS_V_RID)) {
	return fs_value_boolean(FS_IS_URI(a.rid));
    }
    if (a.attr == FS_RID_NULL) {
	return fs_value_boolean(1);
    }

    return fs_value_boolean(0);
}
Пример #12
0
fs_value fn_datetime_equal(fs_query *q, fs_value a, fs_value b)
{
    if (a.attr == fs_c.xsd_datetime && b.attr == fs_c.xsd_datetime)
	return fs_value_boolean(a.in == b.in);

    return fs_value_error(FS_ERROR_INVALID_TYPE, "bad arguments to fn:datetime-equal");
}
Пример #13
0
fs_value fn_datetime_greater_than(fs_query *q, fs_value a, fs_value b)
{
    if (a.attr == fs_c.xsd_datetime && b.attr == fs_c.xsd_datetime)
	return fs_value_boolean(a.in > b.in);

    return fs_value_error(FS_ERROR_INVALID_TYPE, "bad arguments to fn:datetime-greater-than");
}
Пример #14
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));
}
Пример #15
0
fs_value fn_strends(fs_query *q, fs_value arg1, fs_value arg2)
{
    if (!fs_is_plain_or_string(arg1) || !fs_is_plain_or_string(arg2)) {
        return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
    }
    arg1 = fs_value_fill_lexical(q, arg1);
    arg2 = fs_value_fill_lexical(q, arg2);

    const int a1l = strlen(arg1.lex);
    const int a2l = strlen(arg2.lex);

    if (a2l > a1l) {
        return fs_value_boolean(0);
    }

    return fs_value_boolean(strncmp(arg1.lex + a1l - a2l, arg2.lex, a2l) == 0);
}
Пример #16
0
fs_value fn_datetime_less_than(fs_query *q, fs_value a, fs_value b)
{
#if 0
fs_value_print(a);
printf(" < ");
fs_value_print(b);
printf(" [dT]\n");
#endif
    if (a.attr == fs_c.xsd_datetime && b.attr == fs_c.xsd_datetime &&
        (a.in != -1 || b.in != -1))
	return fs_value_boolean(a.in < b.in);

    if (a.lex && b.lex) {
        return fs_value_boolean(iso8601_compare(a.lex, b.lex) == -1);
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, "bad arguments to fn:datetime-less-than");
}
Пример #17
0
fs_value fn_contains(fs_query *q, fs_value arg1, fs_value arg2)
{
    if (!fs_is_plain_or_string(arg1) || !fs_is_plain_or_string(arg2)) {
        return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
    }
    arg1 = fs_value_fill_lexical(q, arg1);
    arg2 = fs_value_fill_lexical(q, arg2);

    return fs_value_boolean(strstr(arg1.lex, arg2.lex) != NULL);
}
Пример #18
0
fs_value fn_numeric_greater_than(fs_query *q, fs_value a, fs_value b)
{
    a = fs_value_promote(q, a, b);
    b = fs_value_promote(q, b, a);

    if (a.attr == b.attr && a.attr != FS_RID_NULL && a.attr != fs_c.empty) {
	if (a.attr == fs_c.xsd_double || a.attr == fs_c.xsd_float) {
	    return fs_value_boolean(a.fp > b.fp);
	}
	if (a.attr == fs_c.xsd_decimal) {
	    return fs_value_boolean(fs_decimal_greater_than(&a.de, &b.de));
	}
	if (a.attr == fs_c.xsd_integer) {
	    return fs_value_boolean(a.in > b.in);
	}
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, "non-numeric arguments to fn:numeric-greater-than");
}
Пример #19
0
fs_value fn_rdfterm_equal(fs_query *q, fs_value a, fs_value b)
{
    if (fs_is_error(a)) {
	return a;
    }
    if (fs_is_error(b)) {
	return b;
    }

    return fs_value_boolean(fs_value_equal(a, b));
}
Пример #20
0
fs_value fn_datetime_less_than(fs_query *q, fs_value a, fs_value b)
{
#if 0
fs_value_print(a);
printf(" < ");
fs_value_print(b);
printf(" [dT]\n");
#endif
    if (a.attr == fs_c.xsd_datetime && b.attr == fs_c.xsd_datetime)
	return fs_value_boolean(a.in < b.in);

    return fs_value_error(FS_ERROR_INVALID_TYPE, "bad arguments to fn:datetime-less-than");
}
Пример #21
0
fs_value fn_ebv(fs_value a)
{
    if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return a;
    }
    if (a.rid == FS_RID_NULL) {
	return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
    }
    if (a.attr == fs_c.xsd_boolean || a.attr == fs_c.xsd_integer) {
	return fs_value_boolean(a.in);
    }
    if (a.attr == fs_c.xsd_double || a.attr == fs_c.xsd_float) {
	return fs_value_boolean(fabs(a.fp) != 0.0);
    }
    if (a.attr == fs_c.xsd_decimal) {
	return fs_value_boolean(!fs_decimal_equal(&a.de, fs_decimal_zero));
    }
    if (a.lex && (a.attr == fs_c.xsd_string || a.attr == fs_c.empty)) {
	return fs_value_boolean(a.lex && a.lex[0]);
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
}
Пример #22
0
fs_value fn_logical_or(fs_query *q, fs_value a, fs_value b)
{
    fs_value ea = fn_ebv(a), eb = fn_ebv(b);

    if (!ea.in && fs_is_error(b)) {
	return b;
    } else if (!eb.in && fs_is_error(a)) {
	return a;
    } else if (fs_is_error(a) && fs_is_error(b)) {
	return a;
    }

    return fs_value_boolean(ea.in || eb.in);
}
Пример #23
0
fs_value fn_not(fs_query *q, fs_value a)
{
#if 0
printf("! ");
fs_value_print(a);
printf("\n");
#endif
    if (fs_is_error(a)) {
	return a;
    }
    if (a.valid & fs_valid_bit(FS_V_RID) && a.rid == FS_RID_NULL) {
	return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
    }

    fs_value ebv = fn_ebv(a);

    if (fs_is_error(ebv)) {
	return ebv;
    }

    return fs_value_boolean(!ebv.in);
}
Пример #24
0
fs_value fn_matches(fs_query *q, fs_value str, fs_value pat, fs_value flags)
{
    if (str.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return str;
    }
    if (pat.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return pat;
    }
    if (flags.valid & fs_valid_bit(FS_V_TYPE_ERROR)) {
	return flags;
    }

    if (!str.lex || !pat.lex) {
	return fs_value_error(FS_ERROR_INVALID_TYPE,
                              "argument to fn:matches has no lexical value");
    }

    if (str.valid & fs_valid_bit(FS_V_RID) && FS_IS_URI(str.rid)) {
	return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
    }
#if 0
printf("REGEX ");
fs_value_print(str);
printf(", ");
fs_value_print(pat);
printf(", ");
fs_value_print(flags);
printf("\n");
#endif

    int reflags = PCRE_UTF8;
    if (flags.lex) {
	for (char *c = flags.lex; *c; c++) {
	    switch (*c) {
		case 's':
		    reflags |= PCRE_DOTALL;
		    break;
		case 'm':
		    reflags |= PCRE_MULTILINE;
		    break;
		case 'i':
		    reflags |= PCRE_CASELESS;
		    break;
		case 'x':
		    reflags |= PCRE_EXTENDED;
		    break;
		default:
		    fs_error(LOG_ERR, "unknown regex flag '%c'", *c);
		    return fs_value_error(FS_ERROR_INVALID_TYPE, "unrecognised flag in fn:matches");
	    }
	}
    }

    const char *error;
    int erroroffset;
    pcre *re = pcre_compile(pat.lex, reflags, &error, &erroroffset, NULL);
    if (!re) {
        return fs_value_error(FS_ERROR_INVALID_TYPE, error);
    }
    int rc = pcre_exec(re, NULL, str.lex, strlen(str.lex), 0, 0, NULL, 0);
    if (rc == PCRE_ERROR_NOMATCH) {
	return fs_value_boolean(0);
    }
    if (rc < 0) {
        fs_error(LOG_ERR, "internal error %d in pcre_exec", rc);

	return fs_value_error(FS_ERROR_INVALID_TYPE, "internal error in fn:matches");
    }

    return fs_value_boolean(1);
}