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; }
static rasqal_row* rasqal_graph_rowsource_read_row(rasqal_rowsource* rowsource, void *user_data) { rasqal_graph_rowsource_context *con; rasqal_row* row = NULL; con = (rasqal_graph_rowsource_context*)user_data; if(con->finished) return NULL; while(1) { row = rasqal_rowsource_read_row(con->rowsource); if(row) break; if(rasqal_graph_next_dg(con)) { con->finished = 1; break; } if(rasqal_rowsource_reset(con->rowsource)) { con->finished = 1; break; } } /* If a row is returned, put the GRAPH variable value as first literal */ if(row) { rasqal_row* nrow; int i; nrow = rasqal_new_row_for_size(rowsource->world, 1 + row->size); if(!nrow) { rasqal_free_row(row); row = NULL; } else { nrow->rowsource = rowsource; nrow->offset = row->offset; /* Put GRAPH variable value (or NULL) first in result row */ nrow->values[0] = rasqal_new_literal_from_literal(con->var->value); /* Copy (size-1) remaining variables from input row */ for(i = 0; i < row->size; i++) nrow->values[i + 1] = rasqal_new_literal_from_literal(row->values[i]); rasqal_free_row(row); row = nrow; } } return row; }
/** * rasqal_new_triple_from_triple: * @t: Triple to copy. * * Copy constructor - create a new #rasqal_triple from an existing one. * * Return value: a new #rasqal_triple or NULL on failure. **/ rasqal_triple* rasqal_new_triple_from_triple(rasqal_triple* t) { rasqal_triple* newt; newt = (rasqal_triple*)RASQAL_CALLOC(rasqal_triple, 1, sizeof(*newt)); if(newt) { newt->subject = rasqal_new_literal_from_literal(t->subject); newt->predicate = rasqal_new_literal_from_literal(t->predicate); newt->object = rasqal_new_literal_from_literal(t->object); } return newt; }
/** * rasqal_engine_rowsort_calculate_order_values: * @query: query object * @row: row * * INTERNAL - Calculate the order condition values for a row * * Return value: non-0 on failure */ int rasqal_engine_rowsort_calculate_order_values(rasqal_query* query, rasqal_row* row) { int i; raptor_sequence *order_seq; if(!row->order_size) return 1; order_seq = rasqal_query_get_order_conditions_sequence(query); for(i = 0; i < row->order_size; i++) { rasqal_expression* e; rasqal_literal *l; e = (rasqal_expression*)raptor_sequence_get_at(order_seq, i); l = rasqal_expression_evaluate(query->world, &query->locator, e, query->compare_flags); if(row->order_values[i]) rasqal_free_literal(row->order_values[i]); if(l) { row->order_values[i] = rasqal_new_literal_from_literal(rasqal_literal_value(l)); rasqal_free_literal(l); } else row->order_values[i] = NULL; } return 0; }
static void rasqal_query_results_update_bindings(rasqal_query_results* query_results) { int i; int size; RASQAL_ASSERT_OBJECT_POINTER_RETURN(query_results, rasqal_query_results); /* bind the construct variables again if running through a sequence */ size = rasqal_variables_table_get_named_variables_count(query_results->vars_table); for(i = 0; i< size; i++) { rasqal_variable* v; rasqal_row* row; rasqal_literal* value = NULL; v = rasqal_variables_table_get(query_results->vars_table, i); rasqal_query_results_ensure_have_row_internal(query_results); row = query_results->row; if(row) { if (i >= row->size) continue; value = row->values[i]; } else query_results->finished = 1; rasqal_variable_set_value(v, rasqal_new_literal_from_literal(value)); } }
/** * 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_row_bind_variables: * @row: Result row * @vars_table: Variables table * * INTERNAL - Bind the variable table vars withvalues in the row * * Return value: non-0 on failure */ int rasqal_row_bind_variables(rasqal_row* row, rasqal_variables_table* vars_table) { int i; for(i = 0; i < row->size; i++) { rasqal_variable* v; v = rasqal_rowsource_get_variable_by_offset(row->rowsource, i); if(v) { rasqal_literal *value = row->values[i]; if(value) { value = rasqal_new_literal_from_literal(value); if(!value) return 1; } /* it is OK to bind to NULL */ rasqal_variable_set_value(v, value); } } return 0; }
static rasqal_literal* rasqal_builtin_agg_expression_execute_result(void* user_data) { rasqal_builtin_agg_expression_execute* b; b = (rasqal_builtin_agg_expression_execute*)user_data; if(b->expr->op == RASQAL_EXPR_COUNT) { rasqal_literal* result; result = rasqal_new_integer_literal(b->world, RASQAL_LITERAL_INTEGER, b->count); return result; } if(b->expr->op == RASQAL_EXPR_GROUP_CONCAT) { size_t len; unsigned char* str; rasqal_literal* result; len = raptor_stringbuffer_length(b->sb); str = (unsigned char*)RASQAL_MALLOC(cstring, len + 1); if(!str) return NULL; if(raptor_stringbuffer_copy_to_string(b->sb, str, len)) { RASQAL_FREE(cstring, str); return NULL; } result = rasqal_new_string_literal(b->world, str, NULL, NULL, NULL); return result; } if(b->expr->op == RASQAL_EXPR_AVG) { rasqal_literal* count_l; rasqal_literal* result; count_l = rasqal_new_integer_literal(b->world, RASQAL_LITERAL_INTEGER, b->count); result = rasqal_literal_divide(b->l, count_l, &b->error); rasqal_free_literal(count_l); if(b->error) { /* result will be NULL and error will be non-0 on division by 0 * in which case the result is literal(integer 0) */ result = rasqal_new_integer_literal(b->world, RASQAL_LITERAL_INTEGER, 0); } return result; } return rasqal_new_literal_from_literal(b->l); }
/** * rasqal_row_set_values_from_variables_table: * @row: Result row * @vars_table: Variables table * * INTERNAL - Set the values of all variables in the row from the given variables table * */ void rasqal_row_set_values_from_variables_table(rasqal_row* row, rasqal_variables_table* vars_table) { int i; for(i = 0; i < row->size; i++) { rasqal_literal *l; l = rasqal_variables_table_get_value(vars_table, i); if(row->values[i]) rasqal_free_literal(row->values[i]); row->values[i] = rasqal_new_literal_from_literal(l); } }
/** * rasqal_row_set_value_at: * @row: query result row * @offset: offset into row (column number) * @value: literal value to set * * Set the value of a variable in a query result row * * Any existing row value is freed and the literal @value passed in * is copied. * * Return value: non-0 on failure */ int rasqal_row_set_value_at(rasqal_row* row, int offset, rasqal_literal* value) { if(!row || !value) return 1; if(offset < 0 || offset >= row->size) return 1; if(row->values[offset]) rasqal_free_literal(row->values[offset]); row->values[offset] = rasqal_new_literal_from_literal(value); return 0; }
static int rasqal_algebra_visitor_set_origin(rasqal_query* query, rasqal_algebra_node* node, void *user_data) { rasqal_literal *origin = (rasqal_literal*)user_data; int i; if(node->op != RASQAL_ALGEBRA_OPERATOR_BGP) return 0; for(i = node->start_column; i <= node->end_column; i++) { rasqal_triple *t; rasqal_literal *o = NULL; t = (rasqal_triple*)raptor_sequence_get_at(node->triples, i); if(origin) o = rasqal_new_literal_from_literal(origin); rasqal_triple_set_origin(t, o); } return 0; }
static rasqal_row* rasqal_aggregation_rowsource_read_row(rasqal_rowsource* rowsource, void *user_data) { rasqal_aggregation_rowsource_context* con; rasqal_row* row; int error = 0; con = (rasqal_aggregation_rowsource_context*)user_data; if(con->finished) return NULL; /* Iterate over input rows until last row seen or group done */ while(1) { error = 0; if(con->saved_row) row = con->saved_row; else row = rasqal_rowsource_read_row(con->rowsource); if(!row) { /* End of input - calculate last aggregation result */ con->finished = 1; break; } if(con->last_group_id != row->group_id) { int i; if(!con->saved_row && con->last_group_id >= 0) { /* Existing aggregation is done - return result */ /* save current row for next time this function is called */ con->saved_row = row; row = NULL; #ifdef RASQAL_DEBUG RASQAL_DEBUG2("Aggregation ending group %d", con->last_group_id); fputc('\n', DEBUG_FH); #endif /* Empty distinct maps */ for(i = 0; i < con->expr_count; i++) { rasqal_agg_expr_data* expr_data = &con->expr_data[i]; if(expr_data->map) { rasqal_free_map(expr_data->map); expr_data->map = NULL; } } break; } /* reference is now in 'row' variable */ con->saved_row = NULL; #ifdef RASQAL_DEBUG RASQAL_DEBUG2("Aggregation starting group %d", row->group_id); fputc('\n', DEBUG_FH); #endif /* next time this function is called we continue here */ for(i = 0; i < con->expr_count; i++) { rasqal_agg_expr_data* expr_data = &con->expr_data[i]; if(!expr_data->agg_user_data) { /* init once */ expr_data->agg_user_data = rasqal_builtin_agg_expression_execute_init(rowsource->world, expr_data->expr); if(!expr_data->agg_user_data) { error = 1; break; } } /* Init map for each group */ if(expr_data->expr->flags & RASQAL_EXPR_FLAG_DISTINCT) { expr_data->map = rasqal_new_literal_sequence_sort_map(1 /* is_distinct */, 0 /* compare_flags */); if(!expr_data->map) { error = 1; break; } } } if(error) break; con->last_group_id = row->group_id; } /* end if handling change of group ID */ /* Bind the values in the input row to the variables in the table */ rasqal_row_bind_variables(row, rowsource->query->vars_table); /* Evaluate the expressions giving a sequence of literals to * run the aggregation step over. */ if(1) { int i; if(!con->step_count) { /* copy first value row from input rowsource */ for(i = 0; i < con->input_values_count; i++) { rasqal_literal* value; value = rasqal_new_literal_from_literal(row->values[i]); raptor_sequence_set_at(con->input_values, i, value); } } con->step_count++; for(i = 0; i < con->expr_count; i++) { rasqal_agg_expr_data* expr_data = &con->expr_data[i]; raptor_sequence* seq; /* SPARQL Aggregation uses ListEvalE() to evaluate - ignoring * errors and filtering out expressions that fail */ seq = rasqal_expression_sequence_evaluate(rowsource->query, expr_data->exprs_seq, /* ignore_errors */ 1, &error); if(error) continue; if(expr_data->map) { if(rasqal_literal_sequence_sort_map_add_literal_sequence(expr_data->map, seq)) { /* duplicate found * * The above function just freed seq so no data is lost */ continue; } } #ifdef RASQAL_DEBUG RASQAL_DEBUG1("Aggregation step over literals: "); raptor_sequence_print(seq, DEBUG_FH); fputc('\n', DEBUG_FH); #endif error = rasqal_builtin_agg_expression_execute_step(expr_data->agg_user_data, seq); /* when DISTINCTing, seq remains owned by the map * otherwise seq is local and must be freed */ if(!expr_data->map) raptor_free_sequence(seq); if(error) break; } } rasqal_free_row(row); row = NULL; if(error) break; } /* end while reading rows */ if(error) { /* Discard row on error */ if(row) { rasqal_free_row(row); row = NULL; } } else if (con->last_group_id >= 0) { int offset = 0; int i; /* Generate result row and reset for next group */ row = rasqal_new_row(rowsource); /* Copy scalar results through */ for(i = 0; i < con->input_values_count; i++) { rasqal_literal* result; /* Reset: get and delete any stored input rowsource literal */ result = (rasqal_literal*)raptor_sequence_delete_at(con->input_values, i); rasqal_row_set_value_at(row, offset, result); rasqal_free_literal(result); offset++; } /* Set aggregate results */ for(i = 0; i < con->expr_count; i++) { rasqal_literal* result; rasqal_agg_expr_data* expr_data = &con->expr_data[i]; rasqal_variable* v; /* Calculate the result because the input ended or a new group started */ result = rasqal_builtin_agg_expression_execute_result(expr_data->agg_user_data); #ifdef RASQAL_DEBUG RASQAL_DEBUG1("Aggregation ending group with result: "); if(result) rasqal_literal_print(result, DEBUG_FH); else fputs("NULL", DEBUG_FH); fputc('\n', DEBUG_FH); #endif v = rasqal_rowsource_get_variable_by_offset(rowsource, offset); result = rasqal_new_literal_from_literal(result); /* it is OK to bind to NULL */ rasqal_variable_set_value(v, result); rasqal_row_set_value_at(row, offset, result); if(result) rasqal_free_literal(result); offset++; if(rasqal_builtin_agg_expression_execute_reset(expr_data->agg_user_data)) { rasqal_free_row(row); row = NULL; break; } } con->step_count = 0; if(row) row->offset = con->offset++; } return row; }
static int rasqal_builtin_agg_expression_execute_step(void* user_data, raptor_sequence* literals) { rasqal_builtin_agg_expression_execute* b; rasqal_literal* l; int i; b = (rasqal_builtin_agg_expression_execute*)user_data; if(b->error) return 1; if(b->expr->op == RASQAL_EXPR_COUNT) { /* COUNT(*) : counts every row (does not care about literals) */ if(b->expr->arg1->op == RASQAL_EXPR_VARSTAR) b->count++; /* COUNT(expr list) : counts rows with non-empty sequence of literals */ else if(raptor_sequence_size(literals) > 0) b->count++; return 0; } /* Other aggregate functions count every row */ b->count++; for(i = 0; (l = (rasqal_literal*)raptor_sequence_get_at(literals, i)); i++) { rasqal_literal* result = NULL; if(b->expr->op == RASQAL_EXPR_SAMPLE) { /* Sample chooses the first literal it sees */ if(!b->l) b->l = rasqal_new_literal_from_literal(l); break; } if(b->expr->op == RASQAL_EXPR_GROUP_CONCAT) { const unsigned char* str; int error = 0; str = (const unsigned char*)rasqal_literal_as_string_flags(l, 0, &error); if(!error) { if(raptor_stringbuffer_length(b->sb)) raptor_stringbuffer_append_counted_string(b->sb, b->separator, 1, 1); raptor_stringbuffer_append_string(b->sb, str, 1); } continue; } if(!b->l) result = rasqal_new_literal_from_literal(l); else { if(b->expr->op == RASQAL_EXPR_SUM || b->expr->op == RASQAL_EXPR_AVG) { result = rasqal_literal_add(b->l, l, &b->error); } else if(b->expr->op == RASQAL_EXPR_MIN) { int cmp = rasqal_literal_compare(b->l, l, 0, &b->error); if(cmp <= 0) result = rasqal_new_literal_from_literal(b->l); else result = rasqal_new_literal_from_literal(l); } else if(b->expr->op == RASQAL_EXPR_MAX) { int cmp = rasqal_literal_compare(b->l, l, 0, &b->error); if(cmp >= 0) result = rasqal_new_literal_from_literal(b->l); else result = rasqal_new_literal_from_literal(l); } else { RASQAL_FATAL2("Builtin aggregation operation %d is not implemented", b->expr->op); } rasqal_free_literal(b->l); if(!result) b->error = 1; } b->l = result; #if RASQAL_DEBUG > 1 RASQAL_DEBUG3("Aggregation step result %s (error=%d)\n", (result ? (const char*)rasqal_literal_as_string(result) : "(NULL)"), b->error); #endif if(b->error) break; } return b->error; }
/** * rasqal_expression_evaluate2: * @e: The expression to evaluate. * @eval_context: expression context * @error_p: pointer to error return flag * * Evaluate a #rasqal_expression tree in the context of a * #rasqal_evaluation_context to give a #rasqal_literal result or error. * * Return value: a #rasqal_literal value or NULL (a valid value). @error_p is set to non-0 on failure. **/ rasqal_literal* rasqal_expression_evaluate2(rasqal_expression* e, rasqal_evaluation_context* eval_context, int *error_p) { rasqal_world *world; int flags; rasqal_literal* result = NULL; rasqal_literal *l1; rasqal_literal *l2; /* pack vars from different switch cases in unions to save some stack space */ union { struct { int e1; int e2; } errs; struct { int dummy_do_not_mask_e; int free_literal; } flags; int e; } errs; union { struct { int b1; int b2; } bools; int b; int i; raptor_uri *dt_uri; const unsigned char *s; unsigned char *new_s; rasqal_variable *v; rasqal_expression *e; struct { void *dummy_do_not_mask; int found; } flags; rasqal_xsd_datetime* dt; struct timeval *tv; raptor_stringbuffer* sb; } vars; RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(e, rasqal_expression, NULL); RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(eval_context, rasqal_evaluation_context, NULL); RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(error_p, intp, NULL); world = eval_context->world; flags = eval_context->flags; errs.e = 0; #ifdef RASQAL_DEBUG RASQAL_DEBUG2("evaluating expression %p: ", e); rasqal_expression_print(e, stderr); fprintf(stderr, "\n"); #endif switch(e->op) { case RASQAL_EXPR_AND: errs.errs.e1 = 0; l1 = rasqal_expression_evaluate2(e->arg1, eval_context, &errs.errs.e1); if(errs.errs.e1) { vars.bools.b1 = 0; } else { vars.bools.b1 = rasqal_literal_as_boolean(l1, &errs.errs.e1); rasqal_free_literal(l1); } errs.errs.e2 = 0; l1 = rasqal_expression_evaluate2(e->arg2, eval_context, &errs.errs.e2); if(errs.errs.e2) { vars.bools.b2 = 0; } else { vars.bools.b2 = rasqal_literal_as_boolean(l1, &errs.errs.e2); rasqal_free_literal(l1); } /* See http://www.w3.org/TR/2005/WD-rdf-sparql-query-20051123/#truthTable */ if(!errs.errs.e1 && !errs.errs.e2) { /* No type error, answer is A && B */ vars.b = vars.bools.b1 && vars.bools.b2; /* don't need b1,b2 anymore */ } else { if((!vars.bools.b1 && errs.errs.e2) || (errs.errs.e1 && vars.bools.b2)) /* F && E => F. E && F => F. */ vars.b = 0; else /* Otherwise E */ goto failed; } result = rasqal_new_boolean_literal(world, vars.b); break; case RASQAL_EXPR_OR: errs.errs.e1 = 0; l1 = rasqal_expression_evaluate2(e->arg1, eval_context, &errs.errs.e1); if(errs.errs.e1) { vars.bools.b1 = 0; } else { vars.bools.b1 = rasqal_literal_as_boolean(l1, &errs.errs.e1); rasqal_free_literal(l1); } errs.errs.e2 = 0; l1 = rasqal_expression_evaluate2(e->arg2, eval_context, &errs.errs.e2); if(errs.errs.e2) { vars.bools.b2 = 0; } else { vars.bools.b2 = rasqal_literal_as_boolean(l1, &errs.errs.e2); rasqal_free_literal(l1); } /* See http://www.w3.org/TR/2005/WD-rdf-sparql-query-20051123/#truthTable */ if(!errs.errs.e1 && !errs.errs.e2) { /* No type error, answer is A || B */ vars.b = vars.bools.b1 || vars.bools.b2; /* don't need b1,b2 anymore */ } else { if((vars.bools.b1 && errs.errs.e2) || (errs.errs.e1 && vars.bools.b2)) /* T || E => T. E || T => T */ vars.b = 1; else /* Otherwise E */ goto failed; } result = rasqal_new_boolean_literal(world, vars.b); break; case RASQAL_EXPR_EQ: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } /* FIXME - this should probably be checked at literal creation * time */ if(!rasqal_xsd_datatype_check(l1->type, l1->string, flags) || !rasqal_xsd_datatype_check(l2->type, l2->string, flags)) { RASQAL_DEBUG1("One of the literals was invalid\n"); goto failed; } vars.b = (rasqal_literal_equals_flags(l1, l2, flags, &errs.e) != 0); #if RASQAL_DEBUG > 1 if(errs.e) RASQAL_DEBUG1("rasqal_literal_equals_flags returned: FAILURE\n"); else RASQAL_DEBUG2("rasqal_literal_equals_flags returned: %d\n", vars.b); #endif rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.e) goto failed; result = rasqal_new_boolean_literal(world, vars.b); break; case RASQAL_EXPR_NEQ: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } vars.b = (rasqal_literal_not_equals_flags(l1, l2, flags, &errs.e) != 0); #if RASQAL_DEBUG > 1 if(errs.e) RASQAL_DEBUG1("rasqal_literal_not_equals_flags returned: FAILURE\n"); else RASQAL_DEBUG2("rasqal_literal_not_equals_flags returned: %d\n", vars.b); #endif rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.e) goto failed; result = rasqal_new_boolean_literal(world, vars.b); break; case RASQAL_EXPR_LT: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } vars.b = (rasqal_literal_compare(l1, l2, flags, &errs.e) < 0); rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.e) goto failed; result = rasqal_new_boolean_literal(world, vars.b); break; case RASQAL_EXPR_GT: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } vars.b = (rasqal_literal_compare(l1, l2, flags, &errs.e) > 0); rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.e) goto failed; result = rasqal_new_boolean_literal(world, vars.b); break; case RASQAL_EXPR_LE: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } vars.b = (rasqal_literal_compare(l1, l2, flags, &errs.e) <= 0); rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.e) goto failed; result = rasqal_new_boolean_literal(world, vars.b); break; case RASQAL_EXPR_GE: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } vars.b = (rasqal_literal_compare(l1, l2, flags, &errs.e) >= 0); rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.e) goto failed; result = rasqal_new_boolean_literal(world, vars.b); break; case RASQAL_EXPR_UMINUS: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; result = rasqal_literal_negate(l1, &errs.e); rasqal_free_literal(l1); if(errs.e) goto failed; break; case RASQAL_EXPR_BOUND: result = rasqal_expression_evaluate_bound(e, eval_context, error_p); break; case RASQAL_EXPR_STR: result = rasqal_expression_evaluate_str(e, eval_context, error_p); break; case RASQAL_EXPR_LANG: result = rasqal_expression_evaluate_lang(e, eval_context, error_p); break; case RASQAL_EXPR_LANGMATCHES: result = rasqal_expression_evaluate_langmatches(e, eval_context, error_p); break; case RASQAL_EXPR_DATATYPE: result = rasqal_expression_evaluate_datatype(e, eval_context, error_p); break; case RASQAL_EXPR_ISURI: case RASQAL_EXPR_ISBLANK: case RASQAL_EXPR_ISLITERAL: case RASQAL_EXPR_ISNUMERIC: result = rasqal_expression_evaluate_istype(e, eval_context, error_p); break; case RASQAL_EXPR_PLUS: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } result = rasqal_literal_add(l1, l2, &errs.e); rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.e) goto failed; break; case RASQAL_EXPR_MINUS: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } result = rasqal_literal_subtract(l1, l2, &errs.e); rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.e) goto failed; break; case RASQAL_EXPR_STAR: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } result = rasqal_literal_multiply(l1, l2, &errs.e); rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.e) goto failed; break; case RASQAL_EXPR_SLASH: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } result = rasqal_literal_divide(l1, l2, &errs.e); rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.e) goto failed; break; case RASQAL_EXPR_REM: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } vars.i = rasqal_literal_as_integer(l2, &errs.errs.e2); /* error if divisor is zero */ if(!vars.i) errs.errs.e2 = 1; else vars.i = rasqal_literal_as_integer(l1, &errs.errs.e1) % vars.i; rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.errs.e1 || errs.errs.e2) goto failed; result = rasqal_new_integer_literal(world, RASQAL_LITERAL_INTEGER, vars.i); break; case RASQAL_EXPR_STR_EQ: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } vars.b = (rasqal_literal_compare(l1, l2, flags | RASQAL_COMPARE_NOCASE, &errs.e) == 0); rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.e) goto failed; result = rasqal_new_boolean_literal(world, vars.b); break; case RASQAL_EXPR_STR_NEQ: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p); if(*error_p || !l2) { rasqal_free_literal(l1); goto failed; } vars.b = (rasqal_literal_compare(l1, l2, flags | RASQAL_COMPARE_NOCASE, &errs.e) != 0); rasqal_free_literal(l1); rasqal_free_literal(l2); if(errs.e) goto failed; result = rasqal_new_boolean_literal(world, vars.b); break; case RASQAL_EXPR_TILDE: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; vars.i= ~ rasqal_literal_as_integer(l1, &errs.e); rasqal_free_literal(l1); if(errs.e) goto failed; result = rasqal_new_integer_literal(world, RASQAL_LITERAL_INTEGER, vars.i); break; case RASQAL_EXPR_BANG: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; vars.b = ! rasqal_literal_as_boolean(l1, &errs.e); rasqal_free_literal(l1); if(errs.e) goto failed; result = rasqal_new_boolean_literal(world, vars.b); break; case RASQAL_EXPR_STR_MATCH: case RASQAL_EXPR_STR_NMATCH: case RASQAL_EXPR_REGEX: result = rasqal_expression_evaluate_strmatch(e, eval_context, error_p); break; case RASQAL_EXPR_LITERAL: /* flatten any literal to a value as soon as possible - this * removes variables from expressions the first time they are seen. * (FLATTEN_LITERAL) */ result = rasqal_new_literal_from_literal(rasqal_literal_value(e->literal)); break; case RASQAL_EXPR_FUNCTION: rasqal_log_warning_simple(world, RASQAL_WARNING_LEVEL_NOT_IMPLEMENTED, eval_context->locator, "No function expressions support at present. Returning false."); result = rasqal_new_boolean_literal(world, 0); break; case RASQAL_EXPR_CAST: l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); if(*error_p || !l1) goto failed; result = rasqal_literal_cast(l1, e->name, flags, &errs.e); rasqal_free_literal(l1); if(errs.e) goto failed; break; case RASQAL_EXPR_ORDER_COND_ASC: case RASQAL_EXPR_ORDER_COND_DESC: case RASQAL_EXPR_GROUP_COND_ASC: case RASQAL_EXPR_GROUP_COND_DESC: result = rasqal_expression_evaluate2(e->arg1, eval_context, error_p); break; case RASQAL_EXPR_COUNT: case RASQAL_EXPR_SUM: case RASQAL_EXPR_AVG: case RASQAL_EXPR_MIN: case RASQAL_EXPR_MAX: case RASQAL_EXPR_SAMPLE: case RASQAL_EXPR_GROUP_CONCAT: rasqal_log_error_simple(world, RAPTOR_LOG_LEVEL_ERROR, eval_context->locator, "Aggregate expressions cannot be evaluated in a general scalar expression."); errs.e = 1; goto failed; break; case RASQAL_EXPR_VARSTAR: /* constants */ break; case RASQAL_EXPR_SAMETERM: result = rasqal_expression_evaluate_sameterm(e, eval_context, error_p); break; case RASQAL_EXPR_CONCAT: result = rasqal_expression_evaluate_concat(e, eval_context, error_p); break; case RASQAL_EXPR_COALESCE: result = rasqal_expression_evaluate_coalesce(e, eval_context, error_p); break; case RASQAL_EXPR_IF: result = rasqal_expression_evaluate_if(e, eval_context, error_p); break; case RASQAL_EXPR_URI: case RASQAL_EXPR_IRI: result = rasqal_expression_evaluate_uri_constructor(e, eval_context, error_p); break; case RASQAL_EXPR_STRLANG: result = rasqal_expression_evaluate_strlang(e, eval_context, error_p); break; case RASQAL_EXPR_STRDT: result = rasqal_expression_evaluate_strdt(e, eval_context, error_p); break; case RASQAL_EXPR_BNODE: result = rasqal_expression_evaluate_bnode_constructor(e, eval_context, error_p); break; case RASQAL_EXPR_IN: result = rasqal_expression_evaluate_in_set(e, eval_context, error_p); break; case RASQAL_EXPR_NOT_IN: result = rasqal_expression_evaluate_in_set(e, eval_context, error_p); break; case RASQAL_EXPR_YEAR: case RASQAL_EXPR_MONTH: case RASQAL_EXPR_DAY: case RASQAL_EXPR_HOURS: case RASQAL_EXPR_MINUTES: case RASQAL_EXPR_SECONDS: result = rasqal_expression_evaluate_datetime_part(e, eval_context, error_p); break; case RASQAL_EXPR_CURRENT_DATETIME: case RASQAL_EXPR_NOW: result = rasqal_expression_evaluate_now(e, eval_context, error_p); break; case RASQAL_EXPR_TO_UNIXTIME: result = rasqal_expression_evaluate_to_unixtime(e, eval_context, error_p); break; case RASQAL_EXPR_FROM_UNIXTIME: result = rasqal_expression_evaluate_from_unixtime(e, eval_context, error_p); break; case RASQAL_EXPR_RAND: result = rasqal_expression_evaluate_rand(e, eval_context, error_p); break; case RASQAL_EXPR_STRLEN: result = rasqal_expression_evaluate_strlen(e, eval_context, error_p); break; case RASQAL_EXPR_UCASE: case RASQAL_EXPR_LCASE: result = rasqal_expression_evaluate_set_case(e, eval_context, error_p); break; case RASQAL_EXPR_STRSTARTS: case RASQAL_EXPR_STRENDS: case RASQAL_EXPR_CONTAINS: result = rasqal_expression_evaluate_str_prefix_suffix(e, eval_context, error_p); break; case RASQAL_EXPR_TIMEZONE: result = rasqal_expression_evaluate_datetime_timezone(e, eval_context, error_p); break; case RASQAL_EXPR_TZ: result = rasqal_expression_evaluate_datetime_tz(e, eval_context, error_p); break; case RASQAL_EXPR_ENCODE_FOR_URI: result = rasqal_expression_evaluate_encode_for_uri(e, eval_context, error_p); break; case RASQAL_EXPR_SUBSTR: result = rasqal_expression_evaluate_substr(e, eval_context, error_p); break; case RASQAL_EXPR_ABS: result = rasqal_expression_evaluate_abs(e, eval_context, error_p); break; case RASQAL_EXPR_ROUND: result = rasqal_expression_evaluate_round(e, eval_context, error_p); break; case RASQAL_EXPR_CEIL: result = rasqal_expression_evaluate_ceil(e, eval_context, error_p); break; case RASQAL_EXPR_FLOOR: result = rasqal_expression_evaluate_floor(e, eval_context, error_p); break; case RASQAL_EXPR_MD5: case RASQAL_EXPR_SHA1: case RASQAL_EXPR_SHA224: case RASQAL_EXPR_SHA256: case RASQAL_EXPR_SHA384: case RASQAL_EXPR_SHA512: result = rasqal_expression_evaluate_digest(e, eval_context, error_p); break; case RASQAL_EXPR_UNKNOWN: default: RASQAL_FATAL3("Unknown operation %s (%d)", rasqal_expression_op_label(e->op), e->op); } got_result: #ifdef RASQAL_DEBUG RASQAL_DEBUG2("result of %p: ", e); rasqal_expression_print(e, stderr); fputs( ": ", stderr); if(*error_p) fputs("FAILURE",stderr); else rasqal_literal_print(result, stderr); fputc('\n', stderr); #endif return result; failed: *error_p = 1; if(result) { rasqal_free_literal(result); result = NULL; } goto got_result; }