Ejemplo n.º 1
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");
}
Ejemplo n.º 2
0
fs_value fn_str(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) && FS_IS_BNODE(a.rid)) {
        return fs_value_error(FS_ERROR_INVALID_TYPE, NULL);
    }

    if (a.lex) {
	return fs_value_plain(a.lex);
    }

    fs_value v = fs_value_plain(NULL);
    a = fs_value_fill_lexical(q, a);
    v.lex = a.lex;

    return v;
}
Ejemplo n.º 3
0
fs_value fn_cast(fs_query *q, fs_value v, fs_value d)
{
#if 0
printf("CAST ");
fs_value_print(v);
printf(" -> ");
fs_value_print(d);
printf("\n");
#endif
    if (FS_IS_URI(d.rid) && FS_IS_LITERAL(v.rid)) {
	return fn_cast_intl(q, v, d.rid);
    }
    if (d.rid == fs_c.xsd_string && FS_IS_URI(v.rid)) {
        fs_value v2 = fn_cast_intl(q, v, d.rid);
        v2.rid = fs_hash_literal(v.lex, d.rid);
	return v2;
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, "cast on URI/bNode");
}
Ejemplo n.º 4
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)) 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.º 5
0
fs_value fn_compare(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 ((FS_IS_LITERAL(a.attr) && FS_IS_LITERAL(b.attr)) ||
	(a.attr == fs_c.empty && b.attr == fs_c.empty)) {
	if (a.lex && b.lex) {
	    int diff = strcmp(a.lex, b.lex);
	    if (diff > 0) {
		return fs_value_integer(1);
	    } else if (diff < 0) {
		return fs_value_integer(-1);
	    }
	    return fs_value_integer(0);
	}
    } else if (a.attr == fs_c.xsd_string && b.attr == fs_c.xsd_string) {
	if (a.lex && b.lex) {
	    int diff = strcmp(a.lex, b.lex);
	    if (diff > 0) {
		return fs_value_integer(1);
	    } else if (diff < 0) {
		return fs_value_integer(-1);
	    }
	    return fs_value_integer(0);
	}
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, "bad arguments to fn:compare");
}
Ejemplo n.º 6
0
fs_value fn_numeric_add(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 0
fs_value_print(a);
printf(" P+ ");
fs_value_print(b);
printf("\n");
#endif

    if (a.attr == b.attr && a.attr != FS_RID_NULL && a.attr != fs_c.empty) {
	fs_value v = fs_value_blank();
	v.attr = a.attr;
	if (a.attr == fs_c.xsd_double || a.attr == fs_c.xsd_float) {
	    v.fp = a.fp + b.fp;
	    v.valid = fs_valid_bit(FS_V_FP);

	    return v;
	} else if (a.attr == fs_c.xsd_decimal) {
            fs_decimal_add(&a.de, &b.de, &v.de);
	    v.valid = fs_valid_bit(FS_V_DE);

	    return v;
	} else if (a.attr == fs_c.xsd_integer) {
	    v.in = a.in + b.in;
	    v.valid = fs_valid_bit(FS_V_IN);

	    return v;
	}
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, "non-numeric arguments to fn:add");
}
Ejemplo n.º 7
0
fs_value fs_value_fill_lexical(fs_query *q, fs_value a)
{
    if (a.lex) {
	return a;
    }	
    if (a.valid & fs_valid_bit(FS_V_FP)) {
	a.lex = g_strdup_printf("%f", a.fp);
        fs_query_add_freeable(q, a.lex);

	return a;
    }
    if (a.valid & fs_valid_bit(FS_V_DE)) {
	a.lex = fs_decimal_to_lex(&a.de);
        fs_query_add_freeable(q, a.lex);

	return a;
    }
    if (a.valid & fs_valid_bit(FS_V_IN)) {
	if (a.attr == fs_c.xsd_integer) {
	    a.lex = g_strdup_printf("%lld", (long long)a.in);
            fs_query_add_freeable(q, a.lex);

	    return a;
	}

	if (a.attr == fs_c.xsd_datetime) {
	    struct tm t;
	    time_t clock = a.in;
	    gmtime_r(&clock, &t);
	    a.lex = g_strdup_printf("%04d-%02d-%02dT%02d:%02d:%02d", 
		    t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
		    t.tm_hour, t.tm_min, t.tm_sec);
            fs_query_add_freeable(q, a.lex);

	    return a;
	}
    }

    return fs_value_error(FS_ERROR_INVALID_TYPE, "bad lexical cast");
}
Ejemplo n.º 8
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);
}
Ejemplo n.º 9
0
fs_value fn_timezone(fs_query *q, fs_value v)
{
    return fs_value_error(FS_ERROR_INVALID_TYPE, "TIMEZONE() function not suported");
}
Ejemplo n.º 10
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);
}