static rasqal_row* rasqal_distinct_rowsource_read_row(rasqal_rowsource* rowsource, void *user_data) { rasqal_distinct_rowsource_context *con; rasqal_row *row = NULL; con = (rasqal_distinct_rowsource_context*)user_data; while(1) { int result; row = rasqal_rowsource_read_row(con->rowsource); if(!row) break; result = rasqal_engine_rowsort_map_add_row(con->map, row); RASQAL_DEBUG2("row is %s\n", result ? "not distinct" : "distinct"); if(!result) /* row was distinct (not a duplicate) so return it */ break; } if(row) { row = rasqal_new_row_from_row(row); row->rowsource = rowsource; row->offset = con->offset++; } return row; }
static rasqal_row* rasqal_groupby_rowsource_read_row(rasqal_rowsource* rowsource, void *user_data) { rasqal_groupby_rowsource_context* con; rasqal_row *row = NULL; con = (rasqal_groupby_rowsource_context*)user_data; /* ensure we have stored grouped rows */ if(rasqal_groupby_rowsource_process(rowsource, con)) return NULL; if(con->tree) { rasqal_groupby_tree_node* node = NULL; /* Rows were grouped so iterate through grouped rows */ while(1) { node = (rasqal_groupby_tree_node*)raptor_avltree_iterator_get(con->group_iterator); if(!node) { /* No more nodes. finished last group and last row */ raptor_free_avltree_iterator(con->group_iterator); con->group_iterator = NULL; raptor_free_avltree(con->tree); con->tree = NULL; /* row = NULL is already set */ break; } /* removes row from sequence and this code now owns the reference */ row = (rasqal_row*)raptor_sequence_delete_at(node->rows, con->group_row_index++); if(row) break; /* End of sequence so reset row sequence index and advance iterator */ con->group_row_index = 0; if(raptor_avltree_iterator_next(con->group_iterator)) break; } if(node && row) row->group_id = node->group_id; } else { /* just pass rows through all in one group */ row = rasqal_rowsource_read_row(con->rowsource); if(row) row->group_id = con->group_id; } if(row) row->offset = con->offset++; return row; }
static rasqal_row* rasqal_service_rowsource_read_row(rasqal_rowsource* rowsource, void *user_data) { rasqal_service_rowsource_context* con; con = (rasqal_service_rowsource_context*)user_data; return rasqal_rowsource_read_row(con->rowsource); }
/** * rasqal_rowsource_read_all_rows: * @rowsource: rasqal rowsource * * Read all rows from a rowsource * * After calling this, the rowsource will be empty of rows and finished * and if a sequence is returned, it is owned by the caller. * * Return value: new sequence of all rows (may be size 0) or NULL on failure **/ raptor_sequence* rasqal_rowsource_read_all_rows(rasqal_rowsource *rowsource) { raptor_sequence* seq; if(rasqal_rowsource_ensure_variables(rowsource)) return NULL; if(rowsource->handler->read_all_rows) { seq = rowsource->handler->read_all_rows(rowsource, rowsource->user_data); if(!seq) { seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_row, (raptor_data_print_handler)rasqal_row_print); } if(seq && rowsource->generate_group) { int i; rasqal_row* row; /* Set group for all rows if there are no groups returned */ for(i = 0; (row = (rasqal_row*)raptor_sequence_get_at(seq, i)); i++) { /* if first row has a group ID, end */ if(!i && row->group_id >= 0) break; row->group_id = 0; } } return seq; } seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_row, (raptor_data_print_handler)rasqal_row_print); if(!seq) return NULL; while(1) { rasqal_row* row = rasqal_rowsource_read_row(rowsource); if(!row) break; /* Generate a group around all rows if there are no groups returned */ if(rowsource->generate_group && row->group_id < 0) row->group_id = 0; raptor_sequence_push(seq, row); } return seq; }
static rasqal_row* rasqal_graph_rowsource_read_row(rasqal_rowsource* rowsource, void *user_data) { rasqal_graph_rowsource_context *con; rasqal_row* row = NULL; con = (rasqal_graph_rowsource_context*)user_data; if(con->finished) return NULL; while(1) { row = rasqal_rowsource_read_row(con->rowsource); if(row) break; if(rasqal_graph_next_dg(con)) { con->finished = 1; break; } if(rasqal_rowsource_reset(con->rowsource)) { con->finished = 1; break; } } /* If a row is returned, put the GRAPH variable value as first literal */ if(row) { rasqal_row* nrow; int i; nrow = rasqal_new_row_for_size(rowsource->world, 1 + row->size); if(!nrow) { rasqal_free_row(row); row = NULL; } else { nrow->rowsource = rowsource; nrow->offset = row->offset; /* Put GRAPH variable value (or NULL) first in result row */ nrow->values[0] = rasqal_new_literal_from_literal(con->var->value); /* Copy (size-1) remaining variables from input row */ for(i = 0; i < row->size; i++) nrow->values[i + 1] = rasqal_new_literal_from_literal(row->values[i]); rasqal_free_row(row); row = nrow; } } return row; }
static int rasqal_sort_rowsource_process(rasqal_rowsource* rowsource, rasqal_sort_rowsource_context* con) { int offset = 0; /* already processed */ if(con->seq) return 0; con->seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_row, (raptor_data_print_handler)rasqal_row_print); if(!con->seq) return 1; while(1) { rasqal_row* row; row = rasqal_rowsource_read_row(con->rowsource); if(!row) break; if(rasqal_row_set_order_size(row, con->order_size)) { rasqal_free_row(row); return 1; } rasqal_engine_rowsort_calculate_order_values(rowsource->query, con->order_seq, row); row->offset = offset; /* after this, row is owned by map */ if(!rasqal_engine_rowsort_map_add_row(con->map, row)) offset++; } #ifdef RASQAL_DEBUG if(con->map) { fputs("resulting ", DEBUG_FH); rasqal_map_print(con->map, DEBUG_FH); fputs("\n", DEBUG_FH); } #endif /* do sort/distinct: walk map in order, adding rows to sequence */ rasqal_engine_rowsort_map_to_sequence(con->map, con->seq); rasqal_free_map(con->map); con->map = NULL; return 0; }
static rasqal_row* rasqal_query_engine_algebra_get_row(void* ex_data, rasqal_engine_error *error_p) { rasqal_engine_algebra_data* execution_data; rasqal_row *row = NULL; execution_data = (rasqal_engine_algebra_data*)ex_data; if(execution_data->rowsource) { row = rasqal_rowsource_read_row(execution_data->rowsource); if(!row) *error_p = RASQAL_ENGINE_FINISHED; } else *error_p = RASQAL_ENGINE_FAILED; return row; }
/** * rasqal_query_results_formatter_read: * @world: rasqal world object * @iostr: #raptor_iostream to read the query from * @formatter: #rasqal_query_results_formatter object * @results: #rasqal_query_results query results format * @base_uri: #raptor_uri base URI of the input format * * Read the query results using the given formatter from an iostream * * See rasqal_query_results_formats_enumerate() to get the * list of syntax URIs and their description. * * Return value: non-0 on failure **/ int rasqal_query_results_formatter_read(rasqal_world *world, raptor_iostream *iostr, rasqal_query_results_formatter* formatter, rasqal_query_results* results, raptor_uri *base_uri) { rasqal_rowsource* rowsource = NULL; RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, 1); RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(iostr, raptor_iostream, 1); RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(formatter, rasqal_query_results_formatter, 1); RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(results, rasqal_query_results, 1); RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(base_uri, raptor_uri, 1); if(formatter->factory->reader) return formatter->factory->reader(iostr, results, base_uri); if(!formatter->factory->get_rowsource) return 1; rowsource = formatter->factory->get_rowsource(world, rasqal_query_results_get_variables_table(results), iostr, base_uri); if(!rowsource) return 1; while(1) { rasqal_row* row = rasqal_rowsource_read_row(rowsource); if(!row) break; rasqal_query_results_add_row(results, row); } if(rowsource) rasqal_free_rowsource(rowsource); return 0; }
int main(int argc, char *argv[]) { const char *program = rasqal_basename(argv[0]); rasqal_rowsource *rowsource = NULL; rasqal_rowsource *left_rs = NULL; rasqal_rowsource *right_rs = NULL; rasqal_world* world = NULL; rasqal_query* query = NULL; raptor_sequence* seq = NULL; int failures = 0; int vars_count; rasqal_variables_table* vt; raptor_sequence* vars_seq = NULL; rasqal_row_compatible* rc_map = NULL; int i; world = rasqal_new_world(); rasqal_world_open(world); query = rasqal_new_query(world, "sparql", NULL); vt = query->vars_table; /* 3 variables and 4 rows */ vars_count = 3; seq = rasqal_new_row_sequence(world, vt, compatible_data_abc_rows, vars_count, &vars_seq); if(!seq) { fprintf(stderr, "%s: failed to create left sequence of %d vars\n", program, vars_count); failures++; goto tidy; } left_rs = rasqal_new_rowsequence_rowsource(world, query, vt, seq, vars_seq); if(!left_rs) { fprintf(stderr, "%s: failed to create left rowsource\n", program); failures++; goto tidy; } /* vars_seq and seq are now owned by left_rs */ vars_seq = seq = NULL; /* 3 variables and 4 rows */ vars_count = 3; seq = rasqal_new_row_sequence(world, vt, compatible_data_abcd_rows, vars_count, &vars_seq); if(!seq) { fprintf(stderr, "%s: failed to create right sequence of %d rows\n", program, vars_count); failures++; goto tidy; } right_rs = rasqal_new_rowsequence_rowsource(world, query, vt, seq, vars_seq); if(!right_rs) { fprintf(stderr, "%s: failed to create right rowsource\n", program); failures++; goto tidy; } /* vars_seq and seq are now owned by right_rs */ vars_seq = seq = NULL; rc_map = rasqal_new_row_compatible(vt, left_rs, right_rs); if(!rc_map) { fprintf(stderr, "%s: failed to create row compatible\n", program); failures++; goto tidy; } rasqal_print_row_compatible(stderr, rc_map); #ifdef RASQAL_DEBUG fputs("\n", stderr); #endif for(i = 0; i < EXPECTED_ROWS_COUNT; i++) { rasqal_row *left_row = rasqal_rowsource_read_row(left_rs); rasqal_row *right_row = rasqal_rowsource_read_row(right_rs); int expected = expected_compatible_results[i]; int compatible; if(!left_row) { fprintf(stderr, "%s: FAILED left rowsource ended early at row #%d\n", program, i); failures++; goto tidy; } if(!right_row) { fprintf(stderr, "%s: FAILED right rowsource ended early at row #%d\n", program, i); failures++; goto tidy; } compatible = rasqal_row_compatible_check(rc_map, left_row, right_row); RASQAL_DEBUG4("%s: compatible check for row #%d returned %d\n", program, i, compatible); if(compatible != expected) { fprintf(stderr, "%s: FAILED compatible check for row #%d returned %d expected %d\n", program, i, compatible, expected); failures++; } #ifdef RASQAL_DEBUG fputs("\n", stderr); #endif if(left_row) rasqal_free_row(left_row); if(right_row) rasqal_free_row(right_row); } tidy: if(rc_map) rasqal_free_row_compatible(rc_map); if(seq) raptor_free_sequence(seq); if(left_rs) rasqal_free_rowsource(left_rs); if(right_rs) rasqal_free_rowsource(right_rs); if(rowsource) rasqal_free_rowsource(rowsource); if(query) rasqal_free_query(query); if(world) rasqal_free_world(world); return failures; }
static rasqal_row* rasqal_aggregation_rowsource_read_row(rasqal_rowsource* rowsource, void *user_data) { rasqal_aggregation_rowsource_context* con; rasqal_row* row; int error = 0; con = (rasqal_aggregation_rowsource_context*)user_data; if(con->finished) return NULL; /* Iterate over input rows until last row seen or group done */ while(1) { error = 0; if(con->saved_row) row = con->saved_row; else row = rasqal_rowsource_read_row(con->rowsource); if(!row) { /* End of input - calculate last aggregation result */ con->finished = 1; break; } if(con->last_group_id != row->group_id) { int i; if(!con->saved_row && con->last_group_id >= 0) { /* Existing aggregation is done - return result */ /* save current row for next time this function is called */ con->saved_row = row; row = NULL; #ifdef RASQAL_DEBUG RASQAL_DEBUG2("Aggregation ending group %d", con->last_group_id); fputc('\n', DEBUG_FH); #endif /* Empty distinct maps */ for(i = 0; i < con->expr_count; i++) { rasqal_agg_expr_data* expr_data = &con->expr_data[i]; if(expr_data->map) { rasqal_free_map(expr_data->map); expr_data->map = NULL; } } break; } /* reference is now in 'row' variable */ con->saved_row = NULL; #ifdef RASQAL_DEBUG RASQAL_DEBUG2("Aggregation starting group %d", row->group_id); fputc('\n', DEBUG_FH); #endif /* next time this function is called we continue here */ for(i = 0; i < con->expr_count; i++) { rasqal_agg_expr_data* expr_data = &con->expr_data[i]; if(!expr_data->agg_user_data) { /* init once */ expr_data->agg_user_data = rasqal_builtin_agg_expression_execute_init(rowsource->world, expr_data->expr); if(!expr_data->agg_user_data) { error = 1; break; } } /* Init map for each group */ if(expr_data->expr->flags & RASQAL_EXPR_FLAG_DISTINCT) { expr_data->map = rasqal_new_literal_sequence_sort_map(1 /* is_distinct */, 0 /* compare_flags */); if(!expr_data->map) { error = 1; break; } } } if(error) break; con->last_group_id = row->group_id; } /* end if handling change of group ID */ /* Bind the values in the input row to the variables in the table */ rasqal_row_bind_variables(row, rowsource->query->vars_table); /* Evaluate the expressions giving a sequence of literals to * run the aggregation step over. */ if(1) { int i; if(!con->step_count) { /* copy first value row from input rowsource */ for(i = 0; i < con->input_values_count; i++) { rasqal_literal* value; value = rasqal_new_literal_from_literal(row->values[i]); raptor_sequence_set_at(con->input_values, i, value); } } con->step_count++; for(i = 0; i < con->expr_count; i++) { rasqal_agg_expr_data* expr_data = &con->expr_data[i]; raptor_sequence* seq; /* SPARQL Aggregation uses ListEvalE() to evaluate - ignoring * errors and filtering out expressions that fail */ seq = rasqal_expression_sequence_evaluate(rowsource->query, expr_data->exprs_seq, /* ignore_errors */ 1, &error); if(error) continue; if(expr_data->map) { if(rasqal_literal_sequence_sort_map_add_literal_sequence(expr_data->map, seq)) { /* duplicate found * * The above function just freed seq so no data is lost */ continue; } } #ifdef RASQAL_DEBUG RASQAL_DEBUG1("Aggregation step over literals: "); raptor_sequence_print(seq, DEBUG_FH); fputc('\n', DEBUG_FH); #endif error = rasqal_builtin_agg_expression_execute_step(expr_data->agg_user_data, seq); /* when DISTINCTing, seq remains owned by the map * otherwise seq is local and must be freed */ if(!expr_data->map) raptor_free_sequence(seq); if(error) break; } } rasqal_free_row(row); row = NULL; if(error) break; } /* end while reading rows */ if(error) { /* Discard row on error */ if(row) { rasqal_free_row(row); row = NULL; } } else if (con->last_group_id >= 0) { int offset = 0; int i; /* Generate result row and reset for next group */ row = rasqal_new_row(rowsource); /* Copy scalar results through */ for(i = 0; i < con->input_values_count; i++) { rasqal_literal* result; /* Reset: get and delete any stored input rowsource literal */ result = (rasqal_literal*)raptor_sequence_delete_at(con->input_values, i); rasqal_row_set_value_at(row, offset, result); rasqal_free_literal(result); offset++; } /* Set aggregate results */ for(i = 0; i < con->expr_count; i++) { rasqal_literal* result; rasqal_agg_expr_data* expr_data = &con->expr_data[i]; rasqal_variable* v; /* Calculate the result because the input ended or a new group started */ result = rasqal_builtin_agg_expression_execute_result(expr_data->agg_user_data); #ifdef RASQAL_DEBUG RASQAL_DEBUG1("Aggregation ending group with result: "); if(result) rasqal_literal_print(result, DEBUG_FH); else fputs("NULL", DEBUG_FH); fputc('\n', DEBUG_FH); #endif v = rasqal_rowsource_get_variable_by_offset(rowsource, offset); result = rasqal_new_literal_from_literal(result); /* it is OK to bind to NULL */ rasqal_variable_set_value(v, result); rasqal_row_set_value_at(row, offset, result); if(result) rasqal_free_literal(result); offset++; if(rasqal_builtin_agg_expression_execute_reset(expr_data->agg_user_data)) { rasqal_free_row(row); row = NULL; break; } } con->step_count = 0; if(row) row->offset = con->offset++; } return row; }
static rasqal_row* rasqal_join_rowsource_read_row(rasqal_rowsource* rowsource, void *user_data) { rasqal_join_rowsource_context* con; rasqal_row* row = NULL; rasqal_query *query = rowsource->query; con = (rasqal_join_rowsource_context*)user_data; if(con->failed || con->state == JS_FINISHED) return NULL; while(1) { rasqal_row *right_row; int bresult = 1; int compatible = 1; if(con->state == JS_START) { /* start / re-start left */ if(con->left_row) rasqal_free_row(con->left_row); con->left_row = rasqal_rowsource_read_row(con->left); #ifdef RASQAL_DEBUG RASQAL_DEBUG2("rowsource %p read left row : ", rowsource); if(con->left_row) rasqal_row_print(con->left_row, stderr); else fputs("NONE", stderr); fputs("\n", stderr); #endif con->state = JS_INIT_RIGHT; } if(con->state == JS_INIT_RIGHT) { /* start right */ if(!con->left_row) { con->state = JS_FINISHED; return NULL; } con->right_rows_joined_count = 0; rasqal_rowsource_reset(con->right); } right_row = rasqal_rowsource_read_row(con->right); #ifdef RASQAL_DEBUG RASQAL_DEBUG2("rowsource %p read right row : ", rowsource); if(right_row) rasqal_row_print(right_row, stderr); else fputs("NONE", stderr); fputs("\n", stderr); #endif if(!right_row && con->state == JS_READ_RIGHT) { /* right has finished */ /* restart left */ con->state = JS_START; /* if all right table returned no bindings, return left row */ if(!con->right_rows_joined_count) { /* otherwise return LEFT or RIGHT row only */ if(con->join_type == RASQAL_JOIN_TYPE_LEFT) { /* LEFT JOIN - add left row if expr fails or not compatible */ if(con->left_row) { con->right_rows_joined_count++; row = rasqal_join_rowsource_build_merged_row(rowsource, con, NULL); break; } } } /* restart left by continuing the loop */ continue; } /* state is always JS_READ_RIGHT at this point */ con->state = JS_READ_RIGHT; /* now may have both left and right rows so compute compatibility */ if(right_row) { compatible = rasqal_row_compatible_check(con->rc_map, con->left_row, right_row); RASQAL_DEBUG2("join rows compatible: %s\n", compatible ? "YES" : "NO"); } if(con->constant_join_condition >= 0) { /* Get constant join expression value */ bresult = con->constant_join_condition; } else if(con->expr) { /* Check join expression if present */ rasqal_literal *result; int error = 0; result = rasqal_expression_evaluate2(con->expr, query->eval_context, &error); #ifdef RASQAL_DEBUG RASQAL_DEBUG1("join expression result: "); if(error) fputs("type error", DEBUG_FH); else rasqal_literal_print(result, DEBUG_FH); fputc('\n', DEBUG_FH); #endif if(error) { bresult = 0; } else { error = 0; bresult = rasqal_literal_as_boolean(result, &error); #ifdef RASQAL_DEBUG if(error) RASQAL_DEBUG1("filter boolean expression returned error\n"); else RASQAL_DEBUG2("filter boolean expression result: %d\n", bresult); #endif rasqal_free_literal(result); } } if(con->join_type == RASQAL_JOIN_TYPE_NATURAL) { /* found a row if compatible and constraint matches */ if(compatible && bresult && right_row) { con->right_rows_joined_count++; /* consumes right_row */ row = rasqal_join_rowsource_build_merged_row(rowsource, con, right_row); break; } } else if(con->join_type == RASQAL_JOIN_TYPE_LEFT) { /* * { merge(mu1, mu2) | mu1 in Omega1 and mu2 in Omega2, and mu1 * and mu2 are compatible and expr(merge(mu1, mu2)) is true } */ if(compatible && bresult) { con->right_rows_joined_count++; /* No constraint OR constraint & compatible so return merged row */ /* Compute row only now it is known to be needed (consumes right_row) */ row = rasqal_join_rowsource_build_merged_row(rowsource, con, right_row); break; } #if 0 /* * { mu1 | mu1 in Omega1 and mu2 in Omega2, and mu1 and mu2 are * not compatible } */ if(!compatible) { /* otherwise return LEFT or RIGHT row only */ if(con->join_type == RASQAL_JOIN_TYPE_LEFT) { /* LEFT JOIN - add left row if expr fails or not compatible */ if(con->left_row) { con->right_rows_joined_count++; row = rasqal_join_rowsource_build_merged_row(rowsource, con, NULL); if(right_row) rasqal_free_row(right_row); break; } } } #endif /* * { mu1 | mu1 in Omega1 and mu2 in Omega2, and mu1 and mu2 are * compatible and for all mu2, expr(merge(mu1, mu2)) is false } */ /* The above is handled using check for * !con->right_rows_joined_count earlier, to generate a row * once. */ } /* end if LEFT JOIN */ if(right_row) rasqal_free_row(right_row); } /* end while */ if(row) { rasqal_row_set_rowsource(row, rowsource); row->offset = con->offset++; rasqal_row_bind_variables(row, rowsource->query->vars_table); } return row; }
int main(int argc, char *argv[]) { const char *program = rasqal_basename(argv[0]); rasqal_rowsource *rowsource = NULL; rasqal_world* world = NULL; rasqal_query* query = NULL; rasqal_row* row = NULL; int count; raptor_sequence* seq = NULL; int failures = 0; raptor_uri* service_uri; const unsigned char* query_string; raptor_sequence* data_graphs = NULL; unsigned int rs_flags = 0; world = rasqal_new_world(); if(!world || rasqal_world_open(world)) { fprintf(stderr, "%s: rasqal_world init failed\n", program); return(1); } query = rasqal_new_query(world, "sparql", NULL); service_uri = raptor_new_uri(world->raptor_world_ptr, (const unsigned char *)"http://example.org/service"); query_string = (const unsigned char*)"SELECT * WHERE { ?s ?p ?o }"; rowsource = rasqal_new_service_rowsource(world, query, service_uri, query_string, data_graphs, rs_flags); if(!rowsource) { fprintf(stderr, "%s: failed to create service rowsource\n", program); failures++; goto tidy; } row = rasqal_rowsource_read_row(rowsource); if(!row) { fprintf(stderr, "%s: read_row failed to return a row for an service rowsource\n", program); failures++; goto tidy; } if(row->size) { fprintf(stderr, "%s: read_row returned an non-service row size %d for a service stream\n", program, row->size); failures++; goto tidy; } count = rasqal_rowsource_get_rows_count(rowsource); if(count != 1) { fprintf(stderr, "%s: read_rows returned count %d for a service stream\n", program, count); failures++; goto tidy; } rasqal_free_rowsource(rowsource); /* re-init rowsource */ rowsource = rasqal_new_service_rowsource(world, query, service_uri, query_string, data_graphs, rs_flags); seq = rasqal_rowsource_read_all_rows(rowsource); if(!seq) { fprintf(stderr, "%s: read_rows returned a NULL seq for a service stream\n", program); failures++; goto tidy; } count = raptor_sequence_size(seq); if(count != 1) { fprintf(stderr, "%s: read_rows returned size %d seq for a service stream\n", program, count); failures++; goto tidy; } tidy: if(seq) raptor_free_sequence(seq); if(rowsource) rasqal_free_rowsource(rowsource); if(query) rasqal_free_query(query); if(world) rasqal_free_world(world); return failures; }
static int rasqal_groupby_rowsource_process(rasqal_rowsource* rowsource, rasqal_groupby_rowsource_context* con) { /* already processed */ if(con->processed) return 0; con->processed = 1; /* Empty expression list - no need to read rows */ if(!con->expr_seq || !con->expr_seq_size) { con->group_id++; return 0; } con->tree = raptor_new_avltree(rasqal_rowsource_groupby_literal_sequence_compare, (raptor_data_free_handler)rasqal_free_groupby_tree_node, /* flags */ 0); if(!con->tree) return 1; raptor_avltree_set_print_handler(con->tree, rasqal_rowsource_groupby_tree_print_node); while(1) { rasqal_row* row; row = rasqal_rowsource_read_row(con->rowsource); if(!row) break; rasqal_row_bind_variables(row, rowsource->query->vars_table); if(con->expr_seq) { raptor_sequence* literal_seq; rasqal_groupby_tree_node key; rasqal_groupby_tree_node* node; literal_seq = rasqal_expression_sequence_evaluate(rowsource->query, con->expr_seq, /* ignore_errors */ 0, /* literal_seq */ NULL, /* error_p */ NULL); if(!literal_seq) { /* FIXME - what to do on errors? */ continue; } memset(&key, '\0', sizeof(key)); key.con = con; key.literals = literal_seq; node = (rasqal_groupby_tree_node*)raptor_avltree_search(con->tree, &key); if(!node) { /* New Group */ node = (rasqal_groupby_tree_node*)RASQAL_CALLOC(rasqal_groupby_tree_node, sizeof(*node), 1); if(!node) { raptor_free_sequence(literal_seq); return 1; } node->con = con; node->group_id = ++con->group_id; /* node now owns literal_seq */ node->literals = literal_seq; #ifdef HAVE_RAPTOR2_API node->rows = raptor_new_sequence((raptor_data_free_handler)rasqal_free_row, (raptor_data_print_handler)rasqal_row_print); #else node->rows = raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_row, (raptor_sequence_print_handler*)rasqal_row_print); #endif if(!node->rows) { rasqal_free_groupby_tree_node(node); return 1; } /* after this, node is owned by con->tree */ raptor_avltree_add(con->tree, node); } else raptor_free_sequence(literal_seq); row->group_id = node->group_id; /* after this, node owns the row */ raptor_sequence_push(node->rows, row); } } #ifdef RASQAL_DEBUG if(con->tree) { fputs("Grouping ", DEBUG_FH); raptor_avltree_print(con->tree, DEBUG_FH); fputs("\n", DEBUG_FH); } #endif con->group_iterator = raptor_new_avltree_iterator(con->tree, NULL, NULL, 1); con->group_row_index = 0; con->offset = 0; return 0; }
/** * rasqal_rowsource_read_all_rows: * @rowsource: rasqal rowsource * * Read all rows from a rowsource * * After calling this, the rowsource will be empty of rows and finished * and if a sequence is returned, it is owned by the caller. * * Return value: new sequence of all rows (may be size 0) or NULL on failure **/ raptor_sequence* rasqal_rowsource_read_all_rows(rasqal_rowsource *rowsource) { raptor_sequence* seq; if(!rowsource) return NULL; if(rowsource->flags & RASQAL_ROWSOURCE_FLAGS_SAVED_ROWS) { raptor_sequence* new_seq; /* Return a complete copy of all previously saved rows */ seq = rowsource->rows_sequence; new_seq = rasqal_row_sequence_copy(seq); RASQAL_DEBUG4("%s rowsource %p returning a sequence of %d saved rows\n", rowsource->handler->name, rowsource, raptor_sequence_size(new_seq)); return new_seq; } /* Execute */ if(rasqal_rowsource_ensure_variables(rowsource)) return NULL; if(rowsource->handler->read_all_rows) { seq = rowsource->handler->read_all_rows(rowsource, rowsource->user_data); if(!seq) { seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_row, (raptor_data_print_handler)rasqal_row_print); } else if(rowsource->generate_group) { int i; rasqal_row* row; /* Set group for all rows if there are no groups returned */ for(i = 0; (row = (rasqal_row*)raptor_sequence_get_at(seq, i)); i++) { /* if first row has a group ID, end */ if(!i && row->group_id >= 0) break; row->group_id = 0; } } goto done; } seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_row, (raptor_data_print_handler)rasqal_row_print); if(!seq) return NULL; while(1) { rasqal_row* row = rasqal_rowsource_read_row(rowsource); if(!row) break; /* Generate a group around all rows if there are no groups returned */ if(rowsource->generate_group && row->group_id < 0) row->group_id = 0; raptor_sequence_push(seq, row); } done: if(seq && rowsource->flags & RASQAL_ROWSOURCE_FLAGS_SAVE_ROWS) { raptor_sequence* new_seq; /* Save a complete copy of all rows */ new_seq = rasqal_row_sequence_copy(seq); RASQAL_DEBUG4("%s rowsource %p saving a sequence of %d rows\n", rowsource->handler->name, rowsource, raptor_sequence_size(new_seq)); rowsource->rows_sequence = new_seq; rowsource->flags |= RASQAL_ROWSOURCE_FLAGS_SAVED_ROWS; } RASQAL_DEBUG4("%s rowsource %p returning a sequence of %d rows\n", rowsource->handler->name, rowsource, raptor_sequence_size(seq)); return seq; }
int main(int argc, char *argv[]) { const char *program = rasqal_basename(argv[0]); rasqal_rowsource *rowsource = NULL; raptor_sequence *seq = NULL; rasqal_world* world = NULL; rasqal_query* query = NULL; rasqal_row* row = NULL; int count; int failures = 0; rasqal_variables_table* vt; int rows_count; int i; raptor_sequence* vars_seq = NULL; world = rasqal_new_world(); if(!world || rasqal_world_open(world)) { fprintf(stderr, "%s: rasqal_world init failed\n", program); return(1); } query = rasqal_new_query(world, "sparql", NULL); /* test 1-row rowsource (2 variables) */ rows_count = 1; #ifdef RASQAL_DEBUG RASQAL_DEBUG2("Testing %d-row rowsource\n", rows_count); #endif vt = rasqal_new_variables_table(world); /* add 2 variables to table and 1 row sequence */ seq = rasqal_new_row_sequence(world, vt, test_1_rows, 2, &vars_seq); if(!seq) { fprintf(stderr, "%s: failed to create sequence of %d rows\n", program, rows_count); failures++; goto tidy; } rowsource = rasqal_new_rowsequence_rowsource(world, query, vt, seq, vars_seq); if(!rowsource) { fprintf(stderr, "%s: failed to create %d-row sequence rowsource\n", program, rows_count); failures++; goto tidy; } /* vars_seq and seq are now owned by rowsource */ vars_seq = seq = NULL; row = rasqal_rowsource_read_row(rowsource); if(!row) { fprintf(stderr, "%s: read_row returned no row for a %d-row sequence rowsource\n", program, rows_count); failures++; goto tidy; } #ifdef RASQAL_DEBUG RASQAL_DEBUG1("Result Row:\n "); rasqal_row_print(row, stderr); fputc('\n', stderr); #endif rasqal_free_row(row); row = NULL; count = rasqal_rowsource_get_rows_count(rowsource); if(count != rows_count) { fprintf(stderr, "%s: read_rows returned count %d instead of %d for a %d-row sequence rowsource\n", program, count, rows_count, rows_count); failures++; goto tidy; } row = rasqal_rowsource_read_row(rowsource); if(row) { fprintf(stderr, "%s: read_row returned > %d rows for a %d-row sequence rowsource\n", program, rows_count, rows_count); failures++; goto tidy; } rasqal_free_rowsource(rowsource); rowsource = NULL; rasqal_free_variables_table(vt); vt = NULL; /* test 3-row rowsource */ rows_count = 3; #ifdef RASQAL_DEBUG RASQAL_DEBUG2("Testing %d-row rowsource\n", rows_count); #endif vt = rasqal_new_variables_table(world); /* add 4 variables to table and 3 row sequence */ seq = rasqal_new_row_sequence(world, vt, test_3_rows, 4, &vars_seq); if(!seq) { fprintf(stderr, "%s: failed to create sequence of %d rows\n", program, rows_count); failures++; goto tidy; } rowsource = rasqal_new_rowsequence_rowsource(world, query, vt, seq, vars_seq); if(!rowsource) { fprintf(stderr, "%s: failed to create %d-row sequence rowsource\n", program, rows_count); failures++; goto tidy; } /* vars_seq and seq are now owned by rowsource */ vars_seq = seq = NULL; for(i = 0; i < rows_count; i++) { row = rasqal_rowsource_read_row(rowsource); if(!row) { fprintf(stderr, "%s: read_row returned no row for row %d in a %d-row sequence rowsource\n", program, i, rows_count); failures++; goto tidy; } #ifdef RASQAL_DEBUG RASQAL_DEBUG1("Result Row:\n "); rasqal_row_print(row, stderr); fputc('\n', stderr); #endif rasqal_free_row(row); row = NULL; } count = rasqal_rowsource_get_rows_count(rowsource); if(count != rows_count) { fprintf(stderr, "%s: read_rows returned count %d instead of %d for a %d-row sequence rowsource\n", program, count, rows_count, rows_count); failures++; goto tidy; } row = rasqal_rowsource_read_row(rowsource); if(row) { fprintf(stderr, "%s: read_row returned >%d rows for a %d-row sequence rowsource\n", program, rows_count, rows_count); failures++; goto tidy; } rasqal_free_rowsource(rowsource); rowsource = NULL; rasqal_free_variables_table(vt); vt = NULL; tidy: if(row) rasqal_free_row(row); if(seq) raptor_free_sequence(seq); if(rowsource) rasqal_free_rowsource(rowsource); if(vt) rasqal_free_variables_table(vt); if(query) rasqal_free_query(query); if(world) rasqal_free_world(world); return failures; }
int main(int argc, char *argv[]) { const char *program = rasqal_basename(argv[0]); rasqal_rowsource *rowsource = NULL; rasqal_world* world = NULL; rasqal_query* query = NULL; rasqal_row* row = NULL; int count; raptor_sequence* seq = NULL; int failures = 0; world = rasqal_new_world(); if(!world || rasqal_world_open(world)) { fprintf(stderr, "%s: rasqal_world init failed\n", program); return(1); } query = rasqal_new_query(world, "sparql", NULL); rowsource = rasqal_new_empty_rowsource(world, query); if(!rowsource) { fprintf(stderr, "%s: failed to create empty rowsource\n", program); failures++; goto tidy; } row = rasqal_rowsource_read_row(rowsource); if(!row) { fprintf(stderr, "%s: read_row failed to return a row for an empty rowsource\n", program); failures++; goto tidy; } if(row->size) { fprintf(stderr, "%s: read_row returned an non-empty row size %d for a empty stream\n", program, row->size); failures++; goto tidy; } count = rasqal_rowsource_get_rows_count(rowsource); if(count != 1) { fprintf(stderr, "%s: read_rows returned count %d for a empty stream\n", program, count); failures++; goto tidy; } rasqal_free_row(row); row = NULL; rasqal_free_rowsource(rowsource); /* re-init rowsource */ rowsource = rasqal_new_empty_rowsource(world, query); seq = rasqal_rowsource_read_all_rows(rowsource); if(!seq) { fprintf(stderr, "%s: read_rows returned a NULL seq for a empty stream\n", program); failures++; goto tidy; } count = raptor_sequence_size(seq); if(count != 1) { fprintf(stderr, "%s: read_rows returned size %d seq for a empty stream\n", program, count); failures++; goto tidy; } tidy: if(row) rasqal_free_row(row); if(seq) raptor_free_sequence(seq); if(rowsource) rasqal_free_rowsource(rowsource); if(query) rasqal_free_query(query); if(world) rasqal_free_world(world); return failures; }