Skip to content

Commit

Permalink
Merge branch 'master'(3.0) into develop(3.1)
Browse files Browse the repository at this point in the history
  • Loading branch information
lawrinn committed May 16, 2023
2 parents 0fe450b + 2eb9877 commit d809d2b
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 27 deletions.
72 changes: 59 additions & 13 deletions CMakeLists.txt
Expand Up @@ -21,16 +21,24 @@ cmake_minimum_required(VERSION 2.8.12)

CMAKE_POLICY(SET CMP0048 NEW)
CMAKE_POLICY(SET CMP0040 OLD)
#CMAKE_POLICY(SET CMP0057 NEW)
PROJECT(mariadb_connector_odbc
VERSION 3.2.1
LANGUAGES CXX C)

SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
cmake_minimum_required(VERSION 2.8...2.8.12)

GET_PROPERTY(MAODBC_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
# We don't need RC for what we need MAODBC_LANGUAGES for
LIST(REMOVE_ITEM MAODBC_LANGUAGES "RC")

SET(MARIADB_ODBC_VERSION_QUALITY "beta")
SET(MARIADB_ODBC_VERSION "03.02.0001")

SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)

SET(MARIADB_DEFAULT_PLUGINS_SUBDIR "plugin")

SET(DSN_DIALOG_FILES ${CMAKE_SOURCE_DIR}/dsn/odbc_dsn.c
Expand All @@ -47,20 +55,59 @@ MACRO(ADD_OPTION _name _text _default)
ENDIF()
ENDMACRO()

INCLUDE(check_compiler_flag)

IF(WITH_ASAN)
IF(MSVC)
MA_SET_COMPILER_FLAG("-fsanitize=address" DEBUG RELWITHDEBINFO)
SET(MAODBC_LINKER_FLAGS ${MAODBC_LINKER_FLAGS} /INCREMENTAL:NO)
MA_SET_LINKER_FLAG("${MAODBC_LINKER_FLAGS}" DEBUG RELWITHDEBINFO)
ELSE()
MY_CHECK_AND_SET_COMPILER_FLAG("-U_FORTIFY_SOURCE" DEBUG RELWITHDEBINFO)
MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=address -fPIC" DEBUG RELWITHDEBINFO)

SET(WITH_ASAN_OK 1)
FOREACH(lang ${MAODBC_LANGUAGES})
IF(NOT ${have_${lang}__fsanitize_address__fPIC})
SET(WITH_ASAN_OK 0)
ENDIF()
ENDFOREACH()
IF(WITH_ASAN_OK)
OPTION(WITH_ASAN_SCOPE "Enable -fsanitize-address-use-after-scope" OFF)
IF(WITH_ASAN_SCOPE)
MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=address -fsanitize-address-use-after-scope" DEBUG RELWITHDEBINFO)
ENDIF()
ELSE()
MESSAGE(FATAL_ERROR "Do not know how to enable address sanitizer")
ENDIF()
ENDIF()
ENDIF()

IF (WITH_UBSAN)
MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=undefined -fno-sanitize=alignment -U_FORTIFY_SOURCE -DWITH_UBSAN" DEBUG RELWITHDEBINFO)
ENDIF()

IF (WITH_MSAN)
MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=memory -fsanitize-memory-track-origins -U_FORTIFY_SOURCE" DEBUG RELWITHDEBINFO)
ENDIF()

# This has to be before C/C's cmake run, or it will build with /MD
IF(WIN32)
IF (MSVC)
SET(CONFIG_TYPES "DEBUG" "RELEASE" "RELWITHDEBINFO" "MINSIZEREL")
FOREACH(BUILD_TYPE ${CONFIG_TYPES})
FOREACH(COMPILER CXX C)
FOREACH(COMPILER ${MAODBC_LANGUAGES})
SET(COMPILER_FLAGS "${CMAKE_${COMPILER}_FLAGS_${BUILD_TYPE}}")
IF (NOT COMPILER_FLAGS STREQUAL "")
STRING(REPLACE "/MD" "/MT" COMPILER_FLAGS ${COMPILER_FLAGS})
IF (BUILD_TYPE STREQUAL "Debug")
SET(COMPILER_FLAGS "${COMPILER_FLAGS} /RTC1 /RTCc")
IF(NOT WITH_ASAN)
STRING(REPLACE "/MD" "/MT" COMPILER_FLAGS ${COMPILER_FLAGS})
IF (BUILD_TYPE STREQUAL "Debug")
SET(COMPILER_FLAGS "${COMPILER_FLAGS} /RTC1 /RTCc")
ENDIF()
STRING(REPLACE "/Zi" "/ZI" COMPILER_FLAGS ${COMPILER_FLAGS})
ENDIF()
ENDIF(NOT WITH_ASAN)
MESSAGE (STATUS "CMAKE_${COMPILER}_FLAGS_${BUILD_TYPE}= ${COMPILER_FLAGS}")
MESSAGE (STATUS "CMAKE_SHARED_LINKER_FLAGS_${BUILD_TYPE}= ${CMAKE_SHARED_LINKER_FLAGS_${BUILD_TYPE}}")
SET(CMAKE_${COMPILER}_FLAGS_${BUILD_TYPE} ${COMPILER_FLAGS} CACHE
STRING "overwritten by mariadb-odbc" FORCE)
ENDIF()
Expand All @@ -71,15 +118,14 @@ IF(WIN32)
SET(INSTALL_PLUGINDIR "${MARIADB_DEFAULT_PLUGINS_SUBDIR}")
ENDIF()

INCLUDE(${CMAKE_SOURCE_DIR}/cmake/SearchLibrary.cmake)
INCLUDE(${CMAKE_SOURCE_DIR}/cmake/SetValueMacro.cmake)
INCLUDE(SearchLibrary)
INCLUDE(SetValueMacro)

### Build options, initial settings and platform defaults
INCLUDE("${CMAKE_SOURCE_DIR}/cmake/options_defaults.cmake")
INCLUDE("options_defaults")

### Setting installation paths - should go before C/C subproject sets its own. We need to have control over those
INCLUDE("${CMAKE_SOURCE_DIR}/cmake/install.cmake")

INCLUDE("install")

IF(WIN32 OR WITH_OPENSSL OR "${WITH_SSL}" STREQUAL "OPENSSL")
# If C/C is linked dynamically, we don't need link C/ODBC against encryption library
Expand Down Expand Up @@ -115,7 +161,7 @@ IF(NOT USE_SYSTEM_INSTALLED_LIB)
SET(ODBC_GIT_BUILD_SRCPKG TRUE)
ENDIF()
MESSAGE(STATUS "Running C/C cmake scripts")
INCLUDE(${CMAKE_SOURCE_DIR}/cmake/connector_c.cmake)
INCLUDE(connector_c)

INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/driver ${CMAKE_SOURCE_DIR}/libmariadb/include)
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/driver ${CMAKE_BINARY_DIR}/libmariadb/include)
Expand Down Expand Up @@ -199,7 +245,7 @@ ENDIF()

IF(NOT WIN32)
# Looking for DM(UnixODBC) files
INCLUDE(${CMAKE_SOURCE_DIR}/cmake/FindDM.cmake)
INCLUDE(FindDM)

IF(DM_FOUND)
INCLUDE_DIRECTORIES(${ODBC_INCLUDE_DIR})
Expand All @@ -215,7 +261,7 @@ IF(APPLE OR CMAKE_SYSTEM_NAME MATCHES AIX)
SET(PLATFORM_DEPENDENCIES ${PLATFORM_DEPENDENCIES} ${ICONV_LIBRARIES})
ELSE()
# Looking for iconv files
INCLUDE(${CMAKE_SOURCE_DIR}/cmake/FindIconv.cmake)
INCLUDE(FindIconv)
IF(ICONV_FOUND)
INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR})
SET(PLATFORM_DEPENDENCIES ${PLATFORM_DEPENDENCIES} ${ICONV_LIBRARIES})
Expand Down
112 changes: 112 additions & 0 deletions cmake/check_compiler_flag.cmake
@@ -0,0 +1,112 @@
include(CheckCSourceCompiles)
include(CheckCXXSourceCompiles)

# We need some extra FAIL_REGEX patterns
# Note that CHECK_C_SOURCE_COMPILES is a misnomer, it will also link.
SET(fail_patterns
FAIL_REGEX "argument unused during compilation"
FAIL_REGEX "unsupported .*option"
FAIL_REGEX "unknown .*option"
FAIL_REGEX "unrecognized .*option"
FAIL_REGEX "ignoring unknown option"
FAIL_REGEX "warning:.*ignored"
FAIL_REGEX "warning:.*is valid for.*but not for"
FAIL_REGEX "warning:.*redefined"
FAIL_REGEX "[Ww]arning: [Oo]ption"
)
#The regex patterns above are not localized, thus LANG=C
SET(ENV{LANG} C)
MACRO (MY_CHECK_C_COMPILER_FLAG flag)
STRING(REGEX REPLACE "[-,= +]" "_" result "have_C_${flag}")
SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${flag}")
CHECK_C_SOURCE_COMPILES("int main(void) { return 0; }" ${result}
${fail_patterns})
SET(CMAKE_REQUIRED_FLAGS "${SAVE_CMAKE_REQUIRED_FLAGS}")
ENDMACRO()

MACRO (MY_CHECK_CXX_COMPILER_FLAG flag)
STRING(REGEX REPLACE "[-,= +]" "_" result "have_CXX_${flag}")
SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${flag}")
CHECK_CXX_SOURCE_COMPILES("int main(void) { return 0; }" ${result}
${fail_patterns})
SET(CMAKE_REQUIRED_FLAGS "${SAVE_CMAKE_REQUIRED_FLAGS}")
ENDMACRO()

FUNCTION(MY_CHECK_AND_SET_COMPILER_FLAG flag_to_set)
# At the moment this is gcc-only.
# Let's avoid expensive compiler tests on Windows:
IF(WIN32)
RETURN()
ENDIF()
STRING(REGEX REPLACE "^-Wno-" "-W" flag_to_check ${flag_to_set})

LIST(FIND MAODBC_LANGUAGES "C" LANGIDX)
IF(NOT LANGIDX EQUAL -1)
MY_CHECK_C_COMPILER_FLAG(${flag_to_check})
ENDIF()
LIST(FIND MAODBC_LANGUAGES "CXX" LANGIDX)
IF(NOT LANGIDX EQUAL -1)
MY_CHECK_CXX_COMPILER_FLAG(${flag_to_check})
ENDIF()

STRING(REGEX REPLACE "[-,= +]" "_" result "${flag_to_check}")
MESSAGE(STATUS "Langs: ${MAODBC_LANGUAGES}")
FOREACH(lang ${MAODBC_LANGUAGES})
IF (have_${lang}_${result})
IF(ARGN)
FOREACH(type ${ARGN})
SET(CMAKE_${lang}_FLAGS_${type} "${CMAKE_${lang}_FLAGS_${type}} ${flag_to_set}" PARENT_SCOPE)
ENDFOREACH()
ELSE()
SET(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} ${flag_to_set}" PARENT_SCOPE)
ENDIF()
ENDIF()
ENDFOREACH()
ENDFUNCTION()

FUNCTION(MA_SET_COMPILER_FLAG flag_to_set)
IF(MSVC)
STRING(REGEX REPLACE "-" "/" result_flag "${flag_to_set}")
ENDIF()
FOREACH(lang ${MAODBC_LANGUAGES})
IF(ARGN)
FOREACH(type ${ARGN})
STRING(REGEX REPLACE "${result_flag}" "" CMAKE_${lang}_FLAGS_${type} "${CMAKE_${lang}_FLAGS_${type}}")
SET(CMAKE_${lang}_FLAGS_${type} "${CMAKE_${lang}_FLAGS_${type}} ${result_flag}" PARENT_SCOPE)
ENDFOREACH()
ELSE()
STRING(REGEX REPLACE "${result_flag}" "" CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}")
SET(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} ${result_flag}" PARENT_SCOPE)
ENDIF()
ENDFOREACH()
ENDFUNCTION()

FUNCTION(MA_SET_LINKER_FLAG flag_to_set)
IF(MSVC)
STRING(REGEX REPLACE ":NO" "" flag_to_check ${flag_to_set})
STRING(REGEX REPLACE "-" "/" result_flag "${flag_to_set}")
ELSE()
STRING(REGEX REPLACE "^-Wno-" "-W" flag_to_check ${flag_to_set})
SET(result_flag "${flag_to_set}")
ENDIF()
IF(ARGN)
FOREACH(type ${ARGN})
# LIST(REMOVE_ITEM could be better here and in similar places above
STRING(REGEX REPLACE "${flag_to_set}" "" CMAKE_EXE_LINKER_FLAGS_${type} "${CMAKE_EXE_LINKER_FLAGS_${type}}")
STRING(REGEX REPLACE "${flag_to_set}" "" CMAKE_SHARED_LINKER_FLAGS_${type} "${CMAKE_SHARED_LINKER_FLAGS_${type}}")
STRING(REGEX REPLACE "${flag_to_set}" "" CMAKE_MODULE_LINKER_FLAGS_${type} "${CMAKE_MODULE_LINKER_FLAGS_${type}}")
STRING(REGEX REPLACE "${flag_to_check}" "" CMAKE_EXE_LINKER_FLAGS_${type} "${CMAKE_EXE_LINKER_FLAGS_${type}}")
STRING(REGEX REPLACE "${flag_to_check}" "" CMAKE_SHARED_LINKER_FLAGS_${type} "${CMAKE_SHARED_LINKER_FLAGS_${type}}")
STRING(REGEX REPLACE "${flag_to_check}" "" CMAKE_MODULE_LINKER_FLAGS_${type} "${CMAKE_MODULE_LINKER_FLAGS_${type}}")
#MESSAGE(STATUS "Before: ${CMAKE_EXE_LINKER_FLAGS_${type}} ${CMAKE_SHARED_LINKER_FLAGS_${type}} ${CMAKE_MODULE_LINKER_FLAGS_${type}}")
SET(CMAKE_EXE_LINKER_FLAGS_${type} "${CMAKE_EXE_LINKER_FLAGS_${type}} ${result_flag}" PARENT_SCOPE)
SET(CMAKE_SHARED_LINKER_FLAGS_${type} "${CMAKE_SHARED_LINKER_FLAGS_${type}} ${result_flag}" PARENT_SCOPE)
SET(CMAKE_MODULE_LINKER_FLAGS_${type} "${CMAKE_MODULE_LINKER_FLAGS_${type}} ${result_flag}" PARENT_SCOPE)
#MESSAGE(STATUS "After: ${CMAKE_EXE_LINKER_FLAGS_${type}} ${CMAKE_SHARED_LINKER_FLAGS_${type}} ${CMAKE_MODULE_LINKER_FLAGS_${type}}, Expected: ${CMAKE_SHARED_LINKER_FLAGS_${type}} ${result_flag}")
ENDFOREACH()
ELSE()
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${result_flag}" PARENT_SCOPE)
ENDIF()
ENDFUNCTION()
7 changes: 7 additions & 0 deletions cmake/options_defaults.cmake
Expand Up @@ -9,6 +9,9 @@
OPTION(BUILD_INTERACTIVE_TESTS "Build test(s) requiring user interaction" OFF)
OPTION(USE_INTERACTIVE_TESTS "Run interactive test(s) with ctest" OFF)
OPTION(CONC_WITH_UNIT_TESTS "Build C/C unit tests" OFF)
OPTION(WITH_ASAN "Compile with ASAN" OFF)
OPTION(WITH_UBSAN "Enable undefined behavior sanitizer" OFF)
OPTION(WITH_MSAN "Enable memory sanitizer" OFF)

IF(WIN32)
OPTION(WITH_MSI "Build MSI installation package" ON)
Expand All @@ -20,6 +23,8 @@ IF(WIN32)
SET(CLIENT_PLUGIN_PVIO_NPIPE "STATIC")
# We don't provide its support in ODBC yet, thus there is no need to bloat the library size
#SET(CLIENT_PLUGIN_PVIO_SHMEM "STATIC")
SET(WITH_UBSAN OFF)
SET(WITH_MSAN OFF)
ELSE()
IF(APPLE)
OPTION(MARIADB_LINK_DYNAMIC "Link Connector/C library dynamically" OFF)
Expand Down Expand Up @@ -53,6 +58,8 @@ IF(NOT EXISTS ${CMAKE_SOURCE_DIR}/libmariadb)
SET(USE_SYSTEM_INSTALLED_LIB ON)
ENDIF()

SET(MAODBC_LINKER_FLAGS "")

IF(APPLE)
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
Expand Down
7 changes: 4 additions & 3 deletions driver/ma_common.c
Expand Up @@ -53,10 +53,11 @@ char* trim(char *Str)
char *end;

Str= (char*)ltrim(Str);

end= Str + strlen(Str) - 1;
while (*end > 0 && isspace(*end))
*end--= 0;
while (end >= Str && *end > 0 && isspace(*end))
{
*end--= '\0';
}
return Str;
}
/* }}} */
Expand Down
7 changes: 5 additions & 2 deletions driver/ma_connection.cpp
Expand Up @@ -707,12 +707,15 @@ std::size_t MADB_Tokenize(std::vector<odbc::bytes>& tokens, const char* cstring,
const char *current= cstring, *next= nullptr, *end= cstring + strlen(cstring);
while (next= std::strpbrk(current, separator))
{
tokens.emplace_back(current, next - current);
/* This is rather bad CArray API - constructor from const array creates copy, while constructor from array creates "wrapping" object,
and here we need the wrapping one - there is no need to create copy, plus copy will not terminate array with \0, and that will create
problems. Possibly more clear way would be to push empty object and than explicitly wrap the string area we need */
tokens.emplace_back(const_cast<char*>(current), next - current);
current= next + 1;
}
if (current < end)
{
tokens.emplace_back(current, end - current);
tokens.emplace_back(const_cast<char*>(current), end - current);
}
return tokens.size();
}
Expand Down
4 changes: 3 additions & 1 deletion driver/ma_string.cpp
Expand Up @@ -329,7 +329,9 @@ my_bool MADB_DynStrGetWhere(MADB_Stmt *Stmt, MADB_DynString *DynString, char *Ta
/* If we already know index columns - we walk through column index values stored in Stmt->UniqueIndex, all columns otherwise */
for (i= IndexArrIdx == 0 ? 0 : Stmt->UniqueIndex[1];
IndexArrIdx == 0 ? i < MADB_STMT_COLUMN_COUNT(Stmt) : IndexArrIdx <= Stmt->UniqueIndex[0];
i= IndexArrIdx == 0 ? i + 1 : Stmt->UniqueIndex[++IndexArrIdx])
i= IndexArrIdx == 0 ? i + 1 : (++IndexArrIdx > Stmt->UniqueIndex[0] ? 0 /* Doesn't really matter what we set here - loop won't go further,
we just don't want to read past Stmt->UniqueIndex allocated area */
: Stmt->UniqueIndex[IndexArrIdx]))
{
const MYSQL_FIELD *field= Stmt->metadata->getField(i);

Expand Down
2 changes: 1 addition & 1 deletion test/multistatement.c
Expand Up @@ -218,7 +218,7 @@ ODBC_TEST(test_semicolon)
Also tests ODBC-97*/
ODBC_TEST(t_odbc74)
{
SQLCHAR ref[][4]= {"\"", "'", "*/", "/*", "end", "one\\", "two\\"}, val[8];
SQLCHAR ref[][6]= {"\"", "'", "*/", "/*", "end", "one\\", "two\\"}, val[10];
unsigned int i;
SQLHDBC hdbc1;
SQLHSTMT Stmt1;
Expand Down
6 changes: 3 additions & 3 deletions test/param.c
Expand Up @@ -376,13 +376,13 @@ ODBC_TEST(t_param_offset)
{
rows[20+i].id= i * 10;
rows[20+i].x= (i * 1000) % 97;
OK_SIMPLE_STMT(Stmt, "insert into t_param_offset values (?,?)");
OK_SIMPLE_STMT(Stmt, "INSERT INTO t_param_offset VALUES (?,?)");
bind_offset+= row_size;
}

/* verify the data */

OK_SIMPLE_STMT(Stmt, "select id, x from t_param_offset order by 1");
CHECK_STMT_RC(Stmt, SQLFreeStmt(Stmt, SQL_RESET_PARAMS));
OK_SIMPLE_STMT(Stmt, "SELECT id, x FROM t_param_offset order by 1");

CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, 1, SQL_C_LONG, &out_id, 0, NULL));
CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, 2, SQL_C_LONG, &out_x, 0, NULL));
Expand Down
17 changes: 13 additions & 4 deletions test/tap.h
Expand Up @@ -652,9 +652,18 @@ do {\
}

#define IS(A) if (!(A)) { diag("Error in %s:%d", __FILE__, __LINE__); return FAIL; }
#define IS_STR_EX(A,B,C,D) do {const char *loc_a=(const char *)(A), *loc_b=(const char *)(B);\
if ((D)) diag("%s %s", loc_a, loc_b);\
FAIL_IF(loc_a == NULL || loc_b == NULL || strncmp(loc_a, loc_b, (C)) != 0, "Strings do not match"); } while(0)

BOOL is_str_ex(const char* str1, const char* str2, size_t len, BOOL verbose)
{
if (verbose)
{
fprintf(stdout, "# %s %s", str1, str2);
}
return str1 == NULL || str2 == NULL || strncmp(str1, str2, len) != 0;
}

#define IS_STR_EX(A,B,C,D) FAIL_IF(is_str_ex((const char *)(A), (const char *)(B), (C), (D)), "Strings do not match")

#define IS_STR(A,B,C) IS_STR_EX(A,B,C,TRUE)

#define is_num(A,B) \
Expand Down Expand Up @@ -719,7 +728,7 @@ SQLWCHAR *my_fetch_wstr(SQLHSTMT Stmt, SQLWCHAR *buffer, SQLUSMALLINT icol, SQLL

const char *my_fetch_str(SQLHSTMT Stmt, SQLCHAR *szData, SQLUSMALLINT icol)
{
SQLLEN nLen;
SQLLEN nLen= 0;

SQLGetData(Stmt, icol, SQL_CHAR, szData, 1000, &nLen);
/* If Null value - putting down smth meaningful. also that allows caller to
Expand Down

0 comments on commit d809d2b

Please sign in to comment.