Search code examples
mysqlcmysql-connector-c

mySQL Connector/C issue


ALL,

    std::wstring query2 = L"SELECT cols.column_name, cols.data_type, cols.character_maximum_length, cols.character_octet_length, cols.numeric_precision, cols.numeric_scale, cols.column_default, cols.is_nullable, cols.ordinal_position, (CASE WHEN kcu.column_name = cols.column_name THEN 1 ELSE 0 END) as pk_flag FROM information_schema.columns cols, information_schema.key_column_usage kcu WHERE kcu.constraint_name = 'PRIMARY' AND kcu.table_schema = cols.table_schema AND kcu.table_name = cols.table_name AND cols.table_schema = ? AND cols.table_name = ?;";
    MYSQL_BIND params[2];
    unsigned long str_length1, str_length2;
    str_data1 = new char[strlen( schema_name )], str_data2 = new char[strlen( table_name )];
    memset( params, 0, sizeof( params ) );
    str_length1 = strlen( schema_name );
    str_length2 = strlen( table_name );
    strncpy( str_data1, schema_name, strlen( schema_name ) );
    strncpy( str_data2, table_name, strlen( table_name ) );
    params[0].buffer_type = MYSQL_TYPE_STRING;
    params[0].buffer = (char *) str_data1;
    params[0].buffer_length = strlen( schema_name );
    params[0].is_null = 0;
    params[0].length = &str_length1;
    params[1].buffer_type = MYSQL_TYPE_STRING;
    params[1].buffer = (char *) str_data2;
    params[1].buffer_length = strlen( table_name );
    params[1].is_null = 0;
    params[1].length = &str_length2;
    res2 = mysql_stmt_init( m_db );
    if( !res2 )
    {
        std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_error( m_db ) );
        errorMsg.push_back( err );
        return 1;
    }
    if( mysql_stmt_prepare( res2, m_pimpl->m_myconv.to_bytes( query2.c_str() ).c_str(), query2.length() ) )
    {
        std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_error( m_db ) );
        errorMsg.push_back( err );
        return 1;
    }
    if( mysql_stmt_bind_param( res2, params ) )
    {
        std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_error( m_db ) );
        errorMsg.push_back( err );
        return 1;
    }
    if( mysql_stmt_execute( res2 ) )
    {
        std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_error( m_db ) );
        errorMsg.push_back( err );
        return 1;
    }
    MYSQL_ROW table_def;
    MYSQL_RES *queryResult1 = mysql_store_result( m_db );
    if( queryResult1 )
    {
        while( ( table_def = mysql_fetch_row( queryResult1 ) ) )
        {
            std::wstring fieldName = m_pimpl->m_myconv.from_bytes( table_def[0] );
            std::wstring fieldType = m_pimpl->m_myconv.from_bytes( table_def[1] );
        }
    }
    if( mysql_stmt_close( res2 ) )
    {
        std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_error( m_db ) );
        errorMsg.push_back( err );
        return 1;
    }
    delete str_data1;
    str_data1 = NULL;
    delete str_data2;
    str_data2 = NULL;

All mysql_() functions returns success, however, queryResult pointer is NULL. Moreover I can successfully execute this query inside Workbench - it returns some rows.

I'm using latest Connector/C against the mySQL-5.6.35 on Gentoo Linux.

It's probably something really stupid I'm missing, but I don't see what. Could someone provide a second pair of eyes, please?

Thank you.


Solution

  • Apparently, when you use prepared statements, you can't use mysql_fetch_row(). You should use mysql_stmt_bind_result()/mysql_stmt_fetch() pair.