Skip to content

Commit d862d7c

Browse files
committed
- 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
1 parent aa107ef commit d862d7c

File tree

9 files changed

+209
-74
lines changed

9 files changed

+209
-74
lines changed

storage/connect/ha_connect.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5462,7 +5462,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
54625462
case TYPE_DOUBLE:
54635463
// Some data sources do not count dec in length (prec)
54645464
prec += (dec + 2); // To be safe
5465+
break;
54655466
case TYPE_DECIM:
5467+
prec= len;
54665468
break;
54675469
default:
54685470
dec= 0;

storage/connect/mysql-test/connect/r/odbc_oracle.result

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ TABNAME='T1';
126126
SHOW CREATE TABLE t1;
127127
Table Create Table
128128
t1 CREATE TABLE `t1` (
129-
`A` decimal(38,0) DEFAULT NULL,
129+
`A` decimal(40,0) DEFAULT NULL,
130130
`B` double(40,0) DEFAULT NULL
131131
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='T1'
132132
SELECT * FROM t1 ORDER BY A;
@@ -138,7 +138,7 @@ CREATE TABLE t2 AS SELECT * FROM t1;
138138
SHOW CREATE TABLE t2;
139139
Table Create Table
140140
t2 CREATE TABLE `t2` (
141-
`A` decimal(38,0) DEFAULT NULL,
141+
`A` decimal(40,0) DEFAULT NULL,
142142
`B` double(40,0) DEFAULT NULL
143143
) ENGINE=MyISAM DEFAULT CHARSET=latin1
144144
SELECT * FROM t2;
@@ -162,7 +162,7 @@ TABNAME='MTR.T1';
162162
SHOW CREATE TABLE t1;
163163
Table Create Table
164164
t1 CREATE TABLE `t1` (
165-
`A` decimal(38,0) DEFAULT NULL,
165+
`A` decimal(40,0) DEFAULT NULL,
166166
`B` double(40,0) DEFAULT NULL
167167
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T1'
168168
SELECT * FROM t1;
@@ -178,7 +178,7 @@ TABNAME='MTR.V1';
178178
SHOW CREATE TABLE t1;
179179
Table Create Table
180180
t1 CREATE TABLE `t1` (
181-
`A` decimal(38,0) DEFAULT NULL,
181+
`A` decimal(40,0) DEFAULT NULL,
182182
`B` double(40,0) DEFAULT NULL
183183
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.V1'
184184
SELECT * FROM t1;
@@ -190,7 +190,7 @@ CREATE TABLE t2 AS SELECT * FROM t1;
190190
SHOW CREATE TABLE t2;
191191
Table Create Table
192192
t2 CREATE TABLE `t2` (
193-
`A` decimal(38,0) DEFAULT NULL,
193+
`A` decimal(40,0) DEFAULT NULL,
194194
`B` double(40,0) DEFAULT NULL
195195
) ENGINE=MyISAM DEFAULT CHARSET=latin1
196196
SELECT * FROM t2;

storage/connect/odbconn.cpp

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,12 @@ static int GetSQLCType(int type)
102102
case TYPE_BIGINT: tp = SQL_C_SBIGINT; break;
103103
case TYPE_DOUBLE: tp = SQL_C_DOUBLE; break;
104104
case TYPE_TINY : tp = SQL_C_TINYINT; break;
105+
//#if (ODBCVER >= 0x0300)
106+
// case TYPE_DECIM: tp = SQL_C_NUMERIC; break; (CRASH!!!)
107+
//#else
105108
case TYPE_DECIM: tp = SQL_C_CHAR; break;
109+
//#endif
110+
106111
} // endswitch type
107112

108113
return tp;
@@ -923,13 +928,13 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp)
923928
m_RowsetSize = (DWORD)((tdbp) ? tdbp->Rows : 10);
924929
m_Catver = (tdbp) ? tdbp->Catver : 0;
925930
m_Rows = 0;
931+
m_Fetch = 0;
926932
m_Connect = NULL;
927933
m_User = NULL;
928934
m_Pwd = NULL;
929935
m_Updatable = true;
930936
m_Transact = false;
931937
m_Scrollable = (tdbp) ? tdbp->Scrollable : false;
932-
m_First = true;
933938
m_Full = false;
934939
m_UseCnc = false;
935940
m_IDQuoteChar[0] = '"';
@@ -984,7 +989,7 @@ void ODBConn::ThrowDBX(RETCODE rc, PSZ msg, HSTMT hstmt)
984989

985990
void ODBConn::ThrowDBX(PSZ msg)
986991
{
987-
DBX* xp = new(m_G) DBX(0, msg);
992+
DBX* xp = new(m_G) DBX(0, "Error");
988993

989994
xp->m_ErrMsg[0] = msg;
990995
throw xp;
@@ -1099,8 +1104,7 @@ int ODBConn::Open(PSZ ConnectString, POPARM sop, DWORD options)
10991104
// VerifyConnect(); Deprecated
11001105
GetConnectInfo();
11011106
} catch(DBX *xp) {
1102-
// strcpy(g->Message, xp->m_ErrMsg[0]);
1103-
strcpy(g->Message, xp->GetErrorMessage(0));
1107+
sprintf(g->Message, "%s: %s", xp->m_Msg, xp->GetErrorMessage(0));
11041108
Close();
11051109
// Free();
11061110
return -1;
@@ -1356,7 +1360,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
13561360
rc = SQLFreeStmt(m_hstmt, SQL_CLOSE);
13571361

13581362
if (!Check(rc))
1359-
ThrowDBX(rc, "SQLFreeStmt");
1363+
ThrowDBX(rc, "SQLFreeStmt", m_hstmt);
13601364

13611365
m_hstmt = NULL;
13621366
} // endif m_hstmt
@@ -1371,7 +1375,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
13711375
(void*)SQL_SCROLLABLE, 0);
13721376

13731377
if (!Check(rc))
1374-
ThrowDBX(rc, "SQLSetStmtAttr");
1378+
ThrowDBX(rc, "Scrollable", hstmt);
13751379

13761380
} // endif m_Scrollable
13771381

@@ -1422,7 +1426,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
14221426

14231427
for (n = 0, colp = tocols; colp; colp = (PODBCCOL)colp->GetNext())
14241428
if (!colp->IsSpecial())
1425-
n++;
1429+
n++;
14261430

14271431
// n can be 0 for query such as Select count(*) from table
14281432
if (n && n != (UWORD)ncol)
@@ -1458,7 +1462,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
14581462
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
14591463
htrc(x->m_ErrMsg[i]);
14601464

1461-
strcpy(m_G->Message, x->GetErrorMessage(0));
1465+
sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
14621466

14631467
if (b)
14641468
SQLCancel(hstmt);
@@ -1521,7 +1525,7 @@ int ODBConn::GetResultSize(char *sql, ODBCCOL *colp)
15211525
/***********************************************************************/
15221526
/* Fetch next row. */
15231527
/***********************************************************************/
1524-
int ODBConn::Fetch()
1528+
int ODBConn::Fetch(int pos)
15251529
{
15261530
ASSERT(m_hstmt);
15271531
int irc;
@@ -1531,7 +1535,9 @@ int ODBConn::Fetch()
15311535

15321536
try {
15331537
// do {
1534-
if (m_RowsetSize) {
1538+
if (pos) {
1539+
rc = SQLExtendedFetch(m_hstmt, SQL_FETCH_ABSOLUTE, pos, &crow, NULL);
1540+
} else if (m_RowsetSize) {
15351541
rc = SQLExtendedFetch(m_hstmt, SQL_FETCH_NEXT, 1, &crow, NULL);
15361542
} else {
15371543
rc = SQLFetch(m_hstmt);
@@ -1544,29 +1550,22 @@ int ODBConn::Fetch()
15441550
m_hstmt, m_RowsetSize, rc);
15451551

15461552
if (!Check(rc))
1547-
ThrowDBX(rc, "Fetch", m_hstmt);
1548-
1549-
irc = (rc == SQL_NO_DATA_FOUND) ? 0 : (int)crow;
1550-
1551-
if (m_First) {
1552-
// First fetch. Check whether the full table was read
1553-
if ((m_Full = irc < (signed)m_RowsetSize)) {
1554-
m_Tdb->Memory = 0; // Not needed anymore
1555-
m_Rows = irc; // Table size
1556-
} // endif m_Full
1557-
1558-
m_First = false;
1559-
} // endif m_First
1553+
ThrowDBX(rc, "Fetching", m_hstmt);
15601554

1561-
if (m_Tdb->Memory == 1)
1562-
m_Rows += irc;
1555+
if (rc == SQL_NO_DATA_FOUND) {
1556+
m_Full = (m_Fetch == 1);
1557+
irc = 0;
1558+
} else
1559+
irc = (int)crow;
15631560

1561+
m_Fetch++;
1562+
m_Rows += irc;
15641563
} catch(DBX *x) {
15651564
if (trace)
15661565
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
15671566
htrc(x->m_ErrMsg[i]);
15681567

1569-
strcpy(g->Message, x->GetErrorMessage(0));
1568+
sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
15701569
irc = -1;
15711570
} // end try/catch
15721571

@@ -1602,7 +1601,7 @@ int ODBConn::PrepareSQL(char *sql)
16021601
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
16031602
htrc(x->m_ErrMsg[i]);
16041603

1605-
strcpy(g->Message, x->GetErrorMessage(0));
1604+
sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
16061605
} // end try/catch
16071606

16081607
} // endif Mode
@@ -1648,7 +1647,7 @@ int ODBConn::PrepareSQL(char *sql)
16481647
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
16491648
htrc(x->m_ErrMsg[i]);
16501649

1651-
strcpy(g->Message, x->GetErrorMessage(0));
1650+
sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
16521651

16531652
if (b)
16541653
SQLCancel(hstmt);
@@ -1700,7 +1699,7 @@ int ODBConn::ExecuteSQL(void)
17001699
} // endif ncol
17011700

17021701
} catch(DBX *x) {
1703-
strcpy(m_G->Message, x->GetErrorMessage(0));
1702+
sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
17041703
SQLCancel(m_hstmt);
17051704
rc = SQLFreeStmt(m_hstmt, SQL_DROP);
17061705
m_hstmt = NULL;
@@ -1737,7 +1736,7 @@ bool ODBConn::BindParam(ODBCCOL *colp)
17371736
ThrowDBX(rc, "SQLDescribeParam", m_hstmt);
17381737

17391738
} catch(DBX *x) {
1740-
strcpy(m_G->Message, x->GetErrorMessage(0));
1739+
sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
17411740
colsize = colp->GetPrecision();
17421741
sqlt = GetSQLType(buftype);
17431742
dec = IsTypeChar(buftype) ? 0 : colp->GetScale();
@@ -1845,7 +1844,7 @@ bool ODBConn::ExecSQLcommand(char *sql)
18451844
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
18461845
htrc(x->m_ErrMsg[i]);
18471846

1848-
sprintf(g->Message, "Remote: %s", x->GetErrorMessage(0));
1847+
sprintf(g->Message, "Remote %s: %s", x->m_Msg, x->GetErrorMessage(0));
18491848

18501849
if (b)
18511850
SQLCancel(hstmt);
@@ -1930,7 +1929,7 @@ PQRYRES ODBConn::GetMetaData(PGLOBAL g, char *dsn, char *src)
19301929
} // endfor i
19311930

19321931
} catch(DBX *x) {
1933-
strcpy(g->Message, x->GetErrorMessage(0));
1932+
sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
19341933
goto err;
19351934
} // end try/catch
19361935

@@ -1981,7 +1980,7 @@ PQRYRES ODBConn::GetMetaData(PGLOBAL g, char *dsn, char *src)
19811980
} // endfor i
19821981

19831982
} catch(DBX *x) {
1984-
strcpy(g->Message, x->GetErrorMessage(0));
1983+
sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
19851984
qrp = NULL;
19861985
} // end try/catch
19871986

@@ -2033,7 +2032,7 @@ bool ODBConn::GetDataSources(PQRYRES qrp)
20332032
} // endfor i
20342033

20352034
} catch(DBX *x) {
2036-
strcpy(m_G->Message, x->GetErrorMessage(0));
2035+
sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
20372036
rv = true;
20382037
} // end try/catch
20392038

@@ -2084,7 +2083,7 @@ bool ODBConn::GetDrivers(PQRYRES qrp)
20842083
} // endfor n
20852084

20862085
} catch(DBX *x) {
2087-
strcpy(m_G->Message, x->GetErrorMessage(0));
2086+
sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
20882087
rv = true;
20892088
} // end try/catch
20902089

@@ -2402,7 +2401,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
24022401
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
24032402
htrc(x->m_ErrMsg[i]);
24042403

2405-
strcpy(g->Message, x->GetErrorMessage(0));
2404+
sprintf(g->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
24062405
irc = -1;
24072406
} // end try/catch
24082407

@@ -2506,7 +2505,7 @@ int ODBConn::Rewind(char *sql, ODBCCOL *tocols)
25062505

25072506
rbuf = (int)crow;
25082507
} catch(DBX *x) {
2509-
strcpy(m_G->Message, x->GetErrorMessage(0));
2508+
sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
25102509
rbuf = -1;
25112510
} // end try/catch
25122511

storage/connect/odbconn.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ class ODBConn : public BLOCK {
141141
//void SetUserPwd(PSZ pwd) {m_Pwd = pwd;}
142142
int GetResultSize(char *sql, ODBCCOL *colp);
143143
int ExecDirectSQL(char *sql, ODBCCOL *tocols);
144-
int Fetch(void);
144+
int Fetch(int pos = 0);
145145
int PrepareSQL(char *sql);
146146
int ExecuteSQL(void);
147147
bool BindParam(ODBCCOL *colp);
@@ -192,10 +192,10 @@ class ODBConn : public BLOCK {
192192
PSZ m_Pwd;
193193
int m_Catver;
194194
int m_Rows;
195+
int m_Fetch;
195196
bool m_Updatable;
196197
bool m_Transact;
197198
bool m_Scrollable;
198199
bool m_UseCnc;
199-
bool m_First;
200200
bool m_Full;
201201
}; // end of ODBConn class definition

storage/connect/tabjson.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,51 @@ int TDBJSON::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
12901290

12911291
} // end of MakeIndex
12921292

1293+
/***********************************************************************/
1294+
/* Return the position in the table. */
1295+
/***********************************************************************/
1296+
int TDBJSON::GetRecpos(void)
1297+
{
1298+
#if 0
1299+
union {
1300+
uint Rpos;
1301+
BYTE Spos[4];
1302+
};
1303+
1304+
Rpos = htonl(Fpos);
1305+
Spos[0] = (BYTE)NextSame;
1306+
return Rpos;
1307+
#endif // 0
1308+
return Fpos;
1309+
} // end of GetRecpos
1310+
1311+
/***********************************************************************/
1312+
/* Set the position in the table. */
1313+
/***********************************************************************/
1314+
bool TDBJSON::SetRecpos(PGLOBAL g, int recpos)
1315+
{
1316+
#if 0
1317+
union {
1318+
uint Rpos;
1319+
BYTE Spos[4];
1320+
};
1321+
1322+
Rpos = recpos;
1323+
NextSame = Spos[0];
1324+
Spos[0] = 0;
1325+
Fpos = (signed)ntohl(Rpos);
1326+
1327+
//if (Fpos != (signed)ntohl(Rpos)) {
1328+
// Fpos = ntohl(Rpos);
1329+
// same = false;
1330+
//} else
1331+
// same = true;
1332+
#endif // 0
1333+
1334+
Fpos = recpos - 1;
1335+
return false;
1336+
} // end of SetRecpos
1337+
12931338
/***********************************************************************/
12941339
/* JSON Access Method opening routine. */
12951340
/***********************************************************************/

storage/connect/tabjson.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,9 @@ class TDBJSON : public TDBJSN {
174174
virtual int Cardinality(PGLOBAL g);
175175
virtual int GetMaxSize(PGLOBAL g);
176176
virtual void ResetSize(void);
177-
virtual int GetRecpos(void) {return Fpos;}
178177
virtual int GetProgCur(void) {return N;}
179-
virtual bool SetRecpos(PGLOBAL g, int recpos)
180-
{Fpos = recpos - 1; return false;}
178+
virtual int GetRecpos(void);
179+
virtual bool SetRecpos(PGLOBAL g, int recpos);
181180
virtual bool OpenDB(PGLOBAL g);
182181
virtual int ReadDB(PGLOBAL g);
183182
virtual bool PrepareWriting(PGLOBAL g) {return false;}

0 commit comments

Comments
 (0)