static rasqal_row*
rasqal_join_rowsource_build_merged_row(rasqal_rowsource* rowsource,
                                       rasqal_join_rowsource_context* con,
                                       rasqal_row *right_row)
{
  rasqal_row *row;
  int i;

  row = rasqal_new_row_for_size(rowsource->world, rowsource->size);
  if(!row) {
    if(right_row)
      rasqal_free_row(right_row);
    return NULL;
  }

  rasqal_row_set_rowsource(row, rowsource);
  row->offset = con->offset;

#ifdef RASQAL_DEBUG
  RASQAL_DEBUG1("merge\n  left row   : ");
  rasqal_row_print(con->left_row, stderr);
  fputs("\n  right row  : ", stderr);
  if(right_row)
    rasqal_row_print(right_row, stderr);
  else
    fputs("NONE", stderr);
  fputs("\n", stderr);
#endif

  for(i = 0; i < con->left_row->size; i++) {
    rasqal_literal *l = con->left_row->values[i];
    row->values[i] = rasqal_new_literal_from_literal(l);
  }

  if(right_row) {
    for(i = 0; i < right_row->size; i++) {
      rasqal_literal *l = right_row->values[i];
      int dest_i = con->right_map[i];
      if(!row->values[dest_i])
        row->values[dest_i] = rasqal_new_literal_from_literal(l);
    }

    rasqal_free_row(right_row);
  }
  
#ifdef RASQAL_DEBUG
  fputs("  result row : ", stderr);
  if(row)
    rasqal_row_print(row, stderr);
  else
    fputs("NONE", stderr);
  fputs("\n", stderr);
#endif

  return row;
}
Example #2
0
static int
#else
static void
#endif
rasqal_rowsource_groupby_tree_print_node(void *object, FILE *fh)
{
  rasqal_groupby_tree_node* node = (rasqal_groupby_tree_node*)object;
  
  fputs("Group\n  Key Sequence of literals: ", fh);
  if(node->literals)
    /* sequence of literals */
    raptor_sequence_print(node->literals, fh);
  else
    fputs("None", fh);

  fputs("\n  Value Sequence of rows:\n", fh);
  if(node->rows) {
    int i;
    int size = raptor_sequence_size(node->rows);
    
    /* sequence of rows */
    for(i = 0; i < size; i++) {
      rasqal_row* row = (rasqal_row*)raptor_sequence_get_at(node->rows, i);
      
      fprintf(fh, "    Row %d: ", i);
      rasqal_row_print(row, fh);
      fputc('\n', fh);
    }
  } else
    fputs("None\n", fh);

#ifdef HAVE_RAPTOR2_API
  return 0;
#endif
}
Example #3
0
static int
#else
static void
#endif
rasqal_engine_rowsort_map_print_row(void *object, FILE *fh)
{
  if(object)
    rasqal_row_print((rasqal_row*)object, fh);
  else
    fputs("NULL", fh);
#ifdef HAVE_RAPTOR2_API
  return 0;
#endif
}
Example #4
0
/**
 * rasqal_rowsource_print_row_sequence:
 * @rowsource: rowsource associated with rows
 * @seq: query result sequence of #rasqal_row
 * @fp: FILE* handle to print to
 *
 * INTERNAL - Print a result set header with row values from a sequence
 */
void
rasqal_rowsource_print_row_sequence(rasqal_rowsource* rowsource,
                                    raptor_sequence* seq,
                                    FILE* fh)
{
    int size = raptor_sequence_size(seq);
    int i;

    rasqal_rowsource_print_header(rowsource, fh);

    for(i = 0; i < size; i++) {
        rasqal_row *row = (rasqal_row*)raptor_sequence_get_at(seq, i);
        rasqal_row_print(row, fh);
        fputs("\n", fh);
    }
}
Example #5
0
/**
 * 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->finished)
        return NULL;

    if(rasqal_rowsource_ensure_variables(rowsource))
        return NULL;

    if(rowsource->handler->read_row)
        row = rowsource->handler->read_row(rowsource, rowsource->user_data);
    else {
        if(!rowsource->rows_sequence) {
            rowsource->rows_sequence = rasqal_rowsource_read_all_rows(rowsource);
            rowsource->offset = 0;
        }

        if(rowsource->rows_sequence)
            /* remove and return row from sequence at offset */
            row = (rasqal_row*)raptor_sequence_delete_at(rowsource->rows_sequence,
                    rowsource->offset++);
    }

    if(!row)
        rowsource->finished = 1;
    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 read row:  ", rowsource->handler->name,
                  rowsource);
    if(row)
        rasqal_row_print(row, stderr);
    else
        fputs("NONE", stderr);
    fputs("\n", stderr);
#endif

    return row;
}
Example #6
0
/**
 * rasqal_engine_rowsort_map_add_row:
 * @map: row map
 * @row: row to add
 *
 * INTERNAL - Add a row o a rowsort_map for sorting
 *
 * return value: non-0 if the row was a duplicate (and not added)
 */
int
rasqal_engine_rowsort_map_add_row(rasqal_map* map, rasqal_row* row)
{
  /* map. after this, row is owned by map */
  if(!rasqal_map_add_kv(map, row, NULL))
    return 0;

  /* duplicate, and not added so delete it */
#ifdef RASQAL_DEBUG
  RASQAL_DEBUG1("Got duplicate row ");
  rasqal_row_print(row, DEBUG_FH);
  fputc('\n', DEBUG_FH);
#endif
  rasqal_free_row(row);

  return 1;
}
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;
}
Example #8
0
static void
roqet_query_walk(rasqal_query *rq, FILE *fh, int indent) {
    rasqal_query_verb verb;
    int i;
    rasqal_graph_pattern* gp;
    raptor_sequence *seq;

    verb = rasqal_query_get_verb(rq);
    roqet_write_indent(fh, indent);
    fprintf(fh, "query verb: %s\n", rasqal_query_verb_as_string(verb));

    i = rasqal_query_get_distinct(rq);
    if(i != 0) {
        roqet_write_indent(fh, indent);
        fprintf(fh, "query asks for distinct results\n");
    }

    i = rasqal_query_get_limit(rq);
    if(i >= 0) {
        roqet_write_indent(fh, indent);
        fprintf(fh, "query asks for result limits %d\n", i);
    }

    i = rasqal_query_get_offset(rq);
    if(i >= 0) {
        roqet_write_indent(fh, indent);
        fprintf(fh, "query asks for result offset %d\n", i);
    }

    seq = rasqal_query_get_bound_variable_sequence(rq);
    if(seq && raptor_sequence_size(seq) > 0) {
        fprintf(fh, "query bound variables (%d): ",
                raptor_sequence_size(seq));
        i = 0;
        while(1) {
            rasqal_variable* v = (rasqal_variable*)raptor_sequence_get_at(seq, i);
            if(!v)
                break;

            if(i > 0)
                fputs(", ", fh);

            roqet_query_write_variable(fh, v);
            i++;
        }
        fputc('\n', fh);
    }

    gp = rasqal_query_get_query_graph_pattern(rq);
    if(!gp)
        return;


    seq = rasqal_query_get_construct_triples_sequence(rq);
    if(seq && raptor_sequence_size(seq) > 0) {
        roqet_write_indent(fh, indent);
        fprintf(fh, "query construct triples (%d) {\n",
                raptor_sequence_size(seq));
        i = 0;
        while(1) {
            rasqal_triple* t = rasqal_query_get_construct_triple(rq, i);
            if(!t)
                break;

            roqet_write_indent(fh, indent + 2);
            fprintf(fh, "triple #%d { ", i);
            rasqal_triple_print(t, fh);
            fputs(" }\n", fh);

            i++;
        }
        roqet_write_indent(fh, indent);
        fputs("}\n", fh);
    }

    /* look for binding rows */
    seq = rasqal_query_get_bindings_variables_sequence(rq);
    if(seq) {
        roqet_write_indent(fh, indent);
        fprintf(fh, "bindings variables (%d): ",  raptor_sequence_size(seq));

        i = 0;
        while(1) {
            rasqal_variable* v = rasqal_query_get_bindings_variable(rq, i);
            if(!v)
                break;

            if(i > 0)
                fputs(", ", fh);

            roqet_query_write_variable(fh, v);
            i++;
        }
        fputc('\n', fh);

        seq = rasqal_query_get_bindings_rows_sequence(rq);

        fprintf(fh, "bindings rows (%d) {\n", raptor_sequence_size(seq));
        i = 0;
        while(1) {
            rasqal_row* row;

            row = rasqal_query_get_bindings_row(rq, i);
            if(!row)
                break;

            roqet_write_indent(fh, indent + 2);
            fprintf(fh, "row #%d { ", i);
            rasqal_row_print(row, fh);
            fputs("}\n", fh);

            i++;
        }
    }


    fputs("query ", fh);
    roqet_graph_pattern_walk(gp, -1, fh, indent);
}
Example #9
0
/**
 * 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;
}
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;
}