diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index e4b0a372ee0..1fdb9cb45b6 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -38,7 +38,7 @@ user_connect.h valblk.h value.h xindex.h xobject.h xtable.h) # Definitions that are shared for all OSes # add_definitions( -DMARIADB -DFORCE_INIT_OF_VARS -Dconnect_EXPORTS) -add_definitions( -DHUGE_SUPPORT -DGZ_SUPPORT -DPIVOT_SUPPORT -DUSE_TRY ) +add_definitions( -DHUGE_SUPPORT -DGZ_SUPPORT -DPIVOT_SUPPORT ) # @@ -291,6 +291,31 @@ IF(CONNECT_WITH_ZIP) add_definitions(-DZIP_SUPPORT -DNOCRYPT) ENDIF(CONNECT_WITH_ZIP) +# +# MONGO (CMAKE NOT YET WORKING) +# + +#OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON) + +#IF(CONNECT_WITH_MONGO) +# IF(WIN32) +# # Adding some typical places to search in +# SET(PC_MONGO_INCLUDE_DIRS +# C:/mongo-c-driver/include +# D:/mongo-c-driver/include) +# SET(PC_MONGO_LIBRARY_DIRS +# C:/mongo-c-driver/lib +# D:/mongo-c-driver/lib) +# ENDIF(WIN32) +# FIND_PACKAGE(libmongoc) +# IF (MONGO_FOUND) +# INCLUDE_DIRECTORIES(${MONGO_INCLUDE_DIR}) +# SET(MONGO_LIBRARY ${MONGO_LIBRARIES}) +# SET(CONNECT_SOURCES ${CONNECT_SOURCES} mongofam.cpp mongofam.h) +# add_definitions(-DMONGO_SUPPORT) +# ENDIF(MONGO_FOUND) +#ENDIF(CONNECT_WITH_MONGO) + # # XMAP @@ -310,6 +335,6 @@ MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES} STORAGE_ENGINE COMPONENT connect-engine RECOMPILE_FOR_EMBEDDED - LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY} + LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY} $(MONGO_LIBRARY) ${ODBC_LIBRARY} ${JDBC_LIBRARY} ${IPHLPAPI_LIBRARY}) diff --git a/storage/connect/array.cpp b/storage/connect/array.cpp index beb58baa107..8f037da46ed 100644 --- a/storage/connect/array.cpp +++ b/storage/connect/array.cpp @@ -519,11 +519,7 @@ bool ARRAY::FilTest(PGLOBAL g, PVAL valp, OPVAL opc, int opm) } else if (opc != OP_EXIST) { sprintf(g->Message, MSG(MISSING_ARG), opc); -#if defined(USE_TRY) throw TYPE_ARRAY; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_ARRAY); -#endif // !USE_TRY } else // OP_EXIST return Nval > 0; @@ -685,22 +681,14 @@ void ARRAY::SetPrecision(PGLOBAL g, int p) { if (Vblp == NULL) { strcpy(g->Message, MSG(PREC_VBLP_NULL)); -#if defined(USE_TRY) throw TYPE_ARRAY; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_ARRAY); -#endif // !USE_TRY } // endif Vblp bool was = Vblp->IsCi(); if (was && !p) { strcpy(g->Message, MSG(BAD_SET_CASE)); -#if defined(USE_TRY) throw TYPE_ARRAY; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_ARRAY); -#endif // !USE_TRY } // endif Vblp if (was || !p) @@ -711,11 +699,7 @@ void ARRAY::SetPrecision(PGLOBAL g, int p) if (!was && Type == TYPE_STRING) // Must be resorted to eliminate duplicate strings if (Sort(g)) -#if defined(USE_TRY) throw TYPE_ARRAY; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_ARRAY); -#endif // !USE_TRY } // end of SetPrecision diff --git a/storage/connect/blkfil.cpp b/storage/connect/blkfil.cpp index 4e5c7484057..e438e185e5d 100644 --- a/storage/connect/blkfil.cpp +++ b/storage/connect/blkfil.cpp @@ -595,11 +595,7 @@ BLKFILIN::BLKFILIN(PGLOBAL g, PTDBDOS tdbp, int op, int opm, PXOB *xp) if (Colp->GetResultType() != Type) { sprintf(g->Message, "BLKFILIN: %s", MSG(VALTYPE_NOMATCH)); -#if defined(USE_TRY) throw g->Message; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 99); -#endif // !USE_TRY } else if (Colp->GetValue()->IsCi()) Arap->SetPrecision(g, 1); // Case insensitive diff --git a/storage/connect/colblk.cpp b/storage/connect/colblk.cpp index a1169296a89..5021b22723d 100644 --- a/storage/connect/colblk.cpp +++ b/storage/connect/colblk.cpp @@ -195,13 +195,9 @@ int COLBLK::GetLengthEx(void) /* corresponding to this column and convert it to buffer type. */ /***********************************************************************/ void COLBLK::ReadColumn(PGLOBAL g) - { +{ sprintf(g->Message, MSG(UNDEFINED_AM), "ReadColumn"); -#if defined(USE_TRY) throw TYPE_COLBLK; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_COLBLK); -#endif // !USE_TRY } // end of ReadColumn /***********************************************************************/ @@ -210,13 +206,9 @@ void COLBLK::ReadColumn(PGLOBAL g) /* corresponding to this column from the column buffer and type. */ /***********************************************************************/ void COLBLK::WriteColumn(PGLOBAL g) - { +{ sprintf(g->Message, MSG(UNDEFINED_AM), "WriteColumn"); -#if defined(USE_TRY) throw TYPE_COLBLK; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_COLBLK); -#endif // !USE_TRY } // end of WriteColumn /***********************************************************************/ @@ -268,13 +260,9 @@ SPCBLK::SPCBLK(PCOLUMN cp) /* corresponding to this column from the column buffer and type. */ /***********************************************************************/ void SPCBLK::WriteColumn(PGLOBAL g) - { +{ sprintf(g->Message, MSG(SPCOL_READONLY), Name); -#if defined(USE_TRY) throw TYPE_COLBLK; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_COLBLK); -#endif // !USE_TRY } // end of WriteColumn /***********************************************************************/ diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc index 45e54ba532b..84782515a15 100644 --- a/storage/connect/connect.cc +++ b/storage/connect/connect.cc @@ -200,50 +200,31 @@ PTDB CntGetTDB(PGLOBAL g, LPCSTR name, MODE mode, PHC h) if (!cat) return NULL; -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return NULL; - } // endif jump_level + // Get table object from the catalog + tabp = new(g) XTAB(name); - if (setjmp(g->jumper[++g->jump_level])) { - tdbp = NULL; - goto err; - } // endif rc -#endif // !USE_TRY + if (trace) + printf("CntGetTDB: tabp=%p\n", tabp); - // Get table object from the catalog - tabp = new(g) XTAB(name); + // Perhaps this should be made thread safe + ((MYCAT*)cat)->SetHandler(h); - if (trace) - printf("CntGetTDB: tabp=%p\n", tabp); + if (!(tdbp = cat->GetTable(g, tabp, mode))) + printf("CntGetTDB: %s\n", g->Message); - // Perhaps this should be made thread safe - ((MYCAT*)cat)->SetHandler(h); - - if (!(tdbp = cat->GetTable(g, tabp, mode))) - printf("CntGetTDB: %s\n", g->Message); - -#if defined(USE_TRY) } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); } catch (const char *msg) { strcpy(g->Message, msg); } // end catch -#else // !USE_TRY -err: - g->jump_level--; -#endif // !USE_TRY if (trace) printf("Returning tdbp=%p mode=%d\n", tdbp, mode); return tdbp; - } // end of CntGetTDB +} // end of CntGetTDB /***********************************************************************/ /* OPENTAB: Open a Table. */ @@ -267,161 +248,116 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2, return true; } // endif tdbp -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return true; - } // endif jump_level + if (!c1) { + if (mode == MODE_INSERT) + // Allocate all column blocks for that table + tdbp->ColDB(g, NULL, 0); - if (setjmp(g->jumper[++g->jump_level])) { - goto err; - } // endif rc -#endif // !USE_TRY + } else for (p = c1; *p; p += n) { + // Allocate only used column blocks + if (trace) + printf("Allocating column %s\n", p); - if (!c1) { - if (mode == MODE_INSERT) - // Allocate all column blocks for that table - tdbp->ColDB(g, NULL, 0); + g->Message[0] = 0; // To check whether ColDB made an error message + colp = tdbp->ColDB(g, p, 0); - } else for (p= c1; *p; p+= n) { - // Allocate only used column blocks - if (trace) - printf("Allocating column %s\n", p); + if (!colp && !(mode == MODE_INSERT && tdbp->IsSpecial(p))) { + if (g->Message[0] == 0) + sprintf(g->Message, MSG(COL_ISNOT_TABLE), p, tdbp->GetName()); - g->Message[0] = 0; // To check whether ColDB made an error message - colp= tdbp->ColDB(g, p, 0); + throw 1; + } // endif colp - if (!colp && !(mode == MODE_INSERT && tdbp->IsSpecial(p))) { - if (g->Message[0] == 0) - sprintf(g->Message, MSG(COL_ISNOT_TABLE), p, tdbp->GetName()); + n = strlen(p) + 1; + } // endfor p -#if defined(USE_TRY) - throw 1; -#else // !USE_TRY - goto err; -#endif // !USE_TRY - } // endif colp + for (i = 0, colp = tdbp->GetColumns(); colp; i++, colp = colp->GetNext()) { + if (colp->InitValue(g)) + throw 2; - n= strlen(p) + 1; - } // endfor p + if (mode == MODE_INSERT) + // Allow type conversion + if (colp->SetBuffer(g, colp->GetValue(), true, false)) + throw 3; - for (i= 0, colp= tdbp->GetColumns(); colp; i++, colp= colp->GetNext()) { - if (colp->InitValue(g)) -#if defined(USE_TRY) - throw 2; -#else // !USE_TRY - goto err; -#endif // !USE_TRY + colp->AddColUse(U_P); // For PLG tables + } // endfor colp - if (mode == MODE_INSERT) - // Allow type conversion - if (colp->SetBuffer(g, colp->GetValue(), true, false)) -#if defined(USE_TRY) - throw 3; -#else // !USE_TRY - goto err; -#endif // !USE_TRY + /*******************************************************************/ + /* 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; - colp->AddColUse(U_P); // For PLG tables - } // endfor colp + if (!(utp = (PTDBASE)tdbp->Duplicate(g))) { + sprintf(g->Message, MSG(INV_UPDT_TABLE), tdbp->GetName()); + throw 4; + } // endif tp - /*********************************************************************/ - /* 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 (!c2) + // Allocate all column blocks for that table + utp->ColDB(g, NULL, 0); + else for (p = c2; *p; p += n) { + // Allocate only used column blocks + colp = utp->ColDB(g, p, 0); + n = strlen(p) + 1; + } // endfor p - if (!(utp= (PTDBASE)tdbp->Duplicate(g))) { - sprintf(g->Message, MSG(INV_UPDT_TABLE), tdbp->GetName()); -#if defined(USE_TRY) - throw 4; -#else // !USE_TRY - goto err; -#endif // !USE_TRY - } // endif tp + for (i = 0, colp = utp->GetColumns(); colp; i++, colp = colp->GetNext()) { + if (colp->InitValue(g)) + throw 5; - if (!c2) - // Allocate all column blocks for that table - utp->ColDB(g, NULL, 0); - else for (p= c2; *p; p+= n) { - // Allocate only used column blocks - colp= utp->ColDB(g, p, 0); - n= strlen(p) + 1; - } // endfor p + if (colp->SetBuffer(g, colp->GetValue(), true, false)) + throw 6; - for (i= 0, colp= utp->GetColumns(); colp; i++, colp= colp->GetNext()) { - if (colp->InitValue(g)) -#if defined(USE_TRY) - throw 5; -#else // !USE_TRY - goto err; -#endif // !USE_TRY + } // endfor colp - if (colp->SetBuffer(g, colp->GetValue(), true, false)) -#if defined(USE_TRY) - throw 6; -#else // !USE_TRY - goto err; -#endif // !USE_TRY + // Attach the updated columns list to the main table + tdbp->SetSetCols(utp->GetColumns()); + } else if (tdbp && mode == MODE_INSERT) + tdbp->SetSetCols(tdbp->GetColumns()); - } // endfor colp + // Now do open the physical table + if (trace) + printf("Opening table %s in mode %d tdbp=%p\n", + tdbp->GetName(), mode, tdbp); - // Attach the updated columns list to the main table - tdbp->SetSetCols(utp->GetColumns()); - } else if (tdbp && mode == MODE_INSERT) - tdbp->SetSetCols(tdbp->GetColumns()); + //tdbp->SetMode(mode); - // Now do open the physical table - if (trace) - printf("Opening table %s in mode %d tdbp=%p\n", - tdbp->GetName(), mode, tdbp); - -//tdbp->SetMode(mode); - - if (del/* && (tdbp->GetFtype() != RECFM_NAF*/) { - // To avoid erasing the table when doing a partial delete - // make a fake Next + if (del/* && (tdbp->GetFtype() != RECFM_NAF*/) { + // To avoid erasing the table when doing a partial delete + // make a fake Next // PDOSDEF ddp= new(g) DOSDEF; // PTDB tp= new(g) TDBDOS(ddp, NULL); - tdbp->SetNext((PTDB)1); - dup->Check &= ~CHK_DELETE; - } // endif del + tdbp->SetNext((PTDB)1); + dup->Check &= ~CHK_DELETE; + } // endif del - if (trace) - printf("About to open the table: tdbp=%p\n", tdbp); + if (trace) + printf("About to open the table: tdbp=%p\n", tdbp); - if (mode != MODE_ANY && mode != MODE_ALTER) { - if (tdbp->OpenDB(g)) { - printf("%s\n", g->Message); -#if defined(USE_TRY) - throw 7; -#else // !USE_TRY - goto err; -#endif // !USE_TRY - } else - tdbp->SetNext(NULL); + if (mode != MODE_ANY && mode != MODE_ALTER) { + if (tdbp->OpenDB(g)) { + printf("%s\n", g->Message); + throw 7; + } else + tdbp->SetNext(NULL); - } // endif mode + } // endif mode - rcop= false; + rcop = false; -#if defined(USE_TRY) } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); } catch (const char *msg) { strcpy(g->Message, msg); } // end catch -#else // !USE_TRY -err: - g->jump_level--; -#endif // !USE_TRY + return rcop; } // end of CntOpenTable @@ -441,65 +377,40 @@ bool CntRewindTable(PGLOBAL g, PTDB tdbp) /* Evaluate all columns after a record is read. */ /***********************************************************************/ RCODE EvalColumns(PGLOBAL g, PTDB tdbp, bool reset, bool mrr) - { +{ RCODE rc= RC_OK; PCOL colp; -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - if (trace) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - printf("EvalColumns: %s\n", g->Message); - } // endif + for (colp = tdbp->GetColumns(); rc == RC_OK && colp; + colp = colp->GetNext()) { + if (reset) + colp->Reset(); - return RC_FX; - } // endif jump_level + // Virtual columns are computed by MariaDB + if (!colp->GetColUse(U_VIRTUAL) && (!mrr || colp->GetKcol())) + if (colp->Eval(g)) + rc = RC_FX; - if (setjmp(g->jumper[++g->jump_level]) != 0) { + } // endfor colp + + } catch (int n) { if (trace) - printf("Error reading columns: %s\n", g->Message); + printf("Error %d reading columns: %s\n", n, g->Message); rc = RC_FX; - goto err; - } // endif rc -#endif // !USE_TRY + } catch (const char *msg) { + strcpy(g->Message, msg); + } // end catch - for (colp= tdbp->GetColumns(); rc == RC_OK && colp; - colp= colp->GetNext()) { - if (reset) - colp->Reset(); - - // Virtual columns are computed by MariaDB - if (!colp->GetColUse(U_VIRTUAL) && (!mrr || colp->GetKcol())) - if (colp->Eval(g)) - rc= RC_FX; - - } // endfor colp - -#if defined(USE_TRY) -} catch (int n) { - if (trace) - printf("Error %d reading columns: %s\n", n, g->Message); - - rc = RC_FX; -} catch (const char *msg) { - strcpy(g->Message, msg); -} // end catch -#else // !USE_TRY -err: - g->jump_level--; -#endif // !USE_TRY return rc; - } // end of EvalColumns +} // end of EvalColumns /***********************************************************************/ /* ReadNext: Read next record sequentially. */ /***********************************************************************/ RCODE CntReadNext(PGLOBAL g, PTDB tdbp) - { +{ RCODE rc; if (!tdbp) @@ -514,103 +425,66 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp) ((PTDBASE)tdbp)->ResetKindex(g, NULL); } // endif index -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return RC_FX; - } // endif jump_level + // Do it now to avoid double eval when filtering + for (PCOL colp = tdbp->GetColumns(); colp; colp = colp->GetNext()) + colp->Reset(); - if ((setjmp(g->jumper[++g->jump_level])) != 0) { - rc = RC_FX; - goto err; - } // endif rc -#endif // !USE_TRY + do { + if ((rc = (RCODE)tdbp->ReadDB(g)) == RC_OK) + if (!ApplyFilter(g, tdbp->GetFilter())) + rc = RC_NF; - // Do it now to avoid double eval when filtering - for (PCOL colp= tdbp->GetColumns(); colp; colp= colp->GetNext()) - colp->Reset(); + } while (rc == RC_NF); - do { - if ((rc= (RCODE)tdbp->ReadDB(g)) == RC_OK) - if (!ApplyFilter(g, tdbp->GetFilter())) - rc= RC_NF; + if (rc == RC_OK) + rc = EvalColumns(g, tdbp, false); - } while (rc == RC_NF); - - if (rc == RC_OK) - rc= EvalColumns(g, tdbp, false); - -#if defined(USE_TRY) - } catch (int) { + } catch (int) { rc = RC_FX; } catch (const char *msg) { strcpy(g->Message, msg); rc = RC_FX; } // end catch -#else // !USE_TRY -err: - g->jump_level--; -#endif // !USE_TRY + return rc; - } // end of CntReadNext +} // end of CntReadNext /***********************************************************************/ /* WriteRow: Insert a new row into a table. */ /***********************************************************************/ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp) - { - RCODE rc; - PCOL colp; -//PTDBASE tp= (PTDBASE)tdbp; +{ + RCODE rc; + PCOL colp; + //PTDBASE tp= (PTDBASE)tdbp; - if (!tdbp) - return RC_FX; - -#if defined(USE_TRY) - try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); + if (!tdbp) return RC_FX; - } // endif jump_level - if (setjmp(g->jumper[++g->jump_level]) != 0) { - printf("%s\n", g->Message); + try { + // Store column values in table write buffer(s) + for (colp = tdbp->GetSetCols(); colp; colp = colp->GetNext()) + if (!colp->GetColUse(U_VIRTUAL)) + colp->WriteColumn(g); + + if (tdbp->IsIndexed()) + // Index values must be sorted before updating + rc = (RCODE)((PTDBDOS)tdbp)->GetTxfp()->StoreValues(g, true); + else + // Return result code from write operation + rc = (RCODE)tdbp->WriteDB(g); + + } catch (int n) { + printf("Exception %d: %s\n", n, g->Message); rc = RC_FX; - goto err; - } // endif rc -#endif // !USE_TRY + } catch (const char *msg) { + strcpy(g->Message, msg); + rc = RC_FX; + } // end catch - // Store column values in table write buffer(s) - for (colp= tdbp->GetSetCols(); colp; colp= colp->GetNext()) - if (!colp->GetColUse(U_VIRTUAL)) - colp->WriteColumn(g); - - if (tdbp->IsIndexed()) - // Index values must be sorted before updating - rc= (RCODE)((PTDBDOS)tdbp)->GetTxfp()->StoreValues(g, true); - else - // Return result code from write operation - rc= (RCODE)tdbp->WriteDB(g); - -#if defined(USE_TRY) -} catch (int n) { - printf("Exception %d: %s\n", n, g->Message); - rc = RC_FX; -} catch (const char *msg) { - strcpy(g->Message, msg); - rc = RC_FX; -} // end catch -#else // !USE_TRY -err: - g->jump_level--; -#endif // !USE_TRY - return rc; - } // end of CntWriteRow + return rc; +} // end of CntWriteRow /***********************************************************************/ /* UpdateRow: Update a row into a table. */ @@ -658,98 +532,78 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all) /* CLOSETAB: Close a table. */ /***********************************************************************/ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) - { - int rc= RC_OK; -//TDBASE *tbxp= (PTDBASE)tdbp; +{ + int rc = RC_OK; + //TDBASE *tbxp= (PTDBASE)tdbp; - if (!tdbp) - return rc; // Nothing to do - else if (tdbp->GetUse() != USE_OPEN) { - if (tdbp->GetAmType() == TYPE_AM_XML) - tdbp->CloseDB(g); // Opened by GetMaxSize + if (!tdbp) + return rc; // Nothing to do + else if (tdbp->GetUse() != USE_OPEN) { + if (tdbp->GetAmType() == TYPE_AM_XML) + tdbp->CloseDB(g); // Opened by GetMaxSize - return rc; - } // endif !USE_OPEN + return rc; + } // endif !USE_OPEN - if (trace) - printf("CntCloseTable: tdbp=%p mode=%d nox=%d abort=%d\n", - tdbp, tdbp->GetMode(), nox, abort); + if (trace) + printf("CntCloseTable: tdbp=%p mode=%d nox=%d abort=%d\n", + tdbp, tdbp->GetMode(), nox, abort); - if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) { - if (tdbp->IsIndexed()) - rc= ((PTDBDOS)tdbp)->GetTxfp()->DeleteSortedRows(g); + if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) { + if (tdbp->IsIndexed()) + rc = ((PTDBDOS)tdbp)->GetTxfp()->DeleteSortedRows(g); - if (!rc) - rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine + if (!rc) + rc = tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine - } else if (tdbp->GetMode() == MODE_UPDATE && tdbp->IsIndexed()) - rc= ((PTDBDOX)tdbp)->Txfp->UpdateSortedRows(g); + } else if (tdbp->GetMode() == MODE_UPDATE && tdbp->IsIndexed()) + rc = ((PTDBDOX)tdbp)->Txfp->UpdateSortedRows(g); - switch(rc) { - case RC_FX: - abort= true; - break; - case RC_INFO: - PushWarning(g, tdbp); - break; - } // endswitch rc + switch (rc) { + case RC_FX: + abort = true; + break; + case RC_INFO: + PushWarning(g, tdbp); + break; + } // endswitch rc -#if defined(USE_TRY) try { -#else // !USE_TRY - // Prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - rc = RC_FX; - goto err; - } // endif + // This will close the table file(s) and also finalize write + // operations such as Insert, Update, or Delete. + tdbp->SetAbort(abort); + tdbp->CloseDB(g); + tdbp->SetAbort(false); - if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) { - rc = RC_FX; - goto err; - } // endif -#endif // !USE_TRY - - // This will close the table file(s) and also finalize write - // operations such as Insert, Update, or Delete. - tdbp->SetAbort(abort); - tdbp->CloseDB(g); - tdbp->SetAbort(false); - - if (trace > 1) - printf("Table %s closed\n", tdbp->GetName()); - - if (!nox && tdbp->GetMode() != MODE_READ && tdbp->GetMode() != MODE_ANY) { if (trace > 1) - printf("About to reset opt\n"); + printf("Table %s closed\n", tdbp->GetName()); - if (!tdbp->IsRemote()) { - // Make all the eventual indexes - PTDBDOX tbxp = (PTDBDOX)tdbp; - tbxp->ResetKindex(g, NULL); - tbxp->SetKey_Col(NULL); - rc = tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1); - } // endif remote + if (!nox && tdbp->GetMode() != MODE_READ && tdbp->GetMode() != MODE_ANY) { + if (trace > 1) + printf("About to reset opt\n"); - } // endif nox + if (!tdbp->IsRemote()) { + // Make all the eventual indexes + PTDBDOX tbxp = (PTDBDOX)tdbp; + tbxp->ResetKindex(g, NULL); + tbxp->SetKey_Col(NULL); + rc = tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1); + } // endif remote -#if defined(USE_TRY) -} catch (int) { - rc = RC_FX; -} catch (const char *msg) { - strcpy(g->Message, msg); - rc = RC_FX; -} // end catch -#else // !USE_TRY -err: - g->jump_level--; -#endif // !USE_TRY + } // endif nox - if (trace > 1) - htrc("Done rc=%d\n", rc); + } catch (int) { + rc = RC_FX; + } catch (const char *msg) { + strcpy(g->Message, msg); + rc = RC_FX; + } // end catch - return (rc == RC_OK || rc == RC_INFO) ? 0 : rc; - } // end of CntCloseTable + if (trace > 1) + htrc("Done rc=%d\n", rc); + + return (rc == RC_OK || rc == RC_INFO) ? 0 : rc; +} // end of CntCloseTable /***********************************************************************/ /* Load and initialize the use of an index. */ diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp index f58a94d958f..382af51aae4 100644 --- a/storage/connect/filamtxt.cpp +++ b/storage/connect/filamtxt.cpp @@ -986,7 +986,7 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc) } else { /*****************************************************************/ - /* Move of eventual preceding lines is not required here. */ + /* Move of eventual preceding lines is not required here. */ /* Set the target file as being the source file itself. */ /* Set the future Tpos, and give Spos a value to block copying. */ /*****************************************************************/ @@ -1174,20 +1174,12 @@ int DOSFAM::RenameTempFile(PGLOBAL g) if (rename(filename, filetemp)) { // Save file for security sprintf(g->Message, MSG(RENAME_ERROR), filename, filetemp, strerror(errno)); -#if defined(USE_TRY) throw 51; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 51); -#endif // !USE_TRY } else if (rename(tempname, filename)) { sprintf(g->Message, MSG(RENAME_ERROR), tempname, filename, strerror(errno)); rc = rename(filetemp, filename); // Restore saved file -#if defined(USE_TRY) throw 52; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 52); -#endif // !USE_TRY } else if (remove(filetemp)) { sprintf(g->Message, MSG(REMOVE_ERROR), filetemp, strerror(errno)); diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp index 8e5c31d6b49..c211f190e82 100755 --- a/storage/connect/filamvct.cpp +++ b/storage/connect/filamvct.cpp @@ -559,7 +559,7 @@ bool VCTFAM::AllocateBuffer(PGLOBAL g) /* Do initial action when inserting. */ /***********************************************************************/ bool VCTFAM::InitInsert(PGLOBAL g) - { +{ bool rc = false; // We come here in MODE_INSERT only @@ -575,26 +575,11 @@ bool VCTFAM::InitInsert(PGLOBAL g) CurBlk = Block - 1; CurNum = Last; -#if defined(USE_TRY) try { -#else // !USE_TRY - // Prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return true; - } // endif + // Last block must be updated by new values + for (; cp; cp = (PVCTCOL)cp->Next) + cp->ReadBlock(g); - if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) { - g->jump_level--; - return true; - } // endif -#endif // !USE_TRY - - // Last block must be updated by new values - for (; cp; cp = (PVCTCOL)cp->Next) - cp->ReadBlock(g); - -#if defined(USE_TRY) } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); @@ -603,9 +588,7 @@ bool VCTFAM::InitInsert(PGLOBAL g) strcpy(g->Message, msg); rc = true; } // end catch -#else // !USE_TRY - g->jump_level--; -#endif // !USE_TRY + } // endif Last if (!rc) @@ -1126,11 +1109,7 @@ void VCTFAM::CloseTableFile(PGLOBAL g, bool abort) } else if (AddBlock) { // Last block was not written rc = ResetTableSize(g, CurBlk, Nrec); -#if defined(USE_TRY) throw 44; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 44); -#endif // !USE_TRY } // endif } else if (mode == MODE_UPDATE) { @@ -1550,7 +1529,7 @@ bool VCMFAM::AllocateBuffer(PGLOBAL g) /* Do initial action when inserting. */ /***********************************************************************/ bool VCMFAM::InitInsert(PGLOBAL g) - { +{ bool rc = false; volatile PVCTCOL cp = (PVCTCOL)Tdbp->GetColumns(); @@ -1565,27 +1544,12 @@ bool VCMFAM::InitInsert(PGLOBAL g) CurNum = Last; } // endif Last -#if defined(USE_TRY) try { -#else // !USE_TRY - // Prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return true; - } // endif + // Initialize the column block pointer + for (; cp; cp = (PVCTCOL)cp->Next) + cp->ReadBlock(g); - if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) { - g->jump_level--; - return true; - } // endif -#endif // !USE_TRY - - // Initialize the column block pointer - for (; cp; cp = (PVCTCOL)cp->Next) - cp->ReadBlock(g); - -#if defined(USE_TRY) - } catch (int n) { + } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); rc = true; @@ -1593,11 +1557,9 @@ bool VCMFAM::InitInsert(PGLOBAL g) strcpy(g->Message, msg); rc = true; } // end catch -#else // !USE_TRY - g->jump_level--; -#endif // !USE_TRY + return rc; - } // end of InitInsert +} // end of InitInsert /***********************************************************************/ /* Data Base write routine for VMP access method. */ @@ -2541,11 +2503,7 @@ void VECFAM::CloseTableFile(PGLOBAL g, bool abort) if (wrc != RC_FX) rc = ResetTableSize(g, Block, Last); else -#if defined(USE_TRY) throw 44; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 44); -#endif // !USE_TRY } else if (mode == MODE_UPDATE) { if (UseTemp && !InitUpdate && !Abort) { @@ -4206,11 +4164,7 @@ void BGVFAM::CloseTableFile(PGLOBAL g, bool abort) } else if (AddBlock) { // Last block was not written rc = ResetTableSize(g, CurBlk, Nrec); -#if defined(USE_TRY) throw 44; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 44); -#endif // !USE_TRY } // endif } else if (mode == MODE_UPDATE) { diff --git a/storage/connect/filter.cpp b/storage/connect/filter.cpp index db96647f634..0c38d10a578 100644 --- a/storage/connect/filter.cpp +++ b/storage/connect/filter.cpp @@ -87,11 +87,7 @@ BYTE OpBmp(PGLOBAL g, OPVAL opc) case OP_EXIST: bt = 0x00; break; default: sprintf(g->Message, MSG(BAD_FILTER_OP), opc); -#if defined(USE_TRY) throw TYPE_ARRAY; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_ARRAY); -#endif // !USE_TRY } // endswitch opc return bt; @@ -1715,11 +1711,7 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having) break; // Remove eventual ending separator(s) // if (fp->Convert(g, having)) -//#if defined(USE_TRY) // throw TYPE_ARRAY; -//#else // !USE_TRY -// longjmp(g->jumper[g->jump_level], TYPE_FILTER); -//#endif // !USE_TRY filp = fp; fp = fp->Next; @@ -1752,11 +1744,7 @@ DllExport bool ApplyFilter(PGLOBAL g, PFIL filp) // return TRUE; if (filp->Eval(g)) -#if defined(USE_TRY) throw TYPE_FILTER; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_FILTER); -#endif // !USE_TRY if (trace > 1) htrc("PlugFilter filp=%p result=%d\n", diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 6d4d875c494..681869755bf 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -172,9 +172,9 @@ #define JSONMAX 10 // JSON Default max grp size extern "C" { - char version[]= "Version 1.05.0003 March 7, 2017"; + char version[]= "Version 1.06.0001 April 7, 2017"; #if defined(__WIN__) - char compver[]= "Version 1.05.0003 " __DATE__ " " __TIME__; + char compver[]= "Version 1.06.0001 " __DATE__ " " __TIME__; char slash= '\\'; #else // !__WIN__ char slash= '/'; @@ -209,7 +209,7 @@ pthread_mutex_t parmut = PTHREAD_MUTEX_INITIALIZER; /***********************************************************************/ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info); PQRYRES VirColumns(PGLOBAL g, bool info); -PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info); +PQRYRES JSONColumns(PGLOBAL g, char *db, char *dsn, PTOS topt, bool info); PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info); int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v); void PushWarning(PGLOBAL g, THD *thd, int level); @@ -217,6 +217,7 @@ bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, const char *db, char *tab, const char *src, int port); bool ZipLoadFile(PGLOBAL, char*, char*, char*, bool, bool); bool ExactInfo(void); +void mongo_init(bool); USETEMP UseTemp(void); int GetConvSize(void); TYPCONV GetTypeConv(void); @@ -670,10 +671,14 @@ static int connect_init_func(void *p) sql_print_information("CONNECT: %s", version); #endif // !__WIN__ -#ifdef LIBXML2_SUPPORT +#if defined(LIBXML2_SUPPORT) XmlInitParserLib(); #endif // LIBXML2_SUPPORT +#if defined(MONGO_SUPPORT) + mongo_init(true); +#endif // MONGO_SUPPORT + init_connect_psi_keys(); connect_hton= (handlerton *)p; @@ -712,6 +717,10 @@ static int connect_done_func(void *) XmlCleanupParserLib(); #endif // LIBXML2_SUPPORT +#if defined(MONGO_SUPPORT) + mongo_init(false); +#endif // MONGO_SUPPORT + #ifdef JDBC_SUPPORT JDBConn::ResetJVM(); #endif // JDBC_SUPPORT @@ -1901,41 +1910,21 @@ bool ha_connect::CheckColumnList(PGLOBAL g) Field* fp; MY_BITMAP *map= table->read_set; -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return true; - } // endif jump_level - - if (!setjmp(g->jumper[++g->jump_level])) { -#endif // !USE_TRY for (field= table->field; fp= *field; field++) if (bitmap_is_set(map, fp->field_index)) { if (!(colp= tdbp->ColDB(g, (PSZ)fp->field_name, 0))) { sprintf(g->Message, "Column %s not found in %s", fp->field_name, tdbp->GetName()); -#if defined(USE_TRY) throw 1; -#else // !USE_TRY - brc = true; - goto fin; -#endif // !USE_TRY } // endif colp if ((brc= colp->InitValue(g))) -#if defined(USE_TRY) throw 2; -#else // !USE_TRY - goto fin; -#endif // !USE_TRY colp->AddColUse(U_P); // For PLG tables } // endif -#if defined(USE_TRY) } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); @@ -1944,13 +1933,7 @@ bool ha_connect::CheckColumnList(PGLOBAL g) strcpy(g->Message, msg); brc = true; } // end catch -#else // !USE_TRY - } else - brc = true; - fin: - g->jump_level--; -#endif // !USE_TRY return brc; } // end of CheckColumnList @@ -3084,59 +3067,46 @@ const COND *ha_connect::cond_push(const COND *cond) tty == TYPE_AM_PLG || tty == TYPE_AM_JDBC || x); // This should never happen but is done to avoid crashing -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - DBUG_RETURN(cond); - } // endif jump_level + if (b) { + PCFIL filp; + int rc; - if (setjmp(g->jumper[++g->jump_level])) - goto fin; -#endif // !USE_TRY + if ((filp = tdbp->GetCondFil()) && filp->Cond == cond && + filp->Idx == active_index && filp->Type == tty) + goto fin; - if (b) { - PCFIL filp; - int rc; + filp = new(g) CONDFIL(cond, active_index, tty); + rc = filp->Init(g, this); - if ((filp= tdbp->GetCondFil()) && filp->Cond == cond && - filp->Idx == active_index && filp->Type == tty) - goto fin; + if (rc == RC_INFO) { + filp->Having = (char*)PlugSubAlloc(g, NULL, 256); + *filp->Having = 0; + } else if (rc == RC_FX) + goto fin; - filp= new(g) CONDFIL(cond, active_index, tty); - rc = filp->Init(g, this); + filp->Body = (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0); + *filp->Body = 0; - if (rc == RC_INFO) { - filp->Having = (char*)PlugSubAlloc(g, NULL, 256); - *filp->Having = 0; - } else if (rc == RC_FX) - goto fin; + if (CheckCond(g, filp, cond)) { + if (filp->Having && strlen(filp->Having) > 255) + goto fin; // Memory collapse - filp->Body = (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0); - *filp->Body = 0; + if (trace) + htrc("cond_push: %s\n", filp->Body); - if (CheckCond(g, filp, cond)) { - if (filp->Having && strlen(filp->Having) > 255) - goto fin; // Memory collapse + if (!x) + PlugSubAlloc(g, NULL, strlen(filp->Body) + 1); + else + cond = NULL; // Does this work? - if (trace) - htrc("cond_push: %s\n", filp->Body); + tdbp->SetCondFil(filp); + } else if (x && cond) + tdbp->SetCondFil(filp); // Wrong filter - if (!x) - PlugSubAlloc(g, NULL, strlen(filp->Body) + 1); - else - cond= NULL; // Does this work? + } else // if (tty != TYPE_AM_JSN && tty != TYPE_AM_JSON) + tdbp->SetFilter(CondFilter(g, (Item *)cond)); - tdbp->SetCondFil(filp); - } else if (x && cond) - tdbp->SetCondFil(filp); // Wrong filter - - } else if (tty != TYPE_AM_JSN && tty != TYPE_AM_JSON) - tdbp->SetFilter(CondFilter(g, (Item *)cond)); - -#if defined(USE_TRY) } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); @@ -3145,10 +3115,6 @@ const COND *ha_connect::cond_push(const COND *cond) } // end catch fin:; -#else // !USE_TRY - fin: - g->jump_level--; -#endif // !USE_TRY } // endif tdbp // Let MySQL do the filtering @@ -3299,44 +3265,28 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT*) PGLOBAL& g= xp->g; PDBUSER dup= PlgGetUser(g); -#if defined(USE_TRY) try { -#else // !USE_TRY - // Prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - rc = HA_ERR_INTERNAL_ERROR; - goto err; - } // endif + // Ignore error on the opt file + dup->Check &= ~CHK_OPT; + tdbp = GetTDB(g); + dup->Check |= CHK_OPT; - if (setjmp(g->jumper[++g->jump_level])) { - rc = HA_ERR_INTERNAL_ERROR; - goto err; - } // endif setjmp -#endif // !USE_TRY + if (tdbp && !tdbp->IsRemote()) { + bool dop = IsTypeIndexable(GetRealType(NULL)); + bool dox = (tdbp->GetDef()->Indexable() == 1); - // Ignore error on the opt file - dup->Check &= ~CHK_OPT; - tdbp= GetTDB(g); - dup->Check |= CHK_OPT; + if ((rc = ((PTDBASE)tdbp)->ResetTableOpt(g, dop, dox))) { + if (rc == RC_INFO) { + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); + rc = 0; + } else + rc = HA_ERR_INTERNAL_ERROR; - if (tdbp && !tdbp->IsRemote()) { - bool dop= IsTypeIndexable(GetRealType(NULL)); - bool dox= (tdbp->GetDef()->Indexable() == 1); + } // endif rc - if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, dop, dox))) { - if (rc == RC_INFO) { - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); - rc= 0; - } else - rc= HA_ERR_INTERNAL_ERROR; + } else if (!tdbp) + rc = HA_ERR_INTERNAL_ERROR; - } // endif rc - - } else if (!tdbp) - rc= HA_ERR_INTERNAL_ERROR; - -#if defined(USE_TRY) } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); @@ -3345,10 +3295,6 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT*) strcpy(g->Message, msg); rc = HA_ERR_INTERNAL_ERROR; } // end catch -#else // !USE_TRY -err: - g->jump_level--; -#endif // !USE_TRY return rc; } // end of optimize @@ -5401,547 +5347,493 @@ static int connect_assisted_discovery(handlerton *, THD* thd, if (!(shm= (char*)db)) db= table_s->db.str; // Default value -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - goto jer; - } // endif jump_level + // Check table type + if (ttp == TAB_UNDEF) { + topt->type = (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS"; + ttp = GetTypeID(topt->type); + sprintf(g->Message, "No table_type. Was set to %s", topt->type); + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); + } else if (ttp == TAB_NIY) { + sprintf(g->Message, "Unsupported table type %s", topt->type); + rc = HA_ERR_INTERNAL_ERROR; + goto err; + } // endif ttp - if (setjmp(g->jumper[++g->jump_level]) != 0) { - rc = HA_ERR_INTERNAL_ERROR; - goto err; - } // endif rc -#endif // !USE_TRY + if (!tab) { + if (ttp == TAB_TBL) { + // Make tab the first table of the list + char *p; - // Check table type - if (ttp == TAB_UNDEF) { - topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS"; - ttp= GetTypeID(topt->type); - sprintf(g->Message, "No table_type. Was set to %s", topt->type); - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); - } else if (ttp == TAB_NIY) { - sprintf(g->Message, "Unsupported table type %s", topt->type); - rc = HA_ERR_INTERNAL_ERROR; - goto err; - } // endif ttp - - if (!tab) { - if (ttp == TAB_TBL) { - // Make tab the first table of the list - char *p; - - if (!tbl) { - strcpy(g->Message, "Missing table list"); - rc = HA_ERR_INTERNAL_ERROR; - goto err; - } // endif tbl - - tab= PlugDup(g, tbl); - - if ((p= strchr(tab, ','))) - *p= 0; - - if ((p=strchr(tab, '.'))) { - *p= 0; - db= tab; - tab= p + 1; - } // endif p - - } else if (ttp != TAB_ODBC || !(fnc & (FNC_TABLE | FNC_COL))) - tab= table_s->table_name.str; // Default value - - } // endif tab - - switch (ttp) { -#if defined(ODBC_SUPPORT) - case TAB_ODBC: - dsn= strz(g, create_info->connect_string); - - if (fnc & (FNC_DSN | FNC_DRIVER)) { - ok= true; -#if defined(PROMPT_OK) - } else if (!stricmp(thd->main_security_ctx.host, "localhost") - && cop == 1) { - if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) { - thd->make_lex_string(&create_info->connect_string, dsn, strlen(dsn)); - ok= true; - } // endif dsn -#endif // PROMPT_OK - - } else if (!dsn) { - sprintf(g->Message, "Missing %s connection string", topt->type); - } else { - // Store ODBC additional parameters - sop= (POPARM)PlugSubAlloc(g, NULL, sizeof(ODBCPARM)); - sop->User= (char*)user; - sop->Pwd= (char*)pwd; - sop->Cto= cto; - sop->Qto= qto; - sop->UseCnc= cnc; - ok= true; - } // endif's - - supfnc |= (FNC_TABLE | FNC_DSN | FNC_DRIVER); - break; -#endif // ODBC_SUPPORT -#if defined(JDBC_SUPPORT) - case TAB_JDBC: - if (fnc & FNC_DRIVER) { - ok= true; - } else if (!(url= strz(g, create_info->connect_string))) { - strcpy(g->Message, "Missing URL"); - } else { - // Store JDBC additional parameters - int rc; - PJDBCDEF jdef= new(g) JDBCDEF(); - - jdef->SetName(create_info->alias); - sjp= (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM)); - sjp->Driver= driver; -// sjp->Properties = prop; - sjp->Fsize= 0; - sjp->Scrollable= false; - - if ((rc = jdef->ParseURL(g, url, false)) == RC_OK) { - sjp->Url= url; - sjp->User= (char*)user; - sjp->Pwd= (char*)pwd; - ok= true; - } else if (rc == RC_NF) { - if (jdef->GetTabname()) - tab= jdef->GetTabname(); - - ok= jdef->SetParms(sjp); - } // endif rc - - } // endif's - - supfnc |= (FNC_DRIVER | FNC_TABLE); - break; -#endif // JDBC_SUPPORT - case TAB_DBF: - dbf= true; - // Passthru - case TAB_CSV: - if (!fn && fnc != FNC_NO) - sprintf(g->Message, "Missing %s file name", topt->type); - else if (sep && strlen(sep) > 1) - sprintf(g->Message, "Invalid separator %s", sep); - else - ok= true; - - break; - case TAB_MYSQL: - ok= true; - - if (create_info->connect_string.str && - create_info->connect_string.length) { - PMYDEF mydef= new(g) MYSQLDEF(); - - dsn= strz(g, create_info->connect_string); - mydef->SetName(create_info->alias); - - if (!mydef->ParseURL(g, dsn, false)) { - if (mydef->GetHostname()) - host= mydef->GetHostname(); - - if (mydef->GetUsername()) - user= mydef->GetUsername(); - - if (mydef->GetPassword()) - pwd= mydef->GetPassword(); - - if (mydef->GetTabschema()) - db = mydef->GetTabschema(); - - if (mydef->GetTabname()) - tab= mydef->GetTabname(); - - if (mydef->GetPortnumber()) - port= mydef->GetPortnumber(); - - } else - ok= false; - - } else if (!user) - user= "root"; - - if (ok && CheckSelf(g, table_s, host, db, tab, src, port)) - ok= false; - - break; -#if defined(__WIN__) - case TAB_WMI: - ok= true; - break; -#endif // __WIN__ -#if defined(PIVOT_SUPPORT) - case TAB_PIVOT: - supfnc= FNC_NO; -#endif // PIVOT_SUPPORT - case TAB_PRX: - case TAB_TBL: - case TAB_XCL: - case TAB_OCCUR: - if (!src && !stricmp(tab, create_info->alias) && - (!db || !stricmp(db, table_s->db.str))) - sprintf(g->Message, "A %s table cannot refer to itself", topt->type); - else - ok= true; - - break; - case TAB_OEM: - if (topt->module && topt->subtype) - ok= true; - else - strcpy(g->Message, "Missing OEM module or subtype"); - - break; -#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT) - case TAB_XML: -#endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT - case TAB_JSON: - if (!fn && !zfn && !mul) - sprintf(g->Message, "Missing %s file name", topt->type); - else - ok= true; - - break; - case TAB_VIR: - ok= true; - break; - default: - sprintf(g->Message, "Cannot get column info for table type %s", topt->type); - break; - } // endif ttp - - // Check for supported catalog function - if (ok && !(supfnc & fnc)) { - sprintf(g->Message, "Unsupported catalog function %s for table type %s", - fncn, topt->type); - ok= false; - } // endif supfnc - - if (src && fnc != FNC_NO) { - strcpy(g->Message, "Cannot make catalog table from srcdef"); - ok= false; - } // endif src - - if (ok) { - char *cnm, *rem, *dft, *xtra, *key, *fmt; - int i, len, prec, dec, typ, flg; - - // if (cat) - // cat->SetDataPath(g, table_s->db.str); - // else - // return HA_ERR_INTERNAL_ERROR; // Should never happen - - dpath = SetPath(g, table_s->db.str); - - if (src && ttp != TAB_PIVOT && ttp != TAB_ODBC && ttp != TAB_JDBC) { - qrp = SrcColumns(g, host, db, user, pwd, src, port); - - if (qrp && ttp == TAB_OCCUR) - if (OcrSrcCols(g, qrp, col, ocl, rnk)) { + if (!tbl) { + strcpy(g->Message, "Missing table list"); rc = HA_ERR_INTERNAL_ERROR; goto err; - } // endif OcrSrcCols + } // endif tbl - } else switch (ttp) { - case TAB_DBF: - qrp = DBFColumns(g, dpath, fn, fnc == FNC_COL); - break; + tab = PlugDup(g, tbl); + + if ((p = strchr(tab, ','))) + *p = 0; + + if ((p = strchr(tab, '.'))) { + *p = 0; + db = tab; + tab = p + 1; + } // endif p + + } else if (ttp != TAB_ODBC || !(fnc & (FNC_TABLE | FNC_COL))) + tab = table_s->table_name.str; // Default value + + } // endif tab + + switch (ttp) { #if defined(ODBC_SUPPORT) case TAB_ODBC: - switch (fnc) { - case FNC_NO: - case FNC_COL: - if (src) { - qrp = ODBCSrcCols(g, dsn, (char*)src, sop); - src = NULL; // for next tests - } else - qrp = ODBCColumns(g, dsn, shm, tab, NULL, - mxr, fnc == FNC_COL, sop); + dsn = strz(g, create_info->connect_string); - break; - case FNC_TABLE: - qrp = ODBCTables(g, dsn, shm, tab, NULL, mxr, true, sop); - break; - case FNC_DSN: - qrp = ODBCDataSources(g, mxr, true); - break; - case FNC_DRIVER: - qrp = ODBCDrivers(g, mxr, true); - break; - default: - sprintf(g->Message, "invalid catfunc %s", fncn); - break; - } // endswitch info + if (fnc & (FNC_DSN | FNC_DRIVER)) { + ok = true; +#if defined(PROMPT_OK) + } else if (!stricmp(thd->main_security_ctx.host, "localhost") + && cop == 1) { + if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) { + thd->make_lex_string(&create_info->connect_string, dsn, strlen(dsn)); + ok = true; + } // endif dsn +#endif // PROMPT_OK + } else if (!dsn) { + sprintf(g->Message, "Missing %s connection string", topt->type); + } else { + // Store ODBC additional parameters + sop = (POPARM)PlugSubAlloc(g, NULL, sizeof(ODBCPARM)); + sop->User = (char*)user; + sop->Pwd = (char*)pwd; + sop->Cto = cto; + sop->Qto = qto; + sop->UseCnc = cnc; + ok = true; + } // endif's + + supfnc |= (FNC_TABLE | FNC_DSN | FNC_DRIVER); break; #endif // ODBC_SUPPORT #if defined(JDBC_SUPPORT) case TAB_JDBC: - switch (fnc) { - case FNC_NO: - case FNC_COL: - if (src) { - qrp = JDBCSrcCols(g, (char*)src, sjp); - src = NULL; // for next tests - } else - qrp = JDBCColumns(g, shm, tab, NULL, mxr, fnc == FNC_COL, sjp); + if (fnc & FNC_DRIVER) { + ok = true; + } else if (!(url = strz(g, create_info->connect_string))) { + strcpy(g->Message, "Missing URL"); + } else { + // Store JDBC additional parameters + int rc; + PJDBCDEF jdef = new(g) JDBCDEF(); - break; - case FNC_TABLE: - qrp = JDBCTables(g, shm, tab, tabtyp, mxr, true, sjp); - break; -#if 0 - case FNC_DSN: - qrp = JDBCDataSources(g, mxr, true); - break; -#endif // 0 - case FNC_DRIVER: - qrp = JDBCDrivers(g, mxr, true); - break; - default: - sprintf(g->Message, "invalid catfunc %s", fncn); - break; - } // endswitch info + jdef->SetName(create_info->alias); + sjp = (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM)); + sjp->Driver = driver; + // sjp->Properties = prop; + sjp->Fsize = 0; + sjp->Scrollable = false; + if ((rc = jdef->ParseURL(g, url, false)) == RC_OK) { + sjp->Url = url; + sjp->User = (char*)user; + sjp->Pwd = (char*)pwd; + ok = true; + } else if (rc == RC_NF) { + if (jdef->GetTabname()) + tab = jdef->GetTabname(); + + ok = jdef->SetParms(sjp); + } // endif rc + + } // endif's + + supfnc |= (FNC_DRIVER | FNC_TABLE); break; #endif // JDBC_SUPPORT - case TAB_MYSQL: - qrp = MyColumns(g, thd, host, db, user, pwd, tab, - NULL, port, fnc == FNC_COL); - break; + case TAB_DBF: + dbf = true; + // Passthru case TAB_CSV: - qrp = CSVColumns(g, dpath, topt, fnc == FNC_COL); + if (!fn && fnc != FNC_NO) + sprintf(g->Message, "Missing %s file name", topt->type); + else if (sep && strlen(sep) > 1) + sprintf(g->Message, "Invalid separator %s", sep); + else + ok = true; + + break; + case TAB_MYSQL: + ok = true; + + if (create_info->connect_string.str && + create_info->connect_string.length) { + PMYDEF mydef = new(g) MYSQLDEF(); + + dsn = strz(g, create_info->connect_string); + mydef->SetName(create_info->alias); + + if (!mydef->ParseURL(g, dsn, false)) { + if (mydef->GetHostname()) + host = mydef->GetHostname(); + + if (mydef->GetUsername()) + user = mydef->GetUsername(); + + if (mydef->GetPassword()) + pwd = mydef->GetPassword(); + + if (mydef->GetTabschema()) + db = mydef->GetTabschema(); + + if (mydef->GetTabname()) + tab = mydef->GetTabname(); + + if (mydef->GetPortnumber()) + port = mydef->GetPortnumber(); + + } else + ok = false; + + } else if (!user) + user = "root"; + + if (ok && CheckSelf(g, table_s, host, db, tab, src, port)) + ok = false; + break; #if defined(__WIN__) case TAB_WMI: - qrp = WMIColumns(g, nsp, cls, fnc == FNC_COL); + ok = true; break; #endif // __WIN__ +#if defined(PIVOT_SUPPORT) + case TAB_PIVOT: + supfnc = FNC_NO; +#endif // PIVOT_SUPPORT case TAB_PRX: case TAB_TBL: case TAB_XCL: case TAB_OCCUR: - bif = fnc == FNC_COL; - qrp = TabColumns(g, thd, db, tab, bif); - - if (!qrp && bif && fnc != FNC_COL) // tab is a view - qrp = MyColumns(g, thd, host, db, user, pwd, tab, NULL, port, false); - - if (qrp && ttp == TAB_OCCUR && fnc != FNC_COL) - if (OcrColumns(g, qrp, col, ocl, rnk)) { - rc = HA_ERR_INTERNAL_ERROR; - goto err; - } // endif OcrColumns + if (!src && !stricmp(tab, create_info->alias) && + (!db || !stricmp(db, table_s->db.str))) + sprintf(g->Message, "A %s table cannot refer to itself", topt->type); + else + ok = true; break; -#if defined(PIVOT_SUPPORT) - case TAB_PIVOT: - qrp = PivotColumns(g, tab, src, pic, fcl, skc, host, db, user, pwd, port); - break; -#endif // PIVOT_SUPPORT - case TAB_VIR: - qrp = VirColumns(g, fnc == FNC_COL); - break; - case TAB_JSON: - qrp = JSONColumns(g, (char*)db, topt, fnc == FNC_COL); + case TAB_OEM: + if (topt->module && topt->subtype) + ok = true; + else + strcpy(g->Message, "Missing OEM module or subtype"); + break; #if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT) case TAB_XML: - qrp = XMLColumns(g, (char*)db, tab, topt, fnc == FNC_COL); - break; #endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT - case TAB_OEM: - qrp = OEMColumns(g, topt, tab, (char*)db, fnc == FNC_COL); + case TAB_JSON: + dsn = strz(g, create_info->connect_string); + + if (!fn && !zfn && !mul && !dsn) + sprintf(g->Message, "Missing %s file name", topt->type); + else + ok = true; + + break; + case TAB_VIR: + ok = true; break; default: - strcpy(g->Message, "System error during assisted discovery"); + sprintf(g->Message, "Cannot get column info for table type %s", topt->type); break; - } // endswitch ttp + } // endif ttp - if (!qrp) { - rc = HA_ERR_INTERNAL_ERROR; - goto err; - } // endif !qrp + // Check for supported catalog function + if (ok && !(supfnc & fnc)) { + sprintf(g->Message, "Unsupported catalog function %s for table type %s", + fncn, topt->type); + ok = false; + } // endif supfnc - if (fnc != FNC_NO || src || ttp == TAB_PIVOT) { - // Catalog like table - for (crp = qrp->Colresp; !rc && crp; crp = crp->Next) { - cnm = (ttp == TAB_PIVOT) ? crp->Name : encode(g, crp->Name); - typ = crp->Type; - len = crp->Length; - dec = crp->Prec; - flg = crp->Flag; - v = (crp->Kdata->IsUnsigned()) ? 'U' : crp->Var; - tm = (crp->Kdata->IsNullable()) ? 0 : NOT_NULL_FLAG; + if (src && fnc != FNC_NO) { + strcpy(g->Message, "Cannot make catalog table from srcdef"); + ok = false; + } // endif src - if (!len && typ == TYPE_STRING) - len = 256; // STRBLK's have 0 length + if (ok) { + char *cnm, *rem, *dft, *xtra, *key, *fmt; + int i, len, prec, dec, typ, flg; - // Now add the field - if (add_field(&sql, cnm, typ, len, dec, NULL, tm, - NULL, NULL, NULL, NULL, flg, dbf, v)) - rc = HA_ERR_OUT_OF_MEM; - } // endfor crp + // if (cat) + // cat->SetDataPath(g, table_s->db.str); + // else + // return HA_ERR_INTERNAL_ERROR; // Should never happen - } else { - char *schem = NULL; - char *tn = NULL; + dpath = SetPath(g, table_s->db.str); - // Not a catalog table - if (!qrp->Nblin) { - if (tab) - sprintf(g->Message, "Cannot get columns from %s", tab); - else - strcpy(g->Message, "Fail to retrieve columns"); + if (src && ttp != TAB_PIVOT && ttp != TAB_ODBC && ttp != TAB_JDBC) { + qrp = SrcColumns(g, host, db, user, pwd, src, port); - rc = HA_ERR_INTERNAL_ERROR; - goto err; - } // endif !nblin - - for (i = 0; !rc && i < qrp->Nblin; i++) { - typ = len = prec = dec = 0; - tm = NOT_NULL_FLAG; - cnm = (char*)"noname"; - dft = xtra = key = fmt = tn = NULL; - v = ' '; - rem = NULL; - - for (crp = qrp->Colresp; crp; crp = crp->Next) - switch (crp->Fld) { - case FLD_NAME: - if (ttp == TAB_PRX || - (ttp == TAB_CSV && topt->data_charset && - (!stricmp(topt->data_charset, "UTF8") || - !stricmp(topt->data_charset, "UTF-8")))) - cnm = crp->Kdata->GetCharValue(i); - else - cnm = encode(g, crp->Kdata->GetCharValue(i)); - - break; - case FLD_TYPE: - typ = crp->Kdata->GetIntValue(i); - v = (crp->Nulls) ? crp->Nulls[i] : 0; - break; - case FLD_TYPENAME: - tn = crp->Kdata->GetCharValue(i); - break; - case FLD_PREC: - // PREC must be always before LENGTH - len = prec = crp->Kdata->GetIntValue(i); - break; - case FLD_LENGTH: - len = crp->Kdata->GetIntValue(i); - break; - case FLD_SCALE: - dec = (!crp->Kdata->IsNull(i)) ? crp->Kdata->GetIntValue(i) : -1; - break; - case FLD_NULL: - if (crp->Kdata->GetIntValue(i)) - tm = 0; // Nullable - - break; - case FLD_FORMAT: - fmt = (crp->Kdata) ? crp->Kdata->GetCharValue(i) : NULL; - break; - case FLD_REM: - rem = crp->Kdata->GetCharValue(i); - break; - // case FLD_CHARSET: - // No good because remote table is already translated - // if (*(csn= crp->Kdata->GetCharValue(i))) - // cs= get_charset_by_name(csn, 0); - - // break; - case FLD_DEFAULT: - dft = crp->Kdata->GetCharValue(i); - break; - case FLD_EXTRA: - xtra = crp->Kdata->GetCharValue(i); - - // Auto_increment is not supported yet - if (!stricmp(xtra, "AUTO_INCREMENT")) - xtra = NULL; - - break; - case FLD_KEY: - if (ttp == TAB_VIR) - key = crp->Kdata->GetCharValue(i); - - break; - case FLD_SCHEM: -#if defined(ODBC_SUPPORT) || defined(JDBC_SUPPORT) - if ((ttp == TAB_ODBC || ttp == TAB_JDBC) && crp->Kdata) { - if (schem && stricmp(schem, crp->Kdata->GetCharValue(i))) { - sprintf(g->Message, - "Several %s tables found, specify DBNAME", tab); - rc = HA_ERR_INTERNAL_ERROR; - goto err; - } else if (!schem) - schem = crp->Kdata->GetCharValue(i); - - } // endif ttp -#endif // ODBC_SUPPORT || JDBC_SUPPORT - default: - break; // Ignore - } // endswitch Fld + if (qrp && ttp == TAB_OCCUR) + if (OcrSrcCols(g, qrp, col, ocl, rnk)) { + rc = HA_ERR_INTERNAL_ERROR; + goto err; + } // endif OcrSrcCols + } else switch (ttp) { + case TAB_DBF: + qrp = DBFColumns(g, dpath, fn, fnc == FNC_COL); + break; #if defined(ODBC_SUPPORT) - if (ttp == TAB_ODBC) { - int plgtyp; - bool w = false; // Wide character type - - // typ must be PLG type, not SQL type - if (!(plgtyp = TranslateSQLType(typ, dec, prec, v, w))) { - if (GetTypeConv() == TPC_SKIP) { - // Skip this column - sprintf(g->Message, "Column %s skipped (unsupported type %d)", - cnm, typ); - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); - continue; - } else { - sprintf(g->Message, "Unsupported SQL type %d", typ); - rc = HA_ERR_INTERNAL_ERROR; - goto err; - } // endif type_conv - - } else - typ = plgtyp; - - switch (typ) { - case TYPE_STRING: - if (w) { - sprintf(g->Message, "Column %s is wide characters", cnm); - push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 0, g->Message); - } // endif w + case TAB_ODBC: + switch (fnc) { + case FNC_NO: + case FNC_COL: + if (src) { + qrp = ODBCSrcCols(g, dsn, (char*)src, sop); + src = NULL; // for next tests + } else + qrp = ODBCColumns(g, dsn, shm, tab, NULL, + mxr, fnc == FNC_COL, sop); break; - case TYPE_DOUBLE: - // Some data sources do not count dec in length (prec) - prec += (dec + 2); // To be safe + case FNC_TABLE: + qrp = ODBCTables(g, dsn, shm, tab, NULL, mxr, true, sop); break; - case TYPE_DECIM: - prec = len; + case FNC_DSN: + qrp = ODBCDataSources(g, mxr, true); + break; + case FNC_DRIVER: + qrp = ODBCDrivers(g, mxr, true); break; default: - dec = 0; - } // endswitch typ + sprintf(g->Message, "invalid catfunc %s", fncn); + break; + } // endswitch info - } else + break; #endif // ODBC_SUPPORT #if defined(JDBC_SUPPORT) - if (ttp == TAB_JDBC) { + case TAB_JDBC: + switch (fnc) { + case FNC_NO: + case FNC_COL: + if (src) { + qrp = JDBCSrcCols(g, (char*)src, sjp); + src = NULL; // for next tests + } else + qrp = JDBCColumns(g, shm, tab, NULL, mxr, fnc == FNC_COL, sjp); + + break; + case FNC_TABLE: + qrp = JDBCTables(g, shm, tab, tabtyp, mxr, true, sjp); + break; +#if 0 + case FNC_DSN: + qrp = JDBCDataSources(g, mxr, true); + break; +#endif // 0 + case FNC_DRIVER: + qrp = JDBCDrivers(g, mxr, true); + break; + default: + sprintf(g->Message, "invalid catfunc %s", fncn); + break; + } // endswitch info + + break; +#endif // JDBC_SUPPORT + case TAB_MYSQL: + qrp = MyColumns(g, thd, host, db, user, pwd, tab, + NULL, port, fnc == FNC_COL); + break; + case TAB_CSV: + qrp = CSVColumns(g, dpath, topt, fnc == FNC_COL); + break; +#if defined(__WIN__) + case TAB_WMI: + qrp = WMIColumns(g, nsp, cls, fnc == FNC_COL); + break; +#endif // __WIN__ + case TAB_PRX: + case TAB_TBL: + case TAB_XCL: + case TAB_OCCUR: + bif = fnc == FNC_COL; + qrp = TabColumns(g, thd, db, tab, bif); + + if (!qrp && bif && fnc != FNC_COL) // tab is a view + qrp = MyColumns(g, thd, host, db, user, pwd, tab, NULL, port, false); + + if (qrp && ttp == TAB_OCCUR && fnc != FNC_COL) + if (OcrColumns(g, qrp, col, ocl, rnk)) { + rc = HA_ERR_INTERNAL_ERROR; + goto err; + } // endif OcrColumns + + break; +#if defined(PIVOT_SUPPORT) + case TAB_PIVOT: + qrp = PivotColumns(g, tab, src, pic, fcl, skc, host, db, user, pwd, port); + break; +#endif // PIVOT_SUPPORT + case TAB_VIR: + qrp = VirColumns(g, fnc == FNC_COL); + break; + case TAB_JSON: + qrp = JSONColumns(g, (char*)db, dsn, topt, fnc == FNC_COL); + break; +#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT) + case TAB_XML: + qrp = XMLColumns(g, (char*)db, tab, topt, fnc == FNC_COL); + break; +#endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT + case TAB_OEM: + qrp = OEMColumns(g, topt, tab, (char*)db, fnc == FNC_COL); + break; + default: + strcpy(g->Message, "System error during assisted discovery"); + break; + } // endswitch ttp + + if (!qrp) { + rc = HA_ERR_INTERNAL_ERROR; + goto err; + } // endif !qrp + + if (fnc != FNC_NO || src || ttp == TAB_PIVOT) { + // Catalog like table + for (crp = qrp->Colresp; !rc && crp; crp = crp->Next) { + cnm = (ttp == TAB_PIVOT) ? crp->Name : encode(g, crp->Name); + typ = crp->Type; + len = crp->Length; + dec = crp->Prec; + flg = crp->Flag; + v = (crp->Kdata->IsUnsigned()) ? 'U' : crp->Var; + tm = (crp->Kdata->IsNullable()) ? 0 : NOT_NULL_FLAG; + + if (!len && typ == TYPE_STRING) + len = 256; // STRBLK's have 0 length + + // Now add the field + if (add_field(&sql, cnm, typ, len, dec, NULL, tm, + NULL, NULL, NULL, NULL, flg, dbf, v)) + rc = HA_ERR_OUT_OF_MEM; + } // endfor crp + + } else { + char *schem = NULL; + char *tn = NULL; + + // Not a catalog table + if (!qrp->Nblin) { + if (tab) + sprintf(g->Message, "Cannot get columns from %s", tab); + else + strcpy(g->Message, "Fail to retrieve columns"); + + rc = HA_ERR_INTERNAL_ERROR; + goto err; + } // endif !nblin + + for (i = 0; !rc && i < qrp->Nblin; i++) { + typ = len = prec = dec = 0; + tm = NOT_NULL_FLAG; + cnm = (char*)"noname"; + dft = xtra = key = fmt = tn = NULL; + v = ' '; + rem = NULL; + + for (crp = qrp->Colresp; crp; crp = crp->Next) + switch (crp->Fld) { + case FLD_NAME: + if (ttp == TAB_PRX || + (ttp == TAB_CSV && topt->data_charset && + (!stricmp(topt->data_charset, "UTF8") || + !stricmp(topt->data_charset, "UTF-8")))) + cnm = crp->Kdata->GetCharValue(i); + else + cnm = encode(g, crp->Kdata->GetCharValue(i)); + + break; + case FLD_TYPE: + typ = crp->Kdata->GetIntValue(i); + v = (crp->Nulls) ? crp->Nulls[i] : 0; + break; + case FLD_TYPENAME: + tn = crp->Kdata->GetCharValue(i); + break; + case FLD_PREC: + // PREC must be always before LENGTH + len = prec = crp->Kdata->GetIntValue(i); + break; + case FLD_LENGTH: + len = crp->Kdata->GetIntValue(i); + break; + case FLD_SCALE: + dec = (!crp->Kdata->IsNull(i)) ? crp->Kdata->GetIntValue(i) : -1; + break; + case FLD_NULL: + if (crp->Kdata->GetIntValue(i)) + tm = 0; // Nullable + + break; + case FLD_FORMAT: + fmt = (crp->Kdata) ? crp->Kdata->GetCharValue(i) : NULL; + break; + case FLD_REM: + rem = crp->Kdata->GetCharValue(i); + break; + // case FLD_CHARSET: + // No good because remote table is already translated + // if (*(csn= crp->Kdata->GetCharValue(i))) + // cs= get_charset_by_name(csn, 0); + + // break; + case FLD_DEFAULT: + dft = crp->Kdata->GetCharValue(i); + break; + case FLD_EXTRA: + xtra = crp->Kdata->GetCharValue(i); + + // Auto_increment is not supported yet + if (!stricmp(xtra, "AUTO_INCREMENT")) + xtra = NULL; + + break; + case FLD_KEY: + if (ttp == TAB_VIR) + key = crp->Kdata->GetCharValue(i); + + break; + case FLD_SCHEM: +#if defined(ODBC_SUPPORT) || defined(JDBC_SUPPORT) + if ((ttp == TAB_ODBC || ttp == TAB_JDBC) && crp->Kdata) { + if (schem && stricmp(schem, crp->Kdata->GetCharValue(i))) { + sprintf(g->Message, + "Several %s tables found, specify DBNAME", tab); + rc = HA_ERR_INTERNAL_ERROR; + goto err; + } else if (!schem) + schem = crp->Kdata->GetCharValue(i); + + } // endif ttp +#endif // ODBC_SUPPORT || JDBC_SUPPORT + default: + break; // Ignore + } // endswitch Fld + +#if defined(ODBC_SUPPORT) + if (ttp == TAB_ODBC) { int plgtyp; + bool w = false; // Wide character type // typ must be PLG type, not SQL type - if (!(plgtyp = TranslateJDBCType(typ, tn, dec, prec, v))) { + if (!(plgtyp = TranslateSQLType(typ, dec, prec, v, w))) { if (GetTypeConv() == TPC_SKIP) { // Skip this column sprintf(g->Message, "Column %s skipped (unsupported type %d)", @@ -5958,43 +5850,84 @@ static int connect_assisted_discovery(handlerton *, THD* thd, typ = plgtyp; switch (typ) { + case TYPE_STRING: + if (w) { + sprintf(g->Message, "Column %s is wide characters", cnm); + push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 0, g->Message); + } // endif w + + break; case TYPE_DOUBLE: - case TYPE_DECIM: // Some data sources do not count dec in length (prec) prec += (dec + 2); // To be safe break; + case TYPE_DECIM: + prec = len; + break; default: dec = 0; } // endswitch typ } else #endif // ODBC_SUPPORT - // Make the arguments as required by add_fields - if (typ == TYPE_DOUBLE) - prec = len; +#if defined(JDBC_SUPPORT) + if (ttp == TAB_JDBC) { + int plgtyp; - if (typ == TYPE_DATE) - prec = 0; + // typ must be PLG type, not SQL type + if (!(plgtyp = TranslateJDBCType(typ, tn, dec, prec, v))) { + if (GetTypeConv() == TPC_SKIP) { + // Skip this column + sprintf(g->Message, "Column %s skipped (unsupported type %d)", + cnm, typ); + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); + continue; + } else { + sprintf(g->Message, "Unsupported SQL type %d", typ); + rc = HA_ERR_INTERNAL_ERROR; + goto err; + } // endif type_conv - // Now add the field - if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra, - fmt, 0, dbf, v)) - rc = HA_ERR_OUT_OF_MEM; - } // endfor i + } else + typ = plgtyp; - } // endif fnc + switch (typ) { + case TYPE_DOUBLE: + case TYPE_DECIM: + // Some data sources do not count dec in length (prec) + prec += (dec + 2); // To be safe + break; + default: + dec = 0; + } // endswitch typ - if (!rc) - rc = init_table_share(thd, table_s, create_info, &sql); + } else +#endif // ODBC_SUPPORT + // Make the arguments as required by add_fields + if (typ == TYPE_DOUBLE) + prec = len; - //g->jump_level--; - //PopUser(xp); - //return rc; - } else { - rc = HA_ERR_UNSUPPORTED; - } // endif ok + if (typ == TYPE_DATE) + prec = 0; + + // Now add the field + if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra, + fmt, 0, dbf, v)) + rc = HA_ERR_OUT_OF_MEM; + } // endfor i + + } // endif fnc + + if (!rc) + rc = init_table_share(thd, table_s, create_info, &sql); + + //g->jump_level--; + //PopUser(xp); + //return rc; + } else { + rc = HA_ERR_UNSUPPORTED; + } // endif ok -#if defined(USE_TRY) } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); @@ -6005,16 +5938,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd, } // end catch err: -#else // !USE_TRY - err: - g->jump_level--; -#endif // !USE_TRY if (rc) my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); -#if !defined(USE_TRY) - jer: -#endif // !USE_TRY PopUser(xp); return rc; } // end of connect_assisted_discovery @@ -7133,10 +7059,10 @@ maria_declare_plugin(connect) PLUGIN_LICENSE_GPL, connect_init_func, /* Plugin Init */ connect_done_func, /* Plugin Deinit */ - 0x0105, /* version number (1.05) */ + 0x0106, /* version number (1.05) */ NULL, /* status variables */ connect_system_variables, /* system variables */ - "1.05.0003", /* string version */ - MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ + "1.06.0001", /* string version */ + MariaDB_PLUGIN_MATURITY_BETA /* maturity */ } maria_declare_plugin_end; diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index 02adff5d2c8..df63e7507ba 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -1200,11 +1200,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) if (rank == 0) if (!name || (jn = env->NewStringUTF(name)) == nullptr) { sprintf(g->Message, "Fail to allocate jstring %s", SVP(name)); -#if defined(USE_TRY) throw TYPE_AM_JDBC; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); -#endif // !USE_TRY } // endif name // Returns 666 is case of error @@ -1212,11 +1208,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) if (Check((ctyp == 666) ? -1 : 1)) { sprintf(g->Message, "Getting ctyp: %s", Msg); -#if defined(USE_TRY) throw TYPE_AM_JDBC; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); -#endif // !USE_TRY } // endif Check if (val->GetNullable()) @@ -1322,11 +1314,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) env->DeleteLocalRef(jn); sprintf(g->Message, "SetColumnValue: %s rank=%d ctyp=%d", Msg, rank, (int)ctyp); -#if defined(USE_TRY) throw TYPE_AM_JDBC; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); -#endif // !USE_TRY } // endif Check if (rank == 0) diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp index 6817439a635..9393e85eb6d 100644 --- a/storage/connect/json.cpp +++ b/storage/connect/json.cpp @@ -81,123 +81,70 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma) if (s[0] == '[' && (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n'))) pty[0] = false; - -#if defined(USE_TRY) - try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return NULL; - } // endif jump_level - -#if defined(SE_CATCH) - // Let's try to recover from any kind of interrupt - _se_translator_function f = _set_se_translator(trans_func); - try { -#endif // SE_CATCH --------------------- try section -------------------- - if (setjmp(g->jumper[++g->jump_level])) { - goto fin; - } // endif rc + for (i = 0; i < len; i++) + switch (s[i]) { + case '[': + if (jsp) + goto tryit; + else if (!(jsp = ParseArray(g, ++i, src, pty))) + throw 1; -#if defined(SE_CATCH) // ------------- end of try section ----------------- -} catch (SE_Exception e) { - sprintf(g->Message, "ParseJson: exception doing setjmp: %s (rc=%hd)", - GetExceptionDesc(g, e.nSE), e.nSE); - _set_se_translator(f); - goto err; -} catch (...) { - strcpy(g->Message, "Exception doing setjmp"); - _set_se_translator(f); - goto err; -} // end of try-catches + break; + case '{': + if (jsp) + goto tryit; + else if (!(jsp = ParseObject(g, ++i, src, pty))) + throw 2; -_set_se_translator(f); -#endif // SE_CATCH -#endif // !USE_TRY + break; + case ' ': + case '\t': + case '\n': + case '\r': + break; + case ',': + if (jsp && (pretty == 1 || pretty == 3)) { + if (comma) + *comma = true; - for (i = 0; i < len; i++) - switch (s[i]) { - case '[': - if (jsp) - goto tryit; - else if (!(jsp = ParseArray(g, ++i, src, pty))) -#if defined(USE_TRY) - throw 1; -#else // !USE_TRY - goto fin; -#endif // !USE_TRY + pty[0] = pty[2] = false; + break; + } // endif pretty - break; - case '{': - if (jsp) - goto tryit; - else if (!(jsp = ParseObject(g, ++i, src, pty))) -#if defined(USE_TRY) - throw 2; -#else // !USE_TRY - goto fin; -#endif // !USE_TRY + sprintf(g->Message, "Unexpected ',' (pretty=%d)", pretty); + throw 3; + case '(': + b = true; + break; + case ')': + if (b) { + b = false; + break; + } // endif b - break; - case ' ': - case '\t': - case '\n': - case '\r': - break; - case ',': - if (jsp && (pretty == 1 || pretty == 3)) { - if (comma) - *comma = true; + default: + if (jsp) + goto tryit; + else if (!(jsp = ParseValue(g, i, src, pty))) + throw 4; - pty[0] = pty[2] = false; - break; - } // endif pretty + break; + }; // endswitch s[i] - sprintf(g->Message, "Unexpected ',' (pretty=%d)", pretty); -#if defined(USE_TRY) - throw 3; -#else // !USE_TRY - jsp = NULL; - goto fin; -#endif // !USE_TRY - case '(': - b = true; - break; - case ')': - if (b) { - b = false; - break; - } // endif b + if (!jsp) + sprintf(g->Message, "Invalid Json string '%.*s'", 50, s); + else if (ptyp && pretty == 3) { + *ptyp = 3; // Not recognized pretty - default: - if (jsp) - goto tryit; - else if (!(jsp = ParseValue(g, i, src, pty))) -#if defined(USE_TRY) - throw 4; -#else // !USE_TRY - goto fin; -#endif // !USE_TRY + for (i = 0; i < 3; i++) + if (pty[i]) { + *ptyp = i; + break; + } // endif pty - break; - }; // endswitch s[i] + } // endif ptyp - if (!jsp) - sprintf(g->Message, "Invalid Json string '%.*s'", 50, s); - else if (ptyp && pretty == 3) { - *ptyp = 3; // Not recognized pretty - - for (i = 0; i < 3; i++) - if (pty[i]) { - *ptyp = i; - break; - } // endif pty - - } // endif ptyp - -#if defined(USE_TRY) } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); @@ -208,20 +155,12 @@ _set_se_translator(f); } // end catch return jsp; -#else // !USE_TRY -fin: - g->jump_level--; - return jsp; -#endif // !USE_TRY tryit: if (pty[0] && (!pretty || pretty > 2)) { if ((jsp = ParseArray(g, (i = 0), src, pty)) && ptyp && pretty == 3) *ptyp = (pty[0]) ? 0 : 3; -#if !defined(USE_TRY) - g->jump_level--; -#endif // !USE_TRY return jsp; } else strcpy(g->Message, "More than one item in file"); @@ -620,101 +559,75 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src) PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty) { PSZ str = NULL; - bool b = false, err = true; - JOUT *jp; + bool b = false, err = true; + JOUT *jp; FILE *fs = NULL; g->Message[0] = 0; -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return NULL; - } // endif jump_level - - if (setjmp(g->jumper[++g->jump_level])) { - str = NULL; - goto fin; - } // endif jmp -#endif // !USE_TRY - - if (!jsp) { - strcpy(g->Message, "Null json tree"); -#if defined(USE_TRY) - throw 1; -#else // !USE_TRY - goto fin; -#endif // !USE_TRY - } else if (!fn) { - // Serialize to a string - jp = new(g) JOUTSTR(g); - b = pretty == 1; - } else { - if (!(fs = fopen(fn, "wb"))) { - sprintf(g->Message, MSG(OPEN_MODE_ERROR), - "w", (int)errno, fn); - strcat(strcat(g->Message, ": "), strerror(errno)); -#if defined(USE_TRY) - throw 2; -#else // !USE_TRY - goto fin; -#endif // !USE_TRY - } else if (pretty >= 2) { - // Serialize to a pretty file - jp = new(g)JOUTPRT(g, fs); + if (!jsp) { + strcpy(g->Message, "Null json tree"); + throw 1; + } else if (!fn) { + // Serialize to a string + jp = new(g) JOUTSTR(g); + b = pretty == 1; } else { - // Serialize to a flat file - b = true; - jp = new(g)JOUTFILE(g, fs, pretty); + if (!(fs = fopen(fn, "wb"))) { + sprintf(g->Message, MSG(OPEN_MODE_ERROR), + "w", (int)errno, fn); + strcat(strcat(g->Message, ": "), strerror(errno)); + throw 2; + } else if (pretty >= 2) { + // Serialize to a pretty file + jp = new(g)JOUTPRT(g, fs); + } else { + // Serialize to a flat file + b = true; + jp = new(g)JOUTFILE(g, fs, pretty); + } // endif's + + } // endif's + + switch (jsp->GetType()) { + case TYPE_JAR: + err = SerializeArray(jp, (PJAR)jsp, b); + break; + case TYPE_JOB: + err = ((b && jp->Prty()) && jp->WriteChr('\t')); + err |= SerializeObject(jp, (PJOB)jsp); + break; + case TYPE_JVAL: + err = SerializeValue(jp, (PJVAL)jsp); + break; + default: + strcpy(g->Message, "Invalid json tree"); + } // endswitch Type + + if (fs) { + fputs(EL, fs); + fclose(fs); + str = (err) ? NULL : strcpy(g->Message, "Ok"); + } else if (!err) { + str = ((JOUTSTR*)jp)->Strp; + jp->WriteChr('\0'); + PlugSubAlloc(g, NULL, ((JOUTSTR*)jp)->N); + } else { + if (!g->Message[0]) + strcpy(g->Message, "Error in Serialize"); + } // endif's - } // endif's + } catch (int n) { + if (trace) + htrc("Exception %d: %s\n", n, g->Message); + str = NULL; + } catch (const char *msg) { + strcpy(g->Message, msg); + str = NULL; + } // end catch - switch (jsp->GetType()) { - case TYPE_JAR: - err = SerializeArray(jp, (PJAR)jsp, b); - break; - case TYPE_JOB: - err = ((b && jp->Prty()) && jp->WriteChr('\t')); - err |= SerializeObject(jp, (PJOB)jsp); - break; - case TYPE_JVAL: - err = SerializeValue(jp, (PJVAL)jsp); - break; - default: - strcpy(g->Message, "Invalid json tree"); - } // endswitch Type - - if (fs) { - fputs(EL, fs); - fclose(fs); - str = (err) ? NULL : strcpy(g->Message, "Ok"); - } else if (!err) { - str = ((JOUTSTR*)jp)->Strp; - jp->WriteChr('\0'); - PlugSubAlloc(g, NULL, ((JOUTSTR*)jp)->N); - } else { - if (!g->Message[0]) - strcpy(g->Message, "Error in Serialize"); - - } // endif's - -#if defined(USE_TRY) -} catch (int n) { - if (trace) - htrc("Exception %d: %s\n", n, g->Message); - str = NULL; -} catch (const char *msg) { - strcpy(g->Message, msg); - str = NULL; -} // end catch -#else // !USE_TRY -fin: - g->jump_level--; -#endif // !USE_TRY return str; } // end of Serialize diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 9ea391edae9..fa6abe29ec9 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -2921,70 +2921,53 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result, if (g->N) { str = (char*)g->Activityp; - goto fin; + goto err; } else if (initid->const_item) g->N = 1; -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - PUSH_WARNING(MSG(TOO_MANY_JUMPS)); - *is_null = 1; - return NULL; - } // endif jump_level - - if (setjmp(g->jumper[++g->jump_level])) { - PUSH_WARNING(g->Message); - str = NULL; - goto err; - } // endif rc -#endif // !USE_TRY - - if (!g->Xchk) { - if (CheckMemory(g, initid, args, 1, true)) { - PUSH_WARNING("CheckMemory error"); - goto err; - } else - jvp = MakeValue(g, args, 0); - - if ((p = jvp->GetString())) { - if (!(jsp = ParseJson(g, p, strlen(p)))) { - PUSH_WARNING(g->Message); + if (!g->Xchk) { + if (CheckMemory(g, initid, args, 1, true)) { + PUSH_WARNING("CheckMemory error"); goto err; - } // endif jsp + } else + jvp = MakeValue(g, args, 0); + + if ((p = jvp->GetString())) { + if (!(jsp = ParseJson(g, p, strlen(p)))) { + PUSH_WARNING(g->Message); + goto err; + } // endif jsp + + } else + jsp = jvp->GetJson(); + + if (g->Mrr) { // First argument is a constant + g->Xchk = jsp; + JsonMemSave(g); + } // endif Mrr } else - jsp = jvp->GetJson(); + jsp = (PJSON)g->Xchk; - if (g->Mrr) { // First argument is a constant - g->Xchk = jsp; - JsonMemSave(g); - } // endif Mrr + path = MakePSZ(g, args, 1); + jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length); - } else - jsp = (PJSON)g->Xchk; + if (jsx->SetJpath(g, path)) { + PUSH_WARNING(g->Message); + goto err; + } // endif SetJpath - path = MakePSZ(g, args, 1); - jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length); + jsx->ReadValue(g); - if (jsx->SetJpath(g, path)) { - PUSH_WARNING(g->Message); - goto err; - } // endif SetJpath + if (!jsx->GetValue()->IsNull()) + str = jsx->GetValue()->GetCharValue(); - jsx->ReadValue(g); + if (initid->const_item) + // Keep result of constant function + g->Activityp = (PACTIVITY)str; - if (!jsx->GetValue()->IsNull()) - str = jsx->GetValue()->GetCharValue(); - - if (initid->const_item) - // Keep result of constant function - g->Activityp = (PACTIVITY)str; - -#if defined(USE_TRY) - } catch (int n) { + } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); PUSH_WARNING(g->Message); @@ -2996,12 +2979,6 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result, } // end catch err: -#else // !USE_TRY - err: - g->jump_level--; -#endif // !USE_TRY - - fin: if (!str) { *is_null = 1; *res_length = 0; @@ -3292,64 +3269,45 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result, } else if (initid->const_item) g->N = 1; -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - PUSH_WARNING(MSG(TOO_MANY_JUMPS)); - *error = 1; - *is_null = 1; - return NULL; - } // endif jump_level - - if (setjmp(g->jumper[++g->jump_level])) { - PUSH_WARNING(g->Message); - *error = 1; - path = NULL; - goto err; - } // endif rc -#endif // !USE_TRY - - if (!g->Xchk) { - if (CheckMemory(g, initid, args, 1, !g->Xchk)) { - PUSH_WARNING("CheckMemory error"); - *error = 1; - goto err; - } else - jvp = MakeValue(g, args, 0); - - if ((p = jvp->GetString())) { - if (!(jsp = ParseJson(g, p, strlen(p)))) { - PUSH_WARNING(g->Message); + if (!g->Xchk) { + if (CheckMemory(g, initid, args, 1, !g->Xchk)) { + PUSH_WARNING("CheckMemory error"); + *error = 1; goto err; - } // endif jsp + } else + jvp = MakeValue(g, args, 0); + + if ((p = jvp->GetString())) { + if (!(jsp = ParseJson(g, p, strlen(p)))) { + PUSH_WARNING(g->Message); + goto err; + } // endif jsp + + } else + jsp = jvp->GetJson(); + + if (g->Mrr) { // First argument is a constant + g->Xchk = jsp; + JsonMemSave(g); + } // endif Mrr } else - jsp = jvp->GetJson(); + jsp = (PJSON)g->Xchk; - if (g->Mrr) { // First argument is a constant - g->Xchk = jsp; - JsonMemSave(g); - } // endif Mrr + // The item to locate + jvp2 = MakeValue(g, args, 1); - } else - jsp = (PJSON)g->Xchk; + k = (args->arg_count > 2) ? (int)*(long long*)args->args[2] : 1; - // The item to locate - jvp2 = MakeValue(g, args, 1); + jsx = new(g) JSNX(g, jsp, TYPE_STRING); + path = jsx->Locate(g, jsp, jvp2, k); - k = (args->arg_count > 2) ? (int)*(long long*)args->args[2] : 1; + if (initid->const_item) + // Keep result of constant function + g->Activityp = (PACTIVITY)path; - jsx = new(g) JSNX(g, jsp, TYPE_STRING); - path = jsx->Locate(g, jsp, jvp2, k); - - if (initid->const_item) - // Keep result of constant function - g->Activityp = (PACTIVITY)path; - -#if defined(USE_TRY) - } catch (int n) { + } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); PUSH_WARNING(g->Message); @@ -3363,11 +3321,6 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result, } // end catch err: -#else // !USE_TRY - err: - g->jump_level--; -#endif // !USE_TRY - if (!path) { *res_length = 0; *is_null = 1; @@ -3439,65 +3392,46 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result, } else if (initid->const_item) g->N = 1; -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - PUSH_WARNING(MSG(TOO_MANY_JUMPS)); - *error = 1; - *is_null = 1; - return NULL; - } // endif jump_level - - if (setjmp(g->jumper[++g->jump_level])) { - PUSH_WARNING(g->Message); - *error = 1; - path = NULL; - goto err; - } // endif rc -#endif // !USE_TRY - - if (!g->Xchk) { - if (CheckMemory(g, initid, args, 1, true)) { - PUSH_WARNING("CheckMemory error"); - *error = 1; - goto err; - } else - jvp = MakeValue(g, args, 0); - - if ((p = jvp->GetString())) { - if (!(jsp = ParseJson(g, p, strlen(p)))) { - PUSH_WARNING(g->Message); + if (!g->Xchk) { + if (CheckMemory(g, initid, args, 1, true)) { + PUSH_WARNING("CheckMemory error"); + *error = 1; goto err; - } // endif jsp + } else + jvp = MakeValue(g, args, 0); + + if ((p = jvp->GetString())) { + if (!(jsp = ParseJson(g, p, strlen(p)))) { + PUSH_WARNING(g->Message); + goto err; + } // endif jsp + + } else + jsp = jvp->GetJson(); + + if (g->Mrr) { // First argument is a constant + g->Xchk = jsp; + JsonMemSave(g); + } // endif Mrr } else - jsp = jvp->GetJson(); + jsp = (PJSON)g->Xchk; - if (g->Mrr) { // First argument is a constant - g->Xchk = jsp; - JsonMemSave(g); - } // endif Mrr + // The item to locate + jvp2 = MakeValue(g, args, 1); - } else - jsp = (PJSON)g->Xchk; + if (args->arg_count > 2) + mx = (int)*(long long*)args->args[2]; - // The item to locate - jvp2 = MakeValue(g, args, 1); + jsx = new(g) JSNX(g, jsp, TYPE_STRING); + path = jsx->LocateAll(g, jsp, jvp2, mx); - if (args->arg_count > 2) - mx = (int)*(long long*)args->args[2]; + if (initid->const_item) + // Keep result of constant function + g->Activityp = (PACTIVITY)path; - jsx = new(g) JSNX(g, jsp, TYPE_STRING); - path = jsx->LocateAll(g, jsp, jvp2, mx); - - if (initid->const_item) - // Keep result of constant function - g->Activityp = (PACTIVITY)path; - -#if defined(USE_TRY) - } catch (int n) { + } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); PUSH_WARNING(g->Message); @@ -3511,11 +3445,6 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result, } // end catch err: -#else // !USE_TRY - err: - g->jump_level--; -#endif // !USE_TRY - if (!path) { *res_length = 0; *is_null = 1; @@ -3722,87 +3651,61 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, goto fin; } // endelse -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - PUSH_WARNING(MSG(TOO_MANY_JUMPS)); - *error = 1; - goto fin; - } // endif jump_level + if (!g->Xchk) { + if (CheckMemory(g, initid, args, 1, true, false, true)) { + PUSH_WARNING("CheckMemory error"); + throw 1; + } else + jvp = MakeValue(g, args, 0); - if (setjmp(g->jumper[++g->jump_level])) { - PUSH_WARNING(g->Message); - str = NULL; - goto err; - } // endif rc -#endif // !USE_TRY + if ((p = jvp->GetString())) { + if (!(jsp = ParseJson(g, p, strlen(p)))) { + throw 2; + } // endif jsp + + } else + jsp = jvp->GetJson(); + + if (g->Mrr) { // First argument is a constant + g->Xchk = jsp; + JsonMemSave(g); + } // endif Mrr - if (!g->Xchk) { - if (CheckMemory(g, initid, args, 1, true, false, true)) { - PUSH_WARNING("CheckMemory error"); -#if defined(USE_TRY) - throw 1; -#else // !USE_TRY - goto err; -#endif // !USE_TRY } else - jvp = MakeValue(g, args, 0); + jsp = (PJSON)g->Xchk; - if ((p = jvp->GetString())) { - if (!(jsp = ParseJson(g, p, strlen(p)))) { -#if defined(USE_TRY) - throw 2; -#else // !USE_TRY + jsx = new(g)JSNX(g, jsp, TYPE_STRING, initid->max_length, 0, true); + + for (uint i = 1; i + 1 < args->arg_count; i += 2) { + jvp = MakeValue(gb, args, i); + path = MakePSZ(g, args, i + 1); + + if (jsx->SetJpath(g, path, false)) { PUSH_WARNING(g->Message); - goto err; -#endif // !USE_TRY - } // endif jsp + continue; + } // endif SetJpath - } else - jsp = jvp->GetJson(); + if (w) { + jsx->ReadValue(g); + b = jsx->GetValue()->IsNull(); + b = (w == 1) ? b : !b; + } // endif w - if (g->Mrr) { // First argument is a constant - g->Xchk = jsp; - JsonMemSave(g); - } // endif Mrr + if (b && jsx->WriteValue(gb, jvp)) + PUSH_WARNING(g->Message); - } else - jsp = (PJSON)g->Xchk; + } // endfor i - jsx = new(g)JSNX(g, jsp, TYPE_STRING, initid->max_length, 0, true); + // In case of error or file, return unchanged argument + if (!(str = MakeResult(g, args, jsp, INT_MAX32))) + str = MakePSZ(g, args, 0); - for (uint i = 1; i+1 < args->arg_count; i += 2) { - jvp = MakeValue(gb, args, i); - path = MakePSZ(g, args, i+1); + if (g->N) + // Keep result of constant function + g->Activityp = (PACTIVITY)str; - if (jsx->SetJpath(g, path, false)) { - PUSH_WARNING(g->Message); - continue; - } // endif SetJpath - - if (w) { - jsx->ReadValue(g); - b = jsx->GetValue()->IsNull(); - b = (w == 1) ? b : !b; - } // endif w - - if (b && jsx->WriteValue(gb, jvp)) - PUSH_WARNING(g->Message); - - } // endfor i - - // In case of error or file, return unchanged argument - if (!(str = MakeResult(g, args, jsp, INT_MAX32))) - str = MakePSZ(g, args, 0); - - if (g->N) - // Keep result of constant function - g->Activityp = (PACTIVITY)str; - -#if defined(USE_TRY) - } catch (int n) { + } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); PUSH_WARNING(g->Message); @@ -3812,10 +3715,6 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, PUSH_WARNING(g->Message); str = NULL; } // end catch -#else // !USE_TRY -err: - g->jump_level--; -#endif // !USE_TRY fin: if (!str) { diff --git a/storage/connect/mongofam.cpp b/storage/connect/mongofam.cpp new file mode 100644 index 00000000000..c1c78db6550 --- /dev/null +++ b/storage/connect/mongofam.cpp @@ -0,0 +1,609 @@ +/************ MONGO FAM C++ Program Source Code File (.CPP) ************/ +/* PROGRAM NAME: mongofam.cpp */ +/* ------------- */ +/* Version 1.0 */ +/* */ +/* COPYRIGHT: */ +/* ---------- */ +/* (C) Copyright to the author Olivier BERTRAND 20017 */ +/* */ +/* WHAT THIS PROGRAM DOES: */ +/* ----------------------- */ +/* This program are the MongoDB access method classes. */ +/* */ +/***********************************************************************/ + +/***********************************************************************/ +/* Include relevant sections of the System header files. */ +/***********************************************************************/ +#include "my_global.h" +#if defined(__WIN__) +//#include +//#include +//#include +#if defined(__BORLANDC__) +#define __MFC_COMPAT__ // To define min/max as macro +#endif // __BORLANDC__ +//#include +#else // !__WIN__ +#if defined(UNIX) || defined(UNIV_LINUX) +//#include +#include +//#if !defined(sun) // Sun has the ftruncate fnc. +//#define USETEMP // Force copy mode for DELETE +//#endif // !sun +#else // !UNIX +//#include +#endif // !UNIX +//#include +#endif // !__WIN__ + +/***********************************************************************/ +/* Include application header files: */ +/* global.h is header containing all global declarations. */ +/* plgdbsem.h is header containing the DB application declarations. */ +/* filamtxt.h is header containing the file AM classes declarations. */ +/***********************************************************************/ +#include "global.h" +#include "plgdbsem.h" +#include "reldef.h" +#include "filamtxt.h" +#include "tabdos.h" +#include "tabjson.h" +#include "mongofam.h" + +#if defined(UNIX) || defined(UNIV_LINUX) +#include "osutil.h" +//#define _fileno fileno +//#define _O_RDONLY O_RDONLY +#endif + +//PGLOBAL MGOFAM::G = NULL; + +// Required to initialize libmongoc's internals +void mongo_init(bool init) +{ + if (init) { + //bson_mem_vtable_t vtable; + + //vtable.malloc = MGOFAM::mgo_alloc; + //vtable.calloc = MGOFAM::mgo_calloc; + //vtable.realloc = MGOFAM::mgo_realloc; + //vtable.free = MGOFAM::mgo_free; + mongoc_init(); + //bson_mem_set_vtable(&vtable); + } else { + //bson_mem_restore_vtable(); + mongoc_cleanup(); + } // endif init + +} // end of mongo_init + +/* --------------------------- Class MGOFAM -------------------------- */ + +/***********************************************************************/ +/* Constructors. */ +/***********************************************************************/ +MGOFAM::MGOFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL) +{ + Client = NULL; + Database = NULL; + Collection = NULL; + Cursor = NULL; + Query = NULL; + Opts = NULL; + To_Fbt = NULL; + Mode = MODE_ANY; + uristr = tdp->Uri; + db_name = tdp->Schema; + coll_name = tdp->Collname; + options = tdp->Options; + filter = NULL; + Done = false; + Lrecl = tdp->Lrecl + tdp->Ending; +} // end of MGOFAM standard constructor + + MGOFAM::MGOFAM(PMGOFAM tdfp) : DOSFAM(tdfp) +{ +//G = tdfp->G; + Client = tdfp->Client; + Database = NULL; + Collection = tdfp->Collection; + Cursor = tdfp->Cursor; + Query = tdfp->Query; + Opts = tdfp->Opts; + To_Fbt = tdfp->To_Fbt; + Mode = tdfp->Mode; + Done = tdfp->Done; +} // end of MGOFAM copy constructor + +#if 0 +void *MGOFAM::mgo_alloc(size_t n) +{ + char *mst = (char*)PlgDBSubAlloc(G, NULL, n + sizeof(size_t)); + + if (mst) { + *(size_t*)mst = n; + return mst + sizeof(size_t); + } // endif mst + + return NULL; +} // end of mgo_alloc + +void *MGOFAM::mgo_calloc(size_t n, size_t sz) +{ + void *m = mgo_alloc(n * sz); + + if (m) + memset(m, 0, n * sz); + + return m; +} // end of mgo_calloc + +void *MGOFAM::mgo_realloc(void *m, size_t n) +{ + if (!m) + return n ? mgo_alloc(n) : NULL; + + size_t *osz = (size_t*)((char*)m - sizeof(size_t)); + + if (n > *osz) { + void *nwm = mgo_alloc(n); + + if (nwm) + memcpy(nwm, m, *osz); + + return nwm; + } else { + *osz = n; + return m; + } // endif n + +} // end of mgo_realloc +#endif // 0 + +/***********************************************************************/ +/* Reset: reset position values at the beginning of file. */ +/***********************************************************************/ +void MGOFAM::Reset(void) +{ + TXTFAM::Reset(); + Fpos = Tpos = Spos = 0; +} // end of Reset + +/***********************************************************************/ +/* MGO GetFileLength: returns file size in number of bytes. */ +/***********************************************************************/ +int MGOFAM::GetFileLength(PGLOBAL g) +{ + return 0; +} // end of GetFileLength + +/***********************************************************************/ +/* Cardinality: returns table cardinality in number of rows. */ +/* This function can be called with a null argument to test the */ +/* availability of Cardinality implementation (1 yes, 0 no). */ +/***********************************************************************/ +int MGOFAM::Cardinality(PGLOBAL g) +{ + if (g) { + if (!Init(g)) { + int64_t card = mongoc_collection_count(Collection, + MONGOC_QUERY_NONE, Query, 0, 0, NULL, &Error); + + if (card < 0) + sprintf(g->Message, "Cardinality: %s", Error.message); + + return (int)card; + } else + return -1; + + } else + return 1; + +} // end of Cardinality + +/***********************************************************************/ +/* Use BlockTest to reduce the table estimated size. */ +/* Note: This function is not really implemented yet. */ +/***********************************************************************/ +int MGOFAM::MaxBlkSize(PGLOBAL, int s) +{ + return s; +} // end of MaxBlkSize + +/***********************************************************************/ +/* Init: initialize MongoDB processing. */ +/***********************************************************************/ +bool MGOFAM::Init(PGLOBAL g) +{ + if (Done) + return false; + + if (options) { + char *p = (char*)strchr(options, ';'); + + if (p) { + *p++ = 0; + filter = p; + } // endif p + + } // endif opts + + if (filter && *filter) { + if (trace) + htrc("filter=%s\n", filter); + + Query = bson_new_from_json((const uint8_t *)filter, -1, &Error); + + if (!Query) { + sprintf(g->Message, "Wrong filter: %s", Error.message); + return true; + } // endif Query + + } else + Query = bson_new(); + + if (options && *options) { + if (trace) + htrc("options=%s\n", options); + + Opts = bson_new_from_json((const uint8_t *)options, -1, &Error); + + if (!Opts) { + sprintf(g->Message, "Wrong options: %s", Error.message); + return true; + } // endif Opts + + } // endif options + + Uri = mongoc_uri_new(uristr); + + if (!Uri) { + sprintf(g->Message, "Failed to parse URI: \"%s\"", uristr); + return true; + } // endif Uri + + // Create a new client pool instance + Pool = mongoc_client_pool_new(Uri); + mongoc_client_pool_set_error_api(Pool, 2); + + // Register the application name so we can track it in the profile logs + // on the server. This can also be done from the URI. + mongoc_client_pool_set_appname(Pool, "Connect"); + + // Create a new client instance + Client = mongoc_client_pool_pop(Pool); + //Client = mongoc_client_new(uristr); + + if (!Client) { + sprintf(g->Message, "Failed to get Client"); + return true; + } // endif Client + +//mongoc_client_set_error_api(Client, 2); + +// Register the application name so we can track it in the profile logs +// on the server. This can also be done from the URI. +//mongoc_client_set_appname(Client, "Connect"); + +// Get a handle on the database db_name and collection coll_name +// Database = mongoc_client_get_database(Client, db_name); +// Collection = mongoc_database_get_collection(Database, coll_name); + Collection = mongoc_client_get_collection(Client, db_name, coll_name); + + if (!Collection /*&& Mode != MODE_INSERT*/) { + sprintf(g->Message, "Failed to get Collection %s.%s", db_name, coll_name); + return true; + } // endif Collection + + Done = true; + return false; +} // end of Init + +/***********************************************************************/ +/* OpenTableFile: Open a MongoDB table. */ +/***********************************************************************/ +bool MGOFAM::OpenTableFile(PGLOBAL g) +{ + //if (!G) { + // G = g; + // Vtable.malloc = mgo_alloc; + // Vtable.calloc = mgo_calloc; + // Vtable.realloc = mgo_realloc; + // Vtable.free = mgo_free; + // bson_mem_set_vtable(&Vtable); + //} else { + // strcpy(g->Message, "G is not usable"); + // return true; + //} // endif G + Mode = Tdbp->GetMode(); + + if (Init(g)) + return true; + + if (Mode == MODE_DELETE && !Tdbp->GetNext()) { + // Store the number of deleted lines + DelRows = Cardinality(g); + + // Delete all documents + if (!mongoc_collection_remove(Collection, MONGOC_REMOVE_NONE, + Query, NULL, &Error)) { + sprintf(g->Message, "Remove all: %s", Error.message); + return true; + } // endif remove + + } else if (Mode != MODE_INSERT) + Cursor = mongoc_collection_find_with_opts(Collection, Query, Opts, NULL); + + return false; +} // end of OpenTableFile + +/***********************************************************************/ +/* GetRowID: return the RowID of last read record. */ +/***********************************************************************/ +int MGOFAM::GetRowID(void) +{ + return Rows; +} // end of GetRowID + +/***********************************************************************/ +/* GetPos: return the position of last read record. */ +/***********************************************************************/ +int MGOFAM::GetPos(void) +{ + return Fpos; +} // end of GetPos + +/***********************************************************************/ +/* GetNextPos: return the position of next record. */ +/***********************************************************************/ +int MGOFAM::GetNextPos(void) +{ + return Fpos; // TODO +} // end of GetNextPos + +/***********************************************************************/ +/* SetPos: Replace the table at the specified position. */ +/***********************************************************************/ +bool MGOFAM::SetPos(PGLOBAL g, int pos) +{ + Fpos = pos; + Placed = true; + return false; +} // end of SetPos + +/***********************************************************************/ +/* Record file position in case of UPDATE or DELETE. */ +/***********************************************************************/ +bool MGOFAM::RecordPos(PGLOBAL g) +{ + strcpy(g->Message, "MGOFAM::RecordPos NIY"); + return true; +} // end of RecordPos + +/***********************************************************************/ +/* Initialize Fpos and the current position for indexed DELETE. */ +/***********************************************************************/ +int MGOFAM::InitDelete(PGLOBAL g, int fpos, int spos) +{ + strcpy(g->Message, "MGOFAM::InitDelete NIY"); + return RC_FX; +} // end of InitDelete + +/***********************************************************************/ +/* Skip one record in file. */ +/***********************************************************************/ +int MGOFAM::SkipRecord(PGLOBAL g, bool header) +{ + return RC_OK; // Dummy +} // end of SkipRecord + +/***********************************************************************/ +/* Use to trace restaurants document contains. */ +/***********************************************************************/ +void MGOFAM::ShowDocument(bson_iter_t *iter, const bson_t *doc, const char *k) +{ + + if (!doc || bson_iter_init(iter, doc)) { + const char *key; + + while (bson_iter_next(iter)) { + key = bson_iter_key(iter); + htrc("Found element key: \"%s\"\n", key); + + if (BSON_ITER_HOLDS_UTF8(iter)) + htrc("%s.%s=\"%s\"\n", k, key, bson_iter_utf8(iter, NULL)); + else if (BSON_ITER_HOLDS_INT32(iter)) + htrc("%s.%s=%d\n", k, key, bson_iter_int32(iter)); + else if (BSON_ITER_HOLDS_INT64(iter)) + htrc("%s.%s=%lld\n", k, key, bson_iter_int64(iter)); + else if (BSON_ITER_HOLDS_DOUBLE(iter)) + htrc("%s.%s=%g\n", k, key, bson_iter_double(iter)); + else if (BSON_ITER_HOLDS_DATE_TIME(iter)) + htrc("%s.%s=date(%lld)\n", k, key, bson_iter_date_time(iter)); + else if (BSON_ITER_HOLDS_OID(iter)) { + char str[25]; + + bson_oid_to_string(bson_iter_oid(iter), str); + htrc("%s.%s=%s\n", k, key, str); + } else if (BSON_ITER_HOLDS_DECIMAL128(iter)) { + char *str = NULL; + bson_decimal128_t dec; + + bson_iter_decimal128(iter, &dec); + bson_decimal128_to_string(&dec, str); + htrc("%s.%s=%s\n", k, key, str); + } else if (BSON_ITER_HOLDS_DOCUMENT(iter)) { + bson_iter_t child; + + if (bson_iter_recurse(iter, &child)) + ShowDocument(&child, NULL, key); + + } else if (BSON_ITER_HOLDS_ARRAY(iter)) { + bson_t *arr; + bson_iter_t itar; + const uint8_t *data = NULL; + uint32_t len = 0; + + bson_iter_array(iter, &len, &data); + arr = bson_new_from_data(data, len); + ShowDocument(&itar, arr, key); + } // endif's + + } // endwhile bson_iter_next + + } // endif bson_iter_init + +} // end of ShowDocument + +/***********************************************************************/ +/* ReadBuffer: Get next document from a collection. */ +/***********************************************************************/ +int MGOFAM::ReadBuffer(PGLOBAL g) +{ + int rc = RC_OK; + + if (mongoc_cursor_next(Cursor, &Document)) { + char *str = bson_as_json(Document, NULL); + + if (trace > 1) { + bson_iter_t iter; + ShowDocument(&iter, Document, ""); + } else if (trace == 1) + htrc("%s\n", str); + + strncpy(Tdbp->GetLine(), str, Lrecl); + bson_free(str); + } else if (mongoc_cursor_error(Cursor, &Error)) { + sprintf(g->Message, "Mongo Cursor Failure: %s", Error.message); + rc = RC_FX; + } else { + //mongoc_cursor_destroy(Cursor); + rc = RC_EF; + } // endif's Cursor + + return rc; +} // end of ReadBuffer + +/***********************************************************************/ +/* WriteBuffer: File write routine for MGO access method. */ +/***********************************************************************/ +int MGOFAM::WriteBuffer(PGLOBAL g) +{ + int rc = RC_OK; + bson_t *doc; + + //if (Mode == MODE_INSERT && !Collection) { + // if ((Database = mongoc_client_get_database(Client, db_name))) + // Collection = mongoc_database_create_collection(Database, coll_name, + // NULL, &Error); + + // if (!Collection) + // if (Database) { + // sprintf(g->Message, "Create collection: %s", Error.message); + // return RC_FX; + // } else { + // sprintf(g->Message, "Fail to get database %s", db_name); + // return RC_FX; + // } // endif Database + + //} // endif Collection + + if (!(doc = bson_new_from_json((const uint8_t *)Tdbp->GetLine(), + -1, &Error))) { + sprintf(g->Message, "Wrong document: %s", Error.message); + return RC_FX; + } // endif doc + + if (Mode != MODE_INSERT) { + bool b = false; + bson_iter_t iter; + bson_t *selector = bson_new(); + + bson_iter_init(&iter, Document); + + if (bson_iter_find(&iter, "_id")) { + if (BSON_ITER_HOLDS_OID(&iter)) + b = BSON_APPEND_OID(selector, "_id", bson_iter_oid(&iter)); + else if (BSON_ITER_HOLDS_INT32(&iter)) + b = BSON_APPEND_INT32(selector, "_id", bson_iter_int32(&iter)); + else if (BSON_ITER_HOLDS_INT64(&iter)) + b = BSON_APPEND_INT64(selector, "_id", bson_iter_int64(&iter)); + else if (BSON_ITER_HOLDS_DOUBLE(&iter)) + b = BSON_APPEND_DOUBLE(selector, "_id", bson_iter_double(&iter)); + else if (BSON_ITER_HOLDS_UTF8(&iter)) + b = BSON_APPEND_UTF8(selector, "_id", bson_iter_utf8(&iter, NULL)); + + } // endif iter + + if (!b) { + strcpy(g->Message, "Cannot find _id"); + return RC_FX; + } // endif oid + + if (Mode == MODE_DELETE) { + if (!mongoc_collection_remove(Collection, MONGOC_REMOVE_NONE, + selector, NULL, &Error)) { + sprintf(g->Message, "Remove: %s", Error.message); + bson_destroy(selector); + return RC_FX; + } // endif remove + + } else { + if (!mongoc_collection_update(Collection, MONGOC_UPDATE_NONE, + selector, doc, NULL, &Error)) { + sprintf(g->Message, "Update: %s", Error.message); + bson_destroy(selector); + return RC_FX; + } // endif remove + + } // endif Mode + + bson_destroy(selector); + } else if (!mongoc_collection_insert(Collection, MONGOC_INSERT_NONE, + doc, NULL, &Error)) { + sprintf(g->Message, "Inserting: %s", Error.message); + rc = RC_FX; + } // endif insert + + bson_destroy(doc); + return rc; +} // end of WriteBuffer + +/***********************************************************************/ +/* Data Base delete line routine for MGO and BLK access methods. */ +/***********************************************************************/ +int MGOFAM::DeleteRecords(PGLOBAL g, int irc) +{ + return (irc == RC_OK) ? WriteBuffer(g) : RC_OK; +} // end of DeleteRecords + +/***********************************************************************/ +/* Table file close routine for MGO access method. */ +/***********************************************************************/ +void MGOFAM::CloseTableFile(PGLOBAL g, bool) +{ + if (Query) bson_destroy(Query); + if (Opts) bson_destroy(Opts); + if (Cursor) mongoc_cursor_destroy(Cursor); + if (Collection) mongoc_collection_destroy(Collection); + // mongoc_database_destroy(Database); + // mongoc_client_destroy(Client); + if (Client) mongoc_client_pool_push(Pool, Client); + if (Pool) mongoc_client_pool_destroy(Pool); + if (Uri) mongoc_uri_destroy(Uri); +//bson_mem_restore_vtable(); +//mongoc_cleanup(); +//G = NULL; + Done = false; +} // end of CloseTableFile + +/***********************************************************************/ +/* Rewind routine for MGO access method. */ +/***********************************************************************/ +void MGOFAM::Rewind(void) +{ + // TODO implement me +} // end of Rewind + diff --git a/storage/connect/mongofam.h b/storage/connect/mongofam.h new file mode 100644 index 00000000000..efe26043e2b --- /dev/null +++ b/storage/connect/mongofam.h @@ -0,0 +1,95 @@ +/************** MongoFam H Declares Source Code File (.H) **************/ +/* Name: mongofam.h Version 1.3 */ +/* */ +/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* */ +/* This file contains the MongoDB access method classes declares. */ +/***********************************************************************/ +#pragma once + +/***********************************************************************/ +/* Include MongoDB library header files. */ +/***********************************************************************/ +#include +#include +#include + +#include "block.h" +//#include "array.h" + +typedef class TXTFAM *PTXF; +typedef class MGOFAM *PMGOFAM; +typedef class MGODEF *PMGODEF; +typedef class TDBMGO *PTDBMGO; + +/***********************************************************************/ +/* This is the MongoDB Access Method class declaration. */ +/***********************************************************************/ +class DllExport MGOFAM : public DOSFAM { + friend void mongo_init(bool); +public: + // Constructor + MGOFAM(PJDEF tdp); + MGOFAM(PMGOFAM txfp); + + // Implementation + virtual AMT GetAmType(void) { return TYPE_AM_MGO; } + virtual bool GetUseTemp(void) { return false; } + virtual int GetPos(void); + virtual int GetNextPos(void); + virtual PTXF Duplicate(PGLOBAL g) { return (PTXF)new(g) MGOFAM(this); } + void SetLrecl(int lrecl) { Lrecl = lrecl; } + + // Methods + virtual void Reset(void); + virtual int GetFileLength(PGLOBAL g); + virtual int Cardinality(PGLOBAL g); + virtual int MaxBlkSize(PGLOBAL g, int s); + virtual bool AllocateBuffer(PGLOBAL g) { return false; } + virtual int GetRowID(void); + virtual bool RecordPos(PGLOBAL g); + virtual bool SetPos(PGLOBAL g, int recpos); + virtual int SkipRecord(PGLOBAL g, bool header); + virtual bool OpenTableFile(PGLOBAL g); + virtual int ReadBuffer(PGLOBAL g); + virtual int WriteBuffer(PGLOBAL g); + virtual int DeleteRecords(PGLOBAL g, int irc); + virtual void CloseTableFile(PGLOBAL g, bool abort); + virtual void Rewind(void); + +protected: + virtual bool OpenTempFile(PGLOBAL g) { return false; } + virtual bool MoveIntermediateLines(PGLOBAL g, bool *b) { return false; } + virtual int RenameTempFile(PGLOBAL g) { return RC_OK; } + virtual int InitDelete(PGLOBAL g, int fpos, int spos); + bool Init(PGLOBAL g); + void ShowDocument(bson_iter_t *i, const bson_t *b, const char *k); + //static void *mgo_alloc(size_t n); + //static void *mgo_calloc(size_t n, size_t sz); + //static void *mgo_realloc(void *m, size_t n); + //static void mgo_free(void *) {} + + + // Members +//static PGLOBAL G; + mongoc_uri_t *Uri; + mongoc_client_pool_t *Pool; // Thread safe client pool + mongoc_client_t *Client; // The MongoDB client + mongoc_database_t *Database; // The MongoDB database + mongoc_collection_t *Collection; // The MongoDB collection + mongoc_cursor_t *Cursor; + const bson_t *Document; +//bson_mem_vtable_t Vtable; + bson_t *Query; // MongoDB cursor filter + bson_t *Opts; // MongoDB cursor options + bson_error_t Error; + PFBLOCK To_Fbt; // Pointer to temp file block + MODE Mode; + const char *uristr; + const char *db_name; + const char *coll_name; + const char *options; + const char *filter; + bool Done; // Init done +}; // end of class MGOFAM + diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index cf55846765f..8da92a25962 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -239,62 +239,43 @@ char *ODBCCheckConnection(PGLOBAL g, char *dsn, int cop) /***********************************************************************/ /* Allocate the structure used to refer to the result set. */ /***********************************************************************/ -static CATPARM *AllocCatInfo(PGLOBAL g, CATINFO fid, char *db, - char *tab, PQRYRES qrp) - { - size_t i, m, n; - CATPARM *cap; +static CATPARM *AllocCatInfo(PGLOBAL g, CATINFO fid, char *db, + char *tab, PQRYRES qrp) +{ + size_t i, m, n; + CATPARM *cap; #if defined(_DEBUG) - assert(qrp); + assert(qrp); #endif -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return NULL; - } // endif jump_level + m = (size_t)qrp->Maxres; + n = (size_t)qrp->Nbcol; + cap = (CATPARM *)PlugSubAlloc(g, NULL, sizeof(CATPARM)); + memset(cap, 0, sizeof(CATPARM)); + cap->Id = fid; + cap->Qrp = qrp; + cap->DB = (PUCHAR)db; + cap->Tab = (PUCHAR)tab; + cap->Vlen = (SQLLEN* *)PlugSubAlloc(g, NULL, n * sizeof(SQLLEN *)); - if (setjmp(g->jumper[++g->jump_level]) != 0) { + for (i = 0; i < n; i++) + cap->Vlen[i] = (SQLLEN *)PlugSubAlloc(g, NULL, m * sizeof(SQLLEN)); + + cap->Status = (UWORD *)PlugSubAlloc(g, NULL, m * sizeof(UWORD)); + + } catch (int n) { + htrc("Exeption %d: %s\n", n, g->Message); + cap = NULL; + } catch (const char *msg) { + htrc(g->Message, msg); printf("%s\n", g->Message); cap = NULL; - goto fin; - } // endif rc -#endif // !USE_TRY + } // end catch - m = (size_t)qrp->Maxres; - n = (size_t)qrp->Nbcol; - cap = (CATPARM *)PlugSubAlloc(g, NULL, sizeof(CATPARM)); - memset(cap, 0, sizeof(CATPARM)); - cap->Id = fid; - cap->Qrp = qrp; - cap->DB = (PUCHAR)db; - cap->Tab = (PUCHAR)tab; - cap->Vlen = (SQLLEN* *)PlugSubAlloc(g, NULL, n * sizeof(SQLLEN *)); - - for (i = 0; i < n; i++) - cap->Vlen[i] = (SQLLEN *)PlugSubAlloc(g, NULL, m * sizeof(SQLLEN)); - - cap->Status = (UWORD *)PlugSubAlloc(g, NULL, m * sizeof(UWORD)); - -#if defined(USE_TRY) -} catch (int n) { - htrc("Exeption %d: %s\n", n, g->Message); - cap = NULL; -} catch (const char *msg) { - htrc(g->Message, msg); - printf("%s\n", g->Message); - cap = NULL; -} // end catch -#else // !USE_TRY - fin: - g->jump_level--; -#endif // !USE_TRY return cap; - } // end of AllocCatInfo +} // end of AllocCatInfo #if 0 /***********************************************************************/ diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h index 800b1098d50..7219f0b617e 100644 --- a/storage/connect/plgdbsem.h +++ b/storage/connect/plgdbsem.h @@ -143,7 +143,8 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */ TYPE_AM_MYX = 193, /* MYSQL EXEC access method type */ TYPE_AM_CAT = 195, /* Catalog access method type no */ TYPE_AM_ZIP = 198, /* ZIP access method type no */ - TYPE_AM_OUT = 200}; /* Output relations (storage) */ + TYPE_AM_MGO = 199, /* MGO access method type no */ + TYPE_AM_OUT = 200}; /* Output relations (storage) */ enum RECFM {RECFM_NAF = -2, /* Not a file */ RECFM_OEM = -1, /* OEM file access method */ diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp index 299332f51b4..eaa53bd478d 100644 --- a/storage/connect/plgdbutl.cpp +++ b/storage/connect/plgdbutl.cpp @@ -238,90 +238,74 @@ void ptrc(char const *fmt, ...) PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids, int *buftyp, XFLD *fldtyp, unsigned int *length, bool blank, bool nonull) - { +{ char cname[NAM_LEN+1]; int i; PCOLRES *pcrp, crp; PQRYRES qrp; -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return NULL; - } // endif jump_level + /**********************************************************************/ + /* Allocate the structure used to contain the result set. */ + /**********************************************************************/ + qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES)); + pcrp = &qrp->Colresp; + qrp->Continued = false; + qrp->Truncated = false; + qrp->Info = false; + qrp->Suball = true; + qrp->Maxres = maxres; + qrp->Maxsize = 0; + qrp->Nblin = 0; + qrp->Nbcol = 0; // will be ncol + qrp->Cursor = 0; + qrp->BadLines = 0; - if (setjmp(g->jumper[++g->jump_level]) != 0) { - printf("%s\n", g->Message); - qrp = NULL; - goto fin; - } // endif rc -#endif // !USE_TRY + for (i = 0; i < ncol; i++) { + *pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES)); + crp = *pcrp; + pcrp = &crp->Next; + memset(crp, 0, sizeof(COLRES)); + crp->Colp = NULL; + crp->Ncol = ++qrp->Nbcol; + crp->Type = buftyp[i]; + crp->Length = length[i]; + crp->Clen = GetTypeSize(crp->Type, length[i]); + crp->Prec = 0; - /************************************************************************/ - /* Allocate the structure used to contain the result set. */ - /************************************************************************/ - qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES)); - pcrp = &qrp->Colresp; - qrp->Continued = false; - qrp->Truncated = false; - qrp->Info = false; - qrp->Suball = true; - qrp->Maxres = maxres; - qrp->Maxsize = 0; - qrp->Nblin = 0; - qrp->Nbcol = 0; // will be ncol - qrp->Cursor = 0; - qrp->BadLines = 0; - - for (i = 0; i < ncol; i++) { - *pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES)); - crp = *pcrp; - pcrp = &crp->Next; - memset(crp, 0, sizeof(COLRES)); - crp->Colp = NULL; - crp->Ncol = ++qrp->Nbcol; - crp->Type = buftyp[i]; - crp->Length = length[i]; - crp->Clen = GetTypeSize(crp->Type, length[i]); - crp->Prec = 0; - - if (ids > 0) { + if (ids > 0) { #if defined(XMSG) - // Get header from message file - strncpy(cname, PlugReadMessage(g, ids + crp->Ncol, NULL), NAM_LEN); - cname[NAM_LEN] = 0; // for truncated long names + // Get header from message file + strncpy(cname, PlugReadMessage(g, ids + crp->Ncol, NULL), NAM_LEN); + cname[NAM_LEN] = 0; // for truncated long names #else // !XMSG - GetRcString(ids + crp->Ncol, cname, sizeof(cname)); + GetRcString(ids + crp->Ncol, cname, sizeof(cname)); #endif // !XMSG - crp->Name = (PSZ)PlugDup(g, cname); - } else - crp->Name = NULL; // Will be set by caller + crp->Name = (PSZ)PlugDup(g, cname); + } else + crp->Name = NULL; // Will be set by caller - if (fldtyp) - crp->Fld = fldtyp[i]; - else - crp->Fld = FLD_NO; + if (fldtyp) + crp->Fld = fldtyp[i]; + else + crp->Fld = FLD_NO; - // Allocate the Value Block that will contain data - if (crp->Length || nonull) - crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres, - crp->Length, 0, true, blank, false); - else - crp->Kdata = NULL; + // Allocate the Value Block that will contain data + if (crp->Length || nonull) + crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres, + crp->Length, 0, true, blank, false); + else + crp->Kdata = NULL; - if (trace) - htrc("Column(%d) %s type=%d len=%d value=%p\n", - crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata); + if (trace) + htrc("Column(%d) %s type=%d len=%d value=%p\n", + crp->Ncol, crp->Name, crp->Type, crp->Length, crp->Kdata); - } // endfor i + } // endfor i - *pcrp = NULL; + *pcrp = NULL; -#if defined(USE_TRY) - } catch (int n) { + } catch (int n) { htrc("Exception %d: %s\n", n, g->Message); qrp = NULL; } catch (const char *msg) { @@ -329,12 +313,9 @@ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids, htrc("%s\n", g->Message); qrp = NULL; } // end catch -#else // !USE_TRY - fin: - g->jump_level--; -#endif // !USE_TRY + return qrp; - } // end of PlgAllocResult +} // end of PlgAllocResult /***********************************************************************/ /* Allocate and initialize the new DB User Block. */ @@ -380,11 +361,7 @@ PCATLG PlgGetCatalog(PGLOBAL g, bool jump) if (!cat && jump) { // Raise exception so caller doesn't have to check return value strcpy(g->Message, MSG(NO_ACTIVE_DB)); -#if defined(USE_TRY) throw 1; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 1); -#endif // !USE_TRY } // endif cat return cat; @@ -495,11 +472,7 @@ bool PlugEvalLike(PGLOBAL g, LPCSTR strg, LPCSTR pat, bool ci) tp = g->Message; else if (!(tp = new char[strlen(pat) + strlen(strg) + 2])) { strcpy(g->Message, MSG(NEW_RETURN_NULL)); -#if defined(USE_TRY) throw OP_LIKE; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], OP_LIKE); -#endif // !USE_TRY } /* endif tp */ sp = tp + strlen(pat) + 1; @@ -510,11 +483,7 @@ bool PlugEvalLike(PGLOBAL g, LPCSTR strg, LPCSTR pat, bool ci) tp = g->Message; /* Use this as temporary work space. */ else if (!(tp = new char[strlen(pat) + 1])) { strcpy(g->Message, MSG(NEW_RETURN_NULL)); -#if defined(USE_TRY) throw OP_LIKE; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], OP_LIKE); -#endif // !USE_TRY } /* endif tp */ strcpy(tp, pat); /* Make a copy to be worked into */ @@ -1547,11 +1516,7 @@ DllExport void NewPointer(PTABS t, void *oldv, void *newv) PGLOBAL g = t->G; sprintf(g->Message, "NewPointer: %s", MSG(MEM_ALLOC_ERROR)); -#if defined(USE_TRY) throw 3; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 3); -#endif // !USE_TRY } else { tp->Next = t->P1; tp->Num = 0; @@ -1588,22 +1553,14 @@ int FileComp(PGLOBAL g, char *file1, char *file2) sprintf(g->Message, MSG(OPEN_MODE_ERROR), "rb", (int)errno, fn[i]); strcat(strcat(g->Message, ": "), strerror(errno)); -#if defined(USE_TRY) throw 666; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 666); -#endif // !USE_TRY // } else // len[i] = 0; // File does not exist yet } else { if ((len[i] = _filelength(h[i])) < 0) { sprintf(g->Message, MSG(FILELEN_ERROR), "_filelength", fn[i]); -#if defined(USE_TRY) throw 666; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 666); -#endif // !USE_TRY } // endif len } // endif h diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp index d34b43a63d2..c5c160073ee 100644 --- a/storage/connect/plugutil.cpp +++ b/storage/connect/plugutil.cpp @@ -519,13 +519,7 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) if (trace) htrc("PlugSubAlloc: %s\n", g->Message); -#if defined(USE_TRY) throw 1234; -#else // !USE_TRY - /* Nothing we can do if longjmp is not initialized. */ - assert(g->jump_level >= 0); - longjmp(g->jumper[g->jump_level], 1); -#endif // !USE_TRY } /* endif size OS32 code */ /*********************************************************************/ diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp index 5e77e7098aa..59db4e4823e 100644 --- a/storage/connect/tabdos.cpp +++ b/storage/connect/tabdos.cpp @@ -132,7 +132,8 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int) bool map = (am && (*am == 'M' || *am == 'm')); LPCSTR dfm = (am && (*am == 'F' || *am == 'f')) ? "F" : (am && (*am == 'B' || *am == 'b')) ? "B" - : (am && !stricmp(am, "DBF")) ? "D" : "V"; + : (am && (*am == 'X' || *am == 'x')) ? "X" + : (am && !stricmp(am, "DBF")) ? "D" : "V"; if ((Zipped = GetBoolCatInfo("Zipped", false))) { Entry = GetStringCatInfo(g, "Entry", NULL); @@ -148,7 +149,8 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int) GetCharCatInfo("Recfm", (PSZ)dfm, buf, sizeof(buf)); Recfm = (toupper(*buf) == 'F') ? RECFM_FIX : (toupper(*buf) == 'B') ? RECFM_BIN : - (toupper(*buf) == 'D') ? RECFM_DBF : RECFM_VAR; + (toupper(*buf) == 'X') ? RECFM_NAF : // MGO + (toupper(*buf) == 'D') ? RECFM_DBF : RECFM_VAR; Lrecl = GetIntCatInfo("Lrecl", 0); if (Recfm != RECFM_DBF) @@ -1511,11 +1513,7 @@ PBF TDBDOS::CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv) if (n == 8 && ctype != TYPE_LIST) { // Should never happen strcpy(g->Message, "Block opt: bad constant"); -#if defined(USE_TRY) throw 99; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 99); -#endif // !USE_TRY } // endif Conv if (type[0] == 1) { @@ -1796,7 +1794,7 @@ err: /* Make a dynamic index. */ /***********************************************************************/ bool TDBDOS::InitialyzeIndex(PGLOBAL g, volatile PIXDEF xdp, bool sorted) - { +{ int k; volatile bool dynamic; bool brc; @@ -1867,17 +1865,7 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, volatile PIXDEF xdp, bool sorted) } else // Column contains same values as ROWID kxp = new(g) XXROW(this); -#if defined(USE_TRY) try { -#else // !USE_TRY - // Prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return true; - } // endif - - if (!setjmp(g->jumper[++g->jump_level])) { -#endif // !USE_TRY if (dynamic) { ResetBlockFilter(g); kxp->SetDynamic(dynamic); @@ -1902,7 +1890,6 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, volatile PIXDEF xdp, bool sorted) } // endif brc -#if defined(USE_TRY) } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); @@ -1911,14 +1898,9 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, volatile PIXDEF xdp, bool sorted) strcpy(g->Message, msg); brc = true; } // end catch -#else // !USE_TRY - } else - brc = true; - g->jump_level--; -#endif // !USE_TRY return brc; - } // end of InitialyzeIndex +} // end of InitialyzeIndex /***********************************************************************/ /* DOS GetProgMax: get the max value for progress information. */ @@ -2139,7 +2121,8 @@ bool TDBDOS::OpenDB(PGLOBAL g) return false; } // endif use - if (Mode == MODE_DELETE && !Next && Txfp->GetAmType() != TYPE_AM_DOS) { + if (Mode == MODE_DELETE && !Next && Txfp->GetAmType() != TYPE_AM_DOS + && Txfp->GetAmType() != TYPE_AM_MGO) { // Delete all lines. Not handled in MAP or block mode Txfp = new(g) DOSFAM((PDOSDEF)To_Def); Txfp->SetTdbp(this); @@ -2537,11 +2520,7 @@ void DOSCOL::ReadColumn(PGLOBAL g) if (rc == RC_EF) sprintf(g->Message, MSG(INV_DEF_READ), rc); -#if defined(USE_TRY) throw 11; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 11); -#endif // !USE_TRY } // endif p = tdbp->To_Line + Deplac; @@ -2597,11 +2576,7 @@ void DOSCOL::ReadColumn(PGLOBAL g) break; default: sprintf(g->Message, MSG(BAD_RECFM), tdbp->Ftype); -#if defined(USE_TRY) throw 34; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 34); -#endif // !USE_TRY } // endswitch Ftype // Set null when applicable @@ -2710,11 +2685,7 @@ void DOSCOL::WriteColumn(PGLOBAL g) break; default: sprintf(g->Message, "Invalid field format for column %s", Name); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } // endswitch BufType p2 = Buf; @@ -2726,11 +2697,7 @@ void DOSCOL::WriteColumn(PGLOBAL g) if ((len = strlen(p2)) > field) { sprintf(g->Message, MSG(VALUE_TOO_LONG), p2, Name, field); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } else if (Dsp) for (i = 0; i < len; i++) if (p2[i] == '.') diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp index fb25ab3d5c8..b1e308ce8fd 100644 --- a/storage/connect/tabfix.cpp +++ b/storage/connect/tabfix.cpp @@ -411,11 +411,7 @@ BINCOL::BINCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am) case 'D': M = sizeof(double); break; default: sprintf(g->Message, MSG(BAD_BIN_FMT), Fmt, Name); -#if defined(USE_TRY) throw 11; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 11); -#endif // !USE_TRY } // endswitch Fmt } else if (IsTypeChar(Buf_Type)) @@ -490,11 +486,7 @@ void BINCOL::ReadColumn(PGLOBAL g) if (rc == RC_EF) sprintf(g->Message, MSG(INV_DEF_READ), rc); -#if defined(USE_TRY) throw 11; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 11); -#endif // !USE_TRY } // endif p = tdbp->To_Line + Deplac; @@ -553,11 +545,7 @@ void BINCOL::ReadColumn(PGLOBAL g) break; default: sprintf(g->Message, MSG(BAD_BIN_FMT), Fmt, Name); -#if defined(USE_TRY) throw 11; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 11); -#endif // !USE_TRY } // endswitch Fmt // Set null when applicable @@ -607,11 +595,7 @@ void BINCOL::WriteColumn(PGLOBAL g) } else if (Value->GetBinValue(p, Long, Status)) { sprintf(g->Message, MSG(BIN_F_TOO_LONG), Name, Value->GetSize(), Long); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } // endif p break; @@ -620,11 +604,7 @@ void BINCOL::WriteColumn(PGLOBAL g) if (n > 32767LL || n < -32768LL) { sprintf(g->Message, MSG(VALUE_TOO_BIG), n, Name); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } else if (Status) Value->GetValueNonAligned(p, (short)n); @@ -634,11 +614,7 @@ void BINCOL::WriteColumn(PGLOBAL g) if (n > 255LL || n < -256LL) { sprintf(g->Message, MSG(VALUE_TOO_BIG), n, Name); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } else if (Status) *p = (char)n; @@ -648,11 +624,7 @@ void BINCOL::WriteColumn(PGLOBAL g) if (n > INT_MAX || n < INT_MIN) { sprintf(g->Message, MSG(VALUE_TOO_BIG), n, Name); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } else if (Status) Value->GetValueNonAligned(p, (int)n); @@ -676,11 +648,7 @@ void BINCOL::WriteColumn(PGLOBAL g) case 'C': // Characters if ((n = (signed)strlen(Value->GetCharString(Buf))) > Long) { sprintf(g->Message, MSG(BIN_F_TOO_LONG), Name, (int) n, Long); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } // endif n if (Status) { @@ -692,11 +660,7 @@ void BINCOL::WriteColumn(PGLOBAL g) break; default: sprintf(g->Message, MSG(BAD_BIN_FMT), Fmt, Name); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } // endswitch Fmt if (Eds && Status) { diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp index be288b3858d..0b4ef0bee6b 100644 --- a/storage/connect/tabfmt.cpp +++ b/storage/connect/tabfmt.cpp @@ -1435,11 +1435,7 @@ void CSVCOL::ReadColumn(PGLOBAL g) if (rc == RC_EF) sprintf(g->Message, MSG(INV_DEF_READ), rc); -#if defined(USE_TRY) throw 34; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 34); -#endif // !USE_TRY } // endif if (tdbp->Mode != MODE_UPDATE) { @@ -1457,11 +1453,7 @@ void CSVCOL::ReadColumn(PGLOBAL g) Long = colen; // Restore column length sprintf(g->Message, MSG(FLD_TOO_LNG_FOR), Fldnum + 1, Name, To_Tdb->RowNumber(g), tdbp->GetFile(g)); -#if defined(USE_TRY) throw 34; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 34); -#endif // !USE_TRY } // endif Long // Now do the reading @@ -1524,11 +1516,7 @@ void CSVCOL::WriteColumn(PGLOBAL g) if ((signed)strlen(p) > flen) { sprintf(g->Message, MSG(BAD_FLD_LENGTH), Name, p, flen, tdbp->RowNumber(g), tdbp->GetFile(g)); -#if defined(USE_TRY) throw 34; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 34); -#endif // !USE_TRY } else if (Dsp) for (int i = 0; p[i]; i++) if (p[i] == '.') @@ -1544,11 +1532,7 @@ void CSVCOL::WriteColumn(PGLOBAL g) if (Fldnum < 0) { // This can happen for wrong offset value in XDB files sprintf(g->Message, MSG(BAD_FIELD_RANK), Fldnum + 1, Name); -#if defined(USE_TRY) throw 34; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 34); -#endif // !USE_TRY } else strncpy(tdbp->Field[Fldnum], p, flen); diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index d6fb6aff2eb..a6e78ca3fd1 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -31,6 +31,9 @@ #if defined(ZIP_SUPPORT) #include "filamzip.h" #endif // ZIP_SUPPORT +#if defined(MONGO_SUPPORT) +#include "mongofam.h" +#endif // MONGO_SUPPORT #include "tabmul.h" #include "checklvl.h" #include "resource.h" @@ -63,7 +66,7 @@ typedef struct _jncol { /* JSONColumns: construct the result blocks containing the description */ /* of all the columns of a table contained inside a JSON file. */ /***********************************************************************/ -PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info) +PQRYRES JSONColumns(PGLOBAL g, char *db, char *dsn, PTOS topt, bool info) { static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING}; @@ -112,7 +115,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info) #endif // ZIP_SUPPORT tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL); - if (!tdp->Fn) { + if (!tdp->Fn && !dsn) { strcpy(g->Message, MSG(MISSING_FNAME)); return NULL; } // endif Fn @@ -126,6 +129,19 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info) htrc("File %s objname=%s pretty=%d lvl=%d\n", tdp->Fn, tdp->Objname, tdp->Pretty, lvl); + if (tdp->Uri = dsn) { +#if defined(MONGO_SUPPORT) + tdp->Collname = GetStringTableOption(g, topt, "Name", NULL); + tdp->Collname = GetStringTableOption(g, topt, "Tabname", tdp->Collname); + tdp->Schema = GetStringTableOption(g, topt, "Dbname", "test"); + tdp->Options = GetStringTableOption(g, topt, "Colist", NULL); + tdp->Pretty = 0; +#else // !MONGO_SUPPORT + sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO"); + return NULL; +#endif // !MONGO_SUPPORT + } // endif Uri + if (tdp->Pretty == 2) { if (tdp->Zipped) { #if defined(ZIP_SUPPORT) @@ -151,12 +167,14 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info) if (tdp->Zipped) { #if defined(ZIP_SUPPORT) - tjnp = new(g)TDBJSN(tdp, new(g)UNZFAM(tdp)); + tjnp = new(g)TDBJSN(tdp, new(g) UNZFAM(tdp)); #else // !ZIP_SUPPORT sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP"); return NULL; #endif // !ZIP_SUPPORT - } else + } else if (tdp->Uri) + tjnp = new(g) TDBJSN(tdp, new(g) MGOFAM(tdp)); + else tjnp = new(g) TDBJSN(tdp, new(g) DOSFAM(tdp)); tjnp->SetMode(MODE_READ); @@ -404,6 +422,10 @@ JSONDEF::JSONDEF(void) Limit = 1; Base = 0; Strict = false; +#if defined(MONGO_SUPPORT) + Uri = NULL; + Collname = Schema = Options = NULL; +#endif // MONGO_SUPPORT } // end of JSONDEF constructor /***********************************************************************/ @@ -417,7 +439,22 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR, int poff) Pretty = GetIntCatInfo("Pretty", 2); Limit = GetIntCatInfo("Limit", 10); Base = GetIntCatInfo("Base", 0) ? 1 : 0; - return DOSDEF::DefineAM(g, "DOS", poff); + + if (Uri = GetStringCatInfo(g, "Connect", NULL)) { +#if defined(MONGO_SUPPORT) + Collname = GetStringCatInfo(g, "Name", + (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); + Collname = GetStringCatInfo(g, "Tabname", Collname); + Schema = GetStringCatInfo(g, "Dbname", "test"); + Options = GetStringCatInfo(g, "Colist", NULL); + Pretty = 0; +#else // !MONGO_SUPPORT + sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "MONGO"); + return true; +#endif // !MONGO_SUPPORT + } // endif Uri + + return DOSDEF::DefineAM(g, (Uri ? "XMGO" : "DOS"), poff); } // end of DefineAM /***********************************************************************/ @@ -463,7 +500,9 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "GZ"); return NULL; #endif // !GZ_SUPPORT - } else if (map) + } else if (Uri) + txfp = new(g) MGOFAM(this); + else if (map) txfp = new(g) MAPFAM(this); else txfp = new(g) DOSFAM(this); @@ -527,6 +566,7 @@ TDBJSN::TDBJSN(PJDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp) if (tdp) { Jmode = tdp->Jmode; Objname = tdp->Objname; + Amtype = (tdp->Uri ? TYPE_AM_MGO : TYPE_AM_JSN); Xcol = tdp->Xcol; Limit = tdp->Limit; Pretty = tdp->Pretty; @@ -535,7 +575,8 @@ TDBJSN::TDBJSN(PJDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp) } else { Jmode = MODE_OBJECT; Objname = NULL; - Xcol = NULL; + Amtype = TYPE_AM_JSN; + Xcol = NULL; Limit = 1; Pretty = 0; B = 0; @@ -865,16 +906,16 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) } // end of PrepareWriting - /***********************************************************************/ - /* WriteDB: Data Base write routine for DOS access method. */ - /***********************************************************************/ - int TDBJSN::WriteDB(PGLOBAL g) +/***********************************************************************/ +/* WriteDB: Data Base write routine for DOS access method. */ +/***********************************************************************/ +int TDBJSN::WriteDB(PGLOBAL g) { int rc = TDBDOS::WriteDB(g); #if USE_G - if (rc == RC_FX) - strcpy(g->Message, G->Message); + //if (rc == RC_FX) + // strcpy(g->Message, G->Message); PlugSubSet(G, G->Sarea, G->Sarea_Size); #endif @@ -882,7 +923,7 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp) return rc; } // end of WriteDB - /* ---------------------------- JSONCOL ------------------------------ */ +/* ---------------------------- JSONCOL ------------------------------ */ /***********************************************************************/ /* JSONCOL public constructor. */ @@ -1290,11 +1331,7 @@ PVAL JSONCOL::ExpandArray(PGLOBAL g, PJAR arp, int n) if (!(jvp = arp->GetValue((Nodes[n].Rx = Nodes[n].Nx)))) { strcpy(g->Message, "Logical error expanding array"); -#if defined(USE_TRY) throw 666; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 666); -#endif // !USE_TRY } // endif jvp if (n < Nod - 1 && jvp->GetJson()) { @@ -1480,11 +1517,7 @@ void JSONCOL::WriteColumn(PGLOBAL g) { if (Xpd && Tjp->Pretty < 2) { strcpy(g->Message, "Cannot write expanded column when Pretty is not 2"); -#if defined(USE_TRY) throw 666; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 666); -#endif // !USE_TRY } // endif Xpd /*********************************************************************/ @@ -1519,11 +1552,7 @@ void JSONCOL::WriteColumn(PGLOBAL g) if (!(jsp = ParseJson(G, s, (int)strlen(s)))) { strcpy(g->Message, s); -#if defined(USE_TRY) throw 666; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 666); -#endif // !USE_TRY } // endif jsp if (arp) { @@ -1996,6 +2025,7 @@ TDBJCL::TDBJCL(PJDEF tdp) : TDBCAT(tdp) { Topt = tdp->GetTopt(); Db = (char*)tdp->GetDB(); + Dsn = (char*)tdp->Uri; } // end of TDBJCL constructor /***********************************************************************/ @@ -2003,7 +2033,7 @@ TDBJCL::TDBJCL(PJDEF tdp) : TDBCAT(tdp) /***********************************************************************/ PQRYRES TDBJCL::GetResult(PGLOBAL g) { - return JSONColumns(g, Db, Topt, false); + return JSONColumns(g, Db, Dsn, Topt, false); } // end of GetResult /* --------------------------- End of json --------------------------- */ diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h index a85f0016200..c98d32a804e 100644 --- a/storage/connect/tabjson.h +++ b/storage/connect/tabjson.h @@ -1,5 +1,5 @@ /*************** tabjson H Declares Source Code File (.H) **************/ -/* Name: tabjson.h Version 1.2 */ +/* Name: tabjson.h Version 1.3 */ /* */ /* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */ /* */ @@ -36,8 +36,11 @@ class DllExport JSONDEF : public DOSDEF { /* Table description */ friend class TDBJSON; friend class TDBJSN; friend class TDBJCL; - friend PQRYRES JSONColumns(PGLOBAL, char*, PTOS, bool); - public: + friend PQRYRES JSONColumns(PGLOBAL, char*, char*, PTOS, bool); +#if defined(MONGO_SUPPORT) + friend class MGOFAM; +#endif // MONGO_SUPPORT +public: // Constructor JSONDEF(void); @@ -58,6 +61,12 @@ class DllExport JSONDEF : public DOSDEF { /* Table description */ int Level; /* Used for catalog table */ int Base; /* Tne array index base */ bool Strict; /* Strict syntax checking */ +#if defined(MONGO_SUPPORT) + const char *Uri; /* MongoDB connection URI */ + PSZ Collname; /* External collection name */ + PSZ Schema; /* External schema (DB) name */ + PSZ Options; /* Colist ; filter */ +#endif // MONGO_SUPPORT }; // end of JSONDEF /* -------------------------- TDBJSN class --------------------------- */ @@ -75,7 +84,7 @@ public: TDBJSN(TDBJSN *tdbp); // Implementation - virtual AMT GetAmType(void) {return TYPE_AM_JSN;} + virtual AMT GetAmType(void) {return Amtype;} virtual bool SkipHeader(PGLOBAL g); virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBJSN(this);} PJSON GetRow(void) {return Row;} @@ -107,6 +116,7 @@ public: PJSON Val; // The value of the current row PJCOL Colp; // The multiple column JMODE Jmode; // MODE_OBJECT by default + AMT Amtype; // Access method type char *Objname; // The table object name char *Xcol; // Name of expandable column int Fpos; // The current row index @@ -233,4 +243,5 @@ class DllExport TDBJCL : public TDBCAT { // Members PTOS Topt; char *Db; + char *Dsn; }; // end of class TDBJCL diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp index 4128fea6afc..ea04e4cf731 100644 --- a/storage/connect/tabmul.cpp +++ b/storage/connect/tabmul.cpp @@ -1008,11 +1008,7 @@ void DIRCOL::ReadColumn(PGLOBAL g) #endif // !__WIN__ default: sprintf(g->Message, MSG(INV_DIRCOL_OFST), N); -#if defined(USE_TRY) throw GetAmType(); -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], GetAmType()); -#endif // !USE_TRY } // endswitch N } // end of ReadColumn @@ -1537,11 +1533,7 @@ void TDBDHR::CloseDB(PGLOBAL g) // Close the search handle. if (!FindClose(Hsearch)) { strcpy(g->Message, MSG(SRCH_CLOSE_ERR)); -#if defined(USE_TRY) throw GetAmType(); -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], GetAmType()); -#endif // !USE_TRY } // endif FindClose iFile = 0; diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp index 3ce1ea1f7d8..f03b45a7d35 100644 --- a/storage/connect/tabmysql.cpp +++ b/storage/connect/tabmysql.cpp @@ -1407,11 +1407,7 @@ void MYSQLCOL::ReadColumn(PGLOBAL g) if (rc == RC_EF) sprintf(g->Message, MSG(INV_DEF_READ), rc); -#if defined(USE_TRY) throw 11; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 11); -#endif // !USE_TRY } else tdbp->Fetched = true; diff --git a/storage/connect/tabpivot.cpp b/storage/connect/tabpivot.cpp index f24929eb2bb..723180fe59a 100644 --- a/storage/connect/tabpivot.cpp +++ b/storage/connect/tabpivot.cpp @@ -106,7 +106,7 @@ bool PIVAID::SkipColumn(PCOLRES crp, char *skc) /* Make the Pivot table column list. */ /***********************************************************************/ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g) - { +{ char *p, *query, *colname, *skc, buf[64]; int ndif, nblin, w = 0; bool b = false; @@ -114,205 +114,190 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g) PQRYRES qrp; PCOLRES *pcrp, crp, fncrp = NULL; -#if defined(USE_TRY) try { -#else // !USE_TRY - // Save stack and allocation environment and prepare error return - if (g->jump_level == MAX_JUMP) { - strcpy(g->Message, MSG(TOO_MANY_JUMPS)); - return NULL; - } // endif jump_level + // Are there columns to skip? + if (Skcol) { + uint n = strlen(Skcol); - if (setjmp(g->jumper[++g->jump_level])) { - goto err; - } // endif rc -#endif // !USE_TRY + skc = (char*)PlugSubAlloc(g, NULL, n + 2); + strcpy(skc, Skcol); + skc[n + 1] = 0; - // Are there columns to skip? - if (Skcol) { - uint n = strlen(Skcol); + // Replace ; by nulls in skc + for (p = strchr(skc, ';'); p; p = strchr(p, ';')) + *p++ = 0; - skc = (char*)PlugSubAlloc(g, NULL, n + 2); - strcpy(skc, Skcol); - skc[n + 1] = 0; + } else + skc = NULL; - // Replace ; by nulls in skc - for (p = strchr(skc, ';'); p; p = strchr(p, ';')) - *p++ = 0; + if (!Tabsrc && Tabname) { + // Locate the query + query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 26); + sprintf(query, "SELECT * FROM `%s` LIMIT 1", Tabname); + } else if (!Tabsrc) { + strcpy(g->Message, MSG(SRC_TABLE_UNDEF)); + goto err; + } else + query = Tabsrc; - } else - skc = NULL; + // Open a MySQL connection for this table + if (!Myc.Open(g, Host, Database, User, Pwd, Port)) { + b = true; - if (!Tabsrc && Tabname) { - // Locate the query - query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 26); - sprintf(query, "SELECT * FROM `%s` LIMIT 1", Tabname); - } else if (!Tabsrc) { - strcpy(g->Message, MSG(SRC_TABLE_UNDEF)); - goto err; - } else - query = Tabsrc; + // Returned values must be in their original character set + if (Myc.ExecSQL(g, "SET character_set_results=NULL", &w) == RC_FX) + goto err; + else + Myc.FreeResult(); - // Open a MySQL connection for this table - if (!Myc.Open(g, Host, Database, User, Pwd, Port)) { - b = true; - - // Returned values must be in their original character set - if (Myc.ExecSQL(g, "SET character_set_results=NULL", &w) == RC_FX) - goto err; - else - Myc.FreeResult(); - - } else - goto err; - - // Send the source command to MySQL - if (Myc.ExecSQL(g, query, &w) == RC_FX) - goto err; - - // We must have a storage query to get pivot column values - if (!(Qryp = Myc.GetResult(g, true))) - goto err; - - if (!Fncol) { - for (crp = Qryp->Colresp; crp; crp = crp->Next) - if ((!Picol || stricmp(Picol, crp->Name)) && !SkipColumn(crp, skc)) - Fncol = crp->Name; - - if (!Fncol) { - strcpy(g->Message, MSG(NO_DEF_FNCCOL)); - goto err; - } // endif Fncol - - } // endif Fncol - - if (!Picol) { - // Find default Picol as the last one not equal to Fncol - for (crp = Qryp->Colresp; crp; crp = crp->Next) - if (stricmp(Fncol, crp->Name) && !SkipColumn(crp, skc)) - Picol = crp->Name; - - if (!Picol) { - strcpy(g->Message, MSG(NO_DEF_PIVOTCOL)); - goto err; - } // endif Picol - - } // endif picol - - // Prepare the column list - for (pcrp = &Qryp->Colresp; crp = *pcrp; ) - if (SkipColumn(crp, skc)) { - // Ignore this column - *pcrp = crp->Next; - } else if (!stricmp(Picol, crp->Name)) { - if (crp->Nulls) { - sprintf(g->Message, "Pivot column %s cannot be nullable", Picol); - goto err; - } // endif Nulls - - Rblkp = crp->Kdata; - *pcrp = crp->Next; - } else if (!stricmp(Fncol, crp->Name)) { - fncrp = crp; - *pcrp = crp->Next; - } else - pcrp = &crp->Next; - - if (!Rblkp) { - strcpy(g->Message, MSG(NO_DEF_PIVOTCOL)); - goto err; - } else if (!fncrp) { - strcpy(g->Message, MSG(NO_DEF_FNCCOL)); - goto err; - } // endif - - if (Tabsrc) { - Myc.Close(); - b = false; - - // Before calling sort, initialize all - nblin = Qryp->Nblin; - - Index.Size = nblin * sizeof(int); - Index.Sub = TRUE; // Should be small enough - - if (!PlgDBalloc(g, NULL, Index)) + } else goto err; - Offset.Size = (nblin + 1) * sizeof(int); - Offset.Sub = TRUE; // Should be small enough - - if (!PlgDBalloc(g, NULL, Offset)) + // Send the source command to MySQL + if (Myc.ExecSQL(g, query, &w) == RC_FX) goto err; - ndif = Qsort(g, nblin); - - if (ndif < 0) // error + // We must have a storage query to get pivot column values + if (!(Qryp = Myc.GetResult(g, true))) goto err; - } else { - // The query was limited, we must get pivot column values - // Returned values must be in their original character set -// if (Myc.ExecSQL(g, "SET character_set_results=NULL", &w) == RC_FX) -// goto err; + if (!Fncol) { + for (crp = Qryp->Colresp; crp; crp = crp->Next) + if ((!Picol || stricmp(Picol, crp->Name)) && !SkipColumn(crp, skc)) + Fncol = crp->Name; - query = (char*)PlugSubAlloc(g, NULL, 0); - sprintf(query, "SELECT DISTINCT `%s` FROM `%s`", Picol, Tabname); - PlugSubAlloc(g, NULL, strlen(query) + 1); - Myc.FreeResult(); + if (!Fncol) { + strcpy(g->Message, MSG(NO_DEF_FNCCOL)); + goto err; + } // endif Fncol - // Send the source command to MySQL - if (Myc.ExecSQL(g, query, &w) == RC_FX) - goto err; + } // endif Fncol - // We must have a storage query to get pivot column values - if (!(qrp = Myc.GetResult(g, true))) - goto err; + if (!Picol) { + // Find default Picol as the last one not equal to Fncol + for (crp = Qryp->Colresp; crp; crp = crp->Next) + if (stricmp(Fncol, crp->Name) && !SkipColumn(crp, skc)) + Picol = crp->Name; - Myc.Close(); - b = false; + if (!Picol) { + strcpy(g->Message, MSG(NO_DEF_PIVOTCOL)); + goto err; + } // endif Picol - // Get the column list - crp = qrp->Colresp; - Rblkp = crp->Kdata; - ndif = qrp->Nblin; - } // endif Tabsrc + } // endif picol - // Allocate the Value used to retieve column names - if (!(valp = AllocateValue(g, Rblkp->GetType(), - Rblkp->GetVlen(), - Rblkp->GetPrec()))) - goto err; + // Prepare the column list + for (pcrp = &Qryp->Colresp; crp = *pcrp; ) + if (SkipColumn(crp, skc)) { + // Ignore this column + *pcrp = crp->Next; + } else if (!stricmp(Picol, crp->Name)) { + if (crp->Nulls) { + sprintf(g->Message, "Pivot column %s cannot be nullable", Picol); + goto err; + } // endif Nulls - // Now make the functional columns - for (int i = 0; i < ndif; i++) { - if (i) { - crp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES)); - memcpy(crp, fncrp, sizeof(COLRES)); - } else - crp = fncrp; + Rblkp = crp->Kdata; + *pcrp = crp->Next; + } else if (!stricmp(Fncol, crp->Name)) { + fncrp = crp; + *pcrp = crp->Next; + } else + pcrp = &crp->Next; - // Get the value that will be the generated column name - if (Tabsrc) - valp->SetValue_pvblk(Rblkp, Pex[Pof[i]]); - else - valp->SetValue_pvblk(Rblkp, i); + if (!Rblkp) { + strcpy(g->Message, MSG(NO_DEF_PIVOTCOL)); + goto err; + } else if (!fncrp) { + strcpy(g->Message, MSG(NO_DEF_FNCCOL)); + goto err; + } // endif - colname = valp->GetCharString(buf); - crp->Name = PlugDup(g, colname); - crp->Flag = 1; + if (Tabsrc) { + Myc.Close(); + b = false; - // Add this column - *pcrp = crp; - crp->Next = NULL; - pcrp = &crp->Next; - } // endfor i + // Before calling sort, initialize all + nblin = Qryp->Nblin; - // We added ndif columns and removed 2 (picol and fncol) - Qryp->Nbcol += (ndif - 2); -#if defined(USE_TRY) - return Qryp; + Index.Size = nblin * sizeof(int); + Index.Sub = TRUE; // Should be small enough + if (!PlgDBalloc(g, NULL, Index)) + goto err; + + Offset.Size = (nblin + 1) * sizeof(int); + Offset.Sub = TRUE; // Should be small enough + + if (!PlgDBalloc(g, NULL, Offset)) + goto err; + + ndif = Qsort(g, nblin); + + if (ndif < 0) // error + goto err; + + } else { + // The query was limited, we must get pivot column values + // Returned values must be in their original character set + // if (Myc.ExecSQL(g, "SET character_set_results=NULL", &w) == RC_FX) + // goto err; + + query = (char*)PlugSubAlloc(g, NULL, 0); + sprintf(query, "SELECT DISTINCT `%s` FROM `%s`", Picol, Tabname); + PlugSubAlloc(g, NULL, strlen(query) + 1); + Myc.FreeResult(); + + // Send the source command to MySQL + if (Myc.ExecSQL(g, query, &w) == RC_FX) + goto err; + + // We must have a storage query to get pivot column values + if (!(qrp = Myc.GetResult(g, true))) + goto err; + + Myc.Close(); + b = false; + + // Get the column list + crp = qrp->Colresp; + Rblkp = crp->Kdata; + ndif = qrp->Nblin; + } // endif Tabsrc + + // Allocate the Value used to retieve column names + if (!(valp = AllocateValue(g, Rblkp->GetType(), + Rblkp->GetVlen(), + Rblkp->GetPrec()))) + goto err; + + // Now make the functional columns + for (int i = 0; i < ndif; i++) { + if (i) { + crp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES)); + memcpy(crp, fncrp, sizeof(COLRES)); + } else + crp = fncrp; + + // Get the value that will be the generated column name + if (Tabsrc) + valp->SetValue_pvblk(Rblkp, Pex[Pof[i]]); + else + valp->SetValue_pvblk(Rblkp, i); + + colname = valp->GetCharString(buf); + crp->Name = PlugDup(g, colname); + crp->Flag = 1; + + // Add this column + *pcrp = crp; + crp->Next = NULL; + pcrp = &crp->Next; + } // endfor i + + // We added ndif columns and removed 2 (picol and fncol) + Qryp->Nbcol += (ndif - 2); + return Qryp; } catch (int n) { if (trace) htrc("Exception %d: %s\n", n, g->Message); @@ -321,19 +306,11 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g) } // end catch err: -#else // !USE_TRY - g->jump_level--; - return Qryp; - -err: - g->jump_level--; -#endif // !USE_TRY - if (b) Myc.Close(); return NULL; - } // end of MakePivotColumns +} // end of MakePivotColumns /***********************************************************************/ /* PIVAID: Compare routine for sorting pivot column values. */ diff --git a/storage/connect/tabsys.cpp b/storage/connect/tabsys.cpp index d2f5cdb2780..53009c7ef9a 100644 --- a/storage/connect/tabsys.cpp +++ b/storage/connect/tabsys.cpp @@ -511,19 +511,11 @@ void INICOL::WriteColumn(PGLOBAL g) if (strlen(p) > (unsigned)Long) { sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } else if (Flag == 1) { if (tdbp->Mode == MODE_UPDATE) { strcpy(g->Message, MSG(NO_SEC_UPDATE)); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } else if (*p) { tdbp->Section = p; } else @@ -532,11 +524,7 @@ void INICOL::WriteColumn(PGLOBAL g) return; } else if (!tdbp->Section) { strcpy(g->Message, MSG(SEC_NAME_FIRST)); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } // endif's /*********************************************************************/ @@ -548,11 +536,7 @@ void INICOL::WriteColumn(PGLOBAL g) if (!rc) { sprintf(g->Message, "Error %d writing to %s", GetLastError(), tdbp->Ifile); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } // endif rc } // endif Status @@ -853,19 +837,11 @@ void XINCOL::WriteColumn(PGLOBAL g) if (strlen(p) > (unsigned)Long) { sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } else if (Flag == 1) { if (tdbp->Mode == MODE_UPDATE) { strcpy(g->Message, MSG(NO_SEC_UPDATE)); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } else if (*p) { tdbp->Section = p; } else @@ -875,11 +851,7 @@ void XINCOL::WriteColumn(PGLOBAL g) } else if (Flag == 2) { if (tdbp->Mode == MODE_UPDATE) { strcpy(g->Message, MSG(NO_KEY_UPDATE)); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } else if (*p) { tdbp->Keycur = p; } else @@ -888,11 +860,7 @@ void XINCOL::WriteColumn(PGLOBAL g) return; } else if (!tdbp->Section || !tdbp->Keycur) { strcpy(g->Message, MSG(SEC_KEY_FIRST)); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } // endif's /*********************************************************************/ @@ -904,11 +872,7 @@ void XINCOL::WriteColumn(PGLOBAL g) if (!rc) { sprintf(g->Message, "Error %d writing to %s", GetLastError(), tdbp->Ifile); -#if defined(USE_TRY) throw 31; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 31); -#endif // !USE_TRY } // endif rc } // endif Status diff --git a/storage/connect/tabvct.cpp b/storage/connect/tabvct.cpp index 902137ead2e..f4985940b9e 100644 --- a/storage/connect/tabvct.cpp +++ b/storage/connect/tabvct.cpp @@ -490,11 +490,7 @@ void VCTCOL::ReadBlock(PGLOBAL g) #if defined(_DEBUG) if (!Blk) { strcpy(g->Message, MSG(TO_BLK_IS_NULL)); -#if defined(USE_TRY) throw 58; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 58); -#endif // !USE_TRY } // endif #endif @@ -502,11 +498,7 @@ void VCTCOL::ReadBlock(PGLOBAL g) /* Read column block according to used access method. */ /*********************************************************************/ if (txfp->ReadBlock(g, this)) -#if defined(USE_TRY) throw 6; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 6); -#endif // !USE_TRY ColBlk = txfp->CurBlk; ColPos = -1; // Any invalid position @@ -526,11 +518,7 @@ void VCTCOL::WriteBlock(PGLOBAL g) #if defined(_DEBUG) if (!Blk) { strcpy(g->Message, MSG(BLK_IS_NULL)); -#if defined(USE_TRY) throw 56; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 56); -#endif // !USE_TRY } // endif #endif @@ -538,11 +526,7 @@ void VCTCOL::WriteBlock(PGLOBAL g) /* Write column block according to used access method. */ /*******************************************************************/ if (txfp->WriteBlock(g, this)) -#if defined(USE_TRY) throw 6; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 6); -#endif // !USE_TRY Modif = 0; } // endif Modif diff --git a/storage/connect/tabvir.cpp b/storage/connect/tabvir.cpp index dc57c9f3538..636c896410c 100644 --- a/storage/connect/tabvir.cpp +++ b/storage/connect/tabvir.cpp @@ -289,11 +289,7 @@ void VIRCOL::ReadColumn(PGLOBAL g) { // This should never be called sprintf(g->Message, "ReadColumn: Column %s is not virtual", Name); -#if defined(USE_TRY) throw TYPE_COLBLK; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_COLBLK); -#endif // !USE_TRY } // end of ReadColumn /* ---------------------------TDBVICL class -------------------------- */ diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp index a895ffbd839..f3411062c86 100644 --- a/storage/connect/tabxml.cpp +++ b/storage/connect/tabxml.cpp @@ -1314,11 +1314,7 @@ void TDBXML::CloseDB(PGLOBAL g) Docp->CloseDoc(g, To_Xb); // This causes a crash in Diagnostics_area::set_error_status -//#if defined(USE_TRY) // throw TYPE_AM_XML; -//#else // !USE_TRY -// longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -//#endif // !USE_TRY } // endif DumpDoc } // endif Changed @@ -1641,11 +1637,7 @@ void XMLCOL::ReadColumn(PGLOBAL g) if (ValNode->GetType() != XML_ELEMENT_NODE && ValNode->GetType() != XML_ATTRIBUTE_NODE) { sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name); -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY } // endif type // Get the Xname value from the XML file @@ -1656,11 +1648,7 @@ void XMLCOL::ReadColumn(PGLOBAL g) PushWarning(g, Tdbp); break; default: -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY } // endswitch Value->SetValue_psz(Valbuf); @@ -1711,11 +1699,7 @@ void XMLCOL::WriteColumn(PGLOBAL g) /* For columns having an Xpath, the Clist must be updated. */ /*********************************************************************/ if (Tdbp->CheckRow(g, Nod || Tdbp->Colname)) -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY /*********************************************************************/ /* Null values are represented by no node. */ @@ -1787,15 +1771,7 @@ void XMLCOL::WriteColumn(PGLOBAL g) if (ColNode == NULL) { strcpy(g->Message, MSG(COL_ALLOC_ERR)); -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY -#if defined(USE_TRY) - throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY -#endif // !USE_TRY } // endif ColNode } // endif ColNode @@ -1824,11 +1800,7 @@ void XMLCOL::WriteColumn(PGLOBAL g) if (strlen(p) > (unsigned)Long) { sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long); -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY } else strcpy(Valbuf, p); @@ -1878,11 +1850,7 @@ void XMULCOL::ReadColumn(PGLOBAL g) if (ValNode->GetType() != XML_ELEMENT_NODE && ValNode->GetType() != XML_ATTRIBUTE_NODE) { sprintf(g->Message, MSG(BAD_VALNODE), ValNode->GetType(), Name); -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY } // endif type // Get the Xname value from the XML file @@ -1968,11 +1936,7 @@ void XMULCOL::WriteColumn(PGLOBAL g) /* For columns having an Xpath, the Clist must be updated. */ /*********************************************************************/ if (Tdbp->CheckRow(g, Nod)) -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY /*********************************************************************/ /* Find the column and value nodes to update or insert. */ @@ -2021,11 +1985,7 @@ void XMULCOL::WriteColumn(PGLOBAL g) if (len > 1 && !Tdbp->Xpand) { sprintf(g->Message, MSG(BAD_VAL_UPDATE), Name); -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY } else ValNode = Nlx->GetItem(g, Tdbp->Nsub, Vxnp); @@ -2067,11 +2027,7 @@ void XMULCOL::WriteColumn(PGLOBAL g) if (ColNode == NULL) { strcpy(g->Message, MSG(COL_ALLOC_ERR)); -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY } // endif ColNode } // endif ColNode @@ -2100,11 +2056,7 @@ void XMULCOL::WriteColumn(PGLOBAL g) if (strlen(p) > (unsigned)Long) { sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long); -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY } else strcpy(Valbuf, p); @@ -2136,11 +2088,7 @@ void XPOSCOL::ReadColumn(PGLOBAL g) if (Tdbp->Clist == NULL) { strcpy(g->Message, MSG(MIS_TAG_LIST)); -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY } // endif Clist if ((ValNode = Tdbp->Clist->GetItem(g, Rank, Vxnp))) { @@ -2152,11 +2100,7 @@ void XPOSCOL::ReadColumn(PGLOBAL g) PushWarning(g, Tdbp); break; default: -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY } // endswitch Value->SetValue_psz(Valbuf); @@ -2207,22 +2151,14 @@ void XPOSCOL::WriteColumn(PGLOBAL g) /* For all columns the Clist must be updated. */ /*********************************************************************/ if (Tdbp->CheckRow(g, true)) -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY /*********************************************************************/ /* Find the column and value nodes to update or insert. */ /*********************************************************************/ if (Tdbp->Clist == NULL) { strcpy(g->Message, MSG(MIS_TAG_LIST)); -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY } // endif Clist n = Tdbp->Clist->GetLength(); @@ -2247,11 +2183,7 @@ void XPOSCOL::WriteColumn(PGLOBAL g) if (strlen(p) > (unsigned)Long) { sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long); -#if defined(USE_TRY) throw TYPE_AM_XML; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_AM_XML); -#endif // !USE_TRY } else strcpy(Valbuf, p); diff --git a/storage/connect/valblk.cpp b/storage/connect/valblk.cpp index 4331962e0ad..4257aa3598d 100644 --- a/storage/connect/valblk.cpp +++ b/storage/connect/valblk.cpp @@ -138,11 +138,7 @@ PSZ VALBLK::GetCharValue(int) assert(g); sprintf(g->Message, MSG(NO_CHAR_FROM), Type); -#if defined(USE_TRY) throw Type; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], Type); -#endif // !USE_TRY return NULL; } // end of GetCharValue @@ -210,11 +206,7 @@ void VALBLK::ChkIndx(int n) if (n < 0 || n >= Nval) { PGLOBAL& g = Global; strcpy(g->Message, MSG(BAD_VALBLK_INDX)); -#if defined(USE_TRY) throw Type; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], Type); -#endif // !USE_TRY } // endif n } // end of ChkIndx @@ -224,11 +216,7 @@ void VALBLK::ChkTyp(PVAL v) if (Check && (Type != v->GetType() || Unsigned != v->IsUnsigned())) { PGLOBAL& g = Global; strcpy(g->Message, MSG(VALTYPE_NOMATCH)); -#if defined(USE_TRY) throw Type; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], Type); -#endif // !USE_TRY } // endif Type } // end of ChkTyp @@ -238,11 +226,7 @@ void VALBLK::ChkTyp(PVBLK vb) if (Check && (Type != vb->GetType() || Unsigned != vb->IsUnsigned())) { PGLOBAL& g = Global; strcpy(g->Message, MSG(VALTYPE_NOMATCH)); -#if defined(USE_TRY) throw Type; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], Type); -#endif // !USE_TRY } // endif Type } // end of ChkTyp @@ -358,11 +342,7 @@ void TYPBLK::SetValue(PSZ p, int n) if (Check) { PGLOBAL& g = Global; strcpy(g->Message, MSG(BAD_SET_STRING)); -#if defined(USE_TRY) throw Type; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], Type); -#endif // !USE_TRY } // endif Check bool minus; @@ -412,11 +392,7 @@ void TYPBLK::SetValue(PSZ p, int n) if (Check) { PGLOBAL& g = Global; strcpy(g->Message, MSG(BAD_SET_STRING)); -#if defined(USE_TRY) throw Type; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], Type); -#endif // !USE_TRY } // endif Check Typp[n] = atof(p); @@ -819,11 +795,7 @@ void CHRBLK::SetValue(char *sp, uint len, int n) if (Check && (signed)len > Long) { PGLOBAL& g = Global; strcpy(g->Message, MSG(SET_STR_TRUNC)); -#if defined(USE_TRY) throw Type; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], Type); -#endif // !USE_TRY } // endif Check #endif // _DEBUG @@ -851,11 +823,7 @@ void CHRBLK::SetValue(PVBLK pv, int n1, int n2) if (Type != pv->GetType() || Long != ((CHRBLK*)pv)->Long) { PGLOBAL& g = Global; strcpy(g->Message, MSG(BLKTYPLEN_MISM)); -#if defined(USE_TRY) throw Type; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], Type); -#endif // !USE_TRY } // endif Type if (!(b = pv->IsNull(n2))) @@ -906,11 +874,7 @@ void CHRBLK::SetValues(PVBLK pv, int k, int n) if (Type != pv->GetType() || Long != ((CHRBLK*)pv)->Long) { PGLOBAL& g = Global; strcpy(g->Message, MSG(BLKTYPLEN_MISM)); -#if defined(USE_TRY) throw Type; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], Type); -#endif // !USE_TRY } // endif Type #endif // _DEBUG char *p = ((CHRBLK*)pv)->Chrp; diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp index 3c9dcb8412c..cb24b7012b2 100644 --- a/storage/connect/value.cpp +++ b/storage/connect/value.cpp @@ -57,17 +57,10 @@ /* Check macro's. */ /***********************************************************************/ #if defined(_DEBUG) -#if defined(USE_TRY) #define CheckType(V) if (Type != V->GetType()) { \ PGLOBAL& g = Global; \ strcpy(g->Message, MSG(VALTYPE_NOMATCH)); \ throw Type; -#else // !USE_TRY -#define CheckType(V) if (Type != V->GetType()) { \ - PGLOBAL& g = Global; \ - strcpy(g->Message, MSG(VALTYPE_NOMATCH)); \ - longjmp(g->jumper[g->jump_level], Type); -#endif // !USE_TRY #else #define CheckType(V) #endif @@ -1026,19 +1019,11 @@ TYPE TYPVAL::SafeAdd(TYPE n1, TYPE n2) if ((n2 > 0) && (n < n1)) { // Overflow strcpy(g->Message, MSG(FIX_OVFLW_ADD)); -#if defined(USE_TRY) throw 138; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 138); -#endif // !USE_TRY } else if ((n2 < 0) && (n > n1)) { // Underflow strcpy(g->Message, MSG(FIX_UNFLW_ADD)); -#if defined(USE_TRY) throw 138; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 138); -#endif // !USE_TRY } // endif's n2 return n; @@ -1062,19 +1047,11 @@ TYPE TYPVAL::SafeMult(TYPE n1, TYPE n2) if (n > MinMaxVal(true)) { // Overflow strcpy(g->Message, MSG(FIX_OVFLW_TIMES)); -#if defined(USE_TRY) throw 138; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 138); -#endif // !USE_TRY } else if (n < MinMaxVal(false)) { // Underflow strcpy(g->Message, MSG(FIX_UNFLW_TIMES)); -#if defined(USE_TRY) throw 138; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 138); -#endif // !USE_TRY } // endif's n2 return (TYPE)n; @@ -1455,15 +1432,7 @@ void TYPVAL::SetValue(int n) if (k > Len) { sprintf(g->Message, MSG(VALSTR_TOO_LONG), buf, Len); -#if defined(USE_TRY) throw 138; -#else // !USE_TRY -#if defined(USE_TRY) - throw 138; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 138); -#endif // !USE_TRY -#endif // !USE_TRY } else SetValue_psz(buf); @@ -1517,11 +1486,7 @@ void TYPVAL::SetValue(longlong n) if (k > Len) { sprintf(g->Message, MSG(VALSTR_TOO_LONG), buf, Len); -#if defined(USE_TRY) throw 138; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 138); -#endif // !USE_TRY } else SetValue_psz(buf); @@ -1564,11 +1529,7 @@ void TYPVAL::SetValue(double f) if (k > Len) { sprintf(g->Message, MSG(VALSTR_TOO_LONG), buf, Len); -#if defined(USE_TRY) throw 138; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 138); -#endif // !USE_TRY } else SetValue_psz(buf); diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp index a2ddf468e5a..fde7741bfce 100755 --- a/storage/connect/xindex.cpp +++ b/storage/connect/xindex.cpp @@ -446,11 +446,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) #if 0 if (!dup->Step) { strcpy(g->Message, MSG(QUERY_CANCELLED)); -#if defined(USE_TRY) throw 99; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], 99); -#endif // !USE_TRY } // endif Step #endif // 0 diff --git a/storage/connect/xobject.cpp b/storage/connect/xobject.cpp index 7d1b6b9c992..988eeb4b136 100644 --- a/storage/connect/xobject.cpp +++ b/storage/connect/xobject.cpp @@ -84,11 +84,7 @@ double XOBJECT::GetFloatValue(void) CONSTANT::CONSTANT(PGLOBAL g, void *value, short type) { if (!(Value = AllocateValue(g, value, (int)type))) -#if defined(USE_TRY) throw TYPE_CONST; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_CONST); -#endif // !USE_TRY Constant = true; } // end of CONSTANT constructor @@ -99,11 +95,7 @@ CONSTANT::CONSTANT(PGLOBAL g, void *value, short type) CONSTANT::CONSTANT(PGLOBAL g, int n) { if (!(Value = AllocateValue(g, &n, TYPE_INT))) -#if defined(USE_TRY) throw TYPE_CONST; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_CONST); -#endif // !USE_TRY Constant = true; } // end of CONSTANT constructor @@ -125,11 +117,7 @@ void CONSTANT::Convert(PGLOBAL g, int newtype) { if (Value->GetType() != newtype) if (!(Value = AllocateValue(g, Value, newtype))) -#if defined(USE_TRY) throw TYPE_CONST; -#else // !USE_TRY - longjmp(g->jumper[g->jump_level], TYPE_CONST); -#endif // !USE_TRY } // end of Convert