Cassdra cppdriver Запрос Переполнение буфера строки?

Я писал оболочку для Cppandriver Cassandra для CQL3.0, и я столкнулся с каким-то странным поведением, и я не уверен, типично ли это или ошибка.

Для справки, я работаю с выпуском кода cppdriver 4 сентября (из репозитория), libuv0.10 и примерами песен / плейлистов, размещенными на сайте datastax ( http://www.datastax.com/documentation/cql/3.1/cql/ddl/ddl_music_service_c.html)

Проблема, с которой я сталкиваюсь, связана с выполнением строк запроса. Кажется, есть некоторый порог символов, после которого строка запроса, отправляемая Кассандре, становится мусором. Код, который я использую для создания и отправки строки в библиотеку cppdriver (и анализа результатов), представлен ниже. Я добавил функцию (cass_session_print_query) в файлы cassandra.h и session.cpp, чтобы распечатать сгенерированный оператор.

map<string, vector<string> > retresults;
int i = 0, ccount;
stringstream ss;
vector<string> keys = get.GetList();
vector<string>::iterator kit = keys.begin();
map<int, pair<string, string> > primkeys = get.GetMap();
map<int, pair<string, string> >::iterator mit = primkeys.begin();

if (!keys.empty())
{
    ss << "SELECT " << (*kit);
    ++kit;
    for ( ; kit != keys.end(); ++kit)
        ss << "," << (*kit);

    ss << " FROM " << tablename;
    if (!primkeys.empty())
    {
        ss << " WHERE ";
        ss << mit->second.first << " = ?";
        ++mit;
        for ( ; mit != primkeys.end(); ++mit)
            ss << " and " << mit->second.first << " = ?";
        mit = primkeys.begin();
    }

    ss << ";";

    cass_bool_t has_more_pages = cass_false;
    const CassResult* result = NULL;
    CassString query = cass_string_init(ss.str().c_str());
    CassStatement* statement = cass_statement_new(query, primkeys.size());
    for ( ; mit != primkeys.end(); ++mit)
        cass_statement_bind_string(statement, i++, cass_string_init(mit->second.second.c_str()));

    cass_statement_set_paging_size(statement, 100);
    do
    {
        cass_session_print_query(statement);
        CassIterator* iterator;
        CassFuture* future = cass_session_execute(session_, statement);
        if (cass_future_error_code(future) != 0)
        {
            CassString message = cass_future_error_message(future);
            fprintf(stderr, "Error: %.*s\n", (int)message.length, message.data);
            break;
        }

        result = cass_future_get_result(future);
        ccount = cass_result_column_count(result);
        vector<string> cnames;
        for (i = 0; i < ccount; i++)
            cnames.push_back(cass_result_column_name(result, i).data);

        iterator = cass_iterator_from_result(result);
        ListVector::iterator vit;
        while (cass_iterator_next(iterator))
        {
            const CassRow* row = cass_iterator_get_row(iterator);
            for (vit = cnames.begin(); vit != cnames.end(); ++vit)
            {
                CassString value;
                char value_buffer[256];
                cass_value_get_string(cass_row_get_column_by_name(row, (*vit).c_str()), &value);
                if (value.length == 0 || value.data == NULL)
                    continue;
                memcpy(value_buffer, value.data, value.length);
                value_buffer[value.length] = '\0';
                retresults[(*vit)].push_back(value_buffer);
            }
        }

        has_more_pages = cass_result_has_more_pages(result);
        if (has_more_pages)
        cass_statement_set_paging_state(statement, result);

        cass_iterator_free(iterator);
        cass_result_free(result);
    } while (has_more_pages);
}

return retresults;

При этом начальная строка запроса SELECT id,album,title,artist,data FROM songs; приводит к строке запроса Cassandra SELECT id,album,title,artist,data FROM songs;, Однако, если я добавлю еще один столбец в часть SELECT SELECT id,album,title,artist,data,tags FROM songs; строка запроса в библиотеке Cassandra cppdriver становится примерно такой: ,ar����,dat�� jOM songX, Это приводит к следующей ошибке из Cassandra / library: Error: line 1:49 no viable alternative at character '�',

Я также пробовал меньше столбцов, но с предложением WHERE, и это приводит к той же проблеме.

Это ошибка? Или я неправильно строю и отправляю строки в библиотеку cppdriver?

4 ответа

Решение

Вы должны cass_future_wait() в будущем выполнения перед проверкой кода ошибки.

Несвязанный: есть также несколько вещей, которые должны быть освобождены (будущее, утверждение), но я предполагаю, что это было опущено, чтобы сохранить это сжатым.

Таким образом, похоже (по какой-то причине) я должен разобрать ключ строки из результатов. Я проверил пример и не смог разобрать информацию о ключе строки, и все по-прежнему работало. Я еще не совсем уверен, что заставляет меня делать это (по сравнению с приведенным примером подкачки), но для других вам необходимо включить в while (cass_iterator_nex(iterator)) блок, чтобы "волшебным образом" исправить мой код выше.

CassUuid key;
char key_buffer[CASS_UUID_STRING_LENGTH];
const CassRow* row = cass_iterator_get_row(iterator);
cass_value_get_uuid(cass_row_get_column(row, 0), key);
cass_uuid_string(key, key_buffer);

Код AeroBuffalo работал для меня, за исключением того, что я должен был поставить '&' перед вторым параметром функции cass_value_get_uuid(). Требуется ссылочный тип.

cass_value_get_uuid(cass_row_get_column(row, 0), &key);

Это действительно долгий путь, но, поскольку вы упомянули пример Music Service, возможно, вы загружали и использовали строки запроса cql_collections.zip? Если так, строки (теперь исправленные) имели незначительные синтаксические ошибки:

использовать музыку
-CREATE TABLE music.songs ( id uuid PRIMARY KEY, текст альбома, текст исполнителя, блок данных, список обзоров, набор тегов, текст заголовка, карта места проведения
+ использовать музыку;
+CREATE TABLE music.songs ( id uuid PRIMARY KEY, текст альбома, текст исполнителя, блок данных, список обзоров, набор тегов, текст заголовка, карта места проведения);
Другие вопросы по тегам