summaryrefslogtreecommitdiff
path: root/storage/connect/ha_connect.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/connect/ha_connect.cc')
-rw-r--r--storage/connect/ha_connect.cc173
1 files changed, 122 insertions, 51 deletions
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 849cf7594eb..2206cfc271d 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -170,7 +170,7 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.07.0002 October 18, 2020";
+ char version[]= "Version 1.07.0002 January 27, 2021";
#if defined(__WIN__)
char compver[]= "Version 1.07.0002 " __DATE__ " " __TIME__;
static char slash= '\\';
@@ -230,6 +230,9 @@ char *GetUserVariable(PGLOBAL g, const uchar *varname)
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
PQRYRES VirColumns(PGLOBAL g, bool info);
PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info);
+#ifdef BSON_SUPPORT
+PQRYRES BSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info);
+#endif // BSON_SUPPORT
PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info);
#if defined(REST_SUPPORT)
PQRYRES RESTColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
@@ -251,11 +254,15 @@ bool ExactInfo(void);
USETEMP UseTemp(void);
int GetConvSize(void);
TYPCONV GetTypeConv(void);
+int GetDefaultDepth(void);
+int GetDefaultPrec(void);
bool JsonAllPath(void);
char *GetJsonNull(void);
-int GetDefaultDepth(void);
uint GetJsonGrpSize(void);
char *GetJavaWrapper(void);
+#if defined(BSON_SUPPORT)
+bool Force_Bson(void);
+#endif // BSON_SUPPORT
size_t GetWorkSize(void);
void SetWorkSize(size_t);
extern "C" const char *msglang(void);
@@ -397,7 +404,7 @@ static MYSQL_THDVAR_ENUM(
// Adding JPATH to all Json table columns
static MYSQL_THDVAR_BOOL(json_all_path, PLUGIN_VAR_RQCMDARG,
"Adding JPATH to all Json table columns",
- NULL, NULL, 0); // NO by default
+ NULL, NULL, 1); // YES by default
// Null representation for JSON values
static MYSQL_THDVAR_STR(json_null,
@@ -410,11 +417,17 @@ static MYSQL_THDVAR_STR(json_null,
static MYSQL_THDVAR_INT(default_depth,
PLUGIN_VAR_RQCMDARG,
"Default depth used by Json, XML and Mongo discovery",
- NULL, NULL, 0, -1, 16, 1);
+ NULL, NULL, 5, -1, 16, 1); // Defaults to 5
+
+// Default precision for doubles
+static MYSQL_THDVAR_INT(default_prec,
+ PLUGIN_VAR_RQCMDARG,
+ "Default precision used for doubles",
+ NULL, NULL, 6, 0, 16, 1); // Defaults to 6
// Estimate max number of rows for JSON aggregate functions
static MYSQL_THDVAR_UINT(json_grp_size,
- PLUGIN_VAR_RQCMDARG, // opt
+ PLUGIN_VAR_RQCMDARG, // opt
"max number of rows for JSON aggregate functions.",
NULL, NULL, JSONMAX, 1, INT_MAX, 1);
@@ -439,6 +452,13 @@ static MYSQL_THDVAR_BOOL(enable_mongo, PLUGIN_VAR_RQCMDARG,
#endif // !version 2,3
#endif // JAVA_SUPPORT || CMGO_SUPPORT
+#if defined(BSON_SUPPORT)
+// Force using BSON for JSON tables
+static MYSQL_THDVAR_BOOL(force_bson, PLUGIN_VAR_RQCMDARG,
+ "Force using BSON for JSON tables",
+ NULL, NULL, 0); // NO by default
+#endif // BSON_SUPPORT
+
#if defined(XMSG) || defined(NEWMSG)
const char *language_names[]=
{
@@ -480,6 +500,7 @@ TYPCONV GetTypeConv(void) {return (TYPCONV)THDVAR(current_thd, type_conv);}
char *GetJsonNull(void)
{return connect_hton ? THDVAR(current_thd, json_null) : NULL;}
int GetDefaultDepth(void) {return THDVAR(current_thd, default_depth);}
+int GetDefaultPrec(void) {return THDVAR(current_thd, default_prec);}
uint GetJsonGrpSize(void)
{return connect_hton ? THDVAR(current_thd, json_grp_size) : 10;}
size_t GetWorkSize(void) {return (size_t)THDVAR(current_thd, work_size);}
@@ -501,6 +522,10 @@ char *GetJavaWrapper(void)
bool MongoEnabled(void) {return THDVAR(current_thd, enable_mongo);}
#endif // JAVA_SUPPORT || CMGO_SUPPORT
+#if defined(BSON_SUPPORT)
+bool Force_Bson(void) {return THDVAR(current_thd, force_bson);}
+#endif // BSON_SUPPORT)
+
#if defined(XMSG) || defined(NEWMSG)
extern "C" const char *msglang(void)
{return language_names[THDVAR(current_thd, msg_lang)];}
@@ -1050,12 +1075,12 @@ static PGLOBAL GetPlug(THD *thd, PCONNECT& lxp)
/****************************************************************************/
TABTYPE ha_connect::GetRealType(PTOS pos)
{
- TABTYPE type;
+ TABTYPE type= TAB_UNDEF;
if (pos || (pos= GetTableOptionStruct())) {
type= GetTypeID(pos->type);
- if (type == TAB_UNDEF)
+ if (type == TAB_UNDEF && !pos->http)
type= pos->srcdef ? TAB_MYSQL : pos->tabname ? TAB_PRX : TAB_DOS;
#if defined(REST_SUPPORT)
else if (pos->http)
@@ -1063,7 +1088,8 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
case TAB_JSON:
case TAB_XML:
case TAB_CSV:
- type = TAB_REST;
+ case TAB_UNDEF:
+ type = TAB_REST;
break;
case TAB_REST:
type = TAB_NIY;
@@ -1073,8 +1099,7 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
} // endswitch type
#endif // REST_SUPPORT
- } else
- type= TAB_UNDEF;
+ } // endif pos
return type;
} // end of GetRealType
@@ -1386,7 +1411,7 @@ PCSZ ha_connect::GetStringOption(PCSZ opname, PCSZ sdef)
PTOS options= GetTableOptionStruct();
if (!stricmp(opname, "Connect")) {
- LEX_CSTRING cnc= (tshp) ? tshp->connect_string
+ LEX_CSTRING cnc= (tshp) ? tshp->connect_string
: table->s->connect_string;
if (cnc.length)
@@ -1572,6 +1597,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
// Now get column information
pcf->Name= (char*)fp->field_name.str;
+ chset = (char*)fp->charset()->name;
if (fop && fop->special) {
pcf->Fieldfmt= (char*)fop->special;
@@ -1582,8 +1608,15 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
pcf->Scale= 0;
pcf->Opt= (fop) ? (int)fop->opt : 0;
- if ((pcf->Length= fp->field_length) < 0)
- pcf->Length= 256; // BLOB?
+ if (fp->field_length >= 0) {
+ pcf->Length = fp->field_length;
+
+ // length is bytes for Connect, not characters
+ if (!strnicmp(chset, "utf8", 4))
+ pcf->Length /= 3;
+
+ } else
+ pcf->Length= 256; // BLOB?
pcf->Precision= pcf->Length;
@@ -1600,8 +1633,6 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
pcf->Fieldfmt= NULL;
} // endif fop
- chset= (char *)fp->charset()->name;
-
if (!strcmp(chset, "binary"))
v = 'B'; // Binary string
@@ -2155,7 +2186,6 @@ int ha_connect::MakeRecord(char *buf)
int rc= 0;
Field* *field;
Field *fp;
- my_bitmap_map *org_bitmap;
CHARSET_INFO *charset= tdbp->data_charset();
//MY_BITMAP readmap;
MY_BITMAP *map;
@@ -2169,7 +2199,7 @@ int ha_connect::MakeRecord(char *buf)
*table->def_read_set.bitmap, *table->def_write_set.bitmap);
// Avoid asserts in field::store() for columns that are not updated
- org_bitmap= dbug_tmp_use_all_columns(table, table->write_set);
+ MY_BITMAP *org_bitmap= dbug_tmp_use_all_columns(table, &table->write_set);
// This is for variable_length rows
memset(buf, 0, table->s->null_bytes);
@@ -2196,7 +2226,7 @@ int ha_connect::MakeRecord(char *buf)
continue;
htrc("Column %s not found\n", fp->field_name.str);
- dbug_tmp_restore_column_map(table->write_set, org_bitmap);
+ dbug_tmp_restore_column_map(&table->write_set, org_bitmap);
DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
} // endif colp
@@ -2256,7 +2286,7 @@ int ha_connect::MakeRecord(char *buf)
sprintf(buf, "Out of range value %.140s for column '%s' at row %ld",
value->GetCharString(val),
- fp->field_name.str,
+ fp->field_name.str,
thd->get_stmt_da()->current_row_for_warning());
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, buf);
@@ -2279,7 +2309,7 @@ int ha_connect::MakeRecord(char *buf)
memcpy(buf, table->record[0], table->s->stored_rec_length);
// This is copied from ha_tina and is necessary to avoid asserts
- dbug_tmp_restore_column_map(table->write_set, org_bitmap);
+ dbug_tmp_restore_column_map(&table->write_set, org_bitmap);
DBUG_RETURN(rc);
} // end of MakeRecord
@@ -2299,7 +2329,7 @@ int ha_connect::ScanRecord(PGLOBAL g, const uchar *)
//PTDBASE tp= (PTDBASE)tdbp;
String attribute(attr_buffer, sizeof(attr_buffer),
table->s->table_charset);
- my_bitmap_map *bmap= dbug_tmp_use_all_columns(table, table->read_set);
+ MY_BITMAP *bmap= dbug_tmp_use_all_columns(table, &table->read_set);
const CHARSET_INFO *charset= tdbp->data_charset();
String data_charset_value(data_buffer, sizeof(data_buffer), charset);
@@ -2421,7 +2451,7 @@ int ha_connect::ScanRecord(PGLOBAL g, const uchar *)
} // endfor field
err:
- dbug_tmp_restore_column_map(table->read_set, bmap);
+ dbug_tmp_restore_column_map(&table->read_set, bmap);
return rc;
} // end of ScanRecord
@@ -2469,7 +2499,7 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
OPVAL op;
Field *fp;
const key_range *ranges[2];
- my_bitmap_map *old_map;
+ MY_BITMAP *old_map;
KEY *kfp;
KEY_PART_INFO *kpart;
@@ -2486,7 +2516,7 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
both= ranges[0] && ranges[1];
kfp= &table->key_info[active_index];
- old_map= dbug_tmp_use_all_columns(table, table->write_set);
+ old_map= dbug_tmp_use_all_columns(table, &table->write_set);
for (i= 0; i <= 1; i++) {
if (ranges[i] == NULL)
@@ -2581,11 +2611,11 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
if ((oom= qry->IsTruncated()))
strcpy(g->Message, "Out of memory");
- dbug_tmp_restore_column_map(table->write_set, old_map);
+ dbug_tmp_restore_column_map(&table->write_set, old_map);
return oom;
err:
- dbug_tmp_restore_column_map(table->write_set, old_map);
+ dbug_tmp_restore_column_map(&table->write_set, old_map);
return true;
} // end of MakeKeyWhere
@@ -4500,7 +4530,10 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, const char *dbn, bool
case TAB_VEC:
case TAB_REST:
case TAB_JSON:
- if (options->filename && *options->filename) {
+#if defined(BSON_SUPPORT)
+ case TAB_BSON:
+#endif // BSON_SUPPORT
+ if (options->filename && *options->filename) {
if (!quick) {
char path[FN_REFLEN], dbpath[FN_REFLEN];
@@ -4531,11 +4564,10 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, const char *dbn, bool
case TAB_DIR:
case TAB_ZIP:
case TAB_OEM:
- if (table && table->pos_in_table_list) { // if SELECT
+ if (table && table->pos_in_table_list) { // if SELECT
#if MYSQL_VERSION_ID > 100200
Switch_to_definer_security_ctx backup_ctx(thd, table->pos_in_table_list);
#endif // VERSION_ID > 100200
-
return check_global_access(thd, FILE_ACL);
} else
return check_global_access(thd, FILE_ACL);
@@ -4551,9 +4583,10 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, const char *dbn, bool
case TAB_OCCUR:
case TAB_PIVOT:
case TAB_VIR:
+ default:
// This is temporary until a solution is found
return false;
- } // endswitch type
+ } // endswitch type
my_printf_error(ER_UNKNOWN_ERROR, "check_privileges failed", MYF(0));
return true;
@@ -4804,6 +4837,7 @@ int ha_connect::start_stmt(THD *thd, thr_lock_type lock_type)
lock.cc by lock_external() and unlock_external() in lock.cc;
the section "locking functions for mysql" in lock.cc;
copy_data_between_tables() in sql_table.cc.
+
*/
int ha_connect::external_lock(THD *thd, int lock_type)
{
@@ -4936,11 +4970,11 @@ int ha_connect::external_lock(THD *thd, int lock_type)
// Here we do make the new indexes
if (tdp->MakeIndex(g, adp, true) == RC_FX) {
// Make it a warning to avoid crash
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
- 0, g->Message);
- rc= 0;
- //my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
- //rc= HA_ERR_INTERNAL_ERROR;
+ //push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
+ // 0, g->Message);
+ //rc= 0;
+ my_message(ER_TOO_MANY_KEYS, g->Message, MYF(0));
+ rc= HA_ERR_INDEX_CORRUPT;
} // endif MakeIndex
} else if (tdbp->GetDef()->Indexable() == 3) {
@@ -5354,7 +5388,8 @@ static char *encode(PGLOBAL g, const char *cnm)
*/
static bool add_field(String* sql, TABTYPE ttp, const char* field_name, int typ,
int len, int dec, char* key, uint tm, const char* rem,
- char* dft, char* xtra, char* fmt, int flag, bool dbf, char v) {
+ char* dft, char* xtra, char* fmt, int flag, bool dbf, char v)
+{
#if defined(DEVELOPMENT)
// Some client programs regard CHAR(36) as GUID
char var = (len > 255 || len == 36) ? 'V' : v;
@@ -5431,7 +5466,10 @@ static bool add_field(String* sql, TABTYPE ttp, const char* field_name, int typ,
if (fmt && *fmt) {
switch (ttp) {
case TAB_JSON: error |= sql->append(" JPATH='"); break;
- case TAB_XML: error |= sql->append(" XPATH='"); break;
+#if defined(BSON_SUPPORT)
+ case TAB_BSON: error |= sql->append(" JPATH='"); break;
+#endif // BSON_SUPPORT
+ case TAB_XML: error |= sql->append(" XPATH='"); break;
default: error |= sql->append(" FIELD_FORMAT='");
} // endswitch ttp
@@ -5596,8 +5634,8 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
String sql(buf, sizeof(buf), system_charset_info);
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
- user = host = pwd = tbl = src = col = ocl = pic = fcl = skc = rnk = zfn = NULL;
- dsn = url = NULL;
+ user= host= pwd= tbl= src= col= ocl= pic= fcl= skc= rnk= zfn= NULL;
+ dsn= url= NULL;
// Get the useful create options
ttp= GetTypeID(topt->type);
@@ -5658,7 +5696,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
try {
// Check table type
- if (ttp == TAB_UNDEF) {
+ if (ttp == TAB_UNDEF && !topt->http) {
topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS";
ttp= GetTypeID(topt->type);
sprintf(g->Message, "No table_type. Was set to %s", topt->type);
@@ -5669,11 +5707,21 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
goto err;
#if defined(REST_SUPPORT)
} else if (topt->http) {
- switch (ttp) {
+ if (ttp == TAB_UNDEF) {
+ topt->type = "JSON";
+ ttp= GetTypeID(topt->type);
+ sprintf(g->Message, "No table_type. Was set to %s", topt->type);
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
+ } // endif ttp
+
+ switch (ttp) {
case TAB_JSON:
- case TAB_XML:
+#if defined(BSON_SUPPORT)
+ case TAB_BSON:
+#endif // BSON_SUPPORT
+ case TAB_XML:
case TAB_CSV:
- ttp = TAB_REST;
+ ttp = TAB_REST;
break;
default:
break;
@@ -5856,7 +5904,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
case TAB_XML:
#endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT
case TAB_JSON:
- dsn= strz(g, create_info->connect_string);
+#if defined(BSON_SUPPORT)
+ case TAB_BSON:
+#endif // BSON_SUPPORT
+ dsn= strz(g, create_info->connect_string);
if (!fn && !zfn && !mul && !dsn)
sprintf(g->Message, "Missing %s file name", topt->type);
@@ -6020,8 +6071,15 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
qrp= VirColumns(g, fnc == FNC_COL);
break;
case TAB_JSON:
+#if !defined(FORCE_BSON)
qrp= JSONColumns(g, db, dsn, topt, fnc == FNC_COL);
break;
+#endif // !FORCE_BSON
+#if defined(BSON_SUPPORT)
+ case TAB_BSON:
+ qrp= BSONColumns(g, db, dsn, topt, fnc == FNC_COL);
+ break;
+#endif // BSON_SUPPORT
#if defined(JAVA_SUPPORT)
case TAB_MONGO:
url= strz(g, create_info->connect_string);
@@ -6086,6 +6144,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
goto err;
} // endif !nblin
+ // Restore language type
+ if (ttp == TAB_REST)
+ ttp = GetTypeID(topt->type);
+
for (i= 0; !rc && i < qrp->Nblin; i++) {
typ= len= prec= dec= flg= 0;
tm= NOT_NULL_FLAG;
@@ -6261,7 +6323,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
// Now add the field
if (add_field(&sql, ttp, cnm, typ, prec, dec, key, tm, rem, dft, xtra,
- fmt, flg, dbf, v))
+ fmt, flg, dbf, v))
rc= HA_ERR_OUT_OF_MEM;
} // endfor i
@@ -6385,6 +6447,9 @@ int ha_connect::create(const char *name, TABLE *table_arg,
// Check table type
if (type == TAB_UNDEF) {
options->type= (options->srcdef) ? "MYSQL" :
+#if defined(REST_SUPPORT)
+ (options->http) ? "JSON" :
+#endif // REST_SUPPORT
(options->tabname) ? "PROXY" : "DOS";
type= GetTypeID(options->type);
sprintf(g->Message, "No table_type. Will be set to %s", options->type);
@@ -6402,7 +6467,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
inward= IsFileType(type) && !options->filename &&
- (type != TAB_JSON || !cnc.length);
+ ((type != TAB_JSON && type != TAB_BSON) || !cnc.length);
if (options->data_charset) {
const CHARSET_INFO *data_charset;
@@ -6760,8 +6825,8 @@ int ha_connect::create(const char *name, TABLE *table_arg,
if (trace(1))
htrc("xchk=%p createas=%d\n", g->Xchk, g->Createas);
-#if defined(ZIP_SUPPORT)
if (options->zipped) {
+#if defined(ZIP_SUPPORT)
// Check whether the zip entry must be made from a file
PCSZ fn= GetListOption(g, "Load", options->oplist, NULL);
@@ -6783,9 +6848,11 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endif LoadFile
} // endif fn
-
+#else // !ZIP_SUPPORT
+ my_message(ER_UNKNOWN_ERROR, "Option ZIP not supported", MYF(0));
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+#endif // !ZIP_SUPPORT
} // endif zipped
-#endif // ZIP_SUPPORT
// To check whether indexes have to be made or remade
if (!g->Xchk) {
@@ -7387,7 +7454,8 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(json_null),
MYSQL_SYSVAR(json_all_path),
MYSQL_SYSVAR(default_depth),
- MYSQL_SYSVAR(json_grp_size),
+ MYSQL_SYSVAR(default_prec),
+ MYSQL_SYSVAR(json_grp_size),
#if defined(JAVA_SUPPORT)
MYSQL_SYSVAR(jvm_path),
MYSQL_SYSVAR(class_path),
@@ -7397,7 +7465,10 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(enable_mongo),
#endif // JAVA_SUPPORT || CMGO_SUPPORT
MYSQL_SYSVAR(cond_push),
- NULL
+#if defined(BSON_SUPPORT)
+ MYSQL_SYSVAR(force_bson),
+#endif // BSON_SUPPORT
+ NULL
};
maria_declare_plugin(connect)