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 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;
}