summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2014-02-03 16:14:13 +0100
committerOlivier Bertrand <bertrandop@gmail.com>2014-02-03 16:14:13 +0100
commit5133cb5e2530954a23b93ee22a49273f7333e36b (patch)
tree42b7b2654c305d6a19aa426d153300ad369b788c /storage
parent4d5f5f4cdf8c99bf693fd78490524a72418f1f45 (diff)
downloadmariadb-git-5133cb5e2530954a23b93ee22a49273f7333e36b.tar.gz
This is a major update of CONNECT that goes from version 1.1 to 1.2
=================================================================== - Implement a first support of the ALTER TABLE command. This fixes MDEV-5440 but does much more than only that. See the details of how ALTER is supported in the new documentation and also in MDEV-5440 comment. This is done principally by implementing for CONNECT the virtual function check_if_supported_inplace_alter. modified: storage/connect/connect.cc storage/connect/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/mysql-test/connect/r/bin.result storage/connect/mysql-test/connect/r/csv.result storage/connect/mysql-test/connect/r/dbf.result storage/connect/mysql-test/connect/r/dir.result storage/connect/mysql-test/connect/r/fix.result storage/connect/mysql-test/connect/r/index.result storage/connect/mysql-test/connect/r/ini.result storage/connect/mysql-test/connect/r/occur.result storage/connect/mysql-test/connect/r/pivot.result storage/connect/mysql-test/connect/r/vec.result storage/connect/mysql-test/connect/t/dbf.test storage/connect/plugutil.c storage/connect/user_connect.cc - Fixes the tabname/table_name issue for XML tables. Implement multiple files XML tables. modified: storage/connect/tabxml.cpp storage/connect/tabxml.h - Set to varchar(256) the fields of catalog tables stored as STRBLK's (had length 0 --> CHAR(1)) Add the GetCharString function to the VALBLK class modified: storage/connect/ha_connect.cc storage/connect/valblk.cpp storage/connect/valblk.h storage/connect/value.cpp - Translate CONNECT error messages to system_charset to avoid truncation on not ASCII characters. modified: storage/connect/ha_connect.cc - Update version number modified: storage/connect/ha_connect.cc storage/connect/mysql-test/connect/r/xml.result - Move the TDBASE::data_charset body from xtable.h to table.cpp. (dont' remember why) modified: storage/connect/table.cpp storage/connect/xtable.h - Other modifications are to enhance the support of OEM tables. In particular, they can now provide column definition in dicovery. modified: storage/connect/colblk.h storage/connect/global.h storage/connect/ha_connect.cc storage/connect/mycat.cc storage/connect/plgcnx.h storage/connect/plgdbsem.h storage/connect/xtable.h - Or to add or modify tracing. modified: storage/connect/filamtxt.cpp storage/connect/ha_connect.cc storage/connect/plgdbutl.cpp storage/connect/tabfix.cpp storage/connect/tabmysql.cpp
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/colblk.h14
-rw-r--r--storage/connect/connect.cc2
-rw-r--r--storage/connect/filamtxt.cpp12
-rw-r--r--storage/connect/global.h3
-rw-r--r--storage/connect/ha_connect.cc946
-rw-r--r--storage/connect/ha_connect.h38
-rw-r--r--storage/connect/mycat.cc83
-rw-r--r--storage/connect/mysql-test/connect/r/bin.result4
-rw-r--r--storage/connect/mysql-test/connect/r/csv.result4
-rw-r--r--storage/connect/mysql-test/connect/r/dbf.result20
-rw-r--r--storage/connect/mysql-test/connect/r/dir.result2
-rw-r--r--storage/connect/mysql-test/connect/r/fix.result4
-rw-r--r--storage/connect/mysql-test/connect/r/index.result2
-rw-r--r--storage/connect/mysql-test/connect/r/ini.result4
-rw-r--r--storage/connect/mysql-test/connect/r/occur.result2
-rw-r--r--storage/connect/mysql-test/connect/r/pivot.result12
-rw-r--r--storage/connect/mysql-test/connect/r/vec.result4
-rw-r--r--storage/connect/mysql-test/connect/r/xml.result2
-rw-r--r--storage/connect/mysql-test/connect/t/dbf.test14
-rw-r--r--storage/connect/plgcnx.h10
-rw-r--r--storage/connect/plgdbsem.h22
-rw-r--r--storage/connect/plgdbutl.cpp12
-rw-r--r--storage/connect/plugutil.c1
-rw-r--r--storage/connect/tabfix.cpp2
-rw-r--r--storage/connect/table.cpp15
-rw-r--r--storage/connect/tabmysql.cpp2
-rw-r--r--storage/connect/tabxml.cpp61
-rw-r--r--storage/connect/tabxml.h1
-rw-r--r--storage/connect/user_connect.cc1
-rw-r--r--storage/connect/valblk.cpp45
-rw-r--r--storage/connect/valblk.h13
-rw-r--r--storage/connect/value.cpp10
-rw-r--r--storage/connect/xtable.h18
33 files changed, 1029 insertions, 356 deletions
diff --git a/storage/connect/colblk.h b/storage/connect/colblk.h
index 320350f1923..11fca3e4fb7 100644
--- a/storage/connect/colblk.h
+++ b/storage/connect/colblk.h
@@ -1,7 +1,7 @@
/*************** Colblk H Declares Source Code File (.H) ***************/
-/* Name: COLBLK.H Version 1.6 */
+/* Name: COLBLK.H Version 1.7 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */
+/* (C) Copyright to the author Olivier BERTRAND 2005-2014 */
/* */
/* This file contains the COLBLK and derived classes declares. */
/***********************************************************************/
@@ -99,7 +99,7 @@ class DllExport COLBLK : public XOBJECT {
/***********************************************************************/
/* Class SPCBLK: Base class for special column descriptors. */
/***********************************************************************/
-class SPCBLK : public COLBLK {
+class DllExport SPCBLK : public COLBLK {
public:
// Constructor
SPCBLK(PCOLUMN cp);
@@ -121,7 +121,7 @@ class SPCBLK : public COLBLK {
/***********************************************************************/
/* Class RIDBLK: ROWID special column descriptor. */
/***********************************************************************/
-class RIDBLK : public SPCBLK {
+class DllExport RIDBLK : public SPCBLK {
public:
// Constructor
RIDBLK(PCOLUMN cp, bool rnm);
@@ -140,7 +140,7 @@ class RIDBLK : public SPCBLK {
/***********************************************************************/
/* Class FIDBLK: FILEID special column descriptor. */
/***********************************************************************/
-class FIDBLK : public SPCBLK {
+class DllExport FIDBLK : public SPCBLK {
public:
// Constructor
FIDBLK(PCOLUMN cp);
@@ -161,7 +161,7 @@ class FIDBLK : public SPCBLK {
/***********************************************************************/
/* Class TIDBLK: TABID special column descriptor. */
/***********************************************************************/
-class TIDBLK : public SPCBLK {
+class DllExport TIDBLK : public SPCBLK {
public:
// Constructor
TIDBLK(PCOLUMN cp);
@@ -186,7 +186,7 @@ class TIDBLK : public SPCBLK {
/***********************************************************************/
/* Class SIDBLK: SERVID special column descriptor. */
/***********************************************************************/
-class SIDBLK : public SPCBLK {
+class DllExport SIDBLK : public SPCBLK {
public:
// Constructor
SIDBLK(PCOLUMN cp);
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index f3c2559f13e..9340ae97258 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -347,7 +347,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
if (xtrace)
printf("About to open the table: tdbp=%p\n", tdbp);
- if (mode != MODE_ANY) {
+ if (mode != MODE_ANY && mode != MODE_ALTER) {
if (tdbp->OpenDB(g)) {
printf("%s\n", g->Message);
return true;
diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp
index 2291f2c2b00..1d3f17e2228 100644
--- a/storage/connect/filamtxt.cpp
+++ b/storage/connect/filamtxt.cpp
@@ -535,7 +535,7 @@ int DOSFAM::ReadBuffer(PGLOBAL g)
if (!Stream)
return RC_EF;
- if (trace)
+ if (trace > 1)
htrc("ReadBuffer: Tdbp=%p To_Line=%p Placed=%d\n",
Tdbp, Tdbp->To_Line, Placed);
@@ -548,20 +548,20 @@ int DOSFAM::ReadBuffer(PGLOBAL g)
CurBlk = (int)Rows++;
- if (trace)
+ if (trace > 1)
htrc("ReadBuffer: CurBlk=%d\n", CurBlk);
} else
Placed = false;
- if (trace)
+ if (trace > 1)
htrc(" About to read: stream=%p To_Buf=%p Buflen=%d\n",
Stream, To_Buf, Buflen);
if (fgets(To_Buf, Buflen, Stream)) {
p = To_Buf + strlen(To_Buf) - 1;
- if (trace)
+ if (trace > 1)
htrc(" Read: To_Buf=%p p=%c\n", To_Buf, To_Buf, p);
#if defined(UNIX)
@@ -589,7 +589,7 @@ int DOSFAM::ReadBuffer(PGLOBAL g)
} else if (*p == '\n')
*p = '\0'; // Eliminate ending new-line character
- if (trace)
+ if (trace > 1)
htrc(" To_Buf='%s'\n", To_Buf);
strcpy(Tdbp->To_Line, To_Buf);
@@ -610,7 +610,7 @@ int DOSFAM::ReadBuffer(PGLOBAL g)
rc = RC_FX;
} // endif's fgets
- if (trace)
+ if (trace > 1)
htrc("ReadBuffer: rc=%d\n", rc);
IsRead = true;
diff --git a/storage/connect/global.h b/storage/connect/global.h
index 4c0bc993123..8bccd742a64 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -219,9 +219,10 @@ typedef struct _global { /* Global structure */
uint Sarea_Size; /* Work area size */
PACTIVITY Activityp, ActivityStart;
char Message[MAX_STR];
- short Trace;
int Createas; /* To pass info to created table */
void *Xchk; /* indexes in create/alter */
+ short Alchecked; /* Checked for ALTER */
+ short Trace;
int jump_level;
jmp_buf jumper[MAX_JUMP + 2];
} GLOBAL;
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index d051ef76698..4533c628686 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) Olivier Bertrand 2004 - 2013
+/* Copyright (C) Olivier Bertrand 2004 - 2014
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -107,6 +107,7 @@
#include "field.h"
#include "sql_parse.h"
#include "sql_base.h"
+#include <sys/stat.h>
#if defined(NEW_WAY)
#include "sql_table.h"
#endif // NEW_WAY
@@ -164,8 +165,13 @@ extern "C" char plgini[];
extern "C" char nmfile[];
extern "C" char pdebug[];
+/***********************************************************************/
+/* Initialize the ha_connect static members. */
+/***********************************************************************/
+#define CONNECT_INI "connect.ini"
extern "C" {
- char version[]= "Version 1.01.0011 December 15, 2013";
+ char connectini[_MAX_PATH]= CONNECT_INI;
+ char version[]= "Version 1.02.0001 February 03, 2014";
#if defined(XMSG)
char msglang[]; // Default message language
@@ -173,17 +179,17 @@ extern "C" {
int trace= 0; // The general trace value
} // extern "C"
-/****************************************************************************/
-/* Initialize the ha_connect static members. */
-/****************************************************************************/
-#define CONNECT_INI "connect.ini"
-char connectini[_MAX_PATH]= CONNECT_INI;
int xtrace= 0;
ulong ha_connect::num= 0;
//int DTVAL::Shift= 0;
+/***********************************************************************/
+/* Utility functions. */
+/***********************************************************************/
+PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
+
static PCONNECT GetUser(THD *thd, PCONNECT xp);
-static PGLOBAL GetPlug(THD *thd, PCONNECT& lxp);
+static PGLOBAL GetPlug(THD *thd, PCONNECT& lxp);
static handler *connect_create_handler(handlerton *hton,
TABLE_SHARE *table,
@@ -474,6 +480,7 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg)
valid_query_id= 0;
creat_query_id= (table && table->in_use) ? table->in_use->query_id : 0;
stop= false;
+ alter= false;
indexing= -1;
locked= 0;
data_file_name= NULL;
@@ -491,6 +498,11 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg)
/****************************************************************************/
ha_connect::~ha_connect(void)
{
+ if (xtrace)
+ printf("Delete CONNECT %p, table: %s, xp=%p count=%d\n", this,
+ table ? table->s->table_name.str : "<null>",
+ xp, xp ? xp->count : 0);
+
if (xp) {
PCONNECT p;
@@ -562,12 +574,55 @@ static PGLOBAL GetPlug(THD *thd, PCONNECT& lxp)
return (lxp) ? lxp->g : NULL;
} // end of GetPlug
+/****************************************************************************/
+/* Get the implied table type. */
+/****************************************************************************/
+TABTYPE ha_connect::GetRealType(PTOS pos)
+{
+ TABTYPE type= GetTypeID(pos->type);
+
+ if (type == TAB_UNDEF)
+ type= pos->srcdef ? TAB_MYSQL : pos->tabname ? TAB_PRX : TAB_DOS;
+
+ return type;
+} // end of GetRealType
+
+/** @brief
+ This is a list of flags that indicate what functionality the storage
+ engine implements. The current table flags are documented in handler.h
+*/
+ulonglong ha_connect::table_flags() const
+{
+ ulonglong flags= HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ |
+ HA_NO_AUTO_INCREMENT | HA_NO_PREFIX_CHAR_KEYS |
+ HA_HAS_RECORDS | HA_CAN_VIRTUAL_COLUMNS |
+ HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
+// HA_NULL_IN_KEY | not implemented yet
+ HA_DUPLICATE_KEY_NOT_IN_ORDER |
+ HA_MUST_USE_TABLE_CONDITION_PUSHDOWN;
+ ha_connect *hp= (ha_connect*)this;
+ PTOS pos= hp->GetTableOptionStruct(table);
+
+ if (pos) {
+ TABTYPE type= hp->GetRealType(pos);
+
+ if (IsFileType(type))
+ flags|= HA_FILE_BASED;
+
+ // No data change on ALTER for outward tables
+ if (!IsFileType(type) || hp->FileExists(pos->filename))
+ flags|= HA_NO_COPY_ON_ALTER;
+
+ } // endif pos
+
+ return flags;
+} // end of table_flags
/****************************************************************************/
/* Return the value of an option specified in the option list. */
/****************************************************************************/
-static char *GetListOption(PGLOBAL g, const char *opname,
- const char *oplist, const char *def=NULL)
+char *GetListOption(PGLOBAL g, const char *opname,
+ const char *oplist, const char *def)
{
char key[16], val[256];
char *pk, *pv, *pn;
@@ -619,7 +674,8 @@ static char *GetListOption(PGLOBAL g, const char *opname,
/****************************************************************************/
PTOS ha_connect::GetTableOptionStruct(TABLE *tab)
{
- return (tshp) ? tshp->option_struct : tab->s->option_struct;
+ return (tshp) ? tshp->option_struct :
+ (tab) ? tab->s->option_struct : NULL;
} // end of GetTableOptionStruct
/****************************************************************************/
@@ -972,24 +1028,27 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
/****************************************************************************/
/* Returns the index description structure used to make the index. */
/****************************************************************************/
-PIXDEF ha_connect::GetIndexInfo(void)
+PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
{
char *name, *pn;
bool unique;
PIXDEF xdp, pxd=NULL, toidx= NULL;
PKPDEF kpp, pkp;
- PGLOBAL& g= xp->g;
KEY kp;
+ PGLOBAL& g= xp->g;
- for (int n= 0; (unsigned)n < table->s->keynames.count; n++) {
+ if (!s)
+ s= table->s;
+
+ for (int n= 0; (unsigned)n < s->keynames.count; n++) {
if (xtrace)
printf("Getting created index %d info\n", n + 1);
// Find the index to describe
- kp= table->s->key_info[n];
+ kp= s->key_info[n];
// Now get index information
- pn= (char*)table->s->keynames.type_names[n];
+ pn= (char*)s->keynames.type_names[n];
name= (char*)PlugSubAlloc(g, NULL, strlen(pn) + 1);
strcpy(name, pn); // This is probably unuseful
unique= (kp.flags & 1) != 0;
@@ -1292,7 +1351,7 @@ int ha_connect::MakeRecord(char *buf)
if (fp->vcol_info && !fp->stored_in_db)
continue; // This is a virtual column
- if (bitmap_is_set(map, fp->field_index)) {
+ if (bitmap_is_set(map, fp->field_index) || alter) {
// This is a used field, fill the buffer with value
for (colp= tdbp->GetColumns(); colp; colp= colp->GetNext())
if (!stricmp(colp->GetName(), (char*)fp->field_name))
@@ -1457,18 +1516,17 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *buf)
break;
default:
fp->val_str(&attribute);
- if (charset == &my_charset_bin)
- {
- value->SetValue_psz(attribute.c_ptr_safe());
- }
- else
- {
+
+ if (charset != &my_charset_bin) {
// Convert from SQL field charset to DATA_CHARSET
uint cnv_errors;
+
data_charset_value.copy(attribute.ptr(), attribute.length(),
attribute.charset(), charset, &cnv_errors);
value->SetValue_psz(data_charset_value.c_ptr_safe());
- }
+ } else
+ value->SetValue_psz(attribute.c_ptr_safe());
+
break;
} // endswitch Type
@@ -1598,7 +1656,7 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
if (!cond)
return NULL;
- if (xtrace > 1)
+ if (xtrace)
printf("Cond type=%d\n", cond->type());
if (cond->type() == COND::COND_ITEM) {
@@ -1608,7 +1666,7 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
if (x)
return NULL;
- if (xtrace > 1)
+ if (xtrace)
printf("Cond: Ftype=%d name=%s\n", cond_item->functype(),
cond_item->func_name());
@@ -1655,7 +1713,7 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
Item_func *condf= (Item_func *)cond;
Item* *args= condf->arguments();
- if (xtrace > 1)
+ if (xtrace)
printf("Func type=%d argnum=%d\n", condf->functype(),
condf->argument_count());
@@ -1684,11 +1742,11 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
return NULL;
for (i= 0; i < condf->argument_count(); i++) {
- if (xtrace > 1)
+ if (xtrace)
printf("Argtype(%d)=%d\n", i, args[i]->type());
if (i >= 2 && !ismul) {
- if (xtrace > 1)
+ if (xtrace)
printf("Unexpected arg for vop=%d\n", vop);
continue;
@@ -1710,6 +1768,8 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
if (fop && fop->special) {
if (tty == TYPE_AM_TBL && !stricmp(fop->special, "TABID"))
fnm= "TABID";
+ else if (tty == TYPE_AM_PLG)
+ fnm= fop->special;
else
return NULL;
@@ -1718,7 +1778,7 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
else
fnm= pField->field->field_name;
- if (xtrace > 1) {
+ if (xtrace) {
printf("Field index=%d\n", pField->field->field_index);
printf("Field name=%s\n", pField->field->field_name);
} // endif xtrace
@@ -1728,15 +1788,36 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
return NULL;
strcat(body, fnm);
+ } else if (args[i]->type() == COND::FUNC_ITEM) {
+ if (tty == TYPE_AM_MYSQL) {
+ if (!CheckCond(g, filp, tty, args[i]))
+ return NULL;
+
+ } else
+ return NULL;
+
} else {
char buff[256];
String *res, tmp(buff, sizeof(buff), &my_charset_bin);
Item_basic_constant *pval= (Item_basic_constant *)args[i];
+ switch (args[i]->type()) {
+ case COND::STRING_ITEM:
+ case COND::INT_ITEM:
+ case COND::REAL_ITEM:
+ case COND::NULL_ITEM:
+ case COND::DECIMAL_ITEM:
+ case COND::DATE_ITEM:
+ case COND::CACHE_ITEM:
+ break;
+ default:
+ return NULL;
+ } // endswitch type
+
if ((res= pval->val_str(&tmp)) == NULL)
return NULL; // To be clarified
- if (xtrace > 1)
+ if (xtrace)
printf("Value=%.*s\n", res->length(), res->ptr());
// IN and BETWEEN clauses should be col VOP list
@@ -1781,7 +1862,7 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
filp->Op= vop;
} else {
- if (xtrace > 1)
+ if (xtrace)
printf("Unsupported condition\n");
return NULL;
@@ -1819,7 +1900,8 @@ const COND *ha_connect::cond_push(const COND *cond)
bool x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC);
if (tty == TYPE_AM_WMI || tty == TYPE_AM_ODBC ||
- tty == TYPE_AM_TBL || tty == TYPE_AM_MYSQL || x) {
+ tty == TYPE_AM_TBL || tty == TYPE_AM_MYSQL ||
+ tty == TYPE_AM_PLG || x) {
PGLOBAL& g= xp->g;
PFIL filp= (PFIL)PlugSubAlloc(g, NULL, sizeof(FILTER));
@@ -1830,7 +1912,7 @@ const COND *ha_connect::cond_push(const COND *cond)
if (CheckCond(g, filp, tty, (Item *)cond)) {
if (xtrace)
- puts(filp->Body);
+ printf("cond_push: %s\n", filp->Body);
if (!x)
PlugSubAlloc(g, NULL, strlen(filp->Body) + 1);
@@ -1879,9 +1961,19 @@ bool ha_connect::get_error_message(int error, String* buf)
{
DBUG_ENTER("ha_connect::get_error_message");
- if (xp && xp->g)
- buf->copy(xp->g->Message, (uint)strlen(xp->g->Message),
- system_charset_info);
+ if (xp && xp->g) {
+ PGLOBAL g= xp->g;
+ char *msg= (char*)PlugSubAlloc(g, NULL, strlen(g->Message) * 3);
+ uint dummy_errors;
+ uint32 len= copy_and_convert(msg, strlen(g->Message) * 3,
+ system_charset_info,
+ g->Message, strlen(g->Message),
+ &my_charset_latin1,
+ &dummy_errors);
+ msg[len]= '\0';
+ buf->copy(msg, (uint)strlen(msg), system_charset_info);
+ } else
+ buf->copy("Cannot retrieve msg", 19, system_charset_info);
DBUG_RETURN(false);
} // end of get_error_message
@@ -2030,6 +2122,10 @@ int ha_connect::write_row(uchar *buf)
PGLOBAL& g= xp->g;
DBUG_ENTER("ha_connect::write_row");
+ // This is not tested yet
+ if (xmod == MODE_ALTER)
+ xmod= MODE_INSERT;
+
// Open the table if it was not opened yet (locked)
if (!IsOpened() || xmod != tdbp->GetMode()) {
if (IsOpened())
@@ -2155,6 +2251,9 @@ int ha_connect::index_init(uint idx, bool sorted)
PGLOBAL& g= xp->g;
DBUG_ENTER("index_init");
+ if (xtrace)
+ printf("index_init: this=%p idx=%u sorted=%d\n", this, idx, sorted);
+
if ((rc= rnd_init(0)))
return rc;
@@ -2184,6 +2283,10 @@ int ha_connect::index_init(uint idx, bool sorted)
rc= 0;
} // endif indexing
+ if (xtrace)
+ printf("index_init: rc=%d indexing=%d active_index=%d\n",
+ rc, indexing, active_index);
+
DBUG_RETURN(rc);
} // end of index_init
@@ -2406,8 +2509,15 @@ int ha_connect::rnd_init(bool scan)
(xp) ? xp->g : NULL);
DBUG_ENTER("ha_connect::rnd_init");
+ // This is not tested yet
+ if (xmod == MODE_ALTER) {
+ xmod= MODE_READ;
+ alter= 1;
+ } // endif xmod
+
if (xtrace)
- printf("%p in rnd_init: scan=%d\n", this, scan);
+ printf("rnd_init: this=%p scan=%d xmod=%d alter=%d\n",
+ this, scan, xmod, alter);
if (!g || !table || xmod == MODE_INSERT)
DBUG_RETURN(HA_ERR_INITIALIZATION);
@@ -2632,7 +2742,8 @@ int ha_connect::info(uint flag)
if (!valid_info) {
// tdbp must be available to get updated info
if (xp->CheckQuery(valid_query_id) || !tdbp) {
- if (xmod == MODE_ANY) { // Pure info, not a query
+ if (xmod == MODE_ANY || xmod == MODE_ALTER) {
+ // Pure info, not a query
pure= true;
xp->CheckCleanup();
} // endif xmod
@@ -2752,19 +2863,9 @@ int ha_connect::delete_all_rows()
bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn)
{
const char *db= (dbn && *dbn) ? dbn : NULL;
+ TABTYPE type=GetRealType(options);
- if (!options->type) {
- if (options->srcdef)
- options->type= "MYSQL";
- else if (options->tabname)
- options->type= "PROXY";
- else
- options->type= "DOS";
-
- } // endif type
-
- switch (GetTypeID(options->type))
- {
+ switch (type) {
case TAB_UNDEF:
// case TAB_CATLG:
case TAB_PLG:
@@ -2784,18 +2885,30 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn)
case TAB_XML:
case TAB_INI:
case TAB_VEC:
- if (!options->filename)
+ if (options->filename && *options->filename) {
+ char *s, path[FN_REFLEN], dbpath[FN_REFLEN];
+#if defined(WIN32)
+ s= "\\";
+#else // !WIN32
+ s= "/";
+#endif // !WIN32
+ strcpy(dbpath, mysql_real_data_home);
+
+ if (db)
+ strcat(strcat(dbpath, db), s);
+
+ (void) fn_format(path, options->filename, dbpath, "",
+ MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
+
+ if (!is_secure_file_path(path)) {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
+ return true;
+ } // endif path
+
+ } else
return false;
- char path[FN_REFLEN];
- (void) fn_format(path, options->filename, mysql_real_data_home, "",
- MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
- if (!is_secure_file_path(path))
- {
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
- return true;
- }
- /* Fall through to check FILE_ACL */
+ /* Fall through to check FILE_ACL */
case TAB_ODBC:
case TAB_MYSQL:
case TAB_DIR:
@@ -2811,7 +2924,7 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn)
case TAB_OCCUR:
case TAB_PIVOT:
return false;
- }
+ } // endswitch type
my_printf_error(ER_UNKNOWN_ERROR, "check_privileges failed", MYF(0));
return true;
@@ -2883,7 +2996,6 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
break;
case SQLCOM_DROP_TABLE:
case SQLCOM_RENAME_TABLE:
- case SQLCOM_ALTER_TABLE:
newmode= MODE_ANY;
break;
case SQLCOM_DROP_INDEX:
@@ -2895,6 +3007,9 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
case SQLCOM_DROP_VIEW:
newmode= MODE_ANY;
break;
+ case SQLCOM_ALTER_TABLE:
+ newmode= MODE_ALTER;
+ break;
default:
printf("Unsupported sql_command=%d", thd_sql_command(thd));
strcpy(g->Message, "CONNECT Unsupported command");
@@ -2926,7 +3041,6 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
break;
case SQLCOM_DROP_INDEX:
case SQLCOM_CREATE_INDEX:
- case SQLCOM_ALTER_TABLE:
*chk= true;
// stop= true;
case SQLCOM_DROP_TABLE:
@@ -2937,6 +3051,10 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
case SQLCOM_DROP_VIEW:
newmode= MODE_ANY;
break;
+ case SQLCOM_ALTER_TABLE:
+ *chk= true;
+ newmode= MODE_ALTER;
+ break;
default:
printf("Unsupported sql_command=%d", thd_sql_command(thd));
strcpy(g->Message, "CONNECT Unsupported command");
@@ -3023,7 +3141,8 @@ int ha_connect::external_lock(THD *thd, int lock_type)
DBUG_ASSERT(thd == current_thd);
if (xtrace)
- printf("%p external_lock: lock_type=%d\n", this, lock_type);
+ printf("external_lock: this=%p thd=%p xp=%d g=%p lock_type=%d\n",
+ this, thd, xp, g, lock_type);
if (!g)
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
@@ -3043,13 +3162,17 @@ int ha_connect::external_lock(THD *thd, int lock_type)
} // endswitch mode
if (newmode == MODE_ANY) {
+ int sqlcom= thd_sql_command(thd);
+
// This is unlocking, do it by closing the table
- if (xp->CheckQueryID() && thd_sql_command(thd) != SQLCOM_UNLOCK_TABLES
- && thd_sql_command(thd) != SQLCOM_LOCK_TABLES)
+ if (xp->CheckQueryID() && sqlcom != SQLCOM_UNLOCK_TABLES
+ && sqlcom != SQLCOM_LOCK_TABLES)
rc= 2; // Logical error ???
- else if (g->Xchk) {
- if (!tdbp || *tdbp->GetName() == '#') {
- if (!tdbp && !(tdbp= GetTDB(g)))
+// else if (g->Xchk && (sqlcom == SQLCOM_CREATE_INDEX ||
+// sqlcom == SQLCOM_DROP_INDEX)) {
+ else if (g->Xchk) {
+ if (!tdbp) {
+ if (!(tdbp= GetTDB(g)))
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
else if (!((PTDBASE)tdbp)->GetDef()->Indexable()) {
sprintf(g->Message, "external_lock: Table %s is not indexable", tdbp->GetName());
@@ -3132,31 +3255,21 @@ int ha_connect::external_lock(THD *thd, int lock_type)
if (adp)
// Here we do make the new indexes
if (tdp->MakeIndex(g, adp, true) == RC_FX) {
-//#if defined(_DEBUG)
- // Make it a warning to avoid crash on debug
+ // Make it a warning to avoid crash
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
0, g->Message);
rc= 0;
-//#else // !_DEBUG
-// my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
-// rc= HA_ERR_INTERNAL_ERROR;
-//#endif // !DEBUG
} // endif MakeIndex
- } // endif Mode
+ } // endif Tdbp
} // endelse Xchk
if (CloseTable(g)) {
// This is an error while builing index
-//#if defined(_DEBUG)
- // Make it a warning to avoid crash on debug
+ // Make it a warning to avoid crash
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
rc= 0;
-//#else // !_DEBUG
-// my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
-// rc= HA_ERR_INTERNAL_ERROR;
-//#endif // !DEBUG
} // endif Close
locked= 0;
@@ -3183,19 +3296,32 @@ int ha_connect::external_lock(THD *thd, int lock_type)
valid_info= false;
} // endif CheckCleanup
+#if 0
if (xcheck) {
// This must occur after CheckCleanup
- g->Xchk= new(g) XCHK;
- ((PCHK)g->Xchk)->oldsep= GetBooleanOption("Sepindex", false);
- ((PCHK)g->Xchk)->oldpix= GetIndexInfo();
+ if (!g->Xchk) {
+ g->Xchk= new(g) XCHK;
+ ((PCHK)g->Xchk)->oldsep= GetBooleanOption("Sepindex", false);
+ ((PCHK)g->Xchk)->oldpix= GetIndexInfo();
+ } // endif Xchk
+
} else
g->Xchk= NULL;
+#endif // 0
if (cras)
g->Createas= 1; // To tell created table to ignore FLAG
- if (xtrace)
- printf("Calling CntCheckDB db=%s\n", GetDBName(NULL));
+ if (xtrace) {
+#if 0
+ printf("xcheck=%d cras=%d\n", xcheck, cras);
+
+ if (xcheck)
+ printf("oldsep=%d oldpix=%p\n",
+ ((PCHK)g->Xchk)->oldsep, ((PCHK)g->Xchk)->oldpix);
+#endif // 0
+ printf("Calling CntCheckDB db=%s cras=%d\n", GetDBName(NULL), cras);
+ } // endif xtrace
// Set or reset the good database environment
if (CntCheckDB(g, this, GetDBName(NULL))) {
@@ -3212,7 +3338,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
else
tdbp= NULL;
- }// endif tdbp
+ } // endif tdbp
xmod= newmode;
@@ -3330,7 +3456,6 @@ filename_to_dbname_and_tablename(const char *filename,
return false;
} // end of filename_to_dbname_and_tablename
-
/**
@brief
Used to delete or rename a table. By the time delete_table() has been
@@ -3355,55 +3480,86 @@ filename_to_dbname_and_tablename(const char *filename,
int ha_connect::delete_or_rename_table(const char *name, const char *to)
{
DBUG_ENTER("ha_connect::delete_or_rename_table");
- /* We have to retrieve the information about this table options. */
- ha_table_option_struct *pos;
- char key[MAX_DBKEY_LENGTH], db[128], tabname[128];
- int rc= 0;
- uint key_length;
- TABLE_SHARE *share;
- THD *thd= current_thd;
+ char db[128], tabname[128];
+ int rc= 0;
+ bool ok= false;
+ THD *thd= current_thd;
+ int sqlcom= thd_sql_command(thd);
+
+ if (xtrace) {
+ if (to)
+ printf("rename_table: this=%p thd=%p sqlcom=%d from=%s to=%s\n",
+ this, thd, sqlcom, name, to);
+ else
+ printf("delete_table: this=%p thd=%p sqlcom=%d name=%s\n",
+ this, thd, sqlcom, name);
+
+ } // endif xtrace
if (to && (filename_to_dbname_and_tablename(to, db, sizeof(db),
- tabname, sizeof(tabname)) ||
- *tabname == '#'))
- goto fin;
+ tabname, sizeof(tabname))
+ || (*tabname == '#' && sqlcom == SQLCOM_CREATE_INDEX)))
+ DBUG_RETURN(0);
if (filename_to_dbname_and_tablename(name, db, sizeof(db),
- tabname, sizeof(tabname)) ||
- *tabname == '#')
- goto fin;
+ tabname, sizeof(tabname))
+ || (*tabname == '#' && sqlcom == SQLCOM_CREATE_INDEX))
+ DBUG_RETURN(0);
- key_length= tdc_create_key(key, db, tabname);
+ // If a temporary file exists, all the tests below were passed
+ // successfully when making it, so they are not needed anymore
+ // in particular because they sometimes cause DBUG_ASSERT crash.
+ if (*tabname != '#') {
+ // We have to retrieve the information about this table options.
+ ha_table_option_struct *pos;
+ char key[MAX_DBKEY_LENGTH];
+ uint key_length;
+ TABLE_SHARE *share;
- // share contains the option struct that we need
- if (!(share= alloc_table_share(db, tabname, key, key_length)))
- goto fin;
+ key_length= tdc_create_key(key, db, tabname);
- // Get the share info from the .frm file
- if (open_table_def(thd, share))
- goto err;
+ // share contains the option struct that we need
+ if (!(share= alloc_table_share(db, tabname, key, key_length)))
+ DBUG_RETURN(rc);
- // Now we can work
- pos= share->option_struct;
+#if 0
+ if (*tabname == '#') {
+ // These are in ???? charset after renaming
+ char *p= strchr(share->path.str, '@');
+ strcpy(p, share->table_name.str);
+ share->path.length= strlen(share->path.str);
+ share->normalized_path.length= share->path.length;
+ } // endif tabname
+#endif // 0
+
+ // Get the share info from the .frm file
+ if (!open_table_def(thd, share)) {
+ // Now we can work
+ if ((pos= share->option_struct)) {
+ if (check_privileges(thd, pos, db))
+ rc= HA_ERR_INTERNAL_ERROR; // ???
+ else
+ if (IsFileType(GetRealType(pos)) && !pos->filename)
+ ok= true;
+
+ } // endif pos
+
+ } else // Avoid infamous DBUG_ASSERT
+ thd->get_stmt_da()->reset_diagnostics_area();
- if (check_privileges(thd, pos, db))
- {
free_table_share(share);
- DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
- }
+ } else // Temporary file
+ ok= true;
- if (IsFileType(GetTypeID(pos->type)) && !pos->filename) {
+ if (ok) {
// Let the base handler do the job
if (to)
rc= handler::rename_table(name, to);
- else
- rc= handler::delete_table(name);
- } // endif filename
+ else if ((rc= handler::delete_table(name)) == ENOENT)
+ rc= 0; // No files is not an error for CONNECT
+
+ } // endif ok
- // Done no more need for this
- err:
- free_table_share(share);
- fin:
DBUG_RETURN(rc);
} // end of delete_or_rename_table
@@ -4114,6 +4270,13 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
ok= true;
break;
+ case TAB_OEM:
+ if (topt->module && topt->subtype)
+ ok= true;
+ else
+ strcpy(g->Message, "Missing OEM module or subtype");
+
+ break;
default:
sprintf(g->Message, "Cannot get column info for table type %s", topt->type);
break;
@@ -4217,6 +4380,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
case TAB_PIVOT:
qrp= PivotColumns(g, tab, src, pic, fcl, host, db, user, pwd, port);
break;
+ case TAB_OEM:
+ qrp= OEMColumns(g, topt, tab, (char*)db, fnc == FNC_COL);
+ break;
default:
strcpy(g->Message, "System error during assisted discovery");
break;
@@ -4236,6 +4402,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
dec= crp->Prec;
flg= crp->Flag;
+ if (!len && typ == TYPE_STRING)
+ len= 256; // STRBLK's have 0 length
+
#if defined(NEW_WAY)
// Now add the field
rc= add_fields(g, thd, &alter_info, cnm, typ, len, dec,
@@ -4422,8 +4591,15 @@ int ha_connect::create(const char *name, TABLE *table_arg,
PGLOBAL g= xp->g;
DBUG_ENTER("ha_connect::create");
+ int sqlcom= thd_sql_command(table_arg->in_use);
PTOS options= GetTableOptionStruct(table_arg);
+ table= table_arg; // Used by called functions
+
+ if (xtrace)
+ printf("create: this=%p thd=%p xp=%p g=%p sqlcom=%d name=%s\n",
+ this, thd, xp, g, sqlcom, GetTableName());
+
// CONNECT engine specific table options:
DBUG_ASSERT(options);
type= GetTypeID(options->type);
@@ -4682,83 +4858,89 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endfor field
- table= table_arg; // Used by called functions
-
- if (IsFileType(type)) {
- if (!options->filename) {
- // The file name is not specified, create a default file in
- // the database directory named table_name.table_type.
- // (temporarily not done for XML because a void file causes
- // the XML parsers to report an error on the first Insert)
- char buf[256], fn[_MAX_PATH], dbpath[128], lwt[12];
- int h;
-
- strcpy(buf, GetTableName());
-
- if (*buf != '#') {
- // Check for incompatible options
- if (options->sepindex) {
- my_message(ER_UNKNOWN_ERROR,
- "SEPINDEX is incompatible with unspecified file name",
- MYF(0));
- DBUG_RETURN(HA_ERR_UNSUPPORTED);
- } else if (GetTypeID(options->type) == TAB_VEC)
- if (!table->s->max_rows || options->split) {
- my_printf_error(ER_UNKNOWN_ERROR,
- "%s tables whose file name is unspecified cannot be split",
- MYF(0), options->type);
- DBUG_RETURN(HA_ERR_UNSUPPORTED);
- } else if (options->header == 2) {
- my_printf_error(ER_UNKNOWN_ERROR,
- "header=2 is not allowed for %s tables whose file name is unspecified",
- MYF(0), options->type);
- DBUG_RETURN(HA_ERR_UNSUPPORTED);
- } // endif's
-
- // Fold type to lower case
- for (int i= 0; i < 12; i++)
- if (!options->type[i]) {
- lwt[i]= 0;
- break;
- } else
- lwt[i]= tolower(options->type[i]);
-
- strcat(strcat(buf, "."), lwt);
- sprintf(g->Message, "No file name. Table will use %s", buf);
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
- strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/");
- PlugSetPath(fn, buf, dbpath);
+ if ((sqlcom == SQLCOM_CREATE_TABLE || *GetTableName() == '#')
+ && IsFileType(type) && !options->filename) {
+ // The file name is not specified, create a default file in
+ // the database directory named table_name.table_type.
+ // (temporarily not done for XML because a void file causes
+ // the XML parsers to report an error on the first Insert)
+ char buf[256], fn[_MAX_PATH], dbpath[128], lwt[12];
+ int h;
+
+ strcpy(buf, GetTableName());
+
+ // Check for incompatible options
+ if (options->sepindex) {
+ my_message(ER_UNKNOWN_ERROR,
+ "SEPINDEX is incompatible with unspecified file name",
+ MYF(0));
+ DBUG_RETURN(HA_ERR_UNSUPPORTED);
+ } else if (GetTypeID(options->type) == TAB_VEC)
+ if (!table->s->max_rows || options->split) {
+ my_printf_error(ER_UNKNOWN_ERROR,
+ "%s tables whose file name is unspecified cannot be split",
+ MYF(0), options->type);
+ DBUG_RETURN(HA_ERR_UNSUPPORTED);
+ } else if (options->header == 2) {
+ my_printf_error(ER_UNKNOWN_ERROR,
+ "header=2 is not allowed for %s tables whose file name is unspecified",
+ MYF(0), options->type);
+ DBUG_RETURN(HA_ERR_UNSUPPORTED);
+ } // endif's
+
+ // Fold type to lower case
+ for (int i= 0; i < 12; i++)
+ if (!options->type[i]) {
+ lwt[i]= 0;
+ break;
+ } else
+ lwt[i]= tolower(options->type[i]);
- if ((h= ::open(fn, O_CREAT | O_EXCL, 0666)) == -1) {
- if (errno == EEXIST)
- sprintf(g->Message, "Default file %s already exists", fn);
- else
- sprintf(g->Message, "Error %d creating file %s", errno, fn);
-
- push_warning(table->in_use,
- Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
- } else
- ::close(h);
+ strcat(strcat(buf, "."), lwt);
+ sprintf(g->Message, "No file name. Table will use %s", buf);
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+ strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/");
+ PlugSetPath(fn, buf, dbpath);
- if (type == TAB_FMT || options->readonly)
- push_warning(table->in_use, Sql_condition::WARN_LEVEL_WARN, 0,
- "Congratulation, you just created a read-only void table!");
+ if ((h= ::open(fn, O_CREAT | O_EXCL, 0666)) == -1) {
+ if (errno == EEXIST)
+ sprintf(g->Message, "Default file %s already exists", fn);
+ else
+ sprintf(g->Message, "Error %d creating file %s", errno, fn);
- } // endif buf
+ push_warning(table->in_use,
+ Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+ } else
+ ::close(h);
+
+ if (type == TAB_FMT || options->readonly)
+ push_warning(table->in_use, Sql_condition::WARN_LEVEL_WARN, 0,
+ "Congratulation, you just created a read-only void table!");
- } // endif filename
+ } // endif
- } // endif type
+ if (xtrace)
+ printf("xchk=%d createas=%d\n", g->Xchk, g->Createas);
- // To check whether indexes have to be made or remade
+ // To check whether indices have to be made or remade
if (!g->Xchk) {
PIXDEF xdp;
- // We should be in CREATE TABLE
- if (thd_sql_command(table->in_use) != SQLCOM_CREATE_TABLE)
+ // We should be in CREATE TABLE or ALTER_TABLE
+ if (sqlcom != SQLCOM_CREATE_TABLE && sqlcom != SQLCOM_ALTER_TABLE)
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
"Wrong command in create, please contact CONNECT team");
+ if (sqlcom == SQLCOM_ALTER_TABLE && g->Alchecked == 0 &&
+ (!IsFileType(type) || FileExists(options->filename))) {
+ // This is an ALTER to CONNECT from another engine.
+ // It cannot be accepted because the table data would be lost
+ // except when the target file does not exist.
+ strcpy(g->Message, "Operation denied. Table data would be lost.");
+ my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+ } // endif outward
+
// Get the index definitions
if (xdp= GetIndexInfo()) {
if (IsTypeIndexable(type)) {
@@ -4786,7 +4968,13 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endif xdp
} else {
+ // This should not happen anymore with indexing new way
+ my_message(ER_UNKNOWN_ERROR,
+ "CONNECT index modification should be in-place", MYF(0));
+ DBUG_RETURN(HA_ERR_UNSUPPORTED);
+#if 0
PIXDEF xdp= GetIndexInfo();
+ PCHK xcp= (PCHK)g->Xchk;
if (xdp) {
if (!IsTypeIndexable(type)) {
@@ -4795,19 +4983,356 @@ int ha_connect::create(const char *name, TABLE *table_arg,
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
rc= HA_ERR_INTERNAL_ERROR;
} else {
- ((PCHK)g->Xchk)->newpix= xdp;
- ((PCHK)g->Xchk)->newsep= GetBooleanOption("Sepindex", false);
+ xcp->newpix= xdp;
+ xcp->newsep= GetBooleanOption("Sepindex", false);
} // endif Indexable
- } else if (!((PCHK)g->Xchk)->oldpix)
+ } else if (!xcp->oldpix)
g->Xchk= NULL;
+ if (xtrace && g->Xchk)
+ printf("oldsep=%d newsep=%d oldpix=%p newpix=%p\n",
+ xcp->oldsep, xcp->newsep, xcp->oldpix, xcp->newpix);
+
+// if (g->Xchk &&
+// (sqlcom != SQLCOM_CREATE_INDEX && sqlcom != SQLCOM_DROP_INDEX)) {
+ if (g->Xchk) {
+ PIXDEF xp1, xp2;
+ bool b= false; // true if index changes
+
+ if (xcp->oldsep == xcp->newsep) {
+ for (xp1= xcp->newpix, xp2= xcp->oldpix;
+ xp1 || xp2;
+ xp1= xp1->Next, xp2= xp2->Next)
+ if (!xp1 || !xp2 || !IsSameIndex(xp1, xp2)) {
+ b= true;
+ break;
+ } // endif xp1
+
+ } else
+ b= true;
+
+ if (!b)
+ g->Xchk= NULL;
+
+#if 0
+ if (b) {
+ // CONNECT does not support indexing via ALTER TABLE
+ my_message(ER_UNKNOWN_ERROR,
+ "CONNECT does not support index modification via ALTER TABLE",
+ MYF(0));
+ DBUG_RETURN(HA_ERR_UNSUPPORTED);
+ } // endif b
+#endif // 0
+
+ } // endif Xchk
+
+#endif // 0
} // endif Xchk
table= st;
DBUG_RETURN(rc);
} // end of create
+/**
+ Used to check whether a file based outward table can be populated by
+ an ALTER TABLE command. The conditions are:
+ - file does not exist or is void
+ - user has file privilege
+*/
+bool ha_connect::FileExists(const char *fn)
+{
+ if (!fn || !*fn)
+ return false;
+
+ if (table) {
+ char *s, filename[_MAX_PATH], path[128];
+ int n;
+ struct stat info;
+
+ if (check_access(ha_thd(), FILE_ACL, table->s->db.str,
+ NULL, NULL, 0, 0))
+ return true;
+
+#if defined(WIN32)
+ s= "\\";
+#else // !WIN32
+ s= "/";
+#endif // !WIN32
+
+ strcat(strcat(strcat(strcpy(path, "."), s), table->s->db.str), s);
+ PlugSetPath(filename, fn, path);
+ n= stat(filename, &info);
+
+ if (n < 0) {
+ if (errno != ENOENT) {
+ char buf[_MAX_PATH + 20];
+
+ sprintf(buf, "Error %d for file %s", errno, filename);
+ push_warning(table->in_use, Sql_condition::WARN_LEVEL_WARN, 0, buf);
+ return true;
+ } else
+ return false;
+
+ } else
+ return (info.st_size) ? true : false;
+
+ } // endif table
+
+ return true;
+} // end of FileExists
+
+/**
+ check whether a string option have changed
+ */
+bool ha_connect::SameChar(TABLE *tab, char *opn)
+{
+ char *str1, *str2;
+ bool b1, b2;
+
+ tshp= tab->s; // The altered table
+ str1= GetStringOption(opn);
+ tshp= NULL;
+ str2= GetStringOption(opn);
+ b1= (!str1 || !*str1);
+ b2= (!str2 || !*str2);
+
+ if (b1 && b2)
+ return true;
+ else if ((b1 && !b2) || (!b1 && b2) || stricmp(str1, str2))
+ return false;
+
+ return true;
+} // end of SameChar
+
+/**
+ check whether a Boolean option have changed
+ */
+bool ha_connect::SameBool(TABLE *tab, char *opn)
+{
+ bool b1, b2;
+
+ tshp= tab->s; // The altered table
+ b1= GetBooleanOption(opn, false);
+ tshp= NULL;
+ b2= GetBooleanOption(opn, false);
+ return (b1 == b2);
+} // end of SameBool
+
+/**
+ check whether an integer option have changed
+ */
+bool ha_connect::SameInt(TABLE *tab, char *opn)
+{
+ int i1, i2;
+
+ tshp= tab->s; // The altered table
+ i1= GetIntegerOption(opn);
+ tshp= NULL;
+ i2= GetIntegerOption(opn);
+
+ if (!stricmp(opn, "lrecl"))
+ return (i1 == i2 || !i1 || !i2);
+ else if (!stricmp(opn, "ending"))
+ return (i1 == i2 || i1 <= 0 || i2 <= 0);
+ else
+ return (i1 == i2);
+
+} // end of SameInt
+
+
+ /**
+ Check if a storage engine supports a particular alter table in-place
+
+ @param altered_table TABLE object for new version of table.
+ @param ha_alter_info Structure describing changes to be done
+ by ALTER TABLE and holding data used
+ during in-place alter.
+
+ @retval HA_ALTER_ERROR Unexpected error.
+ @retval HA_ALTER_INPLACE_NOT_SUPPORTED Not supported, must use copy.
+ @retval HA_ALTER_INPLACE_EXCLUSIVE_LOCK Supported, but requires X lock.
+ @retval HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE
+ Supported, but requires SNW lock
+ during main phase. Prepare phase
+ requires X lock.
+ @retval HA_ALTER_INPLACE_SHARED_LOCK Supported, but requires SNW lock.
+ @retval HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE
+ Supported, concurrent reads/writes
+ allowed. However, prepare phase
+ requires X lock.
+ @retval HA_ALTER_INPLACE_NO_LOCK Supported, concurrent
+ reads/writes allowed.
+
+ @note The default implementation uses the old in-place ALTER API
+ to determine if the storage engine supports in-place ALTER or not.
+
+ @note Called without holding thr_lock.c lock.
+ */
+enum_alter_inplace_result
+ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
+ Alter_inplace_info *ha_alter_info)
+{
+ DBUG_ENTER("check_if_supported_alter");
+
+ bool idx= false, outward= false;
+ THD *thd= ha_thd();
+ 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;
+
+ if (!g || !table) {
+ my_message(ER_UNKNOWN_ERROR, "Cannot check ALTER operations", MYF(0));
+ DBUG_RETURN(HA_ALTER_ERROR);
+ } // endif Xchk
+
+ newopt= altered_table->s->option_struct;
+ oldopt= table->s->option_struct;
+
+ // If this is the start of a new query, cleanup the previous one
+ if (xp->CheckCleanup()) {
+ tdbp= NULL;
+ valid_info= false;
+ } // endif CheckCleanup
+
+ g->Alchecked= 1; // Tested in create
+ g->Xchk= NULL;
+ type= GetRealType(oldopt);
+ newtyp= GetRealType(newopt);
+
+ // No copy algorithm for outward tables
+ outward= (!IsFileType(type) || (oldopt->filename && *oldopt->filename));
+
+ // Index operations
+ Alter_inplace_info::HA_ALTER_FLAGS index_operations=
+ Alter_inplace_info::ADD_INDEX |
+ Alter_inplace_info::DROP_INDEX |
+ Alter_inplace_info::ADD_UNIQUE_INDEX |
+ Alter_inplace_info::DROP_UNIQUE_INDEX |
+ Alter_inplace_info::ADD_PK_INDEX |
+ Alter_inplace_info::DROP_PK_INDEX;
+
+ Alter_inplace_info::HA_ALTER_FLAGS inplace_offline_operations=
+ Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH |
+ Alter_inplace_info::ALTER_COLUMN_NAME |
+ Alter_inplace_info::ALTER_COLUMN_DEFAULT |
+ Alter_inplace_info::CHANGE_CREATE_OPTION |
+ Alter_inplace_info::ALTER_RENAME | index_operations;
+
+ if (ha_alter_info->handler_flags & index_operations ||
+ !SameChar(altered_table, "optname") ||
+ !SameBool(altered_table, "sepindex")) {
+ if (!IsTypeIndexable(type)) {
+ sprintf(g->Message, "Table type %s is not indexable", oldopt->type);
+ my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+ DBUG_RETURN(HA_ALTER_ERROR);
+ } // endif Indexable
+
+ g->Xchk= new(g) XCHK;
+ PCHK xcp= (PCHK)g->Xchk;
+
+ xcp->oldpix= GetIndexInfo(table->s);
+ xcp->newpix= GetIndexInfo(altered_table->s);
+ xcp->oldsep= GetBooleanOption("sepindex", false);
+ xcp->oldsep= xcp->SetName(g, GetStringOption("optname"));
+ tshp= altered_table->s;
+ xcp->newsep= GetBooleanOption("sepindex", false);
+ xcp->newsep= xcp->SetName(g, GetStringOption("optname"));
+ tshp= NULL;
+
+ if (xtrace && g->Xchk)
+ printf(
+ "oldsep=%d newsep=%d oldopn=%s newopn=%s oldpix=%p newpix=%p\n",
+ xcp->oldsep, xcp->newsep,
+ SVP(xcp->oldopn), SVP(xcp->newopn),
+ xcp->oldpix, xcp->newpix);
+
+ if (sqlcom == SQLCOM_ALTER_TABLE)
+ idx= true;
+ else
+ DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK);
+
+ } // endif index operation
+
+ if (!SameChar(altered_table, "filename")) {
+ if (!outward) {
+ // Conversion to outward table is only allowed for file based
+ // tables whose file does not exist.
+ tshp= altered_table->s;
+ char *fn= GetStringOption("filename");
+ tshp= NULL;
+
+ if (FileExists(fn)) {
+ strcpy(g->Message, "Operation denied. Table data would be lost.");
+ my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
+ DBUG_RETURN(HA_ALTER_ERROR);
+ } else
+ goto fin;
+
+ } else
+ goto fin;
+
+ } // endif filename
+
+ /* Is there at least one operation that requires copy algorithm? */
+ if (ha_alter_info->handler_flags & ~inplace_offline_operations)
+ goto fin;
+
+ /*
+ ALTER TABLE tbl_name CONVERT TO CHARACTER SET .. and
+ ALTER TABLE table_name DEFAULT CHARSET = .. most likely
+ change column charsets and so not supported in-place through
+ old API.
+
+ Changing of PACK_KEYS, MAX_ROWS and ROW_FORMAT options were
+ not supported as in-place operations in old API either.
+ */
+ if (create_info->used_fields & (HA_CREATE_USED_CHARSET |
+ HA_CREATE_USED_DEFAULT_CHARSET |
+ HA_CREATE_USED_PACK_KEYS |
+ HA_CREATE_USED_MAX_ROWS) ||
+ (table->s->row_type != create_info->row_type))
+ goto fin;
+
+#if 0
+ uint table_changes= (ha_alter_info->handler_flags &
+ Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH) ?
+ IS_EQUAL_PACK_LENGTH : IS_EQUAL_YES;
+
+ if (table->file->check_if_incompatible_data(create_info, table_changes)
+ == COMPATIBLE_DATA_YES)
+ DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK);
+#endif // 0
+
+ // This was in check_if_incompatible_data
+ if (type == newtyp &&
+ SameInt(altered_table, "lrecl") &&
+ SameInt(altered_table, "elements") &&
+ SameInt(altered_table, "header") &&
+ SameInt(altered_table, "quoted") &&
+ SameInt(altered_table, "ending") &&
+ SameInt(altered_table, "compressed"))
+ DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK);
+
+fin:
+ if (idx) {
+ // Indexing is only supported inplace
+ my_message(ER_UNKNOWN_ERROR,
+ "Alter operations not supported together by CONNECT", MYF(0));
+ DBUG_RETURN(HA_ALTER_ERROR);
+ } else if (outward) {
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
+ "This is an outward table, table data were not modified.");
+ DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK);
+ } else
+ DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
+
+} // end of check_if_supported_inplace_alter
+
/**
check_if_incompatible_data() called if ALTER TABLE can't detect otherwise
@@ -4818,46 +5343,17 @@ int ha_connect::create(const char *name, TABLE *table_arg,
(sql/sql_tables.cc) to decide should we rewrite whole table or only .frm
file.
+ @note: This function is no more called by check_if_supported_inplace_alter
*/
bool ha_connect::check_if_incompatible_data(HA_CREATE_INFO *info,
uint table_changes)
{
-//ha_table_option_struct *param_old, *param_new;
DBUG_ENTER("ha_connect::check_if_incompatible_data");
// TO DO: really implement and check it.
- THD *thd= current_thd;
-
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
- "The current version of CONNECT did not check what you changed in ALTER. Use at your own risk");
-
- if (table) {
- PTOS newopt= info->option_struct;
- PTOS oldopt= table->s->option_struct;
-
-#if 0
- if (newopt->sepindex != oldopt->sepindex) {
- // All indexes to be remade
- PGLOBAL g= GetPlug(thd);
-
- if (!g)
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
- "Execute OPTIMIZE TABLE to remake the indexes");
- else
- g->Xchk= new(g) XCHK;
-
- } // endif sepindex
-#endif // 0
-
- if (oldopt->type != newopt->type)
- DBUG_RETURN(COMPATIBLE_DATA_NO);
-
- if (newopt->filename)
- DBUG_RETURN(COMPATIBLE_DATA_NO);
-
- } // endif table
-
- DBUG_RETURN(COMPATIBLE_DATA_YES);
+ push_warning(ha_thd(), Sql_condition::WARN_LEVEL_WARN, 0,
+ "Unexpected call to check_if_incompatible_data.");
+ DBUG_RETURN(COMPATIBLE_DATA_NO);
} // end of check_if_incompatible_data
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h
index 754e2e37a7f..908c26fefdc 100644
--- a/storage/connect/ha_connect.h
+++ b/storage/connect/ha_connect.h
@@ -50,9 +50,20 @@ typedef struct _xinfo {
class XCHK : public BLOCK {
public:
- XCHK(void) {oldsep= newsep= false; oldpix= newpix= NULL;}
+ XCHK(void) {oldsep= newsep= false;
+ oldopn= newopn= NULL;
+ oldpix= newpix= NULL;}
+
+ inline char *SetName(PGLOBAL g, char *name) {
+ char *nm= NULL;
+ if (name) {nm= (char*)PlugSubAlloc(g, NULL, strlen(name) + 1);
+ strcpy(nm, name);}
+ return nm;}
+
bool oldsep; // Sepindex before create/alter
bool newsep; // Sepindex after create/alter
+ char *oldopn; // Optname before create/alter
+ char *newopn; // Optname after create/alter
PIXDEF oldpix; // The indexes before create/alter
PIXDEF newpix; // The indexes after create/alter
}; // end of class XCHK
@@ -156,15 +167,20 @@ public:
// CONNECT Implementation
static bool connect_init(void);
static bool connect_end(void);
+ TABTYPE GetRealType(PTOS pos);
char *GetStringOption(char *opname, char *sdef= NULL);
PTOS GetTableOptionStruct(TABLE *table_arg);
bool GetBooleanOption(char *opname, bool bdef);
bool SetBooleanOption(char *opname, bool b);
int GetIntegerOption(char *opname);
bool SetIntegerOption(char *opname, int n);
+ bool SameChar(TABLE *tab, char *opn);
+ bool SameInt(TABLE *tab, char *opn);
+ bool SameBool(TABLE *tab, char *opn);
+ bool FileExists(const char *fn);
PFOS GetFieldOptionStruct(Field *fp);
void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf);
- PIXDEF GetIndexInfo(void);
+ PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL);
const char *GetDBName(const char *name);
const char *GetTableName(void);
//int GetColNameLen(Field *fp);
@@ -199,18 +215,19 @@ public:
*/
const char **bas_ext() const;
+ /**
+ Check if a storage engine supports a particular alter table in-place
+ @note Called without holding thr_lock.c lock.
+ */
+ virtual enum_alter_inplace_result
+ check_if_supported_inplace_alter(TABLE *altered_table,
+ Alter_inplace_info *ha_alter_info);
+
/** @brief
This is a list of flags that indicate what functionality the storage engine
implements. The current table flags are documented in handler.h
*/
- ulonglong table_flags() const
- {
- return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_HAS_RECORDS |
- HA_NO_AUTO_INCREMENT | HA_NO_PREFIX_CHAR_KEYS |
- HA_NO_COPY_ON_ALTER | HA_CAN_VIRTUAL_COLUMNS |
- HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
- /*HA_NULL_IN_KEY |*/ HA_MUST_USE_TABLE_CONDITION_PUSHDOWN);
- }
+ ulonglong table_flags() const;
/** @brief
This is a bitmap of flags that indicates how the storage engine
@@ -464,6 +481,7 @@ protected:
XINFO xinfo; // The table info structure
bool valid_info; // True if xinfo is valid
bool stop; // Used when creating index
+ bool alter; // True when converting to other engine
int indexing; // Type of indexing for CONNECT
int locked; // Table lock
THR_LOCK_DATA lock_data;
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index 092d38a142a..dc5db156af0 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -259,6 +259,89 @@ uint GetFuncID(const char *func)
return fnc;
} // end of GetFuncID
+/***********************************************************************/
+/* OEMColumn: Get table column info for an OEM table. */
+/***********************************************************************/
+PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info)
+ {
+ typedef PQRYRES (__stdcall *XCOLDEF) (PGLOBAL, PVOID, char*, char*, bool);
+ const char *module, *subtype;
+ char c, getname[40] = "Col";
+#if defined(WIN32)
+ HANDLE hdll; /* Handle to the external DLL */
+#else // !WIN32
+ void *hdll; /* Handle for the loaded shared library */
+#endif // !WIN32
+ XCOLDEF coldef = NULL;
+ PQRYRES qrp = NULL;
+
+ module = topt->module;
+ subtype = topt->subtype;
+
+ if (!module || !subtype)
+ return NULL;
+
+ // The exported name is always in uppercase
+ for (int i = 0; ; i++) {
+ c = subtype[i];
+ getname[i + 3] = toupper(c);
+ if (!c) break;
+ } // endfor i
+
+#if defined(WIN32)
+ // Load the Dll implementing the table
+ if (!(hdll = LoadLibrary(module))) {
+ char buf[256];
+ DWORD rc = GetLastError();
+
+ sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, module);
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
+ (LPTSTR)buf, sizeof(buf), NULL);
+ strcat(strcat(g->Message, ": "), buf);
+ return NULL;
+ } // endif hDll
+
+ // Get the function returning an instance of the external DEF class
+ if (!(coldef = (XCOLDEF)GetProcAddress((HINSTANCE)hdll, getname))) {
+ sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), getname);
+ FreeLibrary((HMODULE)hdll);
+ return NULL;
+ } // endif coldef
+#else // !WIN32
+ const char *error = NULL;
+
+ // Load the desired shared library
+ if (!(hdll = dlopen(Module, RTLD_LAZY))) {
+ error = dlerror();
+ sprintf(g->Message, MSG(SHARED_LIB_ERR), Module, SVP(error));
+ return NULL;
+ } // endif Hdll
+
+ // Get the function returning an instance of the external DEF class
+ if (!(coldef = (XCOLDEF)dlsym(hdll, getname))) {
+ error = dlerror();
+ sprintf(g->Message, MSG(GET_FUNC_ERR), getname, SVP(error));
+ dlclose(hdll);
+ return NULL;
+ } // endif coldef
+#endif // !WIN32
+
+ // Just in case the external Get function does not set error messages
+ sprintf(g->Message, "Error getting column info from %s", subtype);
+
+ // Get the table column definition
+ qrp = coldef(g, topt, tab, db, info);
+
+#if defined(WIN32)
+ FreeLibrary((HMODULE)hdll);
+#else // !WIN32
+ dlclose(hdll);
+#endif // !WIN32
+
+ return qrp;
+ } // end of OEMColumns
+
/* ------------------------- Class CATALOG --------------------------- */
/***********************************************************************/
diff --git a/storage/connect/mysql-test/connect/r/bin.result b/storage/connect/mysql-test/connect/r/bin.result
index 10deb54cb2e..bbf5614b555 100644
--- a/storage/connect/mysql-test/connect/r/bin.result
+++ b/storage/connect/mysql-test/connect/r/bin.result
@@ -50,8 +50,6 @@ dept INT(4) NOT NULL FIELD_FORMAT='S'
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=NO;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -71,8 +69,6 @@ fig name birth id salary dept
5555 RONALD 1980-02-26 3333 4444.44 555
7777 BILL 1973-06-30 4444 5555.56 777
ALTER TABLE t1 READONLY=YES;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/storage/connect/mysql-test/connect/r/csv.result b/storage/connect/mysql-test/connect/r/csv.result
index 94fd95a5d83..3f424964881 100644
--- a/storage/connect/mysql-test/connect/r/csv.result
+++ b/storage/connect/mysql-test/connect/r/csv.result
@@ -63,8 +63,6 @@ Archibald 2001-05-17 3
Nabucho 2003-08-12 2
RONALD 1980-02-26 4
ALTER TABLE t1 READONLY=no;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -80,8 +78,6 @@ Nabucho 2003-08-12 2
RONALD 1980-02-26 4
BILL 1973-06-30 5
ALTER TABLE t1 READONLY=1;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/storage/connect/mysql-test/connect/r/dbf.result b/storage/connect/mysql-test/connect/r/dbf.result
index c7bb5739e75..bc09f85a631 100644
--- a/storage/connect/mysql-test/connect/r/dbf.result
+++ b/storage/connect/mysql-test/connect/r/dbf.result
@@ -69,8 +69,6 @@ a
10
20
ALTER TABLE t1 READONLY=Yes;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -85,8 +83,6 @@ ERROR HY000: Table 't1' is read only
TRUNCATE TABLE t1;
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=NO;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -508,12 +504,12 @@ DROP TABLE IF EXISTS t1;
CREATE TABLE t1
(
a VARCHAR(10) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
+) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1c.dbf';
INSERT INTO t1 VALUES ('10');
SELECT * FROM t1;
a
10
-CALL dbf_header('MYSQLD_DATADIR/test/t1.dbf');
+CALL dbf_header('MYSQLD_DATADIR/test/t1c.dbf');
-------- --------
FileSize 77
DBF_Version 03
@@ -532,17 +528,15 @@ Dec 0
Flags 00
-------- --------
ALTER TABLE t1 MODIFY a VARCHAR(10) NOT NULL;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(10) NOT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=DBF `FILE_NAME`='t1.dbf'
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=DBF `FILE_NAME`='t1c.dbf'
SELECT * FROM t1;
a
10
-CALL dbf_header('MYSQLD_DATADIR/test/t1.dbf');
+CALL dbf_header('MYSQLD_DATADIR/test/t1c.dbf');
-------- --------
FileSize 77
DBF_Version 03
@@ -561,15 +555,17 @@ Dec 0
Flags 00
-------- --------
ALTER TABLE t1 MODIFY a INT(10) NOT NULL;
+Warnings:
+Warning 1105 This is an outward table, table data were not modified.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(10) NOT NULL
-) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=DBF `FILE_NAME`='t1.dbf'
+) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=DBF `FILE_NAME`='t1c.dbf'
SELECT * FROM t1;
a
10
-CALL dbf_header('MYSQLD_DATADIR/test/t1.dbf');
+CALL dbf_header('MYSQLD_DATADIR/test/t1c.dbf');
-------- --------
FileSize 77
DBF_Version 03
diff --git a/storage/connect/mysql-test/connect/r/dir.result b/storage/connect/mysql-test/connect/r/dir.result
index f4feb5fa960..34a591fb26c 100644
--- a/storage/connect/mysql-test/connect/r/dir.result
+++ b/storage/connect/mysql-test/connect/r/dir.result
@@ -13,8 +13,6 @@ boys .txt 282
boys2 .txt 282
boyswin .txt 288
ALTER TABLE t1 OPTION_LIST='subdir=0';
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/storage/connect/mysql-test/connect/r/fix.result b/storage/connect/mysql-test/connect/r/fix.result
index c218561c3aa..96ba3f84a0d 100644
--- a/storage/connect/mysql-test/connect/r/fix.result
+++ b/storage/connect/mysql-test/connect/r/fix.result
@@ -22,8 +22,6 @@ SELECT * FROM t1;
id
10
ALTER TABLE t1 READONLY=1;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -38,8 +36,6 @@ ERROR HY000: Table 't1' is read only
TRUNCATE TABLE t1;
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=0;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/storage/connect/mysql-test/connect/r/index.result b/storage/connect/mysql-test/connect/r/index.result
index b365046a55d..bffaaecc785 100644
--- a/storage/connect/mysql-test/connect/r/index.result
+++ b/storage/connect/mysql-test/connect/r/index.result
@@ -37,8 +37,6 @@ SUM(brut)
# Testing file mapping
#
ALTER TABLE t1 MAPPED=yes;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SELECT * FROM t1 LIMIT 10;
matricule nom prenom sexe aanais mmnais ddentree ddnom brut net service sitmat formation
5745 ESCOURCHE BENEDICTE 2 1935 7 1962-12-01 1994-05-01 18345 14275.50 0 M TECHN
diff --git a/storage/connect/mysql-test/connect/r/ini.result b/storage/connect/mysql-test/connect/r/ini.result
index fa03435323e..79996eb8525 100644
--- a/storage/connect/mysql-test/connect/r/ini.result
+++ b/storage/connect/mysql-test/connect/r/ini.result
@@ -185,8 +185,6 @@ UK 10
FR 20
RU 30
ALTER TABLE t1 READONLY=1;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -202,8 +200,6 @@ ERROR HY000: Table 't1' is read only
TRUNCATE TABLE t1;
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=0;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/storage/connect/mysql-test/connect/r/occur.result b/storage/connect/mysql-test/connect/r/occur.result
index a497dfc9942..fbcda4660be 100644
--- a/storage/connect/mysql-test/connect/r/occur.result
+++ b/storage/connect/mysql-test/connect/r/occur.result
@@ -193,6 +193,8 @@ Kevin 8
Lisbeth 2
Mary 2
ALTER TABLE xpet MODIFY number INT NOT NULL;
+Warnings:
+Warning 1105 This is an outward table, table data were not modified.
SELECT * FROM xpet;
name race number
John dog 2
diff --git a/storage/connect/mysql-test/connect/r/pivot.result b/storage/connect/mysql-test/connect/r/pivot.result
index 11eee6233a4..2e4a924c8c3 100644
--- a/storage/connect/mysql-test/connect/r/pivot.result
+++ b/storage/connect/mysql-test/connect/r/pivot.result
@@ -44,8 +44,6 @@ Car DOUBLE(8,2) FLAG=1,
Food DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
ALTER TABLE pivex OPTION_LIST='port=PORT';
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SELECT * FROM pivex;
Who Week Beer Car Food
Beth 3 16.00 0.00 0.00
@@ -61,6 +59,8 @@ Joe 5 14.00 0.00 12.00
# Restricting the columns in a Pivot Table
#
ALTER TABLE pivex DROP COLUMN week;
+Warnings:
+Warning 1105 This is an outward table, table data were not modified.
SELECT * FROM pivex;
Who Beer Car Food
Beth 51.00 0.00 29.00
@@ -81,8 +81,6 @@ SRCDEF='select who, week, what, sum(amount) as amount from expenses where week i
Warnings:
Warning 1105 Cannot check looping reference
ALTER TABLE pivex OPTION_LIST='PivotCol=what,FncCol=amount,port=PORT';
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SELECT * FROM pivex;
Who Week Beer Car Food
Beth 4 15.00 0.00 17.00
@@ -103,8 +101,6 @@ What CHAR(12) NOT NULL,
`5` DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
ALTER TABLE pivex OPTION_LIST='PivotCol=Week,port=PORT';
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SELECT * FROM pivex;
Who What 3 4 5
Beth Beer 16.00 15.00 20.00
@@ -130,8 +126,6 @@ SRCDEF='select who, what, case when week=3 then ''First'' when week=5 then ''Las
Warnings:
Warning 1105 Cannot check looping reference
ALTER TABLE pivex OPTION_LIST='PivotCol=wk,FncCol=amnt,port=PORT';
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SELECT * FROM pivex;
Who What First Middle Last
Beth Beer 104.96 98.40 131.20
@@ -202,8 +196,6 @@ ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=
SELECT * FROM pivet;
ERROR HY000: Got error 122 'Cannot find matching column' from CONNECT
ALTER TABLE pivet OPTION_LIST='PivotCol=race,groupby=1,accept=1';
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SELECT * FROM pivet;
name dog cat
John 2 0
diff --git a/storage/connect/mysql-test/connect/r/vec.result b/storage/connect/mysql-test/connect/r/vec.result
index 926c0f2f4c6..e93305fb07a 100644
--- a/storage/connect/mysql-test/connect/r/vec.result
+++ b/storage/connect/mysql-test/connect/r/vec.result
@@ -94,8 +94,6 @@ t1vec .blk 8
# Testing READONLY
#
ALTER TABLE t1 READONLY=yes;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -111,8 +109,6 @@ ERROR HY000: Table 't1' is read only
TRUNCATE TABLE t1;
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=no;
-Warnings:
-Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/storage/connect/mysql-test/connect/r/xml.result b/storage/connect/mysql-test/connect/r/xml.result
index e412e44a9ba..aeb1f5edbcd 100644
--- a/storage/connect/mysql-test/connect/r/xml.result
+++ b/storage/connect/mysql-test/connect/r/xml.result
@@ -413,7 +413,7 @@ DROP TABLE t1;
SET @a=LOAD_FILE('MYSQLD_DATADIR/test/t1.xml');
SELECT CAST(@a AS CHAR CHARACTER SET latin1);
CAST(@a AS CHAR CHARACTER SET latin1) <?xml version="1.0" encoding="iso-8859-1"?>
-<!-- Created by CONNECT Version 1.01.0011 December 15, 2013 -->
+<!-- Created by CONNECT Version 1.02.0001 February 03, 2014 -->
<t1>
<line>
<node>ÀÁÂÃ</node>
diff --git a/storage/connect/mysql-test/connect/t/dbf.test b/storage/connect/mysql-test/connect/t/dbf.test
index 3fd30f98f20..7b364e9b921 100644
--- a/storage/connect/mysql-test/connect/t/dbf.test
+++ b/storage/connect/mysql-test/connect/t/dbf.test
@@ -442,30 +442,32 @@ DROP TABLE IF EXISTS t1;
--echo #
--echo # Testing ALTER
--echo #
+# Temporarily change the file name because ALTER that are not executed not in place
+# delete the data file when it has the same path/name than the default file name.
CREATE TABLE t1
(
a VARCHAR(10) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
+) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1c.dbf';
INSERT INTO t1 VALUES ('10');
SELECT * FROM t1;
---chmod 0777 $MYSQLD_DATADIR/test/t1.dbf
+--chmod 0777 $MYSQLD_DATADIR/test/t1c.dbf
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
-eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
+eval CALL dbf_header('$MYSQLD_DATADIR/test/t1c.dbf');
--horizontal_results
ALTER TABLE t1 MODIFY a VARCHAR(10) NOT NULL;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
-eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
+eval CALL dbf_header('$MYSQLD_DATADIR/test/t1c.dbf');
--horizontal_results
ALTER TABLE t1 MODIFY a INT(10) NOT NULL;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
--vertical_results
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
-eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
+eval CALL dbf_header('$MYSQLD_DATADIR/test/t1c.dbf');
--horizontal_results
# TODO: this does not work on Windows
@@ -478,7 +480,7 @@ eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
#eval CALL dbf_header('$MYSQLD_DATADIR/test/t1.dbf');
#--horizontal_results
DROP TABLE IF EXISTS t1;
---remove_file $MYSQLD_DATADIR/test/t1.dbf
+--remove_file $MYSQLD_DATADIR/test/t1c.dbf
--echo #
diff --git a/storage/connect/plgcnx.h b/storage/connect/plgcnx.h
index 7ce72b45268..fe3997d1986 100644
--- a/storage/connect/plgcnx.h
+++ b/storage/connect/plgcnx.h
@@ -1,6 +1,6 @@
/**************************************************************************/
/* PLGCNX.H */
-/* Copyright to the author: Olivier Bertrand 2000-2012 */
+/* Copyright to the author: Olivier Bertrand 2000-2014 */
/* */
/* This is the connection DLL's declares. */
/**************************************************************************/
@@ -62,6 +62,7 @@ enum INFO {INDX_RC, /* Index of PlugDB return code field */
INDX_SIZE, /* Index of returned data size field */
INDX_MAX}; /* Size of info array */
+#ifdef NOT_USED
/**************************************************************************/
/* Internal message types. */
/**************************************************************************/
@@ -97,9 +98,9 @@ enum VENDOR {VDR_UNKNOWN = -2, /* Not known or not connected */
/**************************************************************************/
enum CKEYS {K_ProgMsg, K_Lang, K_ActiveDB, K_Cmax};
enum LKEYS {K_NBcol, K_NBlin, K_CurPos, K_RC, K_Result, K_Elapsed,
- K_Continued, K_Maxsize, K_Lmax, K_Maxcol,
+ K_Continued, K_Maxsize, K_Affrows, K_Lmax, K_Maxcol,
K_Maxres, K_Maxlin, K_NBparm};
-enum NKEYS {K_Type, K_Length, K_Prec, K_DataLen, K_Nmax};
+enum NKEYS {K_Type, K_Length, K_Prec, K_DataLen, K_Unsigned, K_Nmax};
/**************************************************************************/
/* Result description structures. */
@@ -157,7 +158,6 @@ typedef struct _ResDesc {
#define XTRN
#endif
-#ifdef NOT_USED
//#if !defined(NO_FUNC)
#ifdef __cplusplus
extern "C" {
@@ -172,7 +172,7 @@ XTRN bool CNXFUNC(PLGGetCharValue)(CNXKEY, char *, int, int);
XTRN bool CNXFUNC(PLGGetIntValue)(CNXKEY, int *, int);
XTRN bool CNXFUNC(PLGGetColValue) (CNXKEY, int *, int, int);
XTRN bool CNXFUNC(PLGGetMessage) (CNXKEY, char *, int);
-XTRN bool CNXFUNC(PLGGetHeader) (CNXKEY, char *, int, int);
+XTRN bool CNXFUNC(PLGGetHeader) (CNXKEY, char *, int, int, int);
#ifdef __cplusplus
}
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index b62979451ee..e251ded13df 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -1,7 +1,7 @@
/************** PlgDBSem H Declares Source Code File (.H) **************/
-/* Name: PLGDBSEM.H Version 3.5 */
+/* Name: PLGDBSEM.H Version 3.6 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2012 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2014 */
/* */
/* This file contains the PlugDB++ application type definitions. */
/***********************************************************************/
@@ -166,7 +166,8 @@ enum MODE {MODE_ERROR = -1, /* Invalid mode */
MODE_WRITE = 20, /* Input/Output mode */
MODE_UPDATE = 30, /* Input/Output mode */
MODE_INSERT = 40, /* Input/Output mode */
- MODE_DELETE = 50}; /* Input/Output mode */
+ MODE_DELETE = 50, /* Input/Output mode */
+ MODE_ALTER = 60}; /* alter mode */
#if !defined(RC_OK_DEFINED)
#define RC_OK_DEFINED
@@ -549,8 +550,6 @@ PPARM Vcolist(PGLOBAL, PTDB, PSZ, bool);
void PlugPutOut(PGLOBAL, FILE *, short, void *, uint);
void PlugLineDB(PGLOBAL, PSZ, short, void *, uint);
char *PlgGetDataPath(PGLOBAL g);
-void *PlgDBalloc(PGLOBAL, void *, MBLOCK&);
-void *PlgDBrealloc(PGLOBAL, void *, MBLOCK&, size_t);
void AddPointer(PTABS, void *);
PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int);
int ExtractDate(char *, PDTP, int, int val[6]);
@@ -558,9 +557,10 @@ int ExtractDate(char *, PDTP, int, int val[6]);
/**************************************************************************/
/* Allocate the result structure that will contain result data. */
/**************************************************************************/
-PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
- int *buftyp, XFLD *fldtyp,
- unsigned int *length, bool blank, bool nonull);
+DllExport PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
+ int *buftyp, XFLD *fldtyp,
+ unsigned int *length,
+ bool blank, bool nonull);
/***********************************************************************/
/* Exported utility routines. */
@@ -576,12 +576,16 @@ DllExport PCATLG PlgGetCatalog(PGLOBAL g, bool jump = true);
DllExport bool PlgSetXdbPath(PGLOBAL g, PSZ, PSZ, char *, int, char *, int);
DllExport void PlgDBfree(MBLOCK&);
DllExport void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size);
+DllExport void *PlgDBalloc(PGLOBAL, void *, MBLOCK&);
+DllExport void *PlgDBrealloc(PGLOBAL, void *, MBLOCK&, size_t);
//lExport PSZ GetIniString(PGLOBAL, void *, LPCSTR, LPCSTR, LPCSTR, LPCSTR);
//lExport int GetIniSize(char *, char *, char *, char *);
//lExport bool WritePrivateProfileInt(LPCSTR, LPCSTR, int, LPCSTR);
DllExport void NewPointer(PTABS, void *, void *);
DllExport char *GetIni(int n= 0);
DllExport void SetTrc(void);
+DllExport char *GetListOption(PGLOBAL, const char *, const char *,
+ const char *def=NULL);
#define MSGID_NONE 0
#define MSGID_CANNOT_OPEN 1
@@ -597,4 +601,4 @@ int global_open(GLOBAL *g, int msgid, const char *filename, int flags, int mode)
DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir);
char *MakeEscape(PGLOBAL g, char* str, char q);
-bool PushWarning(PGLOBAL, PTDBASE, int level = 1);
+DllExport bool PushWarning(PGLOBAL, PTDBASE, int level = 1);
diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp
index b5c4239c992..c3c74463271 100644
--- a/storage/connect/plgdbutl.cpp
+++ b/storage/connect/plgdbutl.cpp
@@ -1,11 +1,11 @@
/********** PlgDBUtl Fpe C++ Program Source Code File (.CPP) ***********/
/* PROGRAM NAME: PLGDBUTL */
/* ------------- */
-/* Version 3.8 */
+/* Version 3.9 */
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 1998-2013 */
+/* (C) Copyright to the author Olivier BERTRAND 1998-2014 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -90,6 +90,7 @@ bool Initdone = false;
bool plugin = false; // True when called by the XDB plugin handler
extern "C" {
+extern char connectini[];
char plgxini[_MAX_PATH] = PLGXINI;
char plgini[_MAX_PATH] = PLGINI;
#if defined(WIN32)
@@ -232,6 +233,7 @@ DllExport char *GetIni(int n)
#if defined(XMSG)
case 5: return msglang; break;
#endif // XMSG
+ case 6: return connectini; break;
// default: return plgini;
} // endswitch GetIni
@@ -1329,7 +1331,7 @@ void *PlgDBalloc(PGLOBAL g, void *area, MBLOCK& mp)
maxsub = (pph->FreeBlk < minsub) ? 0 : pph->FreeBlk - minsub;
mp.Sub = mp.Size <= ((mp.Sub) ? maxsub : (maxsub >> 2));
- if (trace)
+ if (trace > 1)
htrc("PlgDBalloc: in %p size=%d used=%d free=%d sub=%d\n",
arp, mp.Size, pph->To_Free, pph->FreeBlk, mp.Sub);
@@ -1372,7 +1374,7 @@ void *PlgDBrealloc(PGLOBAL g, void *area, MBLOCK& mp, size_t newsize)
// assert (mp.Memp != NULL);
#endif
- if (trace)
+ if (trace > 1)
htrc("PlgDBrealloc: %p size=%d sub=%d\n", mp.Memp, mp.Size, mp.Sub);
if (newsize == mp.Size)
@@ -1429,7 +1431,7 @@ void *PlgDBrealloc(PGLOBAL g, void *area, MBLOCK& mp, size_t newsize)
/***********************************************************************/
void PlgDBfree(MBLOCK& mp)
{
- if (trace)
+ if (trace > 1)
htrc("PlgDBfree: %p sub=%d size=%d\n", mp.Memp, mp.Sub, mp.Size);
if (!mp.Sub && mp.Memp)
diff --git a/storage/connect/plugutil.c b/storage/connect/plugutil.c
index ec2ac399ad0..91b850022fb 100644
--- a/storage/connect/plugutil.c
+++ b/storage/connect/plugutil.c
@@ -152,6 +152,7 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
g->Sarea_Size = worksize;
g->Trace = 0;
g->Createas = 0;
+ g->Alchecked = 0;
g->Activityp = g->ActivityStart = NULL;
g->Xchk = NULL;
strcpy(g->Message, "");
diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp
index 2358dc07638..99063e86b57 100644
--- a/storage/connect/tabfix.cpp
+++ b/storage/connect/tabfix.cpp
@@ -331,7 +331,7 @@ void BINCOL::ReadColumn(PGLOBAL g)
int rc;
PTDBFIX tdbp = (PTDBFIX)To_Tdb;
- if (trace)
+ if (trace > 1)
htrc("BIN ReadColumn: col %s R%d coluse=%.4X status=%.4X buf_type=%d\n",
Name, tdbp->GetTdb_No(), ColUse, Status, Buf_Type);
diff --git a/storage/connect/table.cpp b/storage/connect/table.cpp
index efe203e8e75..37035ed752d 100644
--- a/storage/connect/table.cpp
+++ b/storage/connect/table.cpp
@@ -1,7 +1,7 @@
/************** Table C++ Functions Source Code File (.CPP) ************/
-/* Name: TABLE.CPP Version 2.6 */
+/* Name: TABLE.CPP Version 2.7 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 1999-2013 */
+/* (C) Copyright to the author Olivier BERTRAND 1999-2014 */
/* */
/* This file contains the TBX, TDB and OPJOIN classes functions. */
/***********************************************************************/
@@ -263,6 +263,17 @@ PCATLG TDBASE::GetCat(void)
} // end of GetCat
/***********************************************************************/
+/* Return the pointer on the charset of this table. */
+/***********************************************************************/
+CHARSET_INFO *TDBASE::data_charset(void)
+ {
+ // If no DATA_CHARSET is specified, we assume that character
+ // set of the remote data is the same with CHARACTER SET
+ // definition of the SQL column.
+ return m_data_charset ? m_data_charset : &my_charset_bin;
+ } // end of data_charset
+
+/***********************************************************************/
/* Return the datapath of the DB this table belongs to. */
/***********************************************************************/
PSZ TDBASE::GetPath(void)
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index fcf083bcbce..564eddbaf2b 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -1283,7 +1283,7 @@ void MYSQLCOL::ReadColumn(PGLOBAL g)
tdbp->Fetched = TRUE;
if ((buf = ((PTDBMY)To_Tdb)->Myc.GetCharField(Rank))) {
- if (trace)
+ if (trace > 1)
htrc("MySQL ReadColumn: name=%s buf=%s\n", Name, buf);
// TODO: have a true way to differenciate temporal values
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index 5fef4fd9ef0..aa1133b0e92 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -1,9 +1,9 @@
/************* Tabxml C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABXML */
/* ------------- */
-/* Version 2.6 */
+/* Version 2.7 */
/* */
-/* Author Olivier BERTRAND 2007 - 2013 */
+/* Author Olivier BERTRAND 2007 - 2014 */
/* */
/* This program are the XML tables classes using MS-DOM or libxml2. */
/***********************************************************************/
@@ -47,6 +47,7 @@
#include "xindex.h"
#include "plgxml.h"
#include "tabxml.h"
+#include "tabmul.h"
extern "C" {
extern char version[];
@@ -136,7 +137,8 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
} // endswitch typname
Tabname = Cat->GetStringCatInfo(g, "Name", Name); // Deprecated
- Tabname = Cat->GetStringCatInfo(g, "Table_name", Tabname);
+ Tabname = Cat->GetStringCatInfo(g, "Table_name", Tabname); // Deprecated
+ Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
Rowname = Cat->GetStringCatInfo(g, "Rownode", defrow);
Colname = Cat->GetStringCatInfo(g, "Colnode", defcol);
Mulnode = Cat->GetStringCatInfo(g, "Mulnode", "");
@@ -177,7 +179,12 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
/***********************************************************************/
PTDB XMLDEF::GetTable(PGLOBAL g, MODE m)
{
- return new(g) TDBXML(this);
+ PTDBASE tdbp = new(g) TDBXML(this);
+
+ if (Multiple)
+ tdbp = new(g) TDBMUL(tdbp);
+
+ return tdbp;
} // end of GetTable
/***********************************************************************/
@@ -245,6 +252,7 @@ TDBXML::TDBXML(PXMLDEF tdp) : TDBASE(tdp)
Void = false;
Usedom = tdp->Usedom;
Header = tdp->Header;
+ Multiple = tdp->Multiple;
Nrow = -1;
Irow = Header - 1;
Nsub = 0;
@@ -287,6 +295,7 @@ TDBXML::TDBXML(PTDBXML tdbp) : TDBASE(tdbp)
Void = tdbp->Void;
Usedom = tdbp->Usedom;
Header = tdbp->Header;
+ Multiple = tdbp->Multiple;
Nrow = tdbp->Nrow;
Irow = tdbp->Irow;
Nsub = tdbp->Nsub;
@@ -578,7 +587,7 @@ bool TDBXML::Initialize(PGLOBAL g)
#endif
} // end of try-catches
- if (Root && Columns && !Nodedone) {
+ if (Root && Columns && (Multiple || !Nodedone)) {
// Allocate class nodes to avoid dynamic allocation
for (colp = (PXMLCOL)Columns; colp; colp = (PXMLCOL)colp->GetNext())
if (!colp->IsSpecial()) // Not a pseudo column
@@ -671,7 +680,10 @@ void TDBXML::SetNodeAttr(PGLOBAL g, char *attr, PXNODE node)
int TDBXML::Cardinality(PGLOBAL g)
{
if (!g)
- return (Xpand || Coltype == 2) ? 0 : 1;
+ return (Multiple || Xpand || Coltype == 2) ? 0 : 1;
+
+ if (Multiple)
+ return 10;
if (Nrow < 0)
if (Initialize(g))
@@ -685,8 +697,13 @@ int TDBXML::Cardinality(PGLOBAL g)
/***********************************************************************/
int TDBXML::GetMaxSize(PGLOBAL g)
{
- if (MaxSize < 0)
- MaxSize = Cardinality(g) * ((Xpand) ? Limit : 1);
+ if (MaxSize < 0) {
+ if (!Multiple)
+ MaxSize = Cardinality(g) * ((Xpand) ? Limit : 1);
+ else
+ MaxSize = 10;
+
+ } // endif MaxSize
return MaxSize;
} // end of GetMaxSize
@@ -952,6 +969,34 @@ void TDBXML::CloseDB(PGLOBAL g)
Docp->CloseDoc(g, To_Xb);
} // endif docp
+ if (Multiple) {
+ // Reset all constants to start a new parse
+ Docp = NULL;
+ Root = NULL;
+ Curp = NULL;
+ DBnode = NULL;
+ TabNode = NULL;
+ RowNode = NULL;
+ ColNode = NULL;
+ Nlist = NULL;
+ Clist = NULL;
+ To_Xb = NULL;
+ Colp = NULL;
+ Changed = false;
+ Checked = false;
+ NextSame = false;
+ NewRow = false;
+ Hasnod = false;
+ Write = false;
+// Bufdone = false;
+ Nodedone = false;
+ Void = false;
+ Nrow = -1;
+ Irow = Header - 1;
+ Nsub = 0;
+ N = 0;
+ } // endif Multiple
+
} // end of CloseDB
// ------------------------ XMLCOL functions ----------------------------
diff --git a/storage/connect/tabxml.h b/storage/connect/tabxml.h
index 5aa038530c7..817bea45b3b 100644
--- a/storage/connect/tabxml.h
+++ b/storage/connect/tabxml.h
@@ -139,6 +139,7 @@ class DllExport TDBXML : public TDBASE {
int Coltype; // Default column type
int Limit; // Limit of multiple values
int Header; // n first rows are header rows
+ int Multiple; // If multiple files
int Nrow; // The table cardinality
int Irow; // The current row index
int Nsub; // The current subrow index
diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc
index 877f612fc0a..b778d3f0883 100644
--- a/storage/connect/user_connect.cc
+++ b/storage/connect/user_connect.cc
@@ -146,6 +146,7 @@ bool user_connect::CheckCleanup(void)
PlugSubSet(g, g->Sarea, g->Sarea_Size);
g->Xchk = NULL;
g->Createas = 0;
+ g->Alchecked = 0;
last_query_id= thdp->query_id;
if (xtrace)
diff --git a/storage/connect/valblk.cpp b/storage/connect/valblk.cpp
index bef5d6ef716..c0127072896 100644
--- a/storage/connect/valblk.cpp
+++ b/storage/connect/valblk.cpp
@@ -1,7 +1,7 @@
/************ Valblk C++ Functions Source Code File (.CPP) *************/
-/* Name: VALBLK.CPP Version 2.0 */
+/* Name: VALBLK.CPP Version 2.1 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */
+/* (C) Copyright to the author Olivier BERTRAND 2005-2014 */
/* */
/* This file contains the VALBLK and derived classes functions. */
/* Second family is VALBLK, representing simple suballocated arrays */
@@ -237,6 +237,23 @@ void TYPBLK<TYPE>::Init(PGLOBAL g, bool check)
} // end of Init
/***********************************************************************/
+/* TYPVAL GetCharString: get string representation of a typed value. */
+/***********************************************************************/
+template <class TYPE>
+char *TYPBLK<TYPE>::GetCharString(char *p, int n)
+ {
+ sprintf(p, Fmt, Typp[n]);
+ return p;
+ } // end of GetCharString
+
+template <>
+char *TYPBLK<double>::GetCharString(char *p, int n)
+ {
+ sprintf(p, Fmt, Prec, Typp[n]);
+ return p;
+ } // end of GetCharString
+
+/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
template <class TYPE>
@@ -678,6 +695,14 @@ double CHRBLK::GetFloatValue(int n)
} // end of GetFloatValue
/***********************************************************************/
+/* STRING GetCharString: get string representation of a char value. */
+/***********************************************************************/
+char *CHRBLK::GetCharString(char *p, int n)
+ {
+ return (char *)GetValPtrEx(n);
+ } // end of GetCharString
+
+/***********************************************************************/
/* Set one value in a block. */
/***********************************************************************/
void CHRBLK::SetValue(PVAL valp, int n)
@@ -1186,6 +1211,22 @@ bool DATBLK::SetFormat(PGLOBAL g, PSZ fmt, int len, int year)
} // end of SetFormat
/***********************************************************************/
+/* DTVAL GetCharString: get string representation of a date value. */
+/***********************************************************************/
+char *DATBLK::GetCharString(char *p, int n)
+ {
+ char *vp;
+
+ if (Dvalp) {
+ Dvalp->SetValue(Typp[n]);
+ vp = Dvalp->GetCharString(p);
+ } else
+ vp = TYPBLK<int>::GetCharString(p, n);
+
+ return vp;
+ } // end of GetCharString
+
+/***********************************************************************/
/* Set one value in a block from a char string. */
/***********************************************************************/
void DATBLK::SetValue(PSZ p, int n)
diff --git a/storage/connect/valblk.h b/storage/connect/valblk.h
index debeb0669b0..1edfe7f76b4 100644
--- a/storage/connect/valblk.h
+++ b/storage/connect/valblk.h
@@ -1,7 +1,7 @@
/*************** Valblk H Declares Source Code File (.H) ***************/
-/* Name: VALBLK.H Version 2.0 */
+/* Name: VALBLK.H Version 2.1 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */
+/* (C) Copyright to the author Olivier BERTRAND 2005-2014 */
/* */
/* This file contains the VALBLK and derived classes declares. */
/***********************************************************************/
@@ -58,6 +58,7 @@ class VALBLK : public BLOCK {
virtual longlong GetBigintValue(int n) = 0;
virtual ulonglong GetUBigintValue(int n) = 0;
virtual double GetFloatValue(int n) = 0;
+ virtual char *GetCharString(char *p, int n) = 0;
virtual void ReAlloc(void *mp, int n) {Blkp = mp; Nval = n;}
virtual void Reset(int n) = 0;
virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
@@ -133,6 +134,7 @@ class TYPBLK : public VALBLK {
virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];}
virtual double GetFloatValue(int n) {return (double)Typp[n];}
+ virtual char *GetCharString(char *p, int n);
virtual void Reset(int n) {Typp[n] = 0;}
// Methods
@@ -199,6 +201,7 @@ class CHRBLK : public VALBLK {
virtual longlong GetBigintValue(int n);
virtual ulonglong GetUBigintValue(int n);
virtual double GetFloatValue(int n);
+ virtual char *GetCharString(char *p, int n);
virtual void Reset(int n);
virtual void SetPrec(int p) {Ci = (p != 0);}
virtual bool IsCi(void) {return Ci;}
@@ -252,6 +255,7 @@ class STRBLK : public VALBLK {
virtual longlong GetBigintValue(int n);
virtual ulonglong GetUBigintValue(int n);
virtual double GetFloatValue(int n) {return atof(Strp[n]);}
+ virtual char *GetCharString(char *p, int n) {return Strp[n];}
virtual void Reset(int n) {Strp[n] = NULL;}
// Methods
@@ -286,10 +290,11 @@ class DATBLK : public TYPBLK<int> {
DATBLK(void *mp, int size);
// Implementation
- virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
+ virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
+ virtual char *GetCharString(char *p, int n);
// Methods
- virtual void SetValue(PSZ sp, int n);
+ virtual void SetValue(PSZ sp, int n);
protected:
// Members
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index 65a08ba277e..8a839f3b50b 100644
--- a/storage/connect/value.cpp
+++ b/storage/connect/value.cpp
@@ -1,7 +1,7 @@
/************* Value C++ Functions Source Code File (.CPP) *************/
-/* Name: VALUE.CPP Version 2.3 */
+/* Name: VALUE.CPP Version 2.4 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2001-2013 */
+/* (C) Copyright to the author Olivier BERTRAND 2001-2014 */
/* */
/* This file contains the VALUE and derived classes family functions. */
/* These classes contain values of different types. They are used so */
@@ -1142,7 +1142,11 @@ void TYPVAL<PSZ>::SetValue_psz(PSZ s)
void TYPVAL<PSZ>::SetValue_pvblk(PVBLK blk, int n)
{
// STRBLK's can return a NULL pointer
- SetValue_psz(blk->GetCharValue(n));
+ PSZ vp = blk->GetCharString(Strp, n);
+
+ if (vp != Strp)
+ SetValue_psz(vp);
+
} // end of SetValue_pvblk
/***********************************************************************/
diff --git a/storage/connect/xtable.h b/storage/connect/xtable.h
index 174ceb19731..8884860cb5b 100644
--- a/storage/connect/xtable.h
+++ b/storage/connect/xtable.h
@@ -1,7 +1,7 @@
/**************** Table H Declares Source Code File (.H) ***************/
-/* Name: TABLE.H Version 2.2 */
+/* Name: TABLE.H Version 2.3 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 1999-2012 */
+/* (C) Copyright to the author Olivier BERTRAND 1999-2014 */
/* */
/* This file contains the TBX, OPJOIN and TDB class definitions. */
/***********************************************************************/
@@ -185,15 +185,7 @@ class DllExport TDBASE : public TDB {
virtual bool SetRecpos(PGLOBAL g, int recpos);
virtual bool IsReadOnly(void) {return Read_Only;}
virtual bool IsView(void) {return FALSE;}
- virtual CHARSET_INFO *data_charset()
- {
- /*
- If no DATA_CHARSET is specified, we assume that character
- set of the remote data is the same with CHARACTER SET
- definition of the SQL column.
- */
- return m_data_charset ? m_data_charset : &my_charset_bin;
- }
+ virtual CHARSET_INFO *data_charset(void);
virtual int GetProgMax(PGLOBAL g) {return GetMaxSize(g);}
virtual int GetProgCur(void) {return GetRecpos();}
virtual PSZ GetFile(PGLOBAL g) {return "Not a file";}
@@ -229,7 +221,7 @@ class DllExport TDBASE : public TDB {
/***********************************************************************/
/* The abstract base class declaration for the catalog tables. */
/***********************************************************************/
-class TDBCAT : public TDBASE {
+class DllExport TDBCAT : public TDBASE {
friend class CATCOL;
public:
// Constructor
@@ -268,7 +260,7 @@ class TDBCAT : public TDBASE {
/***********************************************************************/
/* Class CATCOL: ODBC info column. */
/***********************************************************************/
-class CATCOL : public COLBLK {
+class DllExport CATCOL : public COLBLK {
friend class TDBCAT;
public:
// Constructors