/* 
 * rasqal_expression_evaluate_if:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_IF (condition, true expr, false expr) expressions.
 *
 * Return value: A #rasqal_literal value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_if(rasqal_expression *e,
                              rasqal_evaluation_context *eval_context,
                              int *error_p)
{
  rasqal_literal* l1;
  int b;
  
  l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
  if(*error_p || !l1)
    goto failed;

  /* IF condition */
  b = rasqal_literal_as_boolean(l1, error_p);
  rasqal_free_literal(l1);

  if(*error_p)
    goto failed;

  /* condition is true: evaluate arg2 or false: evaluate arg3 */
  return rasqal_expression_evaluate2(b ? e->arg2 : e->arg3, eval_context,
                                     error_p);

  failed:
  if(error_p)
    *error_p = 1;
  
  return NULL;
}
/* 
 * rasqal_expression_evaluate_in_set:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_IN and RASQAL_EXPR_NOT_IN (expr,
 * expr list) expression.
 *
 * Return value: A #rasqal_literal boolean value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_in_set(rasqal_expression *e,
                                  rasqal_evaluation_context *eval_context,
                                  int *error_p)
{
  rasqal_world* world = eval_context->world;
  int size = raptor_sequence_size(e->args);
  int i;
  rasqal_literal* l1;
  int found = 0;

  l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
  if(*error_p || !l1)
    goto failed;
  
  for(i = 0; i < size; i++) {
    rasqal_expression* arg_e;
    rasqal_literal* arg_literal;
    
    arg_e = (rasqal_expression*)raptor_sequence_get_at(e->args, i);
    arg_literal = rasqal_expression_evaluate2(arg_e, eval_context, error_p);
    if(!arg_literal)
      goto failed;
    
    found = (rasqal_literal_equals_flags(l1, arg_literal, 
                                         eval_context->flags, error_p) != 0);
#if RASQAL_DEBUG > 1
    if(*error_p)
      RASQAL_DEBUG1("rasqal_literal_equals_flags() returned: FAILURE\n");
    else
      RASQAL_DEBUG2("rasqal_literal_equals_flags() returned: %d\n", found);
#endif
    rasqal_free_literal(arg_literal);

    if(*error_p)
      goto failed;

    if(found)
      /* found - terminate search */
      break;
  }
  rasqal_free_literal(l1);

  if(e->op == RASQAL_EXPR_NOT_IN)
    found = !found;
  return rasqal_new_boolean_literal(world, found);

  failed:
  if(error_p)
    *error_p = 1;
  
  if(l1)
    rasqal_free_literal(l1);

  return NULL;
}
/* 
 * rasqal_expression_evaluate_abs:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate SPARQL 1.1 RASQAL_EXPR_ABS (numeric) expression.
 *
 * Return value: A #rasqal_literal value or NULL on failure.
 */
rasqal_literal*
rasqal_expression_evaluate_abs(rasqal_expression *e,
                               rasqal_evaluation_context *eval_context,
                               int *error_p)
{
  rasqal_literal* l1;
  rasqal_literal* result = NULL;

  l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
  if(*error_p || !l1)
    goto failed;
  
  if(!rasqal_literal_is_numeric(l1))
    goto failed;

  result = rasqal_literal_abs(l1, error_p);
  rasqal_free_literal(l1);
  l1 = NULL;
  
  if(*error_p)
    goto failed;

  return result;

  failed:
  if(error_p)
    *error_p = 1;
  
  if(l1)
    rasqal_free_literal(l1);

  return NULL;
}
/* 
 * rasqal_expression_evaluate_lang:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_LANG (literal expr) expression.
 *
 * Return value: A #rasqal_literal value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_lang(rasqal_expression *e,
                                rasqal_evaluation_context *eval_context,
                                int *error_p)
{
  rasqal_world* world = eval_context->world;
  rasqal_literal* l1;
  int free_literal = 1;
  rasqal_variable* v = NULL;
  unsigned char* new_s;
      
  l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
  if(*error_p || !l1)
    goto failed;

  v = rasqal_literal_as_variable(l1);
  if(v) {
    rasqal_free_literal(l1);

    l1 = v->value; /* don't need v after this */

    free_literal = 0;
    if(!l1)
      goto failed;
  }
  
  if(rasqal_literal_get_rdf_term_type(l1) != RASQAL_LITERAL_STRING)
    goto failed;
  
  if(l1->language) {
    size_t len = strlen(l1->language);
    new_s = (unsigned char*)RASQAL_MALLOC(cstring, len + 1);
    if(!new_s)
      goto failed;

    memcpy((char*)new_s, l1->language, len + 1);
  } else  {
    new_s = (unsigned char*)RASQAL_MALLOC(cstring, 1);
    if(!new_s)
      goto failed;

    *new_s = '\0';
  }

  if(free_literal)
    rasqal_free_literal(l1);

  /* after this new_s is owned by result */
  return rasqal_new_string_literal(world, new_s, NULL, NULL, NULL);

  failed:
  if(error_p)
    *error_p = 1;
  
  if(free_literal)
    rasqal_free_literal(l1);

  return NULL;
}
/* 
 * rasqal_expression_evaluate_datatype:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_DATATYPE (string literal) expression.
 *
 * Return value: A #rasqal_literal URI value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_datatype(rasqal_expression *e,
                                    rasqal_evaluation_context *eval_context,
                                    int *error_p)
{
  rasqal_world* world = eval_context->world;
  rasqal_literal* l1;
  int free_literal = 1;
  rasqal_variable* v = NULL;
  raptor_uri* dt_uri = NULL;
      
  l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
  if(*error_p || !l1)
    goto failed;

  v = rasqal_literal_as_variable(l1);
  if(v) {
    rasqal_free_literal(l1);

    l1 = v->value; /* don't need v after this */

    free_literal = 0;
    if(!l1)
      goto failed;
  }
  
  if(rasqal_literal_get_rdf_term_type(l1) != RASQAL_LITERAL_STRING)
    goto failed;
  
  if(l1->language)
    goto failed;
  
  /* The datatype of a plain literal is xsd:string */
  dt_uri = l1->datatype;
  if(!dt_uri && l1->type == RASQAL_LITERAL_STRING)
    dt_uri = rasqal_xsd_datatype_type_to_uri(l1->world,
                                             RASQAL_LITERAL_XSD_STRING);
  
  if(!dt_uri)
    goto failed;
  
  dt_uri = raptor_uri_copy(dt_uri);

  if(free_literal)
    rasqal_free_literal(l1);

  /* after this dt_uri is owned by result */
  return rasqal_new_uri_literal(world, dt_uri);

  failed:
  if(error_p)
    *error_p = 1;
  
  if(free_literal)
    rasqal_free_literal(l1);

  return NULL;
}
/* 
 * rasqal_expression_evaluate_sameterm:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_SAMETERM (expr1, expr2) expressions.
 *
 * Return value: A #rasqal_literal boolean value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_sameterm(rasqal_expression *e,
                                    rasqal_evaluation_context *eval_context,
                                    int *error_p)
{
  rasqal_world* world = eval_context->world;
  rasqal_literal* l1;
  rasqal_literal* l2;
  int b;

  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)
    goto failed;

  b = rasqal_literal_same_term(l1, l2);
#if RASQAL_DEBUG > 1
  RASQAL_DEBUG2("rasqal_literal_same_term() returned: %d\n", b);
#endif

  rasqal_free_literal(l1);
  rasqal_free_literal(l2);

  return rasqal_new_boolean_literal(world, b);

  failed:
  if(error_p)
    *error_p = 1;
  
  if(l1)
    rasqal_free_literal(l1);

  return NULL;
}
/* 
 * rasqal_expression_evaluate_istype:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_ISBLANK, RASQAL_EXPR_ISURI,
 * RASQAL_EXPR_ISLITERAL and RASQAL_EXPR_ISNUMERIC (expr)
 * expressions.
 *
 * Return value: A #rasqal_literal boolean value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_istype(rasqal_expression *e,
                                  rasqal_evaluation_context *eval_context,
                                  int *error_p)
{
  rasqal_world* world = eval_context->world;
  rasqal_literal* l1;
  int free_literal = 1;
  rasqal_variable *v;
  int b;
  
  l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
  if(*error_p || !l1)
    goto failed;

  v = rasqal_literal_as_variable(l1);
  if(v) {
    rasqal_free_literal(l1);

    l1 = v->value; /* don't need v after this */

    free_literal = 0;
    if(!l1)
      goto failed;
  }
  
  if(e->op == RASQAL_EXPR_ISBLANK)
    b = (l1->type == RASQAL_LITERAL_BLANK);
  else if(e->op == RASQAL_EXPR_ISLITERAL)
    b = (rasqal_literal_get_rdf_term_type(l1) == RASQAL_LITERAL_STRING);
  else if(e->op == RASQAL_EXPR_ISURI)
    b =(l1->type == RASQAL_LITERAL_URI);
  else
    b = (rasqal_literal_is_numeric(l1));
  
  if(free_literal)
    rasqal_free_literal(l1);
  
  return rasqal_new_boolean_literal(world, b);

failed:
  if(error_p)
    *error_p = 1;
  
  if(free_literal && l1)
    rasqal_free_literal(l1);

  return NULL;
}
/* 
 * rasqal_expression_evaluate_str:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_STR (literal expr) expression.
 *
 * Return value: A #rasqal_literal value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_str(rasqal_expression *e,
                               rasqal_evaluation_context *eval_context,
                               int *error_p)
{
  rasqal_world* world = eval_context->world;
  rasqal_literal* l1 = NULL;
  rasqal_literal* result = NULL;
  const unsigned char *s;
  size_t len;
  unsigned char *new_s;
  
  l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
  if(*error_p || !l1)
    goto failed;
  
  /* Note: flags removes RASQAL_COMPARE_XQUERY as this is the
   * explicit stringify operation and we want URIs as strings.
   */
  s = rasqal_literal_as_counted_string(l1, &len,
                                       (eval_context->flags & ~RASQAL_COMPARE_XQUERY),
                                       error_p);
  if(!s || *error_p)
    goto failed;
  
  new_s = (unsigned char *)RASQAL_MALLOC(cstring, len + 1);
  if(!new_s)
    goto failed;

  memcpy((char*)new_s, (const char*)s, len + 1);
  
  /* after this new_s is owned by result */
  result = rasqal_new_string_literal(world, new_s, NULL, NULL, NULL);

  if(l1)
    rasqal_free_literal(l1);

  return result;
  
  failed:
  if(error_p)
    *error_p = 1;
  
  if(l1)
    rasqal_free_literal(l1);
  
  return NULL;
}
/* 
 * rasqal_expression_evaluate_bnode_constructor:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_BNODE (string) expression.
 *
 * Return value: A #rasqal_literal blank node value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_bnode_constructor(rasqal_expression *e,
                                             rasqal_evaluation_context *eval_context,
                                             int *error_p)
{
  rasqal_world* world = eval_context->world;
  rasqal_literal *l1 = NULL;
  unsigned char *new_s = NULL;

  if(e->arg1) {
    const unsigned char *s;
    size_t len;
    
    l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
    if(*error_p || !l1)
      goto failed;
    
    s = rasqal_literal_as_counted_string(l1, &len, eval_context->flags,
                                         error_p);
    if(*error_p)
      goto failed;

    new_s = (unsigned char*)RASQAL_MALLOC(cstring, len + 1);
    if(!new_s)
      goto failed;

    memcpy((char*)new_s, s, len + 1);

    rasqal_free_literal(l1);
  } else {
    new_s = rasqal_world_generate_bnodeid(world, NULL);
    if(!new_s)
      goto failed;
  }

  /* after this new_s is owned by the result */
  return rasqal_new_simple_literal(world, RASQAL_LITERAL_BLANK, new_s);

  failed:
  if(error_p)
    *error_p = 1;
  
  if(l1)
    rasqal_free_literal(l1);

  return NULL;
}
Exemple #10
0
/**
 * rasqal_expression_evaluate:
 * @world: #rasqal_world
 * @locator: error locator (or NULL)
 * @e: The expression to evaluate.
 * @flags: Flags for rasqal_literal_compare() and RASQAL_COMPARE_NOCASE for string matches.
 * 
 * Evaluate a #rasqal_expression tree to give a #rasqal_literal result
 * or error.
 *
 * @Deprecated: use rasqal_expression_evaluate2() using a #rasqal_evaluation_context
 *
 * Return value: a #rasqal_literal value or NULL on failure.
 **/
rasqal_literal*
rasqal_expression_evaluate(rasqal_world *world, raptor_locator *locator,
                           rasqal_expression* e, int flags)
{
  rasqal_evaluation_context context; /* static */
  int error = 0;
  rasqal_literal* l;
  
  RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
  RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(e, rasqal_expression, NULL);

  memset(&context, sizeof(context), '\0');
  context.world = world;
  context.locator = locator;
  context.flags = flags;

  l = rasqal_expression_evaluate2(e, &context, &error);
  if(error)
    return NULL;
  
  return l;
}
Exemple #11
0
/* 
 * rasqal_expression_evaluate_uri_constructor:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_URI and RASQAL_EXPR_IRI (string)
 * expressions.
 *
 * Return value: A #rasqal_literal URI value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_uri_constructor(rasqal_expression *e,
                                           rasqal_evaluation_context *eval_context,
                                           int *error_p)
{
  rasqal_world* world = eval_context->world;
  rasqal_literal* l1;
  raptor_uri* dt_uri;
  const unsigned char *s;

  l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
  if(*error_p || !l1)
    goto failed;
  
  s = rasqal_literal_as_string_flags(l1, eval_context->flags, error_p);
  if(*error_p)
    goto failed;
  
  dt_uri = raptor_new_uri_relative_to_base(world->raptor_world_ptr,
                                           eval_context->base_uri,
                                           s);
  rasqal_free_literal(l1); l1 = NULL;
  
  if(!dt_uri)
    goto failed;
  
  /* after this dt_uri is owned by the result literal */
  return rasqal_new_uri_literal(world, dt_uri);

  failed:
  if(error_p)
    *error_p = 1;
  
  if(l1)
    rasqal_free_literal(l1);

  return NULL;
}
Exemple #12
0
/* 
 * rasqal_expression_evaluate_coalesce:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_COALESCE (expr list) expressions.
 *
 * Return value: A #rasqal_literal value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_coalesce(rasqal_expression *e,
                                    rasqal_evaluation_context *eval_context,
                                    int *error_p)
{
  int size = raptor_sequence_size(e->args);
  int i;
  
  for(i = 0; i < size; i++) {
    rasqal_expression* arg_e;

    arg_e = (rasqal_expression*)raptor_sequence_get_at(e->args, i);
    if(arg_e) {
      rasqal_literal* result;
      result = rasqal_expression_evaluate2(arg_e, eval_context, error_p);
      if(result)
        return result;
    }
  }
  
  /* No arguments evaluated to an RDF term, return an error (NULL) */
  return NULL;
}
/* 
 * rasqal_expression_evaluate_lang:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_LANG (literal expr) expression.
 *
 * Return value: A #rasqal_literal value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_lang(rasqal_expression *e,
                                rasqal_evaluation_context *eval_context,
                                int *error_p)
{
  rasqal_world* world = eval_context->world;
  rasqal_literal* l1;
  int free_literal = 1;
  rasqal_variable* v = NULL;
  unsigned char* new_s;
      
  l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
  if(*error_p || !l1)
    goto failed;

  v = rasqal_literal_as_variable(l1);
  if(v) {
    rasqal_free_literal(l1);

    l1 = v->value; /* don't need v after this */

    free_literal = 0;
    if(!l1)
      goto failed;
  }
  
  if(rasqal_literal_get_rdf_term_type(l1) != RASQAL_LITERAL_STRING)
    goto failed;
  
  if(l1->language) {
    size_t len = strlen(l1->language);
    new_s = RASQAL_MALLOC(unsigned char*, len + 1);
    if(!new_s)
      goto failed;

    memcpy(RASQAL_GOOD_CAST(char*, new_s), l1->language, len + 1);
  } else  {
static int
rasqal_join_rowsource_init(rasqal_rowsource* rowsource, void *user_data) 
{
  rasqal_join_rowsource_context* con;
  rasqal_variables_table* vars_table; 

  con = (rasqal_join_rowsource_context*)user_data;

  con->failed = 0;
  con->state = JS_START;
  con->constant_join_condition = -1;

  /* If join condition is a constant - optimize it away */
  if(con->expr && rasqal_expression_is_constant(con->expr)) {
    rasqal_query *query = rowsource->query;
    rasqal_literal* result;
    int bresult;
    int error = 0;
    
    result = rasqal_expression_evaluate2(con->expr, query->eval_context,
                                         &error);

#ifdef RASQAL_DEBUG
    RASQAL_DEBUG1("join expression condition is constant: ");
    if(error)
      fputs("type error", DEBUG_FH);
    else
      rasqal_literal_print(result, DEBUG_FH);
    fputc('\n', DEBUG_FH);
#endif

    if(error) {
      bresult = 0;
    } else {
      error = 0;
      bresult = rasqal_literal_as_boolean(result, &error);
#ifdef RASQAL_DEBUG
      if(error)
        RASQAL_DEBUG1("join boolean expression returned error\n");
      else
        RASQAL_DEBUG2("join boolean expression result: %d\n", bresult);
#endif
      rasqal_free_literal(result);
    }

    /* free expression always */
    rasqal_free_expression(con->expr); con->expr = NULL;

    if(con->join_type == RASQAL_JOIN_TYPE_NATURAL) {
      if(!bresult) {
        /* Constraint is always false so row source is finished */
        con->state = JS_FINISHED;
      }
      /* otherwise always true so no need to evaluate on each row
       * and deleting con->expr will handle that
       */
    }

    con->constant_join_condition = bresult;
  }

  rasqal_rowsource_set_requirements(con->left, RASQAL_ROWSOURCE_REQUIRE_RESET);
  rasqal_rowsource_set_requirements(con->right, RASQAL_ROWSOURCE_REQUIRE_RESET);
  
  vars_table = con->left->vars_table;
  con->rc_map = rasqal_new_row_compatible(vars_table, con->left, con->right);
  if(!con->rc_map)
    return -1;

#ifdef RASQAL_DEBUG
  RASQAL_DEBUG2("rowsource %p ", rowsource);
  rasqal_print_row_compatible(stderr, con->rc_map);
#endif

  return 0;
}
static rasqal_row*
rasqal_join_rowsource_read_row(rasqal_rowsource* rowsource, void *user_data)
{
  rasqal_join_rowsource_context* con;
  rasqal_row* row = NULL;
  rasqal_query *query = rowsource->query;

  con = (rasqal_join_rowsource_context*)user_data;

  if(con->failed || con->state == JS_FINISHED)
    return NULL;

  while(1) {
    rasqal_row *right_row;
    int bresult = 1;
    int compatible = 1;

    if(con->state == JS_START) {
      /* start / re-start left */
      if(con->left_row)
        rasqal_free_row(con->left_row);

      con->left_row  = rasqal_rowsource_read_row(con->left);
#ifdef RASQAL_DEBUG
      RASQAL_DEBUG2("rowsource %p read left row : ", rowsource);
      if(con->left_row)
        rasqal_row_print(con->left_row, stderr);
      else
        fputs("NONE", stderr);
      fputs("\n", stderr);
#endif
      con->state = JS_INIT_RIGHT;
    }

    if(con->state == JS_INIT_RIGHT) {
      /* start right */

      if(!con->left_row) {
        con->state = JS_FINISHED;
        return NULL;
      }

      con->right_rows_joined_count = 0;

      rasqal_rowsource_reset(con->right);
    }


    right_row = rasqal_rowsource_read_row(con->right);
#ifdef RASQAL_DEBUG
    RASQAL_DEBUG2("rowsource %p read right row : ", rowsource);
    if(right_row)
      rasqal_row_print(right_row, stderr);
    else
      fputs("NONE", stderr);
    fputs("\n", stderr);
#endif

    if(!right_row && con->state == JS_READ_RIGHT) {
      /* right has finished */

      /* restart left */
      con->state = JS_START;

      /* if all right table returned no bindings, return left row */
      if(!con->right_rows_joined_count) {
        /* otherwise return LEFT or RIGHT row only */
        if(con->join_type == RASQAL_JOIN_TYPE_LEFT) {
          /* LEFT JOIN - add left row if expr fails or not compatible */
          if(con->left_row) {
            con->right_rows_joined_count++;
        
            row = rasqal_join_rowsource_build_merged_row(rowsource, con, NULL);
            break;
          }
        }
      }

      /* restart left by continuing the loop */
      continue;
    }


    /* state is always JS_READ_RIGHT at this point */
    con->state = JS_READ_RIGHT;

    /* now may have both left and right rows so compute compatibility */
    if(right_row) {
      compatible = rasqal_row_compatible_check(con->rc_map,
                                               con->left_row, right_row);
      RASQAL_DEBUG2("join rows compatible: %s\n", compatible ? "YES" : "NO");
    }


    if(con->constant_join_condition >= 0) {
      /* Get constant join expression value */
      bresult = con->constant_join_condition;
    } else if(con->expr) {
      /* Check join expression if present */
      rasqal_literal *result;
      int error = 0;
      
      result = rasqal_expression_evaluate2(con->expr, query->eval_context,
                                           &error);
#ifdef RASQAL_DEBUG
      RASQAL_DEBUG1("join expression result: ");
      if(error)
        fputs("type error", DEBUG_FH);
      else
        rasqal_literal_print(result, DEBUG_FH);
      fputc('\n', DEBUG_FH);
#endif

      if(error) {
        bresult = 0;
      } else {
        error = 0;
        bresult = rasqal_literal_as_boolean(result, &error);
#ifdef RASQAL_DEBUG
        if(error)
          RASQAL_DEBUG1("filter boolean expression returned error\n");
        else
          RASQAL_DEBUG2("filter boolean expression result: %d\n", bresult);
#endif
        rasqal_free_literal(result);
      }
    }
    
    if(con->join_type == RASQAL_JOIN_TYPE_NATURAL) {
      /* found a row if compatible and constraint matches */
      if(compatible && bresult && right_row) {
        con->right_rows_joined_count++;

        /* consumes right_row */
        row = rasqal_join_rowsource_build_merged_row(rowsource, con, right_row);
        break;
      }
      
    } else if(con->join_type == RASQAL_JOIN_TYPE_LEFT) {
      /*
       * { merge(mu1, mu2) | mu1 in Omega1 and mu2 in Omega2, and mu1
       *   and mu2 are compatible and expr(merge(mu1, mu2)) is true }
       */
      if(compatible && bresult) {
        con->right_rows_joined_count++;

        /* No constraint OR constraint & compatible so return merged row */

        /* Compute row only now it is known to be needed (consumes right_row) */
        row = rasqal_join_rowsource_build_merged_row(rowsource, con, right_row);
        break;
      }

#if 0    
      /*
       * { mu1 | mu1 in Omega1 and mu2 in Omega2, and mu1 and mu2 are
       * not compatible }
       */
      if(!compatible) {
        /* otherwise return LEFT or RIGHT row only */
        if(con->join_type == RASQAL_JOIN_TYPE_LEFT) {
          /* LEFT JOIN - add left row if expr fails or not compatible */
          if(con->left_row) {
            con->right_rows_joined_count++;

            row = rasqal_join_rowsource_build_merged_row(rowsource, con, NULL);
            if(right_row)
              rasqal_free_row(right_row);
            break;
          }
        }
      }
#endif

      /*
       * { mu1 | mu1 in Omega1 and mu2 in Omega2, and mu1 and mu2 are
       *   compatible and for all mu2, expr(merge(mu1, mu2)) is false }
       */
      
      /* The above is handled using check for
       * !con->right_rows_joined_count earlier, to generate a row
       * once.
       */

    } /* end if LEFT JOIN */

    if(right_row)
      rasqal_free_row(right_row);
      
  } /* end while */

  if(row) {
    rasqal_row_set_rowsource(row, rowsource);
    row->offset = con->offset++;

    rasqal_row_bind_variables(row, rowsource->query->vars_table);
  }
  
  return row;
}
Exemple #16
0
/**
 * 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;
}
Exemple #17
0
/* 
 * rasqal_expression_evaluate_strdt:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_STRDT(expr) expression.
 *
 * Return value: A #rasqal_literal string value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_strdt(rasqal_expression *e,
                                 rasqal_evaluation_context *eval_context,
                                 int *error_p)
{
  rasqal_world* world = eval_context->world;
  rasqal_literal *l1 = NULL;
  rasqal_literal *l2 = NULL;
  const unsigned char* s = NULL;
  unsigned char* new_s = NULL;
  size_t len;
  raptor_uri* dt_uri = NULL;
  
  l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
  if(*error_p || !l1)
    goto failed;

  if(l1->language || l1->datatype) {
    /* not a simple literal so return NULL success */
    rasqal_free_literal(l1);
    return NULL;
  }
  
  s = rasqal_literal_as_counted_string(l1, &len, eval_context->flags, error_p);
  if(*error_p)
    goto failed;
  
  l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
  if(*error_p || !l2)
    goto failed;
  
  dt_uri = rasqal_literal_as_uri(l2);
  if(dt_uri) {
    dt_uri = raptor_uri_copy(dt_uri);
  } else {
    const unsigned char *uri_string;
    
    uri_string = rasqal_literal_as_string_flags(l2, eval_context->flags,
                                                error_p);
    if(*error_p)
      goto failed;

    dt_uri = raptor_new_uri(world->raptor_world_ptr, uri_string);
    if(!dt_uri)
      goto failed;
  }
  
  new_s =(unsigned char*)RASQAL_MALLOC(cstring, len + 1);
  if(!new_s)
    goto failed;
  memcpy(new_s, s, len + 1);

  rasqal_free_literal(l1);
  rasqal_free_literal(l2);
  
  /* after this new_s and dt_uri become owned by result */
  return rasqal_new_string_literal(world, new_s, /* language */ NULL,
                                   dt_uri, /* qname */ NULL);
  
  
  failed:
  if(error_p)
    *error_p = 1;
  
  if(new_s)
    RASQAL_FREE(cstring, new_s);
  if(l1)
    rasqal_free_literal(l1);
  if(l2)
    rasqal_free_literal(l2);

  return NULL;
}
Exemple #18
0
/* 
 * rasqal_expression_evaluate_strlang:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate RASQAL_EXPR_STRLANG(expr) expression.
 *
 * Return value: A #rasqal_literal string value or NULL on failure.
 */
static rasqal_literal*
rasqal_expression_evaluate_strlang(rasqal_expression *e,
                                   rasqal_evaluation_context *eval_context,
                                   int *error_p)
{
  rasqal_world* world = eval_context->world;
  rasqal_literal *l1 = NULL;
  rasqal_literal *l2 = NULL;
  const unsigned char* s = NULL;
  const unsigned char* lang = NULL;
  unsigned char* new_s = NULL;
  unsigned char* new_lang = NULL;
  size_t len;
  size_t lang_len;

  l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
  if(*error_p || !l1)
    goto failed;
  
  if(l1->language || l1->datatype) {
    /* not a simple literal so return NULL success */
    rasqal_free_literal(l1);
    return NULL;
  }
  
  s = rasqal_literal_as_counted_string(l1, &len, eval_context->flags, error_p);
  if(*error_p)
    goto failed;

  l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
  if(*error_p || !l2)
    goto failed;
  
  lang = rasqal_literal_as_counted_string(l2, &lang_len, eval_context->flags,
                                          error_p);
  if(*error_p)
    goto failed;
  
  new_s = (unsigned char*)RASQAL_MALLOC(cstring, len + 1);
  if(!new_s)
    goto failed;
  memcpy(new_s, s, len + 1);
  
  new_lang = (unsigned char*)RASQAL_MALLOC(cstring, lang_len + 1);
  if(!new_lang)
    goto failed;
  memcpy(new_lang, lang, lang_len + 1);
  
  rasqal_free_literal(l1);
  rasqal_free_literal(l2);

  /* after this new_s and new_lang become owned by result */
  return rasqal_new_string_literal(world, new_s, (const char*)new_lang,
                                   /*datatype */ NULL, /* qname */ NULL);
  

  failed:
  if(error_p)
    *error_p = 1;
  
  if(new_s)
    RASQAL_FREE(cstring, new_s);
  if(l1)
    rasqal_free_literal(l1);
  if(l2)
    rasqal_free_literal(l2);

  return NULL;
}
/* 
 * rasqal_expression_evaluate_digest:
 * @e: The expression to evaluate.
 * @eval_context: Evaluation context
 *
 * INTERNAL - Evaluate SPARQL 1.1 RASQAL_EXPR_MD5, RASQAL_EXPR_SHA1,
 * RASQAL_EXPR_SHA224, RASQAL_EXPR_SHA256, RASQAL_EXPR_SHA384,
 * RASQAL_EXPR_SHA512 (string) expression.
 *
 * Return value: A #rasqal_literal xsd:string value or NULL on failure.
 */
rasqal_literal*
rasqal_expression_evaluate_digest(rasqal_expression *e,
                                  rasqal_evaluation_context *eval_context,
                                  int *error_p)
{
  rasqal_world* world = eval_context->world;
  rasqal_digest_type md_type = RASQAL_DIGEST_NONE;
  rasqal_literal* l1;
  const unsigned char *s;
  unsigned char *new_s;
  size_t len;
  int output_len;
  unsigned char *output = NULL;
  unsigned int i;
  unsigned char* p;
  
  /* Turn EXPR enum into DIGEST enum - we know they are ordered the same */
  if(e->op >= RASQAL_EXPR_MD5 && e->op <= RASQAL_EXPR_SHA512)
    md_type = (rasqal_digest_type)(e->op - RASQAL_EXPR_MD5 + RASQAL_DIGEST_MD5);
  else
    return NULL;

  l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
  if(*error_p || !l1)
    goto failed;
  
  s = rasqal_literal_as_counted_string(l1, &len, eval_context->flags, error_p);
  if(*error_p)
    goto failed;

  output_len = rasqal_digest_buffer(md_type, NULL, NULL, 0);
  if(output_len < 0)
    return NULL;

  output = RASQAL_MALLOC(unsigned char*, output_len);
  if(!output)
    return NULL;
  
  output_len = rasqal_digest_buffer(md_type, output, s, len);
  if(output_len < 0)
    goto failed;

  new_s = RASQAL_MALLOC(unsigned char*, (output_len * 2) + 1);
  if(!new_s)
    goto failed;
  
  p = new_s;
  for(i = 0; i < RASQAL_GOOD_CAST(unsigned int, output_len); i++) {
    unsigned short hex;
    char c = output[i];

    hex = (c & 0xf0) >> 4;
    *p++ = (hex < 10) ? ('0' + hex) : ('a' + hex - 10);
    hex = (c & 0x0f);
    *p++ = (hex < 10) ? ('0' + hex) : ('a' + hex - 10);
  }
  *p = '\0';

  RASQAL_FREE(char, output);
  rasqal_free_literal(l1);

  /* after this new_s becomes owned by result */
  return rasqal_new_string_literal(world, new_s, NULL, NULL, NULL);
  
  failed:
  if(output)
    RASQAL_FREE(char, output);
  if(l1)
    rasqal_free_literal(l1);
  
  return NULL;
}