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 void rasqal_engine_rowsort_map_add_to_sequence(void *key, void *value, void *user_data) { rasqal_row* row; row = rasqal_new_row_from_row((rasqal_row*)key); raptor_sequence_push((raptor_sequence*)user_data, row); }
/** * rasqal_query_results_get_row_from_saved: * @query_results: Query results to execute * * INTERNAL - Get next result row from a stored query result sequence * * Return value: result row or NULL if finished or failed */ static rasqal_row* rasqal_query_results_get_row_from_saved(rasqal_query_results* query_results) { rasqal_query* query = query_results->query; int size; rasqal_row* row = NULL; size = raptor_sequence_size(query_results->results_sequence); while(1) { int check; if(query_results->result_count >= size) { query_results->finished = 1; break; } query_results->result_count++; check = rasqal_query_check_limit_offset(query, query_results->result_count); /* finished if beyond result range */ if(check > 0) { query_results->finished = 1; query_results->result_count--; break; } /* continue if before start of result range */ if(check < 0) continue; /* else got result */ row = (rasqal_row*)raptor_sequence_get_at(query_results->results_sequence, query_results->result_count - 1); if(row) { row = rasqal_new_row_from_row(row); /* stored results may not be canonicalized yet - do it lazily */ rasqal_row_to_nodes(row); query_results->row = row; if(query && query->constructs) rasqal_query_results_update_bindings(query_results); } break; } return row; }
/** * rasqal_query_results_get_row_by_offset: * @query_results: query result * @result_offset: index into result rows * * Get stored result row by an offset * * The result_offset index is 0-indexed into the subset of results * constrained by any query limit and offset. * * Return value: row or NULL if @result_offset is out of range */ rasqal_row* rasqal_query_results_get_row_by_offset(rasqal_query_results* query_results, int result_offset) { rasqal_query* query; int check; rasqal_row* row; int offset = 0; RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query_results, rasqal_query_results, NULL); if(!query_results->results_sequence) return NULL; if(result_offset < 0) return NULL; query = query_results->query; if(query) offset = rasqal_query_get_offset(query); /* Adjust 0-indexed to query results 1-indexed + query result offset */ result_offset += 1 + offset; check = rasqal_query_check_limit_offset(query_results->query, result_offset); /* outside limit/offset range in some way */ if(check < 0 || check > 0) return NULL; row = (rasqal_row*)raptor_sequence_get_at(query_results->results_sequence, result_offset - 1); if(row) { row = rasqal_new_row_from_row(row); /* stored results may not be canonicalized yet - do it lazily */ rasqal_row_to_nodes(row); } return row; }
static rasqal_row* rasqal_rowsequence_rowsource_read_row(rasqal_rowsource* rowsource, void *user_data) { rasqal_rowsequence_rowsource_context* con; rasqal_row* row = NULL; con = (rasqal_rowsequence_rowsource_context*)user_data; if(con->failed || con->offset < 0) return NULL; row = (rasqal_row*)raptor_sequence_get_at(con->seq, con->offset); if(!row) { /* finished */ con->offset = -1; } else { row = rasqal_new_row_from_row(row); con->offset++; } return row; }
static raptor_sequence* rasqal_rowsequence_rowsource_read_all_rows(rasqal_rowsource* rowsource, void *user_data) { rasqal_rowsequence_rowsource_context* con; raptor_sequence* seq; con = (rasqal_rowsequence_rowsource_context*)user_data; if(con->offset < 0) return NULL; seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_row, (raptor_data_print_handler)rasqal_row_print); if(seq) { int i; int size = raptor_sequence_size(con->seq); for(i = 0; i < size; i++) { rasqal_row *row = (rasqal_row*)raptor_sequence_get_at(con->seq, i); raptor_sequence_push(seq, rasqal_new_row_from_row(row)); } } return seq; }
/** * rasqal_rowsource_read_row: * @rowsource: rasqal rowsource * * Read a query result row from the rowsource. * * If a row is returned, it is owned by the caller. * * Return value: row or NULL when no more rows are available **/ rasqal_row* rasqal_rowsource_read_row(rasqal_rowsource *rowsource) { rasqal_row* row = NULL; if(!rowsource || rowsource->finished) return NULL; if(rowsource->flags & RASQAL_ROWSOURCE_FLAGS_SAVED_ROWS) { /* return row from saved rows sequence at offset */ row = (rasqal_row*)raptor_sequence_get_at(rowsource->rows_sequence, rowsource->offset++); #ifdef RASQAL_DEBUG RASQAL_DEBUG3("%s rowsource %p returned saved row: ", rowsource->handler->name, rowsource); if(row) rasqal_row_print(row, stderr); else fputs("NONE", stderr); fputs("\n", stderr); #endif if(row) row = rasqal_new_row_from_row(row); /* row is owned by us */ } else { if(rasqal_rowsource_ensure_variables(rowsource)) return NULL; if(rowsource->handler->read_row) { row = rowsource->handler->read_row(rowsource, rowsource->user_data); /* row is owned by us */ if(row && rowsource->flags & RASQAL_ROWSOURCE_FLAGS_SAVE_ROWS) { if(!rowsource->rows_sequence) { rowsource->rows_sequence = raptor_new_sequence((raptor_data_free_handler)rasqal_free_row, (raptor_data_print_handler)rasqal_row_print); rowsource->offset = 0; } /* copy to save it away */ row = rasqal_new_row_from_row(row); raptor_sequence_push(rowsource->rows_sequence, row); } } else { if(!rowsource->rows_sequence) { raptor_sequence* seq; seq = rasqal_rowsource_read_all_rows(rowsource); if(rowsource->rows_sequence) raptor_free_sequence(rowsource->rows_sequence); /* rows_sequence now owns all rows */ rowsource->rows_sequence = seq; rowsource->offset = 0; } if(rowsource->rows_sequence) { /* return row from sequence at offset */ row = (rasqal_row*)raptor_sequence_get_at(rowsource->rows_sequence, rowsource->offset++); if(row) row = rasqal_new_row_from_row(row); /* row is owned by us */ } } } if(!row) { rowsource->finished = 1; if(rowsource->flags & RASQAL_ROWSOURCE_FLAGS_SAVE_ROWS) rowsource->flags |= RASQAL_ROWSOURCE_FLAGS_SAVED_ROWS; } else { rowsource->count++; /* Generate a group around all rows if there are no groups returned */ if(rowsource->generate_group && row->group_id < 0) row->group_id = 0; } #ifdef RASQAL_DEBUG RASQAL_DEBUG3("%s rowsource %p returned row: ", rowsource->handler->name, rowsource); if(row) rasqal_row_print(row, stderr); else fputs("NONE", stderr); fputs("\n", stderr); #endif return row; }