Commit 2cfccbe4 authored by Sergei Golubchik's avatar Sergei Golubchik

Merge branch 'connect/10.0' into 10.0

parents de9ea40f b7aee7db
...@@ -340,6 +340,18 @@ public class JdbcInterface { ...@@ -340,6 +340,18 @@ public class JdbcInterface {
return m; return m;
} // end of GetMaxValue } // end of GetMaxValue
public String GetQuoteString() {
String qs = null;
try {
qs = dbmd.getIdentifierQuoteString();
} catch(SQLException se) {
SetErrmsg(se);
} // end try/catch
return qs;
} // end of GetQuoteString
public int GetColumns(String[] parms) { public int GetColumns(String[] parms) {
int ncol = -1; int ncol = -1;
...@@ -680,11 +692,11 @@ public class JdbcInterface { ...@@ -680,11 +692,11 @@ public class JdbcInterface {
return 0; return 0;
} // end of TimestampField } // end of TimestampField
public String ObjectField(int n, String name) { public Object ObjectField(int n, String name) {
if (rs == null) { if (rs == null) {
System.out.println("No result set"); System.out.println("No result set");
} else try { } else try {
return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); return (n > 0) ? rs.getObject(n) : rs.getObject(name);
} catch (SQLException se) { } catch (SQLException se) {
SetErrmsg(se); SetErrmsg(se);
} //end try/catch } //end try/catch
......
...@@ -383,7 +383,7 @@ DBFBASE::DBFBASE(DBFBASE *txfp) ...@@ -383,7 +383,7 @@ DBFBASE::DBFBASE(DBFBASE *txfp)
/* and header length. Set Records, check that Reclen is equal to lrecl and */ /* and header length. Set Records, check that Reclen is equal to lrecl and */
/* return the header length or 0 in case of error. */ /* return the header length or 0 in case of error. */
/****************************************************************************/ /****************************************************************************/
int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath) int DBFBASE::ScanHeader(PGLOBAL g, PSZ fn, int lrecl, int *rln, char *defpath)
{ {
int rc; int rc;
char filename[_MAX_PATH]; char filename[_MAX_PATH];
...@@ -393,7 +393,7 @@ int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath) ...@@ -393,7 +393,7 @@ int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath)
/************************************************************************/ /************************************************************************/
/* Open the input file. */ /* Open the input file. */
/************************************************************************/ /************************************************************************/
PlugSetPath(filename, fname, defpath); PlugSetPath(filename, fn, defpath);
if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb"))) if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb")))
return 0; // Assume file does not exist return 0; // Assume file does not exist
...@@ -410,11 +410,7 @@ int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath) ...@@ -410,11 +410,7 @@ int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath)
} else if (rc == RC_FX) } else if (rc == RC_FX)
return -1; return -1;
if ((int)header.Reclen() != lrecl) { *rln = (int)header.Reclen();
sprintf(g->Message, MSG(BAD_LRECL), lrecl, header.Reclen());
return -1;
} // endif Lrecl
Records = (int)header.Records(); Records = (int)header.Records();
return (int)header.Headlen(); return (int)header.Headlen();
} // end of ScanHeader } // end of ScanHeader
...@@ -431,9 +427,27 @@ int DBFFAM::Cardinality(PGLOBAL g) ...@@ -431,9 +427,27 @@ int DBFFAM::Cardinality(PGLOBAL g)
if (!g) if (!g)
return 1; return 1;
if (!Headlen) if (!Headlen) {
if ((Headlen = ScanHeader(g, To_File, Lrecl, Tdbp->GetPath())) < 0) int rln = 0; // Record length in the file header
return -1; // Error in ScanHeader
Headlen = ScanHeader(g, To_File, Lrecl, &rln, Tdbp->GetPath());
if (Headlen < 0)
return -1; // Error in ScanHeader
if (rln && Lrecl != rln) {
// This happens always on some Linux platforms
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, rln);
if (Accept) {
Lrecl = rln;
PushWarning(g, Tdbp);
} else
return -1;
} // endif rln
} // endif Headlen
// Set number of blocks for later use // Set number of blocks for later use
Block = (Records > 0) ? (Records + Nrec - 1) / Nrec : 0; Block = (Records > 0) ? (Records + Nrec - 1) / Nrec : 0;
...@@ -565,7 +579,13 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g) ...@@ -565,7 +579,13 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
if (Lrecl != reclen) { if (Lrecl != reclen) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, reclen); sprintf(g->Message, MSG(BAD_LRECL), Lrecl, reclen);
return true;
if (Accept) {
Lrecl = reclen;
PushWarning(g, Tdbp);
} else
return true;
} // endif Lrecl } // endif Lrecl
hlen = HEADLEN * (n + 1) + 2; hlen = HEADLEN * (n + 1) + 2;
...@@ -641,8 +661,14 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g) ...@@ -641,8 +661,14 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
if ((rc = dbfhead(g, Stream, Tdbp->GetFile(g), &header)) == RC_OK) { if ((rc = dbfhead(g, Stream, Tdbp->GetFile(g), &header)) == RC_OK) {
if (Lrecl != (int)header.Reclen()) { if (Lrecl != (int)header.Reclen()) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, header.Reclen()); sprintf(g->Message, MSG(BAD_LRECL), Lrecl, header.Reclen());
return true;
} // endif Lrecl if (Accept) {
Lrecl = header.Reclen();
PushWarning(g, Tdbp);
} else
return true;
} // endif Lrecl
Records = (int)header.Records(); Records = (int)header.Records();
Headlen = (int)header.Headlen(); Headlen = (int)header.Headlen();
...@@ -916,9 +942,27 @@ int DBMFAM::Cardinality(PGLOBAL g) ...@@ -916,9 +942,27 @@ int DBMFAM::Cardinality(PGLOBAL g)
if (!g) if (!g)
return 1; return 1;
if (!Headlen) if (!Headlen) {
if ((Headlen = ScanHeader(g, To_File, Lrecl, Tdbp->GetPath())) < 0) int rln = 0; // Record length in the file header
return -1; // Error in ScanHeader
Headlen = ScanHeader(g, To_File, Lrecl, &rln, Tdbp->GetPath());
if (Headlen < 0)
return -1; // Error in ScanHeader
if (rln && Lrecl != rln) {
// This happens always on some Linux platforms
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, rln);
if (Accept) {
Lrecl = rln;
PushWarning(g, Tdbp);
} else
return -1;
} // endif rln
} // endif Headlen
// Set number of blocks for later use // Set number of blocks for later use
Block = (Records > 0) ? (Records + Nrec - 1) / Nrec : 0; Block = (Records > 0) ? (Records + Nrec - 1) / Nrec : 0;
...@@ -961,8 +1005,14 @@ bool DBMFAM::AllocateBuffer(PGLOBAL g) ...@@ -961,8 +1005,14 @@ bool DBMFAM::AllocateBuffer(PGLOBAL g)
if (Lrecl != (int)hp->Reclen()) { if (Lrecl != (int)hp->Reclen()) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, hp->Reclen()); sprintf(g->Message, MSG(BAD_LRECL), Lrecl, hp->Reclen());
return true;
} // endif Lrecl if (Accept) {
Lrecl = hp->Reclen();
PushWarning(g, Tdbp);
} else
return true;
} // endif Lrecl
Records = (int)hp->Records(); Records = (int)hp->Records();
Headlen = (int)hp->Headlen(); Headlen = (int)hp->Headlen();
......
...@@ -31,7 +31,7 @@ class DllExport DBFBASE { ...@@ -31,7 +31,7 @@ class DllExport DBFBASE {
DBFBASE(PDBF txfp); DBFBASE(PDBF txfp);
// Implementation // Implementation
int ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath); int ScanHeader(PGLOBAL g, PSZ fname, int lrecl, int *rlen, char *defpath);
protected: protected:
// Default constructor, not to be used // Default constructor, not to be used
......
...@@ -224,6 +224,7 @@ uint GetWorkSize(void); ...@@ -224,6 +224,7 @@ uint GetWorkSize(void);
void SetWorkSize(uint); void SetWorkSize(uint);
extern "C" const char *msglang(void); extern "C" const char *msglang(void);
static void PopUser(PCONNECT xp);
static PCONNECT GetUser(THD *thd, PCONNECT xp); static PCONNECT GetUser(THD *thd, PCONNECT xp);
static PGLOBAL GetPlug(THD *thd, PCONNECT& lxp); static PGLOBAL GetPlug(THD *thd, PCONNECT& lxp);
...@@ -831,34 +832,43 @@ ha_connect::~ha_connect(void) ...@@ -831,34 +832,43 @@ ha_connect::~ha_connect(void)
table ? table->s->table_name.str : "<null>", table ? table->s->table_name.str : "<null>",
xp, xp ? xp->count : 0); xp, xp ? xp->count : 0);
if (xp) { PopUser(xp);
PCONNECT p; } // end of ha_connect destructor
xp->count--;
for (p= user_connect::to_users; p; p= p->next) /****************************************************************************/
if (p == xp) /* Check whether this user can be removed. */
break; /****************************************************************************/
static void PopUser(PCONNECT xp)
{
if (xp) {
xp->count--;
if (p && !p->count) { if (!xp->count) {
if (p->next) PCONNECT p;
p->next->previous= p->previous;
if (p->previous) for (p= user_connect::to_users; p; p= p->next)
p->previous->next= p->next; if (p == xp)
else break;
user_connect::to_users= p->next;
} // endif p if (p) {
if (p->next)
p->next->previous= p->previous;
if (!xp->count) { if (p->previous)
PlugCleanup(xp->g, true); p->previous->next= p->next;
delete xp; else
} // endif count 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
/****************************************************************************/ /****************************************************************************/
...@@ -866,7 +876,7 @@ ha_connect::~ha_connect(void) ...@@ -866,7 +876,7 @@ ha_connect::~ha_connect(void)
/****************************************************************************/ /****************************************************************************/
static PCONNECT GetUser(THD *thd, PCONNECT xp) static PCONNECT GetUser(THD *thd, PCONNECT xp)
{ {
if (!thd) if (!thd)
return NULL; return NULL;
if (xp && thd == xp->thdp) if (xp && thd == xp->thdp)
...@@ -890,7 +900,6 @@ static PCONNECT GetUser(THD *thd, PCONNECT xp) ...@@ -890,7 +900,6 @@ static PCONNECT GetUser(THD *thd, PCONNECT xp)
return xp; return xp;
} // end of GetUser } // end of GetUser
/****************************************************************************/ /****************************************************************************/
/* Get the global pointer of the user of this handler. */ /* Get the global pointer of the user of this handler. */
/****************************************************************************/ /****************************************************************************/
...@@ -5261,7 +5270,18 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5261,7 +5270,18 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (!(shm= (char*)db)) if (!(shm= (char*)db))
db= table_s->db.str; // Default value 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) { if (ttp == TAB_UNDEF) {
topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS"; topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS";
ttp= GetTypeID(topt->type); ttp= GetTypeID(topt->type);
...@@ -5270,20 +5290,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5270,20 +5290,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
} else if (ttp == TAB_NIY) { } else if (ttp == TAB_NIY) {
sprintf(g->Message, "Unsupported table type %s", topt->type); sprintf(g->Message, "Unsupported table type %s", topt->type);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
return HA_ERR_INTERNAL_ERROR; goto err;
} // endif ttp } // 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 (!tab) {
if (ttp == TAB_TBL) { if (ttp == TAB_TBL) {
// Make tab the first table of the list // Make tab the first table of the list
...@@ -5843,6 +5852,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5843,6 +5852,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
rc= init_table_share(thd, table_s, create_info, &sql); rc= init_table_share(thd, table_s, create_info, &sql);
g->jump_level--; g->jump_level--;
PopUser(xp);
return rc; return rc;
} // endif ok } // endif ok
...@@ -5850,7 +5860,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd, ...@@ -5850,7 +5860,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
err: err:
g->jump_level--; g->jump_level--;
return HA_ERR_INTERNAL_ERROR; jer:
PopUser(xp);
return HA_ERR_INTERNAL_ERROR;
} // end of connect_assisted_discovery } // end of connect_assisted_discovery
/** /**
......
...@@ -498,145 +498,6 @@ PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info) ...@@ -498,145 +498,6 @@ PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info)
return qrp; return qrp;
} // end of JDBCDrivers } // 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. */ /* JDBConn construction/destruction. */
/***********************************************************************/ /***********************************************************************/
...@@ -651,7 +512,7 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) ...@@ -651,7 +512,7 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp)
xqid = xuid = xid = grs = readid = fetchid = typid = errid = nullptr; xqid = xuid = xid = grs = readid = fetchid = typid = errid = nullptr;
prepid = xpid = pcid = nullptr; prepid = xpid = pcid = nullptr;
chrfldid = intfldid = dblfldid = fltfldid = bigfldid = nullptr; chrfldid = intfldid = dblfldid = fltfldid = bigfldid = nullptr;
datfldid = timfldid = tspfldid = nullptr; objfldid = datfldid = timfldid = tspfldid = nullptr;
//m_LoginTimeout = DEFAULT_LOGIN_TIMEOUT; //m_LoginTimeout = DEFAULT_LOGIN_TIMEOUT;
//m_QueryTimeout = DEFAULT_QUERY_TIMEOUT; //m_QueryTimeout = DEFAULT_QUERY_TIMEOUT;
//m_UpdateOptions = 0; //m_UpdateOptions = 0;
...@@ -739,60 +600,6 @@ bool JDBConn::gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig ...@@ -739,60 +600,6 @@ bool JDBConn::gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig
} // end of gmID } // 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. */ /* Utility routine. */
/***********************************************************************/ /***********************************************************************/
...@@ -1007,7 +814,7 @@ int JDBConn::Open(PJPARM sop) ...@@ -1007,7 +814,7 @@ int JDBConn::Open(PJPARM sop)
#define N 1 #define N 1
#endif #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(sep);
jpop->Append(GetPluginDir()); jpop->Append(GetPluginDir());
jpop->Append("JdbcInterface.jar"); jpop->Append("JdbcInterface.jar");
...@@ -1204,6 +1011,21 @@ int JDBConn::Open(PJPARM sop) ...@@ -1204,6 +1011,21 @@ int JDBConn::Open(PJPARM sop)
return RC_FX; return RC_FX;
} // endif Msg } // endif Msg
jmethodID qcid = nullptr;
if (!gmID(g, qcid, "GetQuoteString", "()Ljava/lang/String;")) {
jstring s = (jstring)env->CallObjectMethod(job, qcid);
if (s != nullptr) {
char *qch = (char*)env->GetStringUTFChars(s, (jboolean)false);
m_IDQuoteChar[0] = *qch;
} else {
s = (jstring)env->CallObjectMethod(job, errid);
Msg = (char*)env->GetStringUTFChars(s, (jboolean)false);
} // endif s
} // endif qcid
if (gmID(g, typid, "ColumnType", "(ILjava/lang/String;)I")) if (gmID(g, typid, "ColumnType", "(ILjava/lang/String;)I"))
return RC_FX; return RC_FX;
else else
...@@ -1345,9 +1167,10 @@ void JDBConn::Close() ...@@ -1345,9 +1167,10 @@ void JDBConn::Close()
/***********************************************************************/ /***********************************************************************/
void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
{ {
PGLOBAL& g = m_G; PGLOBAL& g = m_G;
jint ctyp; jint ctyp;
jstring cn, jn = nullptr; jstring cn, jn = nullptr;
jobject jb = nullptr;
if (rank == 0) if (rank == 0)
if (!name || (jn = env->NewStringUTF(name)) == nullptr) { if (!name || (jn = env->NewStringUTF(name)) == nullptr) {
...@@ -1363,21 +1186,32 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1363,21 +1186,32 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC);
} // endif Check } // endif Check
if (val->GetNullable())
if (!gmID(g, objfldid, "ObjectField", "(ILjava/lang/String;)Ljava/lang/Object;")) {
jb = env->CallObjectMethod(job, objfldid, (jint)rank, jn);
if (jb == nullptr) {
val->Reset();
val->SetNull(true);
goto chk;
} // endif job
} // endif objfldid
switch (ctyp) { switch (ctyp) {
case 12: // VARCHAR case 12: // VARCHAR
case -1: // LONGVARCHAR case -1: // LONGVARCHAR
case 1: // CHAR case 1: // CHAR
if (!gmID(g, chrfldid, "StringField", "(ILjava/lang/String;)Ljava/lang/String;")) { if (jb)
cn = (jstring)jb;
else if (!gmID(g, chrfldid, "StringField", "(ILjava/lang/String;)Ljava/lang/String;"))
cn = (jstring)env->CallObjectMethod(job, chrfldid, (jint)rank, jn); cn = (jstring)env->CallObjectMethod(job, chrfldid, (jint)rank, jn);
else
cn = nullptr;
if (cn) { if (cn) {
const char *field = env->GetStringUTFChars(cn, (jboolean)false); const char *field = env->GetStringUTFChars(cn, (jboolean)false);
val->SetValue_psz((PSZ)field); val->SetValue_psz((PSZ)field);
} else {
val->Reset();
val->SetNull(true);
} // endif cn
} else } else
val->Reset(); val->Reset();
...@@ -1449,6 +1283,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) ...@@ -1449,6 +1283,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
val->Reset(); val->Reset();
} // endswitch Type } // endswitch Type
chk:
if (Check()) { if (Check()) {
if (rank == 0) if (rank == 0)
env->DeleteLocalRef(jn); env->DeleteLocalRef(jn);
......
...@@ -165,6 +165,7 @@ class JDBConn : public BLOCK { ...@@ -165,6 +165,7 @@ class JDBConn : public BLOCK {
jmethodID xpid; // The ExecutePrep method ID jmethodID xpid; // The ExecutePrep method ID
jmethodID pcid; // The ClosePrepStmt method ID jmethodID pcid; // The ClosePrepStmt method ID
jmethodID errid; // The GetErrmsg method ID jmethodID errid; // The GetErrmsg method ID
jmethodID objfldid; // The ObjectField method ID
jmethodID chrfldid; // The StringField method ID jmethodID chrfldid; // The StringField method ID
jmethodID intfldid; // The IntField method ID jmethodID intfldid; // The IntField method ID
jmethodID dblfldid; // The DoubleField method ID jmethodID dblfldid; // The DoubleField method ID
......
...@@ -595,7 +595,7 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty) ...@@ -595,7 +595,7 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty)
fputs(EL, fs); fputs(EL, fs);
fclose(fs); fclose(fs);
str = (err) ? NULL : strcpy(g->Message, "Ok"); str = (err) ? NULL : strcpy(g->Message, "Ok");
} else if (!err) { } else if (!err) {
str = ((JOUTSTR*)jp)->Strp; str = ((JOUTSTR*)jp)->Strp;
jp->WriteChr('\0'); jp->WriteChr('\0');
PlugSubAlloc(g, NULL, ((JOUTSTR*)jp)->N); PlugSubAlloc(g, NULL, ((JOUTSTR*)jp)->N);
......
...@@ -294,7 +294,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g) ...@@ -294,7 +294,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
nlg+= nof; nlg+= nof;
case TAB_DIR: case TAB_DIR:
case TAB_XML: case TAB_XML:
poff= loff + 1; poff= loff + (pcf->Flags & U_VIRTUAL ? 0 : 1);
break; break;
case TAB_INI: case TAB_INI:
case TAB_MAC: case TAB_MAC:
...@@ -440,7 +440,11 @@ int TABDEF::GetColCatInfo(PGLOBAL g) ...@@ -440,7 +440,11 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
} // endswitch tc } // endswitch tc
// lrecl must be at least recln to avoid buffer overflow // lrecl must be at least recln to avoid buffer overflow
recln= MY_MAX(recln, Hc->GetIntegerOption("Lrecl")); if (trace)
htrc("Lrecl: Calculated=%d defined=%d\n",
recln, Hc->GetIntegerOption("Lrecl"));
recln = MY_MAX(recln, Hc->GetIntegerOption("Lrecl"));
Hc->SetIntegerOption("Lrecl", recln); Hc->SetIntegerOption("Lrecl", recln);
((PDOSDEF)this)->SetLrecl(recln); ((PDOSDEF)this)->SetLrecl(recln);
} // endif Lrecl } // endif Lrecl
......
...@@ -686,6 +686,9 @@ bool TDBJDBC::MakeInsert(PGLOBAL g) ...@@ -686,6 +686,9 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
else else
Prepared = true; Prepared = true;
if (trace)
htrc("Insert=%s\n", Query->GetStr());
return false; return false;
} // end of MakeInsert } // end of MakeInsert
...@@ -733,17 +736,18 @@ bool TDBJDBC::MakeCommand(PGLOBAL g) ...@@ -733,17 +736,18 @@ bool TDBJDBC::MakeCommand(PGLOBAL g)
// If so, it must be quoted in the original query // If so, it must be quoted in the original query
strlwr(strcat(strcat(strcpy(name, " "), Name), " ")); strlwr(strcat(strcat(strcpy(name, " "), Name), " "));
if (!strstr(" update delete low_priority ignore quick from ", name)) if (strstr(" update delete low_priority ignore quick from ", name)) {
strlwr(strcpy(name, Name)); // Not a keyword
else
strlwr(strcat(strcat(strcpy(name, qc), Name), qc)); strlwr(strcat(strcat(strcpy(name, qc), Name), qc));
k += 2;
} else
strlwr(strcpy(name, Name)); // Not a keyword
if ((p = strstr(qrystr, name))) { if ((p = strstr(qrystr, name))) {
for (i = 0; i < p - qrystr; i++) for (i = 0; i < p - qrystr; i++)
stmt[i] = (Qrystr[i] == '`') ? *qc : Qrystr[i]; stmt[i] = (Qrystr[i] == '`') ? *qc : Qrystr[i];
stmt[i] = 0; stmt[i] = 0;
k = i + (int)strlen(Name); k += i + (int)strlen(Name);
if (qtd && *(p-1) == ' ') if (qtd && *(p-1) == ' ')
strcat(strcat(strcat(stmt, qc), TableName), qc); strcat(strcat(strcat(stmt, qc), TableName), qc);
...@@ -765,6 +769,9 @@ bool TDBJDBC::MakeCommand(PGLOBAL g) ...@@ -765,6 +769,9 @@ bool TDBJDBC::MakeCommand(PGLOBAL g)
return NULL; return NULL;
} // endif p } // endif p
if (trace)
htrc("Command=%s\n", stmt);
Query = new(g)STRING(g, 0, stmt); Query = new(g)STRING(g, 0, stmt);
return (!Query->GetSize()); return (!Query->GetSize());
} // end of MakeCommand } // end of MakeCommand
...@@ -1214,6 +1221,10 @@ int TDBJDBC::WriteDB(PGLOBAL g) ...@@ -1214,6 +1221,10 @@ int TDBJDBC::WriteDB(PGLOBAL g)
} // endif oom } // endif oom
Query->RepLast(')'); Query->RepLast(')');
if (trace > 1)
htrc("Inserting: %s\n", Query->GetStr());
rc = Jcp->ExecuteUpdate(Query->GetStr()); rc = Jcp->ExecuteUpdate(Query->GetStr());
Query->Truncate(len); // Restore query Query->Truncate(len); // Restore query
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment