/* * rasqal_projection_add_variable: * @projection: #rasqal_projection object * @var: #rasqal_variable variable * * INTERNAL - add a binding variable to the projection. * * Return value: non-0 on failure **/ int rasqal_projection_add_variable(rasqal_projection* projection, rasqal_variable* var) { RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(projection, rasqal_projection, 1); RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(var, rasqal_variable, 1); if(!projection->variables) { projection->variables = raptor_new_sequence((raptor_data_free_handler)rasqal_free_variable, (raptor_data_print_handler)rasqal_variable_print); if(!projection->variables) return 1; } var = rasqal_new_variable_from_variable(var); return raptor_sequence_push(projection->variables, (void*)var); }
/** * rasqal_rowsource_add_variable: * @rowsource: rasqal rowsource * @v: variable * * Add a variable to the rowsource if the variable is not already present * * Return value: variable offset or < 0 on failure **/ int rasqal_rowsource_add_variable(rasqal_rowsource *rowsource, rasqal_variable* v) { int offset; offset = rasqal_rowsource_get_variable_offset_by_name(rowsource, v->name); if(offset >= 0) return offset; v = rasqal_new_variable_from_variable(v); if(raptor_sequence_push(rowsource->variables_sequence, v)) return -1; if(rowsource->size < 0) rowsource->size = 0; offset = rowsource->size; rowsource->size++; return offset; }
int main(int argc, char *argv[]) { const char *program = rasqal_basename(argv[0]); rasqal_rowsource *rowsource = NULL; rasqal_world* world = NULL; rasqal_query* query = NULL; raptor_sequence* row_seq = NULL; raptor_sequence* expr_args_seq = NULL; int failures = 0; rasqal_variables_table* vt; rasqal_rowsource *input_rs = NULL; raptor_sequence* vars_seq = NULL; raptor_sequence* exprs_seq = NULL; int test_id; 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); vt = query->vars_table; for(test_id = 0; test_id < AGGREGATION_TESTS_COUNT; test_id++) { int input_vars_count = test_data[test_id].input_vars; int output_rows_count = test_data[test_id].output_rows; int output_vars_count = test_data[test_id].output_vars; const int* input_group_ids = test_data[test_id].group_ids; const int* result_int_data = test_data[test_id].result_data; const char* const* result_string_data = test_data[test_id].result_string_data; rasqal_op op = test_data[test_id].op; raptor_sequence* seq = NULL; int count; int size; int i; char* output_var_name; rasqal_variable* output_var; rasqal_expression* expr; int output_row_size = (input_vars_count + output_vars_count); if(output_vars_count != 1) { fprintf(stderr, "%s: test %d expects %d variables which is not supported. Test skipped\n", program, test_id, output_vars_count); failures++; goto tidy; } row_seq = rasqal_new_row_sequence(world, vt, test_data[test_id].data, test_data[test_id].input_vars, &vars_seq); if(row_seq) { for(i = 0; i < test_data[test_id].input_rows; i++) { rasqal_row* row = (rasqal_row*)raptor_sequence_get_at(row_seq, i); row->group_id = input_group_ids[i]; } input_rs = rasqal_new_rowsequence_rowsource(world, query, vt, row_seq, vars_seq); /* vars_seq and row_seq are now owned by input_rs */ vars_seq = row_seq = NULL; } if(!input_rs) { fprintf(stderr, "%s: failed to create rowsequence rowsource\n", program); failures++; goto tidy; } expr_args_seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_expression, (raptor_data_print_handler)rasqal_expression_print); if(test_data[test_id].expr_agg_vars[0] != NULL) { int vindex; const unsigned char* var_name; for(vindex = 0; (var_name = (const unsigned char*)test_data[test_id].expr_agg_vars[vindex] ); vindex++) { rasqal_variable* v; rasqal_literal *l = NULL; rasqal_expression* e = NULL; v = rasqal_variables_table_get_by_name(vt, var_name); if(v) l = rasqal_new_variable_literal(world, v); if(l) e = rasqal_new_literal_expression(world, l); if(e) raptor_sequence_push(expr_args_seq, e); else { fprintf(stderr, "%s: failed to create variable %s\n", program, (const char*)var_name); failures++; goto tidy; } } } /* if vars */ output_var_name = (char*)RASQAL_MALLOC(cstring, 5); memcpy(output_var_name, "fake", 5); output_var = rasqal_variables_table_add(vt, RASQAL_VARIABLE_TYPE_ANONYMOUS, (const unsigned char*)output_var_name, NULL); expr = make_test_expr(world, expr_args_seq, op); /* expr_args_seq is now owned by expr */ expr_args_seq = NULL; exprs_seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_expression, (raptor_data_print_handler)rasqal_expression_print); raptor_sequence_push(exprs_seq, expr); /* expr is now owned by exprs_seq */ expr = NULL; vars_seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_variable, (raptor_data_print_handler)rasqal_variable_print); output_var = rasqal_new_variable_from_variable(output_var); raptor_sequence_push(vars_seq, output_var); rowsource = rasqal_new_aggregation_rowsource(world, query, input_rs, exprs_seq, vars_seq); /* exprs_seq, vars_seq and input_rs are now owned by rowsource */ exprs_seq = NULL; vars_seq = NULL; input_rs = NULL; if(!rowsource) { fprintf(stderr, "%s: failed to create aggregation rowsource\n", program); failures++; goto tidy; } /* Test the rowsource */ seq = rasqal_rowsource_read_all_rows(rowsource); if(!seq) { fprintf(stderr, "%s: test %d rasqal_rowsource_read_all_rows() returned a NULL seq for a aggregation rowsource\n", program, test_id); failures++; goto tidy; } count = raptor_sequence_size(seq); if(count != output_rows_count) { fprintf(stderr, "%s: test %d rasqal_rowsource_read_all_rows() returned %d rows for a aggregation rowsource, expected %d\n", program, test_id, count, output_rows_count); failures++; goto tidy; } size = rasqal_rowsource_get_size(rowsource); if(size != output_row_size) { fprintf(stderr, "%s: test %d rasqal_rowsource_get_size() returned %d columns (variables) for a aggregation rowsource, expected %d\n", program, test_id, size, output_row_size); failures++; goto tidy; } if(result_int_data) { for(i = 0; i < output_rows_count; i++) { rasqal_row* row = (rasqal_row*)raptor_sequence_get_at(seq, i); rasqal_literal* value; int integer; int expected_integer = result_int_data[i]; int vc; if(row->size != output_row_size) { fprintf(stderr, "%s: test %d row #%d is size %d expected %d\n", program, test_id, i, row->size, output_row_size); failures++; goto tidy; } /* Expected variable ordering in output row is: * {input vars} {output_vars} */ for(vc = 0; vc < output_vars_count; vc++) { rasqal_variable* row_var; int offset = input_vars_count + vc; row_var = rasqal_rowsource_get_variable_by_offset(rowsource, offset); value = row->values[offset]; if(!value) { fprintf(stderr, "%s: test %d row #%d %s value #%d result is NULL\n", program, test_id, i, row_var->name, vc); failures++; goto tidy; } if(value->type != RASQAL_LITERAL_INTEGER) { fprintf(stderr, "%s: test %d row #%d %s value #%d result is type %s expected integer\n", program, test_id, i, row_var->name, vc, rasqal_literal_type_label(value->type)); failures++; goto tidy; } integer = rasqal_literal_as_integer(value, NULL); if(integer != expected_integer) { fprintf(stderr, "%s: test %d row #%d %s value #%d result is %d expected %d\n", program, test_id, i, row_var->name, vc, integer, expected_integer); failures++; goto tidy; } } } } if(result_string_data) { for(i = 0; i < output_rows_count; i++) { rasqal_row* row = (rasqal_row*)raptor_sequence_get_at(seq, i); rasqal_literal* value; const unsigned char* str; const char* expected_string = result_string_data[i]; int vc; if(row->size != output_row_size) { fprintf(stderr, "%s: test %d row #%d is size %d expected %d\n", program, test_id, i, row->size, output_row_size); failures++; goto tidy; } /* Expected variable ordering in output row is: * {input vars} {output_vars} */ for(vc = 0; vc < output_vars_count; vc++) { rasqal_variable* row_var; int offset = input_vars_count + vc; row_var = rasqal_rowsource_get_variable_by_offset(rowsource, offset); value = row->values[offset]; if(!value) { fprintf(stderr, "%s: test %d row #%d %s value #%d result is NULL\n", program, test_id, i, row_var->name, vc); failures++; goto tidy; } if(value->type != RASQAL_LITERAL_STRING) { fprintf(stderr, "%s: test %d row #%d %s value #%d is type %s expected integer\n", program, test_id, i, row_var->name, vc, rasqal_literal_type_label(value->type)); failures++; goto tidy; } str = rasqal_literal_as_string(value); if(strcmp((const char*)str, expected_string)) { fprintf(stderr, "%s: test %d row #%d %s value #%d is %s expected %s\n", program, test_id, i, row_var->name, vc, str, expected_string); failures++; goto tidy; } } } } #ifdef RASQAL_DEBUG rasqal_rowsource_print_row_sequence(rowsource, seq, stderr); #endif raptor_free_sequence(seq); seq = NULL; rasqal_free_rowsource(rowsource); rowsource = NULL; if(expr_args_seq) raptor_free_sequence(expr_args_seq); expr_args_seq = NULL; } tidy: if(exprs_seq) raptor_free_sequence(exprs_seq); if(vars_seq) raptor_free_sequence(vars_seq); if(expr_args_seq) raptor_free_sequence(expr_args_seq); if(rowsource) rasqal_free_rowsource(rowsource); if(input_rs) rasqal_free_rowsource(input_rs); if(query) rasqal_free_query(query); if(world) rasqal_free_world(world); return failures; }
/** * rasqal_new_row_sequence: * @world: world object ot use * @vt: variables table to use to declare variables * @row_data: row data * @vars_count: number of variables in row * @vars_seq_p: OUT parameter - pointer to place to store sequence of variables (or NULL) * * INTERNAL - Make a sequence of #rasqal_row* objects * with variables defined into the @vt table and values in the sequence * * The @row_data parameter is an array of strings forming a table of * width (vars_count * 2). * The first row is a list of variable names at offset 0. * The remaining rows are values where offset 0 is a literal and * offset 1 is a URI string. * * The last row is indicated by an entire row of NULLs. * * Return value: sequence of rows or NULL on failure */ raptor_sequence* rasqal_new_row_sequence(rasqal_world* world, rasqal_variables_table* vt, const char* const row_data[], int vars_count, raptor_sequence** vars_seq_p) { raptor_sequence *seq = NULL; raptor_sequence *vars_seq = NULL; int row_i; int column_i; int failed = 0; #define GET_CELL(row, column, offset) \ row_data[((((row)*vars_count)+(column))<<1)+(offset)] seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_row, (raptor_data_print_handler)rasqal_row_print); if(!seq) return NULL; if(vars_seq_p) { vars_seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_variable, (raptor_data_print_handler)rasqal_variable_print); if(!vars_seq) { raptor_free_sequence(seq); return NULL; } } /* row 0 is variables */ row_i = 0; for(column_i = 0; column_i < vars_count; column_i++) { const char * var_name = GET_CELL(row_i, column_i, 0); size_t var_name_len = strlen(var_name); const unsigned char* name; rasqal_variable* v; name = (unsigned char*)RASQAL_MALLOC(cstring, var_name_len+1); if(!name) { failed = 1; goto tidy; } memcpy((void*)name, var_name, var_name_len + 1); v = rasqal_variables_table_add(vt, RASQAL_VARIABLE_TYPE_NORMAL, name, NULL); if(!v) { failed = 1; goto tidy; } if(vars_seq) { v = rasqal_new_variable_from_variable(v); raptor_sequence_push(vars_seq, v); } } for(row_i = 1; 1; row_i++) { rasqal_row* row; int data_values_seen = 0; /* Terminate on an entire row of NULLs */ for(column_i = 0; column_i < vars_count; column_i++) { if(GET_CELL(row_i, column_i, 0) || GET_CELL(row_i, column_i, 1)) { data_values_seen++; break; } } if(!data_values_seen) break; row = rasqal_new_row_for_size(world, vars_count); if(!row) { raptor_free_sequence(seq); seq = NULL; goto tidy; } for(column_i = 0; column_i < vars_count; column_i++) { rasqal_literal* l = NULL; if(GET_CELL(row_i, column_i, 0)) { /* string literal */ const char* str = GET_CELL(row_i, column_i, 0); size_t str_len = strlen(str); char *eptr = NULL; int integer; integer = (int)strtol((const char*)str, &eptr, 10); if(!*eptr) { /* is an integer */ l = rasqal_new_integer_literal(world, RASQAL_LITERAL_INTEGER, integer); } else { unsigned char *val; val = (unsigned char*)RASQAL_MALLOC(cstring, str_len+1); if(val) { memcpy(val, str, str_len + 1); l = rasqal_new_string_literal_node(world, val, NULL, NULL); } else failed = 1; } } else if(GET_CELL(row_i, column_i, 1)) { /* URI */ const unsigned char* str; raptor_uri* u; str = (const unsigned char*)GET_CELL(row_i, column_i, 1); u = raptor_new_uri(world->raptor_world_ptr, str); if(u) l = rasqal_new_uri_literal(world, u); else failed = 1; } else { /* variable is not defined for this row */ continue; } if(!l) { rasqal_free_row(row); failed = 1; goto tidy; } rasqal_row_set_value_at(row, column_i, l); /* free our copy of literal, rasqal_row has a reference */ rasqal_free_literal(l); } raptor_sequence_push(seq, row); } tidy: if(failed) { if(seq) { raptor_free_sequence(seq); seq = NULL; } if(vars_seq) { raptor_free_sequence(vars_seq); vars_seq = NULL; } } else { if(vars_seq) { if(vars_seq_p) *vars_seq_p = vars_seq; else raptor_free_sequence(vars_seq); } } return seq; }