Commit 229dad1f authored by Sergei Golubchik's avatar Sergei Golubchik

merge with 10.0-connect

parents 60dd52e3 3743e1e0
......@@ -442,7 +442,7 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
for (PCOL colp= tdbp->GetColumns(); colp; colp= colp->GetNext())
colp->SetKcol(NULL);
((PTDBASE)tdbp)->SetKindex(NULL);
((PTDBASE)tdbp)->ResetKindex(g, NULL);
} // endif index
// Save stack and allocation environment and prepare error return
......@@ -585,7 +585,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
// Make all the eventual indexes
tbxp= (TDBDOX*)tdbp;
tbxp->SetKindex(NULL);
tbxp->ResetKindex(g, NULL);
tbxp->To_Key_Col= NULL;
rc= tbxp->ResetTableOpt(g, ((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
......
......@@ -416,18 +416,24 @@ PXLIST DOMNODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp)
/******************************************************************/
PXNODE DOMNODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np)
{
MSXML2::IXMLDOMNodePtr dnp = Nodep->selectSingleNode(xp);
try {
MSXML2::IXMLDOMNodePtr dnp = Nodep->selectSingleNode(xp);
if (dnp) {
if (np) {
((PDOMNODE)np)->Nodep = dnp;
return np;
} else
return new(g) DOMNODE(Doc, dnp);
if (dnp) {
if (np) {
((PDOMNODE)np)->Nodep = dnp;
return np;
} else
return new(g) DOMNODE(Doc, dnp);
} else
return NULL;
} // endif dnp
} catch(_com_error e) {
sprintf(g->Message, "%s: %s", MSG(COM_ERROR),
_com_util::ConvertBSTRToString(e.Description()));
} catch(...) {}
return NULL;
} // end of SelectSingleNode
/******************************************************************/
......
This diff is collapsed.
......@@ -167,7 +167,7 @@ class ha_connect: public handler
static bool connect_end(void);
TABTYPE GetRealType(PTOS pos= NULL);
char *GetStringOption(char *opname, char *sdef= NULL);
PTOS GetTableOptionStruct(TABLE *table_arg);
PTOS GetTableOptionStruct(TABLE_SHARE *s= NULL);
bool GetBooleanOption(char *opname, bool bdef);
bool SetBooleanOption(char *opname, bool b);
int GetIntegerOption(char *opname);
......@@ -210,7 +210,7 @@ class ha_connect: public handler
The name of the index type that will be used for display.
Don't implement this method unless you really have indexes.
*/
const char *index_type(uint inx) { return "XPLUG"; }
const char *index_type(uint inx);
/** @brief
The file extensions.
......@@ -241,11 +241,7 @@ class ha_connect: public handler
If all_parts is set, MySQL wants to know the flags for the combined
index, up to and including 'part'.
*/
ulong index_flags(uint inx, uint part, bool all_parts) const
{
return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER |
HA_READ_PREV | HA_KEYREAD_ONLY | HA_KEY_SCAN_NOT_ROR;
} // end of index_flags
ulong index_flags(uint inx, uint part, bool all_parts) const;
/** @brief
unireg.cc will call max_supported_record_length(), max_supported_keys(),
......
......@@ -80,7 +80,16 @@ HANDLE CreateFileMap(PGLOBAL g, LPCSTR filename,
} // endif hFileMap
access = (mode == MODE_READ) ? FILE_MAP_READ : FILE_MAP_WRITE;
mm->memory = MapViewOfFile(hFileMap, access, 0, 0, 0);
if (!(mm->memory = MapViewOfFile(hFileMap, access, 0, 0, 0))) {
DWORD ler = GetLastError();
sprintf(g->Message, "Error %ld in MapViewOfFile %s",
ler, filename);
CloseHandle(hFile);
return INVALID_HANDLE_VALUE;
} // endif memory
// lenH is the high-order word of the file size
mm->lenL = GetFileSize(hFile, &mm->lenH);
CloseHandle(hFileMap); // Not used anymore
......
......@@ -31,6 +31,10 @@
/* */
/************************************************************************/
#include "my_global.h"
#if !defined(MYSQL_PREPARED_STATEMENTS)
#include "my_sys.h"
#include "mysqld_error.h"
#endif // !MYSQL_PREPARED_STATEMENTS
#if defined(WIN32)
//#include <windows.h>
#else // !WIN32
......@@ -59,6 +63,59 @@ uint GetDefaultPort(void)
return mysqld_port;
} // end of GetDefaultPort
#if !defined(MYSQL_PREPARED_STATEMENTS)
/**************************************************************************
Alloc struct for use with unbuffered reads. Data is fetched by domand
when calling to mysql_fetch_row.
mysql_data_seek is a noop.
No other queries may be specified with the same MYSQL handle.
There shouldn't be much processing per row because mysql server shouldn't
have to wait for the client (and will not wait more than 30 sec/packet).
NOTE: copied from client.c cli_use_result
**************************************************************************/
static MYSQL_RES *connect_use_result(MYSQL *mysql)
{
MYSQL_RES *result;
DBUG_ENTER("connect_use_result");
if (!mysql->fields)
DBUG_RETURN(NULL);
if (mysql->status != MYSQL_STATUS_GET_RESULT) {
my_message(ER_UNKNOWN_ERROR, "Command out of sync", MYF(0));
DBUG_RETURN(NULL);
} // endif status
if (!(result = (MYSQL_RES*) my_malloc(sizeof(*result) +
sizeof(ulong) * mysql->field_count,
MYF(MY_WME | MY_ZEROFILL))))
DBUG_RETURN(NULL);
result->lengths = (ulong*)(result+1);
result->methods = mysql->methods;
/* Ptrs: to one row */
if (!(result->row = (MYSQL_ROW)my_malloc(sizeof(result->row[0]) *
(mysql->field_count+1), MYF(MY_WME)))) {
my_free(result);
DBUG_RETURN(NULL);
} // endif row
result->fields = mysql->fields;
result->field_alloc = mysql->field_alloc;
result->field_count = mysql->field_count;
result->current_field = 0;
result->handle = mysql;
result->current_row = 0;
mysql->fields = 0; /* fields is now in result */
clear_alloc_root(&mysql->field_alloc);
mysql->status = MYSQL_STATUS_USE_RESULT;
mysql->unbuffered_fetch_owner = &result->unbuffered_fetch_cancelled;
DBUG_RETURN(result); /* Data is ready to be fetched */
} // end of connect_use_result
#endif // !MYSQL_PREPARED_STATEMENTS
/************************************************************************/
/* MyColumns: constructs the result blocks containing all columns */
/* of a MySQL table or view. */
......@@ -339,6 +396,7 @@ MYSQLC::MYSQLC(void)
m_Row = NULL;
m_Fields = -1;
N = 0;
m_Use = false;
} // end of MYSQLC constructor
/***********************************************************************/
......@@ -600,7 +658,16 @@ int MYSQLC::ExecSQL(PGLOBAL g, const char *query, int *w)
rc = RC_FX;
//} else if (mysql_field_count(m_DB) > 0) {
} else if (m_DB->field_count > 0) {
if (!(m_Res = mysql_store_result(m_DB))) {
if (m_Use)
#if defined(MYSQL_PREPARED_STATEMENTS)
m_Res = mysql_use_result(m_DB);
#else // !MYSQL_PREPARED_STATEMENTS)
m_Res = connect_use_result(m_DB);
#endif // !MYSQL_PREPARED_STATEMENTS
else
m_Res = mysql_store_result(m_DB);
if (!m_Res) {
char *msg = (char*)PlugSubAlloc(g, NULL, 512 + strlen(query));
sprintf(msg, "mysql_store_result failed: %s", mysql_error(m_DB));
......@@ -609,7 +676,7 @@ int MYSQLC::ExecSQL(PGLOBAL g, const char *query, int *w)
rc = RC_FX;
} else {
m_Fields = mysql_num_fields(m_Res);
m_Rows = (int)mysql_num_rows(m_Res);
m_Rows = (!m_Use) ? (int)mysql_num_rows(m_Res) : 0;
} // endif m_Res
} else {
......
......@@ -96,5 +96,6 @@ class DllItem MYSQLC {
int N;
int m_Fields; // The number of result fields
int m_Afrw; // The number of affected rows
bool m_Use; // Use or store result set
}; // end of class MYSQLC
Warnings:
Warning 1105 No file name. Table will use t1.xml
SET NAMES utf8;
#
# Testing expanded values
#
CREATE TABLE `bookstore` (
`category` CHAR(16) NOT NULL FIELD_FORMAT='@',
`title` VARCHAR(50) NOT NULL,
`lang` char(2) NOT NULL FIELD_FORMAT='title/@',
`author` VARCHAR(24) NOT NULL,
`year` INT(4) NOT NULL,
`price` DOUBLE(8,2) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='bookstore.xml' OPTION_LIST='expand=1,mulnode=author,limit=6,xmlsup=libxml2';
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
CHILDREN Harry Potter en J K. Rowling 2005 29.99
WEB XQuery Kick Start en James McGovern 2003 49.99
WEB XQuery Kick Start en Per Bothner 2003 49.99
WEB XQuery Kick Start en Kurt Cagle 2003 49.99
WEB XQuery Kick Start en James Linn 2003 49.99
WEB XQuery Kick Start en Vaidyanathan Nagarajan 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
SELECT category, title, price FROM bookstore;
category title price
COOKING Everyday Italian 30.00
CHILDREN Harry Potter 29.99
WEB XQuery Kick Start 49.99
WEB Learning XML 39.95
SELECT category, title, author, price FROM bookstore WHERE author LIKE '%K%';
category title author price
CHILDREN Harry Potter J K. Rowling 29.99
WEB XQuery Kick Start Kurt Cagle 49.99
WEB Learning XML Erik T. Ray 39.95
SELECT category, title, price FROM bookstore WHERE author LIKE 'J%';
category title price
CHILDREN Harry Potter 29.99
WEB XQuery Kick Start 49.99
WEB XQuery Kick Start 49.99
#
# Limiting expanded values
#
ALTER TABLE bookstore OPTION_LIST='expand=1,mulnode=author,limit=3,xmlsup=libxml2';
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
CHILDREN Harry Potter en J K. Rowling 2005 29.99
WEB XQuery Kick Start en James McGovern 2003 49.99
WEB XQuery Kick Start en Per Bothner 2003 49.99
WEB XQuery Kick Start en Kurt Cagle 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
Warnings:
Warning 1105 Mutiple values limited to 3
# One line lost because the where clause is applied only on the first 3 rows
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
category title author price
CHILDREN Harry Potter J K. Rowling 29.99
WEB XQuery Kick Start James McGovern 49.99
Warnings:
Warning 1105 Mutiple values limited to 3
#
# Testing concatenated values
#
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=6,xmlsup=libxml2';
# truncated
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
CHILDREN Harry Potter en J K. Rowling 2005 29.99
WEB XQuery Kick Start en James McGovern, Per Both 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
Warnings:
Warning 1105 Truncated author content
# increase author size
ALTER TABLE bookstore MODIFY `author` VARCHAR(128) NOT NULL;
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
CHILDREN Harry Potter en J K. Rowling 2005 29.99
WEB XQuery Kick Start en James McGovern, Per Bothner, Kurt Cagle, James Linn, Vaidyanathan Nagarajan 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
#
# Limiting concatenated values
#
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=4,xmlsup=libxml2';
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
CHILDREN Harry Potter en J K. Rowling 2005 29.99
WEB XQuery Kick Start en James McGovern, Per Bothner, Kurt Cagle, James Linn 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
Warnings:
Warning 1105 Mutiple values limited to 4
# The where clause is applied on the concatenated column result
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
category title author price
CHILDREN Harry Potter J K. Rowling 29.99
WEB XQuery Kick Start James McGovern, Per Bothner, Kurt Cagle, James Linn 49.99
Warnings:
Warning 1105 Mutiple values limited to 4
DROP TABLE bookstore;
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
--source have_libxml2.inc
let $MYSQLD_DATADIR= `select @@datadir`;
SET NAMES utf8;
--copy_file $MTR_SUITE_DIR/std_data/bookstore.xml $MYSQLD_DATADIR/test/bookstore.xml
#--echo $MYSQL_TEST_DIR
#--exec pwd
#SELECT LOAD_FILE('test/bookstore.xml');
--echo #
--echo # Testing expanded values
--echo #
CREATE TABLE `bookstore` (
`category` CHAR(16) NOT NULL FIELD_FORMAT='@',
`title` VARCHAR(50) NOT NULL,
`lang` char(2) NOT NULL FIELD_FORMAT='title/@',
`author` VARCHAR(24) NOT NULL,
`year` INT(4) NOT NULL,
`price` DOUBLE(8,2) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='bookstore.xml' OPTION_LIST='expand=1,mulnode=author,limit=6,xmlsup=libxml2';
SELECT * FROM bookstore;
SELECT category, title, price FROM bookstore;
SELECT category, title, author, price FROM bookstore WHERE author LIKE '%K%';
SELECT category, title, price FROM bookstore WHERE author LIKE 'J%';
--echo #
--echo # Limiting expanded values
--echo #
ALTER TABLE bookstore OPTION_LIST='expand=1,mulnode=author,limit=3,xmlsup=libxml2';
SELECT * FROM bookstore;
--echo # One line lost because the where clause is applied only on the first 3 rows
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
--echo #
--echo # Testing concatenated values
--echo #
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=6,xmlsup=libxml2';
--echo # truncated
SELECT * FROM bookstore;
--echo # increase author size
ALTER TABLE bookstore MODIFY `author` VARCHAR(128) NOT NULL;
SELECT * FROM bookstore;
--echo #
--echo # Limiting concatenated values
--echo #
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=4,xmlsup=libxml2';
SELECT * FROM bookstore;
--echo # The where clause is applied on the concatenated column result
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
DROP TABLE bookstore;
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/bookstore.xml
......@@ -2135,7 +2135,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
PSZ fnc = "Unknown";
UWORD n;
SWORD ncol, len, tp;
SQLULEN crow;
SQLULEN crow = 0;
PQRYRES qrp = cap->Qrp;
PCOLRES crp;
RETCODE rc = 0;
......@@ -2287,6 +2287,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
} // endfor i
#if 0
if ((crow = i) && (rc == SQL_NO_DATA || rc == SQL_SUCCESS_WITH_INFO))
rc = SQL_SUCCESS;
......@@ -2303,6 +2304,15 @@ int ODBConn::GetCatInfo(CATPARM *cap)
} else
ThrowDBX(rc, fnc, hstmt);
#endif // 0
if (!rc || rc == SQL_NO_DATA || rc == SQL_SUCCESS_WITH_INFO) {
if ((rc = SQLFetch(hstmt)) != SQL_NO_DATA_FOUND)
qrp->Truncated = true;
crow = i;
} else
ThrowDBX(rc, fnc, hstmt);
irc = (int)crow;
} catch(DBX *x) {
......
......@@ -49,7 +49,8 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
int GetEnding(void) {return Ending;}
// Methods
virtual int Indexable(void) {return (Compressed != 1) ? 1 : 0;}
virtual int Indexable(void)
{return (!Multiple && Compressed != 1) ? 1 : 0;}
virtual bool DeleteIndexFile(PGLOBAL g, PIXDEF pxdf);
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE mode);
......
......@@ -304,15 +304,22 @@ int TDBASE::ResetTableOpt(PGLOBAL g, bool dox)
} // end of ResetTableOpt
/***********************************************************************/
/* SetKindex: set or reset the index pointer. */
/* ResetKindex: set or reset the index pointer. */
/***********************************************************************/
void TDBASE::SetKindex(PKXBASE kxp)
void TDBASE::ResetKindex(PGLOBAL g, PKXBASE kxp)
{
if (To_Kindex)
if (To_Kindex) {
int pos = GetRecpos(); // To be reset in Txfp
for (PCOL colp= Columns; colp; colp= colp->GetNext())
colp->SetKcol(NULL);
To_Kindex->Close(); // Discard old index
SetRecpos(g, pos); // Ignore return value
} // endif To_Kindex
To_Kindex = kxp;
} // end of SetKindex
} // end of ResetKindex
/***********************************************************************/
/* SetRecpos: Replace the table at the specified position. */
......
......@@ -84,10 +84,11 @@ MYSQLDEF::MYSQLDEF(void)
Username = NULL;
Password = NULL;
Portnumber = 0;
Isview = FALSE;
Bind = FALSE;
Delayed = FALSE;
Xsrc = FALSE;
Isview = false;
Bind = false;
Delayed = false;
Xsrc = false;
Huge = false;
} // end of MYSQLDEF constructor
/***********************************************************************/
......@@ -329,7 +330,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
} else {
// MYSQL access from a PROXY table
Database = GetStringCatInfo(g, "Database", "*");
Isview = GetBoolCatInfo("View", FALSE);
Isview = GetBoolCatInfo("View", false);
// We must get other connection parms from the calling table
Remove_tshp(Cat);
......@@ -363,7 +364,8 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
// Specific for command executing tables
Xsrc = GetBoolCatInfo("Execsrc", false);
Mxr = GetIntCatInfo("Maxerr", 0);
return FALSE;
Huge = GetBoolCatInfo("Huge", false);
return false;
} // end of DefineAM
/***********************************************************************/
......@@ -401,6 +403,7 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
Isview = tdp->Isview;
Prep = tdp->Bind;
Delayed = tdp->Delayed;
Myc.m_Use = tdp->Huge;
} else {
Host = NULL;
Database = NULL;
......@@ -412,15 +415,15 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
Qrystr = NULL;
Quoted = 0;
Port = 0;
Isview = FALSE;
Prep = FALSE;
Delayed = FALSE;
Isview = false;
Prep = false;
Delayed = false;
} // endif tdp
Bind = NULL;
Query = NULL;
Qbuf = NULL;
Fetched = FALSE;
Fetched = false;
m_Rc = RC_FX;
AftRows = 0;
N = -1;
......@@ -555,17 +558,17 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
char *colist, *valist = NULL;
char *tk = "`";
int len = 0, qlen = 0;
bool b = FALSE;
bool b = false;
PCOL colp;
if (Query)
return FALSE; // already done
return false; // already done
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial()) {
// if (colp->IsSpecial()) {
// strcpy(g->Message, MSG(NO_SPEC_COL));
// return TRUE;
// return true;
// } else {
len += (strlen(colp->GetName()) + 4);
((PMYCOL)colp)->Rank = Nparm++;
......@@ -581,7 +584,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
#else // !MYSQL_PREPARED_STATEMENTS
strcpy(g->Message, "Prepared statements not used (not supported)");
PushWarning(g, this);
Prep = FALSE;
Prep = false;
#endif // !MYSQL_PREPARED_STATEMENTS
} // endif Prep
......@@ -590,7 +593,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
strcat(colist, ", ");
if (Prep) strcat(valist, ",");
} else
b = TRUE;
b = true;
strcat(strcat(strcat(colist, tk), colp->GetName()), tk);
......@@ -628,7 +631,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
Qbuf = (char *)PlugSubAlloc(g, NULL, qlen);
} // endelse Prep
return FALSE;
return false;
} // end of MakeInsert
/***********************************************************************/
......@@ -906,9 +909,9 @@ bool TDBMYSQL::SetColumnRanks(PGLOBAL g)
{
for (PCOL colp = Columns; colp; colp = colp->GetNext())
if (((PMYCOL)colp)->FindRank(g))
return TRUE;
return true;
return FALSE;
return false;
} // end of SetColumnRanks
/***********************************************************************/
......@@ -1233,7 +1236,7 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
{
if (!(To_Val = value)) {
sprintf(g->Message, MSG(VALUE_ERROR), Name);
return TRUE;
return true;
} else if (Buf_Type == value->GetType()) {
// Values are of the (good) column type
if (Buf_Type == TYPE_DATE) {
......@@ -1253,12 +1256,12 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
if (check) {
sprintf(g->Message, MSG(TYPE_VALUE_ERR), Name,
GetTypeName(Buf_Type), GetTypeName(value->GetType()));
return TRUE;
return true;
} // endif check
newval:
if (InitValue(g)) // Allocate the matching value block
return TRUE;
return true;
} // endif's Value, Buf_Type
......@@ -1269,7 +1272,7 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
// Set the Column
Status = (ok) ? BUF_EMPTY : BUF_NO;
return FALSE;
return false;
} // end of SetBuffer
/***********************************************************************/
......@@ -1317,7 +1320,7 @@ void MYSQLCOL::ReadColumn(PGLOBAL g)
longjmp(g->jumper[g->jump_level], 11);
} else
tdbp->Fetched = TRUE;
tdbp->Fetched = true;
if ((buf = ((PTDBMY)To_Tdb)->Myc.GetCharField(Rank))) {
if (trace > 1)
......@@ -1354,7 +1357,7 @@ void MYSQLCOL::WriteColumn(PGLOBAL g)
/* Do convert the column value if necessary. */
/*********************************************************************/
if (Value != To_Val)
Value->SetValue_pval(To_Val, FALSE); // Convert the inserted value
Value->SetValue_pval(To_Val, false); // Convert the inserted value
#if defined(MYSQL_PREPARED_STATEMENTS)
if (((PTDBMY)To_Tdb)->Prep) {
......
......@@ -58,10 +58,11 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
int Portnumber; /* MySQL port number (0 = default) */
int Mxr; /* Maxerr for an Exec table */
int Quoted; /* Identifier quoting level */
bool Isview; /* TRUE if this table is a MySQL view */
bool Isview; /* true if this table is a MySQL view */
bool Bind; /* Use prepared statement on insert */
bool Delayed; /* Delayed insert */
bool Xsrc; /* Execution type */
bool Huge; /* True for big table */
}; // end of MYSQLDEF
/***********************************************************************/
......@@ -84,7 +85,7 @@ class TDBMYSQL : public TDBASE {
virtual int GetRecpos(void) {return N;}
virtual int GetProgMax(PGLOBAL g);
virtual void ResetDB(void) {N = 0;}
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
virtual int RowNumber(PGLOBAL g, bool b = false);
virtual bool IsView(void) {return Isview;}
virtual PSZ GetServer(void) {return Server;}
void SetDatabase(LPCSTR db) {Database = (char*)db;}
......
......@@ -145,7 +145,7 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
XmlDB = GetStringCatInfo(g, "XmlDB", "");
Nslist = GetStringCatInfo(g, "Nslist", "");
DefNs = GetStringCatInfo(g, "DefNs", "");
Limit = GetIntCatInfo("Limit", 2);
Limit = GetIntCatInfo("Limit", 10);
Xpand = (GetIntCatInfo("Expand", 0) != 0);
Header = GetIntCatInfo("Header", 0);
GetCharCatInfo("Xmlsup", "*", buf, sizeof(buf));
......@@ -1038,12 +1038,13 @@ XMLCOL::XMLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
Type = Tdbp->Coltype;
Nx = -1;
Sx = -1;
N = 0;
Valbuf = NULL;
To_Val = NULL;
} // end of XMLCOL constructor
/***********************************************************************/
/* XMLCOL constructor used for copying columns. */
/* XMLCOL constructor used for copying columns. */
/* tdbp is the pointer to the new table descriptor. */
/***********************************************************************/
XMLCOL::XMLCOL(XMLCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
......@@ -1068,6 +1069,7 @@ XMLCOL::XMLCOL(XMLCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
Rank = col1->Rank;
Nx = col1->Nx;
Sx = col1->Sx;
N = col1->N;
Type = col1->Type;
To_Val = col1->To_Val;
} // end of XMLCOL copy constructor
......@@ -1080,8 +1082,8 @@ bool XMLCOL::AllocBuf(PGLOBAL g, bool mode)
if (Valbuf)
return false; // Already done
Valbuf = (char*)PlugSubAlloc(g, NULL, Long + 1);
Valbuf[Long] = '\0';
//Valbuf = (char*)PlugSubAlloc(g, NULL, Long + 1);
//Valbuf[Long] = '\0';
return ParseXpath(g, mode);
} // end of AllocBuf
......@@ -1095,7 +1097,7 @@ bool XMLCOL::AllocBuf(PGLOBAL g, bool mode)
bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
{
char *p, *p2, *pbuf = NULL;
int i, len = strlen(Name);
int i, n = 1, len = strlen(Name);
len += ((Tdbp->Colname) ? strlen(Tdbp->Colname) : 0);
len += ((Xname) ? strlen(Xname) : 0);
......@@ -1122,7 +1124,7 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
// For Update or Insert the Xpath must be analyzed
if (mode) {
for (i = 0, p = pbuf; (p = strchr(p, '/')); i++, p++)
Nod++; // One path node found
Nod++; // One path node found
if (Nod)
Nodes = (char**)PlugSubAlloc(g, NULL, Nod * sizeof(char*));
......@@ -1136,7 +1138,7 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
strcpy(g->Message, MSG(CONCAT_SUBNODE));
return true;
} else
Inod = i; // Index of multiple node
Inod = i; // Index of multiple node
if (mode) {
// For Update or Insert the Xpath must be explicit
......@@ -1171,7 +1173,7 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
} else if (Type == 2) {
// HTML like table, columns are retrieved by position
new(this) XPOSCOL(Value); // Change the class of this column
new(this) XPOSCOL(Value); // Change the class of this column
Tdbp->Hasnod = true;
return false;
} else if (Type == 0 && !mode) {
......@@ -1185,9 +1187,18 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
if (Inod >= 0) {
Tdbp->Colp = this; // To force expand
new(this) XMULCOL(Value); // Change the class of this column
if (Tdbp->Xpand)
n = Tdbp->Limit;
new(this) XMULCOL(Value); // Change the class of this column
} // endif Inod
Valbuf = (char*)PlugSubAlloc(g, NULL, n * (Long + 1));
for (i = 0; i < n; i++)
Valbuf[Long + (i * (Long + 1))] = '\0';
if (Type || Nod)
Tdbp->Hasnod = true;
......@@ -1470,60 +1481,72 @@ void XMLCOL::WriteColumn(PGLOBAL g)
void XMULCOL::ReadColumn(PGLOBAL g)
{
char *p;
int i, n, len;
int i, len;
bool b = Tdbp->Xpand;
if (Nx != Tdbp->Irow) // New row
if (Nx != Tdbp->Irow) { // New row
Nl = Tdbp->RowNode->SelectNodes(g, Xname, Nl);
else if (Sx == Tdbp->Nsub)
return; // Same row
if ((n = Nl->GetLength())) {
*(p = Valbuf) = '\0';
len = Long;
if ((N = Nl->GetLength())) {
*(p = Valbuf) = '\0';
len = Long;
for (i = Tdbp->Nsub; i < n; i++) {
ValNode = Nl->GetItem(g, i, Vxnp);
if (N > Tdbp->Limit) {
N = Tdbp->Limit;
sprintf(g->Message, "Mutiple values limited to %d", Tdbp->Limit);
PushWarning(g, Tdbp);
} // endif N
if (ValNode->GetType() != XML_ELEMENT_NODE &&
ValNode->GetType() != XML_ATTRIBUTE_NODE) {
sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name);
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
} // endif type
for (i = 0; i < N; i++) {
ValNode = Nl->GetItem(g, i, Vxnp);
// Get the Xname value from the XML file
switch (ValNode->GetContent(g, p, len + 1)) {
case RC_OK:
break;
case RC_INFO:
PushWarning(g, Tdbp);
break;
default:
if (ValNode->GetType() != XML_ELEMENT_NODE &&
ValNode->GetType() != XML_ATTRIBUTE_NODE) {
sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name);
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
} // endswitch
if (!Tdbp->Xpand) {
// Concatenate all values
if (n - i > 1)
strncat(Valbuf, ", ", Long + 1);
len -= strlen(p);
p += strlen(p);
} else
break;
} // endfor i
} // endif type
// Get the Xname value from the XML file
switch (ValNode->GetContent(g, p, (b ? Long : len))) {
case RC_OK:
break;
case RC_INFO:
PushWarning(g, Tdbp);
break;
default:
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
} // endswitch
if (!b) {
// Concatenate all values
if (N - i > 1)
strncat(Valbuf, ", ", len - strlen(p));
if ((len -= strlen(p)) <= 0)
break;
p += strlen(p);
} else // Xpand
p += (Long + 1);
} // endfor i
Value->SetValue_psz(Valbuf);
} else {
if (Nullable)
Value->SetNull(true);
Value->SetValue_psz(Valbuf);
} else {
if (Nullable)
Value->SetNull(true);
Value->Reset(); // Null value
} // endif ValNode
Value->Reset(); // Null value
} // endif ValNode
} else if (Sx == Tdbp->Nsub)
return; // Same row
else // Expanded value
Value->SetValue_psz(Valbuf + (Tdbp->Nsub * (Long + 1)));
Nx = Tdbp->Irow;
Sx = Tdbp->Nsub;
Tdbp->NextSame = (Tdbp->Xpand && Nl->GetLength() - Sx > 1);
Tdbp->NextSame = (Tdbp->Xpand && N - Sx > 1);
} // end of ReadColumn
/***********************************************************************/
......
......@@ -190,6 +190,7 @@ class XMLCOL : public COLBLK {
int Long; // Buffer length
int Nx; // The last read row
int Sx; // The last read sub-row
int N; // The number of (multiple) values
PVAL To_Val; // To value used for Update/Insert
}; // end of class XMLCOL
......
......@@ -2131,9 +2131,6 @@ int XINDXS::FastFind(int nk)
XLOAD::XLOAD(void)
{
Hfile = INVALID_HANDLE_VALUE;
#if defined(WIN32) && defined(XMAP)
ViewBase = NULL;
#endif // WIN32 && XMAP
NewOff.Val = 0LL;
} // end of XLOAD constructor
......@@ -2147,15 +2144,6 @@ void XLOAD::Close(void)
Hfile = INVALID_HANDLE_VALUE;
} // endif Hfile
#if defined(WIN32) && defined(XMAP)
if (ViewBase) {
if (!UnmapViewOfFile(ViewBase))
printf("Error %d closing Viewmap\n", GetLastError());
ViewBase = NULL;
} // endif ViewBase
#endif // WIN32 && XMAP
} // end of Close
/* --------------------------- XFILE Class --------------------------- */
......@@ -2166,9 +2154,9 @@ void XLOAD::Close(void)
XFILE::XFILE(void) : XLOAD()
{
Xfile = NULL;
#if defined(XMAP) && !defined(WIN32)
#if defined(XMAP)
Mmp = NULL;
#endif // XMAP && !WIN32
#endif // XMAP
} // end of XFILE constructor
/***********************************************************************/
......@@ -2193,9 +2181,9 @@ bool XFILE::Open(PGLOBAL g, char *filename, int id, MODE mode)
} // endswitch mode
if (!(Xfile= global_fopen(g, MSGID_OPEN_ERROR_AND_STRERROR, filename, pmod))) {
#if defined(TRACE)
printf("Open: %s\n", g->Message);
#endif // TRACE
if (trace)
htrc("Open: %s\n", g->Message);
return true;
} // endif Xfile
......@@ -2311,11 +2299,9 @@ void XFILE::Close(void)
Xfile = NULL;
} // endif Xfile
#if defined(XMAP) && !defined(WIN32)
if (Mmp) {
CloseMemMap(Mmp->memory, Mmp->lenL);
Mmp = NULL;
} // endif Mmp
#if defined(XMAP)
if (Mmp && CloseMemMap(Mmp->memory, Mmp->lenL))
printf("Error closing mapped index\n");
#endif // XMAP
} // end of Close
......@@ -2357,9 +2343,8 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
return true;
} // endif
#if defined(TRACE)
printf( "Xopen: filename=%s mode=%d\n", filename, mode);
#endif // TRACE
if (trace)
htrc(" Xopen: filename=%s mode=%d\n", filename, mode);
#if defined(WIN32)
LONG high = 0;
......@@ -2476,16 +2461,15 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
if (Hfile == INVALID_HANDLE_VALUE) {
/*rc = errno;*/
#if defined(TRACE)
printf("Open: %s\n", g->Message);
#endif // TRACE
if (trace)
htrc("Open: %s\n", g->Message);
return true;
} // endif Hfile
#if defined(TRACE)
printf(" rc=%d oflag=%p mode=%d handle=%d fn=%s\n",
rc, oflag, mode, Hfile, filename);
#endif // TRACE
if (trace)
htrc(" oflag=%p mode=%d handle=%d fn=%s\n",
oflag, mode, Hfile, filename);
if (mode == MODE_INSERT) {
/*******************************************************************/
......@@ -2588,15 +2572,15 @@ bool XHUGE::Read(PGLOBAL g, void *buf, int n, int size)
#else // UNIX
ssize_t count = (ssize_t)(n * size);
#if defined(TRACE)
printf("Hfile=%d n=%d size=%d count=%d\n", Hfile, n, size, count);
#endif // TRACE
if (trace)
htrc("Hfile=%d n=%d size=%d count=%d\n", Hfile, n, size, count);
if (read(Hfile, buf, count) != count) {
sprintf(g->Message, MSG(READ_ERROR), "Index file", strerror(errno));
#if defined(TRACE)
printf("read error %d\n", errno);
#endif // TRACE
if (trace)
htrc("read error %d\n", errno);
rc = true;
} // endif nbr
#endif // UNIX
......@@ -2854,8 +2838,7 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
// Allocate the Value object used when moving items
Type = colp->GetResultType();
if (!(Valp = AllocateValue(g, Type, len, colp->GetScale(),
colp->IsUnsigned())))
if (!(Valp = AllocateValue(g, Type, len, prec, colp->IsUnsigned())))
return true;
Klen = Valp->GetClen();
......@@ -2877,10 +2860,11 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
// Store this information to avoid sorting when already done
if (Asc)
// IsSorted = colp->GetOpt() < 0;
// IsSorted = colp->GetOpt() == 2;
IsSorted = false;
//SetNulls(colp->IsNullable()); for when null columns will be indexable
Colp = colp;
return false;
} // end of Init
......@@ -2891,7 +2875,7 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
/***********************************************************************/
BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
{
int len = colp->GetLength(), prec = colp->GetPrecision();
int len = colp->GetLength(), prec = colp->GetScale();
if (n[3] && colp->GetLength() > n[3]
&& colp->GetResultType() == TYPE_STRING) {
......@@ -2906,7 +2890,7 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
this, colp, Type, n[0], len, m);
// Allocate the Value object used when moving items
Valp = AllocateValue(g, Type, len, prec, false, NULL);
Valp = AllocateValue(g, Type, len, prec, colp->IsUnsigned());
Klen = Valp->GetClen();
if (n[2]) {
......@@ -2926,7 +2910,7 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
// by blanks (if true) or keep the zero ending char (if false).
// Currently we set it to true to be compatible with QRY blocks,
// and last one to enable type checking (no conversion).
Kblp = AllocValBlock(g, To_Keys, Type, n[0], len, prec, true, true);
Kblp = AllocValBlock(g, To_Keys, Type, n[0], len, prec, !Prefix, true);
if (n[1]) {
Koff.Size = n[1] * sizeof(int);
......@@ -2937,6 +2921,7 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
Ndf = n[0];
//IsSorted = colp->GetOpt() < 0;
IsSorted = false;
Colp = colp;
return m + Bkeys.Size + Keys.Size + Koff.Size;
} // end of MapInit
#endif // XMAP
......@@ -3054,9 +3039,8 @@ int KXYCOL::Compare(int i1, int i2)
// Do the actual comparison between values.
register int k = Kblp->CompVal(i1, i2);
#ifdef DEBUG2
htrc("Compare done result=%d\n", k);
#endif
if (trace > 2)
htrc("Compare done result=%d\n", k);
return (Asc) ? k : -k;
} // end of Compare
......@@ -3067,13 +3051,14 @@ int KXYCOL::Compare(int i1, int i2)
int KXYCOL::CompVal(int i)
{
// Do the actual comparison between numerical values.
#ifdef DEBUG2
register int k = (int)Kblp->CompVal(Valp, (int)i);
if (trace > 2) {
register int k = (int)Kblp->CompVal(Valp, (int)i);
htrc("Compare done result=%d\n", k);
return k;
} else
return Kblp->CompVal(Valp, i);
htrc("Compare done result=%d\n", k);
return k;
#endif
return Kblp->CompVal(Valp, i);
} // end of CompVal
/***********************************************************************/
......
......@@ -339,9 +339,6 @@ class DllExport XLOAD : public BLOCK {
// Members
#if defined(WIN32)
HANDLE Hfile; // Handle to file or map
#if defined(XMAP)
void *ViewBase; // Mapped view base address
#endif // XMAP
#else // UNIX
int Hfile; // Descriptor to file or map
#endif // UNIX
......@@ -369,9 +366,9 @@ class DllExport XFILE : public XLOAD {
protected:
// Members
FILE *Xfile; // Index stream file
FILE *Xfile; // Index stream file
#if defined(XMAP)
MMP Mmp; // To mapped index file
MMP Mmp; // Mapped view base address and length
#endif // XMAP
}; // end of class XFILE
......
......@@ -142,9 +142,10 @@ class DllExport TDBASE : public TDB {
inline PKXBASE GetKindex(void) {return To_Kindex;}
inline PCOL GetSetCols(void) {return To_SetCols;}
inline void SetSetCols(PCOL colp) {To_SetCols = colp;}
inline void SetKindex(PKXBASE kxp) {To_Kindex = kxp;}
// Properties
void SetKindex(PKXBASE kxp);
void ResetKindex(PGLOBAL g, PKXBASE kxp);
PCOL Key(int i) {return (To_Key_Col) ? To_Key_Col[i] : NULL;}
// Methods
......
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