mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge connect/10.0 into 10.0
Squash all connect/10.0's commits into one and keep only changes from storage/connect directory.
This commit is contained in:
@@ -520,7 +520,7 @@ bool ARRAY::FilTest(PGLOBAL g, PVAL valp, OPVAL opc, int opm)
|
||||
|
||||
} else if (opc != OP_EXIST) {
|
||||
sprintf(g->Message, MSG(MISSING_ARG), opc);
|
||||
throw TYPE_ARRAY;
|
||||
throw (int)TYPE_ARRAY;
|
||||
} else // OP_EXIST
|
||||
return Nval > 0;
|
||||
|
||||
@@ -683,14 +683,14 @@ void ARRAY::SetPrecision(PGLOBAL g, int p)
|
||||
{
|
||||
if (Vblp == NULL) {
|
||||
strcpy(g->Message, MSG(PREC_VBLP_NULL));
|
||||
throw TYPE_ARRAY;
|
||||
throw (int)TYPE_ARRAY;
|
||||
} // endif Vblp
|
||||
|
||||
bool was = Vblp->IsCi();
|
||||
|
||||
if (was && !p) {
|
||||
strcpy(g->Message, MSG(BAD_SET_CASE));
|
||||
throw TYPE_ARRAY;
|
||||
throw (int)TYPE_ARRAY;
|
||||
} // endif Vblp
|
||||
|
||||
if (was || !p)
|
||||
@@ -701,7 +701,7 @@ void ARRAY::SetPrecision(PGLOBAL g, int p)
|
||||
if (!was && Type == TYPE_STRING)
|
||||
// Must be resorted to eliminate duplicate strings
|
||||
if (Sort(g))
|
||||
throw TYPE_ARRAY;
|
||||
throw (int)TYPE_ARRAY;
|
||||
|
||||
} // end of SetPrecision
|
||||
|
||||
@@ -1035,7 +1035,7 @@ void ARRAY::Printf(PGLOBAL g, FILE *f, uint n)
|
||||
} else
|
||||
fprintf(f, "%sVALLST: numval=%d\n", m, Nval);
|
||||
|
||||
} // end of Print
|
||||
} // end of Printf
|
||||
|
||||
/***********************************************************************/
|
||||
/* Make string output of ARRAY contents. */
|
||||
@@ -1047,7 +1047,7 @@ void ARRAY::Prints(PGLOBAL, char *ps, uint z)
|
||||
|
||||
sprintf(ps, "ARRAY: type=%d\n", Type);
|
||||
// More to be implemented later
|
||||
} // end of Print
|
||||
} // end of Prints
|
||||
|
||||
/* -------------------------- Class MULAR ---------------------------- */
|
||||
|
||||
|
@@ -65,7 +65,7 @@ void BLOCKFILTER::Printf(PGLOBAL, FILE *f, uint n)
|
||||
|
||||
fprintf(f, "%sBLOCKFILTER: at %p opc=%d opm=%d result=%d\n",
|
||||
m, this, Opc, Opm, Result);
|
||||
} // end of Print
|
||||
} // end of Printf
|
||||
|
||||
/***********************************************************************/
|
||||
/* Make string output of BLOCKFILTER contents. */
|
||||
@@ -73,7 +73,7 @@ void BLOCKFILTER::Printf(PGLOBAL, FILE *f, uint n)
|
||||
void BLOCKFILTER::Prints(PGLOBAL, char *ps, uint z)
|
||||
{
|
||||
strncat(ps, "BlockFilter(s)", z);
|
||||
} // end of Print
|
||||
} // end of Prints
|
||||
|
||||
|
||||
/* ---------------------- Class BLKFILLOG ---------------------------- */
|
||||
@@ -1006,9 +1006,9 @@ void BLOCKINDEX::Printf(PGLOBAL g, FILE *f, UINT n)
|
||||
m, this, Next, (Colp) ? Colp->GetName() : "Rowid", Kxp, Result);
|
||||
|
||||
if (Next)
|
||||
Next->Print(g, f, n);
|
||||
Next->Printf(g, f, n);
|
||||
|
||||
} // end of Print
|
||||
} // end of Printf
|
||||
|
||||
/***********************************************************************/
|
||||
/* Make string output of BLOCKINDEX contents. */
|
||||
@@ -1016,7 +1016,7 @@ void BLOCKINDEX::Printf(PGLOBAL g, FILE *f, UINT n)
|
||||
void BLOCKINDEX::Prints(PGLOBAL g, char *ps, UINT z)
|
||||
{
|
||||
strncat(ps, "BlockIndex(es)", z);
|
||||
} // end of Print
|
||||
} // end of Prints
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
|
@@ -197,7 +197,7 @@ int COLBLK::GetLengthEx(void)
|
||||
void COLBLK::ReadColumn(PGLOBAL g)
|
||||
{
|
||||
sprintf(g->Message, MSG(UNDEFINED_AM), "ReadColumn");
|
||||
throw TYPE_COLBLK;
|
||||
throw (int)TYPE_COLBLK;
|
||||
} // end of ReadColumn
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -208,7 +208,7 @@ void COLBLK::ReadColumn(PGLOBAL g)
|
||||
void COLBLK::WriteColumn(PGLOBAL g)
|
||||
{
|
||||
sprintf(g->Message, MSG(UNDEFINED_AM), "WriteColumn");
|
||||
throw TYPE_COLBLK;
|
||||
throw (int)TYPE_COLBLK;
|
||||
} // end of WriteColumn
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -232,7 +232,7 @@ void COLBLK::Printf(PGLOBAL, FILE *f, uint n)
|
||||
fprintf(f,
|
||||
" coluse=%04X status=%04X buftyp=%d value=%p name=%s\n",
|
||||
ColUse, Status, Buf_Type, Value, Name);
|
||||
} // end of Print
|
||||
} // end of Printf
|
||||
|
||||
/***********************************************************************/
|
||||
/* Make string output of a column descriptor block. */
|
||||
@@ -240,7 +240,7 @@ void COLBLK::Printf(PGLOBAL, FILE *f, uint n)
|
||||
void COLBLK::Prints(PGLOBAL, char *ps, uint)
|
||||
{
|
||||
sprintf(ps, "R%d.%s", To_Tdb->GetTdb_No(), Name);
|
||||
} // end of Print
|
||||
} // end of Prints
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -262,7 +262,7 @@ SPCBLK::SPCBLK(PCOLUMN cp)
|
||||
void SPCBLK::WriteColumn(PGLOBAL g)
|
||||
{
|
||||
sprintf(g->Message, MSG(SPCOL_READONLY), Name);
|
||||
throw TYPE_COLBLK;
|
||||
throw (int)TYPE_COLBLK;
|
||||
} // end of WriteColumn
|
||||
|
||||
/***********************************************************************/
|
||||
|
@@ -1,4 +1,5 @@
|
||||
/* Copyright (C) Olivier Bertrand 2004 - 2017
|
||||
Copyright (C) MariaDB Corporation Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -66,8 +67,10 @@ PGLOBAL CntExit(PGLOBAL g)
|
||||
if (g) {
|
||||
CntEndDB(g);
|
||||
|
||||
if (g->Activityp)
|
||||
delete g->Activityp;
|
||||
if (g->Activityp) {
|
||||
delete g->Activityp;
|
||||
g->Activityp = NULL;
|
||||
} // endif Activityp
|
||||
|
||||
PlugExit(g);
|
||||
g= NULL;
|
||||
@@ -185,10 +188,10 @@ bool CntInfo(PGLOBAL g, PTDB tp, PXF info)
|
||||
/***********************************************************************/
|
||||
PTDB CntGetTDB(PGLOBAL g, LPCSTR name, MODE mode, PHC h)
|
||||
{
|
||||
PTDB tdbp;
|
||||
PTDB tdbp = NULL;
|
||||
PTABLE tabp;
|
||||
PDBUSER dup = PlgGetUser(g);
|
||||
volatile PCATLG cat = (dup) ? dup->Catalog : NULL; // Safe over longjmp
|
||||
volatile PCATLG cat = (dup) ? dup->Catalog : NULL; // Safe over throw
|
||||
|
||||
if (trace)
|
||||
printf("CntGetTDB: name=%s mode=%d cat=%p\n", name, mode, cat);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) Olivier Bertrand 2004 - 2011
|
||||
/* Copyright (C) MariaDB Corporation Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
/**************** Cnt H Declares Source Code File (.H) *****************/
|
||||
/* Name: CONNECT.H Version 2.4 */
|
||||
/* Author Olivier BERTRAND bertrandop@gmail.com */
|
||||
/* This file contains the some based classes declares. */
|
||||
/***********************************************************************/
|
||||
#include "filamtxt.h"
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* Copyright (C) MariaDB Corporation Ab */
|
||||
#define MSG_ACCESS_VIOLATN "Access violation"
|
||||
#define MSG_ADD_BAD_TYPE "Array add value type mismatch (%s -> %s)"
|
||||
#define MSG_ALLOC_ERROR "Error allocating %s"
|
||||
|
@@ -87,7 +87,7 @@ BYTE OpBmp(PGLOBAL g, OPVAL opc)
|
||||
case OP_EXIST: bt = 0x00; break;
|
||||
default:
|
||||
sprintf(g->Message, MSG(BAD_FILTER_OP), opc);
|
||||
throw TYPE_ARRAY;
|
||||
throw (int)TYPE_FILTER;
|
||||
} // endswitch opc
|
||||
|
||||
return bt;
|
||||
@@ -1437,7 +1437,7 @@ void FILTER::Printf(PGLOBAL g, FILE *f, uint n)
|
||||
|
||||
} // endfor fp
|
||||
|
||||
} // end of Print
|
||||
} // end of Printf
|
||||
|
||||
/***********************************************************************/
|
||||
/* Make string output of TABLE contents (z should be checked). */
|
||||
@@ -1579,7 +1579,7 @@ void FILTER::Prints(PGLOBAL g, char *ps, uint z)
|
||||
bcp = bxp;
|
||||
} while (bcp); // enddo
|
||||
|
||||
} // end of Print
|
||||
} // end of Prints
|
||||
|
||||
|
||||
/* -------------------- Derived Classes Functions -------------------- */
|
||||
@@ -1697,8 +1697,6 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having)
|
||||
|
||||
if (trace)
|
||||
htrc("PrepareFilter: fp=%p having=%d\n", fp, having);
|
||||
//if (fp)
|
||||
// fp->Print(g, debug, 0);
|
||||
|
||||
while (fp) {
|
||||
if (fp->Opc == OP_SEP)
|
||||
@@ -1712,7 +1710,7 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having)
|
||||
break; // Remove eventual ending separator(s)
|
||||
|
||||
// if (fp->Convert(g, having))
|
||||
// throw TYPE_ARRAY;
|
||||
// throw (int)TYPE_FILTER;
|
||||
|
||||
filp = fp;
|
||||
fp = fp->Next;
|
||||
@@ -1721,8 +1719,6 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having)
|
||||
|
||||
if (trace)
|
||||
htrc(" returning filp=%p\n", filp);
|
||||
//if (filp)
|
||||
// filp->Print(g, debug, 0);
|
||||
|
||||
return filp;
|
||||
} // end of PrepareFilter
|
||||
@@ -1745,7 +1741,7 @@ DllExport bool ApplyFilter(PGLOBAL g, PFIL filp)
|
||||
// return TRUE;
|
||||
|
||||
if (filp->Eval(g))
|
||||
throw TYPE_FILTER;
|
||||
throw (int)TYPE_FILTER;
|
||||
|
||||
if (trace > 1)
|
||||
htrc("PlugFilter filp=%p result=%d\n",
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/***********************************************************************/
|
||||
/* GLOBAL.H: Declaration file used by all CONNECT implementations. */
|
||||
/* (C) Copyright Olivier Bertrand 1993-2017 */
|
||||
/* (C) Copyright MariaDB Corporation Ab */
|
||||
/* Author Olivier Bertrand 1993-2017 */
|
||||
/***********************************************************************/
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -90,6 +91,7 @@
|
||||
#define TYPE_BIGINT 5
|
||||
#define TYPE_LIST 6
|
||||
#define TYPE_INT 7
|
||||
#define TYPE_DATE 8
|
||||
#define TYPE_DECIM 9
|
||||
#define TYPE_BIN 10
|
||||
#define TYPE_PCHAR 11
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) Olivier Bertrand 2004 - 2017
|
||||
/* Copyright (C) MariaDB Corporation Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -98,9 +98,8 @@
|
||||
rnd_next signals that it has reached the end of its data. Calls to
|
||||
ha_connect::extra() are hints as to what will be occuring to the request.
|
||||
|
||||
Happy use!<br>
|
||||
-Olivier
|
||||
*/
|
||||
Author Olivier Bertrand
|
||||
*/
|
||||
|
||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||
#pragma implementation // gcc: Class implementation
|
||||
@@ -198,11 +197,13 @@ extern "C" {
|
||||
char *ClassPath;
|
||||
#endif // JDBC_SUPPORT
|
||||
|
||||
#if defined(__WIN__)
|
||||
CRITICAL_SECTION parsec; // Used calling the Flex parser
|
||||
#else // !__WIN__
|
||||
pthread_mutex_t parmut = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif // !__WIN__
|
||||
//#if defined(__WIN__)
|
||||
//CRITICAL_SECTION parsec; // Used calling the Flex parser
|
||||
//#else // !__WIN__
|
||||
//pthread_mutex_t parmut = PTHREAD_MUTEX_INITIALIZER;
|
||||
//#endif // !__WIN__
|
||||
pthread_mutex_t parmut;
|
||||
pthread_mutex_t usrmut;
|
||||
|
||||
/***********************************************************************/
|
||||
/* Utility functions. */
|
||||
@@ -221,6 +222,7 @@ void mongo_init(bool);
|
||||
USETEMP UseTemp(void);
|
||||
int GetConvSize(void);
|
||||
TYPCONV GetTypeConv(void);
|
||||
char *GetJsonNull(void);
|
||||
uint GetJsonGrpSize(void);
|
||||
char *GetJavaWrapper(void);
|
||||
uint GetWorkSize(void);
|
||||
@@ -330,6 +332,13 @@ static MYSQL_THDVAR_ENUM(
|
||||
0, // def (no)
|
||||
&xconv_typelib); // typelib
|
||||
|
||||
// Null representation for JSON values
|
||||
static MYSQL_THDVAR_STR(json_null,
|
||||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
|
||||
"Representation of Json null values",
|
||||
// check_json_null, update_json_null,
|
||||
NULL, NULL, "<null>");
|
||||
|
||||
// Estimate max number of rows for JSON aggregate functions
|
||||
static MYSQL_THDVAR_UINT(json_grp_size,
|
||||
PLUGIN_VAR_RQCMDARG, // opt
|
||||
@@ -381,6 +390,8 @@ bool ExactInfo(void) {return THDVAR(current_thd, exact_info);}
|
||||
USETEMP UseTemp(void) {return (USETEMP)THDVAR(current_thd, use_tempfile);}
|
||||
int GetConvSize(void) {return THDVAR(current_thd, conv_size);}
|
||||
TYPCONV GetTypeConv(void) {return (TYPCONV)THDVAR(current_thd, type_conv);}
|
||||
char *GetJsonNull(void)
|
||||
{return connect_hton ? THDVAR(current_thd, json_null) : NULL;}
|
||||
uint GetJsonGrpSize(void)
|
||||
{return connect_hton ? THDVAR(current_thd, json_grp_size) : 10;}
|
||||
uint GetWorkSize(void) {return THDVAR(current_thd, work_size);}
|
||||
@@ -666,10 +677,12 @@ static int connect_init_func(void *p)
|
||||
|
||||
#if defined(__WIN__)
|
||||
sql_print_information("CONNECT: %s", compver);
|
||||
InitializeCriticalSection((LPCRITICAL_SECTION)&parsec);
|
||||
//InitializeCriticalSection((LPCRITICAL_SECTION)&parsec);
|
||||
#else // !__WIN__
|
||||
sql_print_information("CONNECT: %s", version);
|
||||
#endif // !__WIN__
|
||||
pthread_mutex_init(&parmut, NULL);
|
||||
pthread_mutex_init(&usrmut, NULL);
|
||||
|
||||
#if defined(LIBXML2_SUPPORT)
|
||||
XmlInitParserLib();
|
||||
@@ -718,12 +731,13 @@ static int connect_done_func(void *)
|
||||
#endif // JDBC_SUPPORT
|
||||
|
||||
#if defined(__WIN__)
|
||||
DeleteCriticalSection((LPCRITICAL_SECTION)&parsec);
|
||||
//DeleteCriticalSection((LPCRITICAL_SECTION)&parsec);
|
||||
#else // !__WIN__
|
||||
PROFILE_End();
|
||||
#endif // !__WIN__
|
||||
|
||||
for (pc= user_connect::to_users; pc; pc= pn) {
|
||||
pthread_mutex_lock(&usrmut);
|
||||
for (pc= user_connect::to_users; pc; pc= pn) {
|
||||
if (pc->g)
|
||||
PlugCleanup(pc->g, true);
|
||||
|
||||
@@ -731,6 +745,10 @@ static int connect_done_func(void *)
|
||||
delete pc;
|
||||
} // endfor pc
|
||||
|
||||
pthread_mutex_unlock(&usrmut);
|
||||
|
||||
pthread_mutex_destroy(&usrmut);
|
||||
pthread_mutex_destroy(&parmut);
|
||||
connect_hton= NULL;
|
||||
DBUG_RETURN(error);
|
||||
} // end of connect_done_func
|
||||
@@ -843,6 +861,7 @@ ha_connect::~ha_connect(void)
|
||||
static void PopUser(PCONNECT xp)
|
||||
{
|
||||
if (xp) {
|
||||
pthread_mutex_lock(&usrmut);
|
||||
xp->count--;
|
||||
|
||||
if (!xp->count) {
|
||||
@@ -867,6 +886,7 @@ static void PopUser(PCONNECT xp)
|
||||
delete xp;
|
||||
} // endif count
|
||||
|
||||
pthread_mutex_unlock(&usrmut);
|
||||
} // endif xp
|
||||
|
||||
} // end of PopUser
|
||||
@@ -880,23 +900,33 @@ static PCONNECT GetUser(THD *thd, PCONNECT xp)
|
||||
if (!thd)
|
||||
return NULL;
|
||||
|
||||
if (xp && thd == xp->thdp)
|
||||
return xp;
|
||||
if (xp) {
|
||||
if (thd == xp->thdp)
|
||||
return xp;
|
||||
|
||||
for (xp= user_connect::to_users; xp; xp= xp->next)
|
||||
PopUser(xp); // Avoid memory leak
|
||||
} // endif xp
|
||||
|
||||
pthread_mutex_lock(&usrmut);
|
||||
|
||||
for (xp= user_connect::to_users; xp; xp= xp->next)
|
||||
if (thd == xp->thdp)
|
||||
break;
|
||||
|
||||
if (!xp) {
|
||||
if (xp)
|
||||
xp->count++;
|
||||
|
||||
pthread_mutex_unlock(&usrmut);
|
||||
|
||||
if (!xp) {
|
||||
xp= new user_connect(thd);
|
||||
|
||||
if (xp->user_init()) {
|
||||
delete xp;
|
||||
xp= NULL;
|
||||
} // endif user_init
|
||||
} // endif user_init
|
||||
|
||||
} else
|
||||
xp->count++;
|
||||
} // endif xp
|
||||
|
||||
return xp;
|
||||
} // end of GetUser
|
||||
@@ -1024,37 +1054,55 @@ PCSZ GetListOption(PGLOBAL g, PCSZ opname, PCSZ oplist, PCSZ def)
|
||||
if (!oplist)
|
||||
return (char*)def;
|
||||
|
||||
char key[16], val[256];
|
||||
char *pk, *pv, *pn;
|
||||
PCSZ opval= def;
|
||||
int n;
|
||||
char key[16], val[256];
|
||||
char *pv, *pn, *pk = (char*)oplist;
|
||||
PCSZ opval = def;
|
||||
int n;
|
||||
|
||||
for (pk= (char*)oplist; pk; pk= ++pn) {
|
||||
pn= strchr(pk, ',');
|
||||
pv= strchr(pk, '=');
|
||||
while (*pk == ' ')
|
||||
pk++;
|
||||
|
||||
if (pv && (!pn || pv < pn)) {
|
||||
n= MY_MIN(pv - pk, (int)sizeof(key) - 1);
|
||||
memcpy(key, pk, n);
|
||||
key[n]= 0;
|
||||
pv++;
|
||||
n= MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1);
|
||||
memcpy(val, pv, n);
|
||||
val[n]= 0;
|
||||
} else {
|
||||
n= MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1);
|
||||
memcpy(key, pk, n);
|
||||
key[n]= 0;
|
||||
val[0]= 0;
|
||||
} // endif pv
|
||||
for (; pk; pk = pn) {
|
||||
pn = strchr(pk, ',');
|
||||
pv = strchr(pk, '=');
|
||||
|
||||
if (!stricmp(opname, key)) {
|
||||
opval= PlugDup(g, val);
|
||||
break;
|
||||
} else if (!pn)
|
||||
break;
|
||||
if (pv && (!pn || pv < pn)) {
|
||||
n = MY_MIN(static_cast<size_t>(pv - pk), sizeof(key) - 1);
|
||||
memcpy(key, pk, n);
|
||||
|
||||
} // endfor pk
|
||||
while (n && key[n - 1] == ' ')
|
||||
n--;
|
||||
|
||||
key[n] = 0;
|
||||
|
||||
while (*(++pv) == ' ');
|
||||
|
||||
n = MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1);
|
||||
memcpy(val, pv, n);
|
||||
|
||||
while (n && val[n - 1] == ' ')
|
||||
n--;
|
||||
|
||||
val[n] = 0;
|
||||
} else {
|
||||
n = MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1);
|
||||
memcpy(key, pk, n);
|
||||
|
||||
while (n && key[n - 1] == ' ')
|
||||
n--;
|
||||
|
||||
key[n] = 0;
|
||||
val[0] = 0;
|
||||
} // endif pv
|
||||
|
||||
if (!stricmp(opname, key)) {
|
||||
opval = PlugDup(g, val);
|
||||
break;
|
||||
} else if (!pn)
|
||||
break;
|
||||
|
||||
while (*(++pn) == ' ');
|
||||
} // endfor pk
|
||||
|
||||
return opval;
|
||||
} // end of GetListOption
|
||||
@@ -1427,7 +1475,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
pcf->Flags |= U_VAR;
|
||||
/* fall through */
|
||||
// fall through
|
||||
default:
|
||||
pcf->Type= MYSQLtoPLG(fp->type(), &v);
|
||||
break;
|
||||
@@ -2802,7 +2850,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
|
||||
case Item_func::LIKE_FUNC: vop= OP_LIKE; break;
|
||||
case Item_func::ISNOTNULL_FUNC:
|
||||
neg = true;
|
||||
/* fall through */
|
||||
// fall through
|
||||
case Item_func::ISNULL_FUNC: vop= OP_NULL; break;
|
||||
case Item_func::IN_FUNC: vop= OP_IN;
|
||||
case Item_func::BETWEEN:
|
||||
@@ -4052,7 +4100,12 @@ int ha_connect::info(uint flag)
|
||||
|
||||
DBUG_ENTER("ha_connect::info");
|
||||
|
||||
if (trace)
|
||||
if (!g) {
|
||||
my_message(ER_UNKNOWN_ERROR, "Cannot get g pointer", MYF(0));
|
||||
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||
} // endif g
|
||||
|
||||
if (trace)
|
||||
htrc("%p In info: flag=%u valid_info=%d\n", this, flag, valid_info);
|
||||
|
||||
// tdbp must be available to get updated info
|
||||
@@ -4063,7 +4116,7 @@ int ha_connect::info(uint flag)
|
||||
if (xmod == MODE_ANY || xmod == MODE_ALTER) {
|
||||
// Pure info, not a query
|
||||
pure= true;
|
||||
xp->CheckCleanup();
|
||||
xp->CheckCleanup(xmod == MODE_ANY && valid_query_id == 0);
|
||||
} // endif xmod
|
||||
|
||||
// This is necessary for getting file length
|
||||
@@ -4247,8 +4300,8 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick)
|
||||
} else
|
||||
return false;
|
||||
|
||||
/* check FILE_ACL */
|
||||
/* fall through */
|
||||
// check FILE_ACL
|
||||
// fall through
|
||||
case TAB_ODBC:
|
||||
case TAB_JDBC:
|
||||
case TAB_MYSQL:
|
||||
@@ -7060,7 +7113,8 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
|
||||
#if defined(XMSG)
|
||||
MYSQL_SYSVAR(errmsg_dir_path),
|
||||
#endif // XMSG
|
||||
MYSQL_SYSVAR(json_grp_size),
|
||||
MYSQL_SYSVAR(json_null),
|
||||
MYSQL_SYSVAR(json_grp_size),
|
||||
#if defined(JDBC_SUPPORT)
|
||||
MYSQL_SYSVAR(jvm_path),
|
||||
MYSQL_SYSVAR(class_path),
|
||||
@@ -7083,6 +7137,6 @@ maria_declare_plugin(connect)
|
||||
NULL, /* status variables */
|
||||
connect_system_variables, /* system variables */
|
||||
"1.06.0001", /* string version */
|
||||
MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */
|
||||
MariaDB_PLUGIN_MATURITY_BETA /* maturity */
|
||||
}
|
||||
maria_declare_plugin_end;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) Olivier Bertrand 2004 - 2015
|
||||
/* Copyright (C) MariaDB Corporation Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,7 @@
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
|
||||
|
||||
/** @file ha_connect.h
|
||||
Author Olivier Bertrand
|
||||
|
||||
@brief
|
||||
The ha_connect engine is a prototype storage engine to access external data.
|
||||
|
@@ -120,66 +120,81 @@ int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v)
|
||||
int type;
|
||||
|
||||
switch (stp) {
|
||||
case -1: // LONGVARCHAR
|
||||
if (GetTypeConv() != TPC_YES)
|
||||
return TYPE_ERROR;
|
||||
else
|
||||
len = MY_MIN(abs(len), GetConvSize());
|
||||
case 12: // VARCHAR
|
||||
v = 'V';
|
||||
case 1: // CHAR
|
||||
type = TYPE_STRING;
|
||||
break;
|
||||
case 2: // NUMERIC
|
||||
case 3: // DECIMAL
|
||||
case -3: // VARBINARY
|
||||
type = TYPE_DECIM;
|
||||
break;
|
||||
case 4: // INTEGER
|
||||
type = TYPE_INT;
|
||||
break;
|
||||
case 5: // SMALLINT
|
||||
type = TYPE_SHORT;
|
||||
break;
|
||||
case -6: // TINYINT
|
||||
case -7: // BIT
|
||||
type = TYPE_TINY;
|
||||
break;
|
||||
case 6: // FLOAT
|
||||
case 7: // REAL
|
||||
case 8: // DOUBLE
|
||||
type = TYPE_DOUBLE;
|
||||
break;
|
||||
case 93: // TIMESTAMP, DATETIME
|
||||
type = TYPE_DATE;
|
||||
len = 19 + ((prec) ? (prec+1) : 0);
|
||||
v = (tn && toupper(tn[0]) == 'T') ? 'S' : 'E';
|
||||
break;
|
||||
case 91: // DATE, YEAR
|
||||
type = TYPE_DATE;
|
||||
case -1: // LONGVARCHAR
|
||||
case -16: // LONGNVARCHAR (unicode)
|
||||
if (GetTypeConv() != TPC_YES)
|
||||
return TYPE_ERROR;
|
||||
else
|
||||
len = MY_MIN(abs(len), GetConvSize());
|
||||
case 12: // VARCHAR
|
||||
case -9: // NVARCHAR (unicode)
|
||||
v = 'V';
|
||||
case 1: // CHAR
|
||||
case -15: // NCHAR (unicode)
|
||||
case -8: // ROWID
|
||||
type = TYPE_STRING;
|
||||
break;
|
||||
case 2: // NUMERIC
|
||||
case 3: // DECIMAL
|
||||
case -3: // VARBINARY
|
||||
type = TYPE_DECIM;
|
||||
break;
|
||||
case 4: // INTEGER
|
||||
type = TYPE_INT;
|
||||
break;
|
||||
case 5: // SMALLINT
|
||||
type = TYPE_SHORT;
|
||||
break;
|
||||
case -6: // TINYINT
|
||||
case -7: // BIT
|
||||
case 16: // BOOLEAN
|
||||
type = TYPE_TINY;
|
||||
break;
|
||||
case 6: // FLOAT
|
||||
case 7: // REAL
|
||||
case 8: // DOUBLE
|
||||
type = TYPE_DOUBLE;
|
||||
break;
|
||||
case 93: // TIMESTAMP, DATETIME
|
||||
type = TYPE_DATE;
|
||||
len = 19 + ((prec) ? (prec + 1) : 0);
|
||||
v = (tn && toupper(tn[0]) == 'T') ? 'S' : 'E';
|
||||
break;
|
||||
case 91: // DATE, YEAR
|
||||
type = TYPE_DATE;
|
||||
|
||||
if (!tn || toupper(tn[0]) != 'Y') {
|
||||
len = 10;
|
||||
v = 'D';
|
||||
} else {
|
||||
len = 4;
|
||||
v = 'Y';
|
||||
} // endif len
|
||||
if (!tn || toupper(tn[0]) != 'Y') {
|
||||
len = 10;
|
||||
v = 'D';
|
||||
} else {
|
||||
len = 4;
|
||||
v = 'Y';
|
||||
} // endif len
|
||||
|
||||
break;
|
||||
case 92: // TIME
|
||||
type = TYPE_DATE;
|
||||
len = 8 + ((prec) ? (prec+1) : 0);
|
||||
v = 'T';
|
||||
break;
|
||||
case -5: // BIGINT
|
||||
type = TYPE_BIGINT;
|
||||
break;
|
||||
case 0: // NULL
|
||||
case -2: // BINARY
|
||||
case -4: // LONGVARBINARY
|
||||
default:
|
||||
type = TYPE_ERROR;
|
||||
break;
|
||||
case 92: // TIME
|
||||
type = TYPE_DATE;
|
||||
len = 8 + ((prec) ? (prec + 1) : 0);
|
||||
v = 'T';
|
||||
break;
|
||||
case -5: // BIGINT
|
||||
type = TYPE_BIGINT;
|
||||
break;
|
||||
case 0: // NULL
|
||||
case -2: // BINARY
|
||||
case -4: // LONGVARBINARY
|
||||
case 70: // DATALINK
|
||||
case 2000: // JAVA_OBJECT
|
||||
case 2001: // DISTINCT
|
||||
case 2002: // STRUCT
|
||||
case 2003: // ARRAY
|
||||
case 2004: // BLOB
|
||||
case 2005: // CLOB
|
||||
case 2006: // REF
|
||||
case 2009: // SQLXML
|
||||
case 2011: // NCLOB
|
||||
default:
|
||||
type = TYPE_ERROR;
|
||||
len = 0;
|
||||
} // endswitch type
|
||||
|
||||
@@ -1200,7 +1215,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));
|
||||
throw TYPE_AM_JDBC;
|
||||
throw (int)TYPE_AM_JDBC;
|
||||
} // endif name
|
||||
|
||||
// Returns 666 is case of error
|
||||
@@ -1208,7 +1223,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
|
||||
|
||||
if (Check((ctyp == 666) ? -1 : 1)) {
|
||||
sprintf(g->Message, "Getting ctyp: %s", Msg);
|
||||
throw TYPE_AM_JDBC;
|
||||
throw (int)TYPE_AM_JDBC;
|
||||
} // endif Check
|
||||
|
||||
if (val->GetNullable())
|
||||
@@ -1225,9 +1240,12 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
|
||||
|
||||
switch (ctyp) {
|
||||
case 12: // VARCHAR
|
||||
case -9: // NVARCHAR
|
||||
case -1: // LONGVARCHAR
|
||||
case 1: // CHAR
|
||||
case 3: // DECIMAL
|
||||
case -15: // NCHAR
|
||||
case 3: // DECIMAL
|
||||
case -8: // ROWID
|
||||
if (jb && ctyp != 3)
|
||||
cn = (jstring)jb;
|
||||
else if (!gmID(g, chrfldid, "StringField", "(ILjava/lang/String;)Ljava/lang/String;"))
|
||||
@@ -1245,6 +1263,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
|
||||
case 4: // INTEGER
|
||||
case 5: // SMALLINT
|
||||
case -6: // TINYINT
|
||||
case 16: // BOOLEAN
|
||||
case -7: // BIT
|
||||
if (!gmID(g, intfldid, "IntField", "(ILjava/lang/String;)I"))
|
||||
val->SetValue((int)env->CallIntMethod(job, intfldid, rank, jn));
|
||||
@@ -1315,7 +1334,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);
|
||||
throw TYPE_AM_JDBC;
|
||||
throw (int)TYPE_AM_JDBC;
|
||||
} // endif Check
|
||||
|
||||
if (rank == 0)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*************** json CPP Declares Source Code File (.H) ***************/
|
||||
/* Name: json.cpp Version 1.3 */
|
||||
/* Name: json.cpp Version 1.4 */
|
||||
/* */
|
||||
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
|
||||
/* */
|
||||
@@ -53,6 +53,38 @@ void trans_func(unsigned int u, _EXCEPTION_POINTERS* pExp)
|
||||
char *GetExceptionDesc(PGLOBAL g, unsigned int e);
|
||||
#endif // SE_CATCH
|
||||
|
||||
char *GetJsonNull(void);
|
||||
|
||||
/***********************************************************************/
|
||||
/* IsNum: check whether this string is all digits. */
|
||||
/***********************************************************************/
|
||||
bool IsNum(PSZ s)
|
||||
{
|
||||
for (char *p = s; *p; p++)
|
||||
if (*p == ']')
|
||||
break;
|
||||
else if (!isdigit(*p) || *p == '-')
|
||||
return false;
|
||||
|
||||
return true;
|
||||
} // end of IsNum
|
||||
|
||||
/***********************************************************************/
|
||||
/* NextChr: return the first found '[' or Sep pointer. */
|
||||
/***********************************************************************/
|
||||
char *NextChr(PSZ s, char sep)
|
||||
{
|
||||
char *p1 = strchr(s, '[');
|
||||
char *p2 = strchr(s, sep);
|
||||
|
||||
if (!p2)
|
||||
return p1;
|
||||
else if (p1)
|
||||
return MY_MIN(p1, p2);
|
||||
|
||||
return p2;
|
||||
} // end of NextChr
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/* Parse a json string. */
|
||||
@@ -933,6 +965,25 @@ return false;
|
||||
|
||||
/* -------------------------- Class JOBJECT -------------------------- */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Return the number of pairs in this object. */
|
||||
/***********************************************************************/
|
||||
int JOBJECT::GetSize(bool b)
|
||||
{
|
||||
if (b) {
|
||||
// Return only non null pairs
|
||||
int n = 0;
|
||||
|
||||
for (PJPR jpp = First; jpp; jpp = jpp->Next)
|
||||
if (jpp->Val && !jpp->Val->IsNull())
|
||||
n++;
|
||||
|
||||
return n;
|
||||
} else
|
||||
return Size;
|
||||
|
||||
} // end of GetSize
|
||||
|
||||
/***********************************************************************/
|
||||
/* Add a new pair to an Object. */
|
||||
/***********************************************************************/
|
||||
@@ -992,14 +1043,31 @@ PSZ JOBJECT::GetText(PGLOBAL g, PSZ text)
|
||||
|
||||
if (!First && n)
|
||||
return NULL;
|
||||
else for (PJPR jp = First; jp; jp = jp->Next)
|
||||
else if (n == 1 && Size == 1 && !strcmp(First->GetKey(), "$date")) {
|
||||
int i;
|
||||
|
||||
First->Val->GetText(g, text);
|
||||
i = (text[1] == '-' ? 2 : 1);
|
||||
|
||||
if (IsNum(text + i)) {
|
||||
// Date is in milliseconds
|
||||
int j = (int)strlen(text);
|
||||
|
||||
if (j >= 4 + i)
|
||||
text[j - 3] = 0; // Change it to seconds
|
||||
else
|
||||
strcpy(text, " 0");
|
||||
|
||||
} // endif text
|
||||
|
||||
} else for (PJPR jp = First; jp; jp = jp->Next)
|
||||
jp->Val->GetText(g, text);
|
||||
|
||||
if (n)
|
||||
PlugSubAlloc(g, NULL, strlen(text) + 1);
|
||||
|
||||
return text + n;
|
||||
} // end of GetValue;
|
||||
} // end of GetText;
|
||||
|
||||
/***********************************************************************/
|
||||
/* Merge two objects. */
|
||||
@@ -1040,7 +1108,7 @@ void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PCSZ key)
|
||||
} // end of SetValue
|
||||
|
||||
/***********************************************************************/
|
||||
/* Delete a value corresponding to the given key. */
|
||||
/* Delete a value corresponding to the given key. */
|
||||
/***********************************************************************/
|
||||
void JOBJECT::DeleteKey(PCSZ key)
|
||||
{
|
||||
@@ -1070,6 +1138,25 @@ bool JOBJECT::IsNull(void)
|
||||
|
||||
/* -------------------------- Class JARRAY --------------------------- */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Return the number of values in this object. */
|
||||
/***********************************************************************/
|
||||
int JARRAY::GetSize(bool b)
|
||||
{
|
||||
if (b) {
|
||||
// Return only non null values
|
||||
int n = 0;
|
||||
|
||||
for (PJVAL jvp = First; jvp; jvp = jvp->Next)
|
||||
if (!jvp->IsNull())
|
||||
n++;
|
||||
|
||||
return n;
|
||||
} else
|
||||
return Size;
|
||||
|
||||
} // end of GetSize
|
||||
|
||||
/***********************************************************************/
|
||||
/* Make the array of values from the values list. */
|
||||
/***********************************************************************/
|
||||
@@ -1178,18 +1265,42 @@ bool JARRAY::SetValue(PGLOBAL g, PJVAL jvp, int n)
|
||||
return false;
|
||||
} // end of SetValue
|
||||
|
||||
/***********************************************************************/
|
||||
/* Return the text corresponding to all values. */
|
||||
/***********************************************************************/
|
||||
PSZ JARRAY::GetText(PGLOBAL g, PSZ text)
|
||||
{
|
||||
int n;
|
||||
PJVAL jp;
|
||||
|
||||
if (!text) {
|
||||
text = (char*)PlugSubAlloc(g, NULL, 0);
|
||||
text[0] = 0;
|
||||
n = 1;
|
||||
} else
|
||||
n = 0;
|
||||
|
||||
for (jp = First; jp; jp = jp->Next)
|
||||
jp->GetText(g, text);
|
||||
|
||||
if (n)
|
||||
PlugSubAlloc(g, NULL, strlen(text) + 1);
|
||||
|
||||
return text + n;
|
||||
} // end of GetText;
|
||||
|
||||
/***********************************************************************/
|
||||
/* Delete a Value from the Arrays Value list. */
|
||||
/***********************************************************************/
|
||||
bool JARRAY::DeleteValue(int n)
|
||||
{
|
||||
PJVAL jvp = GetValue(n);
|
||||
PJVAL jvp = GetValue(n);
|
||||
|
||||
if (jvp) {
|
||||
jvp->Del = true;
|
||||
return false;
|
||||
} else
|
||||
return true;
|
||||
if (jvp) {
|
||||
jvp->Del = true;
|
||||
return false;
|
||||
} else
|
||||
return true;
|
||||
|
||||
} // end of DeleteValue
|
||||
|
||||
@@ -1239,7 +1350,7 @@ JTYP JVALUE::GetValType(void)
|
||||
else if (Value)
|
||||
return (JTYP)Value->GetType();
|
||||
else
|
||||
return (JTYP)TYPE_VOID;
|
||||
return TYPE_NULL;
|
||||
|
||||
} // end of GetValType
|
||||
|
||||
@@ -1303,7 +1414,7 @@ PSZ JVALUE::GetString(void)
|
||||
/***********************************************************************/
|
||||
PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
|
||||
{
|
||||
if (Jsp && Jsp->GetType() == TYPE_JOB)
|
||||
if (Jsp)
|
||||
return Jsp->GetText(g, text);
|
||||
|
||||
char buf[32];
|
||||
@@ -1311,8 +1422,8 @@ PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
|
||||
|
||||
if (s)
|
||||
strcat(strcat(text, " "), s);
|
||||
else
|
||||
strcat(text, " ???");
|
||||
else if (GetJsonNull())
|
||||
strcat(strcat(text, " "), GetJsonNull());
|
||||
|
||||
return text;
|
||||
} // end of GetText
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/**************** json H Declares Source Code File (.H) ****************/
|
||||
/* Name: json.h Version 1.2 */
|
||||
/* */
|
||||
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */
|
||||
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
|
||||
/* */
|
||||
/* This file contains the JSON classes declares. */
|
||||
/***********************************************************************/
|
||||
@@ -13,11 +13,13 @@
|
||||
#define X
|
||||
#endif
|
||||
|
||||
enum JTYP {TYPE_STRG = 1,
|
||||
TYPE_DBL = 2,
|
||||
TYPE_BOOL = 4,
|
||||
TYPE_BINT = 5,
|
||||
TYPE_INTG = 7,
|
||||
enum JTYP {TYPE_NULL = TYPE_VOID,
|
||||
TYPE_STRG = TYPE_STRING,
|
||||
TYPE_DBL = TYPE_DOUBLE,
|
||||
TYPE_BOOL = TYPE_TINY,
|
||||
TYPE_BINT = TYPE_BIGINT,
|
||||
TYPE_DTM = TYPE_DATE,
|
||||
TYPE_INTG = TYPE_INT,
|
||||
TYPE_JSON = 12,
|
||||
TYPE_JAR,
|
||||
TYPE_JOB,
|
||||
@@ -145,6 +147,7 @@ class JSON : public BLOCK {
|
||||
JSON(void) {Size = 0;}
|
||||
|
||||
int size(void) {return Size;}
|
||||
virtual int GetSize(bool b) {return Size;}
|
||||
virtual void Clear(void) {Size = 0;}
|
||||
virtual JTYP GetType(void) {return TYPE_JSON;}
|
||||
virtual JTYP GetValType(void) {X return TYPE_JSON;}
|
||||
@@ -192,10 +195,11 @@ class JOBJECT : public JSON {
|
||||
|
||||
using JSON::GetValue;
|
||||
using JSON::SetValue;
|
||||
virtual void Clear(void) {First = Last = NULL; Size = 0;}
|
||||
virtual void Clear(void) {First = Last = NULL; Size = 0;}
|
||||
virtual JTYP GetType(void) {return TYPE_JOB;}
|
||||
virtual PJPR GetFirst(void) {return First;}
|
||||
virtual PJPR AddPair(PGLOBAL g, PCSZ key);
|
||||
virtual int GetSize(bool b);
|
||||
virtual PJPR AddPair(PGLOBAL g, PCSZ key);
|
||||
virtual PJOB GetObject(void) {return this;}
|
||||
virtual PJVAL GetValue(const char* key);
|
||||
virtual PJAR GetKeyList(PGLOBAL g);
|
||||
@@ -221,11 +225,13 @@ class JARRAY : public JSON {
|
||||
using JSON::GetValue;
|
||||
using JSON::SetValue;
|
||||
virtual void Clear(void) {First = Last = NULL; Size = 0;}
|
||||
virtual JTYP GetType(void) {return TYPE_JAR;}
|
||||
virtual JTYP GetType(void) {return TYPE_JAR;}
|
||||
virtual PJAR GetArray(void) {return this;}
|
||||
PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL);
|
||||
virtual int GetSize(bool b);
|
||||
PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL);
|
||||
virtual void InitArray(PGLOBAL g);
|
||||
virtual PJVAL GetValue(int i);
|
||||
virtual PSZ GetText(PGLOBAL g, PSZ text);
|
||||
virtual bool Merge(PGLOBAL g, PJSON jsp);
|
||||
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i);
|
||||
virtual bool DeleteValue(int n);
|
||||
@@ -245,20 +251,20 @@ class JARRAY : public JSON {
|
||||
class JVALUE : public JSON {
|
||||
friend class JARRAY;
|
||||
friend class JSNX;
|
||||
friend class JSONCOL;
|
||||
friend PJVAL ParseValue(PGLOBAL, int&, STRG&, bool*);
|
||||
friend bool SerializeValue(JOUT *, PJVAL);
|
||||
public:
|
||||
JVALUE(void) : JSON()
|
||||
{Jsp = NULL; Value = NULL; Next = NULL; Del = false;}
|
||||
JVALUE(void) : JSON() {Clear();}
|
||||
JVALUE(PJSON jsp) : JSON()
|
||||
{Jsp = jsp; Value = NULL; Next = NULL; Del = false;}
|
||||
JVALUE(PGLOBAL g, PVAL valp);
|
||||
{Jsp = jsp; Value = NULL; Next = NULL; Del = false; Size = 1;}
|
||||
JVALUE(PGLOBAL g, PVAL valp);
|
||||
JVALUE(PGLOBAL g, PCSZ strp);
|
||||
|
||||
using JSON::GetValue;
|
||||
using JSON::SetValue;
|
||||
virtual void Clear(void)
|
||||
{Jsp = NULL; Value = NULL; Next = NULL; Del = false; Size = 0;}
|
||||
{Jsp = NULL; Value = NULL; Next = NULL; Del = false; Size = 1;}
|
||||
virtual JTYP GetType(void) {return TYPE_JVAL;}
|
||||
virtual JTYP GetValType(void);
|
||||
virtual PJOB GetObject(void);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/****************** jsonudf C++ Program Source Code File (.CPP) ******************/
|
||||
/* PROGRAM NAME: jsonudf Version 1.5 */
|
||||
/* PROGRAM NAME: jsonudf Version 1.6 */
|
||||
/* (C) Copyright to the author Olivier BERTRAND 2015-2017 */
|
||||
/* This program are the JSON User Defined Functions . */
|
||||
/*********************************************************************************/
|
||||
@@ -27,7 +27,8 @@
|
||||
#endif
|
||||
#define M 7
|
||||
|
||||
uint GetJsonGrpSize(void);
|
||||
char *GetJsonNull(void);
|
||||
uint GetJsonGrpSize(void);
|
||||
static int IsJson(UDF_ARGS *args, uint i);
|
||||
static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i);
|
||||
static char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
|
||||
@@ -327,11 +328,13 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
|
||||
SetJsonValue(g, vp, val->GetArray()->GetValue(0), n);
|
||||
break;
|
||||
case TYPE_JOB:
|
||||
// if (!vp->IsTypeNum() || !Strict) {
|
||||
// if (!vp->IsTypeNum() || !Strict) {
|
||||
vp->SetValue_psz(val->GetObject()->GetText(g, NULL));
|
||||
break;
|
||||
// } // endif Type
|
||||
// } // endif Type
|
||||
|
||||
case TYPE_NULL:
|
||||
vp->SetNull(true);
|
||||
default:
|
||||
vp->Reset();
|
||||
} // endswitch Type
|
||||
@@ -459,7 +462,7 @@ PVAL JSNX::ExpandArray(PGLOBAL g, PJAR arp, int n)
|
||||
/*********************************************************************************/
|
||||
PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
|
||||
{
|
||||
//int i, ars, nv = 0, nextsame = Tjp->NextSame;
|
||||
//int i, ars, nv = 0, nextsame = Tjp->NextSame;
|
||||
int i, ars, nv = 0, nextsame = 0;
|
||||
my_bool err;
|
||||
OPVAL op = Nodes[n].Op;
|
||||
@@ -468,15 +471,16 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
|
||||
JVALUE jval;
|
||||
|
||||
vp->Reset();
|
||||
//ars = MY_MIN(Tjp->Limit, arp->size());
|
||||
ars = arp->size();
|
||||
|
||||
for (i = 0; i < ars; i++) {
|
||||
jvrp = arp->GetValue(i);
|
||||
|
||||
// do {
|
||||
if (n < Nod - 1 && jvrp->GetJson()) {
|
||||
// Tjp->NextSame = nextsame;
|
||||
if (!jvrp->IsNull() || (op == OP_CNC && GetJsonNull())) {
|
||||
if (jvrp->IsNull()) {
|
||||
jvrp->Value = AllocateValue(g, GetJsonNull(), TYPE_STRING);
|
||||
jvp = jvrp;
|
||||
} else if (n < Nod - 1 && jvrp->GetJson()) {
|
||||
jval.SetValue(GetColumnValue(g, jvrp->GetJson(), n + 1));
|
||||
jvp = &jval;
|
||||
} else
|
||||
@@ -490,25 +494,25 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
|
||||
|
||||
if (!MulVal->IsZero()) {
|
||||
switch (op) {
|
||||
case OP_CNC:
|
||||
if (Nodes[n].CncVal) {
|
||||
val[0] = Nodes[n].CncVal;
|
||||
err = vp->Compute(g, val, 1, op);
|
||||
} // endif CncVal
|
||||
case OP_CNC:
|
||||
if (Nodes[n].CncVal) {
|
||||
val[0] = Nodes[n].CncVal;
|
||||
err = vp->Compute(g, val, 1, op);
|
||||
} // endif CncVal
|
||||
|
||||
val[0] = MulVal;
|
||||
err = vp->Compute(g, val, 1, op);
|
||||
break;
|
||||
// case OP_NUM:
|
||||
case OP_SEP:
|
||||
val[0] = Nodes[n].Valp;
|
||||
val[1] = MulVal;
|
||||
err = vp->Compute(g, val, 2, OP_ADD);
|
||||
break;
|
||||
default:
|
||||
val[0] = Nodes[n].Valp;
|
||||
val[1] = MulVal;
|
||||
err = vp->Compute(g, val, 2, op);
|
||||
val[0] = MulVal;
|
||||
err = vp->Compute(g, val, 1, op);
|
||||
break;
|
||||
// case OP_NUM:
|
||||
case OP_SEP:
|
||||
val[0] = Nodes[n].Valp;
|
||||
val[1] = MulVal;
|
||||
err = vp->Compute(g, val, 2, OP_ADD);
|
||||
break;
|
||||
default:
|
||||
val[0] = Nodes[n].Valp;
|
||||
val[1] = MulVal;
|
||||
err = vp->Compute(g, val, 2, op);
|
||||
} // endswitch Op
|
||||
|
||||
if (err)
|
||||
@@ -516,7 +520,7 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
|
||||
|
||||
} // endif Zero
|
||||
|
||||
// } while (Tjp->NextSame > nextsame);
|
||||
} // endif jvrp
|
||||
|
||||
} // endfor i
|
||||
|
||||
@@ -1081,6 +1085,7 @@ inline void JsonMemSave(PGLOBAL g)
|
||||
/*********************************************************************************/
|
||||
inline void JsonFreeMem(PGLOBAL g)
|
||||
{
|
||||
g->Activityp = NULL;
|
||||
PlugExit(g);
|
||||
} /* end of JsonFreeMem */
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* Copyright (C) MariaDB Corporation Ab */
|
||||
#define MSG_ACCESS_VIOLATN 200
|
||||
#define MSG_ADD_BAD_TYPE 201
|
||||
#define MSG_ALLOC_ERROR 202
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) Olivier Bertrand 2004 - 2017
|
||||
/* Copyright (C) MariaDB Corporation Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) Olivier Bertrand 2004 - 2015
|
||||
/* Copyright (C) MariaDB Corporation Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
/**************** MYCAT H Declares Source Code File (.H) ***************/
|
||||
/* Name: MYCAT.H Version 2.3 */
|
||||
/* */
|
||||
/* Author: Olivier Bertrand */
|
||||
/* This file contains the CONNECT plugin MYCAT class definitions. */
|
||||
/***********************************************************************/
|
||||
#ifndef __MYCAT__H
|
||||
|
14
storage/connect/mysql-test/connect/r/drop-open-error.result
Normal file
14
storage/connect/mysql-test/connect/r/drop-open-error.result
Normal file
File diff suppressed because one or more lines are too long
@@ -1,6 +1,7 @@
|
||||
#
|
||||
# MDEV-7574 Security definer views don't work with CONNECT ODBC tables
|
||||
#
|
||||
CREATE USER user@localhost;
|
||||
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
|
||||
REVOKE FILE ON *.* FROM user@localhost;
|
||||
# Testing SQLCOM_SELECT
|
||||
@@ -621,7 +622,7 @@ test.t1 optimize status OK
|
||||
OPTIMIZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize Error Access denied for user 'user'@'localhost' (using password: NO)
|
||||
test.t1 optimize Error Can't lock file (errno: 122 "Internal (unspecified) error in handler")
|
||||
test.t1 optimize Error Got error 122 'This operation requires the FILE privilege' from CONNECT
|
||||
test.t1 optimize error Corrupt
|
||||
DROP TABLE t1;
|
||||
# Testing SQLCOM_ALTER_TABLE (adding columns)
|
||||
|
12
storage/connect/mysql-test/connect/r/infoschema-9739.result
Normal file
12
storage/connect/mysql-test/connect/r/infoschema-9739.result
Normal file
@@ -0,0 +1,12 @@
|
||||
Warnings:
|
||||
Warning 1105 No file name. Table will use t1.xml
|
||||
create table t1 (i int) engine=Connect table_type=XML;
|
||||
Warnings:
|
||||
Warning 1105 No file name. Table will use t1.xml
|
||||
select * from information_schema.tables where create_options like '%table_type=XML%';
|
||||
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
|
||||
Warnings:
|
||||
Warning 1286 Unknown storage engine 'InnoDB'
|
||||
Warning 1286 Unknown storage engine 'InnoDB'
|
||||
Warning 1296 Got error 174 'File t1.xml not found' from CONNECT
|
||||
drop table t1;
|
@@ -608,7 +608,7 @@ JsonGet_String(Json_File('test/fx.json'), '[1]:*')
|
||||
{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]}
|
||||
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]');
|
||||
JsonGet_String(Json_File('test/fx.json'), '[1]')
|
||||
6 car roadster 56000 ???
|
||||
6 car roadster 56000 6 9
|
||||
SELECT JsonGet_Int(Json_File('test/fx.json'), '[1]:mileage') AS Mileage;
|
||||
Mileage
|
||||
56000
|
||||
|
@@ -178,7 +178,7 @@ DROP TABLE t1;
|
||||
#
|
||||
# Testing temporal data types
|
||||
#
|
||||
CREATE TABLE t1 (a date, b datetime, c time, d timestamp, e year);
|
||||
CREATE TABLE t1 (a date, b datetime, c time, d timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, e year);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
|
165
storage/connect/mysql-test/connect/r/odbc_firebird.result
Normal file
165
storage/connect/mysql-test/connect/r/odbc_firebird.result
Normal file
@@ -0,0 +1,165 @@
|
||||
SET NAMES utf8;
|
||||
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='Bad connection string';
|
||||
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Sources;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`Name` varchar(256) NOT NULL,
|
||||
`Description` varchar(256) DEFAULT NULL
|
||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Sources'
|
||||
SELECT * FROM t1;
|
||||
Name Description
|
||||
dBASE Files Microsoft Access dBASE Driver (*.dbf, *.ndx, *.mdx)
|
||||
PLUGDB_DEBUG PLUGODBC_Driver
|
||||
PLUGDB_ODBC PLUGODBC_Driver
|
||||
SafeDB_ODBC SDB_ODBC_Driver
|
||||
Firebird Firebird/InterBase(r) driver
|
||||
ConnectEngineXLS Microsoft Excel Driver (*.xls)
|
||||
Excel Files Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)
|
||||
MariaODBC MySQL ODBC 5.2a Driver
|
||||
MariaODBCbeta MariaDB ODBC 1.0 Driver
|
||||
MyODBC MySQL ODBC 5.2a Driver
|
||||
MS Access Database Microsoft Access Driver (*.mdb, *.accdb)
|
||||
MS Access Db1 Microsoft Access Driver (*.mdb)
|
||||
MySQL-ANSI MySQL ODBC 5.3 ANSI Driver
|
||||
MySQL-Unicode MySQL ODBC 5.3 Unicode Driver
|
||||
Xtreme Sample Database 2008 Microsoft Access Driver (*.mdb)
|
||||
PlugDB test PLUGODBC_Driver
|
||||
SQLite3 Datasource SQLite3 ODBC Driver
|
||||
SQLite Datasource SQLite ODBC Driver
|
||||
SQLite UTF-8 Datasource SQLite ODBC (UTF-8) Driver
|
||||
ORACLE_TEST Oracle in XE
|
||||
ConnectEnginePostgresql PostgreSQL ODBC Driver(ANSI)
|
||||
ConnectEngineOracle Oracle in XE
|
||||
ConnectEngineSQLServer SQL Server
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Drivers;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`Description` char(128) NOT NULL,
|
||||
`Attributes` varchar(256) DEFAULT NULL
|
||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers'
|
||||
SELECT * FROM t1;
|
||||
Description Attributes
|
||||
SQL Server UsageCount=1;SQLLevel=1;FileUsage=0;DriverODBCVer=03.50;ConnectFunctions=YYY;APILevel=2;CPTimeout=60;
|
||||
Microsoft ODBC for Oracle UsageCount=1;SQLLevel=1;FileUsage=0;DriverODBCVer=02.50;ConnectFunctions=YYY;APILevel=1;CPTimeout=120;
|
||||
Microsoft Access Driver (*.mdb) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=2;FileExtns=*.mdb;SQLLevel=0;
|
||||
Microsoft Access-Treiber (*.mdb) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=2;FileExtns=*.mdb;SQLLevel=0;
|
||||
Driver do Microsoft Access (*.mdb) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=2;FileExtns=*.mdb;SQLLevel=0;
|
||||
Microsoft dBase Driver (*.dbf) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.dbf,*.ndx,*.mdx;SQLLevel=0;
|
||||
Microsoft dBase-Treiber (*.dbf) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.dbf,*.ndx,*.mdx;SQLLevel=0;
|
||||
Driver do Microsoft dBase (*.dbf) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.dbf,*.ndx,*.mdx;SQLLevel=0;
|
||||
Microsoft Excel Driver (*.xls) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.xls;SQLLevel=0;
|
||||
Microsoft Excel-Treiber (*.xls) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.xls;SQLLevel=0;
|
||||
Driver do Microsoft Excel(*.xls) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.xls;SQLLevel=0;
|
||||
Microsoft Paradox Driver (*.db ) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.db;SQLLevel=0;
|
||||
Microsoft Paradox-Treiber (*.db ) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.db;SQLLevel=0;
|
||||
Driver do Microsoft Paradox (*.db ) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.db;SQLLevel=0;
|
||||
Microsoft Text Driver (*.txt; *.csv) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.,*.asc,*.csv,*.tab,*.txt,*.csv;SQLLevel=0;
|
||||
Microsoft Text-Treiber (*.txt; *.csv) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.,*.asc,*.csv,*.tab,*.txt,*.csv;SQLLevel=0;
|
||||
Driver da Microsoft para arquivos texto (*.txt; *.csv) UsageCount=1;APILevel=1;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.,*.asc,*.csv,*.tab,*.txt,*.csv;SQLLevel=0;
|
||||
Microsoft Visual FoxPro Driver UsageCount=1;APILevel=0;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.dbf,*.cdx,*.idx,*.fpt;SQLLevel=0;
|
||||
Microsoft FoxPro VFP Driver (*.dbf) UsageCount=1;APILevel=0;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.dbf,*.cdx,*.idx,*.fpt;SQLLevel=0;
|
||||
Microsoft dBase VFP Driver (*.dbf) UsageCount=1;APILevel=0;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.dbf,*.cdx,*.idx,*.fpt;SQLLevel=0;
|
||||
Microsoft Visual FoxPro-Treiber UsageCount=1;APILevel=0;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.dbf,*.cdx,*.idx,*.fpt;SQLLevel=0;
|
||||
Driver para o Microsoft Visual FoxPro UsageCount=1;APILevel=0;ConnectFunctions=YYN;DriverODBCVer=02.50;FileUsage=1;FileExtns=*.dbf,*.cdx,*.idx,*.fpt;SQLLevel=0;
|
||||
SQL Native Client UsageCount=1;APILevel=2;ConnectFunctions=YYY;CPTimeout=60;DriverODBCVer=09.00;FileUsage=0;SQLLevel=1;
|
||||
CR Sybase Wire Protocol ODBC Driver 6.0 UsageCount=1;APILevel=1;ConnectFunctions=YYY;DriverODBCVer=3.52;FileUsage=0;SQLLevel=0;CPTimeout=60;HelpRootDirectory=C:\Program Files\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\win32_x86\odbc\help;
|
||||
CR SQL Server Native Wire Protocol ODBC Driver 6.0 UsageCount=1;APILevel=1;ConnectFunctions=YYY;DriverODBCVer=3.52;FileUsage=0;SQLLevel=1;CPTimeout=60;HelpRootDirectory=C:\Program Files\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\win32_x86\odbc\help;
|
||||
CR SQL Server Classic Wire Protocol ODBC Driver 6.0 UsageCount=1;APILevel=1;ConnectFunctions=YYY;DriverODBCVer=3.52;FileUsage=0;SQLLevel=1;CPTimeout=60;HelpRootDirectory=C:\Program Files\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\win32_x86\odbc\help;
|
||||
CR TextFile ODBC Driver 6.0 UsageCount=1;APILevel=1;ConnectFunctions=YYY;DriverODBCVer=3.52;FileUsage=1;FileExtns=*.*;SQLLevel=0;CPTimeout=60;HelpRootDirectory=C:\Program Files\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\win32_x86\odbc\help;
|
||||
PLUGODBC_Driver UsageCount=1;
|
||||
SDB_ODBC_Driver UsageCount=2;
|
||||
Microsoft Access Text Driver (*.txt, *.csv) SQLLevel=0;FileExtns=*.txt, *.csv;FileUsage=2;DriverODBCVer=02.50;ConnectFunctions=YYN;APILevel=1;UsageCount=3;
|
||||
Microsoft Access dBASE Driver (*.dbf, *.ndx, *.mdx) SQLLevel=0;FileExtns=*.dbf, *.ndx, *.mdx;FileUsage=2;DriverODBCVer=02.50;ConnectFunctions=YYN;APILevel=1;UsageCount=3;
|
||||
Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb) SQLLevel=0;FileExtns=*.xls,*.xlsx, *.xlsb;FileUsage=2;DriverODBCVer=02.50;ConnectFunctions=YYN;APILevel=1;UsageCount=3;
|
||||
Microsoft Access Driver (*.mdb, *.accdb) SQLLevel=0;FileExtns=*.mdb,*.accdb;FileUsage=2;DriverODBCVer=02.50;ConnectFunctions=YYN;APILevel=1;UsageCount=3;
|
||||
SQLite3 ODBC Driver UsageCount=1;
|
||||
SQLite ODBC Driver UsageCount=1;
|
||||
SQLite ODBC (UTF-8) Driver UsageCount=1;
|
||||
Oracle in XE ConnectionFunctions=YYY;DriverODBCVer=03.51;CPTimeout=60;FileUsage=0;APILevel=1;SQLLevel=1;
|
||||
Oracle in instantclient_12_1 APILevel=1;ConnectionFunctions=YYY;CPTimeout=60;DriverODBCVer=03.51;FileUsage=0;SQLLevel=1;
|
||||
PostgreSQL ODBC Driver(ANSI) APILevel=1;ConnectFunctions=YYN;DriverODBCVer=09.02.0100;FileUsage=0;SQLLevel=1;
|
||||
PostgreSQL ODBC Driver(UNICODE) APILevel=1;ConnectFunctions=YYN;DriverODBCVer=09.02.0100;FileUsage=0;SQLLevel=1;
|
||||
SQL Server Native Client 11.0 UsageCount=1;APILevel=2;ConnectFunctions=YYY;CPTimeout=60;DriverODBCVer=03.80;FileUsage=0;SQLLevel=1;
|
||||
MariaDB ODBC 1.0 Driver UsageCount=1;
|
||||
Firebird/InterBase(r) driver UsageCount=1;FileExtns=*.fdb,*.gdb;APILevel=1;ConnectFunctions=YYY;FileUsage=0;DriverODBCVer=03.51;SQLLevel=1;
|
||||
MySQL ODBC 5.3 ANSI Driver UsageCount=1;
|
||||
MySQL ODBC 5.3 Unicode Driver UsageCount=1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Tables CONNECTION='Not important';
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`Table_Cat` char(128) DEFAULT NULL,
|
||||
`Table_Schema` char(128) DEFAULT NULL,
|
||||
`Table_Name` char(128) NOT NULL,
|
||||
`Table_Type` char(16) NOT NULL,
|
||||
`Remark` char(255) DEFAULT NULL
|
||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='Not important' `TABLE_TYPE`='ODBC' `CATFUNC`='Tables'
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Columns CONNECTION='Not important';
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`Table_Cat` char(128) DEFAULT NULL,
|
||||
`Table_Schema` char(128) DEFAULT NULL,
|
||||
`Table_Name` char(128) NOT NULL,
|
||||
`Column_Name` char(128) NOT NULL,
|
||||
`Data_Type` smallint(6) NOT NULL,
|
||||
`Type_Name` char(30) NOT NULL,
|
||||
`Column_Size` int(10) NOT NULL,
|
||||
`Buffer_Length` int(10) NOT NULL,
|
||||
`Decimal_Digits` smallint(6) DEFAULT NULL,
|
||||
`Radix` smallint(6) DEFAULT NULL,
|
||||
`Nullable` smallint(6) NOT NULL,
|
||||
`Remarks` char(255) DEFAULT NULL
|
||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='Not important' `TABLE_TYPE`='ODBC' `CATFUNC`='Columns'
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC TABNAME='EMPLOYEE' CONNECTION='DSN=Firebird;UID=SYSDBA;PWD=masterkey';
|
||||
SELECT * FROM t1;
|
||||
EMP_NO FIRST_NAME LAST_NAME PHONE_EXT HIRE_DATE DEPT_NO JOB_CODE JOB_GRADE JOB_COUNTRY SALARY FULL_NAME
|
||||
2 Robert Nelson 250 1988-12-28 00:00:00 600 VP 2 USA 105900.00 Nelson, Robert
|
||||
4 Bruce Young 233 1988-12-28 00:00:00 621 Eng 2 USA 97500.00 Young, Bruce
|
||||
5 Kim Lambert 22 1989-02-06 00:00:00 130 Eng 2 USA 102750.00 Lambert, Kim
|
||||
8 Leslie Johnson 410 1989-04-05 00:00:00 180 Mktg 3 USA 64635.00 Johnson, Leslie
|
||||
9 Phil Forest 229 1989-04-17 00:00:00 622 Mngr 3 USA 75060.00 Forest, Phil
|
||||
11 K. J. Weston 34 1990-01-17 00:00:00 130 SRep 4 USA 86292.94 Weston, K. J.
|
||||
12 Terri Lee 256 1990-05-01 00:00:00 000 Admin 4 USA 53793.00 Lee, Terri
|
||||
14 Stewart Hall 227 1990-06-04 00:00:00 900 Finan 3 USA 69482.63 Hall, Stewart
|
||||
15 Katherine Young 231 1990-06-14 00:00:00 623 Mngr 3 USA 67241.25 Young, Katherine
|
||||
20 Chris Papadopoulos 887 1990-01-01 00:00:00 671 Mngr 3 USA 89655.00 Papadopoulos, Chris
|
||||
24 Pete Fisher 888 1990-09-12 00:00:00 671 Eng 3 USA 81810.19 Fisher, Pete
|
||||
28 Ann Bennet 5 1991-02-01 00:00:00 120 Admin 5 England 22935.00 Bennet, Ann
|
||||
29 Roger De Souza 288 1991-02-18 00:00:00 623 Eng 3 USA 69482.63 De Souza, Roger
|
||||
34 Janet Baldwin 2 1991-03-21 00:00:00 110 Sales 3 USA 61637.81 Baldwin, Janet
|
||||
36 Roger Reeves 6 1991-04-25 00:00:00 120 Sales 3 England 33620.63 Reeves, Roger
|
||||
37 Willie Stansbury 7 1991-04-25 00:00:00 120 Eng 4 England 39224.06 Stansbury, Willie
|
||||
44 Leslie Phong 216 1991-06-03 00:00:00 623 Eng 4 USA 56034.38 Phong, Leslie
|
||||
45 Ashok Ramanathan 209 1991-08-01 00:00:00 621 Eng 3 USA 80689.50 Ramanathan, Ashok
|
||||
46 Walter Steadman 210 1991-08-09 00:00:00 900 CFO 1 USA 116100.00 Steadman, Walter
|
||||
52 Carol Nordstrom 420 1991-10-02 00:00:00 180 PRel 4 USA 42742.50 Nordstrom, Carol
|
||||
61 Luke Leung 3 1992-02-18 00:00:00 110 SRep 4 USA 68805.00 Leung, Luke
|
||||
65 Sue Anne O'Brien 877 1992-03-23 00:00:00 670 Admin 5 USA 31275.00 O'Brien, Sue Anne
|
||||
71 Jennifer M. Burbank 289 1992-04-15 00:00:00 622 Eng 3 USA 53167.50 Burbank, Jennifer M.
|
||||
72 Claudia Sutherland NULL 1992-04-20 00:00:00 140 SRep 4 Canada 100914.00 Sutherland, Claudia
|
||||
83 Dana Bishop 290 1992-06-01 00:00:00 621 Eng 3 USA 62550.00 Bishop, Dana
|
||||
85 Mary S. MacDonald 477 1992-06-01 00:00:00 100 VP 2 USA 111262.50 MacDonald, Mary S.
|
||||
94 Randy Williams 892 1992-08-08 00:00:00 672 Mngr 4 USA 56295.00 Williams, Randy
|
||||
105 Oliver H. Bender 255 1992-10-08 00:00:00 000 CEO 1 USA 212850.00 Bender, Oliver H.
|
||||
107 Kevin Cook 894 1993-02-01 00:00:00 670 Dir 2 USA 111262.50 Cook, Kevin
|
||||
109 Kelly Brown 202 1993-02-04 00:00:00 600 Admin 5 USA 27000.00 Brown, Kelly
|
||||
110 Yuki Ichida 22 1993-02-04 00:00:00 115 Eng 3 Japan 6000000.00 Ichida, Yuki
|
||||
113 Mary Page 845 1993-04-12 00:00:00 671 Eng 4 USA 48000.00 Page, Mary
|
||||
114 Bill Parker 247 1993-06-01 00:00:00 623 Eng 5 USA 35000.00 Parker, Bill
|
||||
118 Takashi Yamamoto 23 1993-07-01 00:00:00 115 SRep 4 Japan 7480000.00 Yamamoto, Takashi
|
||||
121 Roberto Ferrari 1 1993-07-12 00:00:00 125 SRep 4 Italy 99000000.00 Ferrari, Roberto
|
||||
127 Michael Yanowski 492 1993-08-09 00:00:00 100 SRep 4 USA 44000.00 Yanowski, Michael
|
||||
134 Jacques Glon NULL 1993-08-23 00:00:00 123 SRep 4 France 390500.00 Glon, Jacques
|
||||
136 Scott Johnson 265 1993-09-13 00:00:00 623 Doc 3 USA 60000.00 Johnson, Scott
|
||||
138 T.J. Green 218 1993-11-01 00:00:00 621 Eng 4 USA 36000.00 Green, T.J.
|
||||
141 Pierre Osborne NULL 1994-01-03 00:00:00 121 SRep 4 Switzerland 110000.00 Osborne, Pierre
|
||||
144 John Montgomery 820 1994-03-30 00:00:00 672 Eng 5 USA 35000.00 Montgomery, John
|
||||
145 Mark Guckenheimer 221 1994-05-02 00:00:00 622 Eng 5 USA 32000.00 Guckenheimer, Mark
|
||||
DROP TABLE t1;
|
BIN
storage/connect/mysql-test/connect/std_data/mdev9949.frm
Normal file
BIN
storage/connect/mysql-test/connect/std_data/mdev9949.frm
Normal file
Binary file not shown.
1
storage/connect/mysql-test/connect/t/drop-open-error.opt
Normal file
1
storage/connect/mysql-test/connect/t/drop-open-error.opt
Normal file
@@ -0,0 +1 @@
|
||||
--secure-file-priv=""
|
31
storage/connect/mysql-test/connect/t/drop-open-error.test
Normal file
31
storage/connect/mysql-test/connect/t/drop-open-error.test
Normal file
File diff suppressed because one or more lines are too long
@@ -9,6 +9,7 @@ let $MYSQLD_DATADIR= `select @@datadir`;
|
||||
--echo # MDEV-7574 Security definer views don't work with CONNECT ODBC tables
|
||||
--echo #
|
||||
|
||||
CREATE USER user@localhost;
|
||||
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
|
||||
REVOKE FILE ON *.* FROM user@localhost;
|
||||
|
||||
|
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# MDEV-9739 Assertion `m_status == DA_ERROR || m_status == DA_OK' failed in Diagnostics_area::message() ; connect.xml* tests fail in buildbot
|
||||
#
|
||||
|
||||
--source have_libxml2.inc
|
||||
|
||||
create table t1 (i int) engine=Connect table_type=XML;
|
||||
select * from information_schema.tables where create_options like '%table_type=XML%';
|
||||
drop table t1;
|
@@ -304,7 +304,7 @@ DROP TABLE t1;
|
||||
--echo # Testing temporal data types
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a date, b datetime, c time, d timestamp, e year);
|
||||
CREATE TABLE t1 (a date, b datetime, c time, d timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, e year);
|
||||
SHOW CREATE TABLE t1;
|
||||
INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
|
||||
SELECT * FROM t1;
|
||||
|
35
storage/connect/mysql-test/connect/t/odbc_firebird.test
Normal file
35
storage/connect/mysql-test/connect/t/odbc_firebird.test
Normal file
@@ -0,0 +1,35 @@
|
||||
--source have_odbc.inc
|
||||
|
||||
SET NAMES utf8;
|
||||
|
||||
# MS ODBC and unixODBC return different error message text,
|
||||
# so disable displaying error messages
|
||||
--disable_result_log ONCE
|
||||
--error ER_UNKNOWN_ERROR
|
||||
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='Bad connection string';
|
||||
|
||||
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Sources;
|
||||
if (`select count(*)=0 from t1 where name='firebird'`) {
|
||||
DROP TABLE t1;
|
||||
skip No Firebird;
|
||||
}
|
||||
SHOW CREATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Drivers;
|
||||
SHOW CREATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Tables CONNECTION='Not important';
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Columns CONNECTION='Not important';
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC TABNAME='EMPLOYEE' CONNECTION='DSN=Firebird;UID=SYSDBA;PWD=masterkey';
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
@@ -10,4 +10,4 @@ let $SECUREDIR= `select @@secure_file_priv`;
|
||||
INSERT INTO t1 VALUES (10);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
--remove_file $SECUREDIR/t1.dbf
|
||||
--remove_file $MYSQL_TMP_DIR/t1.dbf
|
||||
|
38
storage/connect/noconst.c
Normal file
38
storage/connect/noconst.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/***********************************************************************/
|
||||
/* (C) Copyright to the author Olivier BERTRAND 2015 */
|
||||
/***********************************************************************/
|
||||
#include <my_global.h>
|
||||
#include <mysqld.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__WIN__)
|
||||
#define DllExport __declspec( dllexport )
|
||||
#else // !__WIN__
|
||||
#define DllExport
|
||||
#endif // !__WIN__
|
||||
|
||||
extern "C" {
|
||||
DllExport my_bool noconst_init(UDF_INIT*, UDF_ARGS*, char*);
|
||||
DllExport char *noconst(UDF_INIT*, UDF_ARGS*, char*, unsigned long*, char*, char*);
|
||||
} // extern "C"
|
||||
|
||||
/***********************************************************************/
|
||||
/* Returns its argument saying it is not a constant. */
|
||||
/***********************************************************************/
|
||||
my_bool noconst_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
|
||||
{
|
||||
if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) {
|
||||
strcpy(message, "noconst unique argument must be a string");
|
||||
return true;
|
||||
} // endif arg
|
||||
|
||||
initid->const_item = false; // The trick!
|
||||
return false;
|
||||
} // end of noconst_init
|
||||
|
||||
char *noconst(UDF_INIT *initid, UDF_ARGS *args, char *result,
|
||||
unsigned long *res_length, char *, char *)
|
||||
{
|
||||
return args->args[0];
|
||||
} // end of noconst
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* Copyright (C) MariaDB Corporation Ab */
|
||||
#ifndef _OS_H_INCLUDED
|
||||
#define _OS_H_INCLUDED
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* Copyright (C) MariaDB Corporation Ab */
|
||||
#include "my_global.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* Copyright (C) MariaDB Corporation Ab */
|
||||
#ifndef __OSUTIL_H__
|
||||
#define __OSUTIL_H__
|
||||
|
||||
|
@@ -36,8 +36,6 @@ enum BLKTYP {TYPE_TABLE = 50, /* Table Name/Srcdef/... Block */
|
||||
TYPE_COLCRT = 71, /* Column creation block */
|
||||
TYPE_CONST = 72, /* Constant */
|
||||
|
||||
/*-------------------- type tokenized string --------------------------*/
|
||||
TYPE_DATE = 8, /* Timestamp */
|
||||
/*-------------------- additional values used by LNA ------------------*/
|
||||
TYPE_COLIST = 14, /* Column list */
|
||||
TYPE_COL = 41, /* Column */
|
||||
|
@@ -82,14 +82,10 @@ extern "C" {
|
||||
extern char version[];
|
||||
} // extern "C"
|
||||
|
||||
#if defined(__WIN__)
|
||||
extern CRITICAL_SECTION parsec; // Used calling the Flex parser
|
||||
#else // !__WIN__
|
||||
extern pthread_mutex_t parmut;
|
||||
#endif // !__WIN__
|
||||
|
||||
// The debug trace used by the main thread
|
||||
FILE *pfile = NULL;
|
||||
FILE *pfile = NULL;
|
||||
|
||||
MBLOCK Nmblk = {NULL, false, 0, false, NULL}; // Used to init MBLOCK's
|
||||
|
||||
@@ -473,7 +469,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));
|
||||
throw OP_LIKE;
|
||||
throw (int)OP_LIKE;
|
||||
} /* endif tp */
|
||||
|
||||
sp = tp + strlen(pat) + 1;
|
||||
@@ -484,7 +480,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));
|
||||
throw OP_LIKE;
|
||||
throw (int)OP_LIKE;
|
||||
} /* endif tp */
|
||||
|
||||
strcpy(tp, pat); /* Make a copy to be worked into */
|
||||
@@ -697,21 +693,9 @@ PDTP MakeDateFormat(PGLOBAL g, PCSZ dfmt, bool in, bool out, int flag)
|
||||
/* Call the FLEX generated parser. In multi-threading mode the next */
|
||||
/* instruction is included in an Enter/LeaveCriticalSection bracket. */
|
||||
/*********************************************************************/
|
||||
//#if defined(THREAD)
|
||||
#if defined(__WIN__)
|
||||
EnterCriticalSection((LPCRITICAL_SECTION)&parsec);
|
||||
#else // !__WIN__
|
||||
pthread_mutex_lock(&parmut);
|
||||
#endif // !__WIN__
|
||||
//#endif // THREAD
|
||||
rc = fmdflex(pdp);
|
||||
//#if defined(THREAD)
|
||||
#if defined(__WIN__)
|
||||
LeaveCriticalSection((LPCRITICAL_SECTION)&parsec);
|
||||
#else // !__WIN__
|
||||
pthread_mutex_unlock(&parmut);
|
||||
#endif // !__WIN__
|
||||
//#endif // THREAD
|
||||
|
||||
if (trace)
|
||||
htrc("Done: in=%s out=%s rc=%d\n", SVP(pdp->InFmt), SVP(pdp->OutFmt), rc);
|
||||
|
@@ -2,11 +2,11 @@
|
||||
/* */
|
||||
/* PROGRAM NAME: PLUGUTIL */
|
||||
/* ------------- */
|
||||
/* Version 2.9 */
|
||||
/* Version 3.0 */
|
||||
/* */
|
||||
/* COPYRIGHT: */
|
||||
/* ---------- */
|
||||
/* (C) Copyright to the author Olivier BERTRAND 1993-2015 */
|
||||
/* (C) Copyright to the author Olivier BERTRAND 1993-2017 */
|
||||
/* */
|
||||
/* WHAT THIS PROGRAM DOES: */
|
||||
/* ----------------------- */
|
||||
@@ -76,6 +76,7 @@
|
||||
|
||||
#include "osutil.h"
|
||||
#include "global.h"
|
||||
#include "plgdbsem.h"
|
||||
#if defined(NEWMSG)
|
||||
#include "rcmsg.h"
|
||||
#endif // NEWMSG
|
||||
@@ -132,12 +133,12 @@ void htrc(char const *fmt, ...)
|
||||
/* Return value is the pointer to the Global structure. */
|
||||
/***********************************************************************/
|
||||
PGLOBAL PlugInit(LPCSTR Language, uint worksize)
|
||||
{
|
||||
PGLOBAL g;
|
||||
{
|
||||
PGLOBAL g;
|
||||
|
||||
if (trace > 1)
|
||||
htrc("PlugInit: Language='%s'\n",
|
||||
((!Language) ? "Null" : (char*)Language));
|
||||
if (trace > 1)
|
||||
htrc("PlugInit: Language='%s'\n",
|
||||
((!Language) ? "Null" : (char*)Language));
|
||||
|
||||
try {
|
||||
g = new GLOBAL;
|
||||
@@ -146,53 +147,54 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
|
||||
return NULL;
|
||||
} // end try/catch
|
||||
|
||||
//if (!(g = (PGLOBAL)malloc(sizeof(GLOBAL)))) {
|
||||
// fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL));
|
||||
// return NULL;
|
||||
// } else {
|
||||
g->Sarea = NULL;
|
||||
g->Createas = 0;
|
||||
g->Alchecked = 0;
|
||||
g->Mrr = 0;
|
||||
g->Activityp = NULL;
|
||||
g->Xchk = NULL;
|
||||
g->N = 0;
|
||||
g->More = 0;
|
||||
strcpy(g->Message, "");
|
||||
g->Sarea = NULL;
|
||||
g->Createas = 0;
|
||||
g->Alchecked = 0;
|
||||
g->Mrr = 0;
|
||||
g->Activityp = NULL;
|
||||
g->Xchk = NULL;
|
||||
g->N = 0;
|
||||
g->More = 0;
|
||||
strcpy(g->Message, "");
|
||||
|
||||
/*******************************************************************/
|
||||
/* Allocate the main work segment. */
|
||||
/*******************************************************************/
|
||||
if (worksize && !(g->Sarea = PlugAllocMem(g, worksize))) {
|
||||
char errmsg[MAX_STR];
|
||||
sprintf(errmsg, MSG(WORK_AREA), g->Message);
|
||||
strcpy(g->Message, errmsg);
|
||||
g->Sarea_Size = 0;
|
||||
} else
|
||||
g->Sarea_Size = worksize;
|
||||
/*******************************************************************/
|
||||
/* Allocate the main work segment. */
|
||||
/*******************************************************************/
|
||||
if (worksize && !(g->Sarea = PlugAllocMem(g, worksize))) {
|
||||
char errmsg[MAX_STR];
|
||||
sprintf(errmsg, MSG(WORK_AREA), g->Message);
|
||||
strcpy(g->Message, errmsg);
|
||||
g->Sarea_Size = 0;
|
||||
} else
|
||||
g->Sarea_Size = worksize;
|
||||
|
||||
//} /* endif g */
|
||||
|
||||
g->jump_level = -1; /* New setting to allow recursive call of Plug */
|
||||
return(g);
|
||||
} /* end of PlugInit */
|
||||
g->jump_level = -1; /* New setting to allow recursive call of Plug */
|
||||
return(g);
|
||||
} /* end of PlugInit */
|
||||
|
||||
/***********************************************************************/
|
||||
/* PlugExit: Terminate Plug operations. */
|
||||
/***********************************************************************/
|
||||
int PlugExit(PGLOBAL g)
|
||||
{
|
||||
int rc = 0;
|
||||
{
|
||||
if (g) {
|
||||
PDBUSER dup = PlgGetUser(g);
|
||||
|
||||
if (!g)
|
||||
return rc;
|
||||
if (dup)
|
||||
free(dup);
|
||||
|
||||
if (g->Sarea)
|
||||
free(g->Sarea);
|
||||
if (g->Sarea) {
|
||||
if (trace)
|
||||
htrc("Freeing Sarea size=%d\n", g->Sarea_Size);
|
||||
|
||||
delete g;
|
||||
return rc;
|
||||
} /* end of PlugExit */
|
||||
free(g->Sarea);
|
||||
} // endif Sarea
|
||||
|
||||
delete g;
|
||||
} // endif g
|
||||
|
||||
return 0;
|
||||
} // end of PlugExit
|
||||
|
||||
/***********************************************************************/
|
||||
/* Remove the file type from a file name. */
|
||||
@@ -456,7 +458,7 @@ short GetLineLength(PGLOBAL g)
|
||||
/* Program for memory allocation of work and language areas. */
|
||||
/***********************************************************************/
|
||||
void *PlugAllocMem(PGLOBAL g, uint size)
|
||||
{
|
||||
{
|
||||
void *areap; /* Pointer to allocated area */
|
||||
|
||||
/*********************************************************************/
|
||||
@@ -465,16 +467,16 @@ void *PlugAllocMem(PGLOBAL g, uint size)
|
||||
if (!(areap = malloc(size)))
|
||||
sprintf(g->Message, MSG(MALLOC_ERROR), "malloc");
|
||||
|
||||
if (trace > 1) {
|
||||
if (trace) {
|
||||
if (areap)
|
||||
htrc("Memory of %u allocated at %p\n", size, areap);
|
||||
else
|
||||
htrc("PlugAllocMem: %s\n", g->Message);
|
||||
|
||||
} // endif trace
|
||||
} // endif trace
|
||||
|
||||
return (areap);
|
||||
} /* end of PlugAllocMem */
|
||||
} // end of PlugAllocMem
|
||||
|
||||
/***********************************************************************/
|
||||
/* Program for SubSet initialization of memory pools. */
|
||||
|
@@ -86,7 +86,7 @@ void XTAB::Printf(PGLOBAL g, FILE *f, uint n)
|
||||
PlugPutOut(g, f, TYPE_TDB, tp->To_Tdb, n + 2);
|
||||
} /* endfor tp */
|
||||
|
||||
} /* end of Print */
|
||||
} /* end of Printf */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Make string output of XTAB contents. */
|
||||
@@ -105,7 +105,7 @@ void XTAB::Prints(PGLOBAL, char *ps, uint z)
|
||||
n -= i;
|
||||
} // endif tp
|
||||
|
||||
} /* end of Print */
|
||||
} /* end of Prints */
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -149,7 +149,7 @@ void COLUMN::Printf(PGLOBAL g, FILE *f, uint n)
|
||||
|
||||
PlugPutOut(g, f, TYPE_TABLE, To_Table, n + 2);
|
||||
PlugPutOut(g, f, TYPE_XOBJECT, To_Col, n + 2);
|
||||
} /* end of Print */
|
||||
} /* end of Printf */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Make string output of COLUMN contents. */
|
||||
@@ -166,4 +166,4 @@ void COLUMN::Prints(PGLOBAL, char *ps, uint z)
|
||||
|
||||
strncpy(ps, buf, z);
|
||||
ps[z - 1] = '\0';
|
||||
} /* end of Print */
|
||||
} /* end of Prints */
|
||||
|
@@ -1309,7 +1309,7 @@ PBF TDBDOS::InitBlockFilter(PGLOBAL g, PFIL filp)
|
||||
} // endif !opm
|
||||
|
||||
// if opm, pass thru
|
||||
/* fall through */
|
||||
// fall through
|
||||
case OP_IN:
|
||||
if (filp->GetArgType(0) == TYPE_COLBLK &&
|
||||
filp->GetArgType(1) == TYPE_ARRAY) {
|
||||
@@ -1645,8 +1645,8 @@ int TDBDOS::TestBlock(PGLOBAL g)
|
||||
/***********************************************************************/
|
||||
int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
|
||||
{
|
||||
int k, n;
|
||||
bool fixed, doit, sep, b = (pxdf != NULL);
|
||||
int k, n, rc = RC_OK;
|
||||
bool fixed, doit, sep, b = (pxdf != NULL);
|
||||
PCOL *keycols, colp;
|
||||
PIXDEF xdp, sxp = NULL;
|
||||
PKPDEF kdp;
|
||||
@@ -1690,95 +1690,105 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
|
||||
} else if (!(pxdf = dfp->GetIndx()))
|
||||
return RC_INFO; // No index to make
|
||||
|
||||
// Allocate all columns that will be used by indexes.
|
||||
// This must be done before opening the table so specific
|
||||
// column initialization can be done (in particular by TDBVCT)
|
||||
for (n = 0, xdp = pxdf; xdp; xdp = xdp->GetNext())
|
||||
for (kdp = xdp->GetToKeyParts(); kdp; kdp = kdp->GetNext()) {
|
||||
if (!(colp = ColDB(g, kdp->GetName(), 0))) {
|
||||
sprintf(g->Message, MSG(INDX_COL_NOTIN), kdp->GetName(), Name);
|
||||
goto err;
|
||||
} else if (colp->GetResultType() == TYPE_DECIM) {
|
||||
sprintf(g->Message, "Decimal columns are not indexable yet");
|
||||
goto err;
|
||||
} // endif Type
|
||||
try {
|
||||
// Allocate all columns that will be used by indexes.
|
||||
// This must be done before opening the table so specific
|
||||
// column initialization can be done (in particular by TDBVCT)
|
||||
for (n = 0, xdp = pxdf; xdp; xdp = xdp->GetNext())
|
||||
for (kdp = xdp->GetToKeyParts(); kdp; kdp = kdp->GetNext()) {
|
||||
if (!(colp = ColDB(g, kdp->GetName(), 0))) {
|
||||
sprintf(g->Message, MSG(INDX_COL_NOTIN), kdp->GetName(), Name);
|
||||
goto err;
|
||||
} else if (colp->GetResultType() == TYPE_DECIM) {
|
||||
sprintf(g->Message, "Decimal columns are not indexable yet");
|
||||
goto err;
|
||||
} // endif Type
|
||||
|
||||
colp->InitValue(g);
|
||||
n = MY_MAX(n, xdp->GetNparts());
|
||||
} // endfor kdp
|
||||
colp->InitValue(g);
|
||||
n = MY_MAX(n, xdp->GetNparts());
|
||||
} // endfor kdp
|
||||
|
||||
keycols = (PCOL*)PlugSubAlloc(g, NULL, n * sizeof(PCOL));
|
||||
sep = dfp->GetBoolCatInfo("SepIndex", false);
|
||||
keycols = (PCOL*)PlugSubAlloc(g, NULL, n * sizeof(PCOL));
|
||||
sep = dfp->GetBoolCatInfo("SepIndex", false);
|
||||
|
||||
/*********************************************************************/
|
||||
/* Construct and save the defined indexes. */
|
||||
/*********************************************************************/
|
||||
for (xdp = pxdf; xdp; xdp = xdp->GetNext())
|
||||
if (!OpenDB(g)) {
|
||||
if (xdp->IsAuto() && fixed)
|
||||
// Auto increment key and fixed file: use an XXROW index
|
||||
continue; // XXROW index doesn't need to be made
|
||||
/*********************************************************************/
|
||||
/* Construct and save the defined indexes. */
|
||||
/*********************************************************************/
|
||||
for (xdp = pxdf; xdp; xdp = xdp->GetNext())
|
||||
if (!OpenDB(g)) {
|
||||
if (xdp->IsAuto() && fixed)
|
||||
// Auto increment key and fixed file: use an XXROW index
|
||||
continue; // XXROW index doesn't need to be made
|
||||
|
||||
// On Update, redo only indexes that are modified
|
||||
doit = !To_SetCols;
|
||||
n = 0;
|
||||
// On Update, redo only indexes that are modified
|
||||
doit = !To_SetCols;
|
||||
n = 0;
|
||||
|
||||
if (sxp)
|
||||
xdp->SetID(sxp->GetID() + 1);
|
||||
if (sxp)
|
||||
xdp->SetID(sxp->GetID() + 1);
|
||||
|
||||
for (kdp = xdp->GetToKeyParts(); kdp; kdp = kdp->GetNext()) {
|
||||
// Check whether this column was updated
|
||||
for (colp = To_SetCols; !doit && colp; colp = colp->GetNext())
|
||||
if (!stricmp(kdp->GetName(), colp->GetName()))
|
||||
doit = true;
|
||||
for (kdp = xdp->GetToKeyParts(); kdp; kdp = kdp->GetNext()) {
|
||||
// Check whether this column was updated
|
||||
for (colp = To_SetCols; !doit && colp; colp = colp->GetNext())
|
||||
if (!stricmp(kdp->GetName(), colp->GetName()))
|
||||
doit = true;
|
||||
|
||||
keycols[n++] = ColDB(g, kdp->GetName(), 0);
|
||||
} // endfor kdp
|
||||
keycols[n++] = ColDB(g, kdp->GetName(), 0);
|
||||
} // endfor kdp
|
||||
|
||||
// If no indexed columns were updated, don't remake the index
|
||||
// if indexes are in separate files.
|
||||
if (!doit && sep)
|
||||
continue;
|
||||
// If no indexed columns were updated, don't remake the index
|
||||
// if indexes are in separate files.
|
||||
if (!doit && sep)
|
||||
continue;
|
||||
|
||||
k = xdp->GetNparts();
|
||||
k = xdp->GetNparts();
|
||||
|
||||
// Make the index and save it
|
||||
if (dfp->Huge)
|
||||
pxp = new(g) XHUGE;
|
||||
else
|
||||
pxp = new(g) XFILE;
|
||||
// Make the index and save it
|
||||
if (dfp->Huge)
|
||||
pxp = new(g) XHUGE;
|
||||
else
|
||||
pxp = new(g) XFILE;
|
||||
|
||||
if (k == 1) // Simple index
|
||||
x = new(g) XINDXS(this, xdp, pxp, keycols);
|
||||
else // Multi-Column index
|
||||
x = new(g) XINDEX(this, xdp, pxp, keycols);
|
||||
if (k == 1) // Simple index
|
||||
x = new(g) XINDXS(this, xdp, pxp, keycols);
|
||||
else // Multi-Column index
|
||||
x = new(g) XINDEX(this, xdp, pxp, keycols);
|
||||
|
||||
if (!x->Make(g, sxp)) {
|
||||
// Retreive define values from the index
|
||||
xdp->SetMaxSame(x->GetMaxSame());
|
||||
// xdp->SetSize(x->GetSize());
|
||||
if (!x->Make(g, sxp)) {
|
||||
// Retreive define values from the index
|
||||
xdp->SetMaxSame(x->GetMaxSame());
|
||||
// xdp->SetSize(x->GetSize());
|
||||
|
||||
// store KXYCOL Mxs in KPARTDEF Mxsame
|
||||
xdp->SetMxsame(x);
|
||||
// store KXYCOL Mxs in KPARTDEF Mxsame
|
||||
xdp->SetMxsame(x);
|
||||
|
||||
#if defined(TRACE)
|
||||
printf("Make done...\n");
|
||||
printf("Make done...\n");
|
||||
#endif // TRACE
|
||||
|
||||
// if (x->GetSize() > 0)
|
||||
sxp = xdp;
|
||||
// if (x->GetSize() > 0)
|
||||
sxp = xdp;
|
||||
|
||||
xdp->SetInvalid(false);
|
||||
} else
|
||||
goto err;
|
||||
xdp->SetInvalid(false);
|
||||
} else
|
||||
goto err;
|
||||
|
||||
} else
|
||||
return RC_INFO; // Error or Physical table does not exist
|
||||
} else
|
||||
return RC_INFO; // Error or Physical table does not exist
|
||||
|
||||
} catch (int n) {
|
||||
if (trace)
|
||||
htrc("Exception %d: %s\n", n, g->Message);
|
||||
rc = RC_FX;
|
||||
} catch (const char *msg) {
|
||||
strcpy(g->Message, msg);
|
||||
rc = RC_FX;
|
||||
} // end catch
|
||||
|
||||
if (Use == USE_OPEN)
|
||||
CloseDB(g);
|
||||
|
||||
return RC_OK;
|
||||
return rc;
|
||||
|
||||
err:
|
||||
if (sxp)
|
||||
@@ -2725,7 +2735,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
|
||||
if (Value->GetBinValue(p, Long, Status)) {
|
||||
sprintf(g->Message, MSG(BIN_F_TOO_LONG),
|
||||
Name, Value->GetSize(), Long);
|
||||
longjmp(g->jumper[g->jump_level], 31);
|
||||
throw 31;
|
||||
} // endif
|
||||
|
||||
} // end of WriteColumn
|
||||
@@ -2874,7 +2884,7 @@ bool DOSCOL::AddDistinctValue(PGLOBAL g)
|
||||
void DOSCOL::Printf(PGLOBAL g, FILE *f, uint n)
|
||||
{
|
||||
COLBLK::Printf(g, f, n);
|
||||
} // end of Print
|
||||
} // end of Printf
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
|
@@ -41,12 +41,12 @@
|
||||
/***********************************************************************/
|
||||
#define MAXCOL 200 /* Default max column nb in result */
|
||||
#define TYPE_UNKNOWN 12 /* Must be greater than other types */
|
||||
#define USE_G 1 /* Use recoverable memory if 1 */
|
||||
|
||||
/***********************************************************************/
|
||||
/* External function. */
|
||||
/***********************************************************************/
|
||||
USETEMP UseTemp(void);
|
||||
char *GetJsonNull(void);
|
||||
|
||||
typedef struct _jncol {
|
||||
struct _jncol *Next;
|
||||
@@ -163,7 +163,6 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
|
||||
|
||||
tjnp->SetMode(MODE_READ);
|
||||
|
||||
#if USE_G
|
||||
// Allocate the parse work memory
|
||||
PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
|
||||
memset(G, 0, sizeof(GLOBAL));
|
||||
@@ -172,9 +171,6 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
|
||||
PlugSubSet(G, G->Sarea, G->Sarea_Size);
|
||||
G->jump_level = 0;
|
||||
tjnp->SetG(G);
|
||||
#else
|
||||
tjnp->SetG(g);
|
||||
#endif
|
||||
|
||||
if (tjnp->OpenDB(g))
|
||||
return NULL;
|
||||
@@ -478,7 +474,6 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
|
||||
// Txfp must be set for TDBDOS
|
||||
tdbp = new(g) TDBJSN(this, txfp);
|
||||
|
||||
#if USE_G
|
||||
// Allocate the parse work memory
|
||||
PGLOBAL G = (PGLOBAL)PlugSubAlloc(g, NULL, sizeof(GLOBAL));
|
||||
memset(G, 0, sizeof(GLOBAL));
|
||||
@@ -487,9 +482,6 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
|
||||
PlugSubSet(G, G->Sarea, G->Sarea_Size);
|
||||
G->jump_level = 0;
|
||||
((TDBJSN*)tdbp)->G = G;
|
||||
#else
|
||||
((TDBJSN*)tdbp)->G = g;
|
||||
#endif
|
||||
} else {
|
||||
if (Zipped) {
|
||||
#if defined(ZIP_SUPPORT)
|
||||
@@ -762,10 +754,8 @@ int TDBJSN::ReadDB(PGLOBAL g)
|
||||
// Deferred reading failed
|
||||
return rc;
|
||||
|
||||
#if USE_G
|
||||
// Recover the memory used for parsing
|
||||
PlugSubSet(G, G->Sarea, G->Sarea_Size);
|
||||
#endif
|
||||
|
||||
if ((Row = ParseJson(G, To_Line, strlen(To_Line), &Pretty, &Comma))) {
|
||||
Row = FindRow(g);
|
||||
@@ -774,9 +764,7 @@ int TDBJSN::ReadDB(PGLOBAL g)
|
||||
M = 1;
|
||||
rc = RC_OK;
|
||||
} else if (Pretty != 1 || strcmp(To_Line, "]")) {
|
||||
#if USE_G
|
||||
strcpy(g->Message, G->Message);
|
||||
#endif
|
||||
rc = RC_FX;
|
||||
} else
|
||||
rc = RC_EF;
|
||||
@@ -882,9 +870,7 @@ int TDBJSN::WriteDB(PGLOBAL g)
|
||||
{
|
||||
int rc = TDBDOS::WriteDB(g);
|
||||
|
||||
#if USE_G
|
||||
PlugSubSet(G, G->Sarea, G->Sarea_Size);
|
||||
#endif
|
||||
Row->Clear();
|
||||
return rc;
|
||||
} // end of WriteDB
|
||||
@@ -1228,7 +1214,7 @@ void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
|
||||
case TYPE_INTG:
|
||||
case TYPE_BINT:
|
||||
case TYPE_DBL:
|
||||
case TYPE_DATE:
|
||||
case TYPE_DTM:
|
||||
vp->SetValue_pval(val->GetValue());
|
||||
break;
|
||||
case TYPE_BOOL:
|
||||
@@ -1390,9 +1376,12 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
|
||||
for (i = 0; i < ars; i++) {
|
||||
jvrp = arp->GetValue(i);
|
||||
|
||||
do {
|
||||
if (n < Nod - 1 && jvrp->GetJson()) {
|
||||
Tjp->NextSame = nextsame;
|
||||
if (!jvrp->IsNull() || (op == OP_CNC && GetJsonNull())) do {
|
||||
if (jvrp->IsNull()) {
|
||||
jvrp->Value = AllocateValue(g, GetJsonNull(), TYPE_STRING);
|
||||
jvp = jvrp;
|
||||
} else if (n < Nod - 1 && jvrp->GetJson()) {
|
||||
Tjp->NextSame = nextsame;
|
||||
jval.SetValue(GetColumnValue(g, jvrp->GetJson(), n + 1));
|
||||
jvp = &jval;
|
||||
} else
|
||||
@@ -1404,8 +1393,9 @@ PVAL JSONCOL::CalculateArray(PGLOBAL g, PJAR arp, int n)
|
||||
} else
|
||||
SetJsonValue(g, MulVal, jvp, n);
|
||||
|
||||
if (!MulVal->IsZero()) {
|
||||
switch (op) {
|
||||
// if (!MulVal->IsZero()) {
|
||||
if (!MulVal->IsNull()) {
|
||||
switch (op) {
|
||||
case OP_CNC:
|
||||
if (Nodes[n].CncVal) {
|
||||
val[0] = Nodes[n].CncVal;
|
||||
|
@@ -324,7 +324,7 @@ void TDB::Printf(PGLOBAL g, FILE *f, uint n)
|
||||
void TDB::Prints(PGLOBAL, char *ps, uint)
|
||||
{
|
||||
sprintf(ps, "R%d.%s", Tdb_No, Name);
|
||||
} // end of Print
|
||||
} // end of Prints
|
||||
|
||||
/* -------------------------- class TDBASE --------------------------- */
|
||||
|
||||
|
@@ -273,7 +273,7 @@ PCSZ TDBODBC::GetFile(PGLOBAL g)
|
||||
/***********************************************************************/
|
||||
/* Set DBQ and get the new file name into the connect string. */
|
||||
/***********************************************************************/
|
||||
void TDBODBC::SetFile(PGLOBAL g, PSZ fn)
|
||||
void TDBODBC::SetFile(PGLOBAL g, PCSZ fn)
|
||||
{
|
||||
if (MulConn) {
|
||||
int n = strlen(MulConn) + strlen(fn) - 1;
|
||||
@@ -289,7 +289,7 @@ void TDBODBC::SetFile(PGLOBAL g, PSZ fn)
|
||||
sprintf(Connect, MulConn, fn);
|
||||
} // endif MultConn
|
||||
|
||||
DBQ = fn;
|
||||
DBQ = PlugDup(g, fn);
|
||||
} // end of SetFile
|
||||
|
||||
/***********************************************************************/
|
||||
|
@@ -71,7 +71,7 @@ class TDBODBC : public TDBEXT {
|
||||
virtual PTDB Clone(PTABS t);
|
||||
virtual bool SetRecpos(PGLOBAL g, int recpos);
|
||||
virtual PCSZ GetFile(PGLOBAL g);
|
||||
virtual void SetFile(PGLOBAL g, PSZ fn);
|
||||
virtual void SetFile(PGLOBAL g, PCSZ fn);
|
||||
virtual void ResetSize(void);
|
||||
virtual PCSZ GetServer(void) {return "ODBC";}
|
||||
virtual int Indexable(void) {return 2;}
|
||||
|
@@ -289,7 +289,7 @@ void VIRCOL::ReadColumn(PGLOBAL g)
|
||||
{
|
||||
// This should never be called
|
||||
sprintf(g->Message, "ReadColumn: Column %s is not virtual", Name);
|
||||
throw TYPE_COLBLK;
|
||||
throw (int)TYPE_COLBLK;
|
||||
} // end of ReadColumn
|
||||
|
||||
/* ---------------------------TDBVICL class -------------------------- */
|
||||
|
@@ -1319,7 +1319,7 @@ void TDBXML::CloseDB(PGLOBAL g)
|
||||
Docp->CloseDoc(g, To_Xb);
|
||||
|
||||
// This causes a crash in Diagnostics_area::set_error_status
|
||||
// throw TYPE_AM_XML;
|
||||
// throw (int)TYPE_AM_XML;
|
||||
} // endif DumpDoc
|
||||
|
||||
} // endif Changed
|
||||
@@ -1642,7 +1642,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);
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
} // endif type
|
||||
|
||||
// Get the Xname value from the XML file
|
||||
@@ -1653,7 +1653,7 @@ void XMLCOL::ReadColumn(PGLOBAL g)
|
||||
PushWarning(g, Tdbp);
|
||||
break;
|
||||
default:
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
} // endswitch
|
||||
|
||||
Value->SetValue_psz(Valbuf);
|
||||
@@ -1704,7 +1704,7 @@ void XMLCOL::WriteColumn(PGLOBAL g)
|
||||
/* For columns having an Xpath, the Clist must be updated. */
|
||||
/*********************************************************************/
|
||||
if (Tdbp->CheckRow(g, Nod || Tdbp->Colname))
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
|
||||
/*********************************************************************/
|
||||
/* Null values are represented by no node. */
|
||||
@@ -1776,7 +1776,7 @@ void XMLCOL::WriteColumn(PGLOBAL g)
|
||||
|
||||
if (ColNode == NULL) {
|
||||
strcpy(g->Message, MSG(COL_ALLOC_ERR));
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
} // endif ColNode
|
||||
|
||||
} // endif ColNode
|
||||
@@ -1795,7 +1795,7 @@ void XMLCOL::WriteColumn(PGLOBAL g)
|
||||
|
||||
if (ValNode == NULL && AttNode == NULL) {
|
||||
strcpy(g->Message, MSG(VAL_ALLOC_ERR));
|
||||
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
||||
throw (int)TYPE_AM_XML;
|
||||
} // endif ValNode
|
||||
|
||||
/*********************************************************************/
|
||||
@@ -1805,7 +1805,7 @@ void XMLCOL::WriteColumn(PGLOBAL g)
|
||||
|
||||
if (strlen(p) > (unsigned)Long) {
|
||||
sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long);
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
} else
|
||||
strcpy(Valbuf, p);
|
||||
|
||||
@@ -1855,7 +1855,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);
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
} // endif type
|
||||
|
||||
// Get the Xname value from the XML file
|
||||
@@ -1866,7 +1866,7 @@ void XMULCOL::ReadColumn(PGLOBAL g)
|
||||
PushWarning(g, Tdbp);
|
||||
break;
|
||||
default:
|
||||
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
||||
throw (int)TYPE_AM_XML;
|
||||
} // endswitch
|
||||
|
||||
if (!b) {
|
||||
@@ -1941,7 +1941,7 @@ void XMULCOL::WriteColumn(PGLOBAL g)
|
||||
/* For columns having an Xpath, the Clist must be updated. */
|
||||
/*********************************************************************/
|
||||
if (Tdbp->CheckRow(g, Nod))
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
|
||||
/*********************************************************************/
|
||||
/* Find the column and value nodes to update or insert. */
|
||||
@@ -1990,7 +1990,7 @@ void XMULCOL::WriteColumn(PGLOBAL g)
|
||||
|
||||
if (len > 1 && !Tdbp->Xpand) {
|
||||
sprintf(g->Message, MSG(BAD_VAL_UPDATE), Name);
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
} else
|
||||
ValNode = Nlx->GetItem(g, Tdbp->Nsub, Vxnp);
|
||||
|
||||
@@ -2032,7 +2032,7 @@ void XMULCOL::WriteColumn(PGLOBAL g)
|
||||
|
||||
if (ColNode == NULL) {
|
||||
strcpy(g->Message, MSG(COL_ALLOC_ERR));
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
} // endif ColNode
|
||||
|
||||
} // endif ColNode
|
||||
@@ -2051,8 +2051,8 @@ void XMULCOL::WriteColumn(PGLOBAL g)
|
||||
|
||||
if (ValNode == NULL && AttNode == NULL) {
|
||||
strcpy(g->Message, MSG(VAL_ALLOC_ERR));
|
||||
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
|
||||
} // endif ValNode
|
||||
throw (int)TYPE_AM_XML;
|
||||
} // endif ValNode
|
||||
|
||||
/*********************************************************************/
|
||||
/* Get the string representation of Value according to column type. */
|
||||
@@ -2061,7 +2061,7 @@ void XMULCOL::WriteColumn(PGLOBAL g)
|
||||
|
||||
if (strlen(p) > (unsigned)Long) {
|
||||
sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long);
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
} else
|
||||
strcpy(Valbuf, p);
|
||||
|
||||
@@ -2093,7 +2093,7 @@ void XPOSCOL::ReadColumn(PGLOBAL g)
|
||||
|
||||
if (Tdbp->Clist == NULL) {
|
||||
strcpy(g->Message, MSG(MIS_TAG_LIST));
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
} // endif Clist
|
||||
|
||||
if ((ValNode = Tdbp->Clist->GetItem(g, Rank, Vxnp))) {
|
||||
@@ -2105,7 +2105,7 @@ void XPOSCOL::ReadColumn(PGLOBAL g)
|
||||
PushWarning(g, Tdbp);
|
||||
break;
|
||||
default:
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
} // endswitch
|
||||
|
||||
Value->SetValue_psz(Valbuf);
|
||||
@@ -2156,14 +2156,14 @@ void XPOSCOL::WriteColumn(PGLOBAL g)
|
||||
/* For all columns the Clist must be updated. */
|
||||
/*********************************************************************/
|
||||
if (Tdbp->CheckRow(g, true))
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
|
||||
/*********************************************************************/
|
||||
/* Find the column and value nodes to update or insert. */
|
||||
/*********************************************************************/
|
||||
if (Tdbp->Clist == NULL) {
|
||||
strcpy(g->Message, MSG(MIS_TAG_LIST));
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
} // endif Clist
|
||||
|
||||
n = Tdbp->Clist->GetLength();
|
||||
@@ -2188,7 +2188,7 @@ void XPOSCOL::WriteColumn(PGLOBAL g)
|
||||
|
||||
if (strlen(p) > (unsigned)Long) {
|
||||
sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long);
|
||||
throw TYPE_AM_XML;
|
||||
throw (int)TYPE_AM_XML;
|
||||
} else
|
||||
strcpy(Valbuf, p);
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) Olivier Bertrand 2004 - 2015
|
||||
/* Copyright (C) MariaDB Corporation Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -24,7 +24,7 @@
|
||||
that is a connection with its personnal memory allocation.
|
||||
|
||||
@note
|
||||
|
||||
Author Olivier Bertrand
|
||||
*/
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -47,6 +47,8 @@
|
||||
#include "user_connect.h"
|
||||
#include "mycat.h"
|
||||
|
||||
extern pthread_mutex_t usrmut;
|
||||
|
||||
/****************************************************************************/
|
||||
/* Initialize the user_connect static member. */
|
||||
/****************************************************************************/
|
||||
@@ -111,7 +113,10 @@ bool user_connect::user_init()
|
||||
|
||||
int rc= PlugExit(g);
|
||||
g= NULL;
|
||||
free(dup);
|
||||
|
||||
if (dup)
|
||||
free(dup);
|
||||
|
||||
return true;
|
||||
} // endif g->
|
||||
|
||||
@@ -122,15 +127,19 @@ bool user_connect::user_init()
|
||||
strcpy(ap->Ap_Name, "CONNECT");
|
||||
g->Activityp= ap;
|
||||
g->Activityp->Aptr= dup;
|
||||
next= to_users;
|
||||
|
||||
pthread_mutex_lock(&usrmut);
|
||||
next= to_users;
|
||||
to_users= this;
|
||||
|
||||
if (next)
|
||||
next->previous= this;
|
||||
|
||||
last_query_id= thdp->query_id;
|
||||
count= 1;
|
||||
return false;
|
||||
pthread_mutex_unlock(&usrmut);
|
||||
|
||||
last_query_id = thdp->query_id;
|
||||
return false;
|
||||
} // end of user_init
|
||||
|
||||
|
||||
@@ -144,18 +153,22 @@ void user_connect::SetHandler(ha_connect *hc)
|
||||
/****************************************************************************/
|
||||
/* Check whether we begin a new query and if so cleanup the previous one. */
|
||||
/****************************************************************************/
|
||||
bool user_connect::CheckCleanup(void)
|
||||
bool user_connect::CheckCleanup(bool force)
|
||||
{
|
||||
if (thdp->query_id > last_query_id) {
|
||||
if (thdp->query_id > last_query_id || force) {
|
||||
uint worksize= GetWorkSize();
|
||||
|
||||
PlugCleanup(g, true);
|
||||
|
||||
if (g->Sarea_Size != worksize) {
|
||||
if (g->Sarea)
|
||||
free(g->Sarea);
|
||||
if (g->Sarea) {
|
||||
if (trace)
|
||||
htrc("CheckCleanup: Free Sarea %d\n", g->Sarea_Size);
|
||||
|
||||
// Check whether the work area size was changed
|
||||
free(g->Sarea);
|
||||
} // endif Size
|
||||
|
||||
// Check whether the work area could be allocated
|
||||
if (!(g->Sarea = PlugAllocMem(g, worksize))) {
|
||||
g->Sarea = PlugAllocMem(g, g->Sarea_Size);
|
||||
SetWorkSize(g->Sarea_Size); // Was too big
|
||||
@@ -171,7 +184,7 @@ bool user_connect::CheckCleanup(void)
|
||||
g->Mrr = 0;
|
||||
last_query_id= thdp->query_id;
|
||||
|
||||
if (trace)
|
||||
if (trace && !force)
|
||||
printf("=====> Begin new query %llu\n", last_query_id);
|
||||
|
||||
return true;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) Olivier Bertrand 2004 - 2011
|
||||
/* Copyright (C) MariaDB Corporation Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -19,6 +19,7 @@
|
||||
Declaration of the user_connect class.
|
||||
|
||||
@note
|
||||
Author Olivier Bertrand
|
||||
|
||||
@see
|
||||
/sql/handler.h and /storage/connect/user_connect.cc
|
||||
@@ -53,7 +54,7 @@ public:
|
||||
// Implementation
|
||||
bool user_init();
|
||||
void SetHandler(ha_connect *hc);
|
||||
bool CheckCleanup(void);
|
||||
bool CheckCleanup(bool force = false);
|
||||
bool CheckQueryID(void) {return thdp->query_id > last_query_id;}
|
||||
bool CheckQuery(query_id_t vid) {return last_query_id > vid;}
|
||||
|
||||
|
@@ -118,7 +118,8 @@ ulonglong CharToNumber(const char *p, int n, ulonglong maxval,
|
||||
maxval++;
|
||||
if (minus) *minus = true;
|
||||
} // endif Unsigned
|
||||
/* fall through */
|
||||
|
||||
// Fall through
|
||||
case '+':
|
||||
p++;
|
||||
break;
|
||||
@@ -571,9 +572,9 @@ void VALUE::Printf(PGLOBAL g, FILE *f, uint n)
|
||||
if (Null)
|
||||
fprintf(f, "%s<null>\n", m);
|
||||
else
|
||||
fprintf(f, "%s%s%s", GetCharString(buf), "\n", m);
|
||||
fprintf(f, "%s%s\n", m, GetCharString(buf));
|
||||
|
||||
} /* end of Print */
|
||||
} /* end of Printf */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Make string output of an object value. */
|
||||
@@ -588,7 +589,7 @@ void VALUE::Prints(PGLOBAL g, char *ps, uint z)
|
||||
p = GetCharString(buf);
|
||||
|
||||
strncpy(ps, p, z);
|
||||
} // end of Print
|
||||
} // end of Prints
|
||||
|
||||
/* -------------------------- Class TYPVAL ---------------------------- */
|
||||
|
||||
@@ -1349,7 +1350,7 @@ bool TYPVAL<PSZ>::SetValue_pval(PVAL valp, bool chktype)
|
||||
|
||||
char buf[64];
|
||||
|
||||
if (!(Null = valp->IsNull() && Nullable))
|
||||
if (!(Null = (valp->IsNull() && Nullable)))
|
||||
strncpy(Strp, valp->GetCharString(buf), Len);
|
||||
else
|
||||
Reset();
|
||||
@@ -1451,7 +1452,7 @@ void TYPVAL<PSZ>::SetValue(uint n)
|
||||
|
||||
if (k > Len) {
|
||||
sprintf(g->Message, MSG(VALSTR_TOO_LONG), buf, Len);
|
||||
longjmp(g->jumper[g->jump_level], 138);
|
||||
throw 138;
|
||||
} else
|
||||
SetValue_psz(buf);
|
||||
|
||||
@@ -1505,7 +1506,7 @@ void TYPVAL<PSZ>::SetValue(ulonglong n)
|
||||
|
||||
if (k > Len) {
|
||||
sprintf(g->Message, MSG(VALSTR_TOO_LONG), buf, Len);
|
||||
longjmp(g->jumper[g->jump_level], 138);
|
||||
throw 138;
|
||||
} else
|
||||
SetValue_psz(buf);
|
||||
|
||||
@@ -1655,32 +1656,36 @@ bool TYPVAL<PSZ>::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < np; i++)
|
||||
p[i] = vp[i]->GetCharString(val[i]);
|
||||
p[i] = vp[i]->IsNull() ? NULL : vp[i]->GetCharString(val[i]);
|
||||
|
||||
switch (op) {
|
||||
case OP_CNC:
|
||||
assert(np == 1 || np == 2);
|
||||
if (p[i-1]) {
|
||||
switch (op) {
|
||||
case OP_CNC:
|
||||
assert(np == 1 || np == 2);
|
||||
|
||||
if (np == 2)
|
||||
SetValue_psz(p[0]);
|
||||
if (np == 2)
|
||||
SetValue_psz(p[0]);
|
||||
|
||||
if ((i = Len - (signed)strlen(Strp)) > 0)
|
||||
strncat(Strp, p[np - 1], i);
|
||||
if ((i = Len - (signed)strlen(Strp)) > 0)
|
||||
strncat(Strp, p[np - 1], i);
|
||||
|
||||
break;
|
||||
case OP_MIN:
|
||||
assert(np == 2);
|
||||
SetValue_psz((strcmp(p[0], p[1]) < 0) ? p[0] : p[1]);
|
||||
break;
|
||||
case OP_MAX:
|
||||
assert(np == 2);
|
||||
SetValue_psz((strcmp(p[0], p[1]) > 0) ? p[0] : p[1]);
|
||||
break;
|
||||
default:
|
||||
// sprintf(g->Message, MSG(BAD_EXP_OPER), op);
|
||||
strcpy(g->Message, "Function not supported");
|
||||
return true;
|
||||
} // endswitch op
|
||||
break;
|
||||
case OP_MIN:
|
||||
assert(np == 2);
|
||||
SetValue_psz((strcmp(p[0], p[1]) < 0) ? p[0] : p[1]);
|
||||
break;
|
||||
case OP_MAX:
|
||||
assert(np == 2);
|
||||
SetValue_psz((strcmp(p[0], p[1]) > 0) ? p[0] : p[1]);
|
||||
break;
|
||||
default:
|
||||
// sprintf(g->Message, MSG(BAD_EXP_OPER), op);
|
||||
strcpy(g->Message, "Function not supported");
|
||||
return true;
|
||||
} // endswitch op
|
||||
|
||||
Null = false;
|
||||
} // endif p[i]
|
||||
|
||||
return false;
|
||||
} // end of Compute
|
||||
@@ -1719,10 +1724,14 @@ void TYPVAL<PSZ>::Prints(PGLOBAL g, char *ps, uint z)
|
||||
else
|
||||
strcat(strncat(strncpy(ps, "\"", z), Strp, z-2), "\"");
|
||||
|
||||
} // end of Print
|
||||
} // end of Prints
|
||||
|
||||
/* -------------------------- Class DECIMAL -------------------------- */
|
||||
|
||||
/***********************************************************************/
|
||||
/* DECIMAL public constructor from a constant string. */
|
||||
/* -------------------------- Class DECIMAL -------------------------- */
|
||||
|
||||
/***********************************************************************/
|
||||
/* DECIMAL public constructor from a constant string. */
|
||||
/***********************************************************************/
|
||||
@@ -2562,7 +2571,7 @@ bool DTVAL::SetValue_pval(PVAL valp, bool chktype)
|
||||
} else if (valp->GetType() == TYPE_BIGINT &&
|
||||
!(valp->GetBigintValue() % 1000)) {
|
||||
// Assuming that this timestamp is in milliseconds
|
||||
Tval = valp->GetBigintValue() / 1000;
|
||||
Tval = (int)(valp->GetBigintValue() / 1000);
|
||||
} else
|
||||
Tval = valp->GetIntValue();
|
||||
|
||||
|
@@ -90,8 +90,8 @@ class DllExport VALUE : public BLOCK {
|
||||
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;}
|
||||
bool IsNull(void) {return (Nullable && Null);}
|
||||
void SetNull(bool b) {Null = (Nullable ? b : false);}
|
||||
bool GetNullable(void) {return Nullable;}
|
||||
void SetNullable(bool b) {Nullable = b;}
|
||||
int GetType(void) {return Type;}
|
||||
|
@@ -188,7 +188,7 @@ void XXBASE::Printf(PGLOBAL, FILE *f, uint n)
|
||||
memset(m, ' ', n); // Make margin string
|
||||
m[n] = '\0';
|
||||
fprintf(f, "%sXINDEX: Tbxp=%p Num=%d\n", m, Tbxp, Num_K);
|
||||
} // end of Print
|
||||
} // end of Printf
|
||||
|
||||
/***********************************************************************/
|
||||
/* Make string output of XINDEX contents. */
|
||||
@@ -197,7 +197,7 @@ void XXBASE::Prints(PGLOBAL, char *ps, uint z)
|
||||
{
|
||||
*ps = '\0';
|
||||
strncat(ps, "Xindex", z);
|
||||
} // end of Print
|
||||
} // end of Prints
|
||||
|
||||
/* -------------------------- XINDEX Class --------------------------- */
|
||||
|
||||
@@ -3008,7 +3008,8 @@ KXYCOL::KXYCOL(PKXBASE kp) : To_Keys(Keys.Memp),
|
||||
/***********************************************************************/
|
||||
bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
|
||||
{
|
||||
int len = colp->GetLength(), prec = colp->GetScale();
|
||||
int len = colp->GetLength(), prec = colp->GetScale();
|
||||
bool un = colp->IsUnsigned();
|
||||
|
||||
// Currently no indexing on NULL columns
|
||||
if (colp->IsNullable() && kln) {
|
||||
@@ -3028,7 +3029,7 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
|
||||
// Allocate the Value object used when moving items
|
||||
Type = colp->GetResultType();
|
||||
|
||||
if (!(Valp = AllocateValue(g, Type, len, prec, colp->IsUnsigned())))
|
||||
if (!(Valp = AllocateValue(g, Type, len, prec, un)))
|
||||
return true;
|
||||
|
||||
Klen = Valp->GetClen();
|
||||
@@ -3044,7 +3045,7 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
|
||||
// Currently we set it to true to be compatible with QRY blocks,
|
||||
// and the one before last is to enable length/type checking, set to
|
||||
// true if not a prefix key.
|
||||
Kblp = AllocValBlock(g, To_Keys, Type, n, len, prec, !Prefix, true);
|
||||
Kblp = AllocValBlock(g, To_Keys, Type, n, len, prec, !Prefix, true, un);
|
||||
Asc = sm; // Sort mode: Asc=true Desc=false
|
||||
Ndf = n;
|
||||
|
||||
@@ -3064,7 +3065,8 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
|
||||
/***********************************************************************/
|
||||
BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
|
||||
{
|
||||
int len = colp->GetLength(), prec = colp->GetScale();
|
||||
int len = colp->GetLength(), prec = colp->GetScale();
|
||||
bool un = colp->IsUnsigned();
|
||||
|
||||
if (n[3] && colp->GetLength() > n[3]
|
||||
&& colp->GetResultType() == TYPE_STRING) {
|
||||
@@ -3079,7 +3081,7 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
|
||||
this, colp, Type, n[0], len, m);
|
||||
|
||||
// Allocate the Value object used when moving items
|
||||
Valp = AllocateValue(g, Type, len, prec, colp->IsUnsigned());
|
||||
Valp = AllocateValue(g, Type, len, prec, un);
|
||||
Klen = Valp->GetClen();
|
||||
|
||||
if (n[2]) {
|
||||
@@ -3088,7 +3090,7 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
|
||||
Bkeys.Sub = true;
|
||||
|
||||
// Allocate the Valblk containing initial block key values
|
||||
Blkp = AllocValBlock(g, To_Bkeys, Type, n[2], len, prec, true, true);
|
||||
Blkp = AllocValBlock(g, To_Bkeys, Type, n[2], len, prec, true, true, un);
|
||||
} // endif nb
|
||||
|
||||
Keys.Size = n[0] * Klen;
|
||||
@@ -3099,7 +3101,7 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
|
||||
// by blanks (if true) or keep the zero ending char (if false).
|
||||
// Currently we set it to true to be compatible with QRY blocks,
|
||||
// and last one to enable type checking (no conversion).
|
||||
Kblp = AllocValBlock(g, To_Keys, Type, n[0], len, prec, !Prefix, true);
|
||||
Kblp = AllocValBlock(g, To_Keys, Type, n[0], len, prec, !Prefix, true, un);
|
||||
|
||||
if (n[1]) {
|
||||
Koff.Size = n[1] * sizeof(int);
|
||||
|
@@ -84,7 +84,7 @@ double XOBJECT::GetFloatValue(void)
|
||||
CONSTANT::CONSTANT(PGLOBAL g, void *value, short type)
|
||||
{
|
||||
if (!(Value = AllocateValue(g, value, (int)type)))
|
||||
throw TYPE_CONST;
|
||||
throw (int)TYPE_CONST;
|
||||
|
||||
Constant = true;
|
||||
} // end of CONSTANT constructor
|
||||
@@ -95,7 +95,7 @@ CONSTANT::CONSTANT(PGLOBAL g, void *value, short type)
|
||||
CONSTANT::CONSTANT(PGLOBAL g, int n)
|
||||
{
|
||||
if (!(Value = AllocateValue(g, &n, TYPE_INT)))
|
||||
throw TYPE_CONST;
|
||||
throw (int)TYPE_CONST;
|
||||
|
||||
Constant = true;
|
||||
} // end of CONSTANT constructor
|
||||
@@ -117,7 +117,7 @@ void CONSTANT::Convert(PGLOBAL g, int newtype)
|
||||
{
|
||||
if (Value->GetType() != newtype)
|
||||
if (!(Value = AllocateValue(g, Value, newtype)))
|
||||
throw TYPE_CONST;
|
||||
throw (int)TYPE_CONST;
|
||||
|
||||
} // end of Convert
|
||||
|
||||
@@ -176,7 +176,7 @@ bool CONSTANT::Rephrase(PGLOBAL g, PSZ work)
|
||||
void CONSTANT::Printf(PGLOBAL g, FILE *f, uint n)
|
||||
{
|
||||
Value->Printf(g, f, n);
|
||||
} /* end of Print */
|
||||
} /* end of Printf */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Make string output of a constant object. */
|
||||
@@ -184,7 +184,7 @@ void CONSTANT::Printf(PGLOBAL g, FILE *f, uint n)
|
||||
void CONSTANT::Prints(PGLOBAL g, char *ps, uint z)
|
||||
{
|
||||
Value->Prints(g, ps, z);
|
||||
} /* end of Print */
|
||||
} /* end of Prints */
|
||||
|
||||
/* -------------------------- Class STRING --------------------------- */
|
||||
|
||||
|
Reference in New Issue
Block a user