1 /* Copyright (C) MariaDB Corporation Ab
2 
3   This program is free software; you can redistribute it and/or modify
4   it under the terms of the GNU General Public License as published by
5   the Free Software Foundation; version 2 of the License.
6 
7   This program is distributed in the hope that it will be useful,
8   but WITHOUT ANY WARRANTY; without even the implied warranty of
9   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10   GNU General Public License for more details.
11 
12   You should have received a copy of the GNU General Public License
13   along with this program; if not, write to the Free Software
14   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
15 
16 /*************** Mycat CC Program Source Code File (.CC) ***************/
17 /* PROGRAM NAME: MYCAT                                                 */
18 /* -------------                                                       */
19 /*  Version 1.8                                                        */
20 /*                                                                     */
21 /*  Author: Olivier Bertrand                       2012 - 2020         */
22 /*                                                                     */
23 /* WHAT THIS PROGRAM DOES:                                             */
24 /* -----------------------                                             */
25 /*  This program are the DB description related routines.              */
26 /***********************************************************************/
27 
28 /***********************************************************************/
29 /*  Include relevant MariaDB header file.                              */
30 /***********************************************************************/
31 #define DONT_DEFINE_VOID
32 #include <my_global.h>
33 
34 #if defined(UNIX)
35 #include <unistd.h>
36 #include <string.h>
37 #endif
38 #include "handler.h"
39 #undef  OFFSET
40 
41 /***********************************************************************/
42 /*  Include application header files                                   */
43 /*                                                                     */
44 /*  global.h     is header containing all global declarations.         */
45 /*  plgdbsem.h   is header containing DB application declarations.     */
46 /*  tabdos.h     is header containing TDBDOS classes declarations.     */
47 /*  MYCAT.h      is header containing DB description declarations.     */
48 /***********************************************************************/
49 #if defined(UNIX)
50 #include "osutil.h"
51 #endif   // UNIX
52 #include "global.h"
53 #include "plgdbsem.h"
54 //#include "reldef.h"
55 #include "xtable.h"
56 #include "tabext.h"
57 #include "tabcol.h"
58 #include "filamtxt.h"
59 #include "tabdos.h"
60 #include "tabfmt.h"
61 #if defined(VCT_SUPPORT)
62 #include "tabvct.h"
63 #endif   // VCT_SUPPORT
64 #include "tabsys.h"
65 #if defined(_WIN32)
66 #include "tabmac.h"
67 #include "tabwmi.h"
68 #endif   // _WIN32
69 //#include "tabtbl.h"
70 #include "tabxcl.h"
71 #include "tabtbl.h"
72 #include "taboccur.h"
73 #include "tabmul.h"
74 #include "tabmysql.h"
75 #if defined(ODBC_SUPPORT)
76 #define NODBC
77 #include "tabodbc.h"
78 #endif   // ODBC_SUPPORT
79 #if defined(JAVA_SUPPORT)
80 #define NJDBC
81 #include "tabjdbc.h"
82 #endif   // JAVA_SUPPORT
83 #include "tabpivot.h"
84 #include "tabvir.h"
85 #if defined(BSON_SUPPORT)
86 #include "tabbson.h"
87 #else
88 #include "tabjson.h"
89 #endif   // BSON_SUPPORT
90 #include "ha_connect.h"
91 #if defined(XML_SUPPORT)
92 #include "tabxml.h"
93 #endif   // XML_SUPPORT
94 #if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
95 #include "mongo.h"
96 #endif   // JAVA_SUPPORT || CMGO_SUPPORT
97 #if defined(ZIP_SUPPORT)
98 #include "tabzip.h"
99 #endif   // ZIP_SUPPORT
100 #if defined(REST_SUPPORT)
101 #include "tabrest.h"
102 #endif   // REST_SUPPORT
103 #include "mycat.h"
104 
105 /***********************************************************************/
106 /*  Extern static variables.                                           */
107 /***********************************************************************/
108 #if defined(_WIN32)
109 extern "C" HINSTANCE s_hModule;           // Saved module handle
110 #endif  // !_WIN32
111 #if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
112 bool MongoEnabled(void);
113 #endif   // JAVA_SUPPORT || CMGO_SUPPORT
114 #if defined(BSON_SUPPORT)
115 bool Force_Bson(void);
116 #endif   // BSON_SUPPORT
117 
118 /***********************************************************************/
119 /*  Get the plugin directory.                                          */
120 /***********************************************************************/
GetPluginDir(void)121 char *GetPluginDir(void)
122 {
123   return opt_plugin_dir;
124 } // end of GetPluginDir
125 
126 /***********************************************************************/
127 /*  Get the lc_messages_dir, it is where error messages for various    */
128 /*  languages are installed, and by default the INSTALL_MYSQLSHAREDIR. */
129 /***********************************************************************/
GetMessageDir(void)130 char *GetMessageDir(void)
131 {
132   return lc_messages_dir;
133 } // end of GetMessageDir
134 
135 /***********************************************************************/
136 /*  Get a unique enum table type ID.                                   */
137 /***********************************************************************/
GetTypeID(const char * type)138 TABTYPE GetTypeID(const char *type)
139   {
140   return (!type) ? TAB_UNDEF
141                  : (!stricmp(type, "DOS"))   ? TAB_DOS
142                  : (!stricmp(type, "FIX"))   ? TAB_FIX
143                  : (!stricmp(type, "BIN"))   ? TAB_BIN
144                  : (!stricmp(type, "CSV"))   ? TAB_CSV
145                  : (!stricmp(type, "FMT"))   ? TAB_FMT
146                  : (!stricmp(type, "DBF"))   ? TAB_DBF
147 #if defined(XML_SUPPORT)
148                  : (!stricmp(type, "XML"))   ? TAB_XML
149 #endif   // XML_SUPPORT
150                  : (!stricmp(type, "INI"))   ? TAB_INI
151                  : (!stricmp(type, "VEC"))   ? TAB_VEC
152 #if defined(ODBC_SUPPORT)
153                  : (!stricmp(type, "ODBC"))  ? TAB_ODBC
154 #endif   // ODBC_SUPPORT
155 #if defined(JAVA_SUPPORT)
156                  : (!stricmp(type, "JDBC"))  ? TAB_JDBC
157 #endif   // JAVA_SUPPORT
158 #if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
159                  : (!stricmp(type, "MONGO") && MongoEnabled()) ? TAB_MONGO
160 #endif   // JAVA_SUPPORT  ||         CMGO_SUPPORT
161                  : (!stricmp(type, "MYSQL")) ? TAB_MYSQL
162                  : (!stricmp(type, "MYPRX")) ? TAB_MYSQL
163                  : (!stricmp(type, "DIR"))   ? TAB_DIR
164 #if defined(_WIN32)
165                  : (!stricmp(type, "MAC"))   ? TAB_MAC
166                  : (!stricmp(type, "WMI"))   ? TAB_WMI
167 #endif   // _WIN32
168                  : (!stricmp(type, "TBL"))   ? TAB_TBL
169                  : (!stricmp(type, "XCOL"))  ? TAB_XCL
170                  : (!stricmp(type, "OCCUR")) ? TAB_OCCUR
171                  : (!stricmp(type, "CATLG")) ? TAB_PRX  // Legacy
172                  : (!stricmp(type, "PROXY")) ? TAB_PRX
173                  : (!stricmp(type, "PIVOT")) ? TAB_PIVOT
174                  : (!stricmp(type, "VIR"))   ? TAB_VIR
175                  : (!stricmp(type, "JSON"))  ? TAB_JSON
176 #if defined(BSON_SUPPORT)
177                  : (!stricmp(type, "BSON"))  ? TAB_BSON
178 #endif   // BSON_SUPPORT
179 #if defined(ZIP_SUPPORT)
180                  : (!stricmp(type, "ZIP"))   ? TAB_ZIP
181 #endif   // ZIP_SUPPORT
182                  : (!stricmp(type, "OEM"))   ? TAB_OEM : TAB_NIY;
183   } // end of GetTypeID
184 
185 /***********************************************************************/
186 /*  Return true for table types based on file.                         */
187 /***********************************************************************/
IsFileType(TABTYPE type)188 bool IsFileType(TABTYPE type)
189   {
190   bool isfile;
191 
192   switch (type) {
193     case TAB_DOS:
194     case TAB_FIX:
195     case TAB_BIN:
196     case TAB_CSV:
197     case TAB_FMT:
198     case TAB_DBF:
199     case TAB_XML:
200     case TAB_INI:
201     case TAB_VEC:
202     case TAB_JSON:
203 #if defined(BSON_SUPPORT)
204     case TAB_BSON:
205 #endif   // BSON_SUPPORT
206     case TAB_REST:
207  // case TAB_ZIP:
208       isfile= true;
209       break;
210     default:
211       isfile= false;
212       break;
213     } // endswitch type
214 
215   return isfile;
216   } // end of IsFileType
217 
218 /***********************************************************************/
219 /*  Return true for table types returning exact row count.             */
220 /***********************************************************************/
IsExactType(TABTYPE type)221 bool IsExactType(TABTYPE type)
222   {
223   bool exact;
224 
225   switch (type) {
226     case TAB_FIX:
227     case TAB_BIN:
228     case TAB_DBF:
229 //  case TAB_XML:     depends on Multiple || Xpand || Coltype
230 //  case TAB_JSON:    depends on Multiple || Xpand || Coltype
231     case TAB_VEC:
232     case TAB_VIR:
233       exact= true;
234       break;
235     default:
236       exact= false;
237       break;
238     } // endswitch type
239 
240   return exact;
241   } // end of IsExactType
242 
243 /***********************************************************************/
244 /*  Return true for table types accepting null fields.                 */
245 /***********************************************************************/
IsTypeNullable(TABTYPE type)246 bool IsTypeNullable(TABTYPE type)
247   {
248   bool nullable;
249 
250   switch (type) {
251     case TAB_MAC:
252     case TAB_DIR:
253       nullable= false;
254       break;
255     default:
256       nullable= true;
257       break;
258     } // endswitch type
259 
260   return nullable;
261   } // end of IsTypeNullable
262 
263 /***********************************************************************/
264 /*  Return true for fixed record length tables.                        */
265 /***********************************************************************/
IsTypeFixed(TABTYPE type)266 bool IsTypeFixed(TABTYPE type)
267   {
268   bool fix;
269 
270   switch (type) {
271     case TAB_FIX:
272     case TAB_BIN:
273     case TAB_VEC:
274 //  case TAB_DBF:         ???
275       fix= true;
276       break;
277     default:
278       fix= false;
279       break;
280     } // endswitch type
281 
282   return fix;
283   } // end of IsTypeFixed
284 
285 /***********************************************************************/
286 /*  Return true for table indexable by XINDEX.                         */
287 /***********************************************************************/
IsTypeIndexable(TABTYPE type)288 bool IsTypeIndexable(TABTYPE type)
289   {
290   bool idx;
291 
292   switch (type) {
293     case TAB_DOS:
294     case TAB_CSV:
295     case TAB_FMT:
296     case TAB_FIX:
297     case TAB_BIN:
298     case TAB_VEC:
299     case TAB_DBF:
300     case TAB_JSON:
301 #if defined(BSON_SUPPORT)
302     case TAB_BSON:
303 #endif   // BSON_SUPPORT
304       idx= true;
305       break;
306     default:
307       idx= false;
308       break;
309     } // endswitch type
310 
311   return idx;
312   } // end of IsTypeIndexable
313 
314 /***********************************************************************/
315 /*  Return index type: 0 NO, 1 XINDEX, 2 REMOTE.                       */
316 /***********************************************************************/
GetIndexType(TABTYPE type)317 int GetIndexType(TABTYPE type)
318   {
319   int xtyp;
320 
321   switch (type) {
322     case TAB_DOS:
323     case TAB_CSV:
324     case TAB_FMT:
325     case TAB_FIX:
326     case TAB_BIN:
327     case TAB_VEC:
328     case TAB_DBF:
329     case TAB_JSON:
330 #if defined(BSON_SUPPORT)
331     case TAB_BSON:
332 #endif   // BSON_SUPPORT
333       xtyp= 1;
334       break;
335     case TAB_MYSQL:
336     case TAB_ODBC:
337     case TAB_JDBC:
338     case TAB_MONGO:
339       xtyp= 2;
340       break;
341     case TAB_VIR:
342       xtyp= 3;
343       break;
344     default:
345       xtyp= 0;
346       break;
347     } // endswitch type
348 
349   return xtyp;
350   } // end of GetIndexType
351 
352 /***********************************************************************/
353 /*  Get a unique enum catalog function ID.                             */
354 /***********************************************************************/
GetFuncID(const char * func)355 uint GetFuncID(const char *func)
356   {
357   uint fnc;
358 
359   if (!func)
360     fnc= FNC_NO;
361   else if (!strnicmp(func, "col", 3))
362     fnc= FNC_COL;
363   else if (!strnicmp(func, "tab", 3))
364     fnc= FNC_TABLE;
365   else if (!stricmp(func, "dsn") ||
366            !strnicmp(func, "datasource", 10) ||
367            !strnicmp(func, "source", 6) ||
368            !strnicmp(func, "sqldatasource", 13))
369     fnc= FNC_DSN;
370   else if (!strnicmp(func, "driver", 6) ||
371            !strnicmp(func, "sqldriver", 9))
372     fnc= FNC_DRIVER;
373   else
374     fnc= FNC_NIY;
375 
376   return fnc;
377   } // end of GetFuncID
378 
379 /* ------------------------- Class CATALOG --------------------------- */
380 
381 /***********************************************************************/
382 /*  CATALOG Constructor.                                               */
383 /***********************************************************************/
CATALOG(void)384 CATALOG::CATALOG(void)
385   {
386 #if defined(_WIN32)
387 //DataPath= ".\\";
388 #else   // !_WIN32
389 //DataPath= "./";
390 #endif  // !_WIN32
391   memset(&Ctb, 0, sizeof(CURTAB));
392   Cbuf= NULL;
393   Cblen= 0;
394   DefHuge= false;
395   } // end of CATALOG constructor
396 
397 /* -------------------------- Class MYCAT ---------------------------- */
398 
399 /***********************************************************************/
400 /*  MYCAT Constructor.                                                 */
401 /***********************************************************************/
MYCAT(PHC hc)402 MYCAT::MYCAT(PHC hc) : CATALOG()
403   {
404   Hc= hc;
405   DefHuge= false;
406   } // end of MYCAT constructor
407 
408 /***********************************************************************/
409 /*  Nothing to do for CONNECT.                                         */
410 /***********************************************************************/
Reset(void)411 void MYCAT::Reset(void)
412   {
413   } // end of Reset
414 
415 /***********************************************************************/
416 /*  GetTableDesc: retrieve a table descriptor.                         */
417 /*  Look for a table descriptor matching the name and type.            */
418 /***********************************************************************/
GetTableDesc(PGLOBAL g,PTABLE tablep,LPCSTR type,PRELDEF *)419 PTABDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep,
420                                        LPCSTR type, PRELDEF *)
421 {
422   PTABDEF tdp= NULL;
423 
424   if (trace(1))
425     htrc("GetTableDesc: name=%s am=%s\n", tablep->GetName(), SVP(type));
426 
427   // If not specified get the type of this table
428   //if (!type)
429   //  type= Hc->GetStringOption("Type","*");
430 
431   tdp= MakeTableDesc(g, tablep, type);
432 
433   if (trace(1))
434     htrc("GetTableDesc: tdp=%p\n", tdp);
435 
436   return tdp;
437 } // end of GetTableDesc
438 
439 /***********************************************************************/
440 /*  MakeTableDesc: make a table/view description.                      */
441 /*  Note: caller must check if name already exists before calling it.  */
442 /***********************************************************************/
MakeTableDesc(PGLOBAL g,PTABLE tablep,LPCSTR am)443 PTABDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
444   {
445   TABTYPE tc;
446   LPCSTR  name= (PSZ)PlugDup(g, tablep->GetName());
447   LPCSTR  schema= (PSZ)PlugDup(g, tablep->GetSchema());
448   PTABDEF tdp= NULL;
449 
450   if (trace(1))
451     htrc("MakeTableDesc: name=%s schema=%s am=%s\n",
452                            name, SVP(schema), SVP(am));
453 
454   /*********************************************************************/
455   /*  Get a unique enum identifier for types.                          */
456   /*********************************************************************/
457   if (!am) {
458     tc= Hc->GetRealType();
459     am= Hc->GetStringOption("Type","*");
460   } else
461     tc= GetTypeID(am);
462 
463   switch (tc) {
464     case TAB_FIX:
465     case TAB_BIN:
466     case TAB_DBF:
467     case TAB_DOS: tdp= new(g) DOSDEF;   break;
468     case TAB_CSV:
469     case TAB_FMT: tdp= new(g) CSVDEF;   break;
470     case TAB_INI: tdp= new(g) INIDEF;   break;
471     case TAB_DIR: tdp= new(g) DIRDEF;   break;
472 #if defined(XML_SUPPORT)
473     case TAB_XML: tdp= new(g) XMLDEF;   break;
474 #endif   // XML_SUPPORT
475 #if defined(VCT_SUPPORT)
476     case TAB_VEC: tdp= new(g) VCTDEF;  break;
477 #endif   // VCT_SUPPORT
478 #if defined(ODBC_SUPPORT)
479     case TAB_ODBC: tdp= new(g) ODBCDEF; break;
480 #endif   // ODBC_SUPPORT
481 #if defined(JAVA_SUPPORT)
482     case TAB_JDBC: tdp= new(g) JDBCDEF; break;
483 #endif   // JAVA_SUPPORT
484 #if defined(_WIN32)
485     case TAB_MAC: tdp= new(g) MACDEF;   break;
486     case TAB_WMI: tdp= new(g) WMIDEF;   break;
487 #endif   // _WIN32
488     case TAB_OEM: tdp= new(g) OEMDEF;   break;
489     case TAB_TBL: tdp= new(g) TBLDEF;   break;
490     case TAB_XCL: tdp= new(g) XCLDEF;   break;
491     case TAB_PRX: tdp= new(g) PRXDEF;   break;
492     case TAB_OCCUR: tdp= new(g) OCCURDEF; break;
493     case TAB_MYSQL: tdp= new(g) MYSQLDEF; break;
494     case TAB_PIVOT: tdp= new(g) PIVOTDEF; break;
495     case TAB_VIR: tdp= new(g) VIRDEF;   break;
496     case TAB_JSON:
497 #if defined(BSON_SUPPORT)
498       if (Force_Bson())
499         tdp= new(g) BSONDEF;
500       else
501 #endif   // BSON_SUPPORT
502         tdp= new(g) JSONDEF;
503 
504       break;
505 #if defined(BSON_SUPPORT)
506     case TAB_BSON: tdp= new(g) BSONDEF; break;
507 #endif   // BSON_SUPPORT
508 #if defined(ZIP_SUPPORT)
509     case TAB_ZIP: tdp= new(g) ZIPDEF;   break;
510 #endif   // ZIP_SUPPORT
511 #if defined(REST_SUPPORT)
512     case TAB_REST: tdp= new (g) RESTDEF; break;
513 #endif   // REST_SUPPORT
514 #if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
515     case TAB_MONGO:
516       if (MongoEnabled()) {
517         tdp = new(g) MGODEF;
518         break;
519       } // endif enabled
520       // fall through
521 #endif   // JAVA_SUPPORT || CMGO_SUPPORT
522     default:
523       sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
524     } // endswitch
525 
526   // Do make the table/view definition
527 	if (tdp && tdp->Define(g, this, name, schema, am))
528 		tdp = NULL;
529 
530   if (trace(1))
531     htrc("Table %s made\n", am);
532 
533   return tdp;
534   } // end of MakeTableDesc
535 
536 /***********************************************************************/
537 /*  Initialize a Table Description Block construction.                 */
538 /***********************************************************************/
GetTable(PGLOBAL g,PTABLE tablep,MODE mode,LPCSTR type)539 PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type)
540   {
541   PTABDEF tdp;
542   PTDB    tdbp= NULL;
543 //  LPCSTR  name= tablep->GetName();
544 
545   if (trace(1))
546     htrc("GetTableDB: name=%s\n", tablep->GetName());
547 
548   // Look for the description of the requested table
549   tdp= GetTableDesc(g, tablep, type);
550 
551   if (tdp) {
552     if (trace(1))
553       htrc("tdb=%p type=%s\n", tdp, tdp->GetType());
554 
555     if (tablep->GetSchema())
556       tdp->Database = SetPath(g, tablep->GetSchema());
557 
558     if (trace(2))
559       htrc("Going to get table...\n");
560 
561     tdbp= tdp->GetTable(g, mode);
562     } // endif tdp
563 
564   if (tdbp) {
565     if (trace(1))
566       htrc("tdbp=%p name=%s amtype=%d\n", tdbp, tdbp->GetName(),
567                                           tdbp->GetAmType());
568     tablep->SetTo_Tdb(tdbp);
569     tdbp->SetTable(tablep);
570     tdbp->SetMode(mode);
571     } // endif tdbp
572 
573   return (tdbp);
574   } // end of GetTable
575 
576 /***********************************************************************/
577 /*  ClearDB: Terminates Database usage.                                */
578 /***********************************************************************/
ClearDB(PGLOBAL)579 void MYCAT::ClearDB(PGLOBAL)
580   {
581   } // end of ClearDB
582 
583 /* ------------------------ End of MYCAT --------------------------- */
584