Commit 128136cb authored by Olivier Bertrand's avatar Olivier Bertrand

- Add support of partition tables

modified:
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h
  storage/connect/reldef.cpp

- Add INSERT/UPDATE support to PROXY tables
modified:
  storage/connect/tabutil.cpp
  storage/connect/tabutil.h

- Take care of SPECIAL columns
modified:
  storage/connect/filamdbf.cpp
  storage/connect/reldef.h
  storage/connect/tabfmt.cpp

-Typo and misc
modified:
  storage/connect/odbconn.cpp
  storage/connect/tabfix.cpp
  storage/connect/xindex.cpp
parents 9cb4b6c0 7bbcc3e4
...@@ -546,10 +546,11 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g) ...@@ -546,10 +546,11 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
PDOSDEF tdp = (PDOSDEF)Tdbp->GetDef(); PDOSDEF tdp = (PDOSDEF)Tdbp->GetDef();
// Count the number of columns // Count the number of columns
for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) { for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
if (!(cdp->Flags & U_SPECIAL)) {
reclen += cdp->GetLong(); reclen += cdp->GetLong();
n++; n++;
} // endfor cdp } // endif Flags
if (Lrecl != reclen) { if (Lrecl != reclen) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, reclen); sprintf(g->Message, MSG(BAD_LRECL), Lrecl, reclen);
...@@ -570,7 +571,8 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g) ...@@ -570,7 +571,8 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
descp = (DESCRIPTOR*)header; descp = (DESCRIPTOR*)header;
// Currently only standard Xbase types are supported // Currently only standard Xbase types are supported
for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) { for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
if (!(cdp->Flags & U_SPECIAL)) {
descp++; descp++;
switch ((c = *GetFormatType(cdp->GetType()))) { switch ((c = *GetFormatType(cdp->GetType()))) {
...@@ -593,7 +595,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g) ...@@ -593,7 +595,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
strncpy(descp->Name, cdp->GetName(), 11); strncpy(descp->Name, cdp->GetName(), 11);
descp->Type = c; descp->Type = c;
descp->Length = (uchar)cdp->GetLong(); descp->Length = (uchar)cdp->GetLong();
} // endfor cdp } // endif Flags
*(char*)(++descp) = EOH; *(char*)(++descp) = EOH;
......
...@@ -119,6 +119,7 @@ ...@@ -119,6 +119,7 @@
#if defined(NEW_WAY) #if defined(NEW_WAY)
#include "sql_table.h" #include "sql_table.h"
#endif // NEW_WAY #endif // NEW_WAY
#include "sql_partition.h"
#undef OFFSET #undef OFFSET
#define NOPARSE #define NOPARSE
...@@ -173,6 +174,12 @@ extern "C" { ...@@ -173,6 +174,12 @@ extern "C" {
char version[]= "Version 1.03.0002 May 03, 2014"; char version[]= "Version 1.03.0002 May 03, 2014";
char compver[]= "Version 1.03.0002 " __DATE__ " " __TIME__; char compver[]= "Version 1.03.0002 " __DATE__ " " __TIME__;
#if defined(WIN32)
char slash= '\\';
#else // !WIN32
char slash= '/';
#endif // !WIN32
#if defined(XMSG) #if defined(XMSG)
char msglang[]; // Default message language char msglang[]; // Default message language
#endif #endif
...@@ -538,7 +545,7 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg) ...@@ -538,7 +545,7 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg)
sdvalout= NULL; sdvalout= NULL;
xmod= MODE_ANY; xmod= MODE_ANY;
istable= false; istable= false;
//*tname= '\0'; *partname= 0;
bzero((char*) &xinfo, sizeof(XINFO)); bzero((char*) &xinfo, sizeof(XINFO));
valid_info= false; valid_info= false;
valid_query_id= 0; valid_query_id= 0;
...@@ -1264,6 +1271,16 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s) ...@@ -1264,6 +1271,16 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
return toidx; return toidx;
} // end of GetIndexInfo } // 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) const char *ha_connect::GetDBName(const char* name)
{ {
return (name) ? name : table->s->db.str; return (name) ? name : table->s->db.str;
...@@ -1274,6 +1291,11 @@ const char *ha_connect::GetTableName(void) ...@@ -1274,6 +1291,11 @@ const char *ha_connect::GetTableName(void)
return (tshp) ? tshp->table_name.str : table_share->table_name.str; return (tshp) ? tshp->table_name.str : table_share->table_name.str;
} // end of GetTableName } // end of GetTableName
char *ha_connect::GetPartName(void)
{
return (IsPartitioned()) ? partname : (char*)GetTableName();
} // end of GetTableName
#if 0 #if 0
/****************************************************************************/ /****************************************************************************/
/* Returns the column real or special name length of a field. */ /* 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) ...@@ -2474,6 +2496,15 @@ int ha_connect::open(const char *name, int mode, uint test_if_locked)
} else } else
mrr= false; 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 } else
rc= HA_ERR_INTERNAL_ERROR; rc= HA_ERR_INTERNAL_ERROR;
...@@ -2487,6 +2518,7 @@ int ha_connect::open(const char *name, int mode, uint test_if_locked) ...@@ -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 ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt)
{ {
int rc= 0; int rc= 0;
bool dop= (check_opt != NULL);
PGLOBAL& g= xp->g; PGLOBAL& g= xp->g;
PDBUSER dup= PlgGetUser(g); PDBUSER dup= PlgGetUser(g);
...@@ -2498,7 +2530,7 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt) ...@@ -2498,7 +2530,7 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt)
if (tdbp) { if (tdbp) {
bool b= (((PTDBASE)tdbp)->GetDef()->Indexable() == 1); 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) { if (rc == RC_INFO) {
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
rc= 0; rc= 0;
...@@ -2980,7 +3012,6 @@ int ha_connect::index_next_same(uchar *buf, const uchar *key, uint keylen) ...@@ -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 ha_connect::rnd_init(bool scan)
{ {
int rc;
PGLOBAL g= ((table && table->in_use) ? GetPlug(table->in_use, xp) : PGLOBAL g= ((table && table->in_use) ? GetPlug(table->in_use, xp) :
(xp) ? xp->g : NULL); (xp) ? xp->g : NULL);
DBUG_ENTER("ha_connect::rnd_init"); DBUG_ENTER("ha_connect::rnd_init");
...@@ -3014,8 +3045,8 @@ int ha_connect::rnd_init(bool scan) ...@@ -3014,8 +3045,8 @@ int ha_connect::rnd_init(bool scan)
if (xmod == MODE_UPDATE) if (xmod == MODE_UPDATE)
bitmap_union(table->read_set, table->write_set); bitmap_union(table->read_set, table->write_set);
if ((rc= OpenTable(g, xmod == MODE_DELETE))) if (OpenTable(g, xmod == MODE_DELETE))
DBUG_RETURN(rc); DBUG_RETURN(HA_ERR_INITIALIZATION);
xp->nrd= xp->fnd= xp->nfd= 0; xp->nrd= xp->fnd= xp->nfd= 0;
xp->tb1= my_interval_timer(); xp->tb1= my_interval_timer();
...@@ -3934,11 +3965,6 @@ filename_to_dbname_and_tablename(const char *filename, ...@@ -3934,11 +3965,6 @@ filename_to_dbname_and_tablename(const char *filename,
char *database, size_t database_size, char *database, size_t database_size,
char *table, size_t table_size) char *table, size_t table_size)
{ {
#if defined(WIN32)
char slash= '\\';
#else // !WIN32
char slash= '/';
#endif // !WIN32
LEX_CSTRING d, t; LEX_CSTRING d, t;
size_t length= strlen(filename); size_t length= strlen(filename);
...@@ -4013,29 +4039,27 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to) ...@@ -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 // If a temporary file exists, all the tests below were passed
// successfully when making it, so they are not needed anymore // successfully when making it, so they are not needed anymore
// in particular because they sometimes cause DBUG_ASSERT crash. // 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. // We have to retrieve the information about this table options.
ha_table_option_struct *pos; ha_table_option_struct *pos;
char key[MAX_DBKEY_LENGTH]; char key[MAX_DBKEY_LENGTH];
uint key_length; uint key_length;
TABLE_SHARE *share; 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); key_length= tdc_create_key(key, db, tabname);
// share contains the option struct that we need // share contains the option struct that we need
if (!(share= alloc_table_share(db, tabname, key, key_length))) if (!(share= alloc_table_share(db, tabname, key, key_length)))
DBUG_RETURN(rc); 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 // Get the share info from the .frm file
if (!open_table_def(thd, share)) { if (!open_table_def(thd, share)) {
// Now we can work // Now we can work
...@@ -5111,12 +5135,16 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -5111,12 +5135,16 @@ int ha_connect::create(const char *name, TABLE *table_arg,
TABTYPE type; TABTYPE type;
TABLE *st= table; // Probably unuseful TABLE *st= table; // Probably unuseful
THD *thd= ha_thd(); 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); xp= GetUser(thd, xp);
PGLOBAL g= xp->g; PGLOBAL g= xp->g;
DBUG_ENTER("ha_connect::create"); DBUG_ENTER("ha_connect::create");
int sqlcom= thd_sql_command(table_arg->in_use); int sqlcom= thd_sql_command(table_arg->in_use);
PTOS options= GetTableOptionStruct(table_arg->s); PTOS options= GetTableOptionStruct(table_arg->s);
bool inward= !options->filename;
table= table_arg; // Used by called functions table= table_arg; // Used by called functions
...@@ -5395,7 +5423,7 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -5395,7 +5423,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endfor field } // endfor field
if ((sqlcom == SQLCOM_CREATE_TABLE || *GetTableName() == '#') 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 file name is not specified, create a default file in
// the database directory named table_name.table_type. // the database directory named table_name.table_type.
// (temporarily not done for XML because a void file causes // (temporarily not done for XML because a void file causes
...@@ -5403,8 +5431,6 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -5403,8 +5431,6 @@ int ha_connect::create(const char *name, TABLE *table_arg,
char buf[256], fn[_MAX_PATH], dbpath[128], lwt[12]; char buf[256], fn[_MAX_PATH], dbpath[128], lwt[12];
int h; int h;
strcpy(buf, GetTableName());
// Check for incompatible options // Check for incompatible options
if (options->sepindex) { if (options->sepindex) {
my_message(ER_UNKNOWN_ERROR, my_message(ER_UNKNOWN_ERROR,
...@@ -5432,13 +5458,28 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -5432,13 +5458,28 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} else } else
lwt[i]= tolower(options->type[i]); lwt[i]= tolower(options->type[i]);
strcat(strcat(buf, "."), lwt); #if defined(WITH_PARTITION_STORAGE_ENGINE)
if (part_info) {
char *p;
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); sprintf(g->Message, "No file name. Table will use %s", buf);
if (sqlcom == SQLCOM_CREATE_TABLE) if (sqlcom == SQLCOM_CREATE_TABLE)
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/"); strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/");
#if defined(WITH_PARTITION_STORAGE_ENGINE)
} // endif part_info
#endif // WITH_PARTITION_STORAGE_ENGINE
PlugSetPath(fn, buf, dbpath); PlugSetPath(fn, buf, dbpath);
if ((h= ::open(fn, O_CREAT | O_EXCL, 0666)) == -1) { if ((h= ::open(fn, O_CREAT | O_EXCL, 0666)) == -1) {
...@@ -5455,19 +5496,21 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -5455,19 +5496,21 @@ int ha_connect::create(const char *name, TABLE *table_arg,
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
"Congratulation, you just created a read-only void table!"); "Congratulation, you just created a read-only void table!");
} // endif } // endif sqlcom
if (xtrace) if (xtrace)
htrc("xchk=%p createas=%d\n", g->Xchk, g->Createas); 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) { if (!g->Xchk) {
PIXDEF xdp; PIXDEF xdp;
// We should be in CREATE TABLE or ALTER_TABLE // We should be in CREATE TABLE, ALTER_TABLE or CREATE INDEX
if (sqlcom != SQLCOM_CREATE_TABLE && sqlcom != SQLCOM_ALTER_TABLE) 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, 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 && if (sqlcom == SQLCOM_ALTER_TABLE && g->Alchecked == 0 &&
(!IsFileType(type) || FileExists(options->filename))) { (!IsFileType(type) || FileExists(options->filename))) {
...@@ -5480,7 +5523,7 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -5480,7 +5523,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endif outward } // endif outward
// Get the index definitions // Get the index definitions
if (xdp= GetIndexInfo()) { if ((xdp= GetIndexInfo()) || sqlcom == SQLCOM_DROP_INDEX) {
if (options->multiple) { if (options->multiple) {
strcpy(g->Message, "Multiple tables are not indexable"); strcpy(g->Message, "Multiple tables are not indexable");
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
...@@ -5496,6 +5539,11 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -5496,6 +5539,11 @@ int ha_connect::create(const char *name, TABLE *table_arg,
if (cat) { if (cat) {
cat->SetDataPath(g, table_arg->s->db.str); 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))) { if ((rc= optimize(table->in_use, NULL))) {
htrc("Create rc=%d %s\n", rc, g->Message); htrc("Create rc=%d %s\n", rc, g->Message);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
......
...@@ -201,11 +201,13 @@ public: ...@@ -201,11 +201,13 @@ public:
PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL); PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL);
const char *GetDBName(const char *name); const char *GetDBName(const char *name);
const char *GetTableName(void); const char *GetTableName(void);
char *GetPartName(void);
//int GetColNameLen(Field *fp); //int GetColNameLen(Field *fp);
//char *GetColName(Field *fp); //char *GetColName(Field *fp);
//void AddColName(char *cp, Field *fp); //void AddColName(char *cp, Field *fp);
TABLE *GetTable(void) {return table;} TABLE *GetTable(void) {return table;}
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2); bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
bool IsPartitioned(void);
PTDB GetTDB(PGLOBAL g); PTDB GetTDB(PGLOBAL g);
int OpenTable(PGLOBAL g, bool del= false); int OpenTable(PGLOBAL g, bool del= false);
...@@ -520,7 +522,7 @@ protected: ...@@ -520,7 +522,7 @@ protected:
PVAL sdvalin; // Used to convert date values PVAL sdvalin; // Used to convert date values
PVAL sdvalout; // Used to convert date values PVAL sdvalout; // Used to convert date values
bool istable; // True for table handler bool istable; // True for table handler
//char tname[64]; // The table name char partname[64]; // The partition name
MODE xmod; // Table mode MODE xmod; // Table mode
XINFO xinfo; // The table info structure XINFO xinfo; // The table info structure
bool valid_info; // True if xinfo is valid bool valid_info; // True if xinfo is valid
......
...@@ -2135,7 +2135,7 @@ int ODBConn::GetCatInfo(CATPARM *cap) ...@@ -2135,7 +2135,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
PSZ fnc = "Unknown"; PSZ fnc = "Unknown";
UWORD n; UWORD n;
SWORD ncol, len, tp; SWORD ncol, len, tp;
SQLULEN crow; SQLULEN crow = 0;
PQRYRES qrp = cap->Qrp; PQRYRES qrp = cap->Qrp;
PCOLRES crp; PCOLRES crp;
RETCODE rc = 0; RETCODE rc = 0;
......
...@@ -132,19 +132,28 @@ int RELDEF::GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size) ...@@ -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 *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) { if (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); sval= (char*)PlugSubAlloc(g, NULL, strlen(s) + 1);
strcpy(sval, s); strcpy(sval, s);
} // endif partitioned
} else if (!stricmp(what, "filename")) { } else if (!stricmp(what, "filename")) {
// Return default file name // Return default file name
char *ftype= Hc->GetStringOption("Type", "*"); char *ftype= Hc->GetStringOption("Type", "*");
int i, n; int i, n;
if (IsFileType(GetTypeID(ftype))) { if (IsFileType(GetTypeID(ftype))) {
sval= (char*)PlugSubAlloc(g, NULL, strlen(Hc->GetTableName()) + 12); name= Hc->GetPartName();
strcat(strcpy(sval, Hc->GetTableName()), "."); sval= (char*)PlugSubAlloc(g, NULL, strlen(name) + 12);
strcat(strcpy(sval, name), ".");
n= strlen(sval); n= strlen(sval);
// Fold ftype to lower case // Fold ftype to lower case
......
...@@ -213,6 +213,7 @@ class DllExport COLDEF : public COLCRT { /* Column description block ...@@ -213,6 +213,7 @@ class DllExport COLDEF : public COLCRT { /* Column description block
void SetNbm(int nbm) {Nbm = nbm;} void SetNbm(int nbm) {Nbm = nbm;}
int Define(PGLOBAL g, void *memp, PCOLINFO cfp, int poff); int Define(PGLOBAL g, void *memp, PCOLINFO cfp, int poff);
void Define(PGLOBAL g, PCOL colp); void Define(PGLOBAL g, PCOL colp);
bool IsSpecial(void) {return (Flags & U_SPECIAL) ? true : false;}
protected: protected:
void *To_Min; /* Point to array of block min values */ void *To_Min; /* Point to array of block min values */
......
...@@ -132,6 +132,7 @@ int TDBFIX::ResetTableOpt(PGLOBAL g, bool dop, bool dox) ...@@ -132,6 +132,7 @@ int TDBFIX::ResetTableOpt(PGLOBAL g, bool dop, bool dox)
To_Filter = NULL; // Disable filtering To_Filter = NULL; // Disable filtering
//To_BlkIdx = NULL; // and block filtering //To_BlkIdx = NULL; // and block filtering
To_BlkFil = NULL; // and index filtering To_BlkFil = NULL; // and index filtering
Cardinality(g); // If called by create
RestoreNrec(); // May have been modified RestoreNrec(); // May have been modified
MaxSize = -1; // Size must be recalculated MaxSize = -1; // Size must be recalculated
Cardinal = -1; // as well as Cardinality Cardinal = -1; // as well as Cardinality
......
...@@ -406,7 +406,7 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -406,7 +406,7 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
// Double check correctness of offset values // Double check correctness of offset values
if (Catfunc == FNC_NO) if (Catfunc == FNC_NO)
for (PCOLDEF cdp = To_Cols; cdp; cdp = cdp->GetNext()) 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)); strcpy(g->Message, MSG(BAD_OFFSET_VAL));
return true; return true;
} // endif Offset } // endif Offset
......
...@@ -313,7 +313,7 @@ bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -313,7 +313,7 @@ bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (!(tab = GetStringCatInfo(g, "Tabname", NULL))) { if (!(tab = GetStringCatInfo(g, "Tabname", NULL))) {
if (!def) { if (!def) {
strcpy(g->Message, "Missing object table definition"); strcpy(g->Message, "Missing object table definition");
return TRUE; return true;
} else } else
tab = "Noname"; tab = "Noname";
...@@ -327,7 +327,7 @@ bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -327,7 +327,7 @@ bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Tablep = new(g) XTAB(tab, def); Tablep = new(g) XTAB(tab, def);
Tablep->SetQualifier(db); Tablep->SetQualifier(db);
return FALSE; return false;
} // end of DefineAM } // end of DefineAM
/***********************************************************************/ /***********************************************************************/
...@@ -352,6 +352,28 @@ TDBPRX::TDBPRX(PPRXDEF tdp) : TDBASE(tdp) ...@@ -352,6 +352,28 @@ TDBPRX::TDBPRX(PPRXDEF tdp) : TDBASE(tdp)
Tdbp = NULL; // The object table Tdbp = NULL; // The object table
} // end of TDBPRX constructor } // 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. */ /* Get the PTDB of the sub-table. */
/***********************************************************************/ /***********************************************************************/
...@@ -423,7 +445,7 @@ PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b) ...@@ -423,7 +445,7 @@ PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
} else { } else {
// Sub-table is a CONNECT table // Sub-table is a CONNECT table
tabp->Next = To_Table; // For loop checking tabp->Next = To_Table; // For loop checking
tdbp = cat->GetTable(g, tabp); tdbp = cat->GetTable(g, tabp, Mode);
} // endif mysql } // endif mysql
if (s) { if (s) {
...@@ -456,11 +478,12 @@ bool TDBPRX::InitTable(PGLOBAL g) ...@@ -456,11 +478,12 @@ bool TDBPRX::InitTable(PGLOBAL g)
if (!Tdbp) { if (!Tdbp) {
// Get the table description block of this table // Get the table description block of this table
if (!(Tdbp = GetSubTable(g, ((PPRXDEF)To_Def)->Tablep))) if (!(Tdbp = GetSubTable(g, ((PPRXDEF)To_Def)->Tablep)))
return TRUE; return true;
Tdbp->SetMode(Mode);
} // endif Tdbp } // endif Tdbp
return FALSE; return false;
} // end of InitTable } // end of InitTable
/***********************************************************************/ /***********************************************************************/
...@@ -507,32 +530,51 @@ bool TDBPRX::OpenDB(PGLOBAL g) ...@@ -507,32 +530,51 @@ bool TDBPRX::OpenDB(PGLOBAL g)
return Tdbp->OpenDB(g); return Tdbp->OpenDB(g);
} // endif use } // endif use
if (Mode != MODE_READ) { if (Mode == MODE_DELETE) {
/*******************************************************************/ /*******************************************************************/
/* Currently XCOL tables cannot be modified. */ /* Currently XCOL tables cannot be modified. */
/*******************************************************************/ /*******************************************************************/
strcpy(g->Message, "PROXY tables are read only"); strcpy(g->Message, "No DELETE for PROXY tables");
return TRUE; return true;
} // endif Mode } // endif Mode
if (InitTable(g)) if (InitTable(g))
return TRUE; return true;
/*********************************************************************/ /*********************************************************************/
/* Check and initialize the subtable columns. */ /* Check and initialize the subtable columns. */
/*********************************************************************/ /*********************************************************************/
for (PCOL cp = Columns; cp; cp = cp->GetNext()) for (PCOL cp = Columns; cp; cp = cp->GetNext())
if (((PPRXCOL)cp)->Init(g)) if (((PPRXCOL)cp)->Init(g, Tdbp))
return TRUE; 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. */ /* Physically open the object table. */
/*********************************************************************/ /*********************************************************************/
if (Tdbp->OpenDB(g)) if (Tdbp->OpenDB(g))
return TRUE; return true;
Use = USE_OPEN; Use = USE_OPEN;
return FALSE; return false;
} // end of OpenDB } // end of OpenDB
/***********************************************************************/ /***********************************************************************/
...@@ -551,8 +593,9 @@ int TDBPRX::ReadDB(PGLOBAL g) ...@@ -551,8 +593,9 @@ int TDBPRX::ReadDB(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int TDBPRX::WriteDB(PGLOBAL g) int TDBPRX::WriteDB(PGLOBAL g)
{ {
sprintf(g->Message, "%s tables are read only", To_Def->GetType()); //sprintf(g->Message, "%s tables are read only", To_Def->GetType());
return RC_FX; //return RC_FX;
return Tdbp->WriteDB(g);
} // end of WriteDB } // end of WriteDB
/***********************************************************************/ /***********************************************************************/
...@@ -594,7 +637,7 @@ PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) ...@@ -594,7 +637,7 @@ PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
//strcpy(F_Date, cdp->F_Date); //strcpy(F_Date, cdp->F_Date);
Colp = NULL; Colp = NULL;
To_Val = NULL; To_Val = NULL;
Pseudo = FALSE; Pseudo = false;
Colnum = cdp->GetOffset(); // If columns are retrieved by number Colnum = cdp->GetOffset(); // If columns are retrieved by number
if (trace) if (trace)
...@@ -602,30 +645,49 @@ PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) ...@@ -602,30 +645,49 @@ PRXCOL::PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
} // end of PRXCOL constructor } // 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. */ /* PRXCOL initialization routine. */
/* Look for the matching column in the object table. */ /* 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) if (!(Colp = tp->ColDB(g, Name, 0)) && Colnum)
Colp = tdbp->Tdbp->ColDB(g, NULL, Colnum); Colp = tp->ColDB(g, NULL, Colnum);
if (Colp) { if (Colp) {
MODE mode = To_Tdb->GetMode();
// May not have been done elsewhere // May not have been done elsewhere
Colp->InitValue(g); Colp->InitValue(g);
To_Val = Colp->GetValue(); 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?) // this may be needed by some tables (which?)
Colp->SetColUse(ColUse); Colp->SetColUse(ColUse);
} else { } else {
sprintf(g->Message, MSG(NO_MATCHING_COL), Name, tdbp->Tdbp->GetName()); sprintf(g->Message, MSG(NO_MATCHING_COL), Name, tp->GetName());
return TRUE; return true;
} // endif Colp } // endif Colp
return FALSE; return false;
} // end of Init } // end of Init
/***********************************************************************/ /***********************************************************************/
...@@ -659,6 +721,21 @@ void PRXCOL::ReadColumn(PGLOBAL g) ...@@ -659,6 +721,21 @@ void PRXCOL::ReadColumn(PGLOBAL g)
} // end of ReadColumn } // 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 --------------------------- */ /* ---------------------------TDBTBC class --------------------------- */
/***********************************************************************/ /***********************************************************************/
......
...@@ -57,13 +57,17 @@ class DllExport TDBPRX : public TDBASE { ...@@ -57,13 +57,17 @@ class DllExport TDBPRX : public TDBASE {
friend class PRXDEF; friend class PRXDEF;
friend class PRXCOL; friend class PRXCOL;
public: public:
// Constructor // Constructors
TDBPRX(PPRXDEF tdp); TDBPRX(PPRXDEF tdp);
TDBPRX(PGLOBAL g, PTDBPRX tdbp);
// Implementation // Implementation
virtual AMT GetAmType(void) {return TYPE_AM_PRX;} virtual AMT GetAmType(void) {return TYPE_AM_PRX;}
virtual PTDB Duplicate(PGLOBAL g)
{return (PTDB)new(g) TDBPRX(g, this);}
// Methods // Methods
virtual PTDB CopyOne(PTABS t);
virtual int GetRecpos(void) {return Tdbp->GetRecpos();} virtual int GetRecpos(void) {return Tdbp->GetRecpos();}
virtual void ResetDB(void) {Tdbp->ResetDB();} virtual void ResetDB(void) {Tdbp->ResetDB();}
virtual int RowNumber(PGLOBAL g, bool b = FALSE); virtual int RowNumber(PGLOBAL g, bool b = FALSE);
...@@ -97,6 +101,7 @@ class DllExport PRXCOL : public COLBLK { ...@@ -97,6 +101,7 @@ class DllExport PRXCOL : public COLBLK {
public: public:
// Constructors // Constructors
PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "PRX"); PRXCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "PRX");
PRXCOL(PRXCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation // Implementation
virtual int GetAmType(void) {return TYPE_AM_PRX;} virtual int GetAmType(void) {return TYPE_AM_PRX;}
...@@ -104,8 +109,11 @@ class DllExport PRXCOL : public COLBLK { ...@@ -104,8 +109,11 @@ class DllExport PRXCOL : public COLBLK {
// Methods // Methods
virtual void Reset(void); virtual void Reset(void);
virtual bool IsSpecial(void) {return Pseudo;} 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 ReadColumn(PGLOBAL g);
bool Init(PGLOBAL g); virtual void WriteColumn(PGLOBAL g);
bool Init(PGLOBAL g, PTDBASE tp = NULL);
protected: protected:
// Default constructor not to be used // Default constructor not to be used
......
...@@ -2407,7 +2407,7 @@ void XFILE::Close(void) ...@@ -2407,7 +2407,7 @@ void XFILE::Close(void)
#if defined(XMAP) #if defined(XMAP)
if (Mmp && CloseMemMap(Mmp->memory, Mmp->lenL)) if (Mmp && CloseMemMap(Mmp->memory, Mmp->lenL))
printf("Error %d closing mapped index\n"); printf("Error closing mapped index\n");
#endif // XMAP #endif // XMAP
} // end of Close } // end of Close
...@@ -2574,8 +2574,8 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode) ...@@ -2574,8 +2574,8 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
} // endif Hfile } // endif Hfile
if (trace) if (trace)
htrc(" rc=%d oflag=%p mode=%d handle=%d fn=%s\n", htrc(" oflag=%p mode=%d handle=%d fn=%s\n",
rc, oflag, mode, Hfile, filename); oflag, mode, Hfile, filename);
if (mode == MODE_INSERT) { if (mode == MODE_INSERT) {
/*******************************************************************/ /*******************************************************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment