merge with 10.0-connect
This commit is contained in:
commit
229dad1f9b
@ -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
|
||||
|
||||
/******************************************************************/
|
||||
|
@ -413,9 +413,9 @@ static int connect_init_func(void *p)
|
||||
init_connect_psi_keys();
|
||||
|
||||
connect_hton= (handlerton *)p;
|
||||
connect_hton->state= SHOW_OPTION_YES;
|
||||
connect_hton->create= connect_create_handler;
|
||||
connect_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED | HTON_NO_PARTITION;
|
||||
connect_hton->state= SHOW_OPTION_YES;
|
||||
connect_hton->create= connect_create_handler;
|
||||
connect_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED | HTON_NO_PARTITION;
|
||||
connect_hton->table_options= connect_table_option_list;
|
||||
connect_hton->field_options= connect_field_option_list;
|
||||
connect_hton->tablefile_extensions= ha_connect_exts;
|
||||
@ -621,7 +621,7 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
|
||||
{
|
||||
TABTYPE type;
|
||||
|
||||
if (pos || (pos= GetTableOptionStruct(table))) {
|
||||
if (pos || (pos= GetTableOptionStruct())) {
|
||||
type= GetTypeID(pos->type);
|
||||
|
||||
if (type == TAB_UNDEF)
|
||||
@ -633,6 +633,50 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
|
||||
return type;
|
||||
} // end of GetRealType
|
||||
|
||||
/** @brief
|
||||
The name of the index type that will be used for display.
|
||||
Don't implement this method unless you really have indexes.
|
||||
*/
|
||||
const char *ha_connect::index_type(uint inx)
|
||||
{
|
||||
switch (GetIndexType(GetRealType())) {
|
||||
case 1: return "XPLUG";
|
||||
case 2: return "REMOTE";
|
||||
} // endswitch
|
||||
|
||||
return "Unknown";
|
||||
} // end of index_type
|
||||
|
||||
/** @brief
|
||||
This is a bitmap of flags that indicates how the storage engine
|
||||
implements indexes. The current index flags are documented in
|
||||
handler.h. If you do not implement indexes, just return zero here.
|
||||
|
||||
@details
|
||||
part is the key part to check. First key part is 0.
|
||||
If all_parts is set, MySQL wants to know the flags for the combined
|
||||
index, up to and including 'part'.
|
||||
*/
|
||||
ulong ha_connect::index_flags(uint inx, uint part, bool all_parts) const
|
||||
{
|
||||
ulong flags= HA_READ_NEXT | HA_READ_RANGE |
|
||||
HA_KEYREAD_ONLY | HA_KEY_SCAN_NOT_ROR;
|
||||
ha_connect *hp= (ha_connect*)this;
|
||||
PTOS pos= hp->GetTableOptionStruct();
|
||||
|
||||
if (pos) {
|
||||
TABTYPE type= hp->GetRealType(pos);
|
||||
|
||||
switch (GetIndexType(type)) {
|
||||
case 1: flags|= (HA_READ_ORDER | HA_READ_PREV); break;
|
||||
case 2: flags|= HA_READ_AFTER_KEY; break;
|
||||
} // endswitch
|
||||
|
||||
} // endif pos
|
||||
|
||||
return flags;
|
||||
} // end of index_flags
|
||||
|
||||
/** @brief
|
||||
This is a list of flags that indicate what functionality the storage
|
||||
engine implements. The current table flags are documented in handler.h
|
||||
@ -641,14 +685,14 @@ ulonglong ha_connect::table_flags() const
|
||||
{
|
||||
ulonglong flags= HA_CAN_VIRTUAL_COLUMNS | HA_REC_NOT_IN_SEQ |
|
||||
HA_NO_AUTO_INCREMENT | HA_NO_PREFIX_CHAR_KEYS |
|
||||
// HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
|
||||
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
|
||||
HA_PARTIAL_COLUMN_READ | HA_FILE_BASED |
|
||||
// HA_NULL_IN_KEY | not implemented yet
|
||||
// HA_FAST_KEY_READ | causes error when sorting (???)
|
||||
HA_NO_TRANSACTIONS | HA_DUPLICATE_KEY_NOT_IN_ORDER |
|
||||
HA_NO_BLOBS | HA_MUST_USE_TABLE_CONDITION_PUSHDOWN;
|
||||
ha_connect *hp= (ha_connect*)this;
|
||||
PTOS pos= hp->GetTableOptionStruct(table);
|
||||
PTOS pos= hp->GetTableOptionStruct();
|
||||
|
||||
if (pos) {
|
||||
TABTYPE type= hp->GetRealType(pos);
|
||||
@ -719,10 +763,11 @@ char *GetListOption(PGLOBAL g, const char *opname,
|
||||
/****************************************************************************/
|
||||
/* Return the table option structure. */
|
||||
/****************************************************************************/
|
||||
PTOS ha_connect::GetTableOptionStruct(TABLE *tab)
|
||||
PTOS ha_connect::GetTableOptionStruct(TABLE_SHARE *s)
|
||||
{
|
||||
return (tshp) ? tshp->option_struct :
|
||||
(tab) ? tab->s->option_struct : NULL;
|
||||
TABLE_SHARE *tsp= (tshp) ? tshp : (s) ? s : table_share;
|
||||
|
||||
return (tsp) ? tsp->option_struct : NULL;
|
||||
} // end of GetTableOptionStruct
|
||||
|
||||
/****************************************************************************/
|
||||
@ -731,7 +776,7 @@ PTOS ha_connect::GetTableOptionStruct(TABLE *tab)
|
||||
char *ha_connect::GetStringOption(char *opname, char *sdef)
|
||||
{
|
||||
char *opval= NULL;
|
||||
PTOS options= GetTableOptionStruct(table);
|
||||
PTOS options= GetTableOptionStruct();
|
||||
|
||||
if (!options)
|
||||
;
|
||||
@ -803,10 +848,10 @@ bool ha_connect::GetBooleanOption(char *opname, bool bdef)
|
||||
{
|
||||
bool opval= bdef;
|
||||
char *pv;
|
||||
PTOS options= GetTableOptionStruct(table);
|
||||
PTOS options= GetTableOptionStruct();
|
||||
|
||||
if (!stricmp(opname, "View"))
|
||||
opval= (tshp) ? tshp->is_view : table->s->is_view;
|
||||
opval= (tshp) ? tshp->is_view : table_share->is_view;
|
||||
else if (!options)
|
||||
;
|
||||
else if (!stricmp(opname, "Mapped"))
|
||||
@ -834,7 +879,7 @@ bool ha_connect::GetBooleanOption(char *opname, bool bdef)
|
||||
/****************************************************************************/
|
||||
bool ha_connect::SetBooleanOption(char *opname, bool b)
|
||||
{
|
||||
PTOS options= GetTableOptionStruct(table);
|
||||
PTOS options= GetTableOptionStruct();
|
||||
|
||||
if (!options)
|
||||
return true;
|
||||
@ -854,7 +899,7 @@ int ha_connect::GetIntegerOption(char *opname)
|
||||
{
|
||||
ulonglong opval= NO_IVAL;
|
||||
char *pv;
|
||||
PTOS options= GetTableOptionStruct(table);
|
||||
PTOS options= GetTableOptionStruct();
|
||||
|
||||
if (!options)
|
||||
;
|
||||
@ -891,7 +936,7 @@ int ha_connect::GetIntegerOption(char *opname)
|
||||
/****************************************************************************/
|
||||
bool ha_connect::SetIntegerOption(char *opname, int n)
|
||||
{
|
||||
PTOS options= GetTableOptionStruct(table);
|
||||
PTOS options= GetTableOptionStruct();
|
||||
|
||||
if (!options)
|
||||
return true;
|
||||
@ -1153,7 +1198,7 @@ const char *ha_connect::GetDBName(const char* name)
|
||||
|
||||
const char *ha_connect::GetTableName(void)
|
||||
{
|
||||
return (tshp) ? tshp->table_name.str : table->s->table_name.str;
|
||||
return (tshp) ? tshp->table_name.str : table_share->table_name.str;
|
||||
} // end of GetTableName
|
||||
|
||||
#if 0
|
||||
@ -2404,7 +2449,7 @@ int ha_connect::index_init(uint idx, bool sorted)
|
||||
} // endif index type
|
||||
|
||||
if ((rc= rnd_init(0)))
|
||||
return rc;
|
||||
DBUG_RETURN(rc);
|
||||
|
||||
if (locked == 2) {
|
||||
// Indexes are not updated in lock write mode
|
||||
@ -3310,7 +3355,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
|
||||
int rc= 0;
|
||||
bool xcheck=false, cras= false;
|
||||
MODE newmode;
|
||||
PTOS options= GetTableOptionStruct(table);
|
||||
PTOS options= GetTableOptionStruct();
|
||||
PGLOBAL g= GetPlug(thd, xp);
|
||||
DBUG_ENTER("ha_connect::external_lock");
|
||||
|
||||
@ -3771,7 +3816,8 @@ ha_rows ha_connect::records_in_range(uint inx, key_range *min_key,
|
||||
DBUG_ENTER("ha_connect::records_in_range");
|
||||
|
||||
if (indexing < 0 || inx != active_index)
|
||||
index_init(inx, false);
|
||||
if (index_init(inx, false))
|
||||
DBUG_RETURN(HA_POS_ERROR);
|
||||
|
||||
if (xtrace)
|
||||
htrc("records_in_range: inx=%d indexing=%d\n", inx, indexing);
|
||||
@ -4362,7 +4408,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
||||
if (!qrp) {
|
||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||
return HA_ERR_INTERNAL_ERROR;
|
||||
} // endif qrp
|
||||
} // endif !qrp
|
||||
|
||||
if (fnc != FNC_NO || src || ttp == TAB_PIVOT) {
|
||||
// Catalog like table
|
||||
@ -4384,7 +4430,18 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
||||
|
||||
} // endfor crp
|
||||
|
||||
} else // Not a catalog table
|
||||
} else {
|
||||
// Not a catalog table
|
||||
if (!qrp->Nblin) {
|
||||
if (tab)
|
||||
sprintf(g->Message, "Cannot get columns from %s", tab);
|
||||
else
|
||||
strcpy(g->Message, "Fail to retrieve columns");
|
||||
|
||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||
return HA_ERR_INTERNAL_ERROR;
|
||||
} // endif !nblin
|
||||
|
||||
for (i= 0; !rc && i < qrp->Nblin; i++) {
|
||||
typ= len= prec= dec= 0;
|
||||
tm= NOT_NULL_FLAG;
|
||||
@ -4477,6 +4534,8 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
||||
rc= HA_ERR_OUT_OF_MEM;
|
||||
} // endfor i
|
||||
|
||||
} // endif fnc
|
||||
|
||||
if (!rc)
|
||||
rc= init_table_share(thd, table_s, create_info, &sql);
|
||||
// rc= init_table_share(thd, table_s, create_info, dsn, &sql);
|
||||
@ -4550,7 +4609,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
||||
|
||||
DBUG_ENTER("ha_connect::create");
|
||||
int sqlcom= thd_sql_command(table_arg->in_use);
|
||||
PTOS options= GetTableOptionStruct(table_arg);
|
||||
PTOS options= GetTableOptionStruct(table_arg->s);
|
||||
|
||||
table= table_arg; // Used by called functions
|
||||
|
||||
@ -4885,7 +4944,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
||||
} else
|
||||
::close(h);
|
||||
|
||||
if (type == TAB_FMT || options->readonly)
|
||||
if ((type == TAB_FMT || options->readonly) && sqlcom == SQLCOM_CREATE_TABLE)
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
|
||||
"Congratulation, you just created a read-only void table!");
|
||||
|
||||
@ -4915,7 +4974,15 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
||||
|
||||
// Get the index definitions
|
||||
if (xdp= GetIndexInfo()) {
|
||||
if (GetIndexType(type) == 1) {
|
||||
if (options->multiple) {
|
||||
strcpy(g->Message, "Multiple tables are not indexable");
|
||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||
rc= HA_ERR_UNSUPPORTED;
|
||||
} else if (options->compressed) {
|
||||
strcpy(g->Message, "Compressed tables are not indexable");
|
||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||
rc= HA_ERR_UNSUPPORTED;
|
||||
} else if (GetIndexType(type) == 1) {
|
||||
PDBUSER dup= PlgGetUser(g);
|
||||
PCATLG cat= (dup) ? dup->Catalog : NULL;
|
||||
|
||||
@ -5123,7 +5190,6 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
|
||||
int sqlcom= thd_sql_command(thd);
|
||||
TABTYPE newtyp, type= TAB_UNDEF;
|
||||
HA_CREATE_INFO *create_info= ha_alter_info->create_info;
|
||||
//PTOS pos= GetTableOptionStruct(table);
|
||||
PTOS newopt, oldopt;
|
||||
xp= GetUser(thd, xp);
|
||||
PGLOBAL g= xp->g;
|
||||
@ -5169,7 +5235,15 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
|
||||
if (ha_alter_info->handler_flags & index_operations ||
|
||||
!SameString(altered_table, "optname") ||
|
||||
!SameBool(altered_table, "sepindex")) {
|
||||
if (GetIndexType(type) == 1) {
|
||||
if (newopt->multiple) {
|
||||
strcpy(g->Message, "Multiple tables are not indexable");
|
||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||
DBUG_RETURN(HA_ALTER_ERROR);
|
||||
} else if (newopt->compressed) {
|
||||
strcpy(g->Message, "Compressed tables are not indexable");
|
||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||
DBUG_RETURN(HA_ALTER_ERROR);
|
||||
} else if (GetIndexType(type) == 1) {
|
||||
g->Xchk= new(g) XCHK;
|
||||
PCHK xcp= (PCHK)g->Xchk;
|
||||
|
||||
|
@ -167,7 +167,7 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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
|
||||
|
||||
|
102
storage/connect/mysql-test/connect/r/xml_mult.result
Normal file
102
storage/connect/mysql-test/connect/r/xml_mult.result
Normal file
@ -0,0 +1,102 @@
|
||||
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;
|
31
storage/connect/mysql-test/connect/std_data/bookstore.xml
Normal file
31
storage/connect/mysql-test/connect/std_data/bookstore.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?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>
|
64
storage/connect/mysql-test/connect/t/xml_mult.test
Normal file
64
storage/connect/mysql-test/connect/t/xml_mult.test
Normal file
@ -0,0 +1,64 @@
|
||||
--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
|
||||
} // endif type
|
||||
|
||||
if (!Tdbp->Xpand) {
|
||||
// Concatenate all values
|
||||
if (n - i > 1)
|
||||
strncat(Valbuf, ", ", Long + 1);
|
||||
// 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
|
||||
|
||||
len -= strlen(p);
|
||||
p += strlen(p);
|
||||
} else
|
||||
break;
|
||||
if (!b) {
|
||||
// Concatenate all values
|
||||
if (N - i > 1)
|
||||
strncat(Valbuf, ", ", len - strlen(p));
|
||||
|
||||
} // endfor i
|
||||
if ((len -= strlen(p)) <= 0)
|
||||
break;
|
||||
|
||||
Value->SetValue_psz(Valbuf);
|
||||
} else {
|
||||
if (Nullable)
|
||||
Value->SetNull(true);
|
||||
p += strlen(p);
|
||||
} else // Xpand
|
||||
p += (Long + 1);
|
||||
|
||||
Value->Reset(); // Null value
|
||||
} // endif ValNode
|
||||
} // endfor i
|
||||
|
||||
Value->SetValue_psz(Valbuf);
|
||||
} else {
|
||||
if (Nullable)
|
||||
Value->SetNull(true);
|
||||
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user