コード例 #1
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);
}
コード例 #2
0
ファイル: rasqal_expr_evaluate.c プロジェクト: sengels/rasqal
/**
 * 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;
}
コード例 #3
0
ファイル: rasqal_row.c プロジェクト: sengels/rasqal
/**
 * rasqal_new_row_sequence:
 * @world: world object ot use
 * @vt: variables table to use to declare variables
 * @row_data: row data
 * @vars_count: number of variables in row
 * @vars_seq_p: OUT parameter - pointer to place to store sequence of variables (or NULL)
 *
 * INTERNAL - Make a sequence of #rasqal_row* objects
 * with variables defined into the @vt table and values in the sequence
 *
 * The @row_data parameter is an array of strings forming a table of
 * width (vars_count * 2).
 * The first row is a list of variable names at offset 0.
 * The remaining rows are values where offset 0 is a literal and
 * offset 1 is a URI string.
 *
 * The last row is indicated by an entire row of NULLs.
 *
 * Return value: sequence of rows or NULL on failure
 */
raptor_sequence*
rasqal_new_row_sequence(rasqal_world* world,
                        rasqal_variables_table* vt,
                        const char* const row_data[],
                        int vars_count,
                        raptor_sequence** vars_seq_p)
{
  raptor_sequence *seq = NULL;
  raptor_sequence *vars_seq = NULL;
  int row_i;
  int column_i;
  int failed = 0;
  
#define GET_CELL(row, column, offset) \
  row_data[((((row)*vars_count)+(column))<<1)+(offset)]

  seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_row,
                            (raptor_data_print_handler)rasqal_row_print);
  if(!seq)
    return NULL;

  if(vars_seq_p) {
    vars_seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_variable,
                                   (raptor_data_print_handler)rasqal_variable_print);
    if(!vars_seq) {
      raptor_free_sequence(seq);
      return NULL;
    }
  }
  
  /* row 0 is variables */
  row_i = 0;

  for(column_i = 0; column_i < vars_count; column_i++) {
    const char * var_name = GET_CELL(row_i, column_i, 0);
    size_t var_name_len = strlen(var_name);
    const unsigned char* name;
    rasqal_variable* v;
    
    name = (unsigned char*)RASQAL_MALLOC(cstring, var_name_len+1);
    if(!name) {
      failed = 1;
      goto tidy;
    }

    memcpy((void*)name, var_name, var_name_len + 1);
    v = rasqal_variables_table_add(vt, RASQAL_VARIABLE_TYPE_NORMAL, name, NULL);
    if(!v) {
      failed = 1;
      goto tidy;
    }

    if(vars_seq) {
      v = rasqal_new_variable_from_variable(v);
      raptor_sequence_push(vars_seq, v);
    }
  }

  for(row_i = 1; 1; row_i++) {
    rasqal_row* row;
    int data_values_seen = 0;

    /* Terminate on an entire row of NULLs */
    for(column_i = 0; column_i < vars_count; column_i++) {
      if(GET_CELL(row_i, column_i, 0) || GET_CELL(row_i, column_i, 1)) {
        data_values_seen++;
        break;
      }
    }
    if(!data_values_seen)
      break;
    
    row = rasqal_new_row_for_size(world, vars_count);
    if(!row) {
      raptor_free_sequence(seq); seq = NULL;
      goto tidy;
    }

    for(column_i = 0; column_i < vars_count; column_i++) {
      rasqal_literal* l = NULL;

      if(GET_CELL(row_i, column_i, 0)) {
        /* string literal */
        const char* str = GET_CELL(row_i, column_i, 0);
        size_t str_len = strlen(str);
        char *eptr = NULL;
        int integer;
        
        integer = (int)strtol((const char*)str, &eptr, 10);
        if(!*eptr) {
          /* is an integer */
          l = rasqal_new_integer_literal(world, RASQAL_LITERAL_INTEGER, 
                                         integer);
        } else {
          unsigned char *val;
          val = (unsigned char*)RASQAL_MALLOC(cstring, str_len+1);
          if(val) {
            memcpy(val, str, str_len + 1);

            l = rasqal_new_string_literal_node(world, val, NULL, NULL);
          } else 
            failed = 1;
        }
      } else if(GET_CELL(row_i, column_i, 1)) {
        /* URI */
        const unsigned char* str;
        raptor_uri* u;
        str = (const unsigned char*)GET_CELL(row_i, column_i, 1);
        u = raptor_new_uri(world->raptor_world_ptr, str);
        if(u)
          l = rasqal_new_uri_literal(world, u);
        else
          failed = 1;
      } else {
        /* variable is not defined for this row */
        continue;
      }

      if(!l) {
        rasqal_free_row(row);
        failed = 1;
        goto tidy;
      }
      rasqal_row_set_value_at(row, column_i, l);
      /* free our copy of literal, rasqal_row has a reference */
      rasqal_free_literal(l);
    }

    raptor_sequence_push(seq, row);
  }

  tidy:
  if(failed) {
    if(seq) {
      raptor_free_sequence(seq);
      seq = NULL;
    }
    if(vars_seq) {
      raptor_free_sequence(vars_seq);
      vars_seq = NULL;
    }
  } else {
    if(vars_seq) {
      if(vars_seq_p)
        *vars_seq_p = vars_seq;
      else
        raptor_free_sequence(vars_seq);
    }
  }
  
  return seq;
}