예제 #1
0
/**
 * rasqal_new_variable_from_variable:
 * @v: #rasqal_variable to copy
 *
 * Copy Constructor - Create a new Rasqal variable from an existing one
 *
 * This does a deep copy of all variable fields
 *
 * Return value: a new #rasqal_variable or NULL on failure.
 **/
rasqal_variable*
rasqal_new_variable_from_variable(rasqal_variable* v)
{
  rasqal_variable* new_v;
  size_t name_len;
  unsigned char *new_name;

  new_v = (rasqal_variable*)RASQAL_CALLOC(rasqal_variable, 1,
                                          sizeof(rasqal_variable));
  if(!new_v)
    return NULL;
  
  name_len = strlen((const char*)v->name);
  new_name = (unsigned char*)RASQAL_MALLOC(cstring, name_len+1);
  if(!new_name) {
    RASQAL_FREE(rasqal_variable, new_v);
    return NULL;
  }
  memcpy(new_name, v->name, name_len+1);

  new_v->vars_table = v->vars_table;
  new_v->name= new_name;
  new_v->value= rasqal_new_literal_from_literal(v->value);
  new_v->offset= v->offset;
  new_v->type= v->type;
  new_v->expression= rasqal_new_expression_from_expression(v->expression);

  return new_v;
}
예제 #2
0
/**
 * rasqal_new_join_rowsource:
 * @world: world object
 * @query: query object
 * @left: input left (first) rowsource
 * @right: input right (second) rowsource
 * @join_type: join type
 * @expr: join expression to filter result rows
 *
 * INTERNAL - create a new JOIN over two rowsources
 *
 * This uses the number of variables in @vt to set the rowsource size
 * (order size is always 0) and then checks that all the rows in the
 * sequence are the same.  If not, construction fails and NULL is
 * returned.
 *
 * The @left and @right rowsources become owned by the rowsource.
 *
 * Return value: new rowsource or NULL on failure
 */
rasqal_rowsource*
rasqal_new_join_rowsource(rasqal_world *world,
                          rasqal_query* query,
                          rasqal_rowsource* left,
                          rasqal_rowsource* right,
                          rasqal_join_type join_type,
                          rasqal_expression *expr)
{
  rasqal_join_rowsource_context* con;
  int flags = 0;

  if(!world || !query || !left || !right)
    goto fail;

  /* only left outer join and cross join supported */
  if(join_type != RASQAL_JOIN_TYPE_LEFT &&
     join_type != RASQAL_JOIN_TYPE_NATURAL)
    goto fail;
  
  con = RASQAL_CALLOC(rasqal_join_rowsource_context*, 1, sizeof(*con));
  if(!con)
    goto fail;

  con->left = left;
  con->right = right;
  con->join_type = join_type;
  con->expr = rasqal_new_expression_from_expression(expr);
  
  return rasqal_new_rowsource_from_handler(world, query,
                                           con,
                                           &rasqal_join_rowsource_handler,
                                           query->vars_table,
                                           flags);

  fail:
  if(left)
    rasqal_free_rowsource(left);
  if(right)
    rasqal_free_rowsource(right);
  return NULL;
}
예제 #3
0
rasqal_rowsource*
rasqal_new_aggregation_rowsource(rasqal_world *world, rasqal_query* query,
                                 rasqal_rowsource* rowsource,
                                 raptor_sequence* exprs_seq,
                                 raptor_sequence* vars_seq)
{
  rasqal_aggregation_rowsource_context* con;
  int flags = 0;
  int size;
  int i;
  
  if(!world || !query || !rowsource || !exprs_seq || !vars_seq)
    goto fail;

  exprs_seq = rasqal_expression_copy_expression_sequence(exprs_seq);
  vars_seq = rasqal_variable_copy_variable_sequence(vars_seq);

  size = raptor_sequence_size(exprs_seq);
  if(size != raptor_sequence_size(vars_seq)) {
    RASQAL_DEBUG3("expressions sequence size %d does not match vars sequence size %d\n", size, raptor_sequence_size(vars_seq));
    goto fail;
  }


  con = (rasqal_aggregation_rowsource_context*)RASQAL_CALLOC(rasqal_aggregation_rowsource_context, 1, sizeof(*con));
  if(!con)
    goto fail;

  con->rowsource = rowsource;

  con->exprs_seq = exprs_seq;
  con->vars_seq = vars_seq;
  
  /* allocate per-expr data */
  con->expr_count = size;
  con->expr_data = (rasqal_agg_expr_data*)RASQAL_CALLOC(rasqal_agg_expr_data, 
                                                        sizeof(rasqal_agg_expr_data),
                                                        size);
  if(!con->expr_data)
    goto fail;

  /* Initialise per-expr data */
  for(i = 0; i < size; i++) {
    rasqal_expression* expr = (rasqal_expression *)raptor_sequence_get_at(exprs_seq, i);
    rasqal_variable* variable = (rasqal_variable*)raptor_sequence_get_at(vars_seq, i);
    rasqal_agg_expr_data* expr_data = &con->expr_data[i];

    expr_data->expr = rasqal_new_expression_from_expression(expr);
    expr_data->variable = variable;

    /* Prepare expression arguments sequence in per-expr data */
    if(expr->args) {
      /* list of #rasqal_expression arguments already in expr
       * #RASQAL_EXPR_FUNCTION and #RASQAL_EXPR_GROUP_CONCAT 
       */
      expr_data->exprs_seq = rasqal_expression_copy_expression_sequence(expr->args);
    } else {
      /* single argument */
      
      expr_data->exprs_seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_expression,
                                               (raptor_data_print_handler)rasqal_expression_print);
      raptor_sequence_push(expr_data->exprs_seq,
                           rasqal_new_expression_from_expression(expr->arg1));
    }
  }
  
  
  return rasqal_new_rowsource_from_handler(world, query,
                                           con,
                                           &rasqal_aggregation_rowsource_handler,
                                           query->vars_table,
                                           flags);

  fail:

  if(rowsource)
    rasqal_free_rowsource(rowsource);
  if(exprs_seq)
    raptor_free_sequence(exprs_seq);
  if(vars_seq)
    raptor_free_sequence(vars_seq);

  return NULL;
}