mariadb/storage/connect/tabvct.cpp
Olivier Bertrand 5f64276fb2 - Fix MDEV-25863 : Replace __WIN__ by _WIN32
modified:   storage/connect/array.cpp
  modified:   storage/connect/blkfil.cpp
  modified:   storage/connect/block.h
  modified:   storage/connect/bson.cpp
  modified:   storage/connect/cmgoconn.cpp
  modified:   storage/connect/colblk.cpp
  modified:   storage/connect/domdoc.cpp
  modified:   storage/connect/filamap.cpp
  modified:   storage/connect/filamdbf.cpp
  modified:   storage/connect/filamfix.cpp
  modified:   storage/connect/filamgz.cpp
  modified:   storage/connect/filamtxt.cpp
  modified:   storage/connect/filamvct.cpp
  modified:   storage/connect/filamzip.cpp
  modified:   storage/connect/filter.cpp
  modified:   storage/connect/filter.h
  modified:   storage/connect/fmdlex.c
  modified:   storage/connect/global.h
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/javaconn.cpp
  modified:   storage/connect/javaconn.h
  modified:   storage/connect/jdbconn.cpp
  modified:   storage/connect/jmgfam.cpp
  modified:   storage/connect/json.cpp
  modified:   storage/connect/macutil.cpp
  modified:   storage/connect/macutil.h
  modified:   storage/connect/maputil.cpp
  modified:   storage/connect/mycat.cc
  modified:   storage/connect/myconn.cpp
  modified:   storage/connect/myconn.h
  modified:   storage/connect/myutil.cpp
  modified:   storage/connect/odbconn.cpp
  modified:   storage/connect/odbconn.h
  modified:   storage/connect/os.h
  modified:   storage/connect/osutil.c
  modified:   storage/connect/plgdbsem.h
  modified:   storage/connect/plgdbutl.cpp
  modified:   storage/connect/plugutil.cpp
  modified:   storage/connect/rcmsg.c
  modified:   storage/connect/reldef.cpp
  modified:   storage/connect/reldef.h
  modified:   storage/connect/tabdos.cpp
  modified:   storage/connect/tabext.cpp
  modified:   storage/connect/tabfix.cpp
  modified:   storage/connect/tabfmt.cpp
  modified:   storage/connect/tabjdbc.cpp
  modified:   storage/connect/tabmac.cpp
  modified:   storage/connect/tabmac.h
  modified:   storage/connect/tabmul.cpp
  modified:   storage/connect/tabmul.h
  modified:   storage/connect/tabmysql.cpp
  modified:   storage/connect/taboccur.cpp
  modified:   storage/connect/tabodbc.cpp
  modified:   storage/connect/tabpivot.cpp
  modified:   storage/connect/tabrest.cpp
  modified:   storage/connect/tabrest.h
  modified:   storage/connect/tabsys.cpp
  modified:   storage/connect/tabtbl.cpp
  modified:   storage/connect/tabutil.cpp
  modified:   storage/connect/tabvct.cpp
  modified:   storage/connect/tabwmi.cpp
  modified:   storage/connect/tabxcl.cpp
  modified:   storage/connect/tabxml.cpp
  modified:   storage/connect/valblk.cpp
  modified:   storage/connect/value.cpp
  modified:   storage/connect/xindex.cpp
  modified:   storage/connect/xindex.h

- Fix Date errors and SSL warnings
  modified:   storage/connect/mysql-test/connect/r/jdbc.result
  modified:   storage/connect/mysql-test/connect/r/jdbc_new.result
  modified:   storage/connect/mysql-test/connect/t/jdbc.test
  modified:   storage/connect/mysql-test/connect/t/jdbc_new.test

- Update java source files
  modified:   storage/connect/Mongo2Interface.java
  modified:   storage/connect/Mongo3Interface.java
  added:      storage/connect/Client2.java
  added:      storage/connect/Client3.java
  added:      storage/connect/TestInsert2.java
  added:      storage/connect/TestInsert3.java
2021-06-08 17:44:43 +02:00

588 lines
21 KiB
C++

/************* TabVct C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABVCT */
/* ------------- */
/* Version 3.9 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 1999-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
/* This is the TDBVCT and VCTCOL classes implementation routines. */
/* */
/* WHAT YOU NEED TO COMPILE THIS PROGRAM: */
/* -------------------------------------- */
/* */
/* REQUIRED FILES: */
/* --------------- */
/* TABVCT.C - Source code */
/* PLGDBSEM.H - DB application declaration file */
/* TABDOS.H - TABDOS classes declaration file */
/* GLOBAL.H - Global declaration file */
/* */
/* REQUIRED LIBRARIES: */
/* ------------------- */
/* Large model C library */
/* */
/* REQUIRED PROGRAMS: */
/* ------------------ */
/* IBM, Borland, GNU or Microsoft C++ Compiler and Linker */
/* */
/***********************************************************************/
/***********************************************************************/
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include "my_global.h"
#if defined(_WIN32)
#include <io.h>
#include <fcntl.h>
#if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro
#endif
//#include <windows.h>
#include <sys/stat.h>
#else
#if defined(UNIX)
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#define NO_ERROR 0
#else
#include <io.h>
#endif
#include <fcntl.h>
#endif
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
/* plgdbsem.h is header containing the DB application declarations. */
/* tabdos.h is header containing the TABDOS class declarations. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "reldef.h"
#include "osutil.h"
#include "filamvct.h"
#include "tabdos.h"
#include "tabvct.h"
#include "valblk.h"
#if defined(UNIX)
//add dummy strerror (NGC)
char *strerror(int num);
#endif // UNIX
/***********************************************************************/
/* External function. */
/***********************************************************************/
USETEMP UseTemp(void);
/***********************************************************************/
/* Char VCT column blocks are right filled with blanks (blank = true) */
/* Conversion of block values allowed conditionally for insert only. */
/***********************************************************************/
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int,
bool check = true, bool blank = true, bool un = false);
/* --------------------------- Class VCTDEF -------------------------- */
/***********************************************************************/
/* DefineAM: define specific AM block values from XDB file. */
/***********************************************************************/
bool VCTDEF::DefineAM(PGLOBAL g, LPCSTR, int poff)
{
DOSDEF::DefineAM(g, "BIN", poff);
if ((Estimate = GetIntCatInfo("Estimate", 0)))
Elemt = MY_MIN(Elemt, Estimate);
// Split treated as INT to get default value
Split = GetIntCatInfo("Split", (Estimate) ? 0 : 1);
Header = GetIntCatInfo("Header", 0);
// CONNECT must have Block/Last info for VEC tables
if (Estimate && !Split && !Header) {
char *fn = GetStringCatInfo(g, "Filename", "?");
// No separate header file for urbi tables
Header = (*fn == '?') ? 3 : 2;
} // endif Estimate
Recfm = RECFM_VCT;
// poff is no more in use; This will have to be revisited
#if 0
// For packed files the logical record length is calculated in poff
if (poff != Lrecl) {
Lrecl = poff;
SetIntCatInfo("Lrecl", poff);
} // endif poff
#endif // 0
Padded = false;
Blksize = 0;
return false;
} // end of DefineAM
#if 0
/***********************************************************************/
/* Erase: This was made a separate routine because a strange thing */
/* happened when DeleteTablefile was defined for the VCTDEF class: */
/* when called from Catalog, the DOSDEF routine was still called even */
/* for a VCTDEF class. It also minimizes the specific code. */
/***********************************************************************/
bool VCTDEF::Erase(char *filename)
{
bool rc = false;
if (Split) {
char fpat[_MAX_PATH];
int i;
PCOLDEF cdp;
MakeFnPattern(fpat);
for (i = 1, cdp = To_Cols; cdp; i++, cdp = cdp->GetNext()) {
sprintf(filename, fpat, i);
//#if defined(_WIN32)
// rc |= !DeleteFile(filename);
//#else // UNIX
rc |= remove(filename);
//#endif // UNIX
} // endfor cdp
} else {
rc = DOSDEF::Erase(filename);
if (Estimate && Header == 2) {
PlugSetPath(filename, Fn, GetPath());
strcat(PlugRemoveType(filename, filename), ".blk");
rc |= remove(filename);
} // endif Header
} // endif Split
return rc; // Return true if error
} // end of Erase
#endif // 0
/***********************************************************************/
/* Prepare the column file name pattern for a split table. */
/* This function returns the number of columns of the table. */
/***********************************************************************/
int VCTDEF::MakeFnPattern(char *fpat)
{
char pat[16];
#if defined(_WIN32)
char drive[_MAX_DRIVE];
#else
char *drive = NULL;
#endif
char direc[_MAX_DIR];
char fname[_MAX_FNAME];
char ftype[_MAX_EXT]; // File extention
int n, m, ncol = 0;
PCOLDEF cdp;
for (cdp = To_Cols; cdp; cdp = cdp->GetNext())
ncol++;
for (n = 1, m = ncol; m /= 10; n++) ;
sprintf(pat, "%%0%dd", n);
_splitpath(Fn, drive, direc, fname, ftype);
strcat(fname, pat);
_makepath(fpat, drive, direc, fname, ftype);
PlugSetPath(fpat, fpat, GetPath());
return ncol;
} // end of MakeFnPattern
/***********************************************************************/
/* GetTable: makes a new Table Description Block. */
/***********************************************************************/
PTDB VCTDEF::GetTable(PGLOBAL g, MODE mode)
{
/*********************************************************************/
/* Allocate a TDB of the proper type. */
/* Column blocks will be allocated only when needed. */
/*********************************************************************/
// Mapping not used for insert (except for true VEC not split tables)
// or when UseTemp is forced
bool map = Mapped && (Estimate || mode != MODE_INSERT) &&
!(UseTemp() == TMP_FORCE &&
(mode == MODE_UPDATE || mode == MODE_DELETE));
PTXF txfp;
PTDB tdbp;
if (Multiple) {
strcpy(g->Message, MSG(NO_MUL_VCT));
return NULL;
} // endif Multiple
if (Split) {
if (map)
txfp = new(g) VMPFAM(this);
else
txfp = new(g) VECFAM(this);
} else if (Huge)
txfp = new(g) BGVFAM(this);
else if (map)
txfp = new(g) VCMFAM(this);
else
txfp = new(g) VCTFAM(this);
tdbp = new(g) TDBVCT(this, txfp);
/*********************************************************************/
/* For block tables, get eventually saved optimization values. */
/*********************************************************************/
if (mode != MODE_INSERT)
if (tdbp->GetBlockValues(g))
PushWarning(g, tdbp);
// return NULL; // causes a crash when deleting index
return tdbp;
} // end of GetTable
/* --------------------------- Class TDBVCT -------------------------- */
/***********************************************************************/
/* Implementation of the TDBVCT class. */
/***********************************************************************/
TDBVCT::TDBVCT(PVCTDEF tdp, PTXF txfp) : TDBFIX(tdp, txfp)
{
To_SetCols = NULL;
} // end of TDBVCT standard constructor
TDBVCT::TDBVCT(PGLOBAL g, PTDBVCT tdbp) : TDBFIX(g, tdbp)
{
To_SetCols = tdbp->To_SetCols;
} // end of TDBVCT copy constructor
// Method
PTDB TDBVCT::Clone(PTABS t)
{
PTDB tp;
PVCTCOL cp1, cp2;
PGLOBAL g = t->G; // Is this really useful ???
tp = new(g) TDBVCT(g, this);
for (cp1 = (PVCTCOL)Columns; cp1; cp1 = (PVCTCOL)cp1->Next) {
cp2 = new(g) VCTCOL(cp1, tp); // Make a copy
NewPointer(t, cp1, cp2);
} // endfor cp1
return tp;
} // end of Clone
/***********************************************************************/
/* Allocate VCT column description block. */
/***********************************************************************/
PCOL TDBVCT::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
{
return new(g) VCTCOL(g, cdp, this, cprec, n);
} // end of MakeCol
/***********************************************************************/
/* VEC tables are not ready yet to use temporary files. */
/***********************************************************************/
bool TDBVCT::IsUsingTemp(PGLOBAL)
{
// For developpers
return (UseTemp() == TMP_TEST);
} // end of IsUsingTemp
/***********************************************************************/
/* VCT Access Method opening routine. */
/* New method now that this routine is called recursively (last table */
/* first in reverse order): index blocks are immediately linked to */
/* join block of next table if it exists or else are discarted. */
/***********************************************************************/
bool TDBVCT::OpenDB(PGLOBAL g)
{
if (trace(1))
htrc("VCT OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
this, Tdb_No, Use, To_Key_Col, Mode);
if (Use == USE_OPEN) {
/*******************************************************************/
/* Table already open, just replace it at its beginning. */
/*******************************************************************/
if (To_Kindex)
// Table is to be accessed through a sorted index table
To_Kindex->Reset();
Txfp->Rewind();
ResetBlockFilter(g);
return false;
} // endif Use
/*********************************************************************/
/* Delete all is not handled using file mapping. */
/*********************************************************************/
if (Mode == MODE_DELETE && !Next && Txfp->GetAmType() == TYPE_AM_VMP) {
if (IsSplit())
Txfp = new(g) VECFAM((PVCTDEF)To_Def);
else
Txfp = new(g) VCTFAM((PVCTDEF)To_Def);
Txfp->SetTdbp(this);
} // endif Mode
/*********************************************************************/
/* Open according to input/output mode required and */
/* allocate the block buffers for columns used in the query. */
/*********************************************************************/
if (Txfp->OpenTableFile(g))
return true;
// This was not done in previous version
Use = USE_OPEN; // Do it now in case we are recursively called
/*********************************************************************/
/* Allocate the block filter tree if evaluation is possible. */
/*********************************************************************/
To_BlkFil = InitBlockFilter(g, To_Filter);
/*********************************************************************/
/* Reset buffer access according to indexing and to mode. */
/*********************************************************************/
Txfp->ResetBuffer(g);
return false;
} // end of OpenDB
/***********************************************************************/
/* Data Base read routine for VCT access method. */
/* This routine just set the new block index and record position. */
/* For index accessed tables the physical reading is deferred to the */
/* ReadColumn routine so only really used column are physically read. */
/***********************************************************************/
int TDBVCT::ReadDB(PGLOBAL g)
{
if (trace(1))
htrc("VCT ReadDB: R%d Mode=%d CurBlk=%d CurNum=%d key=%p link=%p Kindex=%p\n",
GetTdb_No(), Mode, Txfp->CurBlk, Txfp->CurNum,
To_Key_Col, To_Link, To_Kindex);
if (To_Kindex) {
/*******************************************************************/
/* Reading is by an index table. */
/*******************************************************************/
int recpos = To_Kindex->Fetch(g);
switch (recpos) {
case -1: // End of file reached
return RC_EF;
case -2: // No match for join
return RC_NF;
case -3: // Same record as last non null one
// num_there++;
return RC_OK;
default:
/***************************************************************/
/* Set the file position according to record to read. */
/***************************************************************/
if (SetRecpos(g, recpos))
return RC_FX;
} // endswitch recpos
} // endif To_Kindex
return ReadBuffer(g);
} // end of ReadDB
/***********************************************************************/
/* Data Base close routine for VEC access method. */
/***********************************************************************/
void TDBVCT::CloseDB(PGLOBAL g)
{
if (To_Kindex) {
To_Kindex->Close();
To_Kindex = NULL;
} // endif
Txfp->CloseTableFile(g, false);
} // end of CloseDB
// ------------------------ VCTCOL functions ----------------------------
/***********************************************************************/
/* VCTCOL public constructor. */
/***********************************************************************/
VCTCOL::VCTCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
: DOSCOL(g, cdp, tdbp, cprec, i, "VCT")
{
Deplac = cdp->GetPoff();
Clen = cdp->GetClen(); // Length of the field in the file
ColBlk = -1;
ColPos = -1;
Blk = NULL;
Modif = 0;
} // end of VCTCOL constructor
/***********************************************************************/
/* VCTCOL constructor used for copying columns. */
/* tdbp is the pointer to the new table descriptor. */
/***********************************************************************/
VCTCOL::VCTCOL(VCTCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp)
{
ColBlk = col1->ColBlk;
ColPos = col1->ColPos;
Blk = col1->Blk; // Should be NULL when copying ????
Modif = col1->Modif; // Should be 0 ????
} // end of VCTCOL copy constructor
/***********************************************************************/
/* SetBuffer: allocate and set the buffers needed for write operation.*/
/***********************************************************************/
bool VCTCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
{
// Eventual conversion will be done when setting ValBlk from Value.
Value = value; // Force To_Val == Value
if (DOSCOL::SetBuffer(g, value, ok, check))
return true;
if (To_Tdb->GetMode() != MODE_INSERT) {
// Allocate the block buffer to use for read/writing except when
// updating a mapped VCT table and Ok is true.
PTDBVCT tdbp = (PTDBVCT)To_Tdb;
if (tdbp->Txfp->GetAmType() == TYPE_AM_VMP && ok) {
Blk = AllocValBlock(g, (void*)1, Buf_Type, tdbp->Txfp->Nrec,
Format.Length, Format.Prec, check, true, Unsigned);
Status |= BUF_MAPPED; // Will point into mapped file
} else
Blk = AllocValBlock(g, NULL, Buf_Type, tdbp->Txfp->Nrec,
Format.Length, Format.Prec, check, true, Unsigned);
} // endif Mode
return false;
} // end of SetBuffer
/***********************************************************************/
/* ReadBlock: Indicate it is Ok to make updates. */
/***********************************************************************/
void VCTCOL::SetOk(void)
{
if (((PTDBVCT)To_Tdb)->Txfp->GetAmType() == TYPE_AM_VMP)
Status |= BUF_MAPPED;
Status |= BUF_EMPTY;
Modif = 0;
} // end of SetOk
/***********************************************************************/
/* ReadBlock: Read column values from current block. */
/***********************************************************************/
void VCTCOL::ReadBlock(PGLOBAL g)
{
PVCTFAM txfp = (PVCTFAM)((PTDBVCT)To_Tdb)->Txfp;
#if defined(_DEBUG)
if (!Blk) {
strcpy(g->Message, MSG(TO_BLK_IS_NULL));
throw 58;
} // endif
#endif
/*********************************************************************/
/* Read column block according to used access method. */
/*********************************************************************/
if (txfp->ReadBlock(g, this))
throw 6;
ColBlk = txfp->CurBlk;
ColPos = -1; // Any invalid position
} // end of ReadBlock
/***********************************************************************/
/* WriteBlock: Write back current column values for one block. */
/* Note: the test of Status is meant to prevent physical writing of */
/* the block during the checking loop in mode Update. It is set to */
/* BUF_EMPTY when reopening the table between the two loops. */
/***********************************************************************/
void VCTCOL::WriteBlock(PGLOBAL g)
{
if (Modif && (Status & BUF_EMPTY)) {
PVCTFAM txfp = (PVCTFAM)((PTDBVCT)To_Tdb)->Txfp;
#if defined(_DEBUG)
if (!Blk) {
strcpy(g->Message, MSG(BLK_IS_NULL));
throw 56;
} // endif
#endif
/*******************************************************************/
/* Write column block according to used access method. */
/*******************************************************************/
if (txfp->WriteBlock(g, this))
throw 6;
Modif = 0;
} // endif Modif
} // end of WriteBlock
/***********************************************************************/
/* ReadColumn: what this routine does is to check whether a column */
/* block has been read from the file, then to extract from it the */
/* field corresponding to this column and convert it to buffer type. */
/***********************************************************************/
void VCTCOL::ReadColumn(PGLOBAL g)
{
PTXF txfp = ((PTDBVCT)To_Tdb)->Txfp;
#if defined(_DEBUG)
assert (!To_Kcol);
#endif
if (trace(2))
htrc("VCT ReadColumn: col %s R%d coluse=%.4X status=%.4X buf_type=%d\n",
Name, To_Tdb->GetTdb_No(), ColUse, Status, Buf_Type);
if (ColBlk != txfp->CurBlk)
ReadBlock(g);
else if (ColPos == txfp->CurNum)
return; // Value is already there
//ColBlk = txfp->CurBlk; done in ReadBlock
ColPos = txfp->CurNum;
Value->SetValue_pvblk(Blk, ColPos);
// Set null when applicable
if (Nullable)
Value->SetNull(Value->IsZero());
} // end of ReadColumn
/***********************************************************************/
/* WriteColumn: Modifications are written back into column buffer. */
/* On each change of block the buffer is written back to file and */
/* in mode Insert the buffer is filled with the block to update. */
/***********************************************************************/
void VCTCOL::WriteColumn(PGLOBAL)
{
PTXF txfp = ((PTDBVCT)To_Tdb)->Txfp;;
if (trace(2))
htrc("VCT WriteColumn: col %s R%d coluse=%.4X status=%.4X buf_type=%d\n",
Name, To_Tdb->GetTdb_No(), ColUse, Status, Buf_Type);
ColBlk = txfp->CurBlk;
ColPos = txfp->CurNum;
Blk->SetValue(Value, ColPos);
Modif++;
} // end of WriteColumn
/* ------------------------ End of TabVct ---------------------------- */