/*
* DBD::MariaDB - DBI driver for the MariaDB and MySQL database
*
* Copyright (c) 2005 Patrick Galbraith
* Copyright (c) 2003 Rudolf Lippan
* Copyright (c) 1997-2003 Jochen Wiedmann
*
* Based on DBD::Oracle; DBD::Oracle is
*
* Copyright (c) 1994,1995 Tim Bunce
*
* You may distribute this under the terms of either the GNU General Public
* License or the Artistic License, as specified in the Perl README file.
*/
#define PERL_NO_GET_CONTEXT
/*
* Header files we use
*/
/*
* On WIN32 windows.h and winsock.h need to be included before mysql.h
* Otherwise SOCKET type which is needed for mysql.h is not defined
* SO_UPDATE_CONNECT_CONTEXT is not defined in all MinGW versions.
*/
#ifdef _WIN32
#include <windows.h>
#include <winsock.h>
#ifndef SO_UPDATE_CONNECT_CONTEXT
#define SO_UPDATE_CONNECT_CONTEXT 0x7010
#endif
#endif
#include <mysql.h> /* Comes with MySQL-devel */
#include <mysqld_error.h> /* Comes MySQL */
#include <errmsg.h> /* Comes with MySQL-devel */
#ifndef MYSQL_VERSION_ID
#include <mysql_version.h> /* Comes with MySQL-devel */
#endif
#include <DBIXS.h> /* installed by the DBI module */
#include <stdint.h> /* For uint32_t */
/*******************************************************************************
* Standard MariaDB macros which are not defined in every MySQL/MariaDB client *
*******************************************************************************/
#if !defined(MARIADB_BASE_VERSION) && defined(MARIADB_PACKAGE_VERSION)
#define MARIADB_BASE_VERSION
#endif
/* Macro is available in my_global.h which is not included or present in some versions of MariaDB */
#ifndef NOT_FIXED_DEC
#define NOT_FIXED_DEC 31
#endif
/* Macro is available in m_ctype.h which is not included in some versions of MySQL */
#ifndef MY_CS_PRIMARY
#define MY_CS_PRIMARY 32
#endif
/* Macro is available in mysql_com.h, but not defined in older MySQL versions */
#ifndef SERVER_STATUS_NO_BACKSLASH_ESCAPES
#define SERVER_STATUS_NO_BACKSLASH_ESCAPES 512
#endif
/* Macro is not defined in older MySQL versions */
#ifndef CR_NO_STMT_METADATA
#define CR_NO_STMT_METADATA 2052
#endif
/* Macro is not defined in some MariaDB versions */
#ifndef CR_NO_RESULT_SET
#define CR_NO_RESULT_SET 2053
#endif
/* Macro is not defined in older MySQL versions */
#ifndef CR_NOT_IMPLEMENTED
#define CR_NOT_IMPLEMENTED 2054
#endif
/* Macro is not defined in older MySQL versions */
#ifndef CR_STMT_CLOSED
#define CR_STMT_CLOSED 2056
#endif
/********************************************************************
* Standard Perl macros which are not defined in every Perl version *
********************************************************************/
#ifndef PERL_STATIC_INLINE
#define PERL_STATIC_INLINE static
#endif
#ifndef NOT_REACHED
#define NOT_REACHED assert(0)
#endif
#ifndef SVfARG
#define SVfARG(p) ((void*)(p))
#endif
#ifndef SSize_t_MAX
#define SSize_t_MAX (SSize_t)(~(Size_t)0 >> 1)
#endif
/* _set_osfhnd() is copied from Perl source file win32.h */
#ifdef _WIN32
typedef intptr_t ioinfo;
extern __declspec(dllimport) ioinfo* __pioinfo[];
# define IOINFO_L2E 5
# define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
# define _ioinfo_size (_msize((void*)__pioinfo[0]) / IOINFO_ARRAY_ELTS)
# define _pioinfo(i) ((intptr_t *) \
(((Size_t)__pioinfo[(i) >> IOINFO_L2E])/* * to head of array ioinfo [] */\
/* offset to the head of a particular ioinfo struct */ \
+ (((i) & (IOINFO_ARRAY_ELTS - 1)) * _ioinfo_size)) \
)
# define _osfhnd(i) (*(_pioinfo(i)))
# define _set_osfhnd(fh, osfh) (void)(_osfhnd(fh) = (intptr_t)osfh)
#endif
/* PERL_UNUSED_ARG does not exist prior to perl 5.9.3 */
#ifndef PERL_UNUSED_ARG
# if defined(lint) && defined(S_SPLINT_S) /* www.splint.org */
# include <note.h>
# define PERL_UNUSED_ARG(x) NOTE(ARGUNUSED(x))
# else
# define PERL_UNUSED_ARG(x) ((void)x)
# endif
#endif
/* assert_not_ROK is broken prior to perl 5.8.2 */
#if PERL_VERSION < 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 2)
#undef assert_not_ROK
#define assert_not_ROK(sv)
#endif
#ifndef SvPV_nomg_nolen
#define SvPV_nomg_nolen(sv) ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK ? SvPVX(sv) : sv_2pv_flags(sv, &PL_na, 0))
#endif
/* Remove wrong SV_NOSTEAL macro defined by ppport.h */
#if defined(SV_NOSTEAL) && (SV_NOSTEAL == 0)
#undef SV_NOSTEAL
#endif
#ifndef newSVsv_nomg
PERL_STATIC_INLINE SV *newSVsv_nomg(pTHX_ SV *sv)
{
SV *ret = newSV(0);
#ifndef SV_NOSTEAL
U32 tmp = SvFLAGS(sv) & SVs_TEMP;
SvTEMP_off(sv);
sv_setsv_flags(ret, sv, 0);
SvFLAGS(sv) |= tmp;
#else
sv_setsv_flags(ret, sv, SV_NOSTEAL);
#endif
return ret;
}
#define newSVsv_nomg(sv) newSVsv_nomg(aTHX_ (sv))
#endif
/* looks_like_number() process get magic prior to perl 5.15.4, so reimplement it */
#if PERL_VERSION < 15 || (PERL_VERSION == 15 && PERL_SUBVERSION < 4)
#undef looks_like_number
PERL_STATIC_INLINE I32 looks_like_number(pTHX_ SV *sv)
{
char *sbegin;
STRLEN len;
if (!SvPOK(sv) && !SvPOKp(sv))
return SvFLAGS(sv) & (SVf_NOK|SVp_NOK|SVf_IOK|SVp_IOK);
sbegin = SvPV_nomg(sv, len);
return grok_number(sbegin, len, NULL);
}
#define looks_like_number(sv) looks_like_number(aTHX_ (sv))
#endif
#ifndef SvPVutf8_nomg
PERL_STATIC_INLINE char * SvPVutf8_nomg(pTHX_ SV *sv, STRLEN *len)
{
char *buf = SvPV_nomg(sv, *len);
if (SvUTF8(sv))
return buf;
if (SvGMAGICAL(sv))
sv = sv_2mortal(newSVpvn(buf, *len));
/* There is sv_utf8_upgrade_nomg(), but it is broken prior to Perl version 5.13.10 */
return SvPVutf8(sv, *len);
}
#define SvPVutf8_nomg(sv, len) SvPVutf8_nomg(aTHX_ (sv), &(len))
#endif
#ifndef SvPVbyte_nomg
PERL_STATIC_INLINE char * SvPVbyte_nomg(pTHX_ SV *sv, STRLEN *len)
{
char *buf = SvPV_nomg(sv, *len);
if (!SvUTF8(sv))
return buf;
if (SvGMAGICAL(sv))
{
sv = sv_2mortal(newSVpvn(buf, *len));
SvUTF8_on(sv);
}
return SvPVbyte(sv, *len);
}
#define SvPVbyte_nomg(sv, len) SvPVbyte_nomg(aTHX_ (sv), &(len))
#endif
#ifndef SvTRUE_nomg
#define SvTRUE_nomg(sv) (!SvGMAGICAL((sv)) ? SvTRUE((sv)) : SvTRUEx(sv_2mortal(newSVsv_nomg((sv)))))
#endif
/* Remove wrong SvIV_nomg macro defined by ppport.h */
#if defined(SvIV_nomg) && (PERL_VERSION < 9 | (PERL_VERSION == 9 && PERL_SUBVERSION < 1))
#undef SvIV_nomg
#endif
#ifndef SvIV_nomg
PERL_STATIC_INLINE IV SvIV_nomg(pTHX_ SV *sv)
{
IV iv;
SV *tmp;
if (!SvGMAGICAL(sv))
return SvIV(sv);
tmp = sv_2mortal(newSVsv_nomg(sv));
iv = SvIV(tmp);
if (SvIsUV(tmp))
SvIsUV_on(sv);
else
SvIsUV_off(sv);
return iv;
}
#define SvIV_nomg(sv) SvIV_nomg(aTHX_ (sv))
#endif
/* Remove wrong SvUV_nomg macro defined by ppport.h */
#if defined(SvUV_nomg) && (PERL_VERSION < 9 | (PERL_VERSION == 9 && PERL_SUBVERSION < 1))
#undef SvUV_nomg
#endif
#ifndef SvUV_nomg
PERL_STATIC_INLINE UV SvUV_nomg(pTHX_ SV *sv)
{
UV uv;
SV *tmp;
if (!SvGMAGICAL(sv))
return SvUV(sv);
tmp = sv_2mortal(newSVsv_nomg(sv));
uv = SvUV(tmp);
if (SvIsUV(tmp))
SvIsUV_on(sv);
else
SvIsUV_off(sv);
return uv;
}
#define SvUV_nomg(sv) SvUV_nomg(aTHX_ (sv))
#endif
#ifndef SvNV_nomg
#define SvNV_nomg(sv) (!SvGMAGICAL((sv)) ? SvNV((sv)) : SvNVx(sv_2mortal(newSVsv_nomg((sv)))))
#endif
#ifndef sv_cmp_flags
#define sv_cmp_flags(sv1, sv2, flags) (((flags) & SV_GMAGIC) ? sv_cmp((sv1), (sv2)) : sv_cmp((!SvGMAGICAL((sv1)) ? (sv1) : sv_2mortal(newSVsv_nomg((sv1)))), (!SvGMAGICAL((sv2)) ? (sv2) : sv_2mortal(newSVsv_nomg((sv2))))))
#endif
#ifndef gv_stashpvs
#define gv_stashpvs(str, flags) gv_stashpvn("" str "", sizeof((str))-1, (flags))
#endif
#ifndef newSVpvs
#define newSVpvs(str) newSVpvn("" str "", sizeof((str)) - 1)
#endif
#ifndef hv_fetchs
#define hv_fetchs(hv, key, lval) hv_fetch((hv), "" key "", sizeof((key))-1, (lval))
#endif
#ifndef hv_stores
#define hv_stores(hv, key, val) hv_store((hv), "" key "", sizeof((key))-1, (val), 0)
#endif
#ifndef hv_deletes
#define hv_deletes(hv, key, flags) hv_delete((hv), "" key "", sizeof((key))-1, (flags))
#endif
#ifndef memEQs
#define memEQs(s1, l, s2) (sizeof((s2))-1 == (l) && memEQ((s1), "" s2 "", sizeof((s2))-1))
#endif
#ifndef strBEGINs
#define strBEGINs(s1, s2) strnEQ((s1), "" s2 "", sizeof((s2))-1)
#endif
/**************************************
* Custom DBD-MariaDB specific macros *
**************************************/
#define GEO_DATATYPE_VERSION 50007
#define NEW_DATATYPE_VERSION 50003
#if MYSQL_VERSION_ID < NEW_DATATYPE_VERSION
#define MYSQL_TYPE_VARCHAR 15
#define MYSQL_TYPE_BIT 16
#define MYSQL_TYPE_NEWDECIMAL 246
#endif
#if MYSQL_VERSION_ID < GEO_DATATYPE_VERSION
#define MYSQL_TYPE_GEOMETRY 255
#endif
/*
* 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(MARIADB_BASE_VERSION) && ((MYSQL_VERSION_ID >= 100202 && MYSQL_VERSION_ID < 100219) || (MYSQL_VERSION_ID >= 100300 && MYSQL_VERSION_ID < 100309)))
#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 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
*/
typedef union numeric_val_u {
unsigned char tval;
unsigned short sval;
uint32_t lval;
my_ulonglong llval;
float fval;
double dval;
} numeric_val_t;
/*
* The bind_param method internally uses this structure for storing
* parameters.
*/
typedef struct imp_sth_phb_st {
numeric_val_t numeric_val;
unsigned long length;
my_bool is_null;
} imp_sth_phb_t;
/*
* The mariadb_st_describe uses this structure for storing
* fields meta info.
*/
typedef struct imp_sth_fbh_st {
unsigned long length;
my_bool is_null;
my_bool error;
char *data;
numeric_val_t numeric_val;
bool is_utf8;
} imp_sth_fbh_t;
typedef struct imp_sth_fbind_st {
unsigned long * length;
my_bool * is_null;
} imp_sth_fbind_t;
/*
* Finally our part of the statement handle. We receive the handle as
* an "SV*", say "dbh", and receive a pointer to the structure below
* by declaring
*
* D_imp_sth(sth);
*
* This declares a variable called "imp_sth" of type
* "struct imp_sth_st *".
*/
struct imp_sth_st {
dbih_stc_t com; /* MUST be first element in structure */
char *statement;
STRLEN statement_len;
MYSQL_STMT *stmt;
MYSQL_BIND *bind;
MYSQL_BIND *buffer;
imp_sth_phb_t *fbind;
imp_sth_fbh_t *fbh;
bool has_been_bound;
bool use_server_side_prepare; /* server side prepare statements? */
bool disable_fallback_for_server_prepare;
MYSQL_RES* result; /* result */
my_ulonglong currow; /* number of current row */
my_ulonglong row_num; /* total number of rows */
bool done_desc; /* have we described this sth yet ? */
long long_buflen; /* length for long/longraw (if >0) */
bool long_trunc_ok; /* is truncating a long an error */
my_ulonglong insertid; /* ID of auto insert */
unsigned int warning_count; /* Number of warnings after execute() */
imp_sth_ph_t* params; /* Pointer to parameter array */
AV* av_attr[AV_ATTRIB_LAST];/* For caching array attributes */
bool use_mysql_use_result; /* TRUE if execute should use */
/* mysql_use_result rather than */
/* mysql_store_result */
bool is_async;
bool async_result;
};
/*
* And last, not least: The prototype definitions.
*
* These defines avoid name clashes for multiple statically linked DBD's */
#define dbd_init mariadb_dr_init
#define dbd_discon_all mariadb_dr_discon_all
#define dbd_take_imp_data mariadb_db_take_imp_data
#define dbd_db_login6_sv mariadb_db_login6_sv
#define dbd_db_do6 mariadb_db_do6
#define dbd_db_commit mariadb_db_commit
#define dbd_db_rollback mariadb_db_rollback
#define dbd_db_disconnect mariadb_db_disconnect
#define dbd_db_destroy mariadb_db_destroy
#define dbd_db_STORE_attrib mariadb_db_STORE_attrib
#define dbd_db_FETCH_attrib mariadb_db_FETCH_attrib
#define dbd_db_last_insert_id mariadb_db_last_insert_id
#define dbd_db_data_sources mariadb_db_data_sources
#define dbd_st_prepare_sv mariadb_st_prepare_sv
#define dbd_st_execute_iv mariadb_st_execute_iv
#define dbd_st_fetch mariadb_st_fetch
#define dbd_st_finish mariadb_st_finish
#define dbd_st_destroy mariadb_st_destroy
#define dbd_st_blob_read mariadb_st_blob_read
#define dbd_st_STORE_attrib mariadb_st_STORE_attrib
#define dbd_st_FETCH_attrib mariadb_st_FETCH_attrib
#define dbd_st_last_insert_id mariadb_st_last_insert_id
#define dbd_bind_ph mariadb_st_bind_ph
#include <dbd_xsh.h>
/* Compatibility for DBI version prior to 1.634 which do not support dbd_st_execute_iv API */
#ifndef HAVE_DBI_1_634
#define dbd_st_execute mariadb_st_execute
IV dbd_st_execute_iv(SV *sth, imp_sth_t *imp_sth);
PERL_STATIC_INLINE int dbd_st_execute(SV *sth, imp_sth_t *imp_sth) {
IV ret = dbd_st_execute_iv(sth, imp_sth);
if (ret >= INT_MIN && ret <= INT_MAX)
return ret;
else /* overflow */
return -1; /* -1 is unknown number of rows */
}
#endif
#ifndef HAVE_DBI_1_642
IV mariadb_db_do6(SV *dbh, imp_dbh_t *imp_dbh, SV *statement, SV *attribs, I32 items, I32 ax);
SV *mariadb_st_last_insert_id(SV *sth, imp_sth_t *imp_sth, SV *catalog, SV *schema, SV *table, SV *field, SV *attr);
#endif
#define MARIADB_DR_ATTRIB_GET_SVPS(attribs, key) DBD_ATTRIB_GET_SVP((attribs), "" key "", sizeof((key))-1)
SV* mariadb_dr_my_ulonglong2sv(pTHX_ my_ulonglong val);
#define my_ulonglong2sv(val) mariadb_dr_my_ulonglong2sv(aTHX_ val)
void mariadb_dr_do_error (SV* h, unsigned int rc, const char *what, const char *sqlstate);
bool mariadb_st_more_results(SV*, imp_sth_t*);
AV* mariadb_db_type_info_all(void);
SV* mariadb_db_quote(SV*, SV*, SV*);
bool mariadb_db_reconnect(SV *h, MYSQL_STMT *stmt);
my_ulonglong mariadb_db_async_result(SV* h, MYSQL_RES** resp);
int mariadb_db_async_ready(SV* h);