summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--storage/connect/filamdbf.cpp58
-rw-r--r--storage/connect/ha_connect.cc124
-rw-r--r--storage/connect/ha_connect.h4
-rw-r--r--storage/connect/odbconn.cpp2
-rw-r--r--storage/connect/reldef.cpp19
-rw-r--r--storage/connect/reldef.h1
-rw-r--r--storage/connect/tabfix.cpp1
-rw-r--r--storage/connect/tabfmt.cpp2
-rw-r--r--storage/connect/tabutil.cpp123
-rw-r--r--storage/connect/tabutil.h20
-rwxr-xr-xstorage/connect/xindex.cpp6
11 files changed, 254 insertions, 106 deletions
diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp
index 7ac81117f35..7ca98eeff55 100644
--- a/storage/connect/filamdbf.cpp
+++ b/storage/connect/filamdbf.cpp
@@ -546,10 +546,11 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
PDOSDEF tdp = (PDOSDEF)Tdbp->GetDef();
// Count the number of columns
- for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) {
- reclen += cdp->GetLong();
- n++;
- } // endfor cdp
+ for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
+ if (!(cdp->Flags & U_SPECIAL)) {
+ reclen += cdp->GetLong();
+ n++;
+ } // endif Flags
if (Lrecl != reclen) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, reclen);
@@ -570,30 +571,31 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
descp = (DESCRIPTOR*)header;
// Currently only standard Xbase types are supported
- for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) {
- descp++;
-
- switch ((c = *GetFormatType(cdp->GetType()))) {
- case 'S': // Short integer
- case 'L': // Large (big) integer
- case 'T': // Tiny integer
- c = 'N'; // Numeric
- case 'N': // Numeric (integer)
- case 'F': // Float (double)
- descp->Decimals = (uchar)cdp->F.Prec;
- case 'C': // Char
- case 'D': // Date
- break;
- default: // Should never happen
- sprintf(g->Message, "Unsupported DBF type %c for column %s",
- c, cdp->GetName());
- return true;
- } // endswitch c
-
- strncpy(descp->Name, cdp->GetName(), 11);
- descp->Type = c;
- descp->Length = (uchar)cdp->GetLong();
- } // endfor cdp
+ for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
+ if (!(cdp->Flags & U_SPECIAL)) {
+ descp++;
+
+ switch ((c = *GetFormatType(cdp->GetType()))) {
+ case 'S': // Short integer
+ case 'L': // Large (big) integer
+ case 'T': // Tiny integer
+ c = 'N'; // Numeric
+ case 'N': // Numeric (integer)
+ case 'F': // Float (double)
+ descp->Decimals = (uchar)cdp->F.Prec;
+ case 'C': // Char
+ case 'D': // Date
+ break;
+ default: // Should never happen
+ sprintf(g->Message, "Unsupported DBF type %c for column %s",
+ c, cdp->GetName());
+ return true;
+ } // endswitch c
+
+ strncpy(descp->Name, cdp->GetName(), 11);
+ descp->Type = c;
+ descp->Length = (uchar)cdp->GetLong();
+ } // endif Flags
*(char*)(++descp) = EOH;
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 37141e5c290..297af710ba8 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -119,6 +119,7 @@
#if defined(NEW_WAY)
#include "sql_table.h"
#endif // NEW_WAY
+#include "sql_partition.h"
#undef OFFSET
#define NOPARSE
@@ -173,6 +174,12 @@ extern "C" {
char version[]= "Version 1.03.0002 May 03, 2014";
char compver[]= "Version 1.03.0002 " __DATE__ " " __TIME__;
+#if defined(WIN32)
+ char slash= '\\';
+#else // !WIN32
+ char slash= '/';
+#endif // !WIN32
+
#if defined(XMSG)
char msglang[]; // Default message language
#endif
@@ -433,10 +440,10 @@ static int connect_init_func(void *p)
init_connect_psi_keys();
connect_hton= (handlerton *)p;
- connect_hton->state= SHOW_OPTION_YES;
+ connect_hton->state= SHOW_OPTION_YES;
connect_hton->create= connect_create_handler;
-//connect_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED | HTON_NO_PARTITION;
- connect_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED;
+//connect_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED | HTON_NO_PARTITION;
+ connect_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED;
connect_hton->table_options= connect_table_option_list;
connect_hton->field_options= connect_field_option_list;
connect_hton->index_options= connect_index_option_list;
@@ -538,7 +545,7 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg)
sdvalout= NULL;
xmod= MODE_ANY;
istable= false;
-//*tname= '\0';
+ *partname= 0;
bzero((char*) &xinfo, sizeof(XINFO));
valid_info= false;
valid_query_id= 0;
@@ -1264,6 +1271,16 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
return toidx;
} // end of GetIndexInfo
+bool ha_connect::IsPartitioned(void)
+{
+ if (tshp)
+ return tshp->partition_info_str_len > 0;
+ else if (table && table->part_info)
+ return true;
+ else
+ return false;
+} // end of IsPartitioned
+
const char *ha_connect::GetDBName(const char* name)
{
return (name) ? name : table->s->db.str;
@@ -1274,6 +1291,11 @@ const char *ha_connect::GetTableName(void)
return (tshp) ? tshp->table_name.str : table_share->table_name.str;
} // end of GetTableName
+char *ha_connect::GetPartName(void)
+{
+ return (IsPartitioned()) ? partname : (char*)GetTableName();
+} // end of GetTableName
+
#if 0
/****************************************************************************/
/* Returns the column real or special name length of a field. */
@@ -2474,6 +2496,15 @@ int ha_connect::open(const char *name, int mode, uint test_if_locked)
} else
mrr= false;
+#if defined(WITH_PARTITION_STORAGE_ENGINE)
+ if (table->part_info) {
+ if (GetStringOption("Filename") || GetStringOption("Tabname"))
+ strcpy(partname, strrchr(name, '#') + 1);
+ else // Inward table
+ strcpy(partname, strrchr(name, slash) + 1);
+
+ } // endif part_info
+#endif // WITH_PARTITION_STORAGE_ENGINE
} else
rc= HA_ERR_INTERNAL_ERROR;
@@ -2487,6 +2518,7 @@ int ha_connect::open(const char *name, int mode, uint test_if_locked)
int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt)
{
int rc= 0;
+ bool dop= (check_opt != NULL);
PGLOBAL& g= xp->g;
PDBUSER dup= PlgGetUser(g);
@@ -2498,7 +2530,7 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt)
if (tdbp) {
bool b= (((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
- if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, true, b))) {
+ if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, dop, b))) {
if (rc == RC_INFO) {
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
rc= 0;
@@ -2980,7 +3012,6 @@ int ha_connect::index_next_same(uchar *buf, const uchar *key, uint keylen)
*/
int ha_connect::rnd_init(bool scan)
{
- int rc;
PGLOBAL g= ((table && table->in_use) ? GetPlug(table->in_use, xp) :
(xp) ? xp->g : NULL);
DBUG_ENTER("ha_connect::rnd_init");
@@ -3014,8 +3045,8 @@ int ha_connect::rnd_init(bool scan)
if (xmod == MODE_UPDATE)
bitmap_union(table->read_set, table->write_set);
- if ((rc= OpenTable(g, xmod == MODE_DELETE)))
- DBUG_RETURN(rc);
+ if (OpenTable(g, xmod == MODE_DELETE))
+ DBUG_RETURN(HA_ERR_INITIALIZATION);
xp->nrd= xp->fnd= xp->nfd= 0;
xp->tb1= my_interval_timer();
@@ -3934,11 +3965,6 @@ filename_to_dbname_and_tablename(const char *filename,
char *database, size_t database_size,
char *table, size_t table_size)
{
-#if defined(WIN32)
- char slash= '\\';
-#else // !WIN32
- char slash= '/';
-#endif // !WIN32
LEX_CSTRING d, t;
size_t length= strlen(filename);
@@ -4013,29 +4039,27 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to)
// 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 != '#') {
+ // Also, for partitioned tables, no test can be done because when
+ // this function is called, the .par file is already deleted and
+ // this causes the open_table_def function to fail.
+ // Not having any other clues (table and table_share are NULL)
+ // the only mean we have to test for partitioning is this:
+ if (*tabname != '#' && !strstr(tabname, "#P#")) {
// 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;
+// if ((p= strstr(tabname, "#P#"))) won't work, see above
+// *p= 0; // Get the main the table name
+
key_length= tdc_create_key(key, db, tabname);
// share contains the option struct that we need
if (!(share= alloc_table_share(db, tabname, key, key_length)))
DBUG_RETURN(rc);
-#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
@@ -5111,12 +5135,16 @@ int ha_connect::create(const char *name, TABLE *table_arg,
TABTYPE type;
TABLE *st= table; // Probably unuseful
THD *thd= ha_thd();
+#if defined(WITH_PARTITION_STORAGE_ENGINE)
+ partition_info *part_info= table_arg->part_info;
+#endif // WITH_PARTITION_STORAGE_ENGINE
xp= GetUser(thd, xp);
PGLOBAL g= xp->g;
DBUG_ENTER("ha_connect::create");
int sqlcom= thd_sql_command(table_arg->in_use);
PTOS options= GetTableOptionStruct(table_arg->s);
+ bool inward= !options->filename;
table= table_arg; // Used by called functions
@@ -5395,7 +5423,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endfor field
if ((sqlcom == SQLCOM_CREATE_TABLE || *GetTableName() == '#')
- && IsFileType(type) && !options->filename) {
+ && IsFileType(type) && inward) {
// 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
@@ -5403,8 +5431,6 @@ int ha_connect::create(const char *name, TABLE *table_arg,
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,
@@ -5432,13 +5458,28 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} else
lwt[i]= tolower(options->type[i]);
- strcat(strcat(buf, "."), lwt);
- sprintf(g->Message, "No file name. Table will use %s", buf);
+#if defined(WITH_PARTITION_STORAGE_ENGINE)
+ if (part_info) {
+ char *p;
- if (sqlcom == SQLCOM_CREATE_TABLE)
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+ strcpy(dbpath, name);
+ p= strrchr(dbpath, slash);
+ strcpy(partname, ++p);
+ strcat(strcat(strcpy(buf, p), "."), lwt);
+ *p= 0;
+ } else {
+#endif // WITH_PARTITION_STORAGE_ENGINE
+ strcat(strcat(strcpy(buf, GetTableName()), "."), lwt);
+ sprintf(g->Message, "No file name. Table will use %s", buf);
+
+ if (sqlcom == SQLCOM_CREATE_TABLE)
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+
+ strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/");
+#if defined(WITH_PARTITION_STORAGE_ENGINE)
+ } // endif part_info
+#endif // WITH_PARTITION_STORAGE_ENGINE
- strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/");
PlugSetPath(fn, buf, dbpath);
if ((h= ::open(fn, O_CREAT | O_EXCL, 0666)) == -1) {
@@ -5455,19 +5496,21 @@ int ha_connect::create(const char *name, TABLE *table_arg,
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
"Congratulation, you just created a read-only void table!");
- } // endif
+ } // endif sqlcom
if (xtrace)
htrc("xchk=%p createas=%d\n", g->Xchk, g->Createas);
- // To check whether indices have to be made or remade
+ // To check whether indexes have to be made or remade
if (!g->Xchk) {
PIXDEF xdp;
- // We should be in CREATE TABLE or ALTER_TABLE
- if (sqlcom != SQLCOM_CREATE_TABLE && sqlcom != SQLCOM_ALTER_TABLE)
+ // We should be in CREATE TABLE, ALTER_TABLE or CREATE INDEX
+ if (!(sqlcom == SQLCOM_CREATE_TABLE || sqlcom == SQLCOM_ALTER_TABLE ||
+ (sqlcom == SQLCOM_CREATE_INDEX && part_info) ||
+ (sqlcom == SQLCOM_DROP_INDEX && part_info)))
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
- "Wrong command in create, please contact CONNECT team");
+ "Unexpected command in create, please contact CONNECT team");
if (sqlcom == SQLCOM_ALTER_TABLE && g->Alchecked == 0 &&
(!IsFileType(type) || FileExists(options->filename))) {
@@ -5480,7 +5523,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endif outward
// Get the index definitions
- if (xdp= GetIndexInfo()) {
+ if ((xdp= GetIndexInfo()) || sqlcom == SQLCOM_DROP_INDEX) {
if (options->multiple) {
strcpy(g->Message, "Multiple tables are not indexable");
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
@@ -5496,6 +5539,11 @@ int ha_connect::create(const char *name, TABLE *table_arg,
if (cat) {
cat->SetDataPath(g, table_arg->s->db.str);
+#if defined(WITH_PARTITION_STORAGE_ENGINE)
+ if (part_info)
+ strcpy(partname, strrchr(name, (inward ? slash : '#')) + 1);
+#endif // WITH_PARTITION_STORAGE_ENGINE
+
if ((rc= optimize(table->in_use, NULL))) {
htrc("Create rc=%d %s\n", rc, g->Message);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h
index ebdeeae8623..33e52165289 100644
--- a/storage/connect/ha_connect.h
+++ b/storage/connect/ha_connect.h
@@ -201,11 +201,13 @@ public:
PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL);
const char *GetDBName(const char *name);
const char *GetTableName(void);
+ char *GetPartName(void);
//int GetColNameLen(Field *fp);
//char *GetColName(Field *fp);
//void AddColName(char *cp, Field *fp);
TABLE *GetTable(void) {return table;}
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
+ bool IsPartitioned(void);
PTDB GetTDB(PGLOBAL g);
int OpenTable(PGLOBAL g, bool del= false);
@@ -520,7 +522,7 @@ protected:
PVAL sdvalin; // Used to convert date values
PVAL sdvalout; // Used to convert date values
bool istable; // True for table handler
-//char tname[64]; // The table name
+ char partname[64]; // The partition name
MODE xmod; // Table mode
XINFO xinfo; // The table info structure
bool valid_info; // True if xinfo is valid
diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp
index d0072987fd0..679e8dc703c 100644
--- a/storage/connect/odbconn.cpp
+++ b/storage/connect/odbconn.cpp
@@ -2135,7 +2135,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
PSZ fnc = "Unknown";
UWORD n;
SWORD ncol, len, tp;
- SQLULEN crow;
+ SQLULEN crow = 0;
PQRYRES qrp = cap->Qrp;
PCOLRES crp;
RETCODE rc = 0;
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index 238cecc48eb..7b3818cc98b 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -132,19 +132,28 @@ int RELDEF::GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size)
/***********************************************************************/
char *RELDEF::GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef)
{
- char *sval= NULL, *s= Hc->GetStringOption(what, sdef);
+ char *name, *sval= NULL, *s= Hc->GetStringOption(what, sdef);
if (s) {
- sval= (char*)PlugSubAlloc(g, NULL, strlen(s) + 1);
- strcpy(sval, s);
+ if (Hc->IsPartitioned() &&
+ (!stricmp(what, "filename") || !stricmp(what, "tabname"))) {
+ name= Hc->GetPartName();
+ sval= (char*)PlugSubAlloc(g, NULL, strlen(s) + strlen(name));
+ sprintf(sval, s, name);
+ } else {
+ sval= (char*)PlugSubAlloc(g, NULL, strlen(s) + 1);
+ strcpy(sval, s);
+ } // endif partitioned
+
} else if (!stricmp(what, "filename")) {
// Return default file name
char *ftype= Hc->GetStringOption("Type", "*");
int i, n;
if (IsFileType(GetTypeID(ftype))) {
- sval= (char*)PlugSubAlloc(g, NULL, strlen(Hc->GetTableName()) + 12);
- strcat(strcpy(sval, Hc->GetTableName()), ".");
+ name= Hc->GetPartName();
+ sval= (char*)PlugSubAlloc(g, NULL, strlen(name) + 12);
+ strcat(strcpy(sval, name), ".");
n= strlen(sval);
// Fold ftype to lower case
diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h
index ed4a7d9dcac..fe6297f52e4 100644
--- a/storage/connect/reldef.h
+++ b/storage/connect/reldef.h
@@ -213,6 +213,7 @@ class DllExport COLDEF : public COLCRT { /* Column description block
void SetNbm(int nbm) {Nbm = nbm;}
int Define(PGLOBAL g, void *memp, PCOLINFO cfp, int poff);
void Define(PGLOBAL g, PCOL colp);
+ bool IsSpecial(void) {return (Flags & U_SPECIAL) ? true : false;}
protected:
void *To_Min; /* Point to array of block min values */
diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp
index 4b75a89bba4..c376f76d377 100644
--- a/storage/connect/tabfix.cpp
+++ b/storage/connect/tabfix.cpp
@@ -132,6 +132,7 @@ int TDBFIX::ResetTableOpt(PGLOBAL g, bool dop, bool dox)
To_Filter = NULL; // Disable filtering
//To_BlkIdx = NULL; // and block filtering
To_BlkFil = NULL; // and index filtering
+ Cardinality(g); // If called by create
RestoreNrec(); // May have been modified
MaxSize = -1; // Size must be recalculated
Cardinal = -1; // as well as Cardinality
diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp
index 77062488a29..f0e565dcba7 100644
--- a/storage/connect/tabfmt.cpp
+++ b/storage/connect/tabfmt.cpp
@@ -406,7 +406,7 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
// Double check correctness of offset values
if (Catfunc == FNC_NO)
for (PCOLDEF cdp = To_Cols; cdp; cdp = cdp->GetNext())
- if (cdp->GetOffset() < 1) {
+ if (cdp->GetOffset() < 1 && !cdp->IsSpecial()) {
strcpy(g->Message, MSG(BAD_OFFSET_VAL));
return true;
} // endif Offset
diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp
index 4b9046e08d1..e1dc58ce404 100644
--- a/storage/connect/tabutil.cpp
+++ b/storage/connect/tabutil.cpp
@@ -313,7 +313,7 @@ bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (!(tab = GetStringCatInfo(g, "Tabname", NULL))) {
if (!def) {
strcpy(g->Message, "Missing object table definition");
- return TRUE;
+ return true;
} else
tab = "Noname";
@@ -327,7 +327,7 @@ bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Tablep = new(g) XTAB(tab, def);
Tablep->SetQualifier(db);
- return FALSE;
+ return false;
} // end of DefineAM
/***********************************************************************/
@@ -352,6 +352,28 @@ TDBPRX::TDBPRX(PPRXDEF tdp) : TDBASE(tdp)
Tdbp = NULL; // The object table
} // end of TDBPRX constructor
+TDBPRX::TDBPRX(PGLOBAL g, PTDBPRX tdbp) : TDBASE(tdbp)
+ {
+ Tdbp = tdbp->Tdbp;
+ } // end of TDBPRX copy constructor
+
+// Method
+PTDB TDBPRX::CopyOne(PTABS t)
+ {
+ PTDB tp;
+ PPRXCOL cp1, cp2;
+ PGLOBAL g = t->G;
+
+ tp = new(g) TDBPRX(g, this);
+
+ for (cp1 = (PPRXCOL)Columns; cp1; cp1 = (PPRXCOL)cp1->GetNext()) {
+ cp2 = new(g) PRXCOL(cp1, tp); // Make a copy
+ NewPointer(t, cp1, cp2);
+ } // endfor cp1
+
+ return tp;
+ } // end of CopyOne
+
/***********************************************************************/
/* Get the PTDB of the sub-table. */
/***********************************************************************/
@@ -423,7 +445,7 @@ PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
} else {
// Sub-table is a CONNECT table
tabp->Next = To_Table; // For loop checking
- tdbp = cat->GetTable(g, tabp);
+ tdbp = cat->GetTable(g, tabp, Mode);
} // endif mysql
if (s) {
@@ -456,11 +478,12 @@ bool TDBPRX::InitTable(PGLOBAL g)
if (!Tdbp) {
// Get the table description block of this table
if (!(Tdbp = GetSubTable(g, ((PPRXDEF)To_Def)->Tablep)))
- return TRUE;
+ return true;
+ Tdbp->SetMode(Mode);
} // endif Tdbp
- return FALSE;
+ return false;
} // end of InitTable
/***********************************************************************/
@@ -507,32 +530,51 @@ bool TDBPRX::OpenDB(PGLOBAL g)
return Tdbp->OpenDB(g);
} // endif use
- if (Mode != MODE_READ) {
+ if (Mode == MODE_DELETE) {
/*******************************************************************/
/* Currently XCOL tables cannot be modified. */
/*******************************************************************/
- strcpy(g->Message, "PROXY tables are read only");
- return TRUE;
+ strcpy(g->Message, "No DELETE for PROXY tables");
+ return true;
} // endif Mode
if (InitTable(g))
- return TRUE;
+ return true;
/*********************************************************************/
/* Check and initialize the subtable columns. */
/*********************************************************************/
for (PCOL cp = Columns; cp; cp = cp->GetNext())
- if (((PPRXCOL)cp)->Init(g))
- return TRUE;
+ if (((PPRXCOL)cp)->Init(g, Tdbp))
+ return true;
+
+ /*********************************************************************/
+ /* In Update mode, the updated column blocks must be distinct from */
+ /* the read column blocks. So make a copy of the TDB and allocate */
+ /* its column blocks in mode write (required by XML tables). */
+ /*********************************************************************/
+ if (Mode == MODE_UPDATE) {
+ PTDBASE utp;
+
+ if (!(utp= (PTDBASE)Tdbp->Duplicate(g))) {
+ sprintf(g->Message, MSG(INV_UPDT_TABLE), Tdbp->GetName());
+ return true;
+ } // endif tp
+
+ for (PCOL cp = To_SetCols; cp; cp = cp->GetNext())
+ if (((PPRXCOL)cp)->Init(g, utp))
+ return true;
+
+ } // endif MODE_UPDATE
/*********************************************************************/
/* Physically open the object table. */
/*********************************************************************/
if (Tdbp->OpenDB(g))
- return TRUE;
+ return true;
Use = USE_OPEN;
- return FALSE;
+ return false;
} // end of OpenDB
/***********************************************************************/
@@ -551,8 +593,9 @@ int TDBPRX::ReadDB(PGLOBAL g)
/***********************************************************************/
int TDBPRX::WriteDB(PGLOBAL g)
{
- sprintf(g->Message, "%s tables are read only", To_Def->GetType());
- return RC_FX;
+//sprintf(g->Message, "%s tables are read only", To_Def->GetType());
+//return RC_FX;
+ return Tdbp->WriteDB(g);
} // end of WriteDB
/***********************************************************************/
@@ -594,7 +637,7 @@ PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
//strcpy(F_Date, cdp->F_Date);
Colp = NULL;
To_Val = NULL;
- Pseudo = FALSE;
+ Pseudo = false;
Colnum = cdp->GetOffset(); // If columns are retrieved by number
if (trace)
@@ -603,29 +646,48 @@ PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
} // end of PRXCOL constructor
/***********************************************************************/
+/* PRXCOL constructor used for copying columns. */
+/* tdbp is the pointer to the new table descriptor. */
+/***********************************************************************/
+PRXCOL::PRXCOL(PRXCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
+ {
+ Colp = col1->Colp;
+ To_Val = col1->To_Val;
+ Pseudo = col1->Pseudo;
+ Colnum = col1->Colnum;
+ } // end of PRXCOL copy constructor
+
+/***********************************************************************/
/* PRXCOL initialization routine. */
/* Look for the matching column in the object table. */
/***********************************************************************/
-bool PRXCOL::Init(PGLOBAL g)
+bool PRXCOL::Init(PGLOBAL g, PTDBASE tp)
{
- PTDBPRX tdbp = (PTDBPRX)To_Tdb;
+ if (!tp)
+ tp = ((PTDBPRX)To_Tdb)->Tdbp;
- if (!(Colp = tdbp->Tdbp->ColDB(g, Name, 0)) && Colnum)
- Colp = tdbp->Tdbp->ColDB(g, NULL, Colnum);
+ if (!(Colp = tp->ColDB(g, Name, 0)) && Colnum)
+ Colp = tp->ColDB(g, NULL, Colnum);
if (Colp) {
+ MODE mode = To_Tdb->GetMode();
+
// May not have been done elsewhere
Colp->InitValue(g);
To_Val = Colp->GetValue();
+ if (mode == MODE_INSERT || mode == MODE_UPDATE)
+ if (Colp->SetBuffer(g, Colp->GetValue(), true, false))
+ return true;
+
// this may be needed by some tables (which?)
Colp->SetColUse(ColUse);
} else {
- sprintf(g->Message, MSG(NO_MATCHING_COL), Name, tdbp->Tdbp->GetName());
- return TRUE;
+ sprintf(g->Message, MSG(NO_MATCHING_COL), Name, tp->GetName());
+ return true;
} // endif Colp
- return FALSE;
+ return false;
} // end of Init
/***********************************************************************/
@@ -659,6 +721,21 @@ void PRXCOL::ReadColumn(PGLOBAL g)
} // end of ReadColumn
+/***********************************************************************/
+/* WriteColumn: */
+/***********************************************************************/
+void PRXCOL::WriteColumn(PGLOBAL g)
+ {
+ if (trace > 1)
+ htrc("PRX WriteColumn: name=%s\n", Name);
+
+ if (Colp) {
+ To_Val->SetValue_pval(Value);
+ Colp->WriteColumn(g);
+ } // endif Colp
+
+ } // end of WriteColumn
+
/* ---------------------------TDBTBC class --------------------------- */
/***********************************************************************/
diff --git a/storage/connect/tabutil.h b/storage/connect/tabutil.h
index c87065befba..5344372a30b 100644
--- a/storage/connect/tabutil.h
+++ b/storage/connect/tabutil.h
@@ -57,13 +57,17 @@ class DllExport TDBPRX : public TDBASE {
friend class PRXDEF;
friend class PRXCOL;
public:
- // Constructor
+ // Constructors
TDBPRX(PPRXDEF tdp);
+ TDBPRX(PGLOBAL g, PTDBPRX tdbp);
// Implementation
virtual AMT GetAmType(void) {return TYPE_AM_PRX;}
+ virtual PTDB Duplicate(PGLOBAL g)
+ {return (PTDB)new(g) TDBPRX(g, this);}
// Methods
+ virtual PTDB CopyOne(PTABS t);
virtual int GetRecpos(void) {return Tdbp->GetRecpos();}
virtual void ResetDB(void) {Tdbp->ResetDB();}
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
@@ -97,15 +101,19 @@ class DllExport PRXCOL : public COLBLK {
public:
// Constructors
PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "PRX");
+ PRXCOL(PRXCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
- virtual int GetAmType(void) {return TYPE_AM_PRX;}
+ virtual int GetAmType(void) {return TYPE_AM_PRX;}
// Methods
- virtual void Reset(void);
- virtual bool IsSpecial(void) {return Pseudo;}
- virtual void ReadColumn(PGLOBAL g);
- bool Init(PGLOBAL g);
+ virtual void Reset(void);
+ virtual bool IsSpecial(void) {return Pseudo;}
+ virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
+ {return false;}
+ virtual void ReadColumn(PGLOBAL g);
+ virtual void WriteColumn(PGLOBAL g);
+ bool Init(PGLOBAL g, PTDBASE tp = NULL);
protected:
// Default constructor not to be used
diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp
index 5f7d982c701..ff682517251 100755
--- a/storage/connect/xindex.cpp
+++ b/storage/connect/xindex.cpp
@@ -2407,7 +2407,7 @@ void XFILE::Close(void)
#if defined(XMAP)
if (Mmp && CloseMemMap(Mmp->memory, Mmp->lenL))
- printf("Error %d closing mapped index\n");
+ printf("Error closing mapped index\n");
#endif // XMAP
} // end of Close
@@ -2574,8 +2574,8 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
} // endif Hfile
if (trace)
- htrc(" rc=%d oflag=%p mode=%d handle=%d fn=%s\n",
- rc, oflag, mode, Hfile, filename);
+ htrc(" oflag=%p mode=%d handle=%d fn=%s\n",
+ oflag, mode, Hfile, filename);
if (mode == MODE_INSERT) {
/*******************************************************************/