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