fs_value fs_value_datetime_from_string(const char *s) { fs_value v = fs_value_blank(); v.attr = fs_c.xsd_datetime; struct tm td; memset(&td, 0, sizeof(struct tm)); GTimeVal gtime; if (g_time_val_from_iso8601(s, >ime)) { v.in = gtime.tv_sec; v.valid = fs_valid_bit(FS_V_IN); v.lex = (char *)s; return v; } char *ret = strptime(s, "%Y-%m-%d", &td); if (ret) { v.in = timegm(&td); v.valid = fs_valid_bit(FS_V_IN); return v; } return fs_value_error(FS_ERROR_INVALID_TYPE, "cannot convert value to xsd:dateTime"); }
fs_value fn_numeric_divide(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) { fs_value v = fs_value_blank(); if (a.attr == fs_c.xsd_integer) { fs_decimal_init_from_int64(&a.de, a.in); fs_decimal_init_from_int64(&b.de, b.in); a.attr = fs_c.xsd_decimal; } 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) { if (fs_decimal_divide(&a.de, &b.de, &v.de)) { return fs_value_error(FS_ERROR_INVALID_TYPE, "divide by zero"); } v.valid = fs_valid_bit(FS_V_DE); return v; } } return fs_value_error(FS_ERROR_INVALID_TYPE, "non-numeric arguments to fn:numeric-divide"); }
fs_value fn_uri(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)) { fs_value v = fs_value_blank(); v.lex = g_strdup_printf("bnode:b%llx", FS_BNODE_NUM(a.rid)); fs_query_add_freeable(q, v.lex); v.rid = fs_hash_uri_ignore_bnode(v.lex); v.valid = fs_valid_bit(FS_V_RID); v.attr = FS_RID_NULL; return v; } if (a.lex) { return fs_value_uri(a.lex); } a = fs_value_fill_lexical(q, a); fs_value v = fs_value_uri(a.lex); return v; }
fs_value fn_numeric_multiply(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) { 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_multiply(&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:numeric-multiply"); }
fs_value fs_value_error(fs_error e, const char *msg) { fs_value v = fs_value_blank(); v.valid = fs_valid_bit(FS_V_TYPE_ERROR); v.lex = (char *)msg; return v; }
fs_value fs_value_plain(const char *s) { fs_value v = fs_value_blank(); v.attr = fs_c.empty; v.lex = (char *)s; return v; }
fs_value fs_value_string(const char *s) { fs_value v = fs_value_blank(); v.attr = fs_c.xsd_string; v.lex = (char *)s; return v; }
fs_value fs_value_integer(long long i) { fs_value v = fs_value_blank(); v.attr = fs_c.xsd_integer; v.valid = fs_valid_bit(FS_V_IN); v.in = i; return v; }
fs_value fs_value_float(double f) { fs_value v = fs_value_blank(); v.attr = fs_c.xsd_float; v.valid = fs_valid_bit(FS_V_FP); v.fp = f; return v; }
fs_value fs_value_datetime(time_t d) { fs_value v = fs_value_blank(); v.attr = fs_c.xsd_datetime; v.valid = fs_valid_bit(FS_V_IN); v.in = d; return v; }
fs_value fs_value_uri(const char *s) { fs_value v = fs_value_blank(); v.rid = fs_hash_uri(s); v.lex = (char *)s; v.valid = fs_valid_bit(FS_V_RID); v.attr = FS_RID_NULL; return v; }
fs_value fs_value_decimal(double d) { fs_value v = fs_value_blank(); v.attr = fs_c.xsd_decimal; v.valid = fs_valid_bit(FS_V_DE); fs_decimal_init_from_double(&v.de, d); return v; }
fs_value fs_value_rid(fs_rid r) { fs_value v = fs_value_blank(); if (r == FS_RID_GONE) { fs_error(LOG_ERR, "found RID_GONE value, optimiser elimination bug"); r = FS_RID_NULL; } v.rid = r; v.valid = fs_valid_bit(FS_V_RID); return v; }
fs_value fs_value_plain_with_dt(const char *s, const char *d) { fs_value v = fs_value_blank(); if (!d || *d == '\0') { v.attr = fs_c.empty; } else { v.attr = fs_hash_uri(d); } v.lex = (char *)s; return v; }
fs_value fs_value_plain_with_lang(const char *s, const char *l) { fs_value v = fs_value_blank(); if (!l || *l == '\0') { v.attr = fs_c.empty; } else { v.attr = fs_hash_literal(l, 0); } v.lex = (char *)s; return v; }
fs_value fn_bnode(fs_query *q, fs_value a) { a = fs_value_fill_rid(q, a); /* scramble the RID number a bit */ fs_value b = fs_value_blank(); b.rid = a.rid + q->block * 39916801; b.rid += q->row; b.rid += FS_NUM_BNODE(a.rid & ~0xC000000000000000LL); b.valid = fs_valid_bit(FS_V_RID); b.attr = FS_RID_NULL; return b; }
fs_value fs_value_decimal_from_string(const char *s) { fs_value v = fs_value_blank(); int ret = fs_decimal_init_from_str(&v.de, s); if (ret) { return fs_value_error(FS_ERROR_INVALID_TYPE, "cannot convert value to decimal"); } v.attr = fs_c.xsd_decimal; v.valid = fs_valid_bit(FS_V_DE); return v; }
fs_value fs_value_boolean(int b) { fs_value v = fs_value_blank(); v.attr = fs_c.xsd_boolean; v.valid = fs_valid_bit(FS_V_IN); v.in = b ? 1 : 0; if (v.in) { v.lex = "true"; } else { v.lex = "false"; } return v; }
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; if (FS_IS_URI(v.rid) || FS_IS_BNODE(v.rid)) v.attr = fs_c.empty; else v.attr = r->attr; v.valid |= fs_valid_bit(FS_V_RID) | fs_valid_bit(FS_V_ATTR); return v; }
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"); }