Skip to content

Commit

Permalink
- Fix MDEV-10496. Memory leak in discovery
Browse files Browse the repository at this point in the history
  modified:   storage/connect/ha_connect.cc

- Fix wrong lrecl calculation for virtual columns
  modified:   storage/connect/reldef.cpp

- Typo
  modified:   storage/connect/jdbconn.cpp
  modified:   storage/connect/json.cpp
  • Loading branch information
Buggynours committed Sep 5, 2016
1 parent 55fb72d commit a4623b5
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 233 deletions.
84 changes: 48 additions & 36 deletions storage/connect/ha_connect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ uint GetWorkSize(void);
void SetWorkSize(uint);
extern "C" const char *msglang(void);

static void PopUser(PCONNECT xp);
static PCONNECT GetUser(THD *thd, PCONNECT xp);
static PGLOBAL GetPlug(THD *thd, PCONNECT& lxp);

Expand Down Expand Up @@ -831,42 +832,51 @@ ha_connect::~ha_connect(void)
table ? table->s->table_name.str : "<null>",
xp, xp ? xp->count : 0);

if (xp) {
PCONNECT p;
PopUser(xp);
} // end of ha_connect destructor

xp->count--;

for (p= user_connect::to_users; p; p= p->next)
if (p == xp)
break;
/****************************************************************************/
/* Check whether this user can be removed. */
/****************************************************************************/
static void PopUser(PCONNECT xp)
{
if (xp) {
xp->count--;

if (p && !p->count) {
if (p->next)
p->next->previous= p->previous;
if (!xp->count) {
PCONNECT p;

if (p->previous)
p->previous->next= p->next;
else
user_connect::to_users= p->next;
for (p= user_connect::to_users; p; p= p->next)
if (p == xp)
break;

} // endif p
if (p) {
if (p->next)
p->next->previous= p->previous;

if (!xp->count) {
PlugCleanup(xp->g, true);
delete xp;
} // endif count
if (p->previous)
p->previous->next= p->next;
else
user_connect::to_users= p->next;

} // endif xp
} // endif p

} // end of ha_connect destructor
PlugCleanup(xp->g, true);
delete xp;
} // endif count

} // endif xp

} // end of PopUser


/****************************************************************************/
/* Get a pointer to the user of this handler. */
/****************************************************************************/
static PCONNECT GetUser(THD *thd, PCONNECT xp)
{
if (!thd)
if (!thd)
return NULL;

if (xp && thd == xp->thdp)
Expand All @@ -890,7 +900,6 @@ static PCONNECT GetUser(THD *thd, PCONNECT xp)
return xp;
} // end of GetUser


/****************************************************************************/
/* Get the global pointer of the user of this handler. */
/****************************************************************************/
Expand Down Expand Up @@ -5261,7 +5270,18 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (!(shm= (char*)db))
db= table_s->db.str; // Default value

// Check table type
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
goto jer;
} // endif jump_level

if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
goto err;
} // endif rc

// Check table type
if (ttp == TAB_UNDEF) {
topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS";
ttp= GetTypeID(topt->type);
Expand All @@ -5270,20 +5290,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
} else if (ttp == TAB_NIY) {
sprintf(g->Message, "Unsupported table type %s", topt->type);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
return HA_ERR_INTERNAL_ERROR;
goto err;
} // endif ttp

// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
return HA_ERR_INTERNAL_ERROR;
} // endif jump_level

if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
goto err;
} // endif rc

if (!tab) {
if (ttp == TAB_TBL) {
// Make tab the first table of the list
Expand Down Expand Up @@ -5843,14 +5852,17 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
rc= init_table_share(thd, table_s, create_info, &sql);

g->jump_level--;
PopUser(xp);
return rc;
} // endif ok

my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));

err:
g->jump_level--;
return HA_ERR_INTERNAL_ERROR;
jer:
PopUser(xp);
return HA_ERR_INTERNAL_ERROR;
} // end of connect_assisted_discovery

/**
Expand Down
195 changes: 1 addition & 194 deletions storage/connect/jdbconn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,145 +498,6 @@ PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info)
return qrp;
} // end of JDBCDrivers

#if 0
/*************************************************************************/
/* JDBCDataSources: constructs the result blocks containing all JDBC */
/* data sources available on the local host. */
/* Called with info=true to have result column names. */
/*************************************************************************/
PQRYRES JDBCDataSources(PGLOBAL g, int maxres, bool info)
{
int buftyp[] ={ TYPE_STRING, TYPE_STRING };
XFLD fldtyp[] ={ FLD_NAME, FLD_REM };
unsigned int length[] ={ 0, 256 };
bool b[] ={ false, true };
int i, n = 0, ncol = 2;
PCOLRES crp;
PQRYRES qrp;
JDBConn *jcp = NULL;

/************************************************************************/
/* Do an evaluation of the result size. */
/************************************************************************/
if (!info) {
jcp = new(g)JDBConn(g, NULL);
n = jcp->GetMaxValue(SQL_MAX_DSN_LENGTH);
length[0] = (n) ? (n + 1) : 256;

if (!maxres)
maxres = 512; // Estimated max number of data sources

} else {
length[0] = 256;
maxres = 0;
} // endif info

if (trace)
htrc("JDBCDataSources: max=%d len=%d\n", maxres, length[0]);

/************************************************************************/
/* Allocate the structures used to refer to the result set. */
/************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, IDS_DSRC,
buftyp, fldtyp, length, false, true);

for (i = 0, crp = qrp->Colresp; crp; i++, crp = crp->Next)
if (b[i])
crp->Kdata->SetNullable(true);

/************************************************************************/
/* Now get the results into blocks. */
/************************************************************************/
if (!info && qrp && jcp->GetDataSources(qrp))
qrp = NULL;

/************************************************************************/
/* Return the result pointer for use by GetData routines. */
/************************************************************************/
return qrp;
} // end of JDBCDataSources

/**************************************************************************/
/* PrimaryKeys: constructs the result blocks containing all the */
/* JDBC catalog information concerning primary keys. */
/**************************************************************************/
PQRYRES JDBCPrimaryKeys(PGLOBAL g, JDBConn *op, char *dsn, char *table)
{
static int buftyp[] ={ TYPE_STRING, TYPE_STRING, TYPE_STRING,
TYPE_STRING, TYPE_SHORT, TYPE_STRING };
static unsigned int length[] ={ 0, 0, 0, 0, 6, 128 };
int n, ncol = 5;
int maxres;
PQRYRES qrp;
JCATPARM *cap;
JDBConn *jcp = op;

if (!op) {
/**********************************************************************/
/* Open the connection with the JDBC data source. */
/**********************************************************************/
jcp = new(g)JDBConn(g, NULL);

if (jcp->Open(dsn, 2) < 1) // 2 is openReadOnly
return NULL;

} // endif op

/************************************************************************/
/* Do an evaluation of the result size. */
/************************************************************************/
n = jcp->GetMaxValue(SQL_MAX_COLUMNS_IN_TABLE);
maxres = (n) ? (int)n : 250;
n = jcp->GetMaxValue(SQL_MAX_CATALOG_NAME_LEN);
length[0] = (n) ? (n + 1) : 128;
n = jcp->GetMaxValue(SQL_MAX_SCHEMA_NAME_LEN);
length[1] = (n) ? (n + 1) : 128;
n = jcp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
length[2] = (n) ? (n + 1) : 128;
n = jcp->GetMaxValue(SQL_MAX_COLUMN_NAME_LEN);
length[3] = (n) ? (n + 1) : 128;

if (trace)
htrc("JDBCPrimaryKeys: max=%d len=%d,%d,%d\n",
maxres, length[0], length[1], length[2]);

/************************************************************************/
/* Allocate the structure used to refer to the result set. */
/************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, IDS_PKEY,
buftyp, NULL, length, false, true);

if (trace)
htrc("Getting pkey results ncol=%d\n", qrp->Nbcol);

cap = AllocCatInfo(g, CAT_KEY, NULL, table, qrp);

/************************************************************************/
/* Now get the results into blocks. */
/************************************************************************/
if ((n = jcp->GetCatInfo(cap)) >= 0) {
qrp->Nblin = n;
// ResetNullValues(cap);

if (trace)
htrc("PrimaryKeys: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin);

} else
qrp = NULL;

/************************************************************************/
/* Close any local connection. */
/************************************************************************/
if (!op)
jcp->Close();

/************************************************************************/
/* Return the result pointer for use by GetData routines. */
/************************************************************************/
return qrp;
} // end of JDBCPrimaryKeys
#endif // 0

/***********************************************************************/
/* JDBConn construction/destruction. */
/***********************************************************************/
Expand Down Expand Up @@ -739,60 +600,6 @@ bool JDBConn::gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig

} // end of gmID

#if 0
/***********************************************************************/
/* Utility routine. */
/***********************************************************************/
PSZ JDBConn::GetStringInfo(ushort infotype)
{
//ASSERT(m_hdbc != SQL_NULL_HDBC);
char *p, buffer[MAX_STRING_INFO];
SWORD result;
RETCODE rc;

rc = SQLGetInfo(m_hdbc, infotype, buffer, sizeof(buffer), &result);

if (!Check(rc)) {
ThrowDJX(rc, "SQLGetInfo"); // Temporary
// *buffer = '\0';
} // endif rc

p = PlugDup(m_G, buffer);
return p;
} // end of GetStringInfo

/***********************************************************************/
/* Utility routines. */
/***********************************************************************/
void JDBConn::OnSetOptions(HSTMT hstmt)
{
RETCODE rc;
ASSERT(m_hdbc != SQL_NULL_HDBC);

if ((signed)m_QueryTimeout != -1) {
// Attempt to set query timeout. Ignore failure
rc = SQLSetStmtOption(hstmt, SQL_QUERY_TIMEOUT, m_QueryTimeout);

if (!Check(rc))
// don't attempt it again
m_QueryTimeout = (DWORD)-1;

} // endif m_QueryTimeout

if (m_RowsetSize > 0) {
// Attempt to set rowset size.
// In case of failure reset it to 0 to use Fetch.
rc = SQLSetStmtOption(hstmt, SQL_ROWSET_SIZE, m_RowsetSize);

if (!Check(rc))
// don't attempt it again
m_RowsetSize = 0;

} // endif m_RowsetSize

} // end of OnSetOptions
#endif // 0

/***********************************************************************/
/* Utility routine. */
/***********************************************************************/
Expand Down Expand Up @@ -1007,7 +814,7 @@ int JDBConn::Open(PJPARM sop)
#define N 1
#endif

// Java source will be compiled as ajar file installed in the plugin dir
// Java source will be compiled as a jar file installed in the plugin dir
jpop->Append(sep);
jpop->Append(GetPluginDir());
jpop->Append("JdbcInterface.jar");
Expand Down
4 changes: 2 additions & 2 deletions storage/connect/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ bool JOUTSTR::Escape(const char *s)
{
WriteChr('"');

for (unsigned int i = 0; i < strlen(s); i++)
for (unsigned int i = 0; s[i]; i++)
switch (s[i]) {
case '"':
case '\\':
Expand Down Expand Up @@ -816,7 +816,7 @@ bool JOUTFILE::Escape(const char *s)
// This is temporary
fputc('"', Stream);

for (unsigned int i = 0; i < strlen(s); i++)
for (unsigned int i = 0; s[i]; i++)
switch (s[i]) {
case '"': fputs("\\\"", Stream); break;
case '\\': fputs("\\\\", Stream); break;
Expand Down
2 changes: 1 addition & 1 deletion storage/connect/reldef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
nlg+= nof;
case TAB_DIR:
case TAB_XML:
poff= loff + 1;
poff= loff + (pcf->Flags & U_VIRTUAL ? 0 : 1);
break;
case TAB_INI:
case TAB_MAC:
Expand Down

0 comments on commit a4623b5

Please sign in to comment.