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