void rasqal_print_row_compatible(FILE *handle, rasqal_row_compatible* map) { int count = map->variables_count; rasqal_variables_table* vt = map->variables_table; int i; char left_rs[4]; char right_rs[4]; fprintf(handle, "Row compatible map: total variables: %d shared variables: %d\n", count, map->variables_in_both_rows_count); for(i = 0; i < count; i++) { rasqal_variable *v = rasqal_variables_table_get(vt, i); int offset1 = map->defined_in_map[i<<1]; int offset2 = map->defined_in_map[1 + (i<<1)]; if(offset1 < 0) *left_rs='\0'; else sprintf(left_rs, "%2d", offset1); if(offset2 < 0) *right_rs='\0'; else sprintf(right_rs, "%2d", offset2); fprintf(handle, " Variable %10s offsets left RS: %-3s right RS: %-3s %s\n", v->name, left_rs, right_rs, ((offset1 >=0 && offset2 >= 0) ? "SHARED" : "")); } }
/** * rasqal_row_compatible_check: * @map: row compatible map object * @first_row: first row * @second_row: second row * * Test if two rows have SPARQL Algebra "Compatible Mappings" * * "Two solution mappings μ1 and μ2 are compatible if, for every * variable v in dom(μ1) and in dom(μ2), μ1(v) = μ2(v)." * -- SPARQL Query Language 20080115, 12.3 Basic Graph Patterns * * interpretation: * for all variables in both rows * the values for both rows must either * a) be the same defined value * b) both be undefined */ int rasqal_row_compatible_check(rasqal_row_compatible* map, rasqal_row *first_row, rasqal_row *second_row) { int i; int count = map->variables_count; int compatible = 1; /* If no variables in common, always compatible */ if(!map->variables_in_both_rows_count) return 1; for(i = 0; i < count; i++) { #ifdef RASQAL_DEBUG rasqal_variable *v = rasqal_variables_table_get(map->variables_table, i); const unsigned char *name = v->name; #endif rasqal_literal *first_value = NULL; rasqal_literal *second_value = NULL; int offset1 = map->defined_in_map[i<<1]; int offset2 = map->defined_in_map[1 + (i<<1)]; if(offset1 >= 0) first_value = first_row->values[offset1]; if(offset2 >= 0) second_value = second_row->values[offset2]; #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1 RASQAL_DEBUG5("row variable #%d - %s has first row offset #%d second row offset #%d\n", i, name, offset1, offset2); #endif /* do not test if both are NULL */ if(!first_value && !second_value) continue; if(!first_value || !second_value) { #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1 RASQAL_DEBUG3("row variable #%d - %s has (one NULL, one value)\n", i, name); #endif /* compatible if one is NULL and the other is not */ continue; } if(!rasqal_literal_equals(first_value, second_value)) { RASQAL_DEBUG3("row variable #%d - %s has different values\n", i, name); /* incompatible if not equal values */ compatible = 0; break; } else { #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1 RASQAL_DEBUG3("row variable #%d - %s has same values\n", i, name); #endif } } return compatible; }
/** * rasqal_query_results_get_binding_name: * @query_results: #rasqal_query_results query_results * @offset: offset of binding name into array of known names * * Get binding name for the current result. * * Return value: a pointer to a shared copy of the binding name or NULL on failure **/ const unsigned char* rasqal_query_results_get_binding_name(rasqal_query_results* query_results, int offset) { rasqal_variable* v; RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query_results, rasqal_query_results, NULL); if(!rasqal_query_results_is_bindings(query_results)) return NULL; if(query_results->query) { /* If there is a query, take variable names from the order in the * projection not the order inserted into the variables table. */ v = (rasqal_variable*)raptor_sequence_get_at(query_results->query->selects, offset); } else v = rasqal_variables_table_get(query_results->vars_table, offset); if(!v) return NULL; return v->name; }
static void rasqal_query_results_update_bindings(rasqal_query_results* query_results) { int i; int size; RASQAL_ASSERT_OBJECT_POINTER_RETURN(query_results, rasqal_query_results); /* bind the construct variables again if running through a sequence */ size = rasqal_variables_table_get_named_variables_count(query_results->vars_table); for(i = 0; i< size; i++) { rasqal_variable* v; rasqal_row* row; rasqal_literal* value = NULL; v = rasqal_variables_table_get(query_results->vars_table, i); rasqal_query_results_ensure_have_row_internal(query_results); row = query_results->row; if(row) { if (i >= row->size) continue; value = row->values[i]; } else query_results->finished = 1; rasqal_variable_set_value(v, rasqal_new_literal_from_literal(value)); } }
rasqal_literal* rasqal_variables_table_get_value(rasqal_variables_table* vt, int idx) { rasqal_variable* v; v = rasqal_variables_table_get(vt, idx); if(!v) return NULL; return v->value; }
rasqal_variable* rasqal_variables_table_get_by_name(rasqal_variables_table* vt, const unsigned char *name) { int i; rasqal_variable* v; for(i = 0; (v = rasqal_variables_table_get(vt, i)); i++) { if(!strcmp((const char*)v->name, (const char*)name)) return v; } return NULL; }
rasqal_row_compatible* rasqal_new_row_compatible(rasqal_variables_table* vt, rasqal_rowsource *first_rowsource, rasqal_rowsource *second_rowsource) { rasqal_row_compatible* map = NULL; int count = rasqal_variables_table_get_total_variables_count(vt); int i; map = RASQAL_CALLOC(rasqal_row_compatible*, 1, sizeof(*map)); if(!map) return NULL; map->variables_table = vt; map->first_rowsource = first_rowsource; map->second_rowsource = second_rowsource; map->variables_count = count; map->defined_in_map = RASQAL_CALLOC(int*, RASQAL_GOOD_CAST(size_t, 2 * count), sizeof(int)); if(!map->defined_in_map) { RASQAL_FREE(rasqal_row_compatible, map); return NULL; } for(i = 0; i < count; i++) { rasqal_variable *v; int offset1; int offset2; v = rasqal_variables_table_get(vt, i); offset1 = rasqal_rowsource_get_variable_offset_by_name(first_rowsource, v->name); offset2 = rasqal_rowsource_get_variable_offset_by_name(second_rowsource, v->name); map->defined_in_map[i<<1] = offset1; map->defined_in_map[1 + (i<<1)] = offset2; if(offset1 >= 0 && offset2 >= 0) map->variables_in_both_rows_count++; } return map; }