/** * 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; }
/** * rasqal_service_execute: * @svc: rasqal service * * Execute a rasqal sparql protocol service * * Return value: query results or NULL on failure */ rasqal_query_results* rasqal_service_execute(rasqal_service* svc) { rasqal_query_results* results = NULL; unsigned char* result_string = NULL; size_t result_length; raptor_iostream* read_iostr = NULL; raptor_uri* read_base_uri = NULL; rasqal_variables_table* vars_table = NULL; rasqal_query_results_formatter* read_formatter = NULL; raptor_uri* retrieval_uri = NULL; raptor_stringbuffer* uri_sb = NULL; size_t len; unsigned char* str; raptor_world* raptor_world_ptr = rasqal_world_get_raptor(svc->world); if(!svc->www) { svc->www = raptor_new_www(raptor_world_ptr); if(!svc->www) { rasqal_log_error_simple(svc->world, RAPTOR_LOG_LEVEL_ERROR, NULL, "Failed to create WWW"); goto error; } } svc->started = 0; svc->final_uri = NULL; svc->sb = raptor_new_stringbuffer(); svc->content_type = NULL; if(svc->format) raptor_www_set_http_accept(svc->www, svc->format); else raptor_www_set_http_accept(svc->www, DEFAULT_FORMAT); raptor_www_set_write_bytes_handler(svc->www, rasqal_service_write_bytes, svc); raptor_www_set_content_type_handler(svc->www, rasqal_service_content_type_handler, svc); /* Construct a URI to retrieve following SPARQL protocol HTTP * binding from concatenation of * * 1. service_uri * 2. '?' * 3. "query=" query_string * 4. "&default-graph-uri=" background graph URI if any * 5. "&named-graph-uri=" named graph URI for all named graphs * with URI-escaping of the values */ uri_sb = raptor_new_stringbuffer(); if(!uri_sb) { rasqal_log_error_simple(svc->world, RAPTOR_LOG_LEVEL_ERROR, NULL, "Failed to create stringbuffer"); goto error; } str = raptor_uri_as_counted_string(svc->service_uri, &len); raptor_stringbuffer_append_counted_string(uri_sb, str, len, 1); raptor_stringbuffer_append_counted_string(uri_sb, (const unsigned char*)"?", 1, 1); if(svc->query_string) { raptor_stringbuffer_append_counted_string(uri_sb, (const unsigned char*)"query=", 6, 1); raptor_stringbuffer_append_uri_escaped_counted_string(uri_sb, svc->query_string, svc->query_string_len, 1); } if(svc->data_graphs) { rasqal_data_graph* dg; int i; int bg_graph_count; for(i = 0, bg_graph_count = 0; (dg = (rasqal_data_graph*)raptor_sequence_get_at(svc->data_graphs, i)); i++) { unsigned char* graph_str; size_t graph_len; raptor_uri* graph_uri; if(dg->flags & RASQAL_DATA_GRAPH_BACKGROUND) { if(bg_graph_count++) { if(bg_graph_count == 2) { /* Warn once, only when the second BG is seen */ rasqal_log_warning_simple(svc->world, RASQAL_WARNING_LEVEL_MULTIPLE_BG_GRAPHS, NULL, "Attempted to add multiple background graphs"); } /* always skip after first BG */ continue; } raptor_stringbuffer_append_counted_string(uri_sb, (const unsigned char*)"&default-graph-uri=", 19, 1); graph_uri = dg->uri; } else { raptor_stringbuffer_append_counted_string(uri_sb, (const unsigned char*)"&named-graph-uri=", 17, 1); graph_uri = dg->name_uri; } graph_str = raptor_uri_as_counted_string(graph_uri, &graph_len); raptor_stringbuffer_append_uri_escaped_counted_string(uri_sb, (const char*)graph_str, graph_len, 1); } } str = raptor_stringbuffer_as_string(uri_sb); retrieval_uri = raptor_new_uri(raptor_world_ptr, str); if(!retrieval_uri) { rasqal_log_error_simple(svc->world, RAPTOR_LOG_LEVEL_ERROR, NULL, "Failed to create retrieval URI %s", raptor_uri_as_string(retrieval_uri)); goto error; } raptor_free_stringbuffer(uri_sb); uri_sb = NULL; if(raptor_www_fetch(svc->www, retrieval_uri)) { rasqal_log_error_simple(svc->world, RAPTOR_LOG_LEVEL_ERROR, NULL, "Failed to fetch retrieval URI %s", raptor_uri_as_string(retrieval_uri)); goto error; } vars_table = rasqal_new_variables_table(svc->world); if(!vars_table) { rasqal_log_error_simple(svc->world, RAPTOR_LOG_LEVEL_ERROR, NULL, "Failed to create variables table"); goto error; } results = rasqal_new_query_results(svc->world, NULL, RASQAL_QUERY_RESULTS_BINDINGS, vars_table); /* (results takes a reference/copy to vars_table) */ rasqal_free_variables_table(vars_table); vars_table = NULL; if(!results) { rasqal_log_error_simple(svc->world, RAPTOR_LOG_LEVEL_ERROR, NULL, "Failed to create query results"); goto error; } result_length = raptor_stringbuffer_length(svc->sb); result_string = raptor_stringbuffer_as_string(svc->sb); read_iostr = raptor_new_iostream_from_string(raptor_world_ptr, result_string, result_length); if(!read_iostr) { rasqal_log_error_simple(svc->world, RAPTOR_LOG_LEVEL_ERROR, NULL, "Failed to create iostream from string"); rasqal_free_query_results(results); results = NULL; goto error; } read_base_uri = svc->final_uri ? svc->final_uri : svc->service_uri; read_formatter = rasqal_new_query_results_formatter(svc->world, /* format name */ NULL, svc->content_type, /* format URI */ NULL); if(!read_formatter) { rasqal_log_error_simple(svc->world, RAPTOR_LOG_LEVEL_ERROR, NULL, "Failed to create query formatter for type %s", svc->content_type); rasqal_free_query_results(results); results = NULL; goto error; } if(rasqal_query_results_formatter_read(svc->world, read_iostr, read_formatter, results, read_base_uri)) { rasqal_log_error_simple(svc->world, RAPTOR_LOG_LEVEL_ERROR, NULL, "Failed to read from query formatter"); rasqal_free_query_results(results); results = NULL; goto error; } error: if(retrieval_uri) raptor_free_uri(retrieval_uri); if(uri_sb) raptor_free_stringbuffer(uri_sb); if(read_formatter) rasqal_free_query_results_formatter(read_formatter); if(read_iostr) raptor_free_iostream(read_iostr); if(vars_table) rasqal_free_variables_table(vars_table); if(svc->final_uri) { raptor_free_uri(svc->final_uri); svc->final_uri = NULL; } if(svc->content_type) { RASQAL_FREE(cstring, svc->content_type); svc->content_type = NULL; } if(svc->sb) { raptor_free_stringbuffer(svc->sb); svc->sb = NULL; } return results; }
/** * rasqal_query_results_get_triple: * @query_results: #rasqal_query_results query_results * * Get the current triple in the result. * * The return value is a shared #raptor_statement. * * Return value: #raptor_statement or NULL if failed or results exhausted **/ raptor_statement* rasqal_query_results_get_triple(rasqal_query_results* query_results) { rasqal_query* query; int rc; rasqal_triple *t; rasqal_literal *s, *p, *o; raptor_statement *rs = NULL; unsigned char *nodeid; int skipped; RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query_results, rasqal_query_results, NULL); if(query_results->failed || query_results->finished) return NULL; if(!rasqal_query_results_is_graph(query_results)) return NULL; query = query_results->query; if(!query) return NULL; if(query->verb == RASQAL_QUERY_VERB_DESCRIBE) return NULL; /* ensure we have a row to work on */ if(rasqal_query_results_ensure_have_row_internal(query_results)) return NULL; skipped = 0; while(1) { if(skipped) { rc = rasqal_query_results_next(query_results); if(rc) { rs = NULL; break; } query_results->current_triple_result = -1; } if(query_results->current_triple_result < 0) query_results->current_triple_result = 0; t = (rasqal_triple*)raptor_sequence_get_at(query->constructs, query_results->current_triple_result); rs = &query_results->result_triple; s = rasqal_literal_as_node(t->subject); if(!s) { rasqal_log_warning_simple(query_results->world, RASQAL_WARNING_LEVEL_BAD_TRIPLE, &query->locator, "Triple with unbound subject skipped"); skipped = 1; continue; } /* raptor v2 terms are copied, not shared */ if(rs->subject) { raptor_free_term(rs->subject); rs->subject = NULL; } switch(s->type) { case RASQAL_LITERAL_URI: rs->subject = raptor_new_term_from_uri(query_results->world->raptor_world_ptr, s->value.uri); break; case RASQAL_LITERAL_BLANK: nodeid = rasqal_prefix_id(query_results->result_count, (unsigned char*)s->string); rasqal_free_literal(s); if(!nodeid) { rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_FATAL, &query->locator, "Could not prefix subject blank identifier"); return NULL; } s = rasqal_new_simple_literal(query_results->world, RASQAL_LITERAL_BLANK, nodeid); if(!s) { rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_FATAL, &query->locator, "Could not create a new subject blank literal"); return NULL; } rs->subject = raptor_new_term_from_blank(query_results->world->raptor_world_ptr, nodeid); break; case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_XSD_STRING: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: case RASQAL_LITERAL_UDT: case RASQAL_LITERAL_INTEGER_SUBTYPE: /* QNames should be gone by the time expression eval happens * Everything else is removed by rasqal_literal_as_node() above. */ case RASQAL_LITERAL_STRING: /* string [literal] subjects are not RDF */ case RASQAL_LITERAL_UNKNOWN: default: /* case RASQAL_LITERAL_STRING: */ rasqal_log_warning_simple(query_results->world, RASQAL_WARNING_LEVEL_BAD_TRIPLE, &query->locator, "Triple with non-URI/blank node subject skipped"); skipped = 1; break; } if(skipped) { if(s) rasqal_free_literal(s); continue; } p = rasqal_literal_as_node(t->predicate); if(!p) { rasqal_log_warning_simple(query_results->world, RASQAL_WARNING_LEVEL_BAD_TRIPLE, &query->locator, "Triple with unbound predicate skipped"); rasqal_free_literal(s); skipped = 1; continue; } switch(p->type) { case RASQAL_LITERAL_URI: /* raptor v2 terms are copied, not shared */ if(rs->predicate) { raptor_free_term(rs->predicate); rs->predicate = NULL; } rs->predicate = raptor_new_term_from_uri(query_results->world->raptor_world_ptr, p->value.uri); break; case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_XSD_STRING: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: case RASQAL_LITERAL_UDT: case RASQAL_LITERAL_INTEGER_SUBTYPE: /* QNames should be gone by the time expression eval happens * Everything else is removed by rasqal_literal_as_node() above. */ case RASQAL_LITERAL_BLANK: case RASQAL_LITERAL_STRING: /* blank node or string [literal] predicates are not RDF */ case RASQAL_LITERAL_UNKNOWN: default: rasqal_log_warning_simple(query_results->world, RASQAL_WARNING_LEVEL_BAD_TRIPLE, &query->locator, "Triple with non-URI predicate skipped"); skipped = 1; break; } if(skipped) { rasqal_free_literal(s); if(p) rasqal_free_literal(p); continue; } o = rasqal_literal_as_node(t->object); if(!o) { rasqal_log_warning_simple(query_results->world, RASQAL_WARNING_LEVEL_BAD_TRIPLE, &query->locator, "Triple with unbound object skipped"); rasqal_free_literal(s); rasqal_free_literal(p); skipped = 1; continue; } /* raptor v2 terms are copied, not shared */ if(rs->object) { raptor_free_term(rs->object); rs->object = NULL; } switch(o->type) { case RASQAL_LITERAL_URI: rs->object = raptor_new_term_from_uri(query_results->world->raptor_world_ptr, o->value.uri); break; case RASQAL_LITERAL_BLANK: nodeid = rasqal_prefix_id(query_results->result_count, (unsigned char*)o->string); rasqal_free_literal(o); if(!nodeid) { rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_FATAL, &query->locator, "Could not prefix blank identifier"); rasqal_free_literal(s); rasqal_free_literal(p); return NULL; } o = rasqal_new_simple_literal(query_results->world, RASQAL_LITERAL_BLANK, nodeid); if(!o) { rasqal_log_error_simple(query_results->world, RAPTOR_LOG_LEVEL_FATAL, &query->locator, "Could not create a new subject blank literal"); rasqal_free_literal(s); rasqal_free_literal(p); return NULL; } rs->object = raptor_new_term_from_blank(query_results->world->raptor_world_ptr, nodeid); break; case RASQAL_LITERAL_STRING: rs->object = raptor_new_term_from_literal(query_results->world->raptor_world_ptr, o->string, o->datatype, (const unsigned char*)o->language); break; case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_XSD_STRING: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: case RASQAL_LITERAL_UDT: case RASQAL_LITERAL_INTEGER_SUBTYPE: /* QNames should be gone by the time expression eval happens * Everything else is removed by rasqal_literal_as_node() above. */ case RASQAL_LITERAL_UNKNOWN: default: rasqal_log_warning_simple(query_results->world, RASQAL_WARNING_LEVEL_BAD_TRIPLE, &query->locator, "Triple with unknown object skipped"); skipped = 1; break; } if(skipped) { rasqal_free_literal(s); rasqal_free_literal(p); if(o) rasqal_free_literal(o); continue; } /* dispose previous triple if any */ if(query_results->triple) { rasqal_free_triple(query_results->triple); query_results->triple = NULL; } /* for saving s, p, o for later disposal */ query_results->triple = rasqal_new_triple(s, p, o); /* got triple, return it */ break; } return rs; }
/* * rasqal_regex_match: * @world: world * @locator: locator * @pattern: regex pattern * @regex_flags: regex flags string * @subject: input string * @subject_len: input string length * * INTERNAL - Test if a string matches a regex pattern. * * Intended to be used for executing #RASQAL_EXPR_STR_MATCH and * #RASQAL_EXPR_STR_NMATCH operations (unused: formerly RDQL) * * Return value: <0 on error, 0 for no match, >0 for match * */ int rasqal_regex_match(rasqal_world* world, raptor_locator* locator, const char* pattern, const char* regex_flags, const char* subject, size_t subject_len) { int flag_i = 0; /* regex_flags contains i */ const char *p; #ifdef RASQAL_REGEX_PCRE pcre* re; int compile_options = PCRE_UTF8; int exec_options = 0; const char *re_error = NULL; int erroffset = 0; #endif #ifdef RASQAL_REGEX_POSIX regex_t reg; int compile_options = REG_EXTENDED; int exec_options = 0; #endif int rc = 0; for(p = regex_flags; p && *p; p++) if(*p == 'i') flag_i++; #ifdef RASQAL_REGEX_PCRE if(flag_i) compile_options |= PCRE_CASELESS; re = pcre_compile(RASQAL_GOOD_CAST(const char*, pattern), compile_options, &re_error, &erroffset, NULL); if(!re) { rasqal_log_error_simple(world, RAPTOR_LOG_LEVEL_ERROR, locator, "Regex compile of '%s' failed - %s", pattern, re_error); rc = -1; } else { rc = pcre_exec(re, NULL, /* no study */ subject, RASQAL_BAD_CAST(int, subject_len), /* PCRE API is an int */ 0 /* startoffset */, exec_options /* options */, NULL, 0 /* ovector, ovecsize - no matches wanted */ ); if(rc >= 0) rc = 1; else if(rc != PCRE_ERROR_NOMATCH) { rasqal_log_error_simple(world, RAPTOR_LOG_LEVEL_ERROR, locator, "Regex match failed - returned code %d", rc); rc= -1; } else rc = 0; } pcre_free(re); #endif #ifdef RASQAL_REGEX_POSIX if(flag_i) compile_options |= REG_ICASE; rc = regcomp(®, RASQAL_GOOD_CAST(const char*, pattern), compile_options); if(rc) { rasqal_log_error_simple(world, RAPTOR_LOG_LEVEL_ERROR, locator, "Regex compile of '%s' failed", pattern); rc = -1; } else { rc = regexec(®, RASQAL_GOOD_CAST(const char*, subject), 0, NULL, /* nmatch, regmatch_t pmatch[] - no matches wanted */ exec_options /* eflags */ ); if(!rc) rc = 1; else if (rc != REG_NOMATCH) { rasqal_log_error_simple(world, RAPTOR_LOG_LEVEL_ERROR, locator, "Regex match failed - returned code %d", rc); rc = -1; } else rc = 0; } regfree(®); #endif #ifdef RASQAL_REGEX_NONE rasqal_log_warning_simple(world, RASQAL_WARNING_LEVEL_MISSING_SUPPORT, locator, "Regex support missing, cannot compare '%s' to '%s'", match_string, pattern); rc = -1; #endif return rc; }