diff options
Diffstat (limited to 'storage/connect/ha_connect.cc')
-rw-r--r-- | storage/connect/ha_connect.cc | 226 |
1 files changed, 144 insertions, 82 deletions
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 72f3e601958..2c8e563ffdc 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -130,10 +130,8 @@ #if defined(ODBC_SUPPORT) #include "odbccat.h" #endif // ODBC_SUPPORT -#if defined(MYSQL_SUPPORT) #include "xtable.h" #include "tabmysql.h" -#endif // MYSQL_SUPPORT #include "filamdbf.h" #include "tabxcl.h" #include "tabfmt.h" @@ -147,7 +145,6 @@ #include "connect.h" #include "user_connect.h" #include "ha_connect.h" -#include "mycat.h" #include "myutil.h" #include "preparse.h" #include "inihandl.h" @@ -171,35 +168,21 @@ #define JSONMAX 10 // JSON Default max grp size extern "C" { - char version[]= "Version 1.03.0006 February 06, 2015"; - + char version[]= "Version 1.03.0007 April 30, 2015"; #if defined(WIN32) - char compver[]= "Version 1.03.0006 " __DATE__ " " __TIME__; + char compver[]= "Version 1.03.0007 " __DATE__ " " __TIME__; char slash= '\\'; #else // !WIN32 char slash= '/'; #endif // !WIN32 - -// int trace= 0; // The general trace value -// ulong xconv= 0; // The type conversion option -// int zconv= 0; // The text conversion size } // extern "C" #if defined(XMAP) my_bool xmap= false; #endif // XMAP -// uint worksize= 0; ulong ha_connect::num= 0; -//int DTVAL::Shift= 0; -/* CONNECT system variables */ -//atic int conv_size= 0; -//atic uint work_size= 0; -//atic ulong type_conv= 0; -#if defined(XMAP) -//atic my_bool indx_map= 0; -#endif // XMAP #if defined(XMSG) extern "C" { char *msg_path; @@ -211,6 +194,9 @@ extern "C" { /***********************************************************************/ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info); PQRYRES VirColumns(PGLOBAL g, char *tab, char *db, bool info); +PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn, + int pretty, int lvl, int mxr, bool info); +PQRYRES XMLColumns(PGLOBAL g, char *dp, char *tab, PTOS topt, bool info); void PushWarning(PGLOBAL g, THD *thd, int level); bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, const char *db, char *tab, const char *src, int port); @@ -613,9 +599,9 @@ DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir) delete_table method in handler.cc */ static const char *ha_connect_exts[]= { - ".dos", ".fix", ".csv", ".bin", ".fmt", ".dbf", ".xml", ".ini", ".vec", - ".dnx", ".fnx", ".bnx", ".vnx", ".dbx", ".dop", ".fop", ".bop", ".vop", - NULL}; + ".dos", ".fix", ".csv", ".bin", ".fmt", ".dbf", ".xml", ".json", ".ini", + ".vec", ".dnx", ".fnx", ".bnx", ".vnx", ".dbx", ".dop", ".fop", ".bop", + ".vop", NULL}; /** @brief @@ -1020,8 +1006,7 @@ char *GetListOption(PGLOBAL g, const char *opname, } // endif pv if (!stricmp(opname, key)) { - opval= (char*)PlugSubAlloc(g, NULL, strlen(val) + 1); - strcpy(opval, val); + opval= PlugDup(g, val); break; } else if (!pn) break; @@ -1506,8 +1491,7 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s) // Now get index information pn= (char*)s->keynames.type_names[n]; - name= (char*)PlugSubAlloc(g, NULL, strlen(pn) + 1); - strcpy(name, pn); // This is probably unuseful + name= PlugDup(g, pn); unique= (kp.flags & 1) != 0; pkp= NULL; @@ -1517,8 +1501,7 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s) // Get the the key parts info for (int k= 0; (unsigned)k < kp.user_defined_key_parts; k++) { pn= (char*)kp.key_part[k].field->field_name; - name= (char*)PlugSubAlloc(g, NULL, strlen(pn) + 1); - strcpy(name, pn); // This is probably unuseful + name= PlugDup(g, pn); // Allocate the key part description block kpp= new(g) KPARTDEF(name, k + 1); @@ -2176,12 +2159,12 @@ int ha_connect::CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf) /***********************************************************************/ /* Return the where clause for remote indexed read. */ /***********************************************************************/ -bool ha_connect::MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q, +bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL op, char q, const void *key, int klen) { const uchar *ptr; uint rem, len, stlen; //, prtlen; - bool nq, b= false; + bool nq, oom, b= false; Field *fp; KEY *kfp; KEY_PART_INFO *kpart; @@ -2193,7 +2176,7 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q, return true; } // endif key - strcat(qry, " WHERE ("); + oom= qry->Append(" WHERE ("); kfp= &table->key_info[active_index]; rem= kfp->user_defined_key_parts, len= klen, @@ -2206,24 +2189,26 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q, nq= fp->str_needs_quotes(); if (b) - strcat(qry, " AND "); + oom|= qry->Append(" AND "); else b= true; - strcat(strncat(strcat(qry, q), fp->field_name, strlen(fp->field_name)), q); + oom|= qry->Append(q); + oom|= qry->Append((PSZ)fp->field_name); + oom|= qry->Append(q); switch (op) { case OP_EQ: case OP_GT: case OP_GE: - strcat(qry, GetValStr(op, false)); + oom|= qry->Append((PSZ)GetValStr(op, false)); break; default: - strcat(qry, " ??? "); + oom|= qry->Append(" ??? "); } // endwitch op if (nq) - strcat(qry, "'"); + oom|= qry->Append('\''); if (kpart->key_part_flag & HA_VAR_LENGTH_PART) { String varchar; @@ -2231,17 +2216,17 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q, varchar.set_quick((char*) ptr+HA_KEY_BLOB_LENGTH, var_length, &my_charset_bin); - strncat(qry, varchar.ptr(), varchar.length()); + oom|= qry->Append(varchar.ptr(), varchar.length()); } else { char strbuff[MAX_FIELD_WIDTH]; String str(strbuff, sizeof(strbuff), kpart->field->charset()), *res; res= fp->val_str(&str, ptr); - strncat(qry, res->ptr(), res->length()); + oom|= qry->Append(res->ptr(), res->length()); } // endif flag if (nq) - strcat(qry, "'"); + oom|= qry->Append('\''); if (stlen >= len) break; @@ -2254,8 +2239,10 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q, ptr+= stlen - MY_TEST(kpart->null_bit); } // endfor kpart - strcat(qry, ")"); - return false; + if ((oom|= qry->Append(")"))) + strcpy(g->Message, "Out of memory"); + + return oom; } // end of MakeKeyWhere @@ -2717,7 +2704,12 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) case MYSQL_TYPE_DATETIME: if (tty == TYPE_AM_ODBC) { strcat(body, "{ts '"); - strcat(strncat(body, res->ptr(), res->length()), "'}"); + strncat(body, res->ptr(), res->length()); + + if (res->length() < 19) + strcat(body, "1970-01-01 00:00:00" + res->length()); + + strcat(body, "'}"); break; } // endif ODBC @@ -2742,6 +2734,10 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) case MYSQL_TYPE_DATETIME: strcat(body, "{ts '"); strncat(body, res->ptr(), res->length()); + + if (res->length() < 19) + strcat(body, "1970-01-01 00:00:00" + res->length()); + strcat(body, "'}"); break; case MYSQL_TYPE_DATE: @@ -4134,6 +4130,10 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd, break; // } // endif partitioned + case SQLCOM_END: + // Met in procedures: IF(EXISTS(SELECT... + newmode= MODE_READ; + break; default: htrc("Unsupported sql_command=%d\n", thd_sql_command(thd)); strcpy(g->Message, "CONNECT Unsupported command"); @@ -4629,8 +4629,13 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to) } // endif pos - } else // Avoid infamous DBUG_ASSERT - thd->get_stmt_da()->reset_diagnostics_area(); + } // endif open_table_def + +// This below was done to avoid DBUG_ASSERT in some case that +// we don't know anymore what they were. It was suppressed because +// it did cause assertion in other cases (see MDEV-7935) +// } else // Avoid infamous DBUG_ASSERT +// thd->get_stmt_da()->reset_diagnostics_area(); free_table_share(share); } else // Temporary file @@ -4713,6 +4718,25 @@ ha_rows ha_connect::records_in_range(uint inx, key_range *min_key, DBUG_RETURN(rows); } // end of records_in_range +// Used to check whether a MYSQL table is created on itself +bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, + const char *db, char *tab, const char *src, int port) +{ + if (src) + return false; + else if (host && stricmp(host, "localhost") && strcmp(host, "127.0.0.1")) + return false; + else if (db && stricmp(db, s->db.str)) + return false; + else if (tab && stricmp(tab, s->table_name.str)) + return false; + else if (port && port != (signed)GetDefaultPort()) + return false; + + strcpy(g->Message, "This MySQL table is defined on itself"); + return true; +} // end of CheckSelf + /** Convert an ISO-8859-1 column name to UTF-8 */ @@ -4735,9 +4759,9 @@ static char *encode(PGLOBAL g, const char *cnm) @return Return 0 if ok */ -static bool add_field(String *sql, const char *field_name, int typ, - int len, int dec, char *key, uint tm, const char *rem, - char *dft, char *xtra, int flag, bool dbf, char v) +static bool add_field(String *sql, 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 var = (len > 255) ? 'V' : v; bool q, error= false; @@ -4806,6 +4830,12 @@ static bool add_field(String *sql, const char *field_name, int typ, error|= sql->append("'"); } // endif rem + if (fmt && *fmt) { + error|= sql->append(" FIELD_FORMAT='"); + error|= sql->append_for_single_quote(fmt, strlen(fmt)); + error|= sql->append("'"); + } // endif flag + if (flag) { error|= sql->append(" FLAG="); error|= sql->append_ulonglong(flag); @@ -4910,25 +4940,6 @@ static int init_table_share(THD* thd, sql->ptr(), sql->length()); } // end of init_table_share -// Used to check whether a MYSQL table is created on itself -bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, - const char *db, char *tab, const char *src, int port) -{ - if (src) - return false; - else if (host && stricmp(host, "localhost") && strcmp(host, "127.0.0.1")) - return false; - else if (db && stricmp(db, s->db.str)) - return false; - else if (tab && stricmp(tab, s->table_name.str)) - return false; - else if (port && port != (signed)GetDefaultPort()) - return false; - - strcpy(g->Message, "This MySQL table is defined on itself"); - return true; -} // end of CheckSelf - /** @brief connect_assisted_discovery() is called when creating a table with no columns. @@ -4949,12 +4960,12 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, const char *fncn= "?"; const char *user, *fn, *db, *host, *pwd, *sep, *tbl, *src; const char *col, *ocl, *rnk, *pic, *fcl, *skc; - char *tab, *dsn, *shm, *dpath; + char *tab, *dsn, *shm, *dpath, *objn; #if defined(WIN32) char *nsp= NULL, *cls= NULL; #endif // WIN32 int port= 0, hdr= 0, mxr __attribute__((unused))= 0, mxe= 0, rc= 0; - int cop __attribute__((unused)) = 0; + int cop __attribute__((unused))= 0, pty= 2, lrecl= 0, lvl= 0; #if defined(ODBC_SUPPORT) POPARM sop = NULL; char *ucnc = NULL; @@ -4984,7 +4995,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, if (!g) return HA_ERR_INTERNAL_ERROR; - user= host= pwd= tbl= src= col= ocl= pic= fcl= skc= rnk= dsn= NULL; + user= host= pwd= tbl= src= col= ocl= pic= fcl= skc= rnk= dsn= objn= NULL; // Get the useful create options ttp= GetTypeID(topt->type); @@ -5000,6 +5011,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, hdr= (int)topt->header; tbl= topt->tablist; col= topt->colist; + lrecl= (int)topt->lrecl; if (topt->oplist) { host= GetListOption(g, "host", topt->oplist, "localhost"); @@ -5014,6 +5026,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, skc= GetListOption(g, "skipcol", topt->oplist, NULL); rnk= GetListOption(g, "rankcol", topt->oplist, NULL); pwd= GetListOption(g, "password", topt->oplist); + objn= GetListOption(g, "Object", topt->oplist, NULL); #if defined(WIN32) nsp= GetListOption(g, "namespace", topt->oplist); cls= GetListOption(g, "class", topt->oplist); @@ -5031,6 +5044,8 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, #if defined(PROMPT_OK) cop= atoi(GetListOption(g, "checkdsn", topt->oplist, "0")); #endif // PROMPT_OK + pty= atoi(GetListOption(g,"Pretty", topt->oplist, "2")); + lvl= atoi(GetListOption(g,"Level", topt->oplist, "0")); } else { host= "localhost"; user= (ttp == TAB_ODBC ? NULL : "root"); @@ -5074,8 +5089,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, goto err; } // endif tbl - tab= (char*)PlugSubAlloc(g, NULL, strlen(tbl) + 1); - strcpy(tab, tbl); + tab= PlugDup(g, tbl); if ((p= strchr(tab, ','))) *p= 0; @@ -5136,7 +5150,6 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ok= true; break; -#if defined(MYSQL_SUPPORT) case TAB_MYSQL: ok= true; @@ -5176,14 +5189,15 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ok= false; break; -#endif // MYSQL_SUPPORT #if defined(WIN32) case TAB_WMI: ok= true; break; #endif // WIN32 +#if defined(PIVOT_SUPPORT) case TAB_PIVOT: supfnc= FNC_NO; +#endif // PIVOT_SUPPORT case TAB_PRX: case TAB_TBL: case TAB_XCL: @@ -5202,6 +5216,16 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, strcpy(g->Message, "Missing OEM module or subtype"); break; +#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT) + case TAB_XML: +#endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT + case TAB_JSON: + if (!fn) + sprintf(g->Message, "Missing %s file name", topt->type); + else + ok= true; + + break; case TAB_VIR: ok= true; break; @@ -5223,7 +5247,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, } // endif src if (ok) { - char *cnm, *rem, *dft, *xtra, *key; + char *cnm, *rem, *dft, *xtra, *key, *fmt; int i, len, prec, dec, typ, flg; // if (cat) @@ -5275,12 +5299,10 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, break; #endif // ODBC_SUPPORT -#if defined(MYSQL_SUPPORT) case TAB_MYSQL: qrp= MyColumns(g, thd, host, db, user, pwd, tab, NULL, port, fnc == FNC_COL); break; -#endif // MYSQL_SUPPORT case TAB_CSV: qrp= CSVColumns(g, dpath, fn, spc, qch, hdr, mxe, fnc == FNC_COL); break; @@ -5306,12 +5328,22 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, } // endif OcrColumns break; +#if defined(PIVOT_SUPPORT) case TAB_PIVOT: qrp= PivotColumns(g, tab, src, pic, fcl, skc, host, db, user, pwd, port); break; +#endif // PIVOT_SUPPORT case TAB_VIR: qrp= VirColumns(g, tab, (char*)db, fnc == FNC_COL); break; + case TAB_JSON: + qrp= JSONColumns(g, (char*)db, fn, objn, pty, lrecl, lvl, fnc == FNC_COL); + break; +#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT) + case TAB_XML: + qrp= XMLColumns(g, (char*)db, tab, topt, fnc == FNC_COL); + break; +#endif // LIBXML2_SUPPORT || DOMDOC_SUPPORT case TAB_OEM: qrp= OEMColumns(g, topt, tab, (char*)db, fnc == FNC_COL); break; @@ -5328,7 +5360,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, if (fnc != FNC_NO || src || ttp == TAB_PIVOT) { // Catalog like table for (crp= qrp->Colresp; !rc && crp; crp= crp->Next) { - cnm= encode(g, crp->Name); + cnm= (ttp == TAB_PIVOT) ? crp->Name : encode(g, crp->Name); typ= crp->Type; len= crp->Length; dec= crp->Prec; @@ -5344,12 +5376,14 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, NOT_NULL_FLAG, "", flg, dbf, v); #else // !NEW_WAY if (add_field(&sql, cnm, typ, len, dec, NULL, NOT_NULL_FLAG, - NULL, NULL, NULL, flg, dbf, v)) + NULL, NULL, NULL, NULL, flg, dbf, v)) rc= HA_ERR_OUT_OF_MEM; #endif // !NEW_WAY } // endfor crp - } else { + } else { + char *schem= NULL; + // Not a catalog table if (!qrp->Nblin) { if (tab) @@ -5365,7 +5399,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, typ= len= prec= dec= 0; tm= NOT_NULL_FLAG; cnm= (char*)"noname"; - dft= xtra= key= NULL; + dft= xtra= key= fmt= NULL; v= ' '; #if defined(NEW_WAY) rem= ""; @@ -5405,6 +5439,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, tm= 0; // Nullable break; + case FLD_FORMAT: + fmt= (crp->Kdata) ? crp->Kdata->GetCharValue(i) : NULL; + break; case FLD_REM: rem= crp->Kdata->GetCharValue(i); break; @@ -5430,6 +5467,19 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, key= crp->Kdata->GetCharValue(i); break; + case FLD_SCHEM: +#if defined(ODBC_SUPPORT) + if (ttp == TAB_ODBC && crp->Kdata) { + if (schem && stricmp(schem, crp->Kdata->GetCharValue(i))) { + sprintf(g->Message, + "Several %s tables found, specify DBNAME", tab); + my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); + goto err; + } else if (!schem) + schem= crp->Kdata->GetCharValue(i); + + } // endif ttp +#endif // ODBC_SUPPORT default: break; // Ignore } // endswitch Fld @@ -5482,7 +5532,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, tm, rem, 0, dbf, v); #else // !NEW_WAY if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra, - 0, dbf, v)) + fmt, 0, dbf, v)) rc= HA_ERR_OUT_OF_MEM; #endif // !NEW_WAY } // endfor i @@ -5751,6 +5801,18 @@ int ha_connect::create(const char *name, TABLE *table_arg, } // endif type + if (type == TAB_JSON) { + int pretty= atoi(GetListOption(g, "Pretty", options->oplist, "2")); + + if (!options->lrecl && pretty != 2) { + sprintf(g->Message, "LRECL must be specified for pretty=%d", pretty); + my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); + rc= HA_ERR_INTERNAL_ERROR; + DBUG_RETURN(rc); + } // endif lrecl + + } // endif type + // Check column types for (field= table_arg->field; *field; field++) { fp= *field; @@ -6542,7 +6604,7 @@ maria_declare_plugin(connect) 0x0103, /* version number (1.03) */ NULL, /* status variables */ connect_system_variables, /* system variables */ - "1.03.0005", /* string version */ + "1.03.0006", /* string version */ MariaDB_PLUGIN_MATURITY_BETA /* maturity */ } maria_declare_plugin_end; |