Commit 307258c8 authored by Olivier Bertrand's avatar Olivier Bertrand

- Use BIN type when charset='binary'

  modified:   storage/connect/ha_connect.cc

- Allow JSON columns to be "binary"
  By setting their type as VARBINAY(132)
  and their name begin with Jbin_
  modified:   storage/connect/json.h
  modified:   storage/connect/jsonudf.cpp
  modified:   storage/connect/tabjson.cpp
  modified:   storage/connect/value.cpp
  modified:   storage/connect/value.h

- CHARSET BINARY cannot be used for text columns
  modified:   storage/connect/mysql-test/connect/r/updelx.result
  modified:   storage/connect/mysql-test/connect/t/updelx.test
parent c6eb127c
......@@ -1586,6 +1586,9 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
chset= (char *)fp->charset()->name;
if (!strcmp(chset, "binary"))
v = 'B'; // Binary string
switch (fp->type()) {
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VARCHAR:
......@@ -1595,7 +1598,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
default:
pcf->Type= MYSQLtoPLG(fp->type(), &v);
break;
} // endswitch SQL type
} // endswitch SQL type
switch (pcf->Type) {
case TYPE_STRING:
......@@ -1649,7 +1652,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
break;
default:
break;
} // endswitch type
} // endswitch type
if (fp->flags & UNSIGNED_FLAG)
pcf->Flags |= U_UNSIGNED;
......@@ -2222,7 +2225,7 @@ int ha_connect::MakeRecord(char *buf)
case TYPE_BIN:
p= value->GetCharValue();
charset= &my_charset_bin;
rc= fp->store(p, strlen(p), charset, CHECK_FIELD_WARN);
rc= fp->store(p, value->GetSize(), charset, CHECK_FIELD_WARN);
break;
case TYPE_DOUBLE:
rc= fp->store(value->GetFloatValue());
......
/**************** json H Declares Source Code File (.H) ****************/
/* Name: json.h Version 1.2 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2020 */
/* */
/* This file contains the JSON classes declares. */
/***********************************************************************/
#include <mysql_com.h>
#include "value.h"
#if defined(_DEBUG)
......@@ -44,6 +45,27 @@ typedef struct {
int len;
} STRG, *PSG;
// BSON size should be equal on Linux and Windows
#define BMX 255
typedef struct BSON* PBSON;
/***********************************************************************/
/* Structure used to return binary json to Json UDF functions. */
/***********************************************************************/
struct BSON {
char Msg[BMX + 1];
char *Filename;
PGLOBAL G;
int Pretty;
ulong Reslen;
my_bool Changed;
PJSON Top;
PJSON Jsp;
PBSON Bsp;
}; // end of struct BSON
PBSON JbinAlloc(PGLOBAL g, UDF_ARGS* args, ulong len, PJSON jsp);
char *NextChr(PSZ s, char sep);
char *GetJsonNull(void);
......
......@@ -1076,6 +1076,7 @@ my_bool JSNX::AddPath(void)
/* --------------------------------- JSON UDF ---------------------------------- */
#if 0 // Moved to json.h
// BSON size should be equal on Linux and Windows
#define BMX 255
typedef struct BSON *PBSON;
......@@ -1094,11 +1095,12 @@ struct BSON {
PJSON Jsp;
PBSON Bsp;
}; // end of struct BSON
#endif // 0
/*********************************************************************************/
/* Allocate and initialize a BSON structure. */
/*********************************************************************************/
static PBSON JbinAlloc(PGLOBAL g, UDF_ARGS *args, ulong len, PJSON jsp)
PBSON JbinAlloc(PGLOBAL g, UDF_ARGS *args, ulong len, PJSON jsp)
{
PBSON bsp = (PBSON)PlgDBSubAlloc(g, NULL, sizeof(BSON));
......@@ -1111,7 +1113,7 @@ static PBSON JbinAlloc(PGLOBAL g, UDF_ARGS *args, ulong len, PJSON jsp)
bsp->Reslen = len;
bsp->Changed = false;
bsp->Top = bsp->Jsp = jsp;
bsp->Bsp = (IsJson(args, 0) == 3) ? (PBSON)args->args[0] : NULL;
bsp->Bsp = (args && IsJson(args, 0) == 3) ? (PBSON)args->args[0] : NULL;
} else
PUSH_WARNING(g->Message);
......@@ -1422,7 +1424,7 @@ static int IsJson(UDF_ARGS *args, uint i, bool b)
n = 2; // arg is a json file name
} else if (b) {
char *sap;
PGLOBAL g = PlugInit(NULL, args->lengths[i] * M + 1024);
PGLOBAL g = PlugInit(NULL, (size_t)args->lengths[i] * M + 1024);
JsonSubSet(g);
sap = MakePSZ(g, args, i);
......@@ -5763,7 +5765,7 @@ char *json_serialize(UDF_INIT *initid, UDF_ARGS *args, char *result,
// Keep result of constant function
g->Xchk = (initid->const_item) ? str : NULL;
} else {
*error = 1;
// *error = 1;
str = strcpy(result, "Argument is not a Jbin tree");
} // endif
......
......@@ -978,7 +978,7 @@ DROP TABLE t1;
# FIX table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED)
msg VARCHAR(16) DISTRIB=CLUSTERED)
ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=4;
Warnings:
Warning 1105 No file name. Table will use t1.fix
......@@ -1345,7 +1345,7 @@ DROP TABLE t1;
# BIN table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED)
msg VARCHAR(16) DISTRIB=CLUSTERED)
ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=8;
Warnings:
Warning 1105 No file name. Table will use t1.bin
......
......@@ -36,7 +36,7 @@ DROP TABLE t1;
--echo # FIX table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED)
msg VARCHAR(16) DISTRIB=CLUSTERED)
ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=4;
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
......@@ -48,7 +48,7 @@ DROP TABLE t1;
--echo # BIN table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED)
msg VARCHAR(16) DISTRIB=CLUSTERED)
ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=8;
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
......
......@@ -1486,7 +1486,18 @@ PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp)
if (Value->IsTypeNum()) {
strcpy(g->Message, "Cannot make Json for a numeric column");
Value->Reset();
} else
} else if (Value->GetType() == TYPE_BIN) {
if (Value->GetClen() >= sizeof(BSON)) {
ULONG len = Tjp->Lrecl ? Tjp->Lrecl : 500;
PBSON bsp = JbinAlloc(g, NULL, len, jsp);
strcat(bsp->Msg, " column");
((BINVAL*)Value)->SetBinValue(bsp, sizeof(BSON));
} else {
strcpy(g->Message, "Column size too small");
Value->SetValue_char(NULL, 0);
} // endif Clen
} else
Value->SetValue_psz(Serialize(g, jsp, NULL, 0));
return Value;
......
......@@ -2250,6 +2250,15 @@ void BINVAL::SetBinValue(void *p)
Len = Clen;
} // end of SetBinValue
/***********************************************************************/
/* BINVAL SetBinValue: fill string with len bytes. */
/***********************************************************************/
void BINVAL::SetBinValue(void* p, ulong len)
{
memcpy(Binp, p, len);
Len = len;
} // end of SetBinValue
/***********************************************************************/
/* GetBinValue: fill a buffer with the internal binary value. */
/* This function checks whether the buffer length is enough and */
......
......@@ -115,8 +115,8 @@ class DllExport VALUE : public BLOCK {
virtual void SetValue(ulonglong) {assert(false);}
virtual void SetValue(double) {assert(false);}
virtual void SetValue_pvblk(PVBLK blk, int n) = 0;
virtual void SetBinValue(void *p) = 0;
virtual bool GetBinValue(void *buf, int buflen, bool go) = 0;
virtual void SetBinValue(void* p) = 0;
virtual bool GetBinValue(void *buf, int buflen, bool go) = 0;
virtual int ShowValue(char *buf, int len) = 0;
virtual char *GetCharString(char *p) = 0;
virtual bool IsEqual(PVAL vp, bool chktype) = 0;
......@@ -385,7 +385,8 @@ class DllExport BINVAL: public VALUE {
virtual void SetValue(ulonglong n);
virtual void SetValue(double f);
virtual void SetBinValue(void *p);
virtual bool GetBinValue(void *buf, int buflen, bool go);
virtual void SetBinValue(void* p, ulong len);
virtual bool GetBinValue(void *buf, int buflen, bool go);
virtual int CompareValue(PVAL) {assert(false); return 0;}
virtual int ShowValue(char *buf, int len);
virtual char *GetCharString(char *p);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment