Commit 1de6440a authored by Olivier Bertrand's avatar Olivier Bertrand

Fix MDEV-12587 MariaDB CONNECT DIR Type

 - Subfolder Option: SELECT Query Never Ends
  modified:   storage/connect/tabmul.cpp
  modified:   storage/connect/tabmul.h

Work on MDEV-12667 Crash when using JSON tables
  modified:   storage/connect/connect.cc
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/ha_connect.h
  modified:   storage/connect/plgdbutl.cpp

Change Base offset for DIR tables on Linux
  modified:   storage/connect/reldef.cpp
parent 63b7d9d1
...@@ -117,7 +117,8 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname) ...@@ -117,7 +117,8 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname)
handler); handler);
// Set the database path for this table // Set the database path for this table
handler->SetDataPath(g, pathname); if (handler->SetDataPath(g, pathname))
return true;
if (dbuserp->Catalog) { if (dbuserp->Catalog) {
// ((MYCAT *)dbuserp->Catalog)->SetHandler(handler); done later // ((MYCAT *)dbuserp->Catalog)->SetHandler(handler); done later
......
...@@ -1739,9 +1739,9 @@ void ha_connect::AddColName(char *cp, Field *fp) ...@@ -1739,9 +1739,9 @@ void ha_connect::AddColName(char *cp, Field *fp)
/***********************************************************************/ /***********************************************************************/
/* This function sets the current database path. */ /* This function sets the current database path. */
/***********************************************************************/ /***********************************************************************/
void ha_connect::SetDataPath(PGLOBAL g, const char *path) bool ha_connect::SetDataPath(PGLOBAL g, const char *path)
{ {
datapath= SetPath(g, path); return (!(datapath = SetPath(g, path)));
} // end of SetDataPath } // end of SetDataPath
/****************************************************************************/ /****************************************************************************/
...@@ -2721,6 +2721,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) ...@@ -2721,6 +2721,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
if (x) if (x)
return NULL; return NULL;
else
pb0 = pb1 = pb2 = ph0 = ph1 = ph2 = NULL;
if (trace) if (trace)
htrc("Cond: Ftype=%d name=%s\n", cond_item->functype(), htrc("Cond: Ftype=%d name=%s\n", cond_item->functype(),
...@@ -4110,10 +4112,14 @@ int ha_connect::info(uint flag) ...@@ -4110,10 +4112,14 @@ int ha_connect::info(uint flag)
} // endif xmod } // endif xmod
// This is necessary for getting file length // This is necessary for getting file length
if (table) if (table) {
SetDataPath(g, table->s->db.str); if (SetDataPath(g, table->s->db.str)) {
else my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} // endif SetDataPath
} else
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen
if (!(tdbp= GetTDB(g))) if (!(tdbp= GetTDB(g)))
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen
...@@ -6563,9 +6569,10 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -6563,9 +6569,10 @@ int ha_connect::create(const char *name, TABLE *table_arg,
PDBUSER dup= PlgGetUser(g); PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL; PCATLG cat= (dup) ? dup->Catalog : NULL;
SetDataPath(g, table_arg->s->db.str); if (SetDataPath(g, table_arg->s->db.str)) {
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
if (cat) { rc = HA_ERR_INTERNAL_ERROR;
} else 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 defined(WITH_PARTITION_STORAGE_ENGINE)
...@@ -7137,6 +7144,6 @@ maria_declare_plugin(connect) ...@@ -7137,6 +7144,6 @@ maria_declare_plugin(connect)
NULL, /* status variables */ NULL, /* status variables */
connect_system_variables, /* system variables */ connect_system_variables, /* system variables */
"1.05.0003", /* string version */ "1.05.0003", /* string version */
MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
} }
maria_declare_plugin_end; maria_declare_plugin_end;
...@@ -199,7 +199,7 @@ class ha_connect: public handler ...@@ -199,7 +199,7 @@ class ha_connect: public handler
bool IsUnique(uint n); bool IsUnique(uint n);
char *GetDataPath(void) {return (char*)datapath;} char *GetDataPath(void) {return (char*)datapath;}
void SetDataPath(PGLOBAL g, const char *path); bool SetDataPath(PGLOBAL g, const char *path);
PTDB GetTDB(PGLOBAL g); PTDB GetTDB(PGLOBAL g);
int OpenTable(PGLOBAL g, bool del= false); int OpenTable(PGLOBAL g, bool del= false);
bool CheckColumnList(PGLOBAL g); bool CheckColumnList(PGLOBAL g);
......
...@@ -412,8 +412,9 @@ char *SetPath(PGLOBAL g, const char *path) ...@@ -412,8 +412,9 @@ char *SetPath(PGLOBAL g, const char *path)
if (path) { if (path) {
size_t len= strlen(path) + (*path != '.' ? 4 : 1); size_t len= strlen(path) + (*path != '.' ? 4 : 1);
buf= (char*)PlugSubAlloc(g, NULL, len); if (!(buf = (char*)PlgDBSubAlloc(g, NULL, len)))
return NULL;
if (PlugIsAbsolutePath(path)) { if (PlugIsAbsolutePath(path)) {
strcpy(buf, path); strcpy(buf, path);
return buf; return buf;
......
/************* RelDef CPP Program Source Code File (.CPP) **************/ /************* RelDef CPP Program Source Code File (.CPP) **************/
/* PROGRAM NAME: RELDEF */ /* PROGRAM NAME: RELDEF */
/* ------------- */ /* ------------- */
/* Version 1.6 */ /* Version 1.7 */
/* */ /* */
/* COPYRIGHT: */ /* COPYRIGHT: */
/* ---------- */ /* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 2004-2016 */ /* (C) Copyright to the author Olivier BERTRAND 2004-2017 */
/* */ /* */
/* WHAT THIS PROGRAM DOES: */ /* WHAT THIS PROGRAM DOES: */
/* ----------------------- */ /* ----------------------- */
...@@ -277,8 +277,13 @@ int TABDEF::GetColCatInfo(PGLOBAL g) ...@@ -277,8 +277,13 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
// Take care of the column definitions // Take care of the column definitions
i= poff= nof= nlg= 0; i= poff= nof= nlg= 0;
#if defined(__WIN__)
// Offsets of HTML and DIR tables start from 0, DBF at 1 // Offsets of HTML and DIR tables start from 0, DBF at 1
loff= (tc == TAB_DBF) ? 1 : (tc == TAB_XML || tc == TAB_DIR) ? -1 : 0; loff = (tc == TAB_DBF) ? 1 : (tc == TAB_XML || tc == TAB_DIR) ? -1 : 0;
#else // !__WIN__
// Offsets of HTML tables start from 0, DIR and DBF at 1
loff = (tc == TAB_DBF || tc == TAB_DIR) ? 1 : (tc == TAB_XML) ? -1 : 0;
#endif // !__WIN__
while (true) { while (true) {
// Default Offset depends on table type // Default Offset depends on table type
......
...@@ -117,8 +117,10 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info) ...@@ -117,8 +117,10 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
return NULL; return NULL;
} // endif Fn } // endif Fn
tdp->Database = SetPath(g, db); if (!(tdp->Database = SetPath(g, db)))
tdp->Objname = GetStringTableOption(g, topt, "Object", NULL); return NULL;
tdp->Objname = GetStringTableOption(g, topt, "Object", NULL);
tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0; tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2); tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2);
......
...@@ -603,9 +603,10 @@ bool TDBMSD::InitFileNames(PGLOBAL g) ...@@ -603,9 +603,10 @@ bool TDBMSD::InitFileNames(PGLOBAL g)
bool DIRDEF::DefineAM(PGLOBAL g, LPCSTR, int) bool DIRDEF::DefineAM(PGLOBAL g, LPCSTR, int)
{ {
Desc = Fn = GetStringCatInfo(g, "Filename", NULL); Desc = Fn = GetStringCatInfo(g, "Filename", NULL);
Incl = (GetIntCatInfo("Subdir", 0) != 0); Incl = GetBoolCatInfo("Subdir", false);
Huge = (GetIntCatInfo("Huge", 0) != 0); Huge = GetBoolCatInfo("Huge", false);
return false; Nodir = GetBoolCatInfo("Nodir", true);
return false;
} // end of DefineAM } // end of DefineAM
/***********************************************************************/ /***********************************************************************/
...@@ -654,12 +655,14 @@ void TDBDIR::Init(void) ...@@ -654,12 +655,14 @@ void TDBDIR::Init(void)
TDBDIR::TDBDIR(PDIRDEF tdp) : TDBASE(tdp) TDBDIR::TDBDIR(PDIRDEF tdp) : TDBASE(tdp)
{ {
To_File = tdp->Fn; To_File = tdp->Fn;
Nodir = tdp->Nodir;
Init(); Init();
} // end of TDBDIR standard constructor } // end of TDBDIR standard constructor
TDBDIR::TDBDIR(PSZ fpat) : TDBASE((PTABDEF)NULL) TDBDIR::TDBDIR(PSZ fpat) : TDBASE((PTABDEF)NULL)
{ {
To_File = fpat; To_File = fpat;
Nodir = true;
Init(); Init();
} // end of TDBDIR constructor } // end of TDBDIR constructor
...@@ -812,27 +815,32 @@ int TDBDIR::ReadDB(PGLOBAL g) ...@@ -812,27 +815,32 @@ int TDBDIR::ReadDB(PGLOBAL g)
int rc = RC_OK; int rc = RC_OK;
#if defined(__WIN__) #if defined(__WIN__)
if (hSearch == INVALID_HANDLE_VALUE) { do {
/*******************************************************************/ if (hSearch == INVALID_HANDLE_VALUE) {
/* Start searching files in the target directory. The use of the */ /*****************************************************************/
/* Path function is required when called from TDBSDR. */ /* Start searching files in the target directory. The use of */
/*******************************************************************/ /* the Path function is required when called from TDBSDR. */
hSearch = FindFirstFile(Path(g), &FileData); /*****************************************************************/
hSearch = FindFirstFile(Path(g), &FileData);
if (hSearch == INVALID_HANDLE_VALUE) {
rc = RC_EF;
break;
} else
iFile++;
if (hSearch == INVALID_HANDLE_VALUE) } else {
rc = RC_EF; if (!FindNextFile(hSearch, &FileData)) {
else // Restore file name and type pattern
iFile++; _splitpath(To_File, NULL, NULL, Fname, Ftype);
rc = RC_EF;
break;
} else
iFile++;
} else { } // endif hSearch
if (!FindNextFile(hSearch, &FileData)) {
// Restore file name and type pattern
_splitpath(To_File, NULL, NULL, Fname, Ftype);
rc = RC_EF;
} else
iFile++;
} // endif hSearch } while (Nodir && FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
if (rc == RC_OK) if (rc == RC_OK)
_splitpath(FileData.cFileName, NULL, NULL, Fname, Ftype); _splitpath(FileData.cFileName, NULL, NULL, Fname, Ftype);
...@@ -1229,8 +1237,9 @@ int TDBSDR::ReadDB(PGLOBAL g) ...@@ -1229,8 +1237,9 @@ int TDBSDR::ReadDB(PGLOBAL g)
retry: retry:
do { do {
if (Sub->H == INVALID_HANDLE_VALUE) { if (Sub->H == INVALID_HANDLE_VALUE) {
_makepath(Fpath, Drive, Direc, "*", "."); // _makepath(Fpath, Drive, Direc, "*", "."); why was this made?
Sub->H = FindFirstFile(Fpath, &FileData); _makepath(Fpath, Drive, Direc, "*", NULL);
Sub->H = FindFirstFile(Fpath, &FileData);
} else if (!FindNextFile(Sub->H, &FileData)) { } else if (!FindNextFile(Sub->H, &FileData)) {
FindClose(Sub->H); FindClose(Sub->H);
Sub->H = INVALID_HANDLE_VALUE; Sub->H = INVALID_HANDLE_VALUE;
...@@ -1238,8 +1247,9 @@ int TDBSDR::ReadDB(PGLOBAL g) ...@@ -1238,8 +1247,9 @@ int TDBSDR::ReadDB(PGLOBAL g)
break; break;
} // endif findnext } // endif findnext
} while(!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) } while (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
|| *FileData.cFileName== '.'); (*FileData.cFileName == '.' &&
(!FileData.cFileName[1] || FileData.cFileName[1] == '.')));
if (Sub->H == INVALID_HANDLE_VALUE) { if (Sub->H == INVALID_HANDLE_VALUE) {
// No more sub-directories. Are we in a sub-directory? // No more sub-directories. Are we in a sub-directory?
...@@ -1293,8 +1303,9 @@ int TDBSDR::ReadDB(PGLOBAL g) ...@@ -1293,8 +1303,9 @@ int TDBSDR::ReadDB(PGLOBAL g)
if (lstat(Fpath, &Fileinfo) < 0) { if (lstat(Fpath, &Fileinfo) < 0) {
sprintf(g->Message, "%s: %s", Fpath, strerror(errno)); sprintf(g->Message, "%s: %s", Fpath, strerror(errno));
rc = RC_FX; rc = RC_FX;
} else if (S_ISDIR(Fileinfo.st_mode) && *Entry->d_name != '.') { } else if (S_ISDIR(Fileinfo.st_mode) && strcmp(Entry->d_name, ".")
// Look in the name sub-directory && strcmp(Entry->d_name, "..")) {
// Look in the name sub-directory
if (!Sub->Next) { if (!Sub->Next) {
PSUBDIR sup; PSUBDIR sup;
......
...@@ -119,7 +119,8 @@ class DllExport DIRDEF : public TABDEF { /* Directory listing table */ ...@@ -119,7 +119,8 @@ class DllExport DIRDEF : public TABDEF { /* Directory listing table */
PSZ Fn; /* Path/Name of file search */ PSZ Fn; /* Path/Name of file search */
bool Incl; /* true to include sub-directories */ bool Incl; /* true to include sub-directories */
bool Huge; /* true if files can be larger than 2GB */ bool Huge; /* true if files can be larger than 2GB */
}; // end of DIRDEF bool Nodir; /* true to exclude directories */
}; // end of DIRDEF
/***********************************************************************/ /***********************************************************************/
/* This is the DIR Access Method class declaration for tables that */ /* This is the DIR Access Method class declaration for tables that */
...@@ -175,7 +176,8 @@ class TDBDIR : public TDBASE { ...@@ -175,7 +176,8 @@ class TDBDIR : public TDBASE {
char Direc[_MAX_DIR]; // Search path char Direc[_MAX_DIR]; // Search path
char Fname[_MAX_FNAME]; // File name char Fname[_MAX_FNAME]; // File name
char Ftype[_MAX_EXT]; // File extention char Ftype[_MAX_EXT]; // File extention
}; // end of class TDBDIR bool Nodir; // Exclude directories from file list
}; // end of class TDBDIR
/***********************************************************************/ /***********************************************************************/
/* This is the DIR Access Method class declaration for tables that */ /* This is the DIR Access Method class declaration for tables that */
......
...@@ -157,8 +157,11 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info) ...@@ -157,8 +157,11 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
tdp = new(g) XMLDEF; tdp = new(g) XMLDEF;
tdp->Fn = fn; tdp->Fn = fn;
tdp->Database = SetPath(g, db);
tdp->Tabname = tab; if (!(tdp->Database = SetPath(g, db)))
return NULL;
tdp->Tabname = tab;
tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false); tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false);
tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL); tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL);
......
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