Commit d862d7c0 authored by Olivier Bertrand's avatar Olivier Bertrand

- Implement random access to ODBC tables

modified:
  storage/connect/odbconn.cpp
  storage/connect/odbconn.h

- Fix get proper length of ODBC DECIMAL column in discovery
modified:
  storage/connect/ha_connect.cc
  storage/connect/mysql-test/connect/r/odbc_oracle.result

- Implement random access to JSON tables
modified:
  storage/connect/tabjson.cpp
  storage/connect/tabjson.h

- Fix MDEV-7636
modified:
  storage/connect/tabutil.cpp
parent aa107ef3
...@@ -5462,7 +5462,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -5462,7 +5462,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
case TYPE_DOUBLE: case TYPE_DOUBLE:
// Some data sources do not count dec in length (prec) // Some data sources do not count dec in length (prec)
prec += (dec + 2); // To be safe prec += (dec + 2); // To be safe
break;
case TYPE_DECIM: case TYPE_DECIM:
prec= len;
break; break;
default: default:
dec= 0; dec= 0;
......
...@@ -126,7 +126,7 @@ TABNAME='T1'; ...@@ -126,7 +126,7 @@ TABNAME='T1';
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`A` decimal(38,0) DEFAULT NULL, `A` decimal(40,0) DEFAULT NULL,
`B` double(40,0) DEFAULT NULL `B` double(40,0) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='T1' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='T1'
SELECT * FROM t1 ORDER BY A; SELECT * FROM t1 ORDER BY A;
...@@ -138,7 +138,7 @@ CREATE TABLE t2 AS SELECT * FROM t1; ...@@ -138,7 +138,7 @@ CREATE TABLE t2 AS SELECT * FROM t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
`A` decimal(38,0) DEFAULT NULL, `A` decimal(40,0) DEFAULT NULL,
`B` double(40,0) DEFAULT NULL `B` double(40,0) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT * FROM t2; SELECT * FROM t2;
...@@ -162,7 +162,7 @@ TABNAME='MTR.T1'; ...@@ -162,7 +162,7 @@ TABNAME='MTR.T1';
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`A` decimal(38,0) DEFAULT NULL, `A` decimal(40,0) DEFAULT NULL,
`B` double(40,0) DEFAULT NULL `B` double(40,0) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T1' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T1'
SELECT * FROM t1; SELECT * FROM t1;
...@@ -178,7 +178,7 @@ TABNAME='MTR.V1'; ...@@ -178,7 +178,7 @@ TABNAME='MTR.V1';
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`A` decimal(38,0) DEFAULT NULL, `A` decimal(40,0) DEFAULT NULL,
`B` double(40,0) DEFAULT NULL `B` double(40,0) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.V1' ) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.V1'
SELECT * FROM t1; SELECT * FROM t1;
...@@ -190,7 +190,7 @@ CREATE TABLE t2 AS SELECT * FROM t1; ...@@ -190,7 +190,7 @@ CREATE TABLE t2 AS SELECT * FROM t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
`A` decimal(38,0) DEFAULT NULL, `A` decimal(40,0) DEFAULT NULL,
`B` double(40,0) DEFAULT NULL `B` double(40,0) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT * FROM t2; SELECT * FROM t2;
......
...@@ -102,7 +102,12 @@ static int GetSQLCType(int type) ...@@ -102,7 +102,12 @@ static int GetSQLCType(int type)
case TYPE_BIGINT: tp = SQL_C_SBIGINT; break; case TYPE_BIGINT: tp = SQL_C_SBIGINT; break;
case TYPE_DOUBLE: tp = SQL_C_DOUBLE; break; case TYPE_DOUBLE: tp = SQL_C_DOUBLE; break;
case TYPE_TINY : tp = SQL_C_TINYINT; break; case TYPE_TINY : tp = SQL_C_TINYINT; break;
//#if (ODBCVER >= 0x0300)
// case TYPE_DECIM: tp = SQL_C_NUMERIC; break; (CRASH!!!)
//#else
case TYPE_DECIM: tp = SQL_C_CHAR; break; case TYPE_DECIM: tp = SQL_C_CHAR; break;
//#endif
} // endswitch type } // endswitch type
return tp; return tp;
...@@ -923,13 +928,13 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp) ...@@ -923,13 +928,13 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp)
m_RowsetSize = (DWORD)((tdbp) ? tdbp->Rows : 10); m_RowsetSize = (DWORD)((tdbp) ? tdbp->Rows : 10);
m_Catver = (tdbp) ? tdbp->Catver : 0; m_Catver = (tdbp) ? tdbp->Catver : 0;
m_Rows = 0; m_Rows = 0;
m_Fetch = 0;
m_Connect = NULL; m_Connect = NULL;
m_User = NULL; m_User = NULL;
m_Pwd = NULL; m_Pwd = NULL;
m_Updatable = true; m_Updatable = true;
m_Transact = false; m_Transact = false;
m_Scrollable = (tdbp) ? tdbp->Scrollable : false; m_Scrollable = (tdbp) ? tdbp->Scrollable : false;
m_First = true;
m_Full = false; m_Full = false;
m_UseCnc = false; m_UseCnc = false;
m_IDQuoteChar[0] = '"'; m_IDQuoteChar[0] = '"';
...@@ -984,7 +989,7 @@ void ODBConn::ThrowDBX(RETCODE rc, PSZ msg, HSTMT hstmt) ...@@ -984,7 +989,7 @@ void ODBConn::ThrowDBX(RETCODE rc, PSZ msg, HSTMT hstmt)
void ODBConn::ThrowDBX(PSZ msg) void ODBConn::ThrowDBX(PSZ msg)
{ {
DBX* xp = new(m_G) DBX(0, msg); DBX* xp = new(m_G) DBX(0, "Error");
xp->m_ErrMsg[0] = msg; xp->m_ErrMsg[0] = msg;
throw xp; throw xp;
...@@ -1099,8 +1104,7 @@ int ODBConn::Open(PSZ ConnectString, POPARM sop, DWORD options) ...@@ -1099,8 +1104,7 @@ int ODBConn::Open(PSZ ConnectString, POPARM sop, DWORD options)
// VerifyConnect(); Deprecated // VerifyConnect(); Deprecated
GetConnectInfo(); GetConnectInfo();
} catch(DBX *xp) { } catch(DBX *xp) {
// strcpy(g->Message, xp->m_ErrMsg[0]); sprintf(g->Message, "%s: %s", xp->m_Msg, xp->GetErrorMessage(0));
strcpy(g->Message, xp->GetErrorMessage(0));
Close(); Close();
// Free(); // Free();
return -1; return -1;
...@@ -1356,7 +1360,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols) ...@@ -1356,7 +1360,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
rc = SQLFreeStmt(m_hstmt, SQL_CLOSE); rc = SQLFreeStmt(m_hstmt, SQL_CLOSE);
if (!Check(rc)) if (!Check(rc))
ThrowDBX(rc, "SQLFreeStmt"); ThrowDBX(rc, "SQLFreeStmt", m_hstmt);
m_hstmt = NULL; m_hstmt = NULL;
} // endif m_hstmt } // endif m_hstmt
...@@ -1371,7 +1375,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols) ...@@ -1371,7 +1375,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
(void*)SQL_SCROLLABLE, 0); (void*)SQL_SCROLLABLE, 0);
if (!Check(rc)) if (!Check(rc))
ThrowDBX(rc, "SQLSetStmtAttr"); ThrowDBX(rc, "Scrollable", hstmt);
} // endif m_Scrollable } // endif m_Scrollable
...@@ -1422,7 +1426,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols) ...@@ -1422,7 +1426,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
for (n = 0, colp = tocols; colp; colp = (PODBCCOL)colp->GetNext()) for (n = 0, colp = tocols; colp; colp = (PODBCCOL)colp->GetNext())
if (!colp->IsSpecial()) if (!colp->IsSpecial())
n++; n++;
// n can be 0 for query such as Select count(*) from table // n can be 0 for query such as Select count(*) from table
if (n && n != (UWORD)ncol) if (n && n != (UWORD)ncol)
...@@ -1458,7 +1462,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols) ...@@ -1458,7 +1462,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]); htrc(x->m_ErrMsg[i]);
strcpy(m_G->Message, x->GetErrorMessage(0)); sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
if (b) if (b)
SQLCancel(hstmt); SQLCancel(hstmt);
...@@ -1521,7 +1525,7 @@ int ODBConn::GetResultSize(char *sql, ODBCCOL *colp) ...@@ -1521,7 +1525,7 @@ int ODBConn::GetResultSize(char *sql, ODBCCOL *colp)
/***********************************************************************/ /***********************************************************************/
/* Fetch next row. */ /* Fetch next row. */
/***********************************************************************/ /***********************************************************************/
int ODBConn::Fetch() int ODBConn::Fetch(int pos)
{ {
ASSERT(m_hstmt); ASSERT(m_hstmt);
int irc; int irc;
...@@ -1531,7 +1535,9 @@ int ODBConn::Fetch() ...@@ -1531,7 +1535,9 @@ int ODBConn::Fetch()
try { try {
// do { // do {
if (m_RowsetSize) { if (pos) {
rc = SQLExtendedFetch(m_hstmt, SQL_FETCH_ABSOLUTE, pos, &crow, NULL);
} else if (m_RowsetSize) {
rc = SQLExtendedFetch(m_hstmt, SQL_FETCH_NEXT, 1, &crow, NULL); rc = SQLExtendedFetch(m_hstmt, SQL_FETCH_NEXT, 1, &crow, NULL);
} else { } else {
rc = SQLFetch(m_hstmt); rc = SQLFetch(m_hstmt);
...@@ -1544,29 +1550,22 @@ int ODBConn::Fetch() ...@@ -1544,29 +1550,22 @@ int ODBConn::Fetch()
m_hstmt, m_RowsetSize, rc); m_hstmt, m_RowsetSize, rc);
if (!Check(rc)) if (!Check(rc))
ThrowDBX(rc, "Fetch", m_hstmt); ThrowDBX(rc, "Fetching", m_hstmt);
irc = (rc == SQL_NO_DATA_FOUND) ? 0 : (int)crow;
if (m_First) {
// First fetch. Check whether the full table was read
if ((m_Full = irc < (signed)m_RowsetSize)) {
m_Tdb->Memory = 0; // Not needed anymore
m_Rows = irc; // Table size
} // endif m_Full
m_First = false;
} // endif m_First
if (m_Tdb->Memory == 1) if (rc == SQL_NO_DATA_FOUND) {
m_Rows += irc; m_Full = (m_Fetch == 1);
irc = 0;
} else
irc = (int)crow;
m_Fetch++;
m_Rows += irc;
} catch(DBX *x) { } catch(DBX *x) {
if (trace) if (trace)
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]); htrc(x->m_ErrMsg[i]);
strcpy(g->Message, x->GetErrorMessage(0)); sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
irc = -1; irc = -1;
} // end try/catch } // end try/catch
...@@ -1602,7 +1601,7 @@ int ODBConn::PrepareSQL(char *sql) ...@@ -1602,7 +1601,7 @@ int ODBConn::PrepareSQL(char *sql)
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]); htrc(x->m_ErrMsg[i]);
strcpy(g->Message, x->GetErrorMessage(0)); sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
} // end try/catch } // end try/catch
} // endif Mode } // endif Mode
...@@ -1648,7 +1647,7 @@ int ODBConn::PrepareSQL(char *sql) ...@@ -1648,7 +1647,7 @@ int ODBConn::PrepareSQL(char *sql)
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]); htrc(x->m_ErrMsg[i]);
strcpy(g->Message, x->GetErrorMessage(0)); sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
if (b) if (b)
SQLCancel(hstmt); SQLCancel(hstmt);
...@@ -1700,7 +1699,7 @@ int ODBConn::ExecuteSQL(void) ...@@ -1700,7 +1699,7 @@ int ODBConn::ExecuteSQL(void)
} // endif ncol } // endif ncol
} catch(DBX *x) { } catch(DBX *x) {
strcpy(m_G->Message, x->GetErrorMessage(0)); sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
SQLCancel(m_hstmt); SQLCancel(m_hstmt);
rc = SQLFreeStmt(m_hstmt, SQL_DROP); rc = SQLFreeStmt(m_hstmt, SQL_DROP);
m_hstmt = NULL; m_hstmt = NULL;
...@@ -1737,7 +1736,7 @@ bool ODBConn::BindParam(ODBCCOL *colp) ...@@ -1737,7 +1736,7 @@ bool ODBConn::BindParam(ODBCCOL *colp)
ThrowDBX(rc, "SQLDescribeParam", m_hstmt); ThrowDBX(rc, "SQLDescribeParam", m_hstmt);
} catch(DBX *x) { } catch(DBX *x) {
strcpy(m_G->Message, x->GetErrorMessage(0)); sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
colsize = colp->GetPrecision(); colsize = colp->GetPrecision();
sqlt = GetSQLType(buftype); sqlt = GetSQLType(buftype);
dec = IsTypeChar(buftype) ? 0 : colp->GetScale(); dec = IsTypeChar(buftype) ? 0 : colp->GetScale();
...@@ -1845,7 +1844,7 @@ bool ODBConn::ExecSQLcommand(char *sql) ...@@ -1845,7 +1844,7 @@ bool ODBConn::ExecSQLcommand(char *sql)
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]); htrc(x->m_ErrMsg[i]);
sprintf(g->Message, "Remote: %s", x->GetErrorMessage(0)); sprintf(g->Message, "Remote %s: %s", x->m_Msg, x->GetErrorMessage(0));
if (b) if (b)
SQLCancel(hstmt); SQLCancel(hstmt);
...@@ -1930,7 +1929,7 @@ PQRYRES ODBConn::GetMetaData(PGLOBAL g, char *dsn, char *src) ...@@ -1930,7 +1929,7 @@ PQRYRES ODBConn::GetMetaData(PGLOBAL g, char *dsn, char *src)
} // endfor i } // endfor i
} catch(DBX *x) { } catch(DBX *x) {
strcpy(g->Message, x->GetErrorMessage(0)); sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
goto err; goto err;
} // end try/catch } // end try/catch
...@@ -1981,7 +1980,7 @@ PQRYRES ODBConn::GetMetaData(PGLOBAL g, char *dsn, char *src) ...@@ -1981,7 +1980,7 @@ PQRYRES ODBConn::GetMetaData(PGLOBAL g, char *dsn, char *src)
} // endfor i } // endfor i
} catch(DBX *x) { } catch(DBX *x) {
strcpy(g->Message, x->GetErrorMessage(0)); sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
qrp = NULL; qrp = NULL;
} // end try/catch } // end try/catch
...@@ -2033,7 +2032,7 @@ bool ODBConn::GetDataSources(PQRYRES qrp) ...@@ -2033,7 +2032,7 @@ bool ODBConn::GetDataSources(PQRYRES qrp)
} // endfor i } // endfor i
} catch(DBX *x) { } catch(DBX *x) {
strcpy(m_G->Message, x->GetErrorMessage(0)); sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
rv = true; rv = true;
} // end try/catch } // end try/catch
...@@ -2084,7 +2083,7 @@ bool ODBConn::GetDrivers(PQRYRES qrp) ...@@ -2084,7 +2083,7 @@ bool ODBConn::GetDrivers(PQRYRES qrp)
} // endfor n } // endfor n
} catch(DBX *x) { } catch(DBX *x) {
strcpy(m_G->Message, x->GetErrorMessage(0)); sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
rv = true; rv = true;
} // end try/catch } // end try/catch
...@@ -2402,7 +2401,7 @@ int ODBConn::GetCatInfo(CATPARM *cap) ...@@ -2402,7 +2401,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
htrc(x->m_ErrMsg[i]); htrc(x->m_ErrMsg[i]);
strcpy(g->Message, x->GetErrorMessage(0)); sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
irc = -1; irc = -1;
} // end try/catch } // end try/catch
...@@ -2506,7 +2505,7 @@ int ODBConn::Rewind(char *sql, ODBCCOL *tocols) ...@@ -2506,7 +2505,7 @@ int ODBConn::Rewind(char *sql, ODBCCOL *tocols)
rbuf = (int)crow; rbuf = (int)crow;
} catch(DBX *x) { } catch(DBX *x) {
strcpy(m_G->Message, x->GetErrorMessage(0)); sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
rbuf = -1; rbuf = -1;
} // end try/catch } // end try/catch
......
...@@ -141,7 +141,7 @@ class ODBConn : public BLOCK { ...@@ -141,7 +141,7 @@ class ODBConn : public BLOCK {
//void SetUserPwd(PSZ pwd) {m_Pwd = pwd;} //void SetUserPwd(PSZ pwd) {m_Pwd = pwd;}
int GetResultSize(char *sql, ODBCCOL *colp); int GetResultSize(char *sql, ODBCCOL *colp);
int ExecDirectSQL(char *sql, ODBCCOL *tocols); int ExecDirectSQL(char *sql, ODBCCOL *tocols);
int Fetch(void); int Fetch(int pos = 0);
int PrepareSQL(char *sql); int PrepareSQL(char *sql);
int ExecuteSQL(void); int ExecuteSQL(void);
bool BindParam(ODBCCOL *colp); bool BindParam(ODBCCOL *colp);
...@@ -192,10 +192,10 @@ class ODBConn : public BLOCK { ...@@ -192,10 +192,10 @@ class ODBConn : public BLOCK {
PSZ m_Pwd; PSZ m_Pwd;
int m_Catver; int m_Catver;
int m_Rows; int m_Rows;
int m_Fetch;
bool m_Updatable; bool m_Updatable;
bool m_Transact; bool m_Transact;
bool m_Scrollable; bool m_Scrollable;
bool m_UseCnc; bool m_UseCnc;
bool m_First;
bool m_Full; bool m_Full;
}; // end of ODBConn class definition }; // end of ODBConn class definition
...@@ -1290,6 +1290,51 @@ int TDBJSON::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add) ...@@ -1290,6 +1290,51 @@ int TDBJSON::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
} // end of MakeIndex } // end of MakeIndex
/***********************************************************************/
/* Return the position in the table. */
/***********************************************************************/
int TDBJSON::GetRecpos(void)
{
#if 0
union {
uint Rpos;
BYTE Spos[4];
};
Rpos = htonl(Fpos);
Spos[0] = (BYTE)NextSame;
return Rpos;
#endif // 0
return Fpos;
} // end of GetRecpos
/***********************************************************************/
/* Set the position in the table. */
/***********************************************************************/
bool TDBJSON::SetRecpos(PGLOBAL g, int recpos)
{
#if 0
union {
uint Rpos;
BYTE Spos[4];
};
Rpos = recpos;
NextSame = Spos[0];
Spos[0] = 0;
Fpos = (signed)ntohl(Rpos);
//if (Fpos != (signed)ntohl(Rpos)) {
// Fpos = ntohl(Rpos);
// same = false;
//} else
// same = true;
#endif // 0
Fpos = recpos - 1;
return false;
} // end of SetRecpos
/***********************************************************************/ /***********************************************************************/
/* JSON Access Method opening routine. */ /* JSON Access Method opening routine. */
/***********************************************************************/ /***********************************************************************/
......
...@@ -174,10 +174,9 @@ class TDBJSON : public TDBJSN { ...@@ -174,10 +174,9 @@ class TDBJSON : public TDBJSN {
virtual int Cardinality(PGLOBAL g); virtual int Cardinality(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g); virtual int GetMaxSize(PGLOBAL g);
virtual void ResetSize(void); virtual void ResetSize(void);
virtual int GetRecpos(void) {return Fpos;}
virtual int GetProgCur(void) {return N;} virtual int GetProgCur(void) {return N;}
virtual bool SetRecpos(PGLOBAL g, int recpos) virtual int GetRecpos(void);
{Fpos = recpos - 1; return false;} virtual bool SetRecpos(PGLOBAL g, int recpos);
virtual bool OpenDB(PGLOBAL g); virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g);
virtual bool PrepareWriting(PGLOBAL g) {return false;} virtual bool PrepareWriting(PGLOBAL g) {return false;}
......
...@@ -135,9 +135,16 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -135,9 +135,16 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
//Options = ODBConn::noOdbcDialog | ODBConn::useCursorLib; //Options = ODBConn::noOdbcDialog | ODBConn::useCursorLib;
Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT); Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT);
Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT); Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT);
Scrollable = GetBoolCatInfo("Scrollable", false);
if ((Scrollable = GetBoolCatInfo("Scrollable", false)) && !Elemt)
Elemt = 1; // Cannot merge SQLFetch and SQLExtendedFetch
UseCnc = GetBoolCatInfo("UseDSN", false); UseCnc = GetBoolCatInfo("UseDSN", false);
Memory = GetBoolCatInfo("Memory", false);
// Memory was Boolean, it is now integer
if (!(Memory = GetIntCatInfo("Memory", 0)))
Memory = GetBoolCatInfo("Memory", false) ? 1 : 0;
Pseudo = 2; // FILID is Ok but not ROWID Pseudo = 2; // FILID is Ok but not ROWID
return false; return false;
} // end of DefineAM } // end of DefineAM
...@@ -206,7 +213,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp) ...@@ -206,7 +213,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
Quoted = MY_MAX(0, tdp->GetQuoted()); Quoted = MY_MAX(0, tdp->GetQuoted());
Rows = tdp->GetElemt(); Rows = tdp->GetElemt();
Catver = tdp->Catver; Catver = tdp->Catver;
Memory = (tdp->Memory) ? 1 : 0; Memory = tdp->Memory;
Scrollable = tdp->Scrollable; Scrollable = tdp->Scrollable;
Ops.UseCnc = tdp->UseCnc; Ops.UseCnc = tdp->UseCnc;
} else { } else {
...@@ -238,11 +245,13 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp) ...@@ -238,11 +245,13 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
DBQ = NULL; DBQ = NULL;
Qrp = NULL; Qrp = NULL;
Fpos = 0; Fpos = 0;
Curpos = 0;
AftRows = 0; AftRows = 0;
CurNum = 0; CurNum = 0;
Rbuf = 0; Rbuf = 0;
BufSize = 0; BufSize = 0;
Nparm = 0; Nparm = 0;
Placed = false;
} // end of TDBODBC standard constructor } // end of TDBODBC standard constructor
TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp) TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
...@@ -267,15 +276,15 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp) ...@@ -267,15 +276,15 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
Options = tdbp->Options; Options = tdbp->Options;
Quoted = tdbp->Quoted; Quoted = tdbp->Quoted;
Rows = tdbp->Rows; Rows = tdbp->Rows;
Fpos = tdbp->Fpos; Fpos = 0;
AftRows = tdbp->AftRows; Curpos = 0;
//Tpos = tdbp->Tpos; AftRows = 0;
//Spos = tdbp->Spos; CurNum = 0;
CurNum = tdbp->CurNum; Rbuf = 0;
Rbuf = tdbp->Rbuf;
BufSize = tdbp->BufSize; BufSize = tdbp->BufSize;
Nparm = tdbp->Nparm; Nparm = tdbp->Nparm;
Qrp = tdbp->Qrp; Qrp = tdbp->Qrp;
Placed = false;
} // end of TDBODBC copy constructor } // end of TDBODBC copy constructor
// Method // Method
...@@ -811,10 +820,12 @@ bool TDBODBC::OpenDB(PGLOBAL g) ...@@ -811,10 +820,12 @@ bool TDBODBC::OpenDB(PGLOBAL g)
return true; return true;
} // endif Rewind } // endif Rewind
} // endif Memory } else
Rbuf = Qrp->Nblin;
CurNum = 0; CurNum = 0;
Fpos = 0; Fpos = 0;
Curpos = 1;
return false; return false;
} // endif use } // endif use
...@@ -841,6 +852,37 @@ bool TDBODBC::OpenDB(PGLOBAL g) ...@@ -841,6 +852,37 @@ bool TDBODBC::OpenDB(PGLOBAL g)
/* Make the command and allocate whatever is used for getting results. */ /* Make the command and allocate whatever is used for getting results. */
/*********************************************************************/ /*********************************************************************/
if (Mode == MODE_READ || Mode == MODE_READX) { if (Mode == MODE_READ || Mode == MODE_READX) {
if (Memory > 1 && !Srcdef) {
char *Sql;
int n;
if ((Sql = MakeSQL(g, true))) {
// Allocate a Count(*) column
Cnp = new(g) ODBCCOL;
Cnp->InitValue(g);
if ((n = Ocp->GetResultSize(Sql, Cnp)) < 0) {
strcpy(g->Message, "Cannot get result size");
return true;
} // endif n
Ocp->m_Rows = n;
if ((Qrp = Ocp->AllocateResult(g)))
Memory = 2; // Must be filled
else {
strcpy(g->Message, "Memory allocation failed");
return true;
} // endif n
Ocp->m_Rows = 0;
} else {
strcpy(g->Message, "MakeSQL failed");
return true;
} // endif Sql
} // endif Memory
if ((Query = MakeSQL(g, false))) { if ((Query = MakeSQL(g, false))) {
for (PODBCCOL colp = (PODBCCOL)Columns; colp; for (PODBCCOL colp = (PODBCCOL)Columns; colp;
colp = (PODBCCOL)colp->GetNext()) colp = (PODBCCOL)colp->GetNext())
...@@ -882,9 +924,40 @@ bool TDBODBC::OpenDB(PGLOBAL g) ...@@ -882,9 +924,40 @@ bool TDBODBC::OpenDB(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int TDBODBC::GetRecpos(void) int TDBODBC::GetRecpos(void)
{ {
return Fpos; // To be really implemented return Fpos;
} // end of GetRecpos } // end of GetRecpos
/***********************************************************************/
/* SetRecpos: set the position of next read record. */
/***********************************************************************/
bool TDBODBC::SetRecpos(PGLOBAL g, int recpos)
{
if (Ocp->m_Full) {
Fpos = 0;
CurNum = recpos - 1;
} else if (Memory == 3) {
Fpos = recpos;
CurNum = -1;
} else if (Scrollable) {
// Is new position in the current row set?
if (recpos >= Curpos && recpos < Curpos + Rbuf) {
CurNum = recpos - Curpos;
Fpos = 0;
} else {
Fpos = recpos;
CurNum = 0;
} // endif recpos
} else {
strcpy(g->Message, "This action requires a scrollable cursor");
return true;
} // endif's
// Indicate the table position was externally set
Placed = true;
return false;
} // end of SetRecpos
/***********************************************************************/ /***********************************************************************/
/* VRDNDOS: Data Base read routine for odbc access method. */ /* VRDNDOS: Data Base read routine for odbc access method. */
/***********************************************************************/ /***********************************************************************/
...@@ -924,22 +997,32 @@ int TDBODBC::ReadDB(PGLOBAL g) ...@@ -924,22 +997,32 @@ int TDBODBC::ReadDB(PGLOBAL g)
/* Now start the reading process. */ /* Now start the reading process. */
/* Here is the place to fetch the line(s). */ /* Here is the place to fetch the line(s). */
/*********************************************************************/ /*********************************************************************/
if (Memory != 3) { if (Placed) {
if (++CurNum >= Rbuf) { if (Fpos && CurNum >= 0)
Rbuf = Ocp->Fetch(); Rbuf = Ocp->Fetch((Curpos = Fpos));
CurNum = 0;
} // endif CurNum
rc = (Rbuf > 0) ? RC_OK : (Rbuf == 0) ? RC_EF : RC_FX; rc = (Rbuf > 0) ? RC_OK : (Rbuf == 0) ? RC_EF : RC_FX;
} else // Getting result from memory Placed = false;
rc = (Fpos < Qrp->Nblin) ? RC_OK : RC_EF; } else {
if (Memory != 3) {
if (++CurNum >= Rbuf) {
Rbuf = Ocp->Fetch();
Curpos = Fpos + 1;
CurNum = 0;
} // endif CurNum
if (rc == RC_OK) { rc = (Rbuf > 0) ? RC_OK : (Rbuf == 0) ? RC_EF : RC_FX;
if (Memory == 2) } else // Getting result from memory
Qrp->Nblin++; rc = (Fpos < Qrp->Nblin) ? RC_OK : RC_EF;
Fpos++; // Used for memory if (rc == RC_OK) {
} // endif rc if (Memory == 2)
Qrp->Nblin++;
Fpos++; // Used for memory and pos
} // endif rc
} // endif Placed
if (trace > 1) if (trace > 1)
htrc(" Read: Rbuf=%d rc=%d\n", Rbuf, rc); htrc(" Read: Rbuf=%d rc=%d\n", Rbuf, rc);
......
...@@ -64,8 +64,8 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */ ...@@ -64,8 +64,8 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
int Quoted; /* Identifier quoting level */ int Quoted; /* Identifier quoting level */
int Maxerr; /* Maxerr for an Exec table */ int Maxerr; /* Maxerr for an Exec table */
int Maxres; /* Maxres for a catalog table */ int Maxres; /* Maxres for a catalog table */
int Memory; /* Put result set in memory */
bool Scrollable; /* Use scrollable cursor */ bool Scrollable; /* Use scrollable cursor */
bool Memory; /* Put result set in memory */
bool Xsrc; /* Execution type */ bool Xsrc; /* Execution type */
bool UseCnc; /* Use SQLConnect (!SQLDriverConnect) */ bool UseCnc; /* Use SQLConnect (!SQLDriverConnect) */
}; // end of ODBCDEF }; // end of ODBCDEF
...@@ -93,6 +93,7 @@ class TDBODBC : public TDBASE { ...@@ -93,6 +93,7 @@ class TDBODBC : public TDBASE {
// Methods // Methods
virtual PTDB CopyOne(PTABS t); virtual PTDB CopyOne(PTABS t);
virtual int GetRecpos(void); virtual int GetRecpos(void);
virtual bool SetRecpos(PGLOBAL g, int recpos);
virtual PSZ GetFile(PGLOBAL g); virtual PSZ GetFile(PGLOBAL g);
virtual void SetFile(PGLOBAL g, PSZ fn); virtual void SetFile(PGLOBAL g, PSZ fn);
virtual void ResetSize(void); virtual void ResetSize(void);
...@@ -148,6 +149,7 @@ class TDBODBC : public TDBASE { ...@@ -148,6 +149,7 @@ class TDBODBC : public TDBASE {
int Qto; // Query timeout int Qto; // Query timeout
int Quoted; // The identifier quoting level int Quoted; // The identifier quoting level
int Fpos; // Position of last read record int Fpos; // Position of last read record
int Curpos; // Cursor position of last fetch
int AftRows; // The number of affected rows int AftRows; // The number of affected rows
int Rows; // Rowset size int Rows; // Rowset size
int Catver; // Catalog ODBC version int Catver; // Catalog ODBC version
...@@ -157,6 +159,7 @@ class TDBODBC : public TDBASE { ...@@ -157,6 +159,7 @@ class TDBODBC : public TDBASE {
int Nparm; // The number of statement parameters int Nparm; // The number of statement parameters
int Memory; // 0: No 1: Alloc 2: Put 3: Get int Memory; // 0: No 1: Alloc 2: Put 3: Get
bool Scrollable; // Use scrollable cursor bool Scrollable; // Use scrollable cursor
bool Placed; // True for position reading
bool UseCnc; // Use SQLConnect (!SQLDriverConnect) bool UseCnc; // Use SQLConnect (!SQLDriverConnect)
PQRYRES Qrp; // Points to storage result PQRYRES Qrp; // Points to storage result
}; // end of class TDBODBC }; // end of class TDBODBC
......
/************* Tabutil cpp Declares Source Code File (.CPP) ************/ /************* Tabutil cpp Declares Source Code File (.CPP) ************/
/* Name: TABUTIL.CPP Version 1.0 */ /* Name: TABUTIL.CPP Version 1.1 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2013 */ /* (C) Copyright to the author Olivier BERTRAND 2013 - 2015 */
/* */ /* */
/* Utility function used by the PROXY, XCOL, OCCUR, and TBL tables. */ /* Utility function used by the PROXY, XCOL, OCCUR, and TBL tables. */
/***********************************************************************/ /***********************************************************************/
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
/***********************************************************************/ /***********************************************************************/
/* Include relevant section of system dependant header files. */ /* Include relevant section of system dependant header files. */
/***********************************************************************/ /***********************************************************************/
#include "my_global.h" #define MYSQL_SERVER 1
#include <my_global.h>
#include "sql_class.h" #include "sql_class.h"
#include "table.h" #include "table.h"
#include "field.h" #include "field.h"
...@@ -108,6 +109,9 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db, ...@@ -108,6 +109,9 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db,
} // endif is_view } // endif is_view
} else { } else {
if (thd->is_error())
thd->clear_error(); // Avoid stopping info commands
sprintf(g->Message, "Error %d opening share\n", s->error); sprintf(g->Message, "Error %d opening share\n", s->error);
free_table_share(s); free_table_share(s);
return NULL; return NULL;
......
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