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())
|
for (PCOL colp= tdbp->GetColumns(); colp; colp= colp->GetNext())
|
||||||
colp->SetKcol(NULL);
|
colp->SetKcol(NULL);
|
||||||
|
|
||||||
((PTDBASE)tdbp)->SetKindex(NULL);
|
((PTDBASE)tdbp)->ResetKindex(g, NULL);
|
||||||
} // endif index
|
} // endif index
|
||||||
|
|
||||||
// Save stack and allocation environment and prepare error return
|
// Save stack and allocation environment and prepare error return
|
||||||
@ -585,7 +585,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
|
|||||||
|
|
||||||
// Make all the eventual indexes
|
// Make all the eventual indexes
|
||||||
tbxp= (TDBDOX*)tdbp;
|
tbxp= (TDBDOX*)tdbp;
|
||||||
tbxp->SetKindex(NULL);
|
tbxp->ResetKindex(g, NULL);
|
||||||
tbxp->To_Key_Col= NULL;
|
tbxp->To_Key_Col= NULL;
|
||||||
rc= tbxp->ResetTableOpt(g, ((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
|
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)
|
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 (dnp) {
|
||||||
if (np) {
|
if (np) {
|
||||||
((PDOMNODE)np)->Nodep = dnp;
|
((PDOMNODE)np)->Nodep = dnp;
|
||||||
return np;
|
return np;
|
||||||
} else
|
} else
|
||||||
return new(g) DOMNODE(Doc, dnp);
|
return new(g) DOMNODE(Doc, dnp);
|
||||||
|
|
||||||
} else
|
} // endif dnp
|
||||||
return NULL;
|
|
||||||
|
|
||||||
|
} catch(_com_error e) {
|
||||||
|
sprintf(g->Message, "%s: %s", MSG(COM_ERROR),
|
||||||
|
_com_util::ConvertBSTRToString(e.Description()));
|
||||||
|
} catch(...) {}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
} // end of SelectSingleNode
|
} // end of SelectSingleNode
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
@ -413,9 +413,9 @@ static int connect_init_func(void *p)
|
|||||||
init_connect_psi_keys();
|
init_connect_psi_keys();
|
||||||
|
|
||||||
connect_hton= (handlerton *)p;
|
connect_hton= (handlerton *)p;
|
||||||
connect_hton->state= SHOW_OPTION_YES;
|
connect_hton->state= SHOW_OPTION_YES;
|
||||||
connect_hton->create= connect_create_handler;
|
connect_hton->create= connect_create_handler;
|
||||||
connect_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED | HTON_NO_PARTITION;
|
connect_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED | HTON_NO_PARTITION;
|
||||||
connect_hton->table_options= connect_table_option_list;
|
connect_hton->table_options= connect_table_option_list;
|
||||||
connect_hton->field_options= connect_field_option_list;
|
connect_hton->field_options= connect_field_option_list;
|
||||||
connect_hton->tablefile_extensions= ha_connect_exts;
|
connect_hton->tablefile_extensions= ha_connect_exts;
|
||||||
@ -621,7 +621,7 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
|
|||||||
{
|
{
|
||||||
TABTYPE type;
|
TABTYPE type;
|
||||||
|
|
||||||
if (pos || (pos= GetTableOptionStruct(table))) {
|
if (pos || (pos= GetTableOptionStruct())) {
|
||||||
type= GetTypeID(pos->type);
|
type= GetTypeID(pos->type);
|
||||||
|
|
||||||
if (type == TAB_UNDEF)
|
if (type == TAB_UNDEF)
|
||||||
@ -633,6 +633,50 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
|
|||||||
return type;
|
return type;
|
||||||
} // end of GetRealType
|
} // 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
|
/** @brief
|
||||||
This is a list of flags that indicate what functionality the storage
|
This is a list of flags that indicate what functionality the storage
|
||||||
engine implements. The current table flags are documented in handler.h
|
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 |
|
ulonglong flags= HA_CAN_VIRTUAL_COLUMNS | HA_REC_NOT_IN_SEQ |
|
||||||
HA_NO_AUTO_INCREMENT | HA_NO_PREFIX_CHAR_KEYS |
|
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_PARTIAL_COLUMN_READ | HA_FILE_BASED |
|
||||||
// HA_NULL_IN_KEY | not implemented yet
|
// HA_NULL_IN_KEY | not implemented yet
|
||||||
// HA_FAST_KEY_READ | causes error when sorting (???)
|
// HA_FAST_KEY_READ | causes error when sorting (???)
|
||||||
HA_NO_TRANSACTIONS | HA_DUPLICATE_KEY_NOT_IN_ORDER |
|
HA_NO_TRANSACTIONS | HA_DUPLICATE_KEY_NOT_IN_ORDER |
|
||||||
HA_NO_BLOBS | HA_MUST_USE_TABLE_CONDITION_PUSHDOWN;
|
HA_NO_BLOBS | HA_MUST_USE_TABLE_CONDITION_PUSHDOWN;
|
||||||
ha_connect *hp= (ha_connect*)this;
|
ha_connect *hp= (ha_connect*)this;
|
||||||
PTOS pos= hp->GetTableOptionStruct(table);
|
PTOS pos= hp->GetTableOptionStruct();
|
||||||
|
|
||||||
if (pos) {
|
if (pos) {
|
||||||
TABTYPE type= hp->GetRealType(pos);
|
TABTYPE type= hp->GetRealType(pos);
|
||||||
@ -719,10 +763,11 @@ char *GetListOption(PGLOBAL g, const char *opname,
|
|||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* Return the table option structure. */
|
/* Return the table option structure. */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
PTOS ha_connect::GetTableOptionStruct(TABLE *tab)
|
PTOS ha_connect::GetTableOptionStruct(TABLE_SHARE *s)
|
||||||
{
|
{
|
||||||
return (tshp) ? tshp->option_struct :
|
TABLE_SHARE *tsp= (tshp) ? tshp : (s) ? s : table_share;
|
||||||
(tab) ? tab->s->option_struct : NULL;
|
|
||||||
|
return (tsp) ? tsp->option_struct : NULL;
|
||||||
} // end of GetTableOptionStruct
|
} // end of GetTableOptionStruct
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
@ -731,7 +776,7 @@ PTOS ha_connect::GetTableOptionStruct(TABLE *tab)
|
|||||||
char *ha_connect::GetStringOption(char *opname, char *sdef)
|
char *ha_connect::GetStringOption(char *opname, char *sdef)
|
||||||
{
|
{
|
||||||
char *opval= NULL;
|
char *opval= NULL;
|
||||||
PTOS options= GetTableOptionStruct(table);
|
PTOS options= GetTableOptionStruct();
|
||||||
|
|
||||||
if (!options)
|
if (!options)
|
||||||
;
|
;
|
||||||
@ -803,10 +848,10 @@ bool ha_connect::GetBooleanOption(char *opname, bool bdef)
|
|||||||
{
|
{
|
||||||
bool opval= bdef;
|
bool opval= bdef;
|
||||||
char *pv;
|
char *pv;
|
||||||
PTOS options= GetTableOptionStruct(table);
|
PTOS options= GetTableOptionStruct();
|
||||||
|
|
||||||
if (!stricmp(opname, "View"))
|
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 (!options)
|
||||||
;
|
;
|
||||||
else if (!stricmp(opname, "Mapped"))
|
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)
|
bool ha_connect::SetBooleanOption(char *opname, bool b)
|
||||||
{
|
{
|
||||||
PTOS options= GetTableOptionStruct(table);
|
PTOS options= GetTableOptionStruct();
|
||||||
|
|
||||||
if (!options)
|
if (!options)
|
||||||
return true;
|
return true;
|
||||||
@ -854,7 +899,7 @@ int ha_connect::GetIntegerOption(char *opname)
|
|||||||
{
|
{
|
||||||
ulonglong opval= NO_IVAL;
|
ulonglong opval= NO_IVAL;
|
||||||
char *pv;
|
char *pv;
|
||||||
PTOS options= GetTableOptionStruct(table);
|
PTOS options= GetTableOptionStruct();
|
||||||
|
|
||||||
if (!options)
|
if (!options)
|
||||||
;
|
;
|
||||||
@ -891,7 +936,7 @@ int ha_connect::GetIntegerOption(char *opname)
|
|||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
bool ha_connect::SetIntegerOption(char *opname, int n)
|
bool ha_connect::SetIntegerOption(char *opname, int n)
|
||||||
{
|
{
|
||||||
PTOS options= GetTableOptionStruct(table);
|
PTOS options= GetTableOptionStruct();
|
||||||
|
|
||||||
if (!options)
|
if (!options)
|
||||||
return true;
|
return true;
|
||||||
@ -1153,7 +1198,7 @@ const char *ha_connect::GetDBName(const char* name)
|
|||||||
|
|
||||||
const char *ha_connect::GetTableName(void)
|
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
|
} // end of GetTableName
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -2404,7 +2449,7 @@ int ha_connect::index_init(uint idx, bool sorted)
|
|||||||
} // endif index type
|
} // endif index type
|
||||||
|
|
||||||
if ((rc= rnd_init(0)))
|
if ((rc= rnd_init(0)))
|
||||||
return rc;
|
DBUG_RETURN(rc);
|
||||||
|
|
||||||
if (locked == 2) {
|
if (locked == 2) {
|
||||||
// Indexes are not updated in lock write mode
|
// 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;
|
int rc= 0;
|
||||||
bool xcheck=false, cras= false;
|
bool xcheck=false, cras= false;
|
||||||
MODE newmode;
|
MODE newmode;
|
||||||
PTOS options= GetTableOptionStruct(table);
|
PTOS options= GetTableOptionStruct();
|
||||||
PGLOBAL g= GetPlug(thd, xp);
|
PGLOBAL g= GetPlug(thd, xp);
|
||||||
DBUG_ENTER("ha_connect::external_lock");
|
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");
|
DBUG_ENTER("ha_connect::records_in_range");
|
||||||
|
|
||||||
if (indexing < 0 || inx != active_index)
|
if (indexing < 0 || inx != active_index)
|
||||||
index_init(inx, false);
|
if (index_init(inx, false))
|
||||||
|
DBUG_RETURN(HA_POS_ERROR);
|
||||||
|
|
||||||
if (xtrace)
|
if (xtrace)
|
||||||
htrc("records_in_range: inx=%d indexing=%d\n", inx, indexing);
|
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) {
|
if (!qrp) {
|
||||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
return HA_ERR_INTERNAL_ERROR;
|
return HA_ERR_INTERNAL_ERROR;
|
||||||
} // endif qrp
|
} // endif !qrp
|
||||||
|
|
||||||
if (fnc != FNC_NO || src || ttp == TAB_PIVOT) {
|
if (fnc != FNC_NO || src || ttp == TAB_PIVOT) {
|
||||||
// Catalog like table
|
// Catalog like table
|
||||||
@ -4384,7 +4430,18 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
|
|
||||||
} // endfor crp
|
} // 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++) {
|
for (i= 0; !rc && i < qrp->Nblin; i++) {
|
||||||
typ= len= prec= dec= 0;
|
typ= len= prec= dec= 0;
|
||||||
tm= NOT_NULL_FLAG;
|
tm= NOT_NULL_FLAG;
|
||||||
@ -4477,6 +4534,8 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
rc= HA_ERR_OUT_OF_MEM;
|
rc= HA_ERR_OUT_OF_MEM;
|
||||||
} // endfor i
|
} // endfor i
|
||||||
|
|
||||||
|
} // endif fnc
|
||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rc= init_table_share(thd, table_s, create_info, &sql);
|
rc= init_table_share(thd, table_s, create_info, &sql);
|
||||||
// rc= init_table_share(thd, table_s, create_info, dsn, &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");
|
DBUG_ENTER("ha_connect::create");
|
||||||
int sqlcom= thd_sql_command(table_arg->in_use);
|
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
|
table= table_arg; // Used by called functions
|
||||||
|
|
||||||
@ -4885,7 +4944,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
|||||||
} else
|
} else
|
||||||
::close(h);
|
::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,
|
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
|
||||||
"Congratulation, you just created a read-only void table!");
|
"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
|
// Get the index definitions
|
||||||
if (xdp= GetIndexInfo()) {
|
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);
|
PDBUSER dup= PlgGetUser(g);
|
||||||
PCATLG cat= (dup) ? dup->Catalog : NULL;
|
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);
|
int sqlcom= thd_sql_command(thd);
|
||||||
TABTYPE newtyp, type= TAB_UNDEF;
|
TABTYPE newtyp, type= TAB_UNDEF;
|
||||||
HA_CREATE_INFO *create_info= ha_alter_info->create_info;
|
HA_CREATE_INFO *create_info= ha_alter_info->create_info;
|
||||||
//PTOS pos= GetTableOptionStruct(table);
|
|
||||||
PTOS newopt, oldopt;
|
PTOS newopt, oldopt;
|
||||||
xp= GetUser(thd, xp);
|
xp= GetUser(thd, xp);
|
||||||
PGLOBAL g= xp->g;
|
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 ||
|
if (ha_alter_info->handler_flags & index_operations ||
|
||||||
!SameString(altered_table, "optname") ||
|
!SameString(altered_table, "optname") ||
|
||||||
!SameBool(altered_table, "sepindex")) {
|
!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;
|
g->Xchk= new(g) XCHK;
|
||||||
PCHK xcp= (PCHK)g->Xchk;
|
PCHK xcp= (PCHK)g->Xchk;
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ public:
|
|||||||
static bool connect_end(void);
|
static bool connect_end(void);
|
||||||
TABTYPE GetRealType(PTOS pos= NULL);
|
TABTYPE GetRealType(PTOS pos= NULL);
|
||||||
char *GetStringOption(char *opname, char *sdef= 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 GetBooleanOption(char *opname, bool bdef);
|
||||||
bool SetBooleanOption(char *opname, bool b);
|
bool SetBooleanOption(char *opname, bool b);
|
||||||
int GetIntegerOption(char *opname);
|
int GetIntegerOption(char *opname);
|
||||||
@ -210,7 +210,7 @@ public:
|
|||||||
The name of the index type that will be used for display.
|
The name of the index type that will be used for display.
|
||||||
Don't implement this method unless you really have indexes.
|
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
|
/** @brief
|
||||||
The file extensions.
|
The file extensions.
|
||||||
@ -241,11 +241,7 @@ public:
|
|||||||
If all_parts is set, MySQL wants to know the flags for the combined
|
If all_parts is set, MySQL wants to know the flags for the combined
|
||||||
index, up to and including 'part'.
|
index, up to and including 'part'.
|
||||||
*/
|
*/
|
||||||
ulong index_flags(uint inx, uint part, bool all_parts) const
|
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
|
|
||||||
|
|
||||||
/** @brief
|
/** @brief
|
||||||
unireg.cc will call max_supported_record_length(), max_supported_keys(),
|
unireg.cc will call max_supported_record_length(), max_supported_keys(),
|
||||||
|
@ -80,7 +80,16 @@ HANDLE CreateFileMap(PGLOBAL g, LPCSTR filename,
|
|||||||
} // endif hFileMap
|
} // endif hFileMap
|
||||||
|
|
||||||
access = (mode == MODE_READ) ? FILE_MAP_READ : FILE_MAP_WRITE;
|
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
|
// lenH is the high-order word of the file size
|
||||||
mm->lenL = GetFileSize(hFile, &mm->lenH);
|
mm->lenL = GetFileSize(hFile, &mm->lenH);
|
||||||
CloseHandle(hFileMap); // Not used anymore
|
CloseHandle(hFileMap); // Not used anymore
|
||||||
|
@ -31,6 +31,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
#include "my_global.h"
|
#include "my_global.h"
|
||||||
|
#if !defined(MYSQL_PREPARED_STATEMENTS)
|
||||||
|
#include "my_sys.h"
|
||||||
|
#include "mysqld_error.h"
|
||||||
|
#endif // !MYSQL_PREPARED_STATEMENTS
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
//#include <windows.h>
|
//#include <windows.h>
|
||||||
#else // !WIN32
|
#else // !WIN32
|
||||||
@ -59,6 +63,59 @@ uint GetDefaultPort(void)
|
|||||||
return mysqld_port;
|
return mysqld_port;
|
||||||
} // end of GetDefaultPort
|
} // 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 */
|
/* MyColumns: constructs the result blocks containing all columns */
|
||||||
/* of a MySQL table or view. */
|
/* of a MySQL table or view. */
|
||||||
@ -339,6 +396,7 @@ MYSQLC::MYSQLC(void)
|
|||||||
m_Row = NULL;
|
m_Row = NULL;
|
||||||
m_Fields = -1;
|
m_Fields = -1;
|
||||||
N = 0;
|
N = 0;
|
||||||
|
m_Use = false;
|
||||||
} // end of MYSQLC constructor
|
} // end of MYSQLC constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -600,7 +658,16 @@ int MYSQLC::ExecSQL(PGLOBAL g, const char *query, int *w)
|
|||||||
rc = RC_FX;
|
rc = RC_FX;
|
||||||
//} else if (mysql_field_count(m_DB) > 0) {
|
//} else if (mysql_field_count(m_DB) > 0) {
|
||||||
} else if (m_DB->field_count > 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));
|
char *msg = (char*)PlugSubAlloc(g, NULL, 512 + strlen(query));
|
||||||
|
|
||||||
sprintf(msg, "mysql_store_result failed: %s", mysql_error(m_DB));
|
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;
|
rc = RC_FX;
|
||||||
} else {
|
} else {
|
||||||
m_Fields = mysql_num_fields(m_Res);
|
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
|
} // endif m_Res
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,5 +96,6 @@ class DllItem MYSQLC {
|
|||||||
int N;
|
int N;
|
||||||
int m_Fields; // The number of result fields
|
int m_Fields; // The number of result fields
|
||||||
int m_Afrw; // The number of affected rows
|
int m_Afrw; // The number of affected rows
|
||||||
|
bool m_Use; // Use or store result set
|
||||||
}; // end of class MYSQLC
|
}; // 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";
|
PSZ fnc = "Unknown";
|
||||||
UWORD n;
|
UWORD n;
|
||||||
SWORD ncol, len, tp;
|
SWORD ncol, len, tp;
|
||||||
SQLULEN crow;
|
SQLULEN crow = 0;
|
||||||
PQRYRES qrp = cap->Qrp;
|
PQRYRES qrp = cap->Qrp;
|
||||||
PCOLRES crp;
|
PCOLRES crp;
|
||||||
RETCODE rc = 0;
|
RETCODE rc = 0;
|
||||||
@ -2287,6 +2287,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
|
|||||||
|
|
||||||
} // endfor i
|
} // endfor i
|
||||||
|
|
||||||
|
#if 0
|
||||||
if ((crow = i) && (rc == SQL_NO_DATA || rc == SQL_SUCCESS_WITH_INFO))
|
if ((crow = i) && (rc == SQL_NO_DATA || rc == SQL_SUCCESS_WITH_INFO))
|
||||||
rc = SQL_SUCCESS;
|
rc = SQL_SUCCESS;
|
||||||
|
|
||||||
@ -2303,6 +2304,15 @@ int ODBConn::GetCatInfo(CATPARM *cap)
|
|||||||
|
|
||||||
} else
|
} else
|
||||||
ThrowDBX(rc, fnc, hstmt);
|
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;
|
irc = (int)crow;
|
||||||
} catch(DBX *x) {
|
} catch(DBX *x) {
|
||||||
|
@ -49,7 +49,8 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
|
|||||||
int GetEnding(void) {return Ending;}
|
int GetEnding(void) {return Ending;}
|
||||||
|
|
||||||
// Methods
|
// 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 DeleteIndexFile(PGLOBAL g, PIXDEF pxdf);
|
||||||
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
||||||
virtual PTDB GetTable(PGLOBAL g, MODE mode);
|
virtual PTDB GetTable(PGLOBAL g, MODE mode);
|
||||||
|
@ -304,15 +304,22 @@ int TDBASE::ResetTableOpt(PGLOBAL g, bool dox)
|
|||||||
} // end of ResetTableOpt
|
} // 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
|
To_Kindex->Close(); // Discard old index
|
||||||
|
SetRecpos(g, pos); // Ignore return value
|
||||||
|
} // endif To_Kindex
|
||||||
|
|
||||||
To_Kindex = kxp;
|
To_Kindex = kxp;
|
||||||
} // end of SetKindex
|
} // end of ResetKindex
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* SetRecpos: Replace the table at the specified position. */
|
/* SetRecpos: Replace the table at the specified position. */
|
||||||
|
@ -84,10 +84,11 @@ MYSQLDEF::MYSQLDEF(void)
|
|||||||
Username = NULL;
|
Username = NULL;
|
||||||
Password = NULL;
|
Password = NULL;
|
||||||
Portnumber = 0;
|
Portnumber = 0;
|
||||||
Isview = FALSE;
|
Isview = false;
|
||||||
Bind = FALSE;
|
Bind = false;
|
||||||
Delayed = FALSE;
|
Delayed = false;
|
||||||
Xsrc = FALSE;
|
Xsrc = false;
|
||||||
|
Huge = false;
|
||||||
} // end of MYSQLDEF constructor
|
} // end of MYSQLDEF constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -329,7 +330,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
} else {
|
} else {
|
||||||
// MYSQL access from a PROXY table
|
// MYSQL access from a PROXY table
|
||||||
Database = GetStringCatInfo(g, "Database", "*");
|
Database = GetStringCatInfo(g, "Database", "*");
|
||||||
Isview = GetBoolCatInfo("View", FALSE);
|
Isview = GetBoolCatInfo("View", false);
|
||||||
|
|
||||||
// We must get other connection parms from the calling table
|
// We must get other connection parms from the calling table
|
||||||
Remove_tshp(Cat);
|
Remove_tshp(Cat);
|
||||||
@ -363,7 +364,8 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
// Specific for command executing tables
|
// Specific for command executing tables
|
||||||
Xsrc = GetBoolCatInfo("Execsrc", false);
|
Xsrc = GetBoolCatInfo("Execsrc", false);
|
||||||
Mxr = GetIntCatInfo("Maxerr", 0);
|
Mxr = GetIntCatInfo("Maxerr", 0);
|
||||||
return FALSE;
|
Huge = GetBoolCatInfo("Huge", false);
|
||||||
|
return false;
|
||||||
} // end of DefineAM
|
} // end of DefineAM
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -401,6 +403,7 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
|
|||||||
Isview = tdp->Isview;
|
Isview = tdp->Isview;
|
||||||
Prep = tdp->Bind;
|
Prep = tdp->Bind;
|
||||||
Delayed = tdp->Delayed;
|
Delayed = tdp->Delayed;
|
||||||
|
Myc.m_Use = tdp->Huge;
|
||||||
} else {
|
} else {
|
||||||
Host = NULL;
|
Host = NULL;
|
||||||
Database = NULL;
|
Database = NULL;
|
||||||
@ -412,15 +415,15 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
|
|||||||
Qrystr = NULL;
|
Qrystr = NULL;
|
||||||
Quoted = 0;
|
Quoted = 0;
|
||||||
Port = 0;
|
Port = 0;
|
||||||
Isview = FALSE;
|
Isview = false;
|
||||||
Prep = FALSE;
|
Prep = false;
|
||||||
Delayed = FALSE;
|
Delayed = false;
|
||||||
} // endif tdp
|
} // endif tdp
|
||||||
|
|
||||||
Bind = NULL;
|
Bind = NULL;
|
||||||
Query = NULL;
|
Query = NULL;
|
||||||
Qbuf = NULL;
|
Qbuf = NULL;
|
||||||
Fetched = FALSE;
|
Fetched = false;
|
||||||
m_Rc = RC_FX;
|
m_Rc = RC_FX;
|
||||||
AftRows = 0;
|
AftRows = 0;
|
||||||
N = -1;
|
N = -1;
|
||||||
@ -555,17 +558,17 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
|
|||||||
char *colist, *valist = NULL;
|
char *colist, *valist = NULL;
|
||||||
char *tk = "`";
|
char *tk = "`";
|
||||||
int len = 0, qlen = 0;
|
int len = 0, qlen = 0;
|
||||||
bool b = FALSE;
|
bool b = false;
|
||||||
PCOL colp;
|
PCOL colp;
|
||||||
|
|
||||||
if (Query)
|
if (Query)
|
||||||
return FALSE; // already done
|
return false; // already done
|
||||||
|
|
||||||
for (colp = Columns; colp; colp = colp->GetNext())
|
for (colp = Columns; colp; colp = colp->GetNext())
|
||||||
if (!colp->IsSpecial()) {
|
if (!colp->IsSpecial()) {
|
||||||
// if (colp->IsSpecial()) {
|
// if (colp->IsSpecial()) {
|
||||||
// strcpy(g->Message, MSG(NO_SPEC_COL));
|
// strcpy(g->Message, MSG(NO_SPEC_COL));
|
||||||
// return TRUE;
|
// return true;
|
||||||
// } else {
|
// } else {
|
||||||
len += (strlen(colp->GetName()) + 4);
|
len += (strlen(colp->GetName()) + 4);
|
||||||
((PMYCOL)colp)->Rank = Nparm++;
|
((PMYCOL)colp)->Rank = Nparm++;
|
||||||
@ -581,7 +584,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
|
|||||||
#else // !MYSQL_PREPARED_STATEMENTS
|
#else // !MYSQL_PREPARED_STATEMENTS
|
||||||
strcpy(g->Message, "Prepared statements not used (not supported)");
|
strcpy(g->Message, "Prepared statements not used (not supported)");
|
||||||
PushWarning(g, this);
|
PushWarning(g, this);
|
||||||
Prep = FALSE;
|
Prep = false;
|
||||||
#endif // !MYSQL_PREPARED_STATEMENTS
|
#endif // !MYSQL_PREPARED_STATEMENTS
|
||||||
} // endif Prep
|
} // endif Prep
|
||||||
|
|
||||||
@ -590,7 +593,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
|
|||||||
strcat(colist, ", ");
|
strcat(colist, ", ");
|
||||||
if (Prep) strcat(valist, ",");
|
if (Prep) strcat(valist, ",");
|
||||||
} else
|
} else
|
||||||
b = TRUE;
|
b = true;
|
||||||
|
|
||||||
strcat(strcat(strcat(colist, tk), colp->GetName()), tk);
|
strcat(strcat(strcat(colist, tk), colp->GetName()), tk);
|
||||||
|
|
||||||
@ -628,7 +631,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
|
|||||||
Qbuf = (char *)PlugSubAlloc(g, NULL, qlen);
|
Qbuf = (char *)PlugSubAlloc(g, NULL, qlen);
|
||||||
} // endelse Prep
|
} // endelse Prep
|
||||||
|
|
||||||
return FALSE;
|
return false;
|
||||||
} // end of MakeInsert
|
} // end of MakeInsert
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -906,9 +909,9 @@ bool TDBMYSQL::SetColumnRanks(PGLOBAL g)
|
|||||||
{
|
{
|
||||||
for (PCOL colp = Columns; colp; colp = colp->GetNext())
|
for (PCOL colp = Columns; colp; colp = colp->GetNext())
|
||||||
if (((PMYCOL)colp)->FindRank(g))
|
if (((PMYCOL)colp)->FindRank(g))
|
||||||
return TRUE;
|
return true;
|
||||||
|
|
||||||
return FALSE;
|
return false;
|
||||||
} // end of SetColumnRanks
|
} // end of SetColumnRanks
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -1233,7 +1236,7 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
|||||||
{
|
{
|
||||||
if (!(To_Val = value)) {
|
if (!(To_Val = value)) {
|
||||||
sprintf(g->Message, MSG(VALUE_ERROR), Name);
|
sprintf(g->Message, MSG(VALUE_ERROR), Name);
|
||||||
return TRUE;
|
return true;
|
||||||
} else if (Buf_Type == value->GetType()) {
|
} else if (Buf_Type == value->GetType()) {
|
||||||
// Values are of the (good) column type
|
// Values are of the (good) column type
|
||||||
if (Buf_Type == TYPE_DATE) {
|
if (Buf_Type == TYPE_DATE) {
|
||||||
@ -1253,12 +1256,12 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
|||||||
if (check) {
|
if (check) {
|
||||||
sprintf(g->Message, MSG(TYPE_VALUE_ERR), Name,
|
sprintf(g->Message, MSG(TYPE_VALUE_ERR), Name,
|
||||||
GetTypeName(Buf_Type), GetTypeName(value->GetType()));
|
GetTypeName(Buf_Type), GetTypeName(value->GetType()));
|
||||||
return TRUE;
|
return true;
|
||||||
} // endif check
|
} // endif check
|
||||||
|
|
||||||
newval:
|
newval:
|
||||||
if (InitValue(g)) // Allocate the matching value block
|
if (InitValue(g)) // Allocate the matching value block
|
||||||
return TRUE;
|
return true;
|
||||||
|
|
||||||
} // endif's Value, Buf_Type
|
} // endif's Value, Buf_Type
|
||||||
|
|
||||||
@ -1269,7 +1272,7 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
|||||||
|
|
||||||
// Set the Column
|
// Set the Column
|
||||||
Status = (ok) ? BUF_EMPTY : BUF_NO;
|
Status = (ok) ? BUF_EMPTY : BUF_NO;
|
||||||
return FALSE;
|
return false;
|
||||||
} // end of SetBuffer
|
} // end of SetBuffer
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -1317,7 +1320,7 @@ void MYSQLCOL::ReadColumn(PGLOBAL g)
|
|||||||
|
|
||||||
longjmp(g->jumper[g->jump_level], 11);
|
longjmp(g->jumper[g->jump_level], 11);
|
||||||
} else
|
} else
|
||||||
tdbp->Fetched = TRUE;
|
tdbp->Fetched = true;
|
||||||
|
|
||||||
if ((buf = ((PTDBMY)To_Tdb)->Myc.GetCharField(Rank))) {
|
if ((buf = ((PTDBMY)To_Tdb)->Myc.GetCharField(Rank))) {
|
||||||
if (trace > 1)
|
if (trace > 1)
|
||||||
@ -1354,7 +1357,7 @@ void MYSQLCOL::WriteColumn(PGLOBAL g)
|
|||||||
/* Do convert the column value if necessary. */
|
/* Do convert the column value if necessary. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
if (Value != To_Val)
|
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 defined(MYSQL_PREPARED_STATEMENTS)
|
||||||
if (((PTDBMY)To_Tdb)->Prep) {
|
if (((PTDBMY)To_Tdb)->Prep) {
|
||||||
|
@ -58,10 +58,11 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
|
|||||||
int Portnumber; /* MySQL port number (0 = default) */
|
int Portnumber; /* MySQL port number (0 = default) */
|
||||||
int Mxr; /* Maxerr for an Exec table */
|
int Mxr; /* Maxerr for an Exec table */
|
||||||
int Quoted; /* Identifier quoting level */
|
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 Bind; /* Use prepared statement on insert */
|
||||||
bool Delayed; /* Delayed insert */
|
bool Delayed; /* Delayed insert */
|
||||||
bool Xsrc; /* Execution type */
|
bool Xsrc; /* Execution type */
|
||||||
|
bool Huge; /* True for big table */
|
||||||
}; // end of MYSQLDEF
|
}; // end of MYSQLDEF
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -84,7 +85,7 @@ class TDBMYSQL : public TDBASE {
|
|||||||
virtual int GetRecpos(void) {return N;}
|
virtual int GetRecpos(void) {return N;}
|
||||||
virtual int GetProgMax(PGLOBAL g);
|
virtual int GetProgMax(PGLOBAL g);
|
||||||
virtual void ResetDB(void) {N = 0;}
|
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 bool IsView(void) {return Isview;}
|
||||||
virtual PSZ GetServer(void) {return Server;}
|
virtual PSZ GetServer(void) {return Server;}
|
||||||
void SetDatabase(LPCSTR db) {Database = (char*)db;}
|
void SetDatabase(LPCSTR db) {Database = (char*)db;}
|
||||||
|
@ -145,7 +145,7 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
XmlDB = GetStringCatInfo(g, "XmlDB", "");
|
XmlDB = GetStringCatInfo(g, "XmlDB", "");
|
||||||
Nslist = GetStringCatInfo(g, "Nslist", "");
|
Nslist = GetStringCatInfo(g, "Nslist", "");
|
||||||
DefNs = GetStringCatInfo(g, "DefNs", "");
|
DefNs = GetStringCatInfo(g, "DefNs", "");
|
||||||
Limit = GetIntCatInfo("Limit", 2);
|
Limit = GetIntCatInfo("Limit", 10);
|
||||||
Xpand = (GetIntCatInfo("Expand", 0) != 0);
|
Xpand = (GetIntCatInfo("Expand", 0) != 0);
|
||||||
Header = GetIntCatInfo("Header", 0);
|
Header = GetIntCatInfo("Header", 0);
|
||||||
GetCharCatInfo("Xmlsup", "*", buf, sizeof(buf));
|
GetCharCatInfo("Xmlsup", "*", buf, sizeof(buf));
|
||||||
@ -1038,12 +1038,13 @@ XMLCOL::XMLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
|
|||||||
Type = Tdbp->Coltype;
|
Type = Tdbp->Coltype;
|
||||||
Nx = -1;
|
Nx = -1;
|
||||||
Sx = -1;
|
Sx = -1;
|
||||||
|
N = 0;
|
||||||
Valbuf = NULL;
|
Valbuf = NULL;
|
||||||
To_Val = NULL;
|
To_Val = NULL;
|
||||||
} // end of XMLCOL constructor
|
} // 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. */
|
/* tdbp is the pointer to the new table descriptor. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
XMLCOL::XMLCOL(XMLCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
|
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;
|
Rank = col1->Rank;
|
||||||
Nx = col1->Nx;
|
Nx = col1->Nx;
|
||||||
Sx = col1->Sx;
|
Sx = col1->Sx;
|
||||||
|
N = col1->N;
|
||||||
Type = col1->Type;
|
Type = col1->Type;
|
||||||
To_Val = col1->To_Val;
|
To_Val = col1->To_Val;
|
||||||
} // end of XMLCOL copy constructor
|
} // end of XMLCOL copy constructor
|
||||||
@ -1080,8 +1082,8 @@ bool XMLCOL::AllocBuf(PGLOBAL g, bool mode)
|
|||||||
if (Valbuf)
|
if (Valbuf)
|
||||||
return false; // Already done
|
return false; // Already done
|
||||||
|
|
||||||
Valbuf = (char*)PlugSubAlloc(g, NULL, Long + 1);
|
//Valbuf = (char*)PlugSubAlloc(g, NULL, Long + 1);
|
||||||
Valbuf[Long] = '\0';
|
//Valbuf[Long] = '\0';
|
||||||
return ParseXpath(g, mode);
|
return ParseXpath(g, mode);
|
||||||
} // end of AllocBuf
|
} // end of AllocBuf
|
||||||
|
|
||||||
@ -1095,7 +1097,7 @@ bool XMLCOL::AllocBuf(PGLOBAL g, bool mode)
|
|||||||
bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
|
bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
|
||||||
{
|
{
|
||||||
char *p, *p2, *pbuf = NULL;
|
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 += ((Tdbp->Colname) ? strlen(Tdbp->Colname) : 0);
|
||||||
len += ((Xname) ? strlen(Xname) : 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
|
// For Update or Insert the Xpath must be analyzed
|
||||||
if (mode) {
|
if (mode) {
|
||||||
for (i = 0, p = pbuf; (p = strchr(p, '/')); i++, p++)
|
for (i = 0, p = pbuf; (p = strchr(p, '/')); i++, p++)
|
||||||
Nod++; // One path node found
|
Nod++; // One path node found
|
||||||
|
|
||||||
if (Nod)
|
if (Nod)
|
||||||
Nodes = (char**)PlugSubAlloc(g, NULL, Nod * sizeof(char*));
|
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));
|
strcpy(g->Message, MSG(CONCAT_SUBNODE));
|
||||||
return true;
|
return true;
|
||||||
} else
|
} else
|
||||||
Inod = i; // Index of multiple node
|
Inod = i; // Index of multiple node
|
||||||
|
|
||||||
if (mode) {
|
if (mode) {
|
||||||
// For Update or Insert the Xpath must be explicit
|
// For Update or Insert the Xpath must be explicit
|
||||||
@ -1171,7 +1173,7 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
|
|||||||
|
|
||||||
} else if (Type == 2) {
|
} else if (Type == 2) {
|
||||||
// HTML like table, columns are retrieved by position
|
// 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;
|
Tdbp->Hasnod = true;
|
||||||
return false;
|
return false;
|
||||||
} else if (Type == 0 && !mode) {
|
} else if (Type == 0 && !mode) {
|
||||||
@ -1185,9 +1187,18 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
|
|||||||
|
|
||||||
if (Inod >= 0) {
|
if (Inod >= 0) {
|
||||||
Tdbp->Colp = this; // To force expand
|
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
|
} // 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)
|
if (Type || Nod)
|
||||||
Tdbp->Hasnod = true;
|
Tdbp->Hasnod = true;
|
||||||
|
|
||||||
@ -1470,60 +1481,72 @@ void XMLCOL::WriteColumn(PGLOBAL g)
|
|||||||
void XMULCOL::ReadColumn(PGLOBAL g)
|
void XMULCOL::ReadColumn(PGLOBAL g)
|
||||||
{
|
{
|
||||||
char *p;
|
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);
|
Nl = Tdbp->RowNode->SelectNodes(g, Xname, Nl);
|
||||||
else if (Sx == Tdbp->Nsub)
|
|
||||||
return; // Same row
|
|
||||||
|
|
||||||
if ((n = Nl->GetLength())) {
|
if ((N = Nl->GetLength())) {
|
||||||
*(p = Valbuf) = '\0';
|
*(p = Valbuf) = '\0';
|
||||||
len = Long;
|
len = Long;
|
||||||
|
|
||||||
for (i = Tdbp->Nsub; i < n; i++) {
|
if (N > Tdbp->Limit) {
|
||||||
ValNode = Nl->GetItem(g, i, Vxnp);
|
N = Tdbp->Limit;
|
||||||
|
sprintf(g->Message, "Mutiple values limited to %d", Tdbp->Limit);
|
||||||
|
PushWarning(g, Tdbp);
|
||||||
|
} // endif N
|
||||||
|
|
||||||
if (ValNode->GetType() != XML_ELEMENT_NODE &&
|
for (i = 0; i < N; i++) {
|
||||||
ValNode->GetType() != XML_ATTRIBUTE_NODE) {
|
ValNode = Nl->GetItem(g, i, Vxnp);
|
||||||
sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name);
|
|
||||||
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
|
||||||
} // endif type
|
|
||||||
|
|
||||||
// Get the Xname value from the XML file
|
if (ValNode->GetType() != XML_ELEMENT_NODE &&
|
||||||
switch (ValNode->GetContent(g, p, len + 1)) {
|
ValNode->GetType() != XML_ATTRIBUTE_NODE) {
|
||||||
case RC_OK:
|
sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name);
|
||||||
break;
|
|
||||||
case RC_INFO:
|
|
||||||
PushWarning(g, Tdbp);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
||||||
} // endswitch
|
} // endif type
|
||||||
|
|
||||||
if (!Tdbp->Xpand) {
|
// Get the Xname value from the XML file
|
||||||
// Concatenate all values
|
switch (ValNode->GetContent(g, p, (b ? Long : len))) {
|
||||||
if (n - i > 1)
|
case RC_OK:
|
||||||
strncat(Valbuf, ", ", Long + 1);
|
break;
|
||||||
|
case RC_INFO:
|
||||||
|
PushWarning(g, Tdbp);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
||||||
|
} // endswitch
|
||||||
|
|
||||||
len -= strlen(p);
|
if (!b) {
|
||||||
p += strlen(p);
|
// Concatenate all values
|
||||||
} else
|
if (N - i > 1)
|
||||||
break;
|
strncat(Valbuf, ", ", len - strlen(p));
|
||||||
|
|
||||||
} // endfor i
|
if ((len -= strlen(p)) <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
Value->SetValue_psz(Valbuf);
|
p += strlen(p);
|
||||||
} else {
|
} else // Xpand
|
||||||
if (Nullable)
|
p += (Long + 1);
|
||||||
Value->SetNull(true);
|
|
||||||
|
|
||||||
Value->Reset(); // Null value
|
} // endfor i
|
||||||
} // endif ValNode
|
|
||||||
|
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;
|
Nx = Tdbp->Irow;
|
||||||
Sx = Tdbp->Nsub;
|
Sx = Tdbp->Nsub;
|
||||||
Tdbp->NextSame = (Tdbp->Xpand && Nl->GetLength() - Sx > 1);
|
Tdbp->NextSame = (Tdbp->Xpand && N - Sx > 1);
|
||||||
} // end of ReadColumn
|
} // end of ReadColumn
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@ -190,6 +190,7 @@ class XMLCOL : public COLBLK {
|
|||||||
int Long; // Buffer length
|
int Long; // Buffer length
|
||||||
int Nx; // The last read row
|
int Nx; // The last read row
|
||||||
int Sx; // The last read sub-row
|
int Sx; // The last read sub-row
|
||||||
|
int N; // The number of (multiple) values
|
||||||
PVAL To_Val; // To value used for Update/Insert
|
PVAL To_Val; // To value used for Update/Insert
|
||||||
}; // end of class XMLCOL
|
}; // end of class XMLCOL
|
||||||
|
|
||||||
|
@ -2131,9 +2131,6 @@ int XINDXS::FastFind(int nk)
|
|||||||
XLOAD::XLOAD(void)
|
XLOAD::XLOAD(void)
|
||||||
{
|
{
|
||||||
Hfile = INVALID_HANDLE_VALUE;
|
Hfile = INVALID_HANDLE_VALUE;
|
||||||
#if defined(WIN32) && defined(XMAP)
|
|
||||||
ViewBase = NULL;
|
|
||||||
#endif // WIN32 && XMAP
|
|
||||||
NewOff.Val = 0LL;
|
NewOff.Val = 0LL;
|
||||||
} // end of XLOAD constructor
|
} // end of XLOAD constructor
|
||||||
|
|
||||||
@ -2147,15 +2144,6 @@ void XLOAD::Close(void)
|
|||||||
Hfile = INVALID_HANDLE_VALUE;
|
Hfile = INVALID_HANDLE_VALUE;
|
||||||
} // endif Hfile
|
} // 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
|
} // end of Close
|
||||||
|
|
||||||
/* --------------------------- XFILE Class --------------------------- */
|
/* --------------------------- XFILE Class --------------------------- */
|
||||||
@ -2166,9 +2154,9 @@ void XLOAD::Close(void)
|
|||||||
XFILE::XFILE(void) : XLOAD()
|
XFILE::XFILE(void) : XLOAD()
|
||||||
{
|
{
|
||||||
Xfile = NULL;
|
Xfile = NULL;
|
||||||
#if defined(XMAP) && !defined(WIN32)
|
#if defined(XMAP)
|
||||||
Mmp = NULL;
|
Mmp = NULL;
|
||||||
#endif // XMAP && !WIN32
|
#endif // XMAP
|
||||||
} // end of XFILE constructor
|
} // end of XFILE constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -2193,9 +2181,9 @@ bool XFILE::Open(PGLOBAL g, char *filename, int id, MODE mode)
|
|||||||
} // endswitch mode
|
} // endswitch mode
|
||||||
|
|
||||||
if (!(Xfile= global_fopen(g, MSGID_OPEN_ERROR_AND_STRERROR, filename, pmod))) {
|
if (!(Xfile= global_fopen(g, MSGID_OPEN_ERROR_AND_STRERROR, filename, pmod))) {
|
||||||
#if defined(TRACE)
|
if (trace)
|
||||||
printf("Open: %s\n", g->Message);
|
htrc("Open: %s\n", g->Message);
|
||||||
#endif // TRACE
|
|
||||||
return true;
|
return true;
|
||||||
} // endif Xfile
|
} // endif Xfile
|
||||||
|
|
||||||
@ -2311,11 +2299,9 @@ void XFILE::Close(void)
|
|||||||
Xfile = NULL;
|
Xfile = NULL;
|
||||||
} // endif Xfile
|
} // endif Xfile
|
||||||
|
|
||||||
#if defined(XMAP) && !defined(WIN32)
|
#if defined(XMAP)
|
||||||
if (Mmp) {
|
if (Mmp && CloseMemMap(Mmp->memory, Mmp->lenL))
|
||||||
CloseMemMap(Mmp->memory, Mmp->lenL);
|
printf("Error closing mapped index\n");
|
||||||
Mmp = NULL;
|
|
||||||
} // endif Mmp
|
|
||||||
#endif // XMAP
|
#endif // XMAP
|
||||||
} // end of Close
|
} // end of Close
|
||||||
|
|
||||||
@ -2357,9 +2343,8 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
|
|||||||
return true;
|
return true;
|
||||||
} // endif
|
} // endif
|
||||||
|
|
||||||
#if defined(TRACE)
|
if (trace)
|
||||||
printf( "Xopen: filename=%s mode=%d\n", filename, mode);
|
htrc(" Xopen: filename=%s mode=%d\n", filename, mode);
|
||||||
#endif // TRACE
|
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
LONG high = 0;
|
LONG high = 0;
|
||||||
@ -2476,16 +2461,15 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
|
|||||||
|
|
||||||
if (Hfile == INVALID_HANDLE_VALUE) {
|
if (Hfile == INVALID_HANDLE_VALUE) {
|
||||||
/*rc = errno;*/
|
/*rc = errno;*/
|
||||||
#if defined(TRACE)
|
if (trace)
|
||||||
printf("Open: %s\n", g->Message);
|
htrc("Open: %s\n", g->Message);
|
||||||
#endif // TRACE
|
|
||||||
return true;
|
return true;
|
||||||
} // endif Hfile
|
} // endif Hfile
|
||||||
|
|
||||||
#if defined(TRACE)
|
if (trace)
|
||||||
printf(" rc=%d oflag=%p mode=%d handle=%d fn=%s\n",
|
htrc(" oflag=%p mode=%d handle=%d fn=%s\n",
|
||||||
rc, oflag, mode, Hfile, filename);
|
oflag, mode, Hfile, filename);
|
||||||
#endif // TRACE
|
|
||||||
|
|
||||||
if (mode == MODE_INSERT) {
|
if (mode == MODE_INSERT) {
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
@ -2588,15 +2572,15 @@ bool XHUGE::Read(PGLOBAL g, void *buf, int n, int size)
|
|||||||
#else // UNIX
|
#else // UNIX
|
||||||
ssize_t count = (ssize_t)(n * size);
|
ssize_t count = (ssize_t)(n * size);
|
||||||
|
|
||||||
#if defined(TRACE)
|
if (trace)
|
||||||
printf("Hfile=%d n=%d size=%d count=%d\n", Hfile, n, size, count);
|
htrc("Hfile=%d n=%d size=%d count=%d\n", Hfile, n, size, count);
|
||||||
#endif // TRACE
|
|
||||||
|
|
||||||
if (read(Hfile, buf, count) != count) {
|
if (read(Hfile, buf, count) != count) {
|
||||||
sprintf(g->Message, MSG(READ_ERROR), "Index file", strerror(errno));
|
sprintf(g->Message, MSG(READ_ERROR), "Index file", strerror(errno));
|
||||||
#if defined(TRACE)
|
|
||||||
printf("read error %d\n", errno);
|
if (trace)
|
||||||
#endif // TRACE
|
htrc("read error %d\n", errno);
|
||||||
|
|
||||||
rc = true;
|
rc = true;
|
||||||
} // endif nbr
|
} // endif nbr
|
||||||
#endif // UNIX
|
#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
|
// Allocate the Value object used when moving items
|
||||||
Type = colp->GetResultType();
|
Type = colp->GetResultType();
|
||||||
|
|
||||||
if (!(Valp = AllocateValue(g, Type, len, colp->GetScale(),
|
if (!(Valp = AllocateValue(g, Type, len, prec, colp->IsUnsigned())))
|
||||||
colp->IsUnsigned())))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Klen = Valp->GetClen();
|
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
|
// Store this information to avoid sorting when already done
|
||||||
if (Asc)
|
if (Asc)
|
||||||
// IsSorted = colp->GetOpt() < 0;
|
// IsSorted = colp->GetOpt() == 2;
|
||||||
IsSorted = false;
|
IsSorted = false;
|
||||||
|
|
||||||
//SetNulls(colp->IsNullable()); for when null columns will be indexable
|
//SetNulls(colp->IsNullable()); for when null columns will be indexable
|
||||||
|
Colp = colp;
|
||||||
return false;
|
return false;
|
||||||
} // end of Init
|
} // 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)
|
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]
|
if (n[3] && colp->GetLength() > n[3]
|
||||||
&& colp->GetResultType() == TYPE_STRING) {
|
&& 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);
|
this, colp, Type, n[0], len, m);
|
||||||
|
|
||||||
// Allocate the Value object used when moving items
|
// 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();
|
Klen = Valp->GetClen();
|
||||||
|
|
||||||
if (n[2]) {
|
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).
|
// by blanks (if true) or keep the zero ending char (if false).
|
||||||
// Currently we set it to true to be compatible with QRY blocks,
|
// Currently we set it to true to be compatible with QRY blocks,
|
||||||
// and last one to enable type checking (no conversion).
|
// 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]) {
|
if (n[1]) {
|
||||||
Koff.Size = n[1] * sizeof(int);
|
Koff.Size = n[1] * sizeof(int);
|
||||||
@ -2937,6 +2921,7 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
|
|||||||
Ndf = n[0];
|
Ndf = n[0];
|
||||||
//IsSorted = colp->GetOpt() < 0;
|
//IsSorted = colp->GetOpt() < 0;
|
||||||
IsSorted = false;
|
IsSorted = false;
|
||||||
|
Colp = colp;
|
||||||
return m + Bkeys.Size + Keys.Size + Koff.Size;
|
return m + Bkeys.Size + Keys.Size + Koff.Size;
|
||||||
} // end of MapInit
|
} // end of MapInit
|
||||||
#endif // XMAP
|
#endif // XMAP
|
||||||
@ -3054,9 +3039,8 @@ int KXYCOL::Compare(int i1, int i2)
|
|||||||
// Do the actual comparison between values.
|
// Do the actual comparison between values.
|
||||||
register int k = Kblp->CompVal(i1, i2);
|
register int k = Kblp->CompVal(i1, i2);
|
||||||
|
|
||||||
#ifdef DEBUG2
|
if (trace > 2)
|
||||||
htrc("Compare done result=%d\n", k);
|
htrc("Compare done result=%d\n", k);
|
||||||
#endif
|
|
||||||
|
|
||||||
return (Asc) ? k : -k;
|
return (Asc) ? k : -k;
|
||||||
} // end of Compare
|
} // end of Compare
|
||||||
@ -3067,13 +3051,14 @@ int KXYCOL::Compare(int i1, int i2)
|
|||||||
int KXYCOL::CompVal(int i)
|
int KXYCOL::CompVal(int i)
|
||||||
{
|
{
|
||||||
// Do the actual comparison between numerical values.
|
// Do the actual comparison between numerical values.
|
||||||
#ifdef DEBUG2
|
if (trace > 2) {
|
||||||
register int k = (int)Kblp->CompVal(Valp, (int)i);
|
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
|
} // end of CompVal
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@ -339,9 +339,6 @@ class DllExport XLOAD : public BLOCK {
|
|||||||
// Members
|
// Members
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
HANDLE Hfile; // Handle to file or map
|
HANDLE Hfile; // Handle to file or map
|
||||||
#if defined(XMAP)
|
|
||||||
void *ViewBase; // Mapped view base address
|
|
||||||
#endif // XMAP
|
|
||||||
#else // UNIX
|
#else // UNIX
|
||||||
int Hfile; // Descriptor to file or map
|
int Hfile; // Descriptor to file or map
|
||||||
#endif // UNIX
|
#endif // UNIX
|
||||||
@ -369,9 +366,9 @@ class DllExport XFILE : public XLOAD {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Members
|
// Members
|
||||||
FILE *Xfile; // Index stream file
|
FILE *Xfile; // Index stream file
|
||||||
#if defined(XMAP)
|
#if defined(XMAP)
|
||||||
MMP Mmp; // To mapped index file
|
MMP Mmp; // Mapped view base address and length
|
||||||
#endif // XMAP
|
#endif // XMAP
|
||||||
}; // end of class XFILE
|
}; // end of class XFILE
|
||||||
|
|
||||||
|
@ -142,9 +142,10 @@ class DllExport TDBASE : public TDB {
|
|||||||
inline PKXBASE GetKindex(void) {return To_Kindex;}
|
inline PKXBASE GetKindex(void) {return To_Kindex;}
|
||||||
inline PCOL GetSetCols(void) {return To_SetCols;}
|
inline PCOL GetSetCols(void) {return To_SetCols;}
|
||||||
inline void SetSetCols(PCOL colp) {To_SetCols = colp;}
|
inline void SetSetCols(PCOL colp) {To_SetCols = colp;}
|
||||||
|
inline void SetKindex(PKXBASE kxp) {To_Kindex = kxp;}
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
void SetKindex(PKXBASE kxp);
|
void ResetKindex(PGLOBAL g, PKXBASE kxp);
|
||||||
PCOL Key(int i) {return (To_Key_Col) ? To_Key_Col[i] : NULL;}
|
PCOL Key(int i) {return (To_Key_Col) ? To_Key_Col[i] : NULL;}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
|
Loading…
x
Reference in New Issue
Block a user