DBD-MariaDB
view release on metacpan or search on metacpan
* This is the versions of libmysql that supports MySQL Fabric.
* We need to check for special macro LIBMYSQL_VERSION_ID.
*/
#ifdef LIBMYSQL_VERSION_ID
#if LIBMYSQL_VERSION_ID >= 60200 && LIBMYSQL_VERSION_ID < 70000
#define HAVE_FABRIC
#endif
#endif
#if !defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 80001
#define my_bool bool
#endif
/*
* MariaDB Connector/C 3.1.10 changed API of mysql_get_client_version()
* function. Before that release it returned client version. With that release
* it started returning Connector/C package version.
*
* So when compiling with MariaDB Connector/C client library, redefine
* mysql_get_client_version() to always returns client version via function
* mariadb_get_infov(MARIADB_CLIENT_VERSION_ID) call.
*
* Driver code expects for a long time that mysql_get_client_version() call
* returns client version and not something different.
*
* Function mariadb_get_infov() is supported since MariaDB Connector/C 3.0+.
*/
#if defined(MARIADB_PACKAGE_VERSION) && defined(MARIADB_PACKAGE_VERSION_ID) && MARIADB_PACKAGE_VERSION_ID >= 30000
PERL_STATIC_INLINE unsigned long mariadb_get_client_version(void)
{
/* MARIADB_CLIENT_VERSION_ID really expects size_t type, documentation is wrong and says unsigned int. */
size_t version;
if (mariadb_get_infov(NULL, MARIADB_CLIENT_VERSION_ID, &version) != 0)
version = mysql_get_client_version(); /* On error fallback to mysql_get_client_version() */
return version;
}
#define mysql_get_client_version() mariadb_get_client_version()
#endif
/* mysql_commit() and mysql_rollback() are broken in MariaDB Connector/C prior to version 3.1.3, see: https://jira.mariadb.org/browse/CONC-400 */
#if defined(MARIADB_PACKAGE_VERSION) && MARIADB_PACKAGE_VERSION_ID < 30103
#define mysql_commit(mysql) ((my_bool)(mysql_real_query((mysql), "COMMIT", 6)))
#define mysql_rollback(mysql) ((my_bool)(mysql_real_query((mysql), "ROLLBACK", 8)))
#endif
/* MYSQL_SECURE_AUTH became a no-op from MySQL 5.7.5 and is removed from MySQL 8.0.3 */
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID <= 50704
#define HAVE_SECURE_AUTH
#endif
/* mysql_error(NULL) returns last error message, needs MySQL 5.0.60+ or 5.1.24+; does not work with MariaDB Connector/C yet: https://jira.mariadb.org/browse/CONC-374 */
#if ((MYSQL_VERSION_ID >= 50060 && MYSQL_VERSION_ID < 50100) || MYSQL_VERSION_ID >= 50124) && !defined(MARIADB_PACKAGE_VERSION)
#define HAVE_LAST_ERROR
#endif
/*
* MySQL and MariaDB Embedded are affected by https://jira.mariadb.org/browse/MDEV-16578
* MariaDB 10.2.2+ prior to 10.2.19 and 10.3.9 and MariaDB Connector/C prior to 3.0.5 are affected by https://jira.mariadb.org/browse/CONC-336
* MySQL 8.0.4+ prior to 8.0.20 is affected too by https://bugs.mysql.com/bug.php?id=93276
*/
#if defined(HAVE_EMBEDDED) || (!defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 80004 && MYSQL_VERSION_ID < 80020) || (defined(MARIADB_PACKAGE_VERSION) && (!defined(MARIADB_PACKAGE_VERSION_ID) || MARIADB_PACKAGE_VERSION_ID < 30005)) || (defined(...
#define HAVE_BROKEN_INIT
#endif
/*
* Check which SSL settings are supported by API at compile time
*/
/* Use mysql_options with MYSQL_OPT_SSL_VERIFY_SERVER_CERT */
#if ((MYSQL_VERSION_ID >= 50023 && MYSQL_VERSION_ID < 50100) || MYSQL_VERSION_ID >= 50111) && (MYSQL_VERSION_ID < 80000 || defined(MARIADB_BASE_VERSION))
#define HAVE_SSL_VERIFY
#endif
/* Use mysql_options with MYSQL_OPT_SSL_ENFORCE (CVE-2015-3152, fix for MySQL) */
#if !defined(MARIADB_BASE_VERSION) && !defined(HAVE_EMBEDDED) && MYSQL_VERSION_ID >= 50703 && MYSQL_VERSION_ID < 80000 && MYSQL_VERSION_ID != 60000
#define HAVE_SSL_ENFORCE
#endif
/* Use mysql_options with MYSQL_OPT_SSL_MODE (CVE-2015-3152, fix for MySQL) */
#if !defined(MARIADB_BASE_VERSION) && !defined(HAVE_EMBEDDED) && MYSQL_VERSION_ID >= 50711 && MYSQL_VERSION_ID != 60000
#define HAVE_SSL_MODE
#endif
/* Use mysql_options with MYSQL_OPT_SSL_MODE, but only SSL_MODE_REQUIRED is supported (CVE-2017-3305, fix for MySQL) */
#if !defined(MARIADB_BASE_VERSION) && !defined(HAVE_EMBEDDED) && ((MYSQL_VERSION_ID >= 50636 && MYSQL_VERSION_ID < 50700) || (MYSQL_VERSION_ID >= 50555 && MYSQL_VERSION_ID < 50600))
#define HAVE_SSL_MODE_ONLY_REQUIRED
#endif
/*
* Check which SSL settings are supported by API at runtime
*/
/* MYSQL_OPT_SSL_VERIFY_SERVER_CERT automatically enforce SSL mode (CVE-2015-3152 and CVE-2017-3305 and CVE-2018-2767, fix for MariaDB) */
PERL_STATIC_INLINE bool ssl_verify_also_enforce_ssl(void) {
#ifdef MARIADB_BASE_VERSION
unsigned long version = mysql_get_client_version();
#ifdef HAVE_EMBEDDED
return ((version >= 50560 && version < 50600) || (version >= 100035 && version < 100100) || (version >= 100133 && version < 100200) || (version >= 100215 && version < 100300) || version >= 100307);
#else
return ((version >= 50556 && version < 50600) || (version >= 100031 && version < 100100) || (version >= 100123 && version < 100200) || (version >= 100206 && version < 100300) || version >= 100301);
#endif
#else
return FALSE;
#endif
}
/* MYSQL_OPT_SSL_VERIFY_SERVER_CERT is not vulnerable (CVE-2016-2047) and can be used */
PERL_STATIC_INLINE bool ssl_verify_usable(void) {
unsigned long version = mysql_get_client_version();
#ifdef MARIADB_BASE_VERSION
return ((version >= 50547 && version < 50600) || (version >= 100023 && version < 100100) || version >= 100110);
#else
return ((version >= 50549 && version < 50600) || (version >= 50630 && version < 50700) || version >= 50712);
#endif
}
/*
* Internal constants, used for fetching array attributes
*/
enum av_attribs {
AV_ATTRIB_NAME = 0,
AV_ATTRIB_TABLE,
AV_ATTRIB_TYPE,
AV_ATTRIB_SQL_TYPE,
AV_ATTRIB_IS_PRI_KEY,
AV_ATTRIB_IS_NOT_NULL,
AV_ATTRIB_NULLABLE,
AV_ATTRIB_LENGTH,
AV_ATTRIB_IS_NUM,
AV_ATTRIB_TYPE_NAME,
AV_ATTRIB_PRECISION,
AV_ATTRIB_SCALE,
AV_ATTRIB_MAX_LENGTH,
AV_ATTRIB_IS_KEY,
AV_ATTRIB_IS_BLOB,
AV_ATTRIB_IS_AUTO_INCREMENT,
AV_ATTRIB_LAST /* Dummy attribute, never used, for allocation */
}; /* purposes only */
/* Double linked list */
struct mariadb_list_entry {
void *data;
struct mariadb_list_entry *prev;
struct mariadb_list_entry *next;
};
#define mariadb_list_add(list, entry, ptr) \
STMT_START { \
Newz(0, (entry), 1, struct mariadb_list_entry); \
(entry)->data = (ptr); \
(entry)->prev = NULL; \
(entry)->next = (list); \
if ((list)) \
(list)->prev = (entry); \
(list) = (entry); \
} STMT_END
#define mariadb_list_remove(list, entry) \
STMT_START { \
if ((entry)->prev) \
(entry)->prev->next = (entry)->next; \
if ((entry)->next) \
(entry)->next->prev = (entry)->prev; \
if ((list) == (entry)) \
(list) = (entry)->next; \
Safefree((entry)); \
(entry) = NULL; \
} STMT_END
/*
* This is our part of the driver handle. We receive the handle as
* an "SV*", say "drh", and receive a pointer to the structure below
* by declaring
*
* D_imp_drh(drh);
*
* This declares a variable called "imp_drh" of type
* "struct imp_drh_st *".
*/
struct imp_drh_st {
dbih_drc_t com; /* MUST be first element in structure */
struct mariadb_list_entry *active_imp_dbhs; /* List of imp_dbh structures with active MYSQL* */
struct mariadb_list_entry *taken_pmysqls; /* List of active MYSQL* from take_imp_data() */
unsigned long int instances;
bool non_embedded_started;
#if !defined(HAVE_EMBEDDED) && defined(HAVE_BROKEN_INIT)
bool non_embedded_finished;
#endif
bool embedded_started;
SV *embedded_args;
SV *embedded_groups;
};
/*
* Likewise, this is our part of the database handle, as returned
* by DBI->connect. We receive the handle as an "SV*", say "dbh",
* and receive a pointer to the structure below by declaring
*
* D_imp_dbh(dbh);
*
* This declares a variable called "imp_dbh" of type
* "struct imp_dbh_st *".
*/
struct imp_dbh_st {
dbih_dbc_t com; /* MUST be first element in structure */
struct mariadb_list_entry *list_entry; /* Entry of imp_drh->active_imp_dbhs list */
MYSQL *pmysql;
int sock_fd;
bool connected; /* Set to true after DBI->connect finished */
bool is_embedded;
bool auto_reconnect;
bool bind_type_guessing;
bool bind_comment_placeholders;
bool no_autocommit_cmd;
bool use_mysql_use_result; /* TRUE if execute should use
* mysql_use_result rather than
* mysql_store_result
*/
bool use_server_side_prepare;
bool disable_fallback_for_server_prepare;
bool use_multi_statements;
void* async_query_in_flight;
my_ulonglong insertid;
struct {
unsigned int auto_reconnects_ok;
unsigned int auto_reconnects_failed;
} stats;
};
/*
* The bind_param method internally uses this structure for storing
* parameters.
*/
typedef struct imp_sth_ph_st {
char* value;
STRLEN len;
int type;
bool bound;
} imp_sth_ph_t;
/*
* Storage for numeric value in prepared statement
*/
( run in 1.212 second using v1.01-cache-2.11-cpan-71847e10f99 )