예제 #1
0
    grn_ctx *pull(void) {
      MRN_DBUG_ENTER_METHOD();
      grn_ctx *ctx = NULL;

      {
        time_t now;
        time(&now);

        mrn::Lock lock(mutex_);
        if (pool_) {
          ctx = static_cast<grn_ctx *>(pool_->data);
          list_pop(pool_);
          if ((now - last_pull_time_) >= CLEAR_THREATHOLD_IN_SECONDS) {
            clear();
          }
        }
        last_pull_time_ = now;
      }

      if (!ctx) {
        ctx = grn_ctx_open(0);
      }

      DBUG_RETURN(ctx);
    }
예제 #2
0
  bool ConditionConverter::is_convertable(const Item *item) {
    MRN_DBUG_ENTER_METHOD();

    if (!item) {
      DBUG_RETURN(false);
    }

    switch (item->type()) {
    case Item::COND_ITEM:
      {
        const Item_cond *cond_item = reinterpret_cast<const Item_cond *>(item);
        bool convertable = is_convertable(cond_item);
        DBUG_RETURN(convertable);
      }
      break;
    case Item::FUNC_ITEM:
      {
        const Item_func *func_item = reinterpret_cast<const Item_func *>(item);
        bool convertable = is_convertable(func_item);
        DBUG_RETURN(convertable);
      }
      break;
    default:
      DBUG_RETURN(false);
      break;
    }

    DBUG_RETURN(false);
  }
예제 #3
0
  bool ConditionConverter::have_index(const Item_field *field_item,
                                      Item_func::Functype func_type) {
    MRN_DBUG_ENTER_METHOD();

    bool have = false;
    switch (func_type) {
    case Item_func::EQ_FUNC:
      have = have_index(field_item, GRN_OP_EQUAL);
      break;
    case Item_func::LT_FUNC:
      have = have_index(field_item, GRN_OP_LESS);
      break;
    case Item_func::LE_FUNC:
      have = have_index(field_item, GRN_OP_LESS_EQUAL);
      break;
    case Item_func::GE_FUNC:
      have = have_index(field_item, GRN_OP_GREATER_EQUAL);
      break;
    case Item_func::GT_FUNC:
      have = have_index(field_item, GRN_OP_GREATER);
      break;
    default:
      break;
    }

    DBUG_RETURN(have);
  }
예제 #4
0
  bool FieldNormalizer::should_normalize() {
    MRN_DBUG_ENTER_METHOD();

    DBUG_PRINT("info",
               ("mroonga: result_type = %u", field_->result_type()));
    DBUG_PRINT("info",
               ("mroonga: charset->name = %s", field_->charset()->name));
    DBUG_PRINT("info",
               ("mroonga: charset->csname = %s", field_->charset()->csname));
    DBUG_PRINT("info",
               ("mroonga: charset->state = %u", field_->charset()->state));
    bool need_normalize_p;
    if (field_->charset()->state & (MY_CS_BINSORT | MY_CS_CSSORT)) {
      need_normalize_p = false;
      DBUG_PRINT("info",
                 ("mroonga: should_normalize: false: sort is required"));
    } else {
      if (is_text_type()) {
        need_normalize_p = true;
        DBUG_PRINT("info", ("mroonga: should_normalize: true: text type"));
      } else {
        need_normalize_p = false;
        DBUG_PRINT("info", ("mroonga: should_normalize: false: no text type"));
      }
    }

    DBUG_RETURN(need_normalize_p);
  }
예제 #5
0
  bool IndexTableName::is_custom_name(const char *table_name,
                                      size_t table_name_length,
                                      const char *index_table_name,
                                      size_t index_table_name_length)
  {
    MRN_DBUG_ENTER_METHOD();

    if (index_table_name_length <= (table_name_length + strlen(SEPARATOR))) {
      DBUG_RETURN(true);
    }

    if (strncmp(table_name, index_table_name, table_name_length) != 0) {
      DBUG_RETURN(true);
    }

    if ((strncmp(OLD_SEPARATOR,
                 index_table_name + table_name_length,
                 strlen(OLD_SEPARATOR)) != 0) &&
        (strncmp(SEPARATOR,
                 index_table_name + table_name_length,
                 strlen(SEPARATOR)) != 0)) {
      DBUG_RETURN(true);
    }

    DBUG_RETURN(false);
  }
예제 #6
0
 bool FieldNormalizer::is_text_type() {
   MRN_DBUG_ENTER_METHOD();
   bool text_type_p;
   switch (field_->type()) {
   case MYSQL_TYPE_VARCHAR:
   case MYSQL_TYPE_BLOB:
   case MYSQL_TYPE_VAR_STRING:
     text_type_p = true;
     break;
   case MYSQL_TYPE_STRING:
     switch (field_->real_type()) {
     case MYSQL_TYPE_ENUM:
     case MYSQL_TYPE_SET:
       text_type_p = false;
       break;
     default:
       text_type_p = true;
       break;
     }
     break;
   default:
     text_type_p = false;
     break;
   }
   DBUG_RETURN(text_type_p);
 }
예제 #7
0
  bool ConditionConverter::is_convertable_between(const Item_field *field_item,
                                                  Item *min_item,
                                                  Item *max_item) {
    MRN_DBUG_ENTER_METHOD();

    bool convertable = false;

    enum_field_types field_type = field_item->field_type();
    NormalizedType normalized_type = normalize_field_type(field_type);
    switch (normalized_type) {
    case STRING_TYPE:
      if (min_item->type() == Item::STRING_ITEM &&
          max_item->type() == Item::STRING_ITEM) {
        convertable = have_index(field_item, GRN_OP_LESS);
      }
      break;
    case INT_TYPE:
      if (min_item->type() == Item::INT_ITEM &&
          max_item->type() == Item::INT_ITEM) {
        convertable = have_index(field_item, GRN_OP_LESS);
      }
      break;
    case TIME_TYPE:
      if (is_valid_time_value(field_item, min_item) &&
          is_valid_time_value(field_item, max_item)) {
        convertable = have_index(field_item, GRN_OP_LESS);
      }
      break;
    case UNSUPPORTED_TYPE:
      break;
    }

    DBUG_RETURN(convertable);
  }
예제 #8
0
  bool ConditionConverter::get_time_value(const Item_field *field_item,
                                          Item *value_item,
                                          MYSQL_TIME *mysql_time) {
    MRN_DBUG_ENTER_METHOD();

    bool error;
    Item *real_value_item = value_item->real_item();
    switch (field_item->field_type()) {
    case MYSQL_TYPE_TIME:
      error = real_value_item->get_time(mysql_time);
      break;
    case MYSQL_TYPE_YEAR:
      mysql_time->year        = static_cast<int>(value_item->val_int());
      mysql_time->month       = 1;
      mysql_time->day         = 1;
      mysql_time->hour        = 0;
      mysql_time->hour        = 0;
      mysql_time->minute      = 0;
      mysql_time->second_part = 0;
      mysql_time->neg         = false;
      mysql_time->time_type   = MYSQL_TIMESTAMP_DATE;
      error = false;
      break;
    default:
      error = real_value_item->get_date(mysql_time, TIME_FUZZY_DATE);
      break;
    }

    DBUG_RETURN(error);
  }
예제 #9
0
  bool ConditionConverter::is_convertable_binary_operation(
    const Item_field *field_item,
    Item *value_item,
    Item_func::Functype func_type) {
    MRN_DBUG_ENTER_METHOD();

    bool convertable = false;

    enum_field_types field_type = field_item->field_type();
    NormalizedType normalized_type = normalize_field_type(field_type);
    switch (normalized_type) {
    case STRING_TYPE:
      if (value_item->type() == Item::STRING_ITEM &&
          func_type == Item_func::EQ_FUNC) {
        convertable = have_index(field_item, GRN_OP_EQUAL);
      }
      break;
    case INT_TYPE:
      convertable = value_item->type() == Item::INT_ITEM;
      break;
    case TIME_TYPE:
      if (is_valid_time_value(field_item, value_item)) {
        convertable = have_index(field_item, func_type);
      }
      break;
    case UNSUPPORTED_TYPE:
      break;
    }

    DBUG_RETURN(convertable);
  }
예제 #10
0
  Operation::~Operation() {
    MRN_DBUG_ENTER_METHOD();

    operations_->finish(id_);

    DBUG_VOID_RETURN;
  }
예제 #11
0
  void ConditionConverter::convert_between(const Item_func *func_item,
                                           grn_obj *expression) {
    MRN_DBUG_ENTER_METHOD();

    Item **arguments = func_item->arguments();
    Item *target_item = arguments[0];
    Item *min_item = arguments[1];
    Item *max_item = arguments[2];

    grn_obj *between_func = grn_ctx_get(ctx_, "between", strlen("between"));
    grn_expr_append_obj(ctx_, expression, between_func, GRN_OP_PUSH, 1);

    const Item_field *field_item = static_cast<const Item_field *>(target_item);
    append_field_value(field_item, expression);

    grn_obj include;
    mrn::SmartGrnObj smart_include(ctx_, &include);
    GRN_TEXT_INIT(&include, 0);
    GRN_TEXT_PUTS(ctx_, &include, "include");
    append_const_item(field_item, min_item, expression);
    grn_expr_append_const(ctx_, expression, &include, GRN_OP_PUSH, 1);
    append_const_item(field_item, max_item, expression);
    grn_expr_append_const(ctx_, expression, &include, GRN_OP_PUSH, 1);

    grn_expr_append_op(ctx_, expression, GRN_OP_CALL, 5);

    grn_expr_append_op(ctx_, expression, GRN_OP_AND, 2);

    DBUG_VOID_RETURN;
  }
예제 #12
0
  void Operation::record_target(grn_id record_id) {
    MRN_DBUG_ENTER_METHOD();

    operations_->record_target(id_, record_id);

    DBUG_VOID_RETURN;
  }
예제 #13
0
  bool ConditionConverter::is_valid_time_value(const Item_field *field_item,
                                               Item *value_item) {
    MRN_DBUG_ENTER_METHOD();

    MYSQL_TIME mysql_time;
    bool error = get_time_value(field_item, value_item, &mysql_time);

    DBUG_RETURN(!error);
  }
예제 #14
0
  void FieldNormalizer::find_grn_normalizer(grn_obj *normalizer) {
    MRN_DBUG_ENTER_METHOD();

    const CHARSET_INFO *charset_info = field_->charset();
    const char *normalizer_name = NULL;
    const char *normalizer_spec = NULL;
    const char *default_normalizer_name = "NormalizerAuto";
    if ((strcmp(charset_info->name, "utf8_general_ci") == 0) ||
        (strcmp(charset_info->name, "utf8mb4_general_ci") == 0)) {
      normalizer_name = normalizer_spec = "NormalizerMySQLGeneralCI";
    } else if ((strcmp(charset_info->name, "utf8_unicode_ci") == 0) ||
               (strcmp(charset_info->name, "utf8mb4_unicode_ci") == 0)) {
      normalizer_name = normalizer_spec = "NormalizerMySQLUnicodeCI";
    } else if ((strcmp(charset_info->name, "utf8_unicode_520_ci") == 0) ||
               (strcmp(charset_info->name, "utf8mb4_unicode_520_ci") == 0)) {
      normalizer_name = normalizer_spec = "NormalizerMySQLUnicode520CI";
    } else if ((strcmp(charset_info->name, "utf8mb4_0900_ai_ci") == 0)) {
      normalizer_name = "NormalizerMySQLUnicode900";
      normalizer_spec = "NormalizerMySQLUnicode900('weight_level', 1)";
    } else if ((strcmp(charset_info->name, "utf8mb4_0900_as_ci") == 0)) {
      normalizer_name = "NormalizerMySQLUnicode900";
      normalizer_spec = "NormalizerMySQLUnicode900('weight_level', 2)";
    } else if ((strcmp(charset_info->name, "utf8mb4_0900_as_cs") == 0)) {
      normalizer_name = "NormalizerMySQLUnicode900";
      normalizer_spec = "NormalizerMySQLUnicode900('weight_level', 3)";
    } else if ((strcmp(charset_info->name, "utf8mb4_ja_0900_as_cs") == 0)) {
      normalizer_name = "NormalizerMySQLUnicode900";
      normalizer_spec =
        "NormalizerMySQLUnicode900('locale', 'ja', 'weight_level', 3)";
    } else if ((strcmp(charset_info->name, "utf8mb4_ja_0900_as_cs_ks") == 0)) {
      normalizer_name = "NormalizerMySQLUnicode900";
      normalizer_spec =
        "NormalizerMySQLUnicode900('locale', 'ja', 'weight_level', 4)";
    }

    if (normalizer_name) {
      if (!grn_ctx_get(ctx_, normalizer_name, -1)) {
        char error_message[MRN_MESSAGE_BUFFER_SIZE];
        snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
                 "%s normalizer isn't found for %s. "
                 "Install groonga-normalizer-mysql normalizer. "
                 "%s is used as fallback.",
                 normalizer_name,
                 charset_info->name,
                 default_normalizer_name);
        push_warning(thread_, MRN_SEVERITY_WARNING,
                     HA_ERR_UNSUPPORTED, error_message);
        normalizer_name = NULL;
      }
    }
    if (!normalizer_name) {
      normalizer_name = normalizer_spec = default_normalizer_name;
    }
    GRN_TEXT_PUTS(ctx_, normalizer, normalizer_spec);

    DBUG_VOID_RETURN;
  }
예제 #15
0
 void clear(void) {
   MRN_DBUG_ENTER_METHOD();
   while (pool_) {
     grn_ctx *ctx = static_cast<grn_ctx *>(pool_->data);
     grn_ctx_close(ctx);
     list_pop(pool_);
   }
   DBUG_VOID_RETURN;
 }
예제 #16
0
    void release(grn_ctx *ctx) {
      MRN_DBUG_ENTER_METHOD();

      {
        mrn::Lock lock(mutex_);
        list_push(pool_, ctx);
        grn_ctx_use(ctx, NULL);
      }

      DBUG_VOID_RETURN;
    }
예제 #17
0
 grn_obj *FieldNormalizer::normalize(const char *string,
                                     unsigned int string_length) {
   MRN_DBUG_ENTER_METHOD();
   grn_obj *normalizer = find_grn_normalizer();
   int flags = 0;
   grn_encoding original_encoding = GRN_CTX_GET_ENCODING(ctx_);
   encoding::set(ctx_, field_->charset());
   grn_obj *grn_string = grn_string_open(ctx_, string, string_length,
                                         normalizer, flags);
   GRN_CTX_SET_ENCODING(ctx_, original_encoding);
   DBUG_RETURN(grn_string);
 }
예제 #18
0
  void ConditionConverter::append_field_value(const Item_field *field_item,
                                              grn_obj *expression) {
    MRN_DBUG_ENTER_METHOD();

    GRN_BULK_REWIND(&column_name_);
    GRN_TEXT_PUT(ctx_, &column_name_,
                 MRN_ITEM_FIELD_GET_NAME(field_item),
                 MRN_ITEM_FIELD_GET_NAME_LENGTH(field_item));
    grn_expr_append_const(ctx_, expression, &column_name_,
                          GRN_OP_PUSH, 1);
    grn_expr_append_op(ctx_, expression, GRN_OP_GET_VALUE, 1);

    DBUG_VOID_RETURN;
  }
예제 #19
0
  void ConditionConverter::convert(const Item *where, grn_obj *expression) {
    MRN_DBUG_ENTER_METHOD();

    if (!where || where->type() != Item::COND_ITEM) {
      DBUG_VOID_RETURN;
    }

    Item_cond *cond_item = (Item_cond *)where;
    List_iterator<Item> iterator(*((cond_item)->argument_list()));
    const Item *sub_item;
    while ((sub_item = iterator++)) {
      switch (sub_item->type()) {
      case Item::FUNC_ITEM:
        {
          const Item_func *func_item = (const Item_func *)sub_item;
          switch (func_item->functype()) {
          case Item_func::EQ_FUNC:
            convert_binary_operation(func_item, expression, GRN_OP_EQUAL);
            break;
          case Item_func::LT_FUNC:
            convert_binary_operation(func_item, expression, GRN_OP_LESS);
            break;
          case Item_func::LE_FUNC:
            convert_binary_operation(func_item, expression, GRN_OP_LESS_EQUAL);
            break;
          case Item_func::GE_FUNC:
            convert_binary_operation(func_item, expression,
                                     GRN_OP_GREATER_EQUAL);
            break;
          case Item_func::GT_FUNC:
            convert_binary_operation(func_item, expression, GRN_OP_GREATER);
            break;
          case Item_func::BETWEEN:
            convert_between(func_item, expression);
            break;
          default:
            break;
          }
        }
        break;
      default:
        break;
      }
    }

    DBUG_VOID_RETURN;
  }
예제 #20
0
  void ConditionConverter::append_const_item(const Item_field *field_item,
                                             Item *const_item,
                                             grn_obj *expression) {
    MRN_DBUG_ENTER_METHOD();

    enum_field_types field_type = field_item->field_type();
    NormalizedType normalized_type = normalize_field_type(field_type);

    switch (normalized_type) {
    case STRING_TYPE:
      grn_obj_reinit(ctx_, &value_, GRN_DB_TEXT, 0);
      {
        String *string;
        string = const_item->val_str(NULL);
        GRN_TEXT_SET(ctx_, &value_, string->ptr(), string->length());
      }
      break;
    case INT_TYPE:
      grn_obj_reinit(ctx_, &value_, GRN_DB_INT64, 0);
      GRN_INT64_SET(ctx_, &value_, const_item->val_int());
      break;
    case TIME_TYPE:
      grn_obj_reinit(ctx_, &value_, GRN_DB_TIME, 0);
      {
        MYSQL_TIME mysql_time;
        get_time_value(field_item, const_item, &mysql_time);
        bool truncated = false;
        TimeConverter time_converter;
        long long int time =
          time_converter.mysql_time_to_grn_time(&mysql_time, &truncated);
        GRN_TIME_SET(ctx_, &value_, time);
      }
      break;
    case UNSUPPORTED_TYPE:
      // Should not be occurred.
      DBUG_PRINT("error",
                 ("mroonga: append_const_item: unsupported type: <%d> "
                  "This case should not be occurred.",
                  field_type));
      grn_obj_reinit(ctx_, &value_, GRN_DB_VOID, 0);
      break;
    }
    grn_expr_append_const(ctx_, expression, &value_, GRN_OP_PUSH, 1);

    DBUG_VOID_RETURN;
  }
예제 #21
0
  bool ConditionConverter::have_index(const Item_field *field_item,
                                      grn_operator _operator) {
    MRN_DBUG_ENTER_METHOD();

    grn_obj *column;
    column = grn_obj_column(ctx_, table_,
                            MRN_ITEM_FIELD_GET_NAME(field_item),
                            MRN_ITEM_FIELD_GET_NAME_LENGTH(field_item));
    if (!column) {
      DBUG_RETURN(false);
    }
    mrn::SmartGrnObj smart_column(ctx_, column);

    int n_indexes = grn_column_index(ctx_, column, _operator, NULL, 0, NULL);
    bool convertable = (n_indexes > 0);

    DBUG_RETURN(convertable);
  }
예제 #22
0
  unsigned int ConditionConverter::count_match_against(const Item *item) {
    MRN_DBUG_ENTER_METHOD();

    if (!item) {
      DBUG_RETURN(0);
    }

    switch (item->type()) {
    case Item::COND_ITEM:
      if (is_storage_mode_) {
        Item_cond *cond_item = (Item_cond *)item;
        if (cond_item->functype() == Item_func::COND_AND_FUNC) {
          unsigned int n_match_againsts = 0;
          List_iterator<Item> iterator(*((cond_item)->argument_list()));
          const Item *sub_item;
          while ((sub_item = iterator++)) {
            n_match_againsts += count_match_against(sub_item);
          }
          DBUG_RETURN(n_match_againsts);
        }
      }
      break;
    case Item::FUNC_ITEM:
      {
        const Item_func *func_item = (const Item_func *)item;
        switch (func_item->functype()) {
        case Item_func::FT_FUNC:
          DBUG_RETURN(1);
          break;
        default:
          break;
        }
      }
      break;
    default:
      break;
    }

    DBUG_RETURN(0);
  }
예제 #23
0
 grn_obj *FieldNormalizer::normalize(const char *string,
                                     unsigned int string_length) {
   MRN_DBUG_ENTER_METHOD();
   grn_obj normalizer;
   GRN_TEXT_INIT(&normalizer, 0);
   find_grn_normalizer(&normalizer);
   int flags = 0;
   grn_encoding original_encoding = GRN_CTX_GET_ENCODING(ctx_);
   encoding::set_raw(ctx_, field_->charset());
   grn_obj *grn_string;
   if (GRN_TEXT_VALUE(&normalizer)[GRN_TEXT_LEN(&normalizer) - 1] == ')') {
     if (!lexicon_) {
       lexicon_ = grn_table_create(ctx_,
                                   NULL, 0,
                                   NULL,
                                   GRN_OBJ_TABLE_PAT_KEY,
                                   grn_ctx_at(ctx_, GRN_DB_SHORT_TEXT),
                                   NULL);
     }
     grn_obj_set_info(ctx_, lexicon_, GRN_INFO_NORMALIZER, &normalizer);
     grn_string = grn_string_open(ctx_,
                                  string,
                                  string_length,
                                  lexicon_,
                                  flags);
   } else {
     grn_string = grn_string_open(ctx_,
                                  string,
                                  string_length,
                                  grn_ctx_get(ctx_,
                                              GRN_TEXT_VALUE(&normalizer),
                                              GRN_TEXT_LEN(&normalizer)),
                                  flags);
   }
   GRN_OBJ_FIN(ctx_, &normalizer);
   GRN_CTX_SET_ENCODING(ctx_, original_encoding);
   DBUG_RETURN(grn_string);
 }
예제 #24
0
  bool ConditionConverter::is_convertable(const Item_cond *cond_item) {
    MRN_DBUG_ENTER_METHOD();

    if (!is_storage_mode_) {
      DBUG_RETURN(false);
    }

    if (cond_item->functype() != Item_func::COND_AND_FUNC) {
      DBUG_RETURN(false);
    }

    List<Item> *argument_list =
      const_cast<Item_cond *>(cond_item)->argument_list();
    List_iterator<Item> iterator(*argument_list);
    const Item *sub_item;
    while ((sub_item = iterator++)) {
      if (!is_convertable(sub_item)) {
        DBUG_RETURN(false);
      }
    }

    DBUG_RETURN(true);
  }
예제 #25
0
  grn_obj *FieldNormalizer::find_grn_normalizer() {
    MRN_DBUG_ENTER_METHOD();

    const CHARSET_INFO *charset_info = field_->charset();
    const char *normalizer_name = NULL;
    const char *default_normalizer_name = "NormalizerAuto";
    if ((strcmp(charset_info->name, "utf8_general_ci") == 0) ||
        (strcmp(charset_info->name, "utf8mb4_general_ci") == 0)) {
      normalizer_name = "NormalizerMySQLGeneralCI";
    } else if ((strcmp(charset_info->name, "utf8_unicode_ci") == 0) ||
               (strcmp(charset_info->name, "utf8mb4_unicode_ci") == 0)) {
      normalizer_name = "NormalizerMySQLUnicodeCI";
    }

    grn_obj *normalizer = NULL;
    if (normalizer_name) {
      normalizer = grn_ctx_get(ctx_, normalizer_name, -1);
      if (!normalizer) {
        char error_message[MRN_MESSAGE_BUFFER_SIZE];
        snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
                 "%s normalizer isn't found for %s. "
                 "Install groonga-normalizer-mysql normalizer. "
                 "%s is used as fallback.",
                 normalizer_name,
                 charset_info->name,
                 default_normalizer_name);
        push_warning(thread_, Sql_condition::WARN_LEVEL_WARN,
                     HA_ERR_UNSUPPORTED, error_message);
      }
    }

    if (!normalizer) {
      normalizer = grn_ctx_get(ctx_, default_normalizer_name, -1);
    }

    DBUG_RETURN(normalizer);
  }
예제 #26
0
 uint IndexTableName::encode(uchar *encoded_start,
                             uchar *encoded_end,
                             const uchar *mysql_string_start,
                             const uchar *mysql_string_end) {
   MRN_DBUG_ENTER_METHOD();
   my_charset_conv_mb_wc mb_wc = system_charset_info->cset->mb_wc;
   my_charset_conv_wc_mb wc_mb = my_charset_filename.cset->wc_mb;
   DBUG_PRINT("info", ("mroonga: in=%s", mysql_string_start));
   encoded_end--;
   uchar *encoded = encoded_start;
   const uchar *mysql_string = mysql_string_start;
   while (mysql_string < mysql_string_end && encoded < encoded_end) {
     my_wc_t wc;
     int mb_wc_converted_length;
     int wc_mb_converted_length;
     mb_wc_converted_length =
       (*mb_wc)(NULL, &wc, mysql_string, mysql_string_end);
     if (mb_wc_converted_length > 0) {
       wc_mb_converted_length = (*wc_mb)(NULL, wc, encoded, encoded_end);
       if (wc_mb_converted_length <= 0) {
         break;
       }
     } else if (mb_wc_converted_length == MY_CS_ILSEQ) {
       *encoded = *mysql_string;
       mb_wc_converted_length = 1;
       wc_mb_converted_length = 1;
     } else {
       break;
     }
     mysql_string += mb_wc_converted_length;
     encoded += wc_mb_converted_length;
   }
   *encoded = '\0';
   DBUG_PRINT("info", ("mroonga: out=%s", encoded_start));
   DBUG_RETURN(encoded - encoded_start);
 }
예제 #27
0
  bool ConditionConverter::is_convertable(const Item_func *func_item) {
    MRN_DBUG_ENTER_METHOD();

    switch (func_item->functype()) {
    case Item_func::EQ_FUNC:
    case Item_func::LT_FUNC:
    case Item_func::LE_FUNC:
    case Item_func::GE_FUNC:
    case Item_func::GT_FUNC:
      if (!is_storage_mode_) {
        DBUG_RETURN(false);
      }
      {
        Item **arguments = func_item->arguments();
        Item *left_item = arguments[0];
        Item *right_item = arguments[1];
        if (left_item->type() != Item::FIELD_ITEM) {
          DBUG_RETURN(false);
        }
        if (!right_item->basic_const_item()) {
          DBUG_RETURN(false);
        }

        bool convertable =
          is_convertable_binary_operation(static_cast<Item_field *>(left_item),
                                          right_item,
                                          func_item->functype());
        DBUG_RETURN(convertable);
      }
      break;
    case Item_func::FT_FUNC:
      DBUG_RETURN(true);
      break;
    case Item_func::BETWEEN:
      if (!is_storage_mode_) {
        DBUG_RETURN(false);
      }
      {
        Item **arguments = func_item->arguments();
        Item *target_item = arguments[0];
        Item *min_item = arguments[1];
        Item *max_item = arguments[2];
        if (target_item->type() != Item::FIELD_ITEM) {
          DBUG_RETURN(false);
        }
        if (!min_item->basic_const_item()) {
          DBUG_RETURN(false);
        }
        if (!max_item->basic_const_item()) {
          DBUG_RETURN(false);
        }

        bool convertable =
          is_convertable_between(static_cast<Item_field *>(target_item),
                                 min_item,
                                 max_item);
        DBUG_RETURN(convertable);
      }
    default:
      DBUG_RETURN(false);
      break;
    }

    DBUG_RETURN(true);
  }
예제 #28
0
  ConditionConverter::NormalizedType
  ConditionConverter::normalize_field_type(enum_field_types field_type) {
    MRN_DBUG_ENTER_METHOD();

    NormalizedType type = UNSUPPORTED_TYPE;

    switch (field_type) {
    case MYSQL_TYPE_DECIMAL:
      type = STRING_TYPE;
      break;
    case MYSQL_TYPE_TINY:
    case MYSQL_TYPE_SHORT:
    case MYSQL_TYPE_LONG:
      type = INT_TYPE;
      break;
    case MYSQL_TYPE_FLOAT:
    case MYSQL_TYPE_DOUBLE:
      type = UNSUPPORTED_TYPE;
      break;
    case MYSQL_TYPE_NULL:
      type = UNSUPPORTED_TYPE;
      break;
    case MYSQL_TYPE_TIMESTAMP:
      type = TIME_TYPE;
      break;
    case MYSQL_TYPE_LONGLONG:
    case MYSQL_TYPE_INT24:
      type = INT_TYPE;
      break;
    case MYSQL_TYPE_DATE:
    case MYSQL_TYPE_TIME:
    case MYSQL_TYPE_DATETIME:
    case MYSQL_TYPE_YEAR:
    case MYSQL_TYPE_NEWDATE:
      type = TIME_TYPE;
      break;
    case MYSQL_TYPE_VARCHAR:
      type = STRING_TYPE;
      break;
    case MYSQL_TYPE_BIT:
      type = INT_TYPE;
      break;
#ifdef MRN_HAVE_MYSQL_TYPE_TIMESTAMP2
    case MYSQL_TYPE_TIMESTAMP2:
      type = TIME_TYPE;
      break;
#endif
#ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2
    case MYSQL_TYPE_DATETIME2:
      type = TIME_TYPE;
      break;
#endif
#ifdef MRN_HAVE_MYSQL_TYPE_TIME2
    case MYSQL_TYPE_TIME2:
      type = TIME_TYPE;
      break;
#endif
    case MYSQL_TYPE_NEWDECIMAL:
      type = STRING_TYPE;
      break;
    case MYSQL_TYPE_ENUM:
      type = INT_TYPE;
      break;
    case MYSQL_TYPE_SET:
      type = INT_TYPE;
      break;
    case MYSQL_TYPE_TINY_BLOB:
    case MYSQL_TYPE_MEDIUM_BLOB:
    case MYSQL_TYPE_LONG_BLOB:
    case MYSQL_TYPE_BLOB:
    case MYSQL_TYPE_VAR_STRING:
    case MYSQL_TYPE_STRING:
      type = STRING_TYPE;
      break;
    case MYSQL_TYPE_GEOMETRY:
      type = UNSUPPORTED_TYPE;
      break;
#ifdef MRN_HAVE_MYSQL_TYPE_JSON
    case MYSQL_TYPE_JSON:
      type = STRING_TYPE;
      break;
#endif
    }

    DBUG_RETURN(type);
  }
예제 #29
0
 void ContextPool::release(grn_ctx *ctx) {
   MRN_DBUG_ENTER_METHOD();
   impl_->release(ctx);
   DBUG_VOID_RETURN;
 }
예제 #30
0
 grn_ctx *ContextPool::pull(void) {
   MRN_DBUG_ENTER_METHOD();
   grn_ctx *ctx = impl_->pull();
   DBUG_RETURN(ctx);
 }