From 99d95c8a2fec8037738a4c700a163b206f9ab4c8 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 10 May 2013 20:22:21 +0200 Subject: [PATCH] - Added table type PIVOT modified: storage/connect/filamdbf.cpp storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/mycat.cc storage/connect/myconn.cpp storage/connect/odbconn.cpp storage/connect/plgcnx.h storage/connect/plgdbsem.h storage/connect/plgdbutl.cpp storage/connect/tabfmt.cpp storage/connect/tabpivot.cpp storage/connect/tabpivot.h storage/connect/tabutil.cpp storage/connect/tabwmi.cpp storage/connect/tabxcl.cpp storage/connect/value.cpp storage/connect/value.h --- storage/connect/filamdbf.cpp | 7 +- storage/connect/ha_connect.cc | 10 +- storage/connect/ha_connect.h | 2 + storage/connect/mycat.cc | 9 +- storage/connect/myconn.cpp | 10 +- storage/connect/odbconn.cpp | 28 +- storage/connect/plgcnx.h | 11 - storage/connect/plgdbsem.h | 3 +- storage/connect/plgdbutl.cpp | 3 +- storage/connect/tabfmt.cpp | 6 +- storage/connect/tabpivot.cpp | 596 ++++++++++++++++++++-------------- storage/connect/tabpivot.h | 107 +++--- storage/connect/tabutil.cpp | 9 +- storage/connect/tabwmi.cpp | 6 +- storage/connect/tabxcl.cpp | 1 - storage/connect/value.cpp | 49 +-- storage/connect/value.h | 5 +- 17 files changed, 444 insertions(+), 418 deletions(-) diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp index 3575a6b422a..0a67195b200 100644 --- a/storage/connect/filamdbf.cpp +++ b/storage/connect/filamdbf.cpp @@ -178,15 +178,13 @@ static int dbfhead(PGLOBAL g, FILE *file, PSZ fn, DBFHEADER *buf) /****************************************************************************/ PQRYRES DBFColumns(PGLOBAL g, const char *fn, BOOL info) { - static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, - DB_INT, DB_INT, DB_SHORT}; static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_SHORT}; static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC, FLD_LENGTH, FLD_SCALE}; static unsigned int length[] = {11, 6, 8, 10, 10, 6}; char buf[2], filename[_MAX_PATH]; - int ncol = sizeof(dbtype) / sizeof(int); + int ncol = sizeof(buftyp) / sizeof(int); int rc, type, len, field, fields; BOOL bad; DBFHEADER mainhead; @@ -228,8 +226,7 @@ PQRYRES DBFColumns(PGLOBAL g, const char *fn, BOOL info) fields = 0; qrp = PlgAllocResult(g, ncol, fields, IDS_COLUMNS + 3, - dbtype, buftyp, fldtyp, length, true, false); -//qrp->Info = info || (rc == RC_INFO); + buftyp, fldtyp, length, true, false); if (info) return qrp; diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 2eefd1e20d2..298fb71b334 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -207,6 +207,8 @@ ha_create_table_option connect_table_option_list[]= HA_TOPTION_STRING("MODULE", module), HA_TOPTION_STRING("SUBTYPE", subtype), HA_TOPTION_STRING("CATFUNC", catfunc), + HA_TOPTION_STRING("SRCDEF", srcdef), + HA_TOPTION_STRING("COLIST", colist), HA_TOPTION_STRING("OPTION_LIST", oplist), HA_TOPTION_STRING("DATA_CHARSET", data_charset), HA_TOPTION_NUMBER("LRECL", lrecl, 0, 0, INT_MAX32, 1), @@ -590,7 +592,7 @@ static char *GetListOption(PGLOBAL g, const char *opname, } else { if (pn) { - n= pn - pk; + n= min(pn - pk, 15); memcpy(key, pk, n); key[n]= 0; } else @@ -655,6 +657,10 @@ char *ha_connect::GetStringOption(char *opname, char *sdef) opval= (char*)options->subtype; else if (!stricmp(opname, "Catfunc")) opval= (char*)options->catfunc; + else if (!stricmp(opname, "Srcdef")) + opval= (char*)options->srcdef; + else if (!stricmp(opname, "Colist")) + opval= (char*)options->colist; else if (!stricmp(opname, "Data_charset")) opval= (char*)options->data_charset; @@ -2667,7 +2673,6 @@ bool ha_connect::check_privileges(THD *thd, PTOS options) case TAB_JCT: case TAB_DMY: case TAB_NIY: - case TAB_PIVOT: my_printf_error(ER_UNKNOWN_ERROR, "Unsupported table type %s", MYF(0), options->type); return true; @@ -2706,6 +2711,7 @@ bool ha_connect::check_privileges(THD *thd, PTOS options) case TAB_XCL: case TAB_PRX: case TAB_OCCUR: + case TAB_PIVOT: return false; } diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h index 53339d168d0..0d6354ca078 100644 --- a/storage/connect/ha_connect.h +++ b/storage/connect/ha_connect.h @@ -83,6 +83,8 @@ struct ha_table_option_struct { const char *module; const char *subtype; const char *catfunc; + const char *srcdef; + const char *colist; const char *oplist; const char *data_charset; ulonglong lrecl; diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc index badcdcb9514..7b7f79d7b58 100644 --- a/storage/connect/mycat.cc +++ b/storage/connect/mycat.cc @@ -132,6 +132,9 @@ TABTYPE GetTypeID(const char *type) : (!stricmp(type, "OCCUR")) ? TAB_OCCUR : (!stricmp(type, "CATLG")) ? TAB_PRX // Legacy : (!stricmp(type, "PROXY")) ? TAB_PRX +#ifdef PIVOT_SUPPORT + : (!stricmp(type, "PIVOT")) ? TAB_PIVOT +#endif : (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY; } // end of GetTypeID @@ -650,9 +653,9 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am) #if defined(MYSQL_SUPPORT) case TAB_MYSQL: tdp= new(g) MYSQLDEF; break; #endif // MYSQL_SUPPORT -//#if defined(PIVOT_SUPPORT) -// case TAB_PIVOT: tdp= new(g) PIVOTDEF; break; -//#endif // PIVOT_SUPPORT +#if defined(PIVOT_SUPPORT) + case TAB_PIVOT: tdp= new(g) PIVOTDEF; break; +#endif // PIVOT_SUPPORT default: sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name); } // endswitch diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index 53a2496b197..fab2af54aa7 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -74,10 +74,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, const char *table, const char *colpat, int port, bool key, bool info) { - static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, DB_INT, - DB_CHAR, DB_SHORT, DB_SHORT, DB_SHORT, - DB_CHAR, DB_CHAR, DB_CHAR}; - static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, + static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_STRING, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING, TYPE_STRING, TYPE_STRING}; static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC, @@ -85,7 +82,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, FLD_REM, FLD_NO, FLD_CHARSET}; static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32}; char *fld, *fmt, cmd[128]; - int i, n, nf, ncol = sizeof(dbtype) / sizeof(int); + int i, n, nf, ncol = sizeof(buftyp) / sizeof(int); int len, type, prec, rc, k = 0; PQRYRES qrp; PCOLRES crp; @@ -134,7 +131,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db, /* Allocate the structures used to refer to the result set. */ /**********************************************************************/ qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3, - dbtype, buftyp, fldtyp, length, true, true); + buftyp, fldtyp, length, true, true); // Some columns must be renamed for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next) @@ -665,7 +662,6 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb) crp->Prec = fld->decimals; crp->Length = fld->max_length; crp->Clen = GetTypeSize(crp->Type, crp->Length); - crp->DBtype = GetDBType((int)crp->Type); if (!(crp->Kdata = AllocValBlock(g, NULL, crp->Type, m_Rows, crp->Clen, 0, FALSE, TRUE))) { diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index 6de2acef391..e32e666e1fe 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -230,11 +230,7 @@ void ResetNullValues(CATPARM *cap) PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *table, char *colpat, bool info) { - static int dbtype[] = {DB_CHAR, DB_CHAR, DB_CHAR, - DB_CHAR, DB_SHORT, DB_CHAR, - DB_INT, DB_INT, DB_SHORT, - DB_SHORT, DB_SHORT, DB_CHAR}; - static int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, + static int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING}; @@ -285,7 +281,7 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *table, /* Allocate the structures used to refer to the result set. */ /************************************************************************/ qrp = PlgAllocResult(g, ncol, maxres, IDS_COLUMNS, - dbtype, buftyp, fldtyp, length, true, true); + buftyp, fldtyp, length, true, true); if (info) // Info table return qrp; @@ -396,7 +392,6 @@ PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info) /*************************************************************************/ PQRYRES ODBCDataSources(PGLOBAL g, bool info) { - static int dbtype[] = {DB_CHAR, DB_CHAR}; static int buftyp[] = {TYPE_STRING, TYPE_STRING}; static XFLD fldtyp[] = {FLD_NAME, FLD_REM}; static unsigned int length[] = {0, 256}; @@ -425,7 +420,7 @@ PQRYRES ODBCDataSources(PGLOBAL g, bool info) /* Allocate the structures used to refer to the result set. */ /************************************************************************/ qrp = PlgAllocResult(g, ncol, maxres, IDS_DSRC, - dbtype, buftyp, fldtyp, length, true, true); + buftyp, fldtyp, length, true, true); /************************************************************************/ /* Now get the results into blocks. */ @@ -446,7 +441,6 @@ PQRYRES ODBCDataSources(PGLOBAL g, bool info) /*************************************************************************/ PQRYRES ODBCDrivers(PGLOBAL g, bool info) { - static int dbtype[] = {DB_CHAR, DB_CHAR}; static int buftyp[] = {TYPE_STRING, TYPE_STRING}; static XFLD fldtyp[] = {FLD_NAME, FLD_REM}; static unsigned int length[] = {128, 256}; @@ -471,7 +465,7 @@ PQRYRES ODBCDrivers(PGLOBAL g, bool info) /* Allocate the structures used to refer to the result set. */ /************************************************************************/ qrp = PlgAllocResult(g, ncol, maxres, IDS_DRIVER, - dbtype, buftyp, fldtyp, length, true, true); + buftyp, fldtyp, length, true, true); /************************************************************************/ /* Now get the results into blocks. */ @@ -492,8 +486,7 @@ PQRYRES ODBCDrivers(PGLOBAL g, bool info) /***********************************************************************/ PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *tabpat, bool info) { - static int dbtype[] = {DB_CHAR, DB_CHAR, DB_CHAR, DB_CHAR, DB_CHAR}; - static int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, + static int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING}; static XFLD fldtyp[] = {FLD_QUALIF, FLD_OWNER, FLD_NAME, FLD_TYPE, FLD_REM}; @@ -536,7 +529,7 @@ PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *tabpat, bool info) /************************************************************************/ /* Allocate the structures used to refer to the result set. */ /************************************************************************/ - qrp = PlgAllocResult(g, ncol, maxres, IDS_TABLES, dbtype, buftyp, + qrp = PlgAllocResult(g, ncol, maxres, IDS_TABLES, buftyp, fldtyp, length, true, true); if (info) @@ -579,8 +572,6 @@ PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *tabpat, bool info) /**************************************************************************/ PQRYRES ODBCPrimaryKeys(PGLOBAL g, ODBConn *op, char *dsn, char *table) { - static int dbtype[] = {DB_CHAR, DB_CHAR, DB_CHAR, - DB_CHAR, DB_SHORT, DB_CHAR}; static int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_SHORT, TYPE_STRING}; static unsigned int length[] = {0, 0, 0, 0, 6, 128}; @@ -623,7 +614,7 @@ PQRYRES ODBCPrimaryKeys(PGLOBAL g, ODBConn *op, char *dsn, char *table) /* Allocate the structure used to refer to the result set. */ /************************************************************************/ qrp = PlgAllocResult(g, ncol, maxres, IDS_PKEY, - dbtype, buftyp, NULL, length, true, true); + buftyp, NULL, length, true, true); if (trace) htrc("Getting pkey results ncol=%d\n", qrp->Nbcol); @@ -662,9 +653,6 @@ PQRYRES ODBCPrimaryKeys(PGLOBAL g, ODBConn *op, char *dsn, char *table) PQRYRES ODBCStatistics(PGLOBAL g, ODBConn *op, char *dsn, char *pat, int un, int acc) { - static int dbtype[] = {DB_CHAR, DB_CHAR, DB_CHAR, DB_SHORT, DB_CHAR, - DB_CHAR, DB_SHORT, DB_SHORT, DB_CHAR, DB_CHAR, - DB_INT, DB_INT, DB_CHAR}; static int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_STRING, TYPE_SHORT, TYPE_SHORT, TYPE_STRING, @@ -708,7 +696,7 @@ PQRYRES ODBCStatistics(PGLOBAL g, ODBConn *op, char *dsn, char *pat, /* Allocate the structure used to refer to the result set. */ /************************************************************************/ qrp = PlgAllocResult(g, ncol, maxres, IDS_STAT, - dbtype, buftyp, NULL, length, true, true); + buftyp, NULL, length, true, true); if (trace) htrc("Getting stat results ncol=%d\n", qrp->Nbcol); diff --git a/storage/connect/plgcnx.h b/storage/connect/plgcnx.h index 33b0ba64edc..7ce72b45268 100644 --- a/storage/connect/plgcnx.h +++ b/storage/connect/plgcnx.h @@ -49,17 +49,6 @@ enum RCODE {RC_OK = 0, /* No error return code */ RC_INFO = 4}; /* Success with info */ #endif // !RC_OK_DEFINED -/**************************************************************************/ -/* Data types. */ -/**************************************************************************/ -enum XDBTYPE {DB_ERROR = 0, /* Unknown or wrong type */ - DB_STRING = 1, /* Null terminated string */ - DB_CHAR = 2, /* Character array */ - DB_SHORT = 3, /* Used by some catalog functions */ - DB_INT = 4, /* Long integer array */ - DB_DOUBLE = 5, /* Double float array */ - DB_DATE = 6}; /* Datetime value array */ - /**************************************************************************/ /* Index of info values within the info int integer array. */ /**************************************************************************/ diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h index a1eaf97bd10..5eb55c4a29b 100644 --- a/storage/connect/plgdbsem.h +++ b/storage/connect/plgdbsem.h @@ -513,7 +513,6 @@ typedef struct _colres { PVBLK Kdata; /* Column block of values */ char *Nulls; /* Column null value array */ int Type; /* Internal type */ - int DBtype; /* Data type */ int Datasize; /* Overall data size */ int Ncol; /* Column number */ int Clen; /* Data individual internal size */ @@ -545,7 +544,7 @@ int ExtractDate(char *, PDTP, int, int val[6]); /* Allocate the result structure that will contain result data. */ /**************************************************************************/ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids, - int *dbtype, int *buftyp, XFLD *fldtyp, + int *buftyp, XFLD *fldtyp, unsigned int *length, bool blank, bool nonull); /***********************************************************************/ diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp index 6d1e502945b..32ee105c19c 100644 --- a/storage/connect/plgdbutl.cpp +++ b/storage/connect/plgdbutl.cpp @@ -270,7 +270,7 @@ void ptrc(char const *fmt, ...) /* Allocate the result structure that will contain result data. */ /**************************************************************************/ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids, - int *dbtype, int *buftyp, XFLD *fldtyp, + int *buftyp, XFLD *fldtyp, unsigned int *length, bool blank, bool nonull) { char cname[NAM_LEN+1]; @@ -304,7 +304,6 @@ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids, crp->Length = length[i]; crp->Clen = GetTypeSize(crp->Type, length[i]); crp->Prec = 0; - crp->DBtype = dbtype[i]; if (ids > 0) { #if defined(XMSG) diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp index 51631107f6e..aaa32a57f04 100644 --- a/storage/connect/tabfmt.cpp +++ b/storage/connect/tabfmt.cpp @@ -78,8 +78,6 @@ extern "C" int trace; PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q, int hdr, int mxr, bool info) { - static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, - DB_INT, DB_INT, DB_SHORT}; static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_SHORT}; static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, @@ -87,7 +85,7 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q, static unsigned int length[] = {6, 6, 8, 10, 10, 6}; char *p, *colname[MAXCOL], dechar, filename[_MAX_PATH], buf[4096]; int i, imax, hmax, n, nerr, phase, blank, digit, dec, type; - int ncol = sizeof(dbtype) / sizeof(int); + int ncol = sizeof(buftyp) / sizeof(int); int num_read = 0, num_max = 10000000; // Statistics int len[MAXCOL], typ[MAXCOL], prc[MAXCOL]; FILE *infile; @@ -341,7 +339,7 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q, /* Allocate the structures used to refer to the result set. */ /*********************************************************************/ qrp = PlgAllocResult(g, ncol, imax, IDS_COLUMNS + 3, - dbtype, buftyp, fldtyp, length, true, false); + buftyp, fldtyp, length, true, false); qrp->Nblin = imax; if (info) diff --git a/storage/connect/tabpivot.cpp b/storage/connect/tabpivot.cpp index fccd8338d8a..429bb88e0fc 100644 --- a/storage/connect/tabpivot.cpp +++ b/storage/connect/tabpivot.cpp @@ -1,11 +1,11 @@ /************ TabPivot C++ Program Source Code File (.CPP) *************/ /* PROGRAM NAME: TABPIVOT */ /* ------------- */ -/* Version 1.3 */ +/* Version 1.4 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2005-2012 */ +/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -41,10 +41,13 @@ #include "global.h" #include "plgdbsem.h" #include "xtable.h" -#include "xindex.h" +//#include "xindex.h" +#include "tabcol.h" #include "colblk.h" -#include "tabmysql.h" +//#include "tabmysql.h" +#include "myconn.h" #include "csort.h" +#include "tabutil.h" #include "tabpivot.h" #include "valblk.h" #include "ha_connect.h" @@ -52,111 +55,7 @@ extern "C" int trace; -/* --------------- Implementation of the PIVOT classes --------------- */ - -/***********************************************************************/ -/* DefineAM: define specific AM block values from PIVOT table. */ -/***********************************************************************/ -bool PIVOTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) - { - char *p1, *p2; - PHC hc = ((MYCAT*)Cat)->GetHandler(); - - Host = Cat->GetStringCatInfo(g, Name, "Host", "localhost"); - User = Cat->GetStringCatInfo(g, Name, "User", "root"); - Pwd = Cat->GetStringCatInfo(g, Name, "Password", NULL); - DB = Cat->GetStringCatInfo(g, Name, "Database", (PSZ)hc->GetDBName(NULL)); - Tabsrc = Cat->GetStringCatInfo(g, Name, "SrcDef", NULL); - Tabname = Cat->GetStringCatInfo(g, Name, "Name", NULL); - Picol = Cat->GetStringCatInfo(g, Name, "PivotCol", NULL); - Fncol = Cat->GetStringCatInfo(g, Name, "FncCol", NULL); - - // If fncol is like avg(colname), separate Fncol and Function - if (Fncol && (p1 = strchr(Fncol, '(')) && (p2 = strchr(p1, ')')) && - (*Fncol != '"') && (!*(p2+1))) { - *p1++ = '\0'; *p2 = '\0'; - Function = Fncol; - Fncol = p1; - } else - Function = Cat->GetStringCatInfo(g, Name, "Function", "SUM"); - - GBdone = Cat->GetIntCatInfo(Name, "Groupby", 0) ? TRUE : FALSE; - Port = Cat->GetIntCatInfo(Name, "Port", 3306); - Desc = (*Tabname) ? Tabname : Tabsrc; - return FALSE; - } // end of DefineAM - -/***********************************************************************/ -/* GetTable: makes a new TDB of the proper type. */ -/***********************************************************************/ -PTDB PIVOTDEF::GetTable(PGLOBAL g, MODE m) - { - return new(g) TDBPIVOT(this); - } // end of GetTable - -/* ------------------------------------------------------------------- */ - -/***********************************************************************/ -/* Implementation of the TDBPIVOT class. */ -/***********************************************************************/ -TDBPIVOT::TDBPIVOT(PPIVOTDEF tdp) : TDBASE(tdp), CSORT(FALSE) - { - Tqrp = NULL; - Host = tdp->Host; - Database = tdp->DB; - User = tdp->User; - Pwd = tdp->Pwd; - Port = tdp->Port; - Qryp = NULL; - Tabname = tdp->Tabname; // Name of source table - Tabsrc = tdp->Tabsrc; // SQL description of source table - Picol = tdp->Picol; // Pivot column name - Fncol = tdp->Fncol; // Function column name - Function = tdp->Function; // Aggregate function name - Xcolp = NULL; // To the FNCCOL column -//Xresp = NULL; // To the pivot result column -//Rblkp = NULL; // The value block of the pivot column - Fcolp = NULL; // To the function column - GBdone = tdp->GBdone; - Mult = -1; // Estimated table size - N = 0; // The current table index - M = 0; // The occurence rank - FileStatus = 0; // Logical End-of-File - RowFlag = 0; // 0: Ok, 1: Same, 2: Skip - } // end of TDBPIVOT constructor - #if 0 -TDBPIVOT::TDBPIVOT(PTDBPIVOT tdbp) : TDBASE(tdbp), CSORT(FALSE) - { - Tdbp = tdbp->Tdbp; - Sqlp = tdbp->Sqlp; - Qryp = tdbp->Qryp; - Tabname = tdbp->Tabname; - Tabsrc = tdbp->Tabsrc; - Picol = tdbp->Picol; - Fncol = tdbp->Fncol; - Function = tdbp->Function; - Xcolp = tdbp->Xcolp; - Xresp = tdbp->Xresp; - Rblkp = tdbp->Rblkp; - Fcolp = tdbp->Fcolp; - Mult = tdbp->Mult; - N = tdbp->N; - M = tdbp->M; - FileStatus = tdbp->FileStatus; - RowFlag = tdbp->RowFlag; - } // end of TDBPIVOT copy constructor - -// Is this really useful ??? -PTDB TDBPIVOT::CopyOne(PTABS t) - { - PTDB tp = new(t->G) TDBPIVOT(this); - - tp->SetColumns(Columns); - return tp; - } // end of CopyOne -#endif // 0 - /***********************************************************************/ /* Prepare the source table Query. */ /***********************************************************************/ @@ -165,14 +64,17 @@ PQRYRES TDBPIVOT::GetSourceTable(PGLOBAL g) if (Qryp) return Qryp; // Already done - if (!Tabsrc && Tabname) { + if (Tabname) { char *def, *colist; size_t len = 0; PCOL colp; PDBUSER dup = (PDBUSER)g->Activityp->Aptr; + if (InitTable(g)) + return NULL; + // Evaluate the length of the column list - for (colp = Columns; colp; colp = colp->GetNext()) + for (colp = Tdbp->Columns; colp; colp = colp->GetNext()) len += (strlen(colp->GetName()) + 2); *(colist = (char*)PlugSubAlloc(g, NULL, len)) = 0; @@ -182,7 +84,7 @@ PQRYRES TDBPIVOT::GetSourceTable(PGLOBAL g) strcpy(def, "SELECT "); if (!Fncol) { - for (colp = Columns; colp; colp = colp->GetNext()) + for (colp = Tdbp->Columns; colp; colp = colp->GetNext()) if (!Picol || stricmp(Picol, colp->GetName())) Fncol = colp->GetName(); @@ -199,7 +101,7 @@ PQRYRES TDBPIVOT::GetSourceTable(PGLOBAL g) if (!Picol) { // Find default Picol as the last one not equal to Fncol - for (colp = Columns; colp; colp = colp->GetNext()) + for (colp = Tdbp->Columns; colp; colp = colp->GetNext()) if (!Fncol || stricmp(Fncol, colp->GetName())) Picol = colp->GetName(); @@ -357,7 +259,6 @@ int TDBPIVOT::MakePivotColumns(PGLOBAL g) return Mult; } // end of MakePivotColumns -#if 0 /***********************************************************************/ /* Update fields in the MySQL table structure */ /* Note: this does not work. Indeed the new rows are correctly made */ @@ -529,31 +430,257 @@ bool TDBPIVOT::UpdateTableFields(PGLOBAL g, int n) } // end of UpdateTableFields #endif // 0 +/* --------------- Implementation of the PIVOT classes --------------- */ + +/***********************************************************************/ +/* PIVOTDEF constructor. */ +/***********************************************************************/ + PIVOTDEF::PIVOTDEF(void) + { + Host = User = Pwd = DB = NULL; + Tabname = Tabsrc = Picol = Fncol = Function = NULL; + GBdone = Accept = false; + Port = 0; + } // end of PIVOTDEF constructor + +/***********************************************************************/ +/* DefineAM: define specific AM block values from PIVOT table. */ +/***********************************************************************/ +bool PIVOTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) + { + char *p1, *p2; + PHC hc = ((MYCAT*)Cat)->GetHandler(); + + if (!PRXDEF::DefineAM(g, am, poff)) { + Tabname = (char*)Tablep->GetName(); + DB = (char*)Tablep->GetQualifier(); + } else { + DB = Cat->GetStringCatInfo(g, "Database", "*"); + Tabsrc = Cat->GetStringCatInfo(g, "SrcDef", NULL); + } // endif + + Host = Cat->GetStringCatInfo(g, "Host", "localhost"); + User = Cat->GetStringCatInfo(g, "User", "*"); + Pwd = Cat->GetStringCatInfo(g, "Password", NULL); + Picol = Cat->GetStringCatInfo(g, "PivotCol", NULL); + Fncol = Cat->GetStringCatInfo(g, "FncCol", NULL); + + // If fncol is like avg(colname), separate Fncol and Function + if (Fncol && (p1 = strchr(Fncol, '(')) && (p2 = strchr(p1, ')')) && + (*Fncol != '"') && (!*(p2+1))) { + *p1++ = '\0'; *p2 = '\0'; + Function = Fncol; + Fncol = p1; + } else + Function = Cat->GetStringCatInfo(g, "Function", "SUM"); + + GBdone = Cat->GetBoolCatInfo("Groupby", false); + Accept = Cat->GetBoolCatInfo("Accept", false); + Port = Cat->GetIntCatInfo("Port", 3306); + Desc = (Tabname) ? Tabname : Tabsrc; + return FALSE; + } // end of DefineAM + +/***********************************************************************/ +/* GetTable: makes a new TDB of the proper type. */ +/***********************************************************************/ +PTDB PIVOTDEF::GetTable(PGLOBAL g, MODE m) + { + return new(g) TDBPIVOT(this); + } // end of GetTable + +/* ------------------------------------------------------------------- */ + +/***********************************************************************/ +/* Implementation of the TDBPIVOT class. */ +/***********************************************************************/ +TDBPIVOT::TDBPIVOT(PPIVOTDEF tdp) : TDBPRX(tdp) + { + Host = tdp->Host; + Database = tdp->DB; + User = tdp->User; + Pwd = tdp->Pwd; + Port = tdp->Port; + Tabname = tdp->Tabname; // Name of source table + Tabsrc = tdp->Tabsrc; // SQL description of source table + Picol = tdp->Picol; // Pivot column name + Fncol = tdp->Fncol; // Function column name + Function = tdp->Function; // Aggregate function name + Xcolp = NULL; // To the FNCCOL column +//Xresp = NULL; // To the pivot result column +//Rblkp = NULL; // The value block of the pivot column + Fcolp = NULL; // To the function column + Dcolp = NULL; // To the dump column + GBdone = tdp->GBdone; + Accept = tdp->Accept; + Mult = -1; // Estimated table size + N = 0; // The current table index + M = 0; // The occurence rank + FileStatus = 0; // Logical End-of-File + RowFlag = 0; // 0: Ok, 1: Same, 2: Skip + } // end of TDBPIVOT constructor + +/***********************************************************************/ +/* Prepare the source table Query. */ +/***********************************************************************/ +bool TDBPIVOT::GetSourceTable(PGLOBAL g) + { + if (Tdbp) + return false; // Already done + + if (Tabname) { + PTABDEF defp; + PCOLDEF cdp; + + if (InitTable(g)) + return true; + else + defp = Tdbp->GetDef(); + + if (!Fncol) { + for (cdp = defp->GetCols(); cdp; cdp = cdp->GetNext()) + if (!Picol || stricmp(Picol, cdp->GetName())) + Fncol = cdp->GetName(); + + if (!Fncol) { + strcpy(g->Message, MSG(NO_DEF_FNCCOL)); + return true; + } // endif Fncol + + } // endif Fncol + + if (!Picol) { + // Find default Picol as the last one not equal to Fncol + for (cdp = defp->GetCols(); cdp; cdp = cdp->GetNext()) + if (!Fncol || stricmp(Fncol, cdp->GetName())) + Picol = cdp->GetName(); + + if (!Picol) { + strcpy(g->Message, MSG(NO_DEF_PIVOTCOL)); + return true; + } // endif Picol + + } // endif Picol + + if (!GBdone) { + char *colist; + + // Locate the suballocated colist (size is not known yet) + *(colist = (char*)PlugSubAlloc(g, NULL, 0)) = 0; + + // Make the column list + for (cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext()) + if (!cdp->GetOffset()) + strcat(strcat(colist, cdp->GetName()), ", "); + + // Add the Pivot column at the end of the list + strcat(colist, Picol); + + // Now we know how much was suballocated + PlugSubAlloc(g, NULL, strlen(colist)); + + // Locate the source string (size is not known yet) + Tabsrc = (char*)PlugSubAlloc(g, NULL, 0); + + // Start making the definition + strcat(strcat(strcpy(Tabsrc, "SELECT "), colist), ", "); + + // Make it suitable for Pivot by doing the group by + strcat(strcat(Tabsrc, Function), "("); + strcat(strcat(strcat(Tabsrc, Fncol), ") "), Fncol); + strcat(strcat(Tabsrc, " FROM "), Tabname); + strcat(strcat(Tabsrc, " GROUP BY "), colist); + + // Now we know how much was suballocated + PlugSubAlloc(g, NULL, strlen(Tabsrc)); + } // endif !GBdone + + } else if (!Tabsrc) { + strcpy(g->Message, MSG(SRC_TABLE_UNDEF)); + return true; + } // endif + + if (Tabsrc) { + MYSQLC myc; // MySQL connection class + PQRYRES qryp; + PCOLRES crp; + int w; + + // Open a MySQL connection for this table + if (myc.Open(g, Host, Database, User, Pwd, Port)) + return true; + + // Send the source command to MySQL + if (myc.ExecSQL(g, Tabsrc, &w) == RC_FX) { + myc.Close(); + return true; + } // endif Exec + + // We must have a storage query to get pivot column values + qryp = myc.GetResult(g); + myc.Close(); + Tdbp = new(g) TDBQRS(qryp); + + if (!Fncol) { + for (crp = qryp->Colresp; crp; crp = crp->Next) + if (!Picol || stricmp(Picol, crp->Name)) + Fncol = crp->Name; + + if (!Fncol) { + strcpy(g->Message, MSG(NO_DEF_FNCCOL)); + return true; + } // 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 (!Fncol || stricmp(Fncol, crp->Name)) + Picol = crp->Name; + + if (!Picol) { + strcpy(g->Message, MSG(NO_DEF_PIVOTCOL)); + return true; + } // endif Picol + + } // endif Picol + + } // endif Tabsrc + + // Now it is time to allocate the pivot and function columns + if (!(Fcolp = Tdbp->ColDB(g, Fncol, 0))) { + // Function column not found in table + sprintf(g->Message, MSG(COL_ISNOT_TABLE), Fncol, Tabname); + return true; + } else if (Fcolp->InitValue(g)) + return true; + + if (!(Xcolp = Tdbp->ColDB(g, Picol, 0))) { + // Pivot column not found in table + sprintf(g->Message, MSG(COL_ISNOT_TABLE), Picol, Tabname); + return true; + } else if (Xcolp->InitValue(g)) + return true; + + return false; + } // end of GetSourceTable + /***********************************************************************/ /* Allocate source column description block. */ /***********************************************************************/ PCOL TDBPIVOT::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) { - PCOL colp = NULL; + PCOL colp; -//if (stricmp(cdp->GetName(), Picol) && stricmp(cdp->GetName(), Fncol)) { - colp = new(g) COLBLK(cdp, this, n); + if (cdp->GetOffset()) { + colp = new(g) FNCCOL(cdp, this, cprec, n); -// if (((PSRCCOL)colp)->Init(g, this)) -// return NULL; + if (cdp->GetOffset() > 1) + Dcolp = colp; -//} else { -// sprintf(g->Message, MSG(NO_MORE_COL), cdp->GetName()); -// return NULL; -//} // endif Name - - if (cprec) { - colp->SetNext(cprec->GetNext()); - cprec->SetNext(colp); - } else { - colp->SetNext(Columns); - Columns = colp; - } // endif cprec + } else + colp = new(g) SRCCOL(cdp, this, cprec, n); return colp; } // end of MakeCol @@ -598,13 +725,6 @@ bool TDBPIVOT::OpenDB(PGLOBAL g) return FALSE; } // endif use - /*********************************************************************/ - /* Do it here if not done yet (should not be the case). */ - /*********************************************************************/ -//if (MakePivotColumns(g) < 0) - if (!(Qryp = GetSourceTable(g))) - return TRUE; - if (Mode != MODE_READ) { /*******************************************************************/ /* Currently PIVOT tables cannot be modified. */ @@ -621,6 +741,30 @@ bool TDBPIVOT::OpenDB(PGLOBAL g) return TRUE; } // endif To_Key_Col + /*********************************************************************/ + /* Do it here if not done yet (should not be the case). */ + /*********************************************************************/ + if (GetSourceTable(g)) + return TRUE; + + /*********************************************************************/ + /* Check and initialize the subtable columns. */ + /*********************************************************************/ + for (PCOL cp = Columns; cp; cp = cp->GetNext()) + if (cp->GetAmType() == TYPE_AM_SRC) { + if (((PPRXCOL)cp)->Init(g)) + return TRUE; + + } else if (cp->GetAmType() == TYPE_AM_FNC) + if (((PFNCCOL)cp)->InitColumn(g)) + return TRUE; + + /*********************************************************************/ + /* Physically open the object table. */ + /*********************************************************************/ + if (Tdbp->OpenDB(g)) + return TRUE; + return FALSE; } // end of OpenDB @@ -632,7 +776,6 @@ int TDBPIVOT::ReadDB(PGLOBAL g) int rc = RC_OK; bool newrow = FALSE; PCOL colp; - PVAL vp1, vp2; if (FileStatus == 2) return RC_EF; @@ -652,7 +795,7 @@ int TDBPIVOT::ReadDB(PGLOBAL g) /*********************************************************************/ do { if (RowFlag != 1) { - if ((rc = Tqrp->ReadDB(g)) != RC_OK) { + if ((rc = Tdbp->ReadDB(g)) != RC_OK) { if (FileStatus && rc == RC_EF) { // A prepared row remains to be sent FileStatus = 2; @@ -662,14 +805,16 @@ int TDBPIVOT::ReadDB(PGLOBAL g) break; } // endif rc - for (colp = Tqrp->GetColumns(); colp; colp = colp->GetNext()) + for (colp = Tdbp->GetColumns(); colp; colp = colp->GetNext()) colp->ReadColumn(g); for (colp = Columns; colp; colp = colp->GetNext()) if (colp->GetAmType() == TYPE_AM_SRC) if (FileStatus) { - if (((PSRCCOL)colp)->CompareColumn()) + if (((PSRCCOL)colp)->CompareLast()) { newrow = (RowFlag) ? TRUE : FALSE; + break; + } // endif CompareLast } else ((PSRCCOL)colp)->SetColumn(); @@ -683,21 +828,21 @@ int TDBPIVOT::ReadDB(PGLOBAL g) } else RowFlag = 2; - vp1 = Xcolp->GetValue(); - // Look for the column having this header for (colp = Columns; colp; colp = colp->GetNext()) if (colp->GetAmType() == TYPE_AM_FNC) { - vp2 = ((PFNCCOL)colp)->Hval; - - if (!vp1->CompareValue(vp2)) + if (((PFNCCOL)colp)->CompareColumn()) break; } // endif AmType - if (!colp) { - strcpy(g->Message, MSG(NO_MATCH_COL)); - return RC_FX; + if (!colp && !(colp = Dcolp)) { + if (!Accept) { + strcpy(g->Message, MSG(NO_MATCH_COL)); + return RC_FX; + } else + continue; + } // endif colp // Set the value of the matching column from the fonction value @@ -734,6 +879,7 @@ void TDBPIVOT::CloseDB(PGLOBAL g) //Tdbp->CloseDB(g); } // end of CloseDB +#if 0 /***********************************************************************/ /* TDBPIVOT: Compare routine for sorting pivot column values. */ /***********************************************************************/ @@ -742,120 +888,81 @@ int TDBPIVOT::Qcompare(int *i1, int *i2) // TODO: the actual comparison between pivot column result values. return Rblkp->CompVal(*i1, *i2); } // end of Qcompare +#endif // 0 // ------------------------ FNCCOL functions ---------------------------- /***********************************************************************/ /* FNCCOL public constructor. */ /***********************************************************************/ -FNCCOL::FNCCOL(PCOL col1, PTDBPIVOT tdbp) - : COLBLK(col1, tdbp) +FNCCOL::FNCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) + : COLBLK(cdp, tdbp, i) { + if (cprec) { + Next = cprec->GetNext(); + cprec->SetNext(this); + } else { + Next = tdbp->GetColumns(); + tdbp->SetColumns(this); + } // endif cprec + Value = NULL; // We'll get a new one later - Hval = NULL; // The unconverted header value + Hval = NULL; // The unconverted header value + Xcolp = NULL; } // end of FNCCOL constructor /***********************************************************************/ -/* FNCCOL initialization function. */ +/* FNCCOL initialization function. */ /***********************************************************************/ -bool FNCCOL::InitColumn(PGLOBAL g, PVAL valp) +bool FNCCOL::InitColumn(PGLOBAL g) { - char *p, buf[128]; - int len; - // Must have its own value block if (InitValue(g)) return TRUE; - // Convert header value to a null terminated character string - Hval = valp; - p = Hval->GetCharString(buf); - len = strlen(p) + 1; + // Make a value from the column name + Hval = AllocateValue(g, Name, TYPE_STRING); + Hval->SetPrec(1); // Case insensitive - if (len > (signed)sizeof(buf)) { - strcpy(g->Message, MSG(COLNAM_TOO_LONG)); - return TRUE; - } // endif buf - - // Set the name of the functional pivot column - Name = (PSZ)PlugSubAlloc(g, NULL, len); - strcpy(Name, p); + Xcolp = ((PTDBPIVOT)To_Tdb)->Xcolp; AddStatus(BUF_READ); // All is done here return FALSE; } // end of InitColumn +/***********************************************************************/ +/* CompareColumn: Compare column value with source column value. */ +/***********************************************************************/ +bool FNCCOL::CompareColumn(void) + { + // Compare the unconverted values + return Hval->IsEqual(Xcolp->GetValue(), false); + } // end of CompareColumn + // ------------------------ SRCCOL functions ---------------------------- -#if 0 /***********************************************************************/ /* SRCCOL public constructor. */ /***********************************************************************/ -SRCCOL::SRCCOL(PCOLDEF cdp, PTDBPIVOT tdbp, int n) - : COLBLK(cdp, tdbp, n) +SRCCOL::SRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int n) + : PRXCOL(cdp, tdbp, cprec, n) { // Set additional SRC access method information for column. - Colp = NULL; - Cnval = NULL; +//Cnval = NULL; } // end of SRCCOL constructor -#endif // 0 - -/***********************************************************************/ -/* SRCCOL public constructor. */ -/***********************************************************************/ -SRCCOL::SRCCOL(PCOL cp, PTDBPIVOT tdbp, int n) - : COLBLK(cp, tdbp) - { - Index = n; - - // Set additional SRC access method information for column. - Colp = (PQRSCOL)cp; - - // Don't share Value with the source column so we can compare - Cnval = Value = NULL; - } // end of SRCCOL constructor - -#if 0 -/***********************************************************************/ -/* SRCCOL constructor used for copying columns. */ -/* tdbp is the pointer to the new table descriptor. */ -/***********************************************************************/ -SRCCOL::SRCCOL(SRCCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp) - { - Colp = col1->Colp; - } // end of SRCCOL copy constructor -#endif // 0 /***********************************************************************/ /* Initialize the column as pointing to the source column. */ /***********************************************************************/ -bool SRCCOL::Init(PGLOBAL g, PTDBPIVOT tdbp) +bool SRCCOL::Init(PGLOBAL g) { - // Currently we ignore the type of the create table column - bool conv = FALSE; + if (PRXCOL::Init(g)) + return true; -#if 0 - if (!Colp) { - // Column was defined in the Create Table statement - if (!(Colp = tdbp->ColDB(g, Name, 0))) - return TRUE; - - // We can have a conversion problem converting from numeric to - // character because GetCharValue does not exist for numeric types. - conv = (IsTypeChar(Buf_Type) && IsTypeNum(Colp->GetResultType())); - } else -#endif // 0 - conv = FALSE; - - if (InitValue(g)) - return TRUE; - -//if (conv) -// Cnval = AllocateValue(g, Colp->GetValue()); -//else - Cnval = Value; + // Will contain the last value +//Cnval = AllocateValue(g, Value, TYPE_VOID); AddStatus(BUF_READ); // All is done here - return FALSE; + return false; } // end of SRCCOL constructor /***********************************************************************/ @@ -863,25 +970,18 @@ bool SRCCOL::Init(PGLOBAL g, PTDBPIVOT tdbp) /***********************************************************************/ void SRCCOL::SetColumn(void) { -#if defined(_DEBUG) - Cnval->SetValue_pval(Colp->GetValue(), TRUE); -#else - Cnval->SetValue_pval(Colp->GetValue()); -#endif // _DEBUG - - if (Value != Cnval) - // Convert value - Value->SetValue_pval(Cnval); - +//Cnval->SetValue_pval(Value); + Value->SetValue_pval(To_Val); } // end of SetColumn /***********************************************************************/ /* SetColumn: Compare column value with source column value. */ /***********************************************************************/ -bool SRCCOL::CompareColumn(void) +bool SRCCOL::CompareLast(void) { // Compare the unconverted values - return Cnval->CompareValue(Colp->GetValue()); +//return !Cnval->IsEqual(Colp->GetValue(), true); + return !Value->IsEqual(To_Val, true); } // end of CompareColumn @@ -1019,18 +1119,8 @@ bool TDBQRS::OpenDB(PGLOBAL g) CurPos = -1; - 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(); - + if (Use == USE_OPEN) return FALSE; - } // endif use /*********************************************************************/ /* Open (retrieve data from) the query if not already open. */ @@ -1059,6 +1149,7 @@ int TDBQRS::ReadDB(PGLOBAL g) htrc("QRS ReadDB: R%d CurPos=%d key=%p link=%p Kindex=%p\n", GetTdb_No(), CurPos, To_Key_Col, To_Link, To_Kindex); +#if 0 if (To_Kindex) { /*******************************************************************/ /* Reading is by an index table. */ @@ -1086,6 +1177,7 @@ int TDBQRS::ReadDB(PGLOBAL g) htrc("Position is now %d\n", CurPos); } else +#endif // 0 /*******************************************************************/ /* !To_Kindex ---> sequential reading */ /*******************************************************************/ @@ -1117,10 +1209,10 @@ int TDBQRS::DeleteDB(PGLOBAL g, int irc) /***********************************************************************/ void TDBQRS::CloseDB(PGLOBAL g) { - if (To_Kindex) { - To_Kindex->Close(); - To_Kindex = NULL; - } // endif +//if (To_Kindex) { +// To_Kindex->Close(); +// To_Kindex = NULL; +// } // endif if (trace) htrc("Qryres CloseDB"); diff --git a/storage/connect/tabpivot.h b/storage/connect/tabpivot.h index fb480b9abbf..3aa5288b5d8 100644 --- a/storage/connect/tabpivot.h +++ b/storage/connect/tabpivot.h @@ -22,13 +22,12 @@ typedef class QRSCOL *PQRSCOL; /***********************************************************************/ /* PIVOT table. */ /***********************************************************************/ -//ass DllExport PIVOTDEF : public TABDEF {/* Logical table description */ -class PIVOTDEF : public TABDEF { /* Logical table description */ +//ass DllExport PIVOTDEF : public PRXDEF {/* Logical table description */ +class PIVOTDEF : public PRXDEF { /* Logical table description */ friend class TDBPIVOT; public: // Constructor - PIVOTDEF(void) {Pseudo = 3; - Tabname = Tabsrc = Picol = Fncol = Function = NULL;} + PIVOTDEF(void); // Implementation virtual const char *GetType(void) {return "PIVOT";} @@ -39,26 +38,27 @@ class PIVOTDEF : public TABDEF { /* Logical table description */ protected: // Members - char *Host; /* Host machine to use */ - char *User; /* User logon info */ - char *Pwd; /* Password logon info */ - char *DB; /* Database to be used by server */ - char *Tabname; /* Name of source table */ + char *Host; /* Host machine to use */ + char *User; /* User logon info */ + char *Pwd; /* Password logon info */ + char *DB; /* Database to be used by server */ + char *Tabname; /* Name of source table */ char *Tabsrc; /* The source table SQL description */ - char *Picol; /* The pivot column */ + char *Picol; /* The pivot column */ char *Fncol; /* The function column */ char *Function; /* The function applying to group by */ bool GBdone; /* True if tabname as group by format */ - int Port; /* MySQL port number */ + bool Accept; /* TRUE if no match is accepted */ + int Port; /* MySQL port number */ }; // end of PIVOTDEF /***********************************************************************/ /* This is the class declaration for the PIVOT table. */ /***********************************************************************/ //ass DllExport TDBPIVOT : public TDBASE, public CSORT { -class TDBPIVOT : public TDBASE, public CSORT { +class TDBPIVOT : public TDBPRX { friend class FNCCOL; - friend class SRCCOL; +//friend class SRCCOL; public: // Constructor TDBPIVOT(PPIVOTDEF tdp); @@ -85,39 +85,41 @@ class TDBPIVOT : public TDBASE, public CSORT { virtual void CloseDB(PGLOBAL g); // The sorting function - virtual int Qcompare(int *, int *); +//virtual int Qcompare(int *, int *); protected: - PQRYRES GetSourceTable(PGLOBAL g); - int MakePivotColumns(PGLOBAL g); - bool UpdateTableFields(PGLOBAL g, int n); + bool GetSourceTable(PGLOBAL g); +//int MakePivotColumns(PGLOBAL g); +//bool UpdateTableFields(PGLOBAL g, int n); // Members - MYSQLC Myc; // MySQL connection class - PTDBQRS Tqrp; // To the source table result - char *Host; // Host machine to use - char *User; // User logon info - char *Pwd; // Password logon info - char *Database; // Database to be used by server - PQRYRES Qryp; // Points to Query result block - char *Tabname; // Name of source table - char *Tabsrc; // SQL of source table - char *Picol; // Pivot column name - char *Fncol; // Function column name - char *Function; // The function applying to group by - PQRSCOL Fcolp; // To the function column in source - PQRSCOL Xcolp; // To the pivot column in source - PCOLRES Xresp; // To the pivot result column -//PCOLRES To_Sort; // Saved Qryp To_Sort pointer - PVBLK Rblkp; // The value block of the pivot column - bool GBdone; // True when subtable is "Group by" - int Mult; // Multiplication factor - int Ncol; // The number of generated columns - int N; // The current table index - int M; // The occurence rank - int Port; // MySQL port number - BYTE FileStatus; // 0: First 1: Rows 2: End-of-File - BYTE RowFlag; // 0: Ok, 1: Same, 2: Skip +//MYSQLC Myc; // MySQL connection class +//PTDBQRS Tqrp; // To the source table result + char *Host; // Host machine to use + char *User; // User logon info + char *Pwd; // Password logon info + char *Database; // Database to be used by server +//PQRYRES Qryp; // Points to Query result block + char *Tabname; // Name of source table + char *Tabsrc; // SQL of source table + char *Picol; // Pivot column name + char *Fncol; // Function column name + char *Function; // The function applying to group by + PCOL Fcolp; // To the function column in source + PCOL Xcolp; // To the pivot column in source + PCOL Dcolp; // To the dump column +//PCOLRES Xresp; // To the pivot result column +//PCOLRES To_Sort; // Saved Qryp To_Sort pointer +//PVBLK Rblkp; // The value block of the pivot column + bool GBdone; // True when subtable is "Group by" + bool Accept; // TRUE if no match is accepted + int Mult; // Multiplication factor + int Ncol; // The number of generated columns + int N; // The current table index + int M; // The occurence rank + int Port; // MySQL port number + BYTE FileStatus; // 0: First 1: Rows 2: End-of-File + BYTE RowFlag; // 0: Ok, 1: Same, 2: Skip }; // end of class TDBPIVOT /***********************************************************************/ @@ -127,30 +129,30 @@ class FNCCOL : public COLBLK { friend class TDBPIVOT; public: // Constructor - FNCCOL(PCOL colp, PTDBPIVOT tdbp); + FNCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i); // Implementation virtual int GetAmType(void) {return TYPE_AM_FNC;} // Methods virtual void Reset(void) {} - bool InitColumn(PGLOBAL g, PVAL valp); + bool InitColumn(PGLOBAL g); + bool CompareColumn(void); protected: // Member - PVAL Hval; // The original value used to generate the header + PVAL Hval; // The value containing the header + PCOL Xcolp; }; // end of class FNCCOL /***********************************************************************/ /* Class SRCCOL: for other source columns. */ /***********************************************************************/ -class SRCCOL : public COLBLK { +class SRCCOL : public PRXCOL { friend class TDBPIVOT; public: // Constructors -//SRCCOL(PCOLDEF cdp, PTDBPIVOT tdbp, int n); - SRCCOL(PCOL cp, PTDBPIVOT tdbp, int n); -//SRCCOL(SRCCOL *colp, PTDB tdbp); // Constructor used in copy process + SRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int n); // Implementation virtual int GetAmType(void) {return TYPE_AM_SRC;} @@ -158,16 +160,15 @@ class SRCCOL : public COLBLK { // Methods virtual void Reset(void) {} void SetColumn(void); - bool Init(PGLOBAL g, PTDBPIVOT tdbp); - bool CompareColumn(void); + bool Init(PGLOBAL g); + bool CompareLast(void); protected: // Default constructor not to be used SRCCOL(void) {} // Members - PQRSCOL Colp; - PVAL Cnval; +//PVAL Cnval; }; // end of class SRCCOL /***********************************************************************/ diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp index 2bd92ff9607..2c14b711f86 100644 --- a/storage/connect/tabutil.cpp +++ b/storage/connect/tabutil.cpp @@ -121,10 +121,7 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db, PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, const char *name, bool info) { - static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, DB_INT, - DB_INT, DB_SHORT, DB_SHORT, DB_SHORT, - DB_CHAR, DB_CHAR, DB_CHAR}; - static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, + static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING, TYPE_STRING, TYPE_STRING}; static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC, @@ -132,7 +129,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, FLD_REM, FLD_NO, FLD_CHARSET}; static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32}; char *fld, *fmt; - int i, n, ncol = sizeof(dbtype) / sizeof(int); + int i, n, ncol = sizeof(buftyp) / sizeof(int); int len, type, prec; bool mysql; TABLE_SHARE *s; @@ -156,7 +153,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, /* Allocate the structures used to refer to the result set. */ /**********************************************************************/ qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3, - dbtype, buftyp, fldtyp, length, true, true); + buftyp, fldtyp, length, true, true); // Some columns must be renamed for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next) diff --git a/storage/connect/tabwmi.cpp b/storage/connect/tabwmi.cpp index d89d61dc11c..dbd4330a2f9 100644 --- a/storage/connect/tabwmi.cpp +++ b/storage/connect/tabwmi.cpp @@ -135,14 +135,12 @@ PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname) /***********************************************************************/ PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info) { - static int dbtype[] = {DB_CHAR, DB_SHORT, DB_CHAR, - DB_INT, DB_INT, DB_SHORT}; static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_SHORT}; static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC, FLD_LENGTH, FLD_SCALE}; static unsigned int len, length[] = {0, 6, 8, 10, 10, 6}; - int i = 0, n = 0, ncol = sizeof(dbtype) / sizeof(int); + int i = 0, n = 0, ncol = sizeof(buftyp) / sizeof(int); int lng, typ, prec; LONG low, upp; BSTR propname; @@ -213,7 +211,7 @@ PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info) /* Allocate the structures used to refer to the result set. */ /*********************************************************************/ qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3, - dbtype, buftyp, fldtyp, length, true, true); + buftyp, fldtyp, length, true, true); if (info) return qrp; diff --git a/storage/connect/tabxcl.cpp b/storage/connect/tabxcl.cpp index d64a730beb0..96da0571271 100644 --- a/storage/connect/tabxcl.cpp +++ b/storage/connect/tabxcl.cpp @@ -66,7 +66,6 @@ extern "C" int trace; /***********************************************************************/ XCLDEF::XCLDEF(void) { - Pseudo = 3; Xcol = NULL; Sep = ','; Mult = 10; diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp index 9053658b461..7a1146e6c32 100644 --- a/storage/connect/value.cpp +++ b/storage/connect/value.cpp @@ -154,46 +154,6 @@ int GetTypeSize(int type, int len) return len; } // end of GetTypeSize -/***********************************************************************/ -/* GetPLGType: returns the PlugDB type corresponding to a DB type. */ -/***********************************************************************/ -int GetPLGType(int type) - { - int tp; - - switch (type) { - case DB_CHAR: - case DB_STRING: tp = TYPE_STRING; break; - case DB_SHORT: tp = TYPE_SHORT; break; - case DB_INT: tp = TYPE_INT; break; - case DB_DOUBLE: tp = TYPE_FLOAT; break; - case DB_DATE: tp = TYPE_DATE; break; - default: tp = TYPE_ERROR; - } // endswitch type - - return tp; - } // end of GetPLGType - -/***********************************************************************/ -/* GetDBType: returns the DB type corresponding to a PlugDB type. */ -/***********************************************************************/ -int GetDBType(int type) - { - int tp; - - switch (type) { - case TYPE_STRING: tp = DB_CHAR; break; - case TYPE_SHORT: tp = DB_SHORT; break; - case TYPE_INT: tp = DB_INT; break; - case TYPE_BIGINT: - case TYPE_FLOAT: tp = DB_DOUBLE; break; - case TYPE_DATE: tp = DB_DATE; break; - default: tp = DB_ERROR; - } // endswitch type - - return tp; - } // end of GetPLGType - /***********************************************************************/ /* GetFormatType: returns the FORMAT character(s) according to type. */ /***********************************************************************/ @@ -1143,10 +1103,13 @@ bool TYPVAL::IsEqual(PVAL vp, bool chktype) return false; else if (Null || vp->IsNull()) return false; - else if (Ci || vp->IsCi()) - return !stricmp(Strp, vp->GetCharValue()); + + char buf[32]; + + if (Ci || vp->IsCi()) + return !stricmp(Strp, vp->GetCharString(buf)); else // (!Ci) - return !strcmp(Strp, vp->GetCharValue()); + return !strcmp(Strp, vp->GetCharString(buf)); } // end of IsEqual diff --git a/storage/connect/value.h b/storage/connect/value.h index 0f7b795c252..95d69dae92f 100644 --- a/storage/connect/value.h +++ b/storage/connect/value.h @@ -38,7 +38,6 @@ typedef struct _datpar *PDTP; // For DTVAL /***********************************************************************/ /* Utilities used to test types and to allocated values. */ /***********************************************************************/ -int GetPLGType(int); PVAL AllocateValue(PGLOBAL, void *, short); // Exported functions @@ -50,7 +49,6 @@ DllExport int TranslateSQLType(int stp, int prec, int& len); #endif DllExport char *GetFormatType(int); DllExport int GetFormatType(char); -DllExport int GetDBType(int); DllExport bool IsTypeChar(int type); DllExport bool IsTypeNum(int type); DllExport int ConvertType(int, int, CONV, bool match = false); @@ -82,12 +80,12 @@ class DllExport VALUE : public BLOCK { virtual longlong GetBigintValue(void) = 0; virtual double GetFloatValue(void) = 0; virtual void *GetTo_Val(void) = 0; + virtual void SetPrec(int prec) {Prec = prec;} bool IsNull(void) {return Null;} void SetNull(bool b) {Null = b;} void SetNullable(bool b) {Nullable = b;} int GetType(void) {return Type;} int GetClen(void) {return Clen;} - void SetPrec(int prec) {Prec = prec;} void SetGlobal(PGLOBAL g) {Global = g;} // Methods @@ -217,6 +215,7 @@ class DllExport TYPVAL: public VALUE { virtual longlong GetBigintValue(void) {return atoll(Strp);} virtual double GetFloatValue(void) {return atof(Strp);} virtual void *GetTo_Val(void) {return Strp;} + virtual void SetPrec(int prec) {Ci = prec != 0;} // Methods virtual bool SetValue_pval(PVAL valp, bool chktype);