void fs_binding_add_vector(fs_binding *b, rasqal_variable *var, fs_rid_vector *vals) { #ifdef DEBUG_BINDING if (!strcmp(DEBUG_BINDING, name)) printf("@@ add_vector("DEBUG_BINDING", %p)\n", vals); #endif fs_binding *bv = fs_binding_get(b, var); if (bv) { fs_rid_vector_append_vector(bv->vals, vals); bv->bound = 1; return; } int i; for (i=0; i < FS_BINDING_MAX_VARS && b[i].name; i++); if (i == FS_BINDING_MAX_VARS) { fs_error(LOG_ERR, "variable limit (%d) exceeded", FS_BINDING_MAX_VARS); return; } /* name wasn't found, add it */ b[i].name = g_strdup((char *)var->name); b[i].vals = fs_rid_vector_copy(vals); b[i].bound = 1; }
void fs_binding_set_used(fs_binding *b, rasqal_variable *var) { #ifdef DEBUG_BINDING if (!strcmp(DEBUG_BINDING, name)) printf("@@ set_used("DEBUG_BINDING")\n"); #endif fs_binding *vb = fs_binding_get(b, var); if (vb) { vb->used = 1; } else { fs_error(LOG_ERR, "tried to set 'used' on unknown varaible %s", var->name); } }
int fs_binding_set_expression(fs_binding *b, rasqal_variable *var, rasqal_expression *ex) { fs_binding *vb = fs_binding_get(b, var); if (vb) { vb->expression = ex; return 0; } fs_error(LOG_ERR, "cannot find varaible %s", var->name); return 1; }
fs_binding *fs_binding_add(fs_binding *b, rasqal_variable *var, fs_rid val, int projected) { #ifdef DEBUG_BINDING if (strcmp(DEBUG_BINDING, name)) printf("@@ add("DEBUG_BINDING", %016llx, %d)\n", val, projected); #endif fs_binding *bv = fs_binding_get(b, var); if (bv) { fs_rid_vector_append(bv->vals, val); bv->bound = 1; bv->proj |= projected; bv->need_val |= projected; return bv; } long i; for (i=0; i < FS_BINDING_MAX_VARS && b[i].name; i++); if (i == FS_BINDING_MAX_VARS) { fs_error(LOG_ERR, "variable limit (%d) exceeded", FS_BINDING_MAX_VARS); return NULL; } b[i].name = g_strdup((char *)var->name); if (val != FS_RID_NULL) { if (b[i].vals) { fs_error(LOG_WARNING, "loosing pointer to rid_vector"); } b[i].vals = fs_rid_vector_new_from_args(1, val); b[i].bound = 1; } else { if (b[i].vals) { fs_error(LOG_WARNING, "loosing pointer to rid_vector"); } b[i].vals = fs_rid_vector_new(0); } b[i].proj = projected; b[i].need_val = projected; var->user_data = (void *)i; return b+i; }
/* returns true if the expression has bound values, or nothing does */ int fs_opt_is_bound(fs_binding *b, rasqal_literal *l) { if (!l) return 0; switch (l->type) { case RASQAL_LITERAL_VARIABLE: { if (fs_binding_length(b) == 0) { return 1; } fs_binding *bv = fs_binding_get(b, l->value.variable); if (bv && bv->bound == 1) { return 1; } return 0; } case RASQAL_LITERAL_INTEGER_SUBTYPE: case RASQAL_LITERAL_XSD_STRING: case RASQAL_LITERAL_UDT: case RASQAL_LITERAL_URI: case RASQAL_LITERAL_STRING: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: #if RASQAL_VERSION >= 929 case RASQAL_LITERAL_DATE: #endif return 0; /* we shouldn't find any of these... */ case RASQAL_LITERAL_UNKNOWN: case RASQAL_LITERAL_BLANK: case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_QNAME: return 0; } return 0; }
/* returns true if the expression can be hashed */ int fs_opt_is_const(fs_binding *b, rasqal_literal *l) { if (!l) return 0; switch (l->type) { #if RASQAL_VERSION >= 917 case RASQAL_LITERAL_XSD_STRING: case RASQAL_LITERAL_UDT: #endif case RASQAL_LITERAL_URI: case RASQAL_LITERAL_STRING: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: return 1; case RASQAL_LITERAL_VARIABLE: { char *vname = (char *)l->value.variable->name; fs_binding *bv = fs_binding_get(b, vname); if (bv && bv->bound == 1) { return 1; } return 0; } /* we shouldn't find any of these... */ case RASQAL_LITERAL_UNKNOWN: case RASQAL_LITERAL_BLANK: case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_QNAME: return 0; } return 0; }
fs_rid fs_binding_get_val(fs_binding *b, rasqal_variable *var, int idx, int *bound) { #ifdef DEBUG_BINDING if (!strcmp(DEBUG_BINDING, name)) printf("@@ get_val("DEBUG_BINDING", %d)\n", idx); #endif fs_binding *bv = fs_binding_get(b, var); if (!bv) { if (bound) *bound = 0; return FS_RID_NULL; } if (!bv->need_val) return FS_RID_GONE; if (bound) *bound = bv->bound; if (!bv->bound) { return FS_RID_NULL; } if (idx >= 0 && idx < bv->vals->length) { return bv->vals->data[idx]; } fs_error(LOG_ERR, "val request out of range for variable '%s'", var->name); return FS_RID_NULL; }
/* returns the number of values for the expression, or INT_MAX if its unbound */ int fs_opt_num_vals(fs_binding *b, rasqal_literal *l) { if (!l) return 0; switch (l->type) { case RASQAL_LITERAL_XSD_STRING: case RASQAL_LITERAL_UDT: case RASQAL_LITERAL_URI: case RASQAL_LITERAL_STRING: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_INTEGER_SUBTYPE: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: return 1; case RASQAL_LITERAL_VARIABLE: { char *vname = (char *)l->value.variable->name; fs_binding *bv = fs_binding_get(b, vname); if (bv && bv->bound == 1) { return bv->vals->length; } return INT_MAX; } /* we shouldn't find any of these */ case RASQAL_LITERAL_UNKNOWN: case RASQAL_LITERAL_BLANK: case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_QNAME: return 0; } return INT_MAX; }
static int update_op(struct update_context *ct) { fs_rid_vector *vec[4]; switch (ct->op->type) { case RASQAL_UPDATE_TYPE_UNKNOWN: add_message(ct, "Unknown update operation", 0); return 1; case RASQAL_UPDATE_TYPE_CLEAR: fs_clear(ct, (char *)raptor_uri_as_string(ct->op->graph_uri)); return 0; case RASQAL_UPDATE_TYPE_CREATE: return 0; case RASQAL_UPDATE_TYPE_DROP: fs_clear(ct, (char *)raptor_uri_as_string(ct->op->graph_uri)); return 0; case RASQAL_UPDATE_TYPE_LOAD: fs_load(ct, (char *)raptor_uri_as_string(ct->op->document_uri), (char *)raptor_uri_as_string(ct->op->graph_uri)); return 0; case RASQAL_UPDATE_TYPE_UPDATE: break; } fs_hash_freshen(); raptor_sequence *todel = NULL; raptor_sequence *toins = NULL; if (ct->op->where) { todel = raptor_new_sequence(NULL, NULL); toins = raptor_new_sequence(NULL, NULL); raptor_sequence *todel_p = raptor_new_sequence(NULL, NULL); raptor_sequence *toins_p = raptor_new_sequence(NULL, NULL); raptor_sequence *vars = raptor_new_sequence(NULL, NULL); fs_query *q = calloc(1, sizeof(fs_query)); ct->q = q; q->qs = ct->qs; q->rq = ct->rq; q->flags = FS_BIND_DISTINCT; q->opt_level = 3; q->soft_limit = -1; q->segments = fsp_link_segments(ct->link); q->link = ct->link; q->bb[0] = fs_binding_new(); q->bt = q->bb[0]; /* add column to denote join ordering */ fs_binding_add(q->bb[0], "_ord", FS_RID_NULL, 0); struct pattern_data pd = { .q = q, .vars = vars, .patterns = NULL, .fixed = NULL }; if (ct->op->delete_templates) { pd.patterns = todel_p; pd.fixed = todel; for (int t=0; t<raptor_sequence_size(ct->op->delete_templates); t++) { rasqal_graph_pattern *gp = raptor_sequence_get_at(ct->op->delete_templates, t); assign_gp(gp, NULL, &pd); } } if (ct->op->insert_templates) { pd.patterns = toins_p; pd.fixed = toins; for (int t=0; t<raptor_sequence_size(ct->op->insert_templates); t++) { rasqal_graph_pattern *gp = raptor_sequence_get_at(ct->op->insert_templates, t); assign_gp(gp, NULL, &pd); } } q->num_vars = raptor_sequence_size(vars); for (int i=0; i < q->num_vars; i++) { rasqal_variable *v = raptor_sequence_get_at(vars, i); fs_binding *b = fs_binding_get(q->bb[0], (char *)v->name); if (b) { b->need_val = 1; } else { fs_binding_add(q->bb[0], (char *)v->name, FS_RID_NULL, 1); } } fs_query_process_pattern(q, ct->op->where, vars); q->length = fs_binding_length(q->bb[0]); for (int s=0; s<4; s++) { vec[s] = fs_rid_vector_new(0); } for (int t=0; t<raptor_sequence_size(todel_p); t++) { rasqal_triple *triple = raptor_sequence_get_at(todel_p, t); for (int row=0; row < q->length; row++) { delete_rasqal_triple(ct, vec, triple, row); if (fs_rid_vector_length(vec[0]) > 0) { fsp_delete_quads_all(ct->link, vec); } } } for (int s=0; s<4; s++) { //fs_rid_vector_print(vec[s], 0, stdout); fs_rid_vector_free(vec[s]); } for (int t=0; t<raptor_sequence_size(toins_p); t++) { rasqal_triple *triple = raptor_sequence_get_at(toins_p, t); for (int row=0; row < q->length; row++) { insert_rasqal_triple(ct, triple, row); } } /* must not free the rasqal_query */ q->rq = NULL; fs_query_free(q); ct->q = NULL; } else {