diff options
Diffstat (limited to 'storage')
-rw-r--r-- | storage/connect/ha_connect.cc | 1 | ||||
-rw-r--r-- | storage/connect/odbconn.cpp | 112 | ||||
-rw-r--r-- | storage/connect/odbconn.h | 5 | ||||
-rw-r--r-- | storage/connect/tabodbc.cpp | 90 | ||||
-rw-r--r-- | storage/connect/tabodbc.h | 5 |
5 files changed, 185 insertions, 28 deletions
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index ebf286a049b..1453c418025 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -5190,6 +5190,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, tm= NOT_NULL_FLAG; cnm= (char*)"noname"; dft= xtra= key= NULL; + v= ' '; #if defined(NEW_WAY) rem= ""; // cs= NULL; diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index bef735b4a6d..88b9978977a 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -146,18 +146,25 @@ int TranslateSQLType(int stp, int prec, int& len, char& v) type = TYPE_DOUBLE; break; case SQL_DATETIME: // 9 -// case SQL_DATE: // 9 + type = TYPE_DATE; + len = 19; + break; + case SQL_TYPE_DATE: // 91 type = TYPE_DATE; len = 10; + v = 'D'; break; case SQL_INTERVAL: // 10 -// case SQL_TIME: // 10 + case SQL_TYPE_TIME: // 92 type = TYPE_STRING; len = 8 + ((prec) ? (prec+1) : 0); + v = 'T'; break; case SQL_TIMESTAMP: // 11 + case SQL_TYPE_TIMESTAMP: // 93 type = TYPE_DATE; len = 19 + ((prec) ? (prec+1) : 0); + v = 'S'; break; case SQL_BIGINT: // (-5) type = TYPE_BIGINT; @@ -910,6 +917,7 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp) m_UpdateOptions = 0; m_RowsetSize = (DWORD)((tdbp) ? tdbp->Rows : 10); m_Catver = (tdbp) ? tdbp->Catver : 0; + m_Rows = 0; m_Connect = NULL; m_Updatable = true; m_Transact = false; @@ -1068,6 +1076,9 @@ int ODBConn::Open(PSZ ConnectString, DWORD options) } // endif /*ver = GetStringInfo(SQL_DRIVER_ODBC_VER);*/ + // Verify support for required functionality and cache info +// VerifyConnect(); Deprecated + GetConnectInfo(); } catch(DBX *xp) { // strcpy(g->Message, xp->m_ErrMsg[0]); strcpy(g->Message, xp->GetErrorMessage(0)); @@ -1076,9 +1087,6 @@ int ODBConn::Open(PSZ ConnectString, DWORD options) return -1; } // end try-catch - // Verify support for required functionality and cache info - VerifyConnect(); - GetConnectInfo(); return 1; } // end of Open @@ -1500,6 +1508,10 @@ int ODBConn::Fetch() ThrowDBX(rc, "Fetch", m_hstmt); irc = (rc == SQL_NO_DATA_FOUND) ? 0 : (int)crow; + + if (m_Tdb->Memory == 1) + m_Rows += irc; + } catch(DBX *x) { if (trace) for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++) @@ -2150,6 +2162,7 @@ int ODBConn::GetCatInfo(CATPARM *cap) HSTMT hstmt = NULL; SQLLEN *vl, *vlen = NULL; PVAL *pval = NULL; + char* *pbuf = NULL; try { b = false; @@ -2226,6 +2239,7 @@ int ODBConn::GetCatInfo(CATPARM *cap) // Unconditional to handle STRBLK's pval = (PVAL *)PlugSubAlloc(g, NULL, n * sizeof(PVAL)); vlen = (SQLLEN *)PlugSubAlloc(g, NULL, n * sizeof(SQLLEN)); + pbuf = (char**)PlugSubAlloc(g, NULL, n * sizeof(char*)); // Now bind the column buffers for (n = 0, crp = qrp->Colresp; crp; crp = crp->Next) { @@ -2240,7 +2254,13 @@ int ODBConn::GetCatInfo(CATPARM *cap) } // endif len pval[n] = AllocateValue(g, crp->Type, len); - buffer = pval[n]->GetTo_Val(); + + if (crp->Type == TYPE_STRING) { + pbuf[n] = (char*)PlugSubAlloc(g, NULL, len); + buffer = pbuf[n]; + } else + buffer = pval[n]->GetTo_Val(); + vl = vlen + n; // n + 1 because column numbers begin with 1 @@ -2288,7 +2308,13 @@ int ODBConn::GetCatInfo(CATPARM *cap) } // endif rc for (n = 0, crp = qrp->Colresp; crp; n++, crp = crp->Next) { - pval[n]->SetNull(vlen[n] == SQL_NULL_DATA); + if (vlen[n] == SQL_NULL_DATA) + pval[n]->SetNull(true); + else if (crp->Type == TYPE_STRING && vlen[n] != SQL_NULL_DATA) + pval[n]->SetValue_char(pbuf[n], vlen[n]); + else + pval[n]->SetNull(false); + crp->Kdata->SetValue(pval[n], i); cap->Vlen[n][i] = vlen[n]; } // endfor crp @@ -2343,6 +2369,76 @@ int ODBConn::GetCatInfo(CATPARM *cap) } // end of GetCatInfo /***********************************************************************/ +/* Allocate a CONNECT result structure from the ODBC result. */ +/***********************************************************************/ +PQRYRES ODBConn::AllocateResult(PGLOBAL g) + { +//char *fmt, v; + int n; + bool uns; + PODBCCOL colp; + PCOLRES *pcrp, crp; + PQRYRES qrp; + + if (!m_Rows) { + strcpy(g->Message, "Void result"); + return NULL; + } // endif m_Res + + /*********************************************************************/ + /* Allocate the result storage for future retrieval. */ + /*********************************************************************/ + qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES)); + pcrp = &qrp->Colresp; + qrp->Continued = FALSE; + qrp->Truncated = FALSE; + qrp->Info = FALSE; + qrp->Suball = TRUE; + qrp->BadLines = 0; + qrp->Maxsize = m_Rows; + qrp->Maxres = m_Rows; + qrp->Nbcol = 0; + qrp->Nblin = 0; + qrp->Cursor = 0; + + for (n = 1, colp = (PODBCCOL)m_Tdb->Columns; colp; + colp = (PODBCCOL)colp->GetNext()) + if (!colp->IsSpecial()) { + *pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES)); + crp = *pcrp; + pcrp = &crp->Next; + memset(crp, 0, sizeof(COLRES)); + crp->Ncol = ++qrp->Nbcol; + crp->Name = colp->GetName(); + crp->Type = colp->GetResultType(); + crp->Prec = colp->GetScale(); + crp->Length = colp->GetLength(); + crp->Clen = colp->GetBuflen(); + uns = colp->IsUnsigned(); + + if (!(crp->Kdata = AllocValBlock(g, NULL, crp->Type, m_Rows, + crp->Clen, 0, FALSE, TRUE, uns))) { + sprintf(g->Message, MSG(INV_RESULT_TYPE), + GetFormatType(crp->Type)); + return NULL; + } // endif Kdata + + if (!colp->IsNullable()) + crp->Nulls = NULL; + else { + crp->Nulls = (char*)PlugSubAlloc(g, NULL, m_Rows); + memset(crp->Nulls, ' ', m_Rows); + } // endelse Nullable + + colp->SetCrp(crp); + } // endif colp + + *pcrp = NULL; +//qrp->Nblin = n; + return qrp; + } // end of AllocateResult + +/***********************************************************************/ /* Restart from beginning of result set */ /***********************************************************************/ bool ODBConn::Rewind(char *sql, ODBCCOL *tocols) @@ -2382,7 +2478,7 @@ void ODBConn::Close() rc = SQLFreeStmt(m_hstmt, SQL_DROP); m_hstmt = NULL; } // endif m_hstmt - + if (m_hdbc != SQL_NULL_HDBC) { if (m_Transact) { rc = SQLEndTran(SQL_HANDLE_DBC, m_hdbc, SQL_COMMIT); diff --git a/storage/connect/odbconn.h b/storage/connect/odbconn.h index 1dd2aa2c16e..13d58488b39 100644 --- a/storage/connect/odbconn.h +++ b/storage/connect/odbconn.h @@ -126,6 +126,7 @@ class ODBConn : public BLOCK { int Open(PSZ ConnectString, DWORD Options = 0); bool Rewind(char *sql, ODBCCOL *tocols); void Close(void); + PQRYRES AllocateResult(PGLOBAL g); // Attributes public: @@ -187,9 +188,11 @@ class ODBConn : public BLOCK { DWORD m_UpdateOptions; DWORD m_RowsetSize; char m_IDQuoteChar[2]; - int m_Catver; PSZ m_Connect; + int m_Catver; + int m_Rows; bool m_Updatable; bool m_Transact; bool m_Scrollable; + bool m_Memory; }; // end of ODBConn class definition diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index bbc17129aaf..cb21f33c1b1 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -134,6 +134,7 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) if ((Scrollable = GetBoolCatInfo("Scrollable", false))) Elemt = 0; // Not compatible with extended fetch + Memory = GetBoolCatInfo("Memory", false); Pseudo = 2; // FILID is Ok but not ROWID return false; } // end of DefineAM @@ -198,6 +199,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp) Quoted = MY_MAX(0, tdp->GetQuoted()); Rows = tdp->GetElemt(); Catver = tdp->Catver; + Memory = (tdp->Memory) ? 1 : 0; Scrollable = tdp->Scrollable; } else { Connect = NULL; @@ -211,6 +213,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp) Quoted = 0; Rows = 0; Catver = 0; + Memory = 0; Scrollable = false; } // endif tdp @@ -220,6 +223,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp) //Where = NULL; MulConn = NULL; DBQ = NULL; + Qrp = NULL; Fpos = 0; AftRows = 0; CurNum = 0; @@ -238,6 +242,7 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp) Catalog = tdbp->Catalog; Srcdef = tdbp->Srcdef; Qrystr = tdbp->Qrystr; + Memory = tdbp->Memory; Scrollable = tdbp->Scrollable; Quote = tdbp->Quote; Query = tdbp->Query; @@ -256,6 +261,7 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp) Rbuf = tdbp->Rbuf; BufSize = tdbp->BufSize; Nparm = tdbp->Nparm; + Qrp = tdbp->Qrp; } // end of TDBODBC copy constructor // Method @@ -758,17 +764,23 @@ bool TDBODBC::OpenDB(PGLOBAL g) /*******************************************************************/ /* Table already open, just replace it at its beginning. */ /*******************************************************************/ -// if (To_Kindex) - /*****************************************************************/ - /* Table is to be accessed through a sorted index table. */ - /*****************************************************************/ -// To_Kindex->Reset(); - -// rewind(Stream); >>>>>>> Something to be done with Cursor <<<<<<< - if (Ocp->Rewind(Query, (PODBCCOL)Columns)) { - Ocp->Close(); - return true; - } // endif Rewind + if (Memory == 1) { + if ((Qrp = Ocp->AllocateResult(g))) + Memory = 2; // Must be filled + else + Memory = 0; // Allocation failed, don't use it + + } else if (Memory == 2) + Memory = 3; // Ok to use memory result + + if (Memory < 3) { + // Method will depend on cursor type + if (Ocp->Rewind(Query, (PODBCCOL)Columns)) { + Ocp->Close(); + return true; + } // endif Rewind + + } // endif Memory Fpos = 0; return false; @@ -877,13 +889,22 @@ int TDBODBC::ReadDB(PGLOBAL g) /* Now start the reading process. */ /* Here is the place to fetch the line(s). */ /*********************************************************************/ - if (++CurNum >= Rbuf) { - Rbuf = Ocp->Fetch(); - CurNum = 0; - } // endif CurNum + if (Memory != 3) { + if (++CurNum >= Rbuf) { + Rbuf = Ocp->Fetch(); + CurNum = 0; + } // endif CurNum + + rc = (Rbuf > 0) ? RC_OK : (Rbuf == 0) ? RC_EF : RC_FX; + } else // Getting result from memory + rc = (Fpos < Qrp->Nblin) ? RC_OK : RC_EF; - rc = (Rbuf > 0) ? RC_OK : (Rbuf == 0) ? RC_EF : RC_FX; - Fpos++; // Used for progress info + if (rc == RC_OK) { + if (Memory == 2) + Qrp->Nblin++; + + Fpos++; // Used for memory + } // endif rc if (trace > 1) htrc(" Read: Rbuf=%d rc=%d\n", Rbuf, rc); @@ -966,6 +987,7 @@ ODBCCOL::ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) } // endif cprec // Set additional ODBC access method information for column. + Crp = NULL; //Long = cdp->GetLong(); Long = Precision; //strcpy(F_Date, cdp->F_Date); @@ -987,6 +1009,7 @@ ODBCCOL::ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) /***********************************************************************/ ODBCCOL::ODBCCOL(void) : COLBLK() { + Crp = NULL; Buf_Type = TYPE_INT; // This is a count(*) column // Set additional Dos access method information for column. Long = sizeof(int); @@ -1005,6 +1028,7 @@ ODBCCOL::ODBCCOL(void) : COLBLK() /***********************************************************************/ ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp) { + Crp = col1->Crp; Long = col1->Long; //strcpy(F_Date, col1->F_Date); To_Val = col1->To_Val; @@ -1070,7 +1094,20 @@ bool ODBCCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check) void ODBCCOL::ReadColumn(PGLOBAL g) { PTDBODBC tdbp = (PTDBODBC)To_Tdb; - int n = tdbp->CurNum; + int i = tdbp->Fpos - 1, n = tdbp->CurNum; + + if (tdbp->Memory == 3) { + // Get the value from the stored memory + if (Crp->Nulls && Crp->Nulls[i] == '*') { + Value->Reset(); + Value->SetNull(true); + } else { + Value->SetValue_pvblk(Crp->Kdata, i); + Value->SetNull(false); + } // endif Nulls + + return; + } // endif Memory if (StrLen[n] == SQL_NULL_DATA) { // Null value @@ -1078,7 +1115,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g) Value->SetNull(true); Value->Reset(); - return; + goto put; } else Value->SetNull(false); @@ -1117,6 +1154,21 @@ void ODBCCOL::ReadColumn(PGLOBAL g) Name, tdbp->Rows, Bufp, Buf_Type, Value->GetCharString(buf)); } // endif Trace +put: + if (tdbp->Memory != 2) + return; + + /*********************************************************************/ + /* Fill the allocated result structure. */ + /*********************************************************************/ + if (Value->IsNull()) { + if (Crp->Nulls) + Crp->Nulls[i] = '*'; // Null value + + Crp->Kdata->Reset(i); + } else + Crp->Kdata->SetValue(Value, i); + } // end of ReadColumn /***********************************************************************/ diff --git a/storage/connect/tabodbc.h b/storage/connect/tabodbc.h index f042b0c73ca..da9d373add8 100644 --- a/storage/connect/tabodbc.h +++ b/storage/connect/tabodbc.h @@ -60,6 +60,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */ int Maxerr; /* Maxerr for an Exec table */ int Maxres; /* Maxres for a catalog table */ bool Scrollable; /* Use scrollable cursor */ + bool Memory; /* Put result set in memory */ bool Xsrc; /* Execution type */ }; // end of ODBCDEF @@ -143,7 +144,9 @@ class TDBODBC : public TDBASE { int Rbuf; // Number of lines read in buffer int BufSize; // Size of connect string buffer int Nparm; // The number of statement parameters + int Memory; // 0: No 1: Alloc 2: Put 3: Get bool Scrollable; // Use scrollable cursor + PQRYRES Qrp; // Points to storage result }; // end of class TDBODBC /***********************************************************************/ @@ -162,6 +165,7 @@ class ODBCCOL : public COLBLK { SQLLEN *GetStrLen(void) {return StrLen;} int GetRank(void) {return Rank;} // PVBLK GetBlkp(void) {return Blkp;} + void SetCrp(PCOLRES crp) {Crp = crp;} // Methods virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); @@ -178,6 +182,7 @@ class ODBCCOL : public COLBLK { // Members TIMESTAMP_STRUCT *Sqlbuf; // To get SQL_TIMESTAMP's + PCOLRES Crp; // To storage result void *Bufp; // To extended buffer PVBLK Blkp; // To Value Block //char F_Date[12]; // Internal Date format |