summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2016-09-16 22:14:14 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2016-09-16 22:14:14 +0200
commit7d596c9ff526bc912769490023c44e9a5b2fa743 (patch)
tree12edec16848c2065375e7c832f751ecba317328d
parent2140dcf66d7f430cbaba0cc47fe8d382574cc375 (diff)
downloadmariadb-git-7d596c9ff526bc912769490023c44e9a5b2fa743.tar.gz
- Working on MDEV-10525. Lrecl mismatch on DBF files
modified: storage/connect/filamdbf.cpp modified: storage/connect/filamdbf.h modified: storage/connect/reldef.cpp
-rw-r--r--storage/connect/filamdbf.cpp86
-rw-r--r--storage/connect/filamdbf.h2
-rw-r--r--storage/connect/reldef.cpp6
3 files changed, 74 insertions, 20 deletions
diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp
index 8afda723578..a4557facbd8 100644
--- a/storage/connect/filamdbf.cpp
+++ b/storage/connect/filamdbf.cpp
@@ -383,7 +383,7 @@ DBFBASE::DBFBASE(DBFBASE *txfp)
/* and header length. Set Records, check that Reclen is equal to lrecl and */
/* return the header length or 0 in case of error. */
/****************************************************************************/
-int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath)
+int DBFBASE::ScanHeader(PGLOBAL g, PSZ fn, int lrecl, int *rln, char *defpath)
{
int rc;
char filename[_MAX_PATH];
@@ -393,7 +393,7 @@ int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath)
/************************************************************************/
/* Open the input file. */
/************************************************************************/
- PlugSetPath(filename, fname, defpath);
+ PlugSetPath(filename, fn, defpath);
if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb")))
return 0; // Assume file does not exist
@@ -410,11 +410,7 @@ int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath)
} else if (rc == RC_FX)
return -1;
- if ((int)header.Reclen() != lrecl) {
- sprintf(g->Message, MSG(BAD_LRECL), lrecl, header.Reclen());
- return -1;
- } // endif Lrecl
-
+ *rln = (int)header.Reclen();
Records = (int)header.Records();
return (int)header.Headlen();
} // end of ScanHeader
@@ -431,9 +427,27 @@ int DBFFAM::Cardinality(PGLOBAL g)
if (!g)
return 1;
- if (!Headlen)
- if ((Headlen = ScanHeader(g, To_File, Lrecl, Tdbp->GetPath())) < 0)
- return -1; // Error in ScanHeader
+ if (!Headlen) {
+ int rln = 0; // Record length in the file header
+
+ Headlen = ScanHeader(g, To_File, Lrecl, &rln, Tdbp->GetPath());
+
+ if (Headlen < 0)
+ return -1; // Error in ScanHeader
+
+ if (rln && Lrecl != rln) {
+ // This happens always on some Linux platforms
+ sprintf(g->Message, MSG(BAD_LRECL), Lrecl, rln);
+
+ if (Accept) {
+ Lrecl = rln;
+ PushWarning(g, Tdbp);
+ } else
+ return -1;
+
+ } // endif rln
+
+ } // endif Headlen
// Set number of blocks for later use
Block = (Records > 0) ? (Records + Nrec - 1) / Nrec : 0;
@@ -565,7 +579,13 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
if (Lrecl != reclen) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, reclen);
- return true;
+
+ if (Accept) {
+ Lrecl = reclen;
+ PushWarning(g, Tdbp);
+ } else
+ return true;
+
} // endif Lrecl
hlen = HEADLEN * (n + 1) + 2;
@@ -641,8 +661,14 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
if ((rc = dbfhead(g, Stream, Tdbp->GetFile(g), &header)) == RC_OK) {
if (Lrecl != (int)header.Reclen()) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, header.Reclen());
- return true;
- } // endif Lrecl
+
+ if (Accept) {
+ Lrecl = header.Reclen();
+ PushWarning(g, Tdbp);
+ } else
+ return true;
+
+ } // endif Lrecl
Records = (int)header.Records();
Headlen = (int)header.Headlen();
@@ -916,9 +942,27 @@ int DBMFAM::Cardinality(PGLOBAL g)
if (!g)
return 1;
- if (!Headlen)
- if ((Headlen = ScanHeader(g, To_File, Lrecl, Tdbp->GetPath())) < 0)
- return -1; // Error in ScanHeader
+ if (!Headlen) {
+ int rln = 0; // Record length in the file header
+
+ Headlen = ScanHeader(g, To_File, Lrecl, &rln, Tdbp->GetPath());
+
+ if (Headlen < 0)
+ return -1; // Error in ScanHeader
+
+ if (rln && Lrecl != rln) {
+ // This happens always on some Linux platforms
+ sprintf(g->Message, MSG(BAD_LRECL), Lrecl, rln);
+
+ if (Accept) {
+ Lrecl = rln;
+ PushWarning(g, Tdbp);
+ } else
+ return -1;
+
+ } // endif rln
+
+ } // endif Headlen
// Set number of blocks for later use
Block = (Records > 0) ? (Records + Nrec - 1) / Nrec : 0;
@@ -961,8 +1005,14 @@ bool DBMFAM::AllocateBuffer(PGLOBAL g)
if (Lrecl != (int)hp->Reclen()) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, hp->Reclen());
- return true;
- } // endif Lrecl
+
+ if (Accept) {
+ Lrecl = hp->Reclen();
+ PushWarning(g, Tdbp);
+ } else
+ return true;
+
+ } // endif Lrecl
Records = (int)hp->Records();
Headlen = (int)hp->Headlen();
diff --git a/storage/connect/filamdbf.h b/storage/connect/filamdbf.h
index da84d7685a8..66458a10eaa 100644
--- a/storage/connect/filamdbf.h
+++ b/storage/connect/filamdbf.h
@@ -31,7 +31,7 @@ class DllExport DBFBASE {
DBFBASE(PDBF txfp);
// Implementation
- int ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath);
+ int ScanHeader(PGLOBAL g, PSZ fname, int lrecl, int *rlen, char *defpath);
protected:
// Default constructor, not to be used
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index 8ad6e203d51..ac2327212e0 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -440,7 +440,11 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
} // endswitch tc
// lrecl must be at least recln to avoid buffer overflow
- recln= MY_MAX(recln, Hc->GetIntegerOption("Lrecl"));
+ if (trace)
+ htrc("Lrecl: Calculated=%d defined=%d\n",
+ recln, Hc->GetIntegerOption("Lrecl"));
+
+ recln = MY_MAX(recln, Hc->GetIntegerOption("Lrecl"));
Hc->SetIntegerOption("Lrecl", recln);
((PDOSDEF)this)->SetLrecl(recln);
} // endif Lrecl