diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2015-02-28 23:01:55 +0100 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2015-02-28 23:01:55 +0100 |
commit | d862d7c049f95575242164341605b7e69d71e427 (patch) | |
tree | d6cebd444750355e66b1b199e6ff954c01bfef26 /storage | |
parent | aa107ef3ab47c9bfbd177672e64d2af56ce1b1b5 (diff) | |
download | mariadb-git-d862d7c049f95575242164341605b7e69d71e427.tar.gz |
- 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
Diffstat (limited to 'storage')
-rw-r--r-- | storage/connect/ha_connect.cc | 2 | ||||
-rw-r--r-- | storage/connect/mysql-test/connect/r/odbc_oracle.result | 10 | ||||
-rw-r--r-- | storage/connect/odbconn.cpp | 73 | ||||
-rw-r--r-- | storage/connect/odbconn.h | 4 | ||||
-rw-r--r-- | storage/connect/tabjson.cpp | 45 | ||||
-rw-r--r-- | storage/connect/tabjson.h | 5 | ||||
-rw-r--r-- | storage/connect/tabodbc.cpp | 129 | ||||
-rw-r--r-- | storage/connect/tabodbc.h | 5 | ||||
-rw-r--r-- | storage/connect/tabutil.cpp | 10 |
9 files changed, 209 insertions, 74 deletions
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 64c81272b59..ea81bf43a01 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -5462,7 +5462,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, case TYPE_DOUBLE: // Some data sources do not count dec in length (prec) prec += (dec + 2); // To be safe + break; case TYPE_DECIM: + prec= len; break; default: dec= 0; diff --git a/storage/connect/mysql-test/connect/r/odbc_oracle.result b/storage/connect/mysql-test/connect/r/odbc_oracle.result index fff2f192184..96d8e53b8e5 100644 --- a/storage/connect/mysql-test/connect/r/odbc_oracle.result +++ b/storage/connect/mysql-test/connect/r/odbc_oracle.result @@ -126,7 +126,7 @@ TABNAME='T1'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `A` decimal(38,0) DEFAULT NULL, + `A` decimal(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' SELECT * FROM t1 ORDER BY A; @@ -138,7 +138,7 @@ CREATE TABLE t2 AS SELECT * FROM t1; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `A` decimal(38,0) DEFAULT NULL, + `A` decimal(40,0) DEFAULT NULL, `B` double(40,0) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 SELECT * FROM t2; @@ -162,7 +162,7 @@ TABNAME='MTR.T1'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `A` decimal(38,0) DEFAULT NULL, + `A` decimal(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' SELECT * FROM t1; @@ -178,7 +178,7 @@ TABNAME='MTR.V1'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `A` decimal(38,0) DEFAULT NULL, + `A` decimal(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' SELECT * FROM t1; @@ -190,7 +190,7 @@ CREATE TABLE t2 AS SELECT * FROM t1; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `A` decimal(38,0) DEFAULT NULL, + `A` decimal(40,0) DEFAULT NULL, `B` double(40,0) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 SELECT * FROM t2; diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index fec14820ef6..ea20672eb29 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -102,7 +102,12 @@ static int GetSQLCType(int type) case TYPE_BIGINT: tp = SQL_C_SBIGINT; break; case TYPE_DOUBLE: tp = SQL_C_DOUBLE; 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; +//#endif + } // endswitch type return tp; @@ -923,13 +928,13 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp) m_RowsetSize = (DWORD)((tdbp) ? tdbp->Rows : 10); m_Catver = (tdbp) ? tdbp->Catver : 0; m_Rows = 0; + m_Fetch = 0; m_Connect = NULL; m_User = NULL; m_Pwd = NULL; m_Updatable = true; m_Transact = false; m_Scrollable = (tdbp) ? tdbp->Scrollable : false; - m_First = true; m_Full = false; m_UseCnc = false; m_IDQuoteChar[0] = '"'; @@ -984,7 +989,7 @@ void ODBConn::ThrowDBX(RETCODE rc, PSZ msg, HSTMT hstmt) 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; throw xp; @@ -1099,8 +1104,7 @@ int ODBConn::Open(PSZ ConnectString, POPARM sop, DWORD options) // VerifyConnect(); Deprecated GetConnectInfo(); } catch(DBX *xp) { -// strcpy(g->Message, xp->m_ErrMsg[0]); - strcpy(g->Message, xp->GetErrorMessage(0)); + sprintf(g->Message, "%s: %s", xp->m_Msg, xp->GetErrorMessage(0)); Close(); // Free(); return -1; @@ -1356,7 +1360,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols) rc = SQLFreeStmt(m_hstmt, SQL_CLOSE); if (!Check(rc)) - ThrowDBX(rc, "SQLFreeStmt"); + ThrowDBX(rc, "SQLFreeStmt", m_hstmt); m_hstmt = NULL; } // endif m_hstmt @@ -1371,7 +1375,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols) (void*)SQL_SCROLLABLE, 0); if (!Check(rc)) - ThrowDBX(rc, "SQLSetStmtAttr"); + ThrowDBX(rc, "Scrollable", hstmt); } // endif m_Scrollable @@ -1422,7 +1426,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols) for (n = 0, colp = tocols; colp; colp = (PODBCCOL)colp->GetNext()) if (!colp->IsSpecial()) - n++; + n++; // n can be 0 for query such as Select count(*) from table if (n && n != (UWORD)ncol) @@ -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++) 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) SQLCancel(hstmt); @@ -1521,7 +1525,7 @@ int ODBConn::GetResultSize(char *sql, ODBCCOL *colp) /***********************************************************************/ /* Fetch next row. */ /***********************************************************************/ -int ODBConn::Fetch() +int ODBConn::Fetch(int pos) { ASSERT(m_hstmt); int irc; @@ -1531,7 +1535,9 @@ int ODBConn::Fetch() try { // 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); } else { rc = SQLFetch(m_hstmt); @@ -1544,29 +1550,22 @@ int ODBConn::Fetch() m_hstmt, m_RowsetSize, rc); if (!Check(rc)) - ThrowDBX(rc, "Fetch", 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 + ThrowDBX(rc, "Fetching", m_hstmt); - if (m_Tdb->Memory == 1) - m_Rows += irc; + if (rc == SQL_NO_DATA_FOUND) { + m_Full = (m_Fetch == 1); + irc = 0; + } else + irc = (int)crow; + m_Fetch++; + m_Rows += irc; } catch(DBX *x) { if (trace) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; 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; } // end try/catch @@ -1602,7 +1601,7 @@ int ODBConn::PrepareSQL(char *sql) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; 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 } // endif Mode @@ -1648,7 +1647,7 @@ int ODBConn::PrepareSQL(char *sql) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; 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) SQLCancel(hstmt); @@ -1700,7 +1699,7 @@ int ODBConn::ExecuteSQL(void) } // endif ncol } 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); rc = SQLFreeStmt(m_hstmt, SQL_DROP); m_hstmt = NULL; @@ -1737,7 +1736,7 @@ bool ODBConn::BindParam(ODBCCOL *colp) ThrowDBX(rc, "SQLDescribeParam", m_hstmt); } 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(); sqlt = GetSQLType(buftype); dec = IsTypeChar(buftype) ? 0 : colp->GetScale(); @@ -1845,7 +1844,7 @@ bool ODBConn::ExecSQLcommand(char *sql) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; 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) SQLCancel(hstmt); @@ -1930,7 +1929,7 @@ PQRYRES ODBConn::GetMetaData(PGLOBAL g, char *dsn, char *src) } // endfor i } catch(DBX *x) { - strcpy(g->Message, x->GetErrorMessage(0)); + sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0)); goto err; } // end try/catch @@ -1981,7 +1980,7 @@ PQRYRES ODBConn::GetMetaData(PGLOBAL g, char *dsn, char *src) } // endfor i } catch(DBX *x) { - strcpy(g->Message, x->GetErrorMessage(0)); + sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0)); qrp = NULL; } // end try/catch @@ -2033,7 +2032,7 @@ bool ODBConn::GetDataSources(PQRYRES qrp) } // endfor i } catch(DBX *x) { - strcpy(m_G->Message, x->GetErrorMessage(0)); + sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0)); rv = true; } // end try/catch @@ -2084,7 +2083,7 @@ bool ODBConn::GetDrivers(PQRYRES qrp) } // endfor n } catch(DBX *x) { - strcpy(m_G->Message, x->GetErrorMessage(0)); + sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0)); rv = true; } // end try/catch @@ -2402,7 +2401,7 @@ int ODBConn::GetCatInfo(CATPARM *cap) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; 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; } // end try/catch @@ -2506,7 +2505,7 @@ int ODBConn::Rewind(char *sql, ODBCCOL *tocols) rbuf = (int)crow; } catch(DBX *x) { - strcpy(m_G->Message, x->GetErrorMessage(0)); + sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0)); rbuf = -1; } // end try/catch diff --git a/storage/connect/odbconn.h b/storage/connect/odbconn.h index b7c5e0c942d..41cc2439354 100644 --- a/storage/connect/odbconn.h +++ b/storage/connect/odbconn.h @@ -141,7 +141,7 @@ class ODBConn : public BLOCK { //void SetUserPwd(PSZ pwd) {m_Pwd = pwd;} int GetResultSize(char *sql, ODBCCOL *colp); int ExecDirectSQL(char *sql, ODBCCOL *tocols); - int Fetch(void); + int Fetch(int pos = 0); int PrepareSQL(char *sql); int ExecuteSQL(void); bool BindParam(ODBCCOL *colp); @@ -192,10 +192,10 @@ class ODBConn : public BLOCK { PSZ m_Pwd; int m_Catver; int m_Rows; + int m_Fetch; bool m_Updatable; bool m_Transact; bool m_Scrollable; bool m_UseCnc; - bool m_First; bool m_Full; }; // end of ODBConn class definition diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index 41a6e72a76a..ccc21960bfd 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -1291,6 +1291,51 @@ int TDBJSON::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add) } // 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. */ /***********************************************************************/ bool TDBJSON::OpenDB(PGLOBAL g) diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h index eb9d078012b..397c2cf5d3a 100644 --- a/storage/connect/tabjson.h +++ b/storage/connect/tabjson.h @@ -174,10 +174,9 @@ class TDBJSON : public TDBJSN { virtual int Cardinality(PGLOBAL g); virtual int GetMaxSize(PGLOBAL g); virtual void ResetSize(void); - virtual int GetRecpos(void) {return Fpos;} virtual int GetProgCur(void) {return N;} - virtual bool SetRecpos(PGLOBAL g, int recpos) - {Fpos = recpos - 1; return false;} + virtual int GetRecpos(void); + virtual bool SetRecpos(PGLOBAL g, int recpos); virtual bool OpenDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g); virtual bool PrepareWriting(PGLOBAL g) {return false;} diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index bf76a124b70..3bf1238cebc 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -135,9 +135,16 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) //Options = ODBConn::noOdbcDialog | ODBConn::useCursorLib; Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_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); - 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 return false; } // end of DefineAM @@ -206,7 +213,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp) Quoted = MY_MAX(0, tdp->GetQuoted()); Rows = tdp->GetElemt(); Catver = tdp->Catver; - Memory = (tdp->Memory) ? 1 : 0; + Memory = tdp->Memory; Scrollable = tdp->Scrollable; Ops.UseCnc = tdp->UseCnc; } else { @@ -238,11 +245,13 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp) DBQ = NULL; Qrp = NULL; Fpos = 0; + Curpos = 0; AftRows = 0; CurNum = 0; Rbuf = 0; BufSize = 0; Nparm = 0; + Placed = false; } // end of TDBODBC standard constructor TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp) @@ -267,15 +276,15 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp) Options = tdbp->Options; Quoted = tdbp->Quoted; Rows = tdbp->Rows; - Fpos = tdbp->Fpos; - AftRows = tdbp->AftRows; -//Tpos = tdbp->Tpos; -//Spos = tdbp->Spos; - CurNum = tdbp->CurNum; - Rbuf = tdbp->Rbuf; + Fpos = 0; + Curpos = 0; + AftRows = 0; + CurNum = 0; + Rbuf = 0; BufSize = tdbp->BufSize; Nparm = tdbp->Nparm; Qrp = tdbp->Qrp; + Placed = false; } // end of TDBODBC copy constructor // Method @@ -811,10 +820,12 @@ bool TDBODBC::OpenDB(PGLOBAL g) return true; } // endif Rewind - } // endif Memory + } else + Rbuf = Qrp->Nblin; CurNum = 0; Fpos = 0; + Curpos = 1; return false; } // endif use @@ -841,6 +852,37 @@ bool TDBODBC::OpenDB(PGLOBAL g) /* Make the command and allocate whatever is used for getting results. */ /*********************************************************************/ 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))) { for (PODBCCOL colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->GetNext()) @@ -882,10 +924,41 @@ bool TDBODBC::OpenDB(PGLOBAL g) /***********************************************************************/ int TDBODBC::GetRecpos(void) { - return Fpos; // To be really implemented + return Fpos; } // 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. */ /***********************************************************************/ int TDBODBC::ReadDB(PGLOBAL g) @@ -924,22 +997,32 @@ int TDBODBC::ReadDB(PGLOBAL g) /* Now start the reading process. */ /* Here is the place to fetch the line(s). */ /*********************************************************************/ - if (Memory != 3) { - if (++CurNum >= Rbuf) { - Rbuf = Ocp->Fetch(); - CurNum = 0; - } // endif CurNum + if (Placed) { + if (Fpos && CurNum >= 0) + Rbuf = Ocp->Fetch((Curpos = Fpos)); rc = (Rbuf > 0) ? RC_OK : (Rbuf == 0) ? RC_EF : RC_FX; - } else // Getting result from memory - rc = (Fpos < Qrp->Nblin) ? RC_OK : RC_EF; + Placed = false; + } else { + if (Memory != 3) { + if (++CurNum >= Rbuf) { + Rbuf = Ocp->Fetch(); + Curpos = Fpos + 1; + CurNum = 0; + } // endif CurNum - if (rc == RC_OK) { - if (Memory == 2) - Qrp->Nblin++; + rc = (Rbuf > 0) ? RC_OK : (Rbuf == 0) ? RC_EF : RC_FX; + } else // Getting result from memory + rc = (Fpos < Qrp->Nblin) ? RC_OK : RC_EF; - Fpos++; // Used for memory - } // endif rc + if (rc == RC_OK) { + if (Memory == 2) + Qrp->Nblin++; + + Fpos++; // Used for memory and pos + } // endif rc + + } // endif Placed if (trace > 1) htrc(" Read: Rbuf=%d rc=%d\n", Rbuf, rc); diff --git a/storage/connect/tabodbc.h b/storage/connect/tabodbc.h index eb20eb6efde..b8c9d85aae5 100644 --- a/storage/connect/tabodbc.h +++ b/storage/connect/tabodbc.h @@ -64,8 +64,8 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */ int Quoted; /* Identifier quoting level */ int Maxerr; /* Maxerr for an Exec table */ int Maxres; /* Maxres for a catalog table */ + int Memory; /* Put result set in memory */ bool Scrollable; /* Use scrollable cursor */ - bool Memory; /* Put result set in memory */ bool Xsrc; /* Execution type */ bool UseCnc; /* Use SQLConnect (!SQLDriverConnect) */ }; // end of ODBCDEF @@ -93,6 +93,7 @@ class TDBODBC : public TDBASE { // Methods virtual PTDB CopyOne(PTABS t); virtual int GetRecpos(void); + virtual bool SetRecpos(PGLOBAL g, int recpos); virtual PSZ GetFile(PGLOBAL g); virtual void SetFile(PGLOBAL g, PSZ fn); virtual void ResetSize(void); @@ -148,6 +149,7 @@ class TDBODBC : public TDBASE { int Qto; // Query timeout int Quoted; // The identifier quoting level int Fpos; // Position of last read record + int Curpos; // Cursor position of last fetch int AftRows; // The number of affected rows int Rows; // Rowset size int Catver; // Catalog ODBC version @@ -157,6 +159,7 @@ class TDBODBC : public TDBASE { int Nparm; // The number of statement parameters int Memory; // 0: No 1: Alloc 2: Put 3: Get bool Scrollable; // Use scrollable cursor + bool Placed; // True for position reading bool UseCnc; // Use SQLConnect (!SQLDriverConnect) PQRYRES Qrp; // Points to storage result }; // end of class TDBODBC diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp index c1c112633fd..c114497aa69 100644 --- a/storage/connect/tabutil.cpp +++ b/storage/connect/tabutil.cpp @@ -1,7 +1,7 @@ /************* 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. */ /***********************************************************************/ @@ -9,7 +9,8 @@ /***********************************************************************/ /* 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 "table.h" #include "field.h" @@ -108,6 +109,9 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db, } // endif is_view } else { + if (thd->is_error()) + thd->clear_error(); // Avoid stopping info commands + sprintf(g->Message, "Error %d opening share\n", s->error); free_table_share(s); return NULL; |