1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-09 22:24:09 +03:00

Merge branch 'connect/10.1' into 10.1

This commit is contained in:
Sergei Golubchik
2015-11-19 18:09:06 +01:00
42 changed files with 5887 additions and 1704 deletions

View File

@@ -735,17 +735,12 @@ static void SetSwapValue(PVAL valp, char *kp)
/* IndexRead: fetch a record having the index value. */ /* IndexRead: fetch a record having the index value. */
/***********************************************************************/ /***********************************************************************/
RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op, RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
const void *key, int len, bool mrr) const key_range *kr, bool mrr)
{ {
char *kp= (char*)key;
int n, x; int n, x;
short lg;
bool rcb;
RCODE rc; RCODE rc;
PVAL valp;
PCOL colp;
XXBASE *xbp; XXBASE *xbp;
PTDBDOX tdbp; PTDBDOX tdbp;
if (!ptdb) if (!ptdb)
return RC_FX; return RC_FX;
@@ -757,13 +752,13 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
return RC_FX; return RC_FX;
} else if (x == 2) { } else if (x == 2) {
// Remote index // Remote index
if (ptdb->ReadKey(g, op, key, len)) if (ptdb->ReadKey(g, op, kr))
return RC_FX; return RC_FX;
goto rnd; goto rnd;
} else if (x == 3) { } else if (x == 3) {
if (key) if (kr)
((PTDBASE)ptdb)->SetRecpos(g, *(int*)key); ((PTDBASE)ptdb)->SetRecpos(g, *(int*)kr->key);
if (op == OP_SAME) if (op == OP_SAME)
return RC_NF; return RC_NF;
@@ -790,7 +785,14 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
xbp= (XXBASE*)tdbp->To_Kindex; xbp= (XXBASE*)tdbp->To_Kindex;
if (key) { if (kr) {
char *kp= (char*)kr->key;
int len= kr->length;
short lg;
bool rcb;
PVAL valp;
PCOL colp;
for (n= 0; n < tdbp->Knum; n++) { for (n= 0; n < tdbp->Knum; n++) {
colp= (PCOL)tdbp->To_Key_Col[n]; colp= (PCOL)tdbp->To_Key_Col[n];
@@ -832,10 +834,10 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
kp+= valp->GetClen(); kp+= valp->GetClen();
if (len == kp - (char*)key) { if (len == kp - (char*)kr->key) {
n++; n++;
break; break;
} else if (len < kp - (char*)key) { } else if (len < kp - (char*)kr->key) {
strcpy(g->Message, "Key buffer is too small"); strcpy(g->Message, "Key buffer is too small");
return RC_FX; return RC_FX;
} // endif len } // endif len

View File

@@ -36,7 +36,7 @@ bool CntRewindTable(PGLOBAL g, PTDB tdbp);
int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort); int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort);
int CntIndexInit(PGLOBAL g, PTDB tdbp, int id, bool sorted); int CntIndexInit(PGLOBAL g, PTDB tdbp, int id, bool sorted);
RCODE CntReadNext(PGLOBAL g, PTDB tdbp); RCODE CntReadNext(PGLOBAL g, PTDB tdbp);
RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n, bool mrr); RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const key_range *kr, bool mrr);
RCODE CntWriteRow(PGLOBAL g, PTDB tdbp); RCODE CntWriteRow(PGLOBAL g, PTDB tdbp);
RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp); RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp);
RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all); RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all);
@@ -60,7 +60,7 @@ class TDBDOX: public TDBDOS {
friend int MakeIndex(PGLOBAL, PTDB, PIXDEF); friend int MakeIndex(PGLOBAL, PTDB, PIXDEF);
friend int CntCloseTable(PGLOBAL, PTDB, bool, bool); friend int CntCloseTable(PGLOBAL, PTDB, bool, bool);
friend int CntIndexInit(PGLOBAL, PTDB, int, bool); friend int CntIndexInit(PGLOBAL, PTDB, int, bool);
friend RCODE CntIndexRead(PGLOBAL, PTDB, OPVAL, const void*, int, bool); friend RCODE CntIndexRead(PGLOBAL, PTDB, OPVAL, const key_range*, bool);
friend RCODE CntDeleteRow(PGLOBAL, PTDB, bool); friend RCODE CntDeleteRow(PGLOBAL, PTDB, bool);
friend int CntIndexRange(PGLOBAL, PTDB, const uchar**, uint*, friend int CntIndexRange(PGLOBAL, PTDB, const uchar**, uint*,
bool*, key_part_map*); bool*, key_part_map*);

View File

@@ -1,366 +0,0 @@
100 IDS_TABLES "Table Headers"
101 IDS_TAB_01 "Table_Cat"
102 IDS_TAB_02 "Table_Schema"
103 IDS_TAB_03 "Table_Name"
104 IDS_TAB_04 "Table_Type"
105 IDS_TAB_05 "Remark"
106 IDS_COLUMNS "Column Headers"
107 IDS_COL_01 "Table_Cat"
108 IDS_COL_02 "Table_Schema"
109 IDS_COL_03 "Table_Name"
110 IDS_COL_04 "Column_Name"
111 IDS_COL_05 "Data_Type"
112 IDS_COL_06 "Type_Name"
113 IDS_COL_07 "Column_Size"
114 IDS_COL_08 "Buffer_Length"
115 IDS_COL_09 "Decimal_Digits"
116 IDS_COL_10 "Radix"
117 IDS_COL_11 "Nullable"
118 IDS_COL_12 "Remarks"
119 IDS_PKEY "Key Headers"
120 IDS_PKY_01 "Table_Catalog"
121 IDS_PKY_02 "Table_Schema"
122 IDS_PKY_03 "Table_Name"
123 IDS_PKY_04 "Column_Name"
124 IDS_PKY_05 "Key_Seq"
125 IDS_PKY_06 "Pk_Name"
126 IDS_STAT "Stat Headers"
127 IDS_STA_01 "Table_Catalog"
128 IDS_STA_02 "Table_Schema"
129 IDS_STA_03 "Table_Name"
130 IDS_STA_04 "Non_Unique"
131 IDS_STA_05 "Index_Qualifier"
132 IDS_STA_06 "Index_Name"
133 IDS_STA_07 "Type"
134 IDS_STA_08 "Seq_in_Index"
135 IDS_STA_09 "Column_Name"
136 IDS_STA_10 "Collation"
137 IDS_STA_11 "Cardinality"
138 IDS_STA_12 "Pages"
139 IDS_STA_13 "Filter_Condition"
140 IDS_DRIVER "Driver Headers"
141 IDS_DRV_01 "Description"
142 IDS_DRV_02 "Attributes"
143 IDS_DSRC "DataSrc Headers"
144 IDS_DSC_01 "Name"
145 IDS_DSC_02 "Description"
200 ACCESS_VIOLATN "Access violation"
201 ADD_BAD_TYPE "Array add value type mismatch (%s -> %s)"
202 ALLOC_ERROR "Error allocating %s"
203 ANSWER_TYPE "Answer of type"
204 API_CONF_ERROR "SQL Error: API_CONFORMANCE"
205 APPL_NOT_INIT "Application not initialized"
206 ARRAY_BNDS_EXCD "Array bounds exceeded"
207 BAD_ARRAY_OPER "Arrays must be used with the IN operator"
208 BAD_ARRAY_TYPE "Illegal array type %d"
209 BAD_ARRAY_VAL "Arrays must have the same number of values"
210 BAD_BIN_FMT "Invalid format %c for the %s BIN column"
211 BAD_BLK_ESTIM "Number of blocks exceeds estimate"
212 BAD_BLK_SIZE "No match in block %d size"
213 BAD_BYTE_NUM "bad number of bytes written"
214 BAD_BYTE_READ "bad number of bytes read"
215 BAD_COL_TYPE "Invalid type %s for column %s"
216 BAD_COL_XPATH "Invalid Xpath in column %s for HTML table %s"
217 BAD_CONST_TYPE "Bad constant type=%d"
218 BAD_CONV_TYPE "Invalid convert type %d"
219 BAD_DATETIME "Invalid datetime value"
220 BAD_DBF_FILE "DBF file %s is corrupted"
221 BAD_DBF_REC "DBF file %s corrupted at record %d"
222 BAD_DBF_TYPE "Unsupported DBF type %c for column %s"
223 BAD_DIRECTORY "Bad directory %s: %s"
224 BAD_FIELD_RANK "Invalid field rank %d for column %s"
225 BAD_FIELD_TYPE "Bad type field %s"
226 BAD_FILE_HANDLE "Invalid File Handle: %s"
227 BAD_FILTER "Bad filter: Opc=%d B_T=%d %d Type=%d %d"
228 BAD_FILTER_CONV "Bad filter conversion, B_T=%d,%d"
229 BAD_FILTER_OP "Invalid filter operator %d"
230 BAD_FLD_FORMAT "Bad format for field %d of %s"
231 BAD_FLD_LENGTH "Field %s too long (%s --> %d) line %d of %s"
232 BAD_FREQ_SET "Bad frequency setting for column %s"
233 BAD_FUNC_MODE "%s: invalid mode %d"
234 BAD_HANDLE_VAL "Invalid handle value"
235 BAD_HEADER "File %s: Header corrupted"
236 BAD_HEAD_END "Can't read end of header"
237 BAD_INDEX_FILE "Wrong index file %s"
238 BAD_LINEFLD_FMT "Bad format line %d field %d of %s"
239 BAD_LINE_LEN "Line length not equal to Lrecl"
240 BAD_LRECL "Table/File lrecl mismatch (%d,%hd)"
241 BAD_NODE_TYPE "Bad type %d for table node"
242 BAD_OFFSET_VAL "Invalid null offset value for a CSV table"
243 BAD_OPEN_MODE "Invalid open mode %d"
244 BAD_PARAM_TYPE "%.8s: Bad parameter type=%d"
245 BAD_PARM_COUNT "Parameter count mismatch"
246 BAD_QUOTE_FIELD "Missing ending quote in %s field %d line %d"
247 BAD_READ_NUMBER "Wrong number %d of values read from %s"
248 BAD_RECFM "Invalid recfm type %d for DOSCOL"
249 BAD_RECFM_VAL "Bad Recfm value %d"
250 BAD_SET_CASE "Cannot set sensitive an insensitive array"
251 BAD_SET_STRING "Invalid SetValue from string"
252 BAD_SPECIAL_COL "Bad special column %s"
253 BAD_SPEC_COLUMN "Special column invalid for this table type"
254 BAD_TABLE_TYPE "Bad type %s for table %s"
255 BAD_TYPE_LIKE "Bad operand(%d) type=%d for LIKE"
256 BAD_VALBLK_INDX "Out of range valblock index value"
257 BAD_VALBLK_TYPE "Invalid value block type %d"
258 BAD_VALNODE "Bad type %d for column %s value node"
259 BAD_VALUE_TYPE "Invalid value type %d"
260 BAD_VAL_UPDATE "Don't know which %s value to update"
261 BAS_NS_LIST "Invalid namespaces list format"
262 BIN_F_TOO_LONG "Value too long for field %s (%d --> %d)"
263 BIN_MODE_FAIL "Set binary mode failed: %s"
264 BLKTYPLEN_MISM "Non matching block types/lengths in SetValue"
265 BLK_IS_NULL "Blk is NULL"
266 BREAKPOINT "Breakpoint"
267 BUILD_INDEX "Building index %s on %s"
268 CANNOT_OPEN "Cannot open %s"
269 CHSIZE_ERROR "chsize error: %s"
270 COL_ALLOC_ERR "Cannot allocate column node"
271 COL_ISNOT_TABLE "Column %s is not in table %s"
272 COL_NOT_SORTED "Column %s of table %s is not sorted"
273 COL_NUM_MISM "Number of columns mismatch"
274 COM_ERROR "Com error"
275 CONCAT_SUBNODE "Cannot concatenate sub-nodes"
276 CONNECT_CANCEL "Connection cancelled by user"
277 CONTROL_C_EXIT "Control C exit"
278 DATABASE_LOADED "Database %s loaded"
279 DATA_MISALIGN "Datatype misalignment"
280 DBASE_FILE "dBASE dbf file: "
281 DEF_ALLOC_ERROR "Error allocating %s DEF class"
282 DEL_FILE_ERR "Error deleting %s"
283 DEL_READ_ERROR "Delete: read error req=%d len=%d"
284 DEL_WRITE_ERROR "Delete: write error: %s"
285 DEPREC_FLAG "Deprecated option Flag, use Coltype"
286 DLL_LOAD_ERROR "Error %d loading module %s"
287 DOM_NOT_SUPP "MS-DOM not supported by this version"
288 DVAL_NOTIN_LIST "Value %s not found in distinct values list of column %s"
289 EMPTY_DOC "Empty document"
290 EMPTY_FILE "%s empty file %s: "
291 EOF_AFTER_LINE "EOF after line %d"
292 EOF_INDEX_FILE "EOF while reading index file"
293 ERROR_IN_LSK "Error %d in lseek64"
294 ERROR_IN_SFP "Error %d in SetFilePointer"
295 ERR_READING_REC "Error reading record %d of %s"
296 FAIL_ADD_NODE "Failed to add %s table node"
297 FETCH_NO_RES "Fetch: No Result Set"
298 FIELD_TOO_LONG "Value too long for field %d line %d"
299 FILELEN_ERROR "Error in %s for %s"
300 FILE_IS_EMPTY "File %s is empty"
301 FILE_MAP_ERR "File mapping error"
302 FILE_MAP_ERROR "CreateFileMapping %s error rc=%d"
303 FILE_OPEN_YET "File %s already open"
304 FILE_UNFOUND "File %s not found"
305 FLD_TOO_LNG_FOR "Field %d too long for %s line %d of %s"
306 FLT_BAD_RESULT "Float inexact result"
307 FLT_DENORMAL_OP "Float denormal operand"
308 FLT_INVALID_OP "Float invalid operation"
309 FLT_OVERFLOW "Float overflow"
310 FLT_STACK_CHECK "Float stack check"
311 FLT_UNDERFLOW "Float underflow"
312 FLT_ZERO_DIVIDE "Float divide by zero"
313 FMT_WRITE_NIY "Writing %s files is not implemented yet"
314 FOXPRO_FILE "FoxPro file: "
315 FPUTS_ERROR "fputs error: %s"
316 FSEEK_ERROR "fseek error: %s"
317 FSETPOS_ERROR "fseek error for i=%d"
318 FTELL_ERROR "ftell error for recd=%d: %s"
319 FUNCTION_ERROR "%s error: %d"
320 FUNC_ERRNO "Error %d in %s"
321 FUNC_ERROR "Error in %s"
322 FUNC_ERR_S "%s error: %s"
323 FWRITE_ERROR "fwrite error: %s"
324 GET_DIST_VALS "Retrieving distinct values from "
325 GET_FUNC_ERR "Error getting function %s: %s"
326 GLOBAL_ERROR "Cannot allocate Global (size=%d)\n"
327 GUARD_PAGE "Guard page violation"
328 GZOPEN_ERROR "gzopen %s error %d on %s"
329 ILLEGAL_INSTR "Illegal instruction"
330 ILL_FILTER_CONV "Filtering implies an illegal conversion"
331 INDEX_NOT_UNIQ "Index is not unique"
332 INDEX_YET_ON "Index %s already exists on %s"
333 INDX_COL_NOTIN "Index column %s is not in table %s"
334 INDX_EXIST_YET "Index entry already exists"
335 INIT_FAILED "Failed to initialize %s processing"
336 INT_COL_ERROR "Internal error for index column %s"
337 INT_OVERFLOW "Integer overflow"
338 INT_ZERO_DIVIDE "Integer divide by zero"
339 INVALID_DISP "Invalid disposition"
340 INVALID_FTYPE "SBV: invalid Ftype %d"
341 INVALID_HANDLE "Invalid handle"
342 INVALID_OPER "Invalid operator %d for %s"
343 INV_COLUMN_TYPE "Invalid type %d for column %s"
344 INV_COL_TYPE "Invalid column type %s"
345 INV_DEF_READ "Invalid deferred Read rc=%d"
346 INV_DIRCOL_OFST "Invalid DIRCOL offset %d"
347 INV_MAP_POS "Invalid map position"
348 INV_RAND_ACC "Invalid random access to non optimized table"
349 INV_REC_POS "Invalid record position"
350 INV_RESULT_TYPE "Invalid result type %s"
351 INV_UPDT_TABLE "Table %s invalid for update"
352 IN_WITHOUT_SUB "IN or EXISTS without array or subquery"
353 KEY_ALLOC_ERR "Error allocating Key offset block"
354 KEY_ALLOC_ERROR "Memory allocation error, Klen=%d n=%d"
355 LINE_TOO_LONG "New line is too long"
356 LIST "--List--"
357 LOADING_FAILED "Loading of %s failed"
358 LRECL_TOO_SMALL "Lrecl too small (headlen = %d)"
359 MAKE_EMPTY_FILE "Making empty file %s: %s"
360 MAKING "Making"
361 MALLOC_ERROR "Memory allocation failed: %s returned Null"
362 MAP_VIEW_ERROR "MapViewOfFile %s error rc=%d"
363 MAXSIZE_ERROR "Cannot calculate max size on open table"
364 MEM_ALLOC_ERR "Memory allocation error, %s size=%d"
365 MEM_ALLOC_ERROR "Memory allocation error"
366 MISPLACED_QUOTE "Misplaced quote in line %d"
367 MISSING_ARG "Missing argument for operator %d"
368 MISSING_FIELD "Missing field %d in %s line %d"
369 MISSING_FNAME "Missing file name"
370 MISSING_NODE "Missing %s node in %s"
371 MISSING_ROWNODE "Can't find RowNode for row %d"
372 MIS_TAG_LIST "Missing column tag list"
373 MUL_MAKECOL_ERR "Tabmul MakeCol logical error"
374 NAME_CONV_ERR "Error converting node name"
375 NEW_DOC_FAILED "Cannot create new document"
376 NEW_RETURN_NULL "New returned Null in PlugEvalLike"
377 NEXT_FILE_ERROR "Couldn't find next file. rc=%d"
378 NONCONT_EXCEPT "Noncontinuable exception"
379 NOP_ZLIB_INDEX "Cannot do indexing on non optimized zlib table"
380 NOT_A_DBF_FILE "Not a dBASE dbf file "
381 NOT_FIXED_LEN "File %s is not fixed length, len=%d lrecl=%d"
382 NO_0DH_HEAD "No 0Dh at end of header (dbc=%d)"
383 NO_ACTIVE_DB "No active database"
384 NO_CHAR_FROM "Cannot return char value from type %d"
385 NO_DATE_FMT "No date format for valblock of type %d"
386 NO_DEF_FNCCOL "Cannot find default function column"
387 NO_DEF_PIVOTCOL "Cannot find default pivot column"
388 NO_DIR_INDX_RD "No direct access of %s tables"
389 NO_FEAT_SUPPORT "No %s support in this version"
390 NO_FLD_FORMAT "Missing format for field %d of %s"
391 NO_FORMAT_COL "Cannot format the type COLUMN"
392 NO_FORMAT_TYPE "Cannot set format from type %d"
393 NO_INDEX_READ "No indexed read for multiple tables"
394 NO_KEY_COL "No key columns found"
395 NO_KEY_UPDATE "Cannot update key names"
396 NO_MAP_INSERT "MAP incompatible with Insert"
397 NO_MATCHING_COL "No matching column %s in %s"
398 NO_MATCH_COL "Cannot find matching column"
399 NO_MEMORY "No memory"
400 NO_MODE_PADDED "Mode not supported for padded files"
401 NO_MUL_VCT "VCT tables cannot be multiple"
402 NO_ODBC_DELETE "Delete should not be called for ODBC tables"
403 NO_ODBC_DIRECT "Direct access of ODBC tables not implemented yet"
404 NO_ODBC_MUL "Multiple(2) not supported for ODBC tables"
405 NO_ODBC_SPECOL "No ODBC special columns"
406 NO_PART_DEL "No partial delete of %s files"
407 NO_PART_MAP "Partial mapping not implemented for this OS"
408 NO_PAR_BLK_INS "Cannot insert partial block yet"
409 NO_PIV_DIR_ACC "No direct access to PIVOT tables"
410 NO_READ_32 "Can't read 32 bytes"
411 NO_RECOV_SPACE "Cannot recover space in index file"
412 NO_ROWID_FOR_AM "Can't get RowID in direct access for tables of type %s"
413 NO_ROW_NODE "Row node name is not defined"
414 NO_SECTION_NAME "Missing section name"
415 NO_SEC_UPDATE "Cannot update section names"
416 NO_SETPOS_YET "%s SetPos not implemented yet"
417 NO_SPEC_COL "No MySQL special columns"
418 NO_SUB_VAL "No sub value for array of type %d"
419 NO_TABCOL_DATA "No data found for table %s column %s"
420 NO_TABLE_DEL "Delete not enabled for %s tables "
421 NO_TAB_DATA "No data found for table %s"
422 NO_VCT_DELETE "Partial delete not yet implemented for VCT files"
423 NO_ZIP_DELETE "Delete Zip files not implemented yet"
424 OPENING "Opening"
425 OPEN_EMPTY_FILE "Opening empty file %s: %s"
426 OPEN_ERROR "Open error %d in mode %d on %s: "
427 OPEN_ERROR_IS "Open error on %s: %s"
428 OPEN_MODE_ERROR "Open(%s) error %d on %s"
429 OPEN_STRERROR "open error: %s"
430 OPTBLK_RD_ERR "Error reading opt block values: %s"
431 OPTBLK_WR_ERR "Error writing opt block values: %s"
432 OPTIMIZING "Optimizing "
433 OPT_BMAP_RD_ERR "Error reading opt bitmaps: %s"
434 OPT_BMAP_WR_ERR "Error writing opt bitmaps: %s"
435 OPT_CANCELLED "Optimize cancelled by User"
436 OPT_DVAL_RD_ERR "Error reading distinct values: %s"
437 OPT_DVAL_WR_ERR "Error writing distinct values: %s"
438 OPT_HEAD_RD_ERR "Error reading opt file header: %s"
439 OPT_HEAD_WR_ERR "Error writing opt file header: %s"
440 OPT_LOGIC_ERR "Logical error in SetBitmap, i=%d"
441 OPT_MAX_RD_ERR "Error reading opt max values: %s"
442 OPT_MAX_WR_ERR "Error writing opt max values: %s"
443 OPT_MIN_RD_ERR "Error reading opt min values: %s"
444 OPT_MIN_WR_ERR "Error writing opt min values: %s"
445 OPT_NOT_MATCH "Non-matching opt file %s"
446 PAGE_ERROR "In page error"
447 PARM_CNT_MISS "Parameter count mismatch"
448 PREC_VBLP_NULL "ARRAY SetPrecision: Vblp is NULL"
449 PRIV_INSTR "Privileged instruction"
450 PROCADD_ERROR "Error %d getting address of %s"
451 QUERY_CANCELLED "Query Cancelled by User"
452 RANGE_NO_JOIN "Range is not meant for join index"
453 RC_READING "rc=%d reading table %s"
454 READY "Ready"
455 READ_ERROR "Error reading %s: %s"
456 READ_ONLY "Cannot modify this read/only protected table"
457 READ_SEEK_ERROR "Read seek error: %s"
458 REGISTER_ERR "Unable to register NS with prefix='%s' and href='%s'"
459 REMOVE_ERROR "Error removing %s: %s"
460 RENAME_ERROR "Error renaming %s to %s: %s"
461 ROWID_NOT_IMPL "RowNumber not implemented for tables of type %s"
462 SEC_KEY_FIRST "Section and key names must come first on Insert"
463 SEC_NAME_FIRST "Section name must come first on Insert"
464 SEP_IN_FIELD "Field %d contains the separator character"
465 SEQUENCE_ERROR "Sequence error on statement allocation"
466 SETEOF_ERROR "Error %d in SetEndOfFile"
467 SETRECPOS_NIY "SetRecpos not implemented for this table type"
468 SET_STR_TRUNC "SetValue: String would be truncated"
469 SFP_ERROR "SetFilePointer error: %s"
470 SHARED_LIB_ERR "Error loading shared library %s: %s"
471 SINGLE_STEP "Single step"
472 SORTING_VAL "Sorting %d values"
473 SPCOL_READONLY "Special column %s is Read Only"
474 SQL_CONF_ERROR "SQL Error: SQL_CONFORMANCE"
475 SRCH_CLOSE_ERR "Couldn't close search handle"
476 SRC_TABLE_UNDEF "Source table is not defined"
477 STACK_OVERFLOW "Stack overflow"
478 TABDIR_READONLY "DIR tables are read/only"
479 TABLE_NOT_OPT "Not an optimizable table"
480 TABLE_NO_INDEX "Table %s is not indexable"
481 TABLE_READ_ONLY "%s tables are read only "
482 TABMUL_READONLY "Multiple tables are read/only"
483 TOO_MANY_FIELDS "Too many fields line %d of %s"
484 TOO_MANY_JUMPS "Too many jump levels"
485 TOO_MANY_KEYS "Too many keys (%d)"
486 TO_BLK_IS_NULL "To Blk is NULL"
487 TRUNCATE_ERROR "truncate error: %s"
488 TRUNC_BY_ESTIM "truncated by Estimate"
489 TYPE_MISMATCH "Key and source are not of the same type"
490 TYPE_VALUE_ERR "Column %s type(%s)/value(%s) mismatch"
491 UNBALANCE_QUOTE "Unbalanced quote in line %d"
492 UNDEFINED_AM "COLBLK %s: undefined Access Method"
493 UNKNOWN_EXCPT "Unknown exception"
494 UNMATCH_FIL_ARG "Unmatched filter argument"
495 UPDATE_ERROR "Error updating %s"
496 UPD_ZIP_NOT_IMP "Updating ZDOS tables not implemented yet"
497 VALSTR_TOO_LONG "Value %s too long for string of length %d"
498 VALTYPE_NOMATCH "Non matching Value types"
499 VALUE_ERROR "Column %s: value is null"
500 VALUE_TOO_BIG "Value %lld too big for column %s"
501 VALUE_TOO_LONG "Value %s too long for column %s of length %d"
502 VAL_ALLOC_ERR "Cannot allocate value node"
503 VIR_NO_DELETE "Delete not allowed for %s tables"
504 VIR_READ_ONLY "Virtual %s tables are read only"
505 VOID_FIRST_ARG "First argument should not be void"
506 WORK_AREA "Work area: %s"
507 WRITE_SEEK_ERR "Write seek error: %s"
508 WRITE_STRERROR "Error writing %s: %s"
509 WRITING "Writing"
510 WRITING_ERROR "Error writing to %s: %s"
511 WS_CONV_ERR "Error converting %s to WS"
512 XCOL_MISMATCH "Column %s mismatch in index"
513 XFILE_READERR "Error %d reading index file"
514 XFILE_WRITERR "Error writing index file: %s"
515 XMLTAB_INIT_ERR "Error initializing XML table"
516 XML_INIT_ERROR "Error initializing new XML file"
517 XPATH_CNTX_ERR "Unable to create new XPath context"
518 XPATH_EVAL_ERR "Unable to evaluate xpath location '%s'"
519 XPATH_NOT_SUPP "Unsupported Xpath for column %s"

View File

@@ -1,366 +0,0 @@
100 IDS_TABLES "Table Ent<6E>tes"
101 IDS_TAB_01 "Catalogue"
102 IDS_TAB_02 "Sch<63>ma"
103 IDS_TAB_03 "Nom"
104 IDS_TAB_04 "Type"
105 IDS_TAB_05 "Remarque"
106 IDS_COLUMNS "Colonne Ent<6E>tes"
107 IDS_COL_01 "Cat_Table"
108 IDS_COL_02 "Schem_Table"
109 IDS_COL_03 "Nom_Table"
110 IDS_COL_04 "Nom_Colonne"
111 IDS_COL_05 "Type_Donn<6E>es"
112 IDS_COL_06 "Nom_Type"
113 IDS_COL_07 "Pr<50>cision"
114 IDS_COL_08 "Longueur"
115 IDS_COL_09 "Echelle"
116 IDS_COL_10 "Base"
117 IDS_COL_11 "Nullifiable"
118 IDS_COL_12 "Remarques"
119 IDS_PKEY "Cl<43> Ent<6E>tes"
120 IDS_PKY_01 "Cat_Table"
121 IDS_PKY_02 "Schem_Table"
122 IDS_PKY_03 "Nom_Table"
123 IDS_PKY_04 "Nom_Colonne"
124 IDS_PKY_05 "Num<75>ro_Cl<43>"
125 IDS_PKY_06 "Nom_Cl<43>"
126 IDS_STAT "Stat Ent<6E>tes"
127 IDS_STA_01 "Table_Catalog"
128 IDS_STA_02 "Table_Schema"
129 IDS_STA_03 "Table_Name"
130 IDS_STA_04 "Non_Unique"
131 IDS_STA_05 "Index_Qualifier"
132 IDS_STA_06 "Index_Name"
133 IDS_STA_07 "Type"
134 IDS_STA_08 "Seq_in_Index"
135 IDS_STA_09 "Column_Name"
136 IDS_STA_10 "Collation"
137 IDS_STA_11 "Cardinality"
138 IDS_STA_12 "Pages"
139 IDS_STA_13 "Filter_Condition"
140 IDS_DRIVER "Driver Ent<6E>tes"
141 IDS_DRV_01 "Description"
142 IDS_DRV_02 "Attributs"
143 IDS_DSRC "DataSrc Ent<6E>tes"
144 IDS_DSC_01 "Nom"
145 IDS_DSC_02 "Description"
200 ACCESS_VIOLATN "Violation acc<63>s m<>moire"
201 ADD_BAD_TYPE "Ajout d'une valeur de type %s non conforme dans un tableau %s"
202 ALLOC_ERROR "Erreur d'allocation de %s"
203 ANSWER_TYPE "R<>ponse de type"
204 API_CONF_ERROR "Erreur SQL: API_CONFORMANCE"
205 APPL_NOT_INIT "Application non initialis<69>e"
206 ARRAY_BNDS_EXCD "Hors limite de tableau"
207 BAD_ARRAY_OPER "Les tableaux doivent utiliser l'op<6F>rateur IN"
208 BAD_ARRAY_TYPE "Type=%d invalide pour un tableau"
209 BAD_ARRAY_VAL "Les tableaux doivent avoir le m<>me nombre de valeurs"
210 BAD_BIN_FMT "Format invalide %c pour la colonne BIN %s"
211 BAD_BLK_ESTIM "Nombre de blocs sup<75>rieur <20> l'estimation"
212 BAD_BLK_SIZE "Taille du bloc %d non conforme"
213 BAD_BYTE_NUM "Le nombre d'octets <20>crits est faux"
214 BAD_BYTE_READ "Le nombre d'octets lus est faux"
215 BAD_COL_TYPE "Type invalide %s pour la colonne %s"
216 BAD_COL_XPATH "Xpath invalide colonne %s de la table HTML %s"
217 BAD_CONST_TYPE "Type=%d invalide pour une constante"
218 BAD_CONV_TYPE "Convertion de type invalide %d"
219 BAD_DATETIME "Valeur date/temps invalide"
220 BAD_DBF_FILE "Le fichier DBF %s est alt<6C>r<EFBFBD>"
221 BAD_DBF_REC "Fichier DBF %s alt<6C>r<EFBFBD> enregistrement %d"
222 BAD_DBF_TYPE "Type DBF %c non support<72> colonne %s"
223 BAD_DIRECTORY "R<>pertoire invalide %s: %s"
224 BAD_FIELD_RANK "Rang %d invalide pour la colonne %s"
225 BAD_FIELD_TYPE "Mauvais type de champ %s"
226 BAD_FILE_HANDLE "Handle de fichier invalide: %s"
227 BAD_FILTER "Mauvais filtre: Opc=%d B_T=%d %d Type=%d %d"
228 BAD_FILTER_CONV "Conversion filtre incorrecte, B_T=%d,%d"
229 BAD_FILTER_OP "Op<4F>rateur de filtre invalide %d"
230 BAD_FLD_FORMAT "Format invalide pour le champs %d de %s"
231 BAD_FLD_LENGTH "Champs %s trop long (%s --> %d) ligne %d de %s"
232 BAD_FREQ_SET "Sp<53>cification erronn<6E>e de Freq pour la colonne %s"
233 BAD_FUNC_MODE "%s: mode invalide %d"
234 BAD_HANDLE_VAL "Valeur Handle invalide"
235 BAD_HEADER "Fichier %s: bloc en-t<>te alt<6C>r<EFBFBD>"
236 BAD_HEAD_END "Lecture fin d'en-t<>te impossible"
237 BAD_INDEX_FILE "Fichier index %s corrompu"
238 BAD_LINEFLD_FMT "Format invalide ligne %d champs %d de %s"
239 BAD_LINE_LEN "Longueur ligne non <20>gale <20> Lrecl"
240 BAD_LRECL "Disparit<69> lrecl table/fichier (%d,%hd)"
241 BAD_NODE_TYPE "Type noeud erron<6F> pour la table"
242 BAD_OFFSET_VAL "Nul offset invalide pour une table CSV"
243 BAD_OPEN_MODE "Mode d'ouverture invalide %d"
244 BAD_PARAM_TYPE "%.8s: Param<61>tre de type=%d invalide"
245 BAD_PARM_COUNT "Nombre de param<61>tres incoh<6F>rent"
246 BAD_QUOTE_FIELD "Quote manquante dans %s champs %d ligne %d"
247 BAD_READ_NUMBER "Mauvais nombre %d de valeurs lues dans %s"
248 BAD_RECFM "Recfm type %d invalide pour DOSCOL"
249 BAD_RECFM_VAL "Valeur invalide %d de Recfm"
250 BAD_SET_CASE "La casse d'un tableau ne peut pas passer de non respect <20> respecter"
251 BAD_SET_STRING "SetValue: appel invalide pour STRING"
252 BAD_SPECIAL_COL "Colonne sp<73>ciale invalide %s"
253 BAD_SPEC_COLUMN "Colonne sp<73>ciale invalide pour ce type de table"
254 BAD_TABLE_TYPE "Type invalide %s pour la table %s"
255 BAD_TYPE_LIKE "Type(%d)= %d invalide pour LIKE"
256 BAD_VALBLK_INDX "Valeur hors limites de l'index du bloc de valeurs"
257 BAD_VALBLK_TYPE "Type=%d invalide pour un bloc de valeurs"
258 BAD_VALNODE "Type %d invalide pour le noeud valeur colonne %s"
259 BAD_VALUE_TYPE "Type de valeur invalide %d"
260 BAD_VAL_UPDATE "Impossible de d<>terminer quelle valeur %s doit <20>tre mise <20> jour"
261 BAS_NS_LIST "Format invalide de la liste des espace-noms"
262 BIN_F_TOO_LONG "Valeur trop longue pour le champ %s (%d --> %d)"
263 BIN_MODE_FAIL "Echec mode binaire: %s"
264 BLKTYPLEN_MISM "Disparit<69> types/longueurs de bloc dans SetValue"
265 BLK_IS_NULL "Blk est nul"
266 BREAKPOINT "Point de contr<74>le"
267 BUILD_INDEX "Construction index %s sur %s"
268 CANNOT_OPEN "Ouverture impossible de %s"
269 CHSIZE_ERROR "Erreur dans chsize: %s"
270 COL_ALLOC_ERR "Allocation impossible du noeud colonne"
271 COL_ISNOT_TABLE "La colonne %s n'est pas dans la table %s"
272 COL_NOT_SORTED "La colonne %s de la table %s n'est pas tri<72>e"
273 COL_NUM_MISM "Disparit<69> du nombre de colonnes"
274 COM_ERROR "Erreur Com"
275 CONCAT_SUBNODE "Concat<61>nation de sous-noeuds impossible"
276 CONNECT_CANCEL "Connection interrompue par l'utilisateur"
277 CONTROL_C_EXIT "Exit par Ctrl-C"
278 DATABASE_LOADED "Base de donn<6E>es %s charg<72>e"
279 DATA_MISALIGN "Mauvais alignement pour ce type de donn<6E>es"
280 DBASE_FILE "Fichier dBASE dbf: "
281 DEF_ALLOC_ERROR "Erreur d'allocation de la classe DEF %s"
282 DEL_FILE_ERR "Erreur <20> l'effacement de %s"
283 DEL_READ_ERROR "Delete: erreur en lecture req=%d len=%d"
284 DEL_WRITE_ERROR "Delete: erreur en <20>criture: %s"
285 DEPREC_FLAG "Option Flag p<>rim<69>e, utiliser Coltype"
286 DLL_LOAD_ERROR "Erreur %d au chargement du module %s"
287 DOM_NOT_SUPP "MS-DOM non support<72> par cette version"
288 DVAL_NOTIN_LIST "Valeur %s non trouv<75>e dans la liste des valeurs distinctes de la colonne %s"
289 EMPTY_DOC "Document vide"
290 EMPTY_FILE "%s du fichier vide %s: "
291 EOF_AFTER_LINE "Fin de fichier apr<70>s la ligne %d"
292 EOF_INDEX_FILE "EOF lisant le fichier index"
293 ERROR_IN_LSK "Erreur %d dans lseek64"
294 ERROR_IN_SFP "Erreur %d dans SetFilePointer"
295 ERR_READING_REC "Erreur lisant l'enregistrement %d de %s"
296 FAIL_ADD_NODE "L'ajout du noeud %s dans la table a <20>chou<6F>"
297 FETCH_NO_RES "Fetch: Pas de R<>sultats"
298 FIELD_TOO_LONG "Valeur trop longue pour le champs %d ligne %d"
299 FILELEN_ERROR "Erreur dans %s pour %s"
300 FILE_IS_EMPTY "Le fichier %s est vide"
301 FILE_MAP_ERR "Erreur de File mapping"
302 FILE_MAP_ERROR "CreateFileMapping %s erreur rc=%d"
303 FILE_OPEN_YET "Fichier %s d<>j<EFBFBD> ouvert"
304 FILE_UNFOUND "Fichier %s non trouv<75>"
305 FLD_TOO_LNG_FOR "Champs %d trop long pour %s ligne %d de %s"
306 FLT_BAD_RESULT "Virgule flottante: r<>sultat inexacte"
307 FLT_DENORMAL_OP "Op<4F>rande virgule flottante non normalis<69>"
308 FLT_INVALID_OP "Op<4F>ration virgule flottante invalide"
309 FLT_OVERFLOW "D<>passement de capacit<69> virgule flottante"
310 FLT_STACK_CHECK "Virgule flottante: Erreur de la pile"
311 FLT_UNDERFLOW "Sous-d<>passement de capacit<69> virgule flottante"
312 FLT_ZERO_DIVIDE "Virgule flottante: division par z<>ro"
313 FMT_WRITE_NIY "L'<27>criture des fichiers %s n'est pas encore impl<70>ment<6E>e"
314 FOXPRO_FILE "Fichier FoxPro: "
315 FPUTS_ERROR "Erreur dans fputs: %s"
316 FSEEK_ERROR "Erreur dans fseek: %s"
317 FSETPOS_ERROR "Erreur dans fseek pour i=%d"
318 FTELL_ERROR "Erreur dans ftell enregistrement=%d: %s"
319 FUNCTION_ERROR "Erreur dans %s: %d"
320 FUNC_ERRNO "Erreur %d dans %s"
321 FUNC_ERROR "Erreur dans %s"
322 FUNC_ERR_S "Erreur dans %s: %s"
323 FWRITE_ERROR "Erreur dans fwrite: %s"
324 GET_DIST_VALS "R<>cup<75>ration des valeurs distinctes de "
325 GET_FUNC_ERR "Erreur en recherche de la fonction %s: %s"
326 GLOBAL_ERROR "Erreur d'allocation de Global (taille=%d)\n"
327 GUARD_PAGE "Violation de page de garde"
328 GZOPEN_ERROR "gzopen %s: erreur %d sur %s"
329 ILLEGAL_INSTR "Instruction ill<6C>gale"
330 ILL_FILTER_CONV "Conversion implicite ill<6C>gale dans un filtre"
331 INDEX_NOT_UNIQ "L'index n'est pas Unique"
332 INDEX_YET_ON "L'index %s existe d<>j<EFBFBD> sur %s"
333 INDX_COL_NOTIN "La colonne index %s n'existe pas dans la table %s"
334 INDX_EXIST_YET "L'entr<74>e index existe d<>j<EFBFBD>"
335 INIT_FAILED "L'initialisation de %s a <20>chou<6F>"
336 INT_COL_ERROR "Erreur interne sur la colonne index %s"
337 INT_OVERFLOW "D<>passement de capacit<69> sur entier"
338 INT_ZERO_DIVIDE "Division enti<74>re par z<>ro"
339 INVALID_DISP "Disposition invalide"
340 INVALID_FTYPE "SBV: Ftype %d invalide"
341 INVALID_HANDLE "Poign<67>e invalide"
342 INVALID_OPER "Op<4F>rateur invalide %d pour %s"
343 INV_COLUMN_TYPE "Type %d Invalide pour la colonne %s"
344 INV_COL_TYPE "Type de colonne %s invalide"
345 INV_DEF_READ "Lecture diff<66>r<EFBFBD>e invalide rc=%d"
346 INV_DIRCOL_OFST "Offset invalide pour une colonne DIR"
347 INV_MAP_POS "Position m<>moire invalide"
348 INV_RAND_ACC "L'acc<63>s al<61>atoire d'une table non optimis<69>e est impossible"
349 INV_REC_POS "Position d'enregistrement invalide"
350 INV_RESULT_TYPE "Type de r<>sultat invalide %s"
351 INV_UPDT_TABLE "Table %s invalide pour Update"
352 IN_WITHOUT_SUB "IN ou EXISTS sans tableau ou subquery"
353 KEY_ALLOC_ERR "Erreur d'allocation d'un bloc offset cl<63>"
354 KEY_ALLOC_ERROR "Erreur d'allocation m<>moire, Klen=%d n=%d"
355 LINE_TOO_LONG "La nouvelle ligne est trop longue"
356 LIST "--Liste--"
357 LOADING_FAILED "Le chargement de %s a <20>chou<6F>"
358 LRECL_TOO_SMALL "Lrecl trop petit (longueur en-t<>te = %d)"
359 MAKE_EMPTY_FILE "G<>n<EFBFBD>ration du fichier vide %s: %s"
360 MAKING "G<>n<EFBFBD>ration"
361 MALLOC_ERROR "Allocation m<>moire impossible par %s"
362 MAP_VIEW_ERROR "MapViewOfFile %s erreur rc=%d"
363 MAXSIZE_ERROR "Maxsize incalculable sur table ouverte"
364 MEM_ALLOC_ERR "Erreur d'allocation m<>moire, taille %s = %d"
365 MEM_ALLOC_ERROR "Erreur d'allocation m<>moire"
366 MISPLACED_QUOTE "Appostrophe mal plac<61>e ligne %d"
367 MISSING_ARG "Argument manquant pour l'op<6F>rateur %d"
368 MISSING_FIELD "Champs %d manquant dans %s ligne %d"
369 MISSING_FNAME "Nom du fichier manquant"
370 MISSING_NODE "Noeud %s manquant dans %s"
371 MISSING_ROWNODE "Impossible de trouver le noeud de la ligne %d"
372 MIS_TAG_LIST "Liste des balises colonne manquante"
373 MUL_MAKECOL_ERR "Erreur logique dans TABMUL::MakeCol"
374 NAME_CONV_ERR "Erreur de convertion du nom de noeud"
375 NEW_DOC_FAILED "Impossible de cr<63>er le nouveau document"
376 NEW_RETURN_NULL "NULL renvoy<6F> par New dans PlugEvalLike"
377 NEXT_FILE_ERROR "Erreur en recherche du fichier suivant. rc=%s"
378 NONCONT_EXCEPT "Exception non-continuable"
379 NOP_ZLIB_INDEX "L'indexage d'une table zlib non optimis<69>e est impossible"
380 NOT_A_DBF_FILE "Le fichier n'a pas le format dBASE dbf "
381 NOT_FIXED_LEN "Fichier %s non fixe, len=%d lrecl=%d"
382 NO_0DH_HEAD "0DH manquant en fin d'en-t<>te (dbc=%d)"
383 NO_ACTIVE_DB "Pas de base de donn<6E>es active"
384 NO_CHAR_FROM "Conversion de type %d en caract<63>res impossible"
385 NO_DATE_FMT "Pas de format date pour le valblock de type %d"
386 NO_DEF_FNCCOL "Colonne fonction par d<>faut introuvable"
387 NO_DEF_PIVOTCOL "Colonne pivot par d<>faut introuvable"
388 NO_DIR_INDX_RD "Pas d'acc<63>s directe des tables %s"
389 NO_FEAT_SUPPORT "%s non support<72> dans cette version"
390 NO_FLD_FORMAT "Format absent pour le champs %d de %s"
391 NO_FORMAT_COL "Type COLUMN informattable"
392 NO_FORMAT_TYPE "Le format ne peut pas <20>tre d<>fini <20> partir du type %d"
393 NO_INDEX_READ "Pas d'acc<63>s directe des tables multiples"
394 NO_KEY_COL "Pas de colonne cl<63> trouv<75>e"
395 NO_KEY_UPDATE "Le nom des cl<63>s ne peut pas <20>tre modifi<66>"
396 NO_MAP_INSERT "MAP incompatible avec Insert"
397 NO_MATCHING_COL "Pas de colonne correspondant <20> %s dans %s"
398 NO_MATCH_COL "Colonne correspondante introuvable"
399 NO_MEMORY "M<>moire pleine"
400 NO_MODE_PADDED "Mode non support<72> pour les fichiers 'padded'"
401 NO_MUL_VCT "Les tables VCT ne peuvent pas <20>tre multiples"
402 NO_ODBC_DELETE "Delete ne devrait pas <20>tre appel<65> pour les tables ODBC"
403 NO_ODBC_DIRECT "Acc<63>s directe des tables ODBC non encore impl<70>ment<6E>"
404 NO_ODBC_MUL "Multiple(2) non support<72> pour les tables ODBC"
405 NO_ODBC_SPECOL "Pas de colonne sp<73>ciale ODBC"
406 NO_PART_DEL "Delete partiel des fichier %s impossible"
407 NO_PART_MAP "Mapping partiel non impl<70>ment<6E> pour cet OS"
408 NO_PAR_BLK_INS "Insertion de bloc partiel impossible"
409 NO_PIV_DIR_ACC "Pas d'acc<63>s directe aux tables PIVOT"
410 NO_READ_32 "Lecture de 32 octets impossible"
411 NO_RECOV_SPACE "Espace non recouvrable dans le fichier index"
412 NO_ROWID_FOR_AM "Acc<63>s direct impossible de ROWID pour les tables de type %s"
413 NO_ROW_NODE "Le nom du Rownode n'est pas d<>fini"
414 NO_SECTION_NAME "Nom de section manquant"
415 NO_SEC_UPDATE "Les noms de section ne peuvent pas <20>tre modifi<66>s"
416 NO_SETPOS_YET "SetPos pas encore impl<70>ment<6E> pour les fichier %s"
417 NO_SPEC_COL "Pas de colonne sp<73>ciales MYSQL"
418 NO_SUB_VAL "Pas de sous-value d'un tableau de type %d"
419 NO_TABCOL_DATA "Pas de donn<6E>es pour la table %s colonne %s"
420 NO_TABLE_DEL "Delete non autoris<69> pour les tables %s "
421 NO_TAB_DATA "Pas de donn<6E>es pour la table %s"
422 NO_VCT_DELETE "D<>l<EFBFBD>tion Partielle non impl<70>ment<6E>e pour les fichiers VCT"
423 NO_ZIP_DELETE "Delete sur fichier Zip non encore implement<6E>"
424 OPENING "Ouverture"
425 OPEN_EMPTY_FILE "Ouverture du fichier vide %s: %s"
426 OPEN_ERROR "Erreur d'ouverture %d en mode %d sur %s: "
427 OPEN_ERROR_IS "Erreur <20> l'ouverture de %s: %s"
428 OPEN_MODE_ERROR "Erreur d'ouverture(%s) %d sur %s"
429 OPEN_STRERROR "Erreur <20> l'ouverture: %s"
430 OPTBLK_RD_ERR "Erreur <20> la lecture d'un bloc optimisation: %s"
431 OPTBLK_WR_ERR "Erreur <20> l'<27>criture d'un bloc optimisation: %s"
432 OPTIMIZING "Optimisation de "
433 OPT_BMAP_RD_ERR "Erreur en lecture des bitmaps d'optimisation: %s"
434 OPT_BMAP_WR_ERR "Erreur en <20>criture des bitmaps d'optimisation: %s"
435 OPT_CANCELLED "Optimisation interrompue par l'utilisateur"
436 OPT_DVAL_RD_ERR "Erreur en lecture des valeurs distinctes: %s"
437 OPT_DVAL_WR_ERR "Erreur en <20>criture des valeurs distinctes: %s"
438 OPT_HEAD_RD_ERR "Erreur en lecture de l'ent<6E>te du fichier opt: %s"
439 OPT_HEAD_WR_ERR "Erreur en <20>criture de l'ent<6E>te du fichier opt: %s"
440 OPT_LOGIC_ERR "Erreur logique dans SetBitmap, i=%d"
441 OPT_MAX_RD_ERR "Erreur en lecture des valeurs maxi: %s"
442 OPT_MAX_WR_ERR "Erreur en <20>criture des valeurs maxi: %s"
443 OPT_MIN_RD_ERR "Erreur en lecture des valeurs mini: %s"
444 OPT_MIN_WR_ERR "Erreur en <20>criture des valeurs mini: %s"
445 OPT_NOT_MATCH "Le fichier opt %s n'est pas <20> jour"
446 PAGE_ERROR "Erreur de pagination"
447 PARM_CNT_MISS "Disparit<69> du nombre de Param<61>tres"
448 PREC_VBLP_NULL "ARRAY SetPrecision: Vblp est NULL"
449 PRIV_INSTR "Instruction privil<69>gi<67>e"
450 PROCADD_ERROR "Erreur %d sur l'adresse de %s"
451 QUERY_CANCELLED "Requ<71>te interrompue par l'utilisateur"
452 RANGE_NO_JOIN "Range non compatible avec les index de jointure"
453 RC_READING "rc=%d en lecture de la table %s"
454 READY "Pr<50>t"
455 READ_ERROR "Erreur en lecture sur %s: %s"
456 READ_ONLY "Cette table prot<6F>g<EFBFBD>e en lecture seule ne peut <20>tre modifi<66>e"
457 READ_SEEK_ERROR "Erreur de recherche en lecture: %s"
458 REGISTER_ERR "Enregistrement NS impossible, pr<70>fix='%s' et href='%s'"
459 REMOVE_ERROR "Erreur en supprimant %s: %s"
460 RENAME_ERROR "Erreur renommant %s en %s: %s"
461 ROWID_NOT_IMPL "RowNumber non impl<70>ment<6E> pour les tables de type %s"
462 SEC_KEY_FIRST "Les sections et cl<63>s doivent <20>tre ins<6E>r<EFBFBD>es en premier"
463 SEC_NAME_FIRST "Le nom de section doit <20>tre en t<>te de liste en insertion"
464 SEP_IN_FIELD "Le champ %d contient le caract<63>re s<>parateur"
465 SEQUENCE_ERROR "HSTMT: Allocation hors s<>quence"
466 SETEOF_ERROR "Erreur %d dans SetEndOfFile"
467 SETRECPOS_NIY "SetRecpos non impl<70>ment<6E> pour ce type de table"
468 SET_STR_TRUNC "SetValue: Cha<68>ne de caract<63>res tronqu<71>e"
469 SFP_ERROR "Erreur sur SetFilePointer: %s"
470 SHARED_LIB_ERR "Erreur au chargement de la librairie partag<61>e %s: %s"
471 SINGLE_STEP "Pas <20> pas"
472 SORTING_VAL "Tri de %d valeurs"
473 SPCOL_READONLY "La colonne sp<73>ciale %s est en lecture seulement"
474 SQL_CONF_ERROR "Erreur SQL: SQL_CONFORMANCE"
475 SRCH_CLOSE_ERR "Erreur <20> la fermeture de l'Handle de recherche"
476 SRC_TABLE_UNDEF "La table source n'est pas d<>finie"
477 STACK_OVERFLOW "D<>passement de capacit<69> de la pile"
478 TABDIR_READONLY "Les tables DIR sont en lecture seulement"
479 TABLE_NOT_OPT "Table non optimisable"
480 TABLE_NO_INDEX "La table %s n'est pas indexable"
481 TABLE_READ_ONLY "Les tables %s sont en lecture seulement "
482 TABMUL_READONLY "Les tables multiples sont en lecture seulement"
483 TOO_MANY_FIELDS "Trop de champs ligne %d de %s"
484 TOO_MANY_JUMPS "Trop de niveaux de saut"
485 TOO_MANY_KEYS "Trop de cl<63>s (%d)"
486 TO_BLK_IS_NULL "To Blk est nul"
487 TRUNCATE_ERROR "Erreur en troncation: %s"
488 TRUNC_BY_ESTIM "Tronqu<71> par l'option Estimate"
489 TYPE_MISMATCH "Cl<43> et source ne sont pas du m<>me type"
490 TYPE_VALUE_ERR "Colonne %s: disparit<69> type(%s)/valeur(%s)"
491 UNBALANCE_QUOTE "Appostrophe en trop ligne %d"
492 UNDEFINED_AM "COLBLK %s: m<>thode d'acc<63>s ind<6E>finie"
493 UNKNOWN_EXCPT "Exception non r<>pertori<72>e"
494 UNMATCH_FIL_ARG "Argument de filtre d<>pareill<6C>"
495 UPDATE_ERROR "Erreur en Update sur %s"
496 UPD_ZIP_NOT_IMP "Mise <20> jour des tables ZDOS non encore implement<6E>"
497 VALSTR_TOO_LONG "Valeur %s trop longue pour une cha<68>ne de longueur %d"
498 VALTYPE_NOMATCH "Disparit<69> types de valeur"
499 VALUE_ERROR "Colonne %s: bloc valeur nul"
500 VALUE_TOO_BIG "Valeur %lld trop grande pour la colonne %s"
501 VALUE_TOO_LONG "Valeur %s trop longue pour la colonne %s de longueur %d"
502 VAL_ALLOC_ERR "Allocation impossible du noeud valeur"
503 VIR_NO_DELETE "Delete impossible sur les tables %s"
504 VIR_READ_ONLY "Les tables virtuelles %s sont en lecture seulement"
505 VOID_FIRST_ARG "Le premier argument ne doit pas <20>tre vide"
506 WORK_AREA "Espace de travail: %s"
507 WRITE_SEEK_ERR "Erreur de recherche en <20>criture: %s"
508 WRITE_STRERROR "Erreur en <20>criture sur %s: %s"
509 WRITING "Ecriture"
510 WRITING_ERROR "Erreur <20> l'<27>criture de %s: %s"
511 WS_CONV_ERR "Erreur de convertion de %s en WS"
512 XCOL_MISMATCH "La colonne %s ne correspond pas <20> l'index"
513 XFILE_READERR "Erreur %d en lisant le fichier index"
514 XFILE_WRITERR "Erreur en <20>crivant le fichier index: %s"
515 XMLTAB_INIT_ERR "Erreur d'initialisation de la table XML"
516 XML_INIT_ERROR "Erreur d'initialisation du nouveau fichier XML"
517 XPATH_CNTX_ERR "Le nouveau contexte XPath ne peut <20>tre cr<63><72>"
518 XPATH_EVAL_ERR "Impossible d'<27>valuer l'emplacement xpath '%s'"
519 XPATH_NOT_SUPP "Xpath non support<72> colonne %s"

View File

@@ -169,9 +169,9 @@
#define JSONMAX 10 // JSON Default max grp size #define JSONMAX 10 // JSON Default max grp size
extern "C" { extern "C" {
char version[]= "Version 1.03.0007 October 20, 2015"; char version[]= "Version 1.04.0003 October 25, 2015";
#if defined(__WIN__) #if defined(__WIN__)
char compver[]= "Version 1.03.0007 " __DATE__ " " __TIME__; char compver[]= "Version 1.04.0003 " __DATE__ " " __TIME__;
char slash= '\\'; char slash= '\\';
#else // !__WIN__ #else // !__WIN__
char slash= '/'; char slash= '/';
@@ -941,7 +941,7 @@ ulonglong ha_connect::table_flags() const
// HA_NULL_IN_KEY | not implemented yet // HA_NULL_IN_KEY | not implemented yet
// HA_FAST_KEY_READ | causes error when sorting (???) // HA_FAST_KEY_READ | causes error when sorting (???)
HA_NO_TRANSACTIONS | HA_DUPLICATE_KEY_NOT_IN_ORDER | HA_NO_TRANSACTIONS | HA_DUPLICATE_KEY_NOT_IN_ORDER |
HA_NO_BLOBS | HA_CAN_TABLE_CONDITION_PUSHDOWN; HA_NO_BLOBS | HA_MUST_USE_TABLE_CONDITION_PUSHDOWN;
ha_connect *hp= (ha_connect*)this; ha_connect *hp= (ha_connect*)this;
PTOS pos= hp->GetTableOptionStruct(); PTOS pos= hp->GetTableOptionStruct();
@@ -1095,7 +1095,7 @@ bool GetBooleanTableOption(PGLOBAL g, PTOS options, char *opname, bool bdef)
/****************************************************************************/ /****************************************************************************/
int GetIntegerTableOption(PGLOBAL g, PTOS options, char *opname, int idef) int GetIntegerTableOption(PGLOBAL g, PTOS options, char *opname, int idef)
{ {
longlong opval= NO_IVAL; ulonglong opval= NO_IVAL;
if (!options) if (!options)
return idef; return idef;
@@ -1134,10 +1134,10 @@ PTOS ha_connect::GetTableOptionStruct(TABLE_SHARE *s)
{ {
TABLE_SHARE *tsp= (tshp) ? tshp : (s) ? s : table_share; TABLE_SHARE *tsp= (tshp) ? tshp : (s) ? s : table_share;
return (tsp && (!tsp->db_plugin || return (tsp && (!tsp->db_plugin ||
!stricmp(plugin_name(tsp->db_plugin)->str, "connect") || !stricmp(plugin_name(tsp->db_plugin)->str, "connect") ||
!stricmp(plugin_name(tsp->db_plugin)->str, "partition"))) !stricmp(plugin_name(tsp->db_plugin)->str, "partition")))
? tsp->option_struct : NULL; ? tsp->option_struct : NULL;
} // end of GetTableOptionStruct } // end of GetTableOptionStruct
/****************************************************************************/ /****************************************************************************/
@@ -2191,99 +2191,159 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *)
/***********************************************************************/ /***********************************************************************/
int ha_connect::CheckRecord(PGLOBAL g, const uchar *, uchar *newbuf) int ha_connect::CheckRecord(PGLOBAL g, const uchar *, uchar *newbuf)
{ {
return ScanRecord(g, newbuf); return ScanRecord(g, newbuf);
} // end of dummy CheckRecord } // end of dummy CheckRecord
/***********************************************************************/
/* Return true if this field is used in current indexing. */
/***********************************************************************/
bool ha_connect::IsIndexed(Field *fp)
{
if (active_index < MAX_KEY) {
KEY_PART_INFO *kpart;
KEY *kfp= &table->key_info[active_index];
uint rem= kfp->user_defined_key_parts;
for (kpart= kfp->key_part; rem; rem--, kpart++)
if (kpart->field == fp)
return true;
} // endif active_index
return false;
} // end of IsIndexed
/***********************************************************************/ /***********************************************************************/
/* Return the where clause for remote indexed read. */ /* Return the where clause for remote indexed read. */
/***********************************************************************/ /***********************************************************************/
bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL op, char q, bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
const void *key, int klen) const key_range *kr)
{ {
const uchar *ptr; const uchar *ptr;
uint rem, len, stlen; //, prtlen; //uint i, rem, len, klen, stlen;
bool nq, oom, b= false; uint i, rem, len, stlen;
Field *fp; bool nq, both, oom= false;
KEY *kfp; OPVAL op;
KEY_PART_INFO *kpart; Field *fp;
const key_range *ranges[2];
my_bitmap_map *old_map;
KEY *kfp;
KEY_PART_INFO *kpart;
if (active_index == MAX_KEY) if (active_index == MAX_KEY)
return false; return false;
else if (!key) {
strcpy(g->Message, "MakeKeyWhere: No key");
return true;
} // endif key
oom= qry->Append(" WHERE ("); ranges[0]= kr;
kfp= &table->key_info[active_index]; ranges[1]= (end_range && !eq_range) ? &save_end_range : NULL;
rem= kfp->user_defined_key_parts,
len= klen,
ptr= (const uchar *)key;
for (kpart= kfp->key_part; rem; rem--, kpart++) { if (!ranges[0] && !ranges[1]) {
fp= kpart->field; strcpy(g->Message, "MakeKeyWhere: No key");
stlen= kpart->store_length; return true;
// prtlen= MY_MIN(stlen, len); } else
nq= fp->str_needs_quotes(); both= ranges[0] && ranges[1];
if (b) kfp= &table->key_info[active_index];
oom|= qry->Append(" AND "); old_map= dbug_tmp_use_all_columns(table, table->write_set);
else
b= true;
oom|= qry->Append(q); for (i = 0; i <= 1; i++) {
oom|= qry->Append((PSZ)fp->field_name); if (ranges[i] == NULL)
oom|= qry->Append(q); continue;
switch (op) { if (both && i > 0)
case OP_EQ: oom|= qry->Append(") AND (");
case OP_GT: else
case OP_GE: oom|= qry->Append(" WHERE (");
case OP_LT:
case OP_LE:
oom |= qry->Append((PSZ)GetValStr(op, false));
break;
default:
oom|= qry->Append(" ??? ");
} // endwitch op
if (nq) // klen= len= ranges[i]->length;
oom|= qry->Append('\''); len= ranges[i]->length;
rem= kfp->user_defined_key_parts;
ptr= ranges[i]->key;
if (kpart->key_part_flag & HA_VAR_LENGTH_PART) { for (kpart= kfp->key_part; rem; rem--, kpart++) {
String varchar; fp= kpart->field;
uint var_length= uint2korr(ptr); stlen= kpart->store_length;
nq= fp->str_needs_quotes();
varchar.set_quick((char*) ptr+HA_KEY_BLOB_LENGTH, if (kpart != kfp->key_part)
var_length, &my_charset_bin); oom|= qry->Append(" AND ");
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); if (q) {
oom|= qry->Append(res->ptr(), res->length()); oom|= qry->Append(q);
} // endif flag oom|= qry->Append((PSZ)fp->field_name);
oom|= qry->Append(q);
} else
oom|= qry->Append((PSZ)fp->field_name);
if (nq) switch (ranges[i]->flag) {
oom|= qry->Append('\''); case HA_READ_KEY_EXACT:
// op= (stlen >= len || !nq || fp->result_type() != STRING_RESULT)
// ? OP_EQ : OP_LIKE;
op= OP_EQ;
break;
case HA_READ_AFTER_KEY:
op= (stlen >= len) ? (!i ? OP_GT : OP_LE) : OP_GE;
break;
case HA_READ_KEY_OR_NEXT:
op= OP_GE;
break;
case HA_READ_BEFORE_KEY:
op= (stlen >= len) ? OP_LT : OP_LE;
break;
case HA_READ_KEY_OR_PREV:
op= OP_LE;
break;
default:
sprintf(g->Message, "cannot handle flag %d", ranges[i]->flag);
goto err;
} // endswitch flag
if (stlen >= len) oom|= qry->Append((PSZ)GetValStr(op, false));
break;
len-= stlen; if (nq)
oom|= qry->Append('\'');
/* For nullable columns, null-byte is already skipped before, that is if (kpart->key_part_flag & HA_VAR_LENGTH_PART) {
ptr was incremented by 1. Since store_length still counts null-byte, String varchar;
we need to subtract 1 from store_length. */ uint var_length= uint2korr(ptr);
ptr+= stlen - MY_TEST(kpart->null_bit);
} // endfor kpart varchar.set_quick((char*)ptr + HA_KEY_BLOB_LENGTH,
var_length, &my_charset_bin);
oom|= qry->Append(varchar.ptr(), varchar.length(), nq);
} else {
char strbuff[MAX_FIELD_WIDTH];
String str(strbuff, sizeof(strbuff), kpart->field->charset()), *res;
res= fp->val_str(&str, ptr);
oom|= qry->Append(res->ptr(), res->length(), nq);
} // endif flag
if (nq)
oom |= qry->Append('\'');
if (stlen >= len)
break;
len-= stlen;
/* For nullable columns, null-byte is already skipped before, that is
ptr was incremented by 1. Since store_length still counts null-byte,
we need to subtract 1 from store_length. */
ptr+= stlen - MY_TEST(kpart->null_bit);
} // endfor kpart
} // endfor i
if ((oom|= qry->Append(")"))) if ((oom|= qry->Append(")")))
strcpy(g->Message, "Out of memory"); strcpy(g->Message, "Out of memory");
return oom; dbug_tmp_restore_column_map(table->write_set, old_map);
return oom;
err:
dbug_tmp_restore_column_map(table->write_set, old_map);
return true;
} // end of MakeKeyWhere } // end of MakeKeyWhere
@@ -2483,9 +2543,11 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
case MYSQL_TYPE_YEAR: case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_NEWDATE:
return NULL; return NULL;
default:
break;
} // endswitch type } // endswitch type
if (trace) { if (trace) {
htrc("Field index=%d\n", pField->field->field_index); htrc("Field index=%d\n", pField->field->field_index);
htrc("Field name=%s\n", pField->field->field_name); htrc("Field name=%s\n", pField->field->field_name);
} // endif trace } // endif trace
@@ -2562,8 +2624,9 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
/***********************************************************************/ /***********************************************************************/
/* Check the WHERE condition and return a MYSQL/ODBC/WQL filter. */ /* Check the WHERE condition and return a MYSQL/ODBC/WQL filter. */
/***********************************************************************/ /***********************************************************************/
PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
{ {
AMT tty = filp->Type;
char *body= filp->Body; char *body= filp->Body;
unsigned int i; unsigned int i;
bool ismul= false, x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC); bool ismul= false, x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC);
@@ -2596,7 +2659,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
List<Item>* arglist= cond_item->argument_list(); List<Item>* arglist= cond_item->argument_list();
List_iterator<Item> li(*arglist); List_iterator<Item> li(*arglist);
Item *subitem; const Item *subitem;
p1= body + strlen(body); p1= body + strlen(body);
strcpy(p1, "("); strcpy(p1, "(");
@@ -2604,7 +2667,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
for (i= 0; i < arglist->elements; i++) for (i= 0; i < arglist->elements; i++)
if ((subitem= li++)) { if ((subitem= li++)) {
if (!CheckCond(g, filp, tty, subitem)) { if (!CheckCond(g, filp, subitem)) {
if (vop == OP_OR || nonul) if (vop == OP_OR || nonul)
return NULL; return NULL;
else else
@@ -2626,26 +2689,27 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
} else if (cond->type() == COND::FUNC_ITEM) { } else if (cond->type() == COND::FUNC_ITEM) {
unsigned int i; unsigned int i;
// int n;
bool iscol, neg= FALSE; bool iscol, neg= FALSE;
Item_func *condf= (Item_func *)cond; Item_func *condf= (Item_func *)cond;
Item* *args= condf->arguments(); Item* *args= condf->arguments();
if (trace) if (trace)
htrc("Func type=%d argnum=%d\n", condf->functype(), htrc("Func type=%d argnum=%d\n", condf->functype(),
condf->argument_count()); condf->argument_count());
// neg= condf->
switch (condf->functype()) { switch (condf->functype()) {
case Item_func::EQUAL_FUNC: case Item_func::EQUAL_FUNC:
case Item_func::EQ_FUNC: vop= OP_EQ; break; case Item_func::EQ_FUNC: vop= OP_EQ; break;
case Item_func::NE_FUNC: vop= OP_NE; break; case Item_func::NE_FUNC: vop= OP_NE; break;
case Item_func::LT_FUNC: vop= OP_LT; break; case Item_func::LT_FUNC: vop= OP_LT; break;
case Item_func::LE_FUNC: vop= OP_LE; break; case Item_func::LE_FUNC: vop= OP_LE; break;
case Item_func::GE_FUNC: vop= OP_GE; break; case Item_func::GE_FUNC: vop= OP_GE; break;
case Item_func::GT_FUNC: vop= OP_GT; break; case Item_func::GT_FUNC: vop= OP_GT; break;
case Item_func::IN_FUNC: vop= OP_IN; case Item_func::LIKE_FUNC: vop= OP_LIKE; break;
case Item_func::ISNOTNULL_FUNC:
neg = true;
case Item_func::ISNULL_FUNC: vop= OP_NULL; break;
case Item_func::IN_FUNC: vop= OP_IN;
case Item_func::BETWEEN: case Item_func::BETWEEN:
ismul= true; ismul= true;
neg= ((Item_func_opt_neg *)condf)->negated; neg= ((Item_func_opt_neg *)condf)->negated;
@@ -2658,7 +2722,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
else if (ismul && tty == TYPE_AM_WMI) else if (ismul && tty == TYPE_AM_WMI)
return NULL; // Not supported by WQL return NULL; // Not supported by WQL
if (x && (neg || !(vop == OP_EQ || vop == OP_IN))) if (x && (neg || !(vop == OP_EQ || vop == OP_IN || vop == OP_NULL)))
return NULL; return NULL;
for (i= 0; i < condf->argument_count(); i++) { for (i= 0; i < condf->argument_count(); i++) {
@@ -2679,9 +2743,10 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
if (x && i) if (x && i)
return NULL; return NULL;
else if (pField->field->table != table)
if (pField->field->table != table) return NULL; // Field does not belong to this table
return NULL; // Field does not belong to this table else if (tty != TYPE_AM_WMI && IsIndexed(pField->field))
return NULL; // Will be handled by ReadKey
else else
fop= GetFieldOptionStruct(pField->field); fop= GetFieldOptionStruct(pField->field);
@@ -2712,7 +2777,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
strcat(body, fnm); strcat(body, fnm);
} else if (args[i]->type() == COND::FUNC_ITEM) { } else if (args[i]->type() == COND::FUNC_ITEM) {
if (tty == TYPE_AM_MYSQL) { if (tty == TYPE_AM_MYSQL) {
if (!CheckCond(g, filp, tty, args[i])) if (!CheckCond(g, filp, args[i]))
return NULL; return NULL;
} else } else
@@ -2901,14 +2966,17 @@ const COND *ha_connect::cond_push(const COND *cond)
goto fin; goto fin;
if (b) { if (b) {
PCFIL filp= (PCFIL)PlugSubAlloc(g, NULL, sizeof(CONDFIL)); PCFIL filp;
if ((filp= tdbp->GetCondFil()) && filp->Cond == cond &&
filp->Idx == active_index && filp->Type == tty)
goto fin; // Already done
filp= new(g) CONDFIL(cond, active_index, tty);
filp->Body= (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0); filp->Body= (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0);
*filp->Body= 0; *filp->Body= 0;
filp->Op= OP_XX;
filp->Cmds= NULL;
if (CheckCond(g, filp, tty, (Item *)cond)) { if (CheckCond(g, filp, cond)) {
if (trace) if (trace)
htrc("cond_push: %s\n", filp->Body); htrc("cond_push: %s\n", filp->Body);
@@ -3372,13 +3440,13 @@ int ha_connect::index_end()
/****************************************************************************/ /****************************************************************************/
/* This is internally called by all indexed reading functions. */ /* This is internally called by all indexed reading functions. */
/****************************************************************************/ /****************************************************************************/
int ha_connect::ReadIndexed(uchar *buf, OPVAL op, const uchar *key, uint key_len) int ha_connect::ReadIndexed(uchar *buf, OPVAL op, const key_range *kr)
{ {
int rc; int rc;
//statistic_increment(ha_read_key_count, &LOCK_status); //statistic_increment(ha_read_key_count, &LOCK_status);
switch (CntIndexRead(xp->g, tdbp, op, key, (int)key_len, mrr)) { switch (CntIndexRead(xp->g, tdbp, op, kr, mrr)) {
case RC_OK: case RC_OK:
xp->fnd++; xp->fnd++;
rc= MakeRecord((char*)buf); rc= MakeRecord((char*)buf);
@@ -3400,6 +3468,7 @@ int ha_connect::ReadIndexed(uchar *buf, OPVAL op, const uchar *key, uint key_len
if (trace > 1) if (trace > 1)
htrc("ReadIndexed: op=%d rc=%d\n", op, rc); htrc("ReadIndexed: op=%d rc=%d\n", op, rc);
table->status= (rc == RC_OK) ? 0 : STATUS_NOT_FOUND;
return rc; return rc;
} // end of ReadIndexed } // end of ReadIndexed
@@ -3443,7 +3512,12 @@ int ha_connect::index_read(uchar * buf, const uchar * key, uint key_len,
htrc("%p index_read: op=%d\n", this, op); htrc("%p index_read: op=%d\n", this, op);
if (indexing > 0) { if (indexing > 0) {
rc= ReadIndexed(buf, op, key, key_len); start_key.key= key;
start_key.length= key_len;
start_key.flag= find_flag;
start_key.keypart_map= 0;
rc= ReadIndexed(buf, op, &start_key);
if (rc == HA_ERR_INTERNAL_ERROR) { if (rc == HA_ERR_INTERNAL_ERROR) {
nox= true; // To block making indexes nox= true; // To block making indexes
@@ -3516,6 +3590,7 @@ int ha_connect::index_first(uchar *buf)
else if (indexing < 0) else if (indexing < 0)
rc= HA_ERR_INTERNAL_ERROR; rc= HA_ERR_INTERNAL_ERROR;
else if (CntRewindTable(xp->g, tdbp)) { else if (CntRewindTable(xp->g, tdbp)) {
table->status= STATUS_NOT_FOUND;
rc= HA_ERR_INTERNAL_ERROR; rc= HA_ERR_INTERNAL_ERROR;
} else } else
rc= rnd_next(buf); rc= rnd_next(buf);
@@ -3716,6 +3791,7 @@ int ha_connect::rnd_next(uchar *buf)
xp->fnd= xp->nfd= 0; xp->fnd= xp->nfd= 0;
} // endif nrd } // endif nrd
table->status= (!rc) ? 0 : STATUS_NOT_FOUND;
DBUG_RETURN(rc); DBUG_RETURN(rc);
} // end of rnd_next } // end of rnd_next
@@ -3747,7 +3823,7 @@ void ha_connect::position(const uchar *)
//if (((PTDBASE)tdbp)->GetDef()->Indexable()) //if (((PTDBASE)tdbp)->GetDef()->Indexable())
my_store_ptr(ref, ref_length, (my_off_t)((PTDBASE)tdbp)->GetRecpos()); my_store_ptr(ref, ref_length, (my_off_t)((PTDBASE)tdbp)->GetRecpos());
if (trace) if (trace > 1)
htrc("position: pos=%d\n", ((PTDBASE)tdbp)->GetRecpos()); htrc("position: pos=%d\n", ((PTDBASE)tdbp)->GetRecpos());
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@@ -5040,7 +5116,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
char *nsp= NULL, *cls= NULL; char *nsp= NULL, *cls= NULL;
#endif // __WIN__ #endif // __WIN__
int port= 0, hdr= 0, mxr= 0, mxe= 0, rc= 0; int port= 0, hdr= 0, mxr= 0, mxe= 0, rc= 0;
int cop __attribute__((unused))= 0; int cop __attribute__((unused))= 0, lrecl= 0;
#if defined(ODBC_SUPPORT) #if defined(ODBC_SUPPORT)
POPARM sop = NULL; POPARM sop = NULL;
char *ucnc = NULL; char *ucnc = NULL;
@@ -6198,6 +6274,10 @@ bool ha_connect::FileExists(const char *fn, bool bf)
int n; int n;
struct stat info; struct stat info;
if (check_access(ha_thd(), FILE_ACL, table->s->db.str,
NULL, NULL, 0, 0))
return true;
#if defined(__WIN__) #if defined(__WIN__)
s= "\\"; s= "\\";
#else // !__WIN__ #else // !__WIN__
@@ -6683,10 +6763,10 @@ maria_declare_plugin(connect)
PLUGIN_LICENSE_GPL, PLUGIN_LICENSE_GPL,
connect_init_func, /* Plugin Init */ connect_init_func, /* Plugin Init */
connect_done_func, /* Plugin Deinit */ connect_done_func, /* Plugin Deinit */
0x0103, /* version number (1.03) */ 0x0104, /* version number (1.04) */
NULL, /* status variables */ NULL, /* status variables */
connect_system_variables, /* system variables */ connect_system_variables, /* system variables */
"1.03.0007", /* string version */ "1.04.0003", /* string version */
MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
} }
maria_declare_plugin_end; maria_declare_plugin_end;

View File

@@ -241,11 +241,12 @@ public:
int MakeRecord(char *buf); int MakeRecord(char *buf);
int ScanRecord(PGLOBAL g, uchar *buf); int ScanRecord(PGLOBAL g, uchar *buf);
int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf); int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf);
int ReadIndexed(uchar *buf, OPVAL op, const uchar* key= NULL, int ReadIndexed(uchar *buf, OPVAL op, const key_range *kr= NULL);
uint key_len= 0); bool IsIndexed(Field *fp);
bool MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL op, char q, bool MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL op, char q,
const void *key, int klen); const key_range *kr);
inline char *Strz(LEX_STRING &ls); inline char *Strz(LEX_STRING &ls);
key_range start_key;
/** @brief /** @brief
@@ -374,7 +375,7 @@ public:
condition stack. condition stack.
*/ */
virtual const COND *cond_push(const COND *cond); virtual const COND *cond_push(const COND *cond);
PCFIL CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond); PCFIL CheckCond(PGLOBAL g, PCFIL filp, const Item *cond);
const char *GetValStr(OPVAL vop, bool neg); const char *GetValStr(OPVAL vop, bool neg);
PFIL CondFilter(PGLOBAL g, Item *cond); PFIL CondFilter(PGLOBAL g, Item *cond);
//PFIL CheckFilter(PGLOBAL g); //PFIL CheckFilter(PGLOBAL g);

View File

@@ -1,5 +1,5 @@
/*************** json CPP Declares Source Code File (.H) ***************/ /*************** json CPP Declares Source Code File (.H) ***************/
/* Name: json.cpp Version 1.1 */ /* Name: json.cpp Version 1.2 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */ /* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */
/* */ /* */
@@ -31,11 +31,12 @@
/***********************************************************************/ /***********************************************************************/
/* Parse a json string. */ /* Parse a json string. */
/* Note: when pretty is not known, the caller set pretty to 3. */
/***********************************************************************/ /***********************************************************************/
PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma) PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
{ {
int i, rc; int i, rc, pretty = (ptyp) ? *ptyp : 3;
bool b = false; bool b = false, pty[3] = {true, true, true};
PJSON jsp = NULL; PJSON jsp = NULL;
STRG src; STRG src;
@@ -48,6 +49,10 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
src.str = s; src.str = s;
src.len = len; src.len = len;
// Trying to guess the pretty format
if (s[0] == '[' && (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n')))
pty[0] = false;
// Save stack and allocation environment and prepare error return // Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) { if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS)); strcpy(g->Message, MSG(TOO_MANY_JUMPS));
@@ -58,21 +63,19 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
goto err; goto err;
} // endif rc } // endif rc
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
switch (s[i]) { switch (s[i]) {
case '[': case '[':
if (jsp) { if (jsp)
strcpy(g->Message, "More than one item in file"); goto tryit;
goto err; else if (!(jsp = ParseArray(g, ++i, src, pty)))
} else if (!(jsp = ParseArray(g, ++i, src)))
goto err; goto err;
break; break;
case '{': case '{':
if (jsp) { if (jsp)
strcpy(g->Message, "More than one item in file"); goto tryit;
goto err; else if (!(jsp = ParseObject(g, ++i, src, pty)))
} else if (!(jsp = ParseObject(g, ++i, src)))
goto err; goto err;
break; break;
@@ -82,20 +85,16 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
case '\r': case '\r':
break; break;
case ',': case ',':
if (jsp && pretty == 1) { if (jsp && (pretty == 1 || pretty == 3)) {
if (comma) if (comma)
*comma = true; *comma = true;
pty[0] = pty[2] = false;
break; break;
} // endif pretty } // endif pretty
sprintf(g->Message, "Unexpected ',' (pretty=%d)", pretty); sprintf(g->Message, "Unexpected ',' (pretty=%d)", pretty);
goto err; goto err;
case '"':
if (!(jsp = ParseValue(g, i, src)))
goto err;
break;
case '(': case '(':
b = true; b = true;
break; break;
@@ -106,18 +105,41 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
} // endif b } // endif b
default: default:
sprintf(g->Message, "Bad '%c' character near %.*s", if (jsp)
s[i], ARGS); goto tryit;
goto err; else if (!(jsp = ParseValue(g, i, src, pty)))
}; // endswitch s[i] goto err;
if (!jsp) break;
sprintf(g->Message, "Invalid Json string '%.*s'", 50, s); }; // endswitch s[i]
if (!jsp)
sprintf(g->Message, "Invalid Json string '%.*s'", 50, s);
else if (ptyp && pretty == 3) {
*ptyp = 3; // Not recognized pretty
for (i = 0; i < 3; i++)
if (pty[i]) {
*ptyp = i;
break;
} // endif pty
} // endif ptyp
g->jump_level--; g->jump_level--;
return jsp; return jsp;
err: tryit:
if (pty[0] && (!pretty || pretty > 2)) {
if ((jsp = ParseArray(g, (i = 0), src, pty)) && ptyp && pretty == 3)
*ptyp = (pty[0]) ? 0 : 3;
g->jump_level--;
return jsp;
} else
strcpy(g->Message, "More than one item in file");
err:
g->jump_level--; g->jump_level--;
return NULL; return NULL;
} // end of ParseJson } // end of ParseJson
@@ -125,11 +147,12 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
/***********************************************************************/ /***********************************************************************/
/* Parse a JSON Array. */ /* Parse a JSON Array. */
/***********************************************************************/ /***********************************************************************/
PJAR ParseArray(PGLOBAL g, int& i, STRG& src) PJAR ParseArray(PGLOBAL g, int& i, STRG& src, bool *pty)
{ {
char *s = src.str; char *s = src.str;
int len = src.len; int len = src.len;
int level = 0; int level = 0;
bool b = (!i);
PJAR jarp = new(g) JARRAY; PJAR jarp = new(g) JARRAY;
PJVAL jvp = NULL; PJVAL jvp = NULL;
@@ -151,25 +174,32 @@ PJAR ParseArray(PGLOBAL g, int& i, STRG& src)
jarp->InitArray(g); jarp->InitArray(g);
return jarp; return jarp;
case ' ': case '\n':
if (!b)
pty[0] = pty[1] = false;
case '\r':
case ' ':
case '\t': case '\t':
case '\n':
case '\r':
break; break;
default: default:
if (level == 2) { if (level == 2) {
sprintf(g->Message, "Unexpected value near %.*s", ARGS); sprintf(g->Message, "Unexpected value near %.*s", ARGS);
return NULL; return NULL;
} else if ((jvp = ParseValue(g, i, src))) { } else if ((jvp = ParseValue(g, i, src, pty)))
jarp->AddValue(g, jvp); jarp->AddValue(g, jvp);
level = 2; else
} else
return NULL; return NULL;
level = 2; level = (b) ? 1 : 2;
break; break;
}; // endswitch s[i] }; // endswitch s[i]
if (b) {
// Case of Pretty == 0
jarp->InitArray(g);
return jarp;
} // endif b
strcpy(g->Message, "Unexpected EOF in array"); strcpy(g->Message, "Unexpected EOF in array");
return NULL; return NULL;
} // end of ParseArray } // end of ParseArray
@@ -177,7 +207,7 @@ PJAR ParseArray(PGLOBAL g, int& i, STRG& src)
/***********************************************************************/ /***********************************************************************/
/* Parse a JSON Object. */ /* Parse a JSON Object. */
/***********************************************************************/ /***********************************************************************/
PJOB ParseObject(PGLOBAL g, int& i, STRG& src) PJOB ParseObject(PGLOBAL g, int& i, STRG& src, bool *pty)
{ {
PSZ key; PSZ key;
char *s = src.str; char *s = src.str;
@@ -204,7 +234,7 @@ PJOB ParseObject(PGLOBAL g, int& i, STRG& src)
break; break;
case ':': case ':':
if (level == 1) { if (level == 1) {
if (!(jpp->Val = ParseValue(g, ++i, src))) if (!(jpp->Val = ParseValue(g, ++i, src, pty)))
return NULL; return NULL;
level = 2; level = 2;
@@ -229,10 +259,11 @@ PJOB ParseObject(PGLOBAL g, int& i, STRG& src)
} // endif level } // endif level
return jobp; return jobp;
case ' ': case '\n':
pty[0] = pty[1] = false;
case '\r':
case ' ':
case '\t': case '\t':
case '\n':
case '\r':
break; break;
default: default:
sprintf(g->Message, "Unexpected character '%c' near %.*s", sprintf(g->Message, "Unexpected character '%c' near %.*s",
@@ -247,7 +278,7 @@ PJOB ParseObject(PGLOBAL g, int& i, STRG& src)
/***********************************************************************/ /***********************************************************************/
/* Parse a JSON Value. */ /* Parse a JSON Value. */
/***********************************************************************/ /***********************************************************************/
PJVAL ParseValue(PGLOBAL g, int& i, STRG& src) PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty)
{ {
char *strval, *s = src.str; char *strval, *s = src.str;
int n, len = src.len; int n, len = src.len;
@@ -255,10 +286,11 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src)
for (; i < len; i++) for (; i < len; i++)
switch (s[i]) { switch (s[i]) {
case ' ': case '\n':
pty[0] = pty[1] = false;
case '\r':
case ' ':
case '\t': case '\t':
case '\n':
case '\r':
break; break;
default: default:
goto suite; goto suite;
@@ -267,12 +299,12 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src)
suite: suite:
switch (s[i]) { switch (s[i]) {
case '[': case '[':
if (!(jvp->Jsp = ParseArray(g, ++i, src))) if (!(jvp->Jsp = ParseArray(g, ++i, src, pty)))
return NULL; return NULL;
break; break;
case '{': case '{':
if (!(jvp->Jsp = ParseObject(g, ++i, src))) if (!(jvp->Jsp = ParseObject(g, ++i, src, pty)))
return NULL; return NULL;
break; break;
@@ -319,7 +351,6 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src)
}; // endswitch s[i] }; // endswitch s[i]
jvp->Size = 1;
return jvp; return jvp;
err: err:
@@ -481,9 +512,9 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src)
valp = AllocateValue(g, &dv, TYPE_DOUBLE, nd); valp = AllocateValue(g, &dv, TYPE_DOUBLE, nd);
} else { } else {
int iv = strtol(buf, NULL, 10); long long iv = strtoll(buf, NULL, 10);
valp = AllocateValue(g, &iv, TYPE_INT); valp = AllocateValue(g, &iv, TYPE_BIGINT);
} // endif has } // endif has
i--; // Unstack following character i--; // Unstack following character
@@ -501,35 +532,44 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src)
/***********************************************************************/ /***********************************************************************/
/* Serialize a JSON tree: */ /* Serialize a JSON tree: */
/***********************************************************************/ /***********************************************************************/
PSZ Serialize(PGLOBAL g, PJSON jsp, FILE *fs, int pretty) PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty)
{ {
bool b = false, err = true; bool b = false, err = true;
JOUT *jp; JOUT *jp;
FILE *fs = NULL;
g->Message[0] = 0; g->Message[0] = 0;
if (!jsp) { if (!jsp) {
strcpy(g->Message, "Null json tree"); strcpy(g->Message, "Null json tree");
return NULL; return NULL;
} else if (!fs) { } else if (!fn) {
// Serialize to a string // Serialize to a string
jp = new(g) JOUTSTR(g); jp = new(g) JOUTSTR(g);
b = pretty == 1; b = pretty == 1;
} else if (pretty == 2) { } else {
// Serialize to a pretty file if (!(fs = fopen(fn, "wb"))) {
jp = new(g) JOUTPRT(g, fs); sprintf(g->Message, MSG(OPEN_MODE_ERROR),
} else { "w", (int)errno, fn);
// Serialize to a flat file strcat(strcat(g->Message, ": "), strerror(errno));
jp = new(g) JOUTFILE(g, fs); return g->Message;
b = pretty == 1; } else if (pretty >= 2) {
} // endif's // Serialize to a pretty file
jp = new(g)JOUTPRT(g, fs);
} else {
// Serialize to a flat file
b = true;
jp = new(g)JOUTFILE(g, fs, pretty);
} // endif's
} // endif's
switch (jsp->GetType()) { switch (jsp->GetType()) {
case TYPE_JAR: case TYPE_JAR:
err = SerializeArray(jp, (PJAR)jsp, b); err = SerializeArray(jp, (PJAR)jsp, b);
break; break;
case TYPE_JOB: case TYPE_JOB:
err = (b && jp->WriteChr('\t')); err = ((b && jp->Prty()) && jp->WriteChr('\t'));
err |= SerializeObject(jp, (PJOB)jsp); err |= SerializeObject(jp, (PJOB)jsp);
break; break;
case TYPE_JVAL: case TYPE_JVAL:
@@ -540,7 +580,7 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, FILE *fs, int pretty)
} // endswitch Type } // endswitch Type
if (fs) { if (fs) {
fputc('\n', fs); fputs(EL, fs);
fclose(fs); fclose(fs);
return (err) ? g->Message : NULL; return (err) ? g->Message : NULL;
} else if (!err) { } else if (!err) {
@@ -565,29 +605,40 @@ bool SerializeArray(JOUT *js, PJAR jarp, bool b)
{ {
bool first = true; bool first = true;
if (b) {
if (js->Prty()) {
if (js->WriteChr('['))
return true;
else if (js->Prty() == 1 && (js->WriteStr(EL) || js->WriteChr('\t')))
return true;
if (js->WriteChr('[')) } // endif Prty
return true;
else if (b && (js->WriteStr(EL) || js->WriteChr('\t'))) } else if (js->WriteChr('['))
return true; return true;
for (int i = 0; i < jarp->size(); i++) { for (int i = 0; i < jarp->size(); i++) {
if (first) if (first)
first = false; first = false;
else if (js->WriteChr(',')) else if ((!b || js->Prty()) && js->WriteChr(','))
return true;
else if (b && (js->WriteStr(EL) || js->WriteChr('\t')))
return true; return true;
else if (b) {
if (js->Prty() < 2 && js->WriteStr(EL))
return true;
else if (js->Prty() == 1 && js->WriteChr('\t'))
return true;
} // endif b
if (SerializeValue(js, jarp->GetValue(i))) if (SerializeValue(js, jarp->GetValue(i)))
return true; return true;
} // endfor i } // endfor i
if (b && js->WriteStr(EL)) if (b && js->Prty() == 1 && js->WriteStr(EL))
return true; return true;
return js->WriteChr(']'); return ((!b || js->Prty()) && js->WriteChr(']'));
} // end of SerializeArray } // end of SerializeArray
/***********************************************************************/ /***********************************************************************/
@@ -647,8 +698,8 @@ bool SerializeValue(JOUT *js, PJVAL jvp)
} // endswitch Type } // endswitch Type
strcpy(js->g->Message, "Unrecognized value"); strcpy(js->g->Message, "Unrecognized value");
return true; return true;
} // end of SerializeValue } // end of SerializeValue
/* -------------------------- Class JOUTSTR -------------------------- */ /* -------------------------- Class JOUTSTR -------------------------- */
@@ -866,6 +917,20 @@ PJPR JOBJECT::AddPair(PGLOBAL g, PSZ key)
return jpp; return jpp;
} // end of AddPair } // end of AddPair
/***********************************************************************/
/* Return all keys as an array. */
/***********************************************************************/
PJAR JOBJECT::GetKeyList(PGLOBAL g)
{
PJAR jarp = new(g) JARRAY();
for (PJPR jpp = First; jpp; jpp = jpp->Next)
jarp->AddValue(g, new(g) JVALUE(g, jpp->GetKey()));
jarp->InitArray(g);
return jarp;
} // end of GetKeyList
/***********************************************************************/ /***********************************************************************/
/* Get the value corresponding to the given key. */ /* Get the value corresponding to the given key. */
/***********************************************************************/ /***********************************************************************/
@@ -903,12 +968,30 @@ PSZ JOBJECT::GetText(PGLOBAL g, PSZ text)
return text + n; return text + n;
} // end of GetValue; } // end of GetValue;
/***********************************************************************/
/* Merge two objects. */
/***********************************************************************/
bool JOBJECT::Merge(PGLOBAL g, PJSON jsp)
{
if (jsp->GetType() != TYPE_JOB) {
strcpy(g->Message, "Second argument is not an object");
return true;
} // endif Type
PJOB jobp = (PJOB)jsp;
for (PJPR jpp = jobp->First; jpp; jpp = jpp->Next)
SetValue(g, jpp->GetVal(), jpp->GetKey());
return false;
} // end of Marge;
/***********************************************************************/ /***********************************************************************/
/* Set or add a value corresponding to the given key. */ /* Set or add a value corresponding to the given key. */
/***********************************************************************/ /***********************************************************************/
void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PSZ key) void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PSZ key)
{ {
PJPR jp; PJPR jp;
for (jp = First; jp; jp = jp->Next) for (jp = First; jp; jp = jp->Next)
if (!strcmp(jp->Key, key)) { if (!strcmp(jp->Key, key)) {
@@ -923,6 +1006,23 @@ void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PSZ key)
} // end of SetValue } // end of SetValue
/***********************************************************************/
/* Delete a value corresponding to the given key. */
/***********************************************************************/
void JOBJECT::DeleteKey(PSZ key)
{
PJPR jp, *pjp = &First;
for (jp = First; jp; jp = jp->Next)
if (!strcmp(jp->Key, key)) {
*pjp = jp->Next;
Size--;
break;
} else
pjp = &jp->Next;
} // end of DeleteKey
/***********************************************************************/ /***********************************************************************/
/* True if void or if all members are nulls. */ /* True if void or if all members are nulls. */
/***********************************************************************/ /***********************************************************************/
@@ -943,23 +1043,25 @@ bool JOBJECT::IsNull(void)
void JARRAY::InitArray(PGLOBAL g) void JARRAY::InitArray(PGLOBAL g)
{ {
int i; int i;
PJVAL jvp; PJVAL jvp, *pjvp = &First;
for (Size = 0, jvp = First; jvp; jvp = jvp->Next) for (Size = 0, jvp = First; jvp; jvp = jvp->Next)
if (!jvp->Del) if (!jvp->Del)
Size++; Size++;
if (!Size) { if (Size > Alloc) {
return;
} else if (Size > Alloc) {
// No need to realloc after deleting values // No need to realloc after deleting values
Mvals = (PJVAL*)PlugSubAlloc(g, NULL, Size * sizeof(PJVAL)); Mvals = (PJVAL*)PlugSubAlloc(g, NULL, Size * sizeof(PJVAL));
Alloc = Size; Alloc = Size;
} // endif Size } // endif Size
for (i = 0, jvp = First; jvp; jvp = jvp->Next) for (i = 0, jvp = First; jvp; jvp = jvp->Next)
if (!jvp->Del) if (!jvp->Del) {
Mvals[i++] = jvp; Mvals[i++] = jvp;
pjvp = &jvp->Next;
Last = jvp;
} else
*pjvp = jvp->Next;
} // end of InitArray } // end of InitArray
@@ -975,31 +1077,64 @@ PJVAL JARRAY::GetValue(int i)
} // end of GetValue } // end of GetValue
/***********************************************************************/ /***********************************************************************/
/* Add a Value to the Arrays Value list. */ /* Add a Value to the Array Value list. */
/***********************************************************************/ /***********************************************************************/
PJVAL JARRAY::AddValue(PGLOBAL g, PJVAL jvp) PJVAL JARRAY::AddValue(PGLOBAL g, PJVAL jvp, int *x)
{ {
if (!jvp) if (!jvp)
jvp = new(g) JVALUE; jvp = new(g) JVALUE;
if (Last) if (x) {
Last->Next = jvp; int i = 0, n = *x;
else PJVAL jp, *jpp = &First;
First = jvp;
for (jp = First; jp && i < n; i++, jp = *(jpp = &jp->Next));
(*jpp) = jvp;
if (!(jvp->Next = jp))
Last = jvp;
} else {
if (Last)
Last->Next = jvp;
else
First = jvp;
Last = jvp;
} // endif x
Last = jvp;
return jvp; return jvp;
} // end of AddValue } // end of AddValue
/***********************************************************************/ /***********************************************************************/
/* Add a Value to the Arrays Value list. */ /* Merge two arrays. */
/***********************************************************************/
bool JARRAY::Merge(PGLOBAL g, PJSON jsp)
{
if (jsp->GetType() != TYPE_JAR) {
strcpy(g->Message, "Second argument is not an array");
return true;
} // endif Type
PJAR arp = (PJAR)jsp;
for (int i = 0; i < jsp->size(); i++)
AddValue(g, arp->GetValue(i));
InitArray(g);
return false;
} // end of Merge
/***********************************************************************/
/* Set the nth Value of the Array Value list. */
/***********************************************************************/ /***********************************************************************/
bool JARRAY::SetValue(PGLOBAL g, PJVAL jvp, int n) bool JARRAY::SetValue(PGLOBAL g, PJVAL jvp, int n)
{ {
int i = 0; int i = 0;
PJVAL jp, *jpp = &First; PJVAL jp, *jpp = &First;
for (i = 0, jp = First; i < n; i++, jp = *(jpp = &jp->Next)) for (jp = First; i < n; i++, jp = *(jpp = &jp->Next))
if (!jp) if (!jp)
*jpp = jp = new(g) JVALUE; *jpp = jp = new(g) JVALUE;
@@ -1048,6 +1183,17 @@ JVALUE::JVALUE(PGLOBAL g, PVAL valp) : JSON()
Del = false; Del = false;
} // end of JVALUE constructor } // end of JVALUE constructor
/***********************************************************************/
/* Constructor for a given string. */
/***********************************************************************/
JVALUE::JVALUE(PGLOBAL g, PSZ strp) : JSON()
{
Jsp = NULL;
Value = AllocateValue(g, strp, TYPE_STRING);
Next = NULL;
Del = false;
} // end of JVALUE constructor
/***********************************************************************/ /***********************************************************************/
/* Returns the type of the Value's value. */ /* Returns the type of the Value's value. */
/***********************************************************************/ /***********************************************************************/
@@ -1092,6 +1238,14 @@ int JVALUE::GetInteger(void)
return (Value) ? Value->GetIntValue() : 0; return (Value) ? Value->GetIntValue() : 0;
} // end of GetInteger } // end of GetInteger
/***********************************************************************/
/* Return the Value's Big integer value. */
/***********************************************************************/
long long JVALUE::GetBigint(void)
{
return (Value) ? Value->GetBigintValue() : 0;
} // end of GetBigint
/***********************************************************************/ /***********************************************************************/
/* Return the Value's Double value. */ /* Return the Value's Double value. */
/***********************************************************************/ /***********************************************************************/
@@ -1134,7 +1288,26 @@ PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
void JVALUE::SetInteger(PGLOBAL g, int n) void JVALUE::SetInteger(PGLOBAL g, int n)
{ {
Value = AllocateValue(g, &n, TYPE_INT); Value = AllocateValue(g, &n, TYPE_INT);
} // end of AddInteger Jsp = NULL;
} // end of SetInteger
/***********************************************************************/
/* Set the Value's Boolean value as a tiny integer. */
/***********************************************************************/
void JVALUE::SetTiny(PGLOBAL g, char n)
{
Value = AllocateValue(g, &n, TYPE_TINY);
Jsp = NULL;
} // end of SetInteger
/***********************************************************************/
/* Set the Value's value as the given big integer. */
/***********************************************************************/
void JVALUE::SetBigint(PGLOBAL g, long long ll)
{
Value = AllocateValue(g, &ll, TYPE_BIGINT);
Jsp = NULL;
} // end of SetBigint
/***********************************************************************/ /***********************************************************************/
/* Set the Value's value as the given DOUBLE. */ /* Set the Value's value as the given DOUBLE. */
@@ -1142,15 +1315,17 @@ void JVALUE::SetInteger(PGLOBAL g, int n)
void JVALUE::SetFloat(PGLOBAL g, double f) void JVALUE::SetFloat(PGLOBAL g, double f)
{ {
Value = AllocateValue(g, &f, TYPE_DOUBLE, 6); Value = AllocateValue(g, &f, TYPE_DOUBLE, 6);
} // end of AddFloat Jsp = NULL;
} // end of SetFloat
/***********************************************************************/ /***********************************************************************/
/* Set the Value's value as the given string. */ /* Set the Value's value as the given string. */
/***********************************************************************/ /***********************************************************************/
void JVALUE::SetString(PGLOBAL g, PSZ s) void JVALUE::SetString(PGLOBAL g, PSZ s, short c)
{ {
Value = AllocateValue(g, s, TYPE_STRING); Value = AllocateValue(g, s, TYPE_STRING, c);
} // end of AddFloat Jsp = NULL;
} // end of SetString
/***********************************************************************/ /***********************************************************************/
/* True when its JSON or normal value is null. */ /* True when its JSON or normal value is null. */

View File

@@ -1,5 +1,5 @@
/**************** json H Declares Source Code File (.H) ****************/ /**************** json H Declares Source Code File (.H) ****************/
/* Name: json.h Version 1.1 */ /* Name: json.h Version 1.2 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */ /* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */
/* */ /* */
@@ -16,8 +16,9 @@
enum JTYP {TYPE_STRG = 1, enum JTYP {TYPE_STRG = 1,
TYPE_DBL = 2, TYPE_DBL = 2,
TYPE_BOOL = 4, TYPE_BOOL = 4,
TYPE_INTG = 7, TYPE_BINT = 5,
TYPE_JSON = 12, TYPE_INTG = 7,
TYPE_JSON = 12,
TYPE_JAR, TYPE_JAR,
TYPE_JOB, TYPE_JOB,
TYPE_JVAL}; TYPE_JVAL};
@@ -40,13 +41,13 @@ typedef struct {
int len; int len;
} STRG, *PSG; } STRG, *PSG;
PJSON ParseJson(PGLOBAL g, char *s, int n, int prty, bool *b = NULL); PJSON ParseJson(PGLOBAL g, char *s, int n, int *prty = NULL, bool *b = NULL);
PJAR ParseArray(PGLOBAL g, int& i, STRG& src); PJAR ParseArray(PGLOBAL g, int& i, STRG& src, bool *pty);
PJOB ParseObject(PGLOBAL g, int& i, STRG& src); PJOB ParseObject(PGLOBAL g, int& i, STRG& src, bool *pty);
PJVAL ParseValue(PGLOBAL g, int& i, STRG& src); PJVAL ParseValue(PGLOBAL g, int& i, STRG& src, bool *pty);
char *ParseString(PGLOBAL g, int& i, STRG& src); char *ParseString(PGLOBAL g, int& i, STRG& src);
PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src); PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src);
PSZ Serialize(PGLOBAL g, PJSON jsp, FILE *fs, int pretty); PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty);
bool SerializeArray(JOUT *js, PJAR jarp, bool b); bool SerializeArray(JOUT *js, PJAR jarp, bool b);
bool SerializeObject(JOUT *js, PJOB jobp); bool SerializeObject(JOUT *js, PJOB jobp);
bool SerializeValue(JOUT *js, PJVAL jvp); bool SerializeValue(JOUT *js, PJVAL jvp);
@@ -56,14 +57,16 @@ bool SerializeValue(JOUT *js, PJVAL jvp);
/***********************************************************************/ /***********************************************************************/
class JOUT : public BLOCK { class JOUT : public BLOCK {
public: public:
JOUT(PGLOBAL gp) : BLOCK() {g = gp;} JOUT(PGLOBAL gp) : BLOCK() {g = gp; Pretty = 3;}
virtual bool WriteStr(const char *s) = 0; virtual bool WriteStr(const char *s) = 0;
virtual bool WriteChr(const char c) = 0; virtual bool WriteChr(const char c) = 0;
virtual bool Escape(const char *s) = 0; virtual bool Escape(const char *s) = 0;
int Prty(void) {return Pretty;}
// Member // Member
PGLOBAL g; PGLOBAL g;
int Pretty;
}; // end of class JOUT }; // end of class JOUT
/***********************************************************************/ /***********************************************************************/
@@ -88,7 +91,7 @@ class JOUTSTR : public JOUT {
/***********************************************************************/ /***********************************************************************/
class JOUTFILE : public JOUT { class JOUTFILE : public JOUT {
public: public:
JOUTFILE(PGLOBAL g, FILE *str) : JOUT(g) {Stream = str;} JOUTFILE(PGLOBAL g, FILE *str, int pty) : JOUT(g) {Stream = str; Pretty = pty;}
virtual bool WriteStr(const char *s); virtual bool WriteStr(const char *s);
virtual bool WriteChr(const char c); virtual bool WriteChr(const char c);
@@ -103,7 +106,7 @@ class JOUTFILE : public JOUT {
/***********************************************************************/ /***********************************************************************/
class JOUTPRT : public JOUTFILE { class JOUTPRT : public JOUTFILE {
public: public:
JOUTPRT(PGLOBAL g, FILE *str) : JOUTFILE(g, str) {M = 0; B = false;} JOUTPRT(PGLOBAL g, FILE *str) : JOUTFILE(g, str, 2) {M = 0; B = false;}
virtual bool WriteStr(const char *s); virtual bool WriteStr(const char *s);
virtual bool WriteChr(const char c); virtual bool WriteChr(const char c);
@@ -118,7 +121,8 @@ class JOUTPRT : public JOUTFILE {
/***********************************************************************/ /***********************************************************************/
class JPAIR : public BLOCK { class JPAIR : public BLOCK {
friend class JOBJECT; friend class JOBJECT;
friend PJOB ParseObject(PGLOBAL, int&, STRG&); friend class JSNX;
friend PJOB ParseObject(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeObject(JOUT *, PJOB); friend bool SerializeObject(JOUT *, PJOB);
public: public:
JPAIR(PSZ key) : BLOCK() {Key = key; Val = NULL; Next = NULL;} JPAIR(PSZ key) : BLOCK() {Key = key; Val = NULL; Next = NULL;}
@@ -145,28 +149,32 @@ class JSON : public BLOCK {
virtual JTYP GetType(void) {return TYPE_JSON;} virtual JTYP GetType(void) {return TYPE_JSON;}
virtual JTYP GetValType(void) {X return TYPE_JSON;} virtual JTYP GetValType(void) {X return TYPE_JSON;}
virtual void InitArray(PGLOBAL g) {X} virtual void InitArray(PGLOBAL g) {X}
virtual PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL) {X return NULL;} virtual PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL) {X return NULL;}
virtual PJPR AddPair(PGLOBAL g, PSZ key) {X return NULL;} virtual PJPR AddPair(PGLOBAL g, PSZ key) {X return NULL;}
virtual PJVAL GetValue(const char *key) {X return NULL;} virtual PJAR GetKeyList(PGLOBAL g) {X return NULL;}
virtual PJVAL GetValue(const char *key) {X return NULL;}
virtual PJOB GetObject(void) {return NULL;} virtual PJOB GetObject(void) {return NULL;}
virtual PJAR GetArray(void) {return NULL;} virtual PJAR GetArray(void) {return NULL;}
virtual PJVAL GetValue(int i) {X return NULL;} virtual PJVAL GetValue(int i) {X return NULL;}
virtual PVAL GetValue(void) {X return NULL;} virtual PVAL GetValue(void) {X return NULL;}
virtual PJSON GetJson(void) {X return NULL;} virtual PJSON GetJsp(void) { X return NULL; }
virtual PJSON GetJson(void) { X return NULL; }
virtual PJPR GetFirst(void) {X return NULL;} virtual PJPR GetFirst(void) {X return NULL;}
virtual int GetInteger(void) {X return 0;} virtual int GetInteger(void) {X return 0;}
virtual double GetFloat() {X return 0.0;} virtual double GetFloat() {X return 0.0;}
virtual PSZ GetString() {X return NULL;} virtual PSZ GetString() {X return NULL;}
virtual PSZ GetText(PGLOBAL g, PSZ text) {X return NULL;} virtual PSZ GetText(PGLOBAL g, PSZ text) {X return NULL;}
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i) {X return true;} virtual bool Merge(PGLOBAL g, PJSON jsp) { X return true; }
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i) { X return true; }
virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key) {X} virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key) {X}
virtual void SetValue(PVAL valp) {X} virtual void SetValue(PVAL valp) {X}
virtual void SetValue(PJSON jsp) {X} virtual void SetValue(PJSON jsp) {X}
virtual void SetString(PGLOBAL g, PSZ s) {X} virtual void SetString(PGLOBAL g, PSZ s, short c) {X}
virtual void SetInteger(PGLOBAL g, int n) {X} virtual void SetInteger(PGLOBAL g, int n) {X}
virtual void SetFloat(PGLOBAL g, double f) {X} virtual void SetFloat(PGLOBAL g, double f) {X}
virtual bool DeleteValue(int i) {X return true;} virtual void DeleteKey(char *k) {X}
virtual bool IsNull(void) {X return true;} virtual bool DeleteValue(int i) {X return true;}
virtual bool IsNull(void) {X return true;}
protected: protected:
int Size; int Size;
@@ -176,8 +184,9 @@ class JSON : public BLOCK {
/* Class JOBJECT: contains a list of value pairs. */ /* Class JOBJECT: contains a list of value pairs. */
/***********************************************************************/ /***********************************************************************/
class JOBJECT : public JSON { class JOBJECT : public JSON {
friend PJOB ParseObject(PGLOBAL, int&, STRG&); friend PJOB ParseObject(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeObject(JOUT *, PJOB); friend bool SerializeObject(JOUT *, PJOB);
friend class JSNX;
public: public:
JOBJECT(void) : JSON() {First = Last = NULL;} JOBJECT(void) : JSON() {First = Last = NULL;}
@@ -189,9 +198,12 @@ class JOBJECT : public JSON {
virtual PJPR AddPair(PGLOBAL g, PSZ key); virtual PJPR AddPair(PGLOBAL g, PSZ key);
virtual PJOB GetObject(void) {return this;} virtual PJOB GetObject(void) {return this;}
virtual PJVAL GetValue(const char* key); virtual PJVAL GetValue(const char* key);
virtual PSZ GetText(PGLOBAL g, PSZ text); virtual PJAR GetKeyList(PGLOBAL g);
virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key); virtual PSZ GetText(PGLOBAL g, PSZ text);
virtual bool IsNull(void); virtual bool Merge(PGLOBAL g, PJSON jsp);
virtual void SetValue(PGLOBAL g, PJVAL jvp, PSZ key);
virtual void DeleteKey(char *k);
virtual bool IsNull(void);
protected: protected:
PJPR First; PJPR First;
@@ -202,7 +214,7 @@ class JOBJECT : public JSON {
/* Class JARRAY. */ /* Class JARRAY. */
/***********************************************************************/ /***********************************************************************/
class JARRAY : public JSON { class JARRAY : public JSON {
friend PJAR ParseArray(PGLOBAL, int&, STRG&); friend PJAR ParseArray(PGLOBAL, int&, STRG&, bool*);
public: public:
JARRAY(void) : JSON() {Alloc = 0; First = Last = NULL; Mvals = NULL;} JARRAY(void) : JSON() {Alloc = 0; First = Last = NULL; Mvals = NULL;}
@@ -211,10 +223,11 @@ class JARRAY : public JSON {
virtual void Clear(void) {First = Last = NULL; Size = 0;} virtual void Clear(void) {First = Last = NULL; Size = 0;}
virtual JTYP GetType(void) {return TYPE_JAR;} virtual JTYP GetType(void) {return TYPE_JAR;}
virtual PJAR GetArray(void) {return this;} virtual PJAR GetArray(void) {return this;}
virtual PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL); virtual PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL);
virtual void InitArray(PGLOBAL g); virtual void InitArray(PGLOBAL g);
virtual PJVAL GetValue(int i); virtual PJVAL GetValue(int i);
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i); virtual bool Merge(PGLOBAL g, PJSON jsp);
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i);
virtual bool DeleteValue(int n); virtual bool DeleteValue(int n);
virtual bool IsNull(void); virtual bool IsNull(void);
@@ -231,7 +244,8 @@ class JARRAY : public JSON {
/***********************************************************************/ /***********************************************************************/
class JVALUE : public JSON { class JVALUE : public JSON {
friend class JARRAY; friend class JARRAY;
friend PJVAL ParseValue(PGLOBAL, int&, STRG&); friend class JSNX;
friend PJVAL ParseValue(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeValue(JOUT *, PJVAL); friend bool SerializeValue(JOUT *, PJVAL);
public: public:
JVALUE(void) : JSON() JVALUE(void) : JSON()
@@ -239,6 +253,7 @@ class JVALUE : public JSON {
JVALUE(PJSON jsp) : JSON() JVALUE(PJSON jsp) : JSON()
{Jsp = jsp; Value = NULL; Next = NULL; Del = false;} {Jsp = jsp; Value = NULL; Next = NULL; Del = false;}
JVALUE(PGLOBAL g, PVAL valp); JVALUE(PGLOBAL g, PVAL valp);
JVALUE(PGLOBAL g, PSZ strp);
using JSON::GetValue; using JSON::GetValue;
using JSON::SetValue; using JSON::SetValue;
@@ -249,17 +264,21 @@ class JVALUE : public JSON {
virtual PJOB GetObject(void); virtual PJOB GetObject(void);
virtual PJAR GetArray(void); virtual PJAR GetArray(void);
virtual PVAL GetValue(void) {return Value;} virtual PVAL GetValue(void) {return Value;}
virtual PJSON GetJson(void) {return (Jsp ? Jsp : this);} virtual PJSON GetJsp(void) {return Jsp;}
virtual int GetInteger(void); virtual PJSON GetJson(void) { return (Jsp ? Jsp : this); }
virtual double GetFloat(void); virtual int GetInteger(void);
virtual long long GetBigint(void);
virtual double GetFloat(void);
virtual PSZ GetString(void); virtual PSZ GetString(void);
virtual PSZ GetText(PGLOBAL g, PSZ text); virtual PSZ GetText(PGLOBAL g, PSZ text);
virtual void SetValue(PVAL valp) {Value = valp;} virtual void SetValue(PVAL valp) {Value = valp; Jsp = NULL;}
virtual void SetValue(PJSON jsp) {Jsp = jsp;} virtual void SetValue(PJSON jsp) {Jsp = jsp; Value = NULL;}
virtual void SetString(PGLOBAL g, PSZ s); virtual void SetString(PGLOBAL g, PSZ s, short c = 0);
virtual void SetInteger(PGLOBAL g, int n); virtual void SetInteger(PGLOBAL g, int n);
virtual void SetFloat(PGLOBAL g, double f); virtual void SetBigint(PGLOBAL g, longlong ll);
virtual bool IsNull(void); virtual void SetFloat(PGLOBAL g, double f);
virtual void SetTiny(PGLOBAL g, char f);
virtual bool IsNull(void);
protected: protected:
PJSON Jsp; // To the json value PJSON Jsp; // To the json value

File diff suppressed because it is too large Load Diff

247
storage/connect/jsonudf.h Normal file
View File

@@ -0,0 +1,247 @@
/******************** tabjson H Declares Source Code File (.H) *******************/
/* Name: jsonudf.h Version 1.2 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2015 */
/* */
/* This file contains the JSON UDF function and class declares. */
/*********************************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "block.h"
#include "osutil.h"
#include "maputil.h"
#include "json.h"
#define UDF_EXEC_ARGS \
UDF_INIT*, UDF_ARGS*, char*, unsigned long*, char*, char*
/*********************************************************************************/
/* The JSON tree node. Can be an Object or an Array. */
/*********************************************************************************/
typedef struct _jnode {
PSZ Key; // The key used for object
OPVAL Op; // Operator used for this node
PVAL CncVal; // To cont value used for OP_CNC
PVAL Valp; // The internal array VALUE
int Rank; // The rank in array
int Rx; // Read row number
int Nx; // Next to read row number
} JNODE, *PJNODE;
typedef class JSNX *PJSNX;
typedef class JOUTPATH *PJTP;
typedef class JOUTALL *PJTA;
extern "C" {
DllExport my_bool jsonvalue_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jsonvalue(UDF_EXEC_ARGS);
DllExport void jsonvalue_deinit(UDF_INIT*);
DllExport my_bool json_array_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_array(UDF_EXEC_ARGS);
DllExport void json_array_deinit(UDF_INIT*);
DllExport my_bool json_array_add_values_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_array_add_values(UDF_EXEC_ARGS);
DllExport void json_array_add_values_deinit(UDF_INIT*);
DllExport my_bool json_array_add_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_array_add(UDF_EXEC_ARGS);
DllExport void json_array_add_deinit(UDF_INIT*);
DllExport my_bool json_array_delete_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_array_delete(UDF_EXEC_ARGS);
DllExport void json_array_delete_deinit(UDF_INIT*);
DllExport my_bool json_object_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_object(UDF_EXEC_ARGS);
DllExport void json_object_deinit(UDF_INIT*);
DllExport my_bool json_object_nonull_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_object_nonull(UDF_EXEC_ARGS);
DllExport void json_object_nonull_deinit(UDF_INIT*);
DllExport my_bool json_object_add_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_object_add(UDF_EXEC_ARGS);
DllExport void json_object_add_deinit(UDF_INIT*);
DllExport my_bool json_object_delete_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_object_delete(UDF_EXEC_ARGS);
DllExport void json_object_delete_deinit(UDF_INIT*);
DllExport my_bool json_object_list_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_object_list(UDF_EXEC_ARGS);
DllExport void json_object_list_deinit(UDF_INIT*);
DllExport my_bool json_array_grp_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport void json_array_grp_add(UDF_INIT *, UDF_ARGS *, char *, char *);
DllExport char *json_array_grp(UDF_EXEC_ARGS);
DllExport void json_array_grp_clear(UDF_INIT *, char *, char *);
DllExport void json_array_grp_deinit(UDF_INIT*);
DllExport my_bool json_object_grp_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport void json_object_grp_add(UDF_INIT *, UDF_ARGS *, char *, char *);
DllExport char *json_object_grp(UDF_EXEC_ARGS);
DllExport void json_object_grp_clear(UDF_INIT *, char *, char *);
DllExport void json_object_grp_deinit(UDF_INIT*);
DllExport my_bool json_item_merge_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_item_merge(UDF_EXEC_ARGS);
DllExport void json_item_merge_deinit(UDF_INIT*);
DllExport my_bool json_get_item_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_get_item(UDF_EXEC_ARGS);
DllExport void json_get_item_deinit(UDF_INIT*);
DllExport my_bool jsonget_string_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jsonget_string(UDF_EXEC_ARGS);
DllExport void jsonget_string_deinit(UDF_INIT*);
DllExport my_bool jsonget_int_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport long long jsonget_int(UDF_INIT*, UDF_ARGS*, char*, char*);
DllExport void jsonget_int_deinit(UDF_INIT*);
DllExport my_bool jsonget_real_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport double jsonget_real(UDF_INIT*, UDF_ARGS*, char*, char*);
DllExport void jsonget_real_deinit(UDF_INIT*);
DllExport my_bool jsonlocate_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jsonlocate(UDF_EXEC_ARGS);
DllExport void jsonlocate_deinit(UDF_INIT*);
DllExport my_bool json_locate_all_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_locate_all(UDF_EXEC_ARGS);
DllExport void json_locate_all_deinit(UDF_INIT*);
DllExport my_bool json_file_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_file(UDF_EXEC_ARGS);
DllExport void json_file_deinit(UDF_INIT*);
DllExport my_bool jfile_make_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jfile_make(UDF_EXEC_ARGS);
DllExport void jfile_make_deinit(UDF_INIT*);
DllExport my_bool jbin_array_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_array(UDF_EXEC_ARGS);
DllExport void jbin_array_deinit(UDF_INIT*);
DllExport my_bool jbin_array_add_values_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_array_add_values(UDF_EXEC_ARGS);
DllExport void jbin_array_add_values_deinit(UDF_INIT*);
DllExport my_bool jbin_array_add_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_array_add(UDF_EXEC_ARGS);
DllExport void jbin_array_add_deinit(UDF_INIT*);
DllExport my_bool jbin_array_delete_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_array_delete(UDF_EXEC_ARGS);
DllExport void jbin_array_delete_deinit(UDF_INIT*);
DllExport my_bool jbin_object_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_object(UDF_EXEC_ARGS);
DllExport void jbin_object_deinit(UDF_INIT*);
DllExport my_bool jbin_object_nonull_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_object_nonull(UDF_EXEC_ARGS);
DllExport void jbin_object_nonull_deinit(UDF_INIT*);
DllExport my_bool jbin_object_add_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_object_add(UDF_EXEC_ARGS);
DllExport void jbin_object_add_deinit(UDF_INIT*);
DllExport my_bool jbin_object_delete_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_object_delete(UDF_EXEC_ARGS);
DllExport void jbin_object_delete_deinit(UDF_INIT*);
DllExport my_bool jbin_object_list_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_object_list(UDF_EXEC_ARGS);
DllExport void jbin_object_list_deinit(UDF_INIT*);
DllExport my_bool jbin_get_item_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_get_item(UDF_EXEC_ARGS);
DllExport void jbin_get_item_deinit(UDF_INIT*);
DllExport my_bool jbin_item_merge_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_item_merge(UDF_EXEC_ARGS);
DllExport void jbin_item_merge_deinit(UDF_INIT*);
DllExport my_bool jbin_file_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *jbin_file(UDF_EXEC_ARGS);
DllExport void jbin_file_deinit(UDF_INIT*);
DllExport my_bool json_serialize_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_serialize(UDF_EXEC_ARGS);
DllExport void json_serialize_deinit(UDF_INIT*);
} // extern "C"
/*********************************************************************************/
/* Structure JPN. Used to make the locate path. */
/*********************************************************************************/
typedef struct _jpn {
enum JTYP Type;
PSZ Key;
int N;
} JPN, *PJPN;
/*********************************************************************************/
/* Class JSNX: JSON access method. */
/*********************************************************************************/
class JSNX : public BLOCK {
public:
// Constructors
JSNX(PGLOBAL g, PJSON row, int type, int len = 64, int prec = 0);
// Implementation
int GetPrecision(void) {return Prec;}
PVAL GetValue(void) {return Value;}
// Methods
my_bool SetJpath(PGLOBAL g, char *path, my_bool jb = false);
my_bool ParseJpath(PGLOBAL g);
void ReadValue(PGLOBAL g);
PJVAL GetValue(PGLOBAL g, PJSON row, int i, my_bool b = true);
PJVAL GetJson(PGLOBAL g);
char *Locate(PGLOBAL g, PJSON jsp, PJVAL jvp, int k = 1);
char *LocateAll(PGLOBAL g, PJSON jsp, PJVAL jvp, int mx = 10);
protected:
my_bool SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm);
PVAL GetColumnValue(PGLOBAL g, PJSON row, int i);
PVAL ExpandArray(PGLOBAL g, PJAR arp, int n);
PVAL CalculateArray(PGLOBAL g, PJAR arp, int n);
PVAL MakeJson(PGLOBAL g, PJSON jsp);
void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n);
my_bool LocateArray(PJAR jarp);
my_bool LocateObject(PJOB jobp);
my_bool LocateValue(PJVAL jvp);
my_bool LocateArrayAll(PJAR jarp);
my_bool LocateObjectAll(PJOB jobp);
my_bool LocateValueAll(PJVAL jvp);
my_bool CompareTree(PJSON jp1, PJSON jp2);
my_bool AddPath(void);
// Default constructor not to be used
JSNX(void) {}
// Members
PJSON Row;
PJVAL Jvalp;
PJPN Jpnp;
JOUTSTR *Jp;
JNODE *Nodes; // The intermediate objects
PVAL Value;
PVAL MulVal; // To value used by multiple column
char *Jpath; // The json path
int Buf_Type;
int Long;
int Prec;
int Nod; // The number of intermediate objects
int Xnod; // Index of multiple values
int K; // Kth item to locate
int I; // Index of JPN
int Imax; // Max number of JPN's
int B; // Index base
my_bool Xpd; // True for expandable column
my_bool Parsed; // True when parsed
my_bool Found; // Item found by locate
}; // end of class JSNX

View File

@@ -299,13 +299,13 @@ int GetIndexType(TABTYPE type)
xtyp= 1; xtyp= 1;
break; break;
case TAB_MYSQL: case TAB_MYSQL:
// case TAB_ODBC: case TAB_ODBC:
xtyp= 2; xtyp= 2;
break; break;
case TAB_VIR: case TAB_VIR:
xtyp= 3; xtyp= 3;
break; break;
case TAB_ODBC: // case TAB_ODBC:
default: default:
xtyp= 0; xtyp= 0;
break; break;

View File

@@ -30,3 +30,30 @@ SELECT id, TIME(tim) FROM t1 LIMIT 1;
id TIME(tim) id TIME(tim)
1 09:35:08.000000 1 09:35:08.000000
DROP TABLE t1; DROP TABLE t1;
#
# Testing use of dates in where clause (MDEV-8926)
#
CREATE TABLE t1 (col1 DATE) ENGINE=CONNECT TABLE_TYPE=CSV;
Warnings:
Warning 1105 No file name. Table will use t1.csv
INSERT INTO t1 VALUES('2015-01-01'),('2015-02-01'),('2015-03-01'),('2015-04-01');
SELECT * FROM t1 WHERE col1 = '2015-02-01';
col1
2015-02-01
SELECT * FROM t1 WHERE col1 > '2015-02-01';
col1
2015-03-01
2015-04-01
SELECT * FROM t1 WHERE col1 >= '2015-02-01';
col1
2015-02-01
2015-03-01
2015-04-01
SELECT * FROM t1 WHERE col1 < '2015-02-01';
col1
2015-01-01
SELECT * FROM t1 WHERE col1 <= '2015-02-01';
col1
2015-01-01
2015-02-01
DROP TABLE t1;

View File

@@ -171,6 +171,40 @@ line
] ]
DROP TABLE t1; DROP TABLE t1;
# #
# Testing a pretty=0 file
#
CREATE TABLE t1
(
ISBN CHAR(15) NOT NULL,
Language CHAR(2) FIELD_FORMAT='LANG',
Subject CHAR(32) FIELD_FORMAT='SUBJECT',
AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:FIRSTNAME',
AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:LASTNAME',
Title CHAR(32) FIELD_FORMAT='TITLE',
Translation CHAR(32) FIELD_FORMAT='TRANSLATED:PREFIX',
TranslatorFN CHAR(80) FIELD_FORMAT='TRANSLATED:TRANSLATOR:FIRSTNAME',
TranslatorLN CHAR(80) FIELD_FORMAT='TRANSLATED:TRANSLATOR:LASTNAME',
Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
Year int(4) FIELD_FORMAT='DATEPUB',
INDEX IX(ISBN)
)
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bib0.json' LRECL=320 OPTION_LIST='Pretty=0';
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 1 IX 1 ISBN A NULL NULL NULL XINDEX
SELECT * FROM t1;
ISBN Language Subject AuthorFN AuthorLN Title Translation TranslatorFN TranslatorLN Publisher Location Year
9782212090819 fr applications Jean-Michel Bernadac Construire une application XML NULL NULL NULL Eyrolles Paris 1999
9782212090819 fr applications Fran<61>ois Knab Construire une application XML NULL NULL NULL Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapt<70> de l'anglais par James Guerin Microsoft Press Paris 2001
DESCRIBE SELECT * FROM t1 WHERE ISBN = '9782212090819';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref IX IX 15 const 1 Using where
UPDATE t1 SET AuthorFN = 'Philippe' WHERE ISBN = '9782212090819';
ERROR HY000: Got error 122 'Cannot write expanded column when Pretty is not 2' from CONNECT
DROP TABLE t1;
#
# A file with 2 arrays # A file with 2 arrays
# #
CREATE TABLE t1 ( CREATE TABLE t1 (

View File

@@ -1,63 +1,147 @@
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=VIR BLOCK_SIZE=5;
# #
# Test UDF's with constant arguments # Test UDF's with constant arguments
# #
SELECT JsonValue(56,3.1416,'foo',NULL);
ERROR HY000: Can't initialize function 'jsonvalue'; Cannot accept more than 1 argument
SELECT JsonValue(3.1416);
JsonValue(3.1416)
3.141600
SELECT JsonValue('foo');
JsonValue('foo')
"foo"
SELECT JsonValue(9223372036854775807);
JsonValue(9223372036854775807)
9223372036854775807
SELECT JsonValue(NULL);
JsonValue(NULL)
null
SELECT JsonValue(TRUE);
JsonValue(TRUE)
true
SELECT JsonValue(FALSE);
JsonValue(FALSE)
false
SELECT JsonValue();
JsonValue()
null
SELECT JsonValue('[11,22,33]' json_) FROM t1;
JsonValue('[11,22,33]' json_)
[11,22,33]
[11,22,33]
[11,22,33]
[11,22,33]
[11,22,33]
SELECT Json_Array(); SELECT Json_Array();
Json_Array() Json_Array()
[] []
SELECT Json_Object(56,3.1416,'foo',NULL);
Json_Object(56,3.1416,'foo',NULL)
{"56":56,"3.1416":3.141600,"foo":"foo","NULL":null}
SELECT Json_Object(56 qty,3.1416 price,'foo' truc, NULL garanty);
Json_Object(56 qty,3.1416 price,'foo' truc, NULL garanty)
{"qty":56,"price":3.141600,"truc":"foo","garanty":null}
SELECT Json_Array(56,3.1416,'My name is "Foo"',NULL); SELECT Json_Array(56,3.1416,'My name is "Foo"',NULL);
Json_Array(56,3.1416,'My name is "Foo"',NULL) Json_Array(56,3.1416,'My name is "Foo"',NULL)
[56,3.141600,"My name is \"Foo\"",null] [56,3.141600,"My name is \"Foo\"",null]
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL)) Array;
ERROR HY000: Can't initialize function 'Json_Array_Add'; Json_Value_Add must have at least 2 arguments
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL),'One more') Array;
Array
[56,3.141600,"foo",null,"One more"]
SELECT Json_Array_Add(Json_Value('one value'),'One more');
Json_Array_Add(Json_Value('one value'),'One more')
["one value","One more"]
SELECT Json_Array_Add('one value','One more');
ERROR HY000: Can't initialize function 'Json_Array_Add'; Json_Value_Add first argument must be a json item
SELECT Json_Array_Add('one value' json_,'One more');
Json_Array_Add('one value' json_,'One more')
[null,"One more"]
Warnings:
Warning 1105 Bad 'o' character near one value
SELECT Json_Value(56,3.1416,'foo',NULL);
ERROR HY000: Can't initialize function 'Json_Value'; Json_Value cannot accept more than 1 argument
SELECT Json_Value(3.1416);
Json_Value(3.1416)
3.141600
SELECT Json_Value('foo');
Json_Value('foo')
"foo"
SELECT Json_Value(NULL);
Json_Value(NULL)
null
SELECT Json_Value();
Json_Value()
null
SELECT Json_Object();
Json_Object()
{}
SELECT Json_Object(Json_Array(56,3.1416,'foo'),NULL);
Json_Object(Json_Array(56,3.1416,'foo'),NULL)
{"Array(56,3.1416,'foo')":[56,3.141600,"foo"],"NULL":null}
SELECT Json_Array(Json_Array(56,3.1416,'foo'),NULL); SELECT Json_Array(Json_Array(56,3.1416,'foo'),NULL);
Json_Array(Json_Array(56,3.1416,'foo'),NULL) Json_Array(Json_Array(56,3.1416,'foo'),NULL)
[[56,3.141600,"foo"],null] [[56,3.141600,"foo"],null]
SELECT Json_Array(Json_Object(56 "qty",3.1416 "price",'foo'),NULL); SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL)) Array;
Json_Array(Json_Object(56 "qty",3.1416 "price",'foo'),NULL) ERROR HY000: Can't initialize function 'json_array_add'; This function must have at least 2 arguments
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL),'One more') Array;
Array
[56,3.141600,"foo",null,"One more"]
SELECT Json_Array_Add(JsonValue('one value'),'One more');
ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
SELECT Json_Array_Add('one value','One more');
ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
SELECT Json_Array_Add('one value' json_,'One more');
Json_Array_Add('one value' json_,'One more')
one value
Warnings:
Warning 1105 Error 2 opening one value
Warning 1105 First argument target is not an array
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 0);
Json_Array_Add('[5,3,8,7,9]' json_, 4, 0)
[4,5,3,8,7,9]
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 2) Array;
Array
[5,3,4,8,7,9]
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 9);
Json_Array_Add('[5,3,8,7,9]' json_, 4, 9)
[5,3,8,7,9,4]
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin', NULL), 'One more', 'Two more') Array;
Array
[56,3.141600,"machin",null,"One more","Two more"]
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), 'One more', 'Two more') Array FROM t1;
Array
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
[56,3.141600,"machin","One more","Two more"]
SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), n) Array FROM t1;
Array
[56,3.141600,"machin",1]
[56,3.141600,"machin",2]
[56,3.141600,"machin",3]
[56,3.141600,"machin",4]
[56,3.141600,"machin",5]
SELECT Json_Array_Add_Values(Json_Array(n, 3.1416, 'machin'), n) Array FROM t1;
Array
[1,3.141600,"machin",1]
[2,3.141600,"machin",2]
[3,3.141600,"machin",3]
[4,3.141600,"machin",4]
[5,3.141600,"machin",5]
SELECT Json_Array_Add_Values('[56]', 3.1416, 'machin') Array;
Array
[56,3.141600,"machin"]
SELECT Json_Array_Delete(Json_Array(56,3.1416,'My name is "Foo"',NULL),0);
Json_Array_Delete(Json_Array(56,3.1416,'My name is "Foo"',NULL),0)
[3.141600,"My name is \"Foo\"",null]
SELECT Json_Array_Delete(Json_Object(56,3.1416,'My name is Foo',NULL),2);
Json_Array_Delete(Json_Object(56,3.1416,'My name is Foo',NULL),2)
{"56":56,"3.1416":3.141600,"My name is Foo":"My name is Foo","NULL":null}
Warnings:
Warning 1105 First argument target is not an array
SELECT Json_Array_Delete(Json_Array(56,3.1416,'My name is "Foo"',NULL),'2');
Json_Array_Delete(Json_Array(56,3.1416,'My name is "Foo"',NULL),'2')
[56,3.141600,"My name is \"Foo\"",null]
Warnings:
Warning 1105 Missing or null array index
SELECT Json_Object(56, 3.1416, 'foo', NULL);
Json_Object(56, 3.1416, 'foo', NULL)
{"56":56,"3.1416":3.141600,"foo":"foo","NULL":null}
SELECT Json_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty);
Json_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty)
{"qty":56,"price":3.141600,"truc":"foo","garanty":null}
SELECT Json_Object();
Json_Object()
{}
SELECT Json_Object(Json_Array(56, 3.1416, 'foo'), NULL);
Json_Object(Json_Array(56, 3.1416, 'foo'), NULL)
{"Array(56, 3.1416, 'foo')":[56,3.141600,"foo"],"NULL":null}
SELECT Json_Array(Json_Object(56 "qty", 3.1416 "price", 'foo') ,NULL);
Json_Array(Json_Object(56 "qty", 3.1416 "price", 'foo') ,NULL)
[{"qty":56,"price":3.141600,"foo":"foo"},null] [{"qty":56,"price":3.141600,"foo":"foo"},null]
SELECT Json_Object_Add(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'blue' color);
Json_Object_Add(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'blue' color)
{"qty":56,"price":3.141600,"truc":"machin","garanty":null,"color":"blue"}
SELECT Json_Object_Add(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 45.99 price);
Json_Object_Add(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 45.99 price)
{"qty":56,"price":45.990000,"truc":"machin","garanty":null}
SELECT Json_Object_Delete(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'truc');
Json_Object_Delete(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'truc')
{"qty":56,"price":3.141600,"garanty":null}
SELECT Json_Object_Delete(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'chose');
Json_Object_Delete(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'chose')
{"qty":56,"price":3.141600,"truc":"machin","garanty":null}
SELECT Json_Object_List(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty)) "Key List";
Key List
["qty","price","truc","garanty"]
SELECT Json_Object_List('{"qty":56, "price":3.1416, "truc":"machin", "garanty":null}') "Key List";
Key List
["qty","price","truc","garanty"]
# #
# Test UDF's with column arguments # Test UDF's with column arguments
# #
CREATE TABLE t1 CREATE TABLE t2
( (
ISBN CHAR(15), ISBN CHAR(15),
LANG CHAR(2), LANG CHAR(2),
@@ -69,21 +153,20 @@ TRANSLATOR CHAR(80),
PUBLISHER CHAR(32), PUBLISHER CHAR(32),
DATEPUB int(4) DATEPUB int(4)
) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json'; ) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t1; SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t2;
Json_Array(AUTHOR, TITLE, DATEPUB) Json_Array(AUTHOR, TITLE, DATEPUB)
["Jean-Christophe Bernadac","Construire une application XML",1999] ["Jean-Christophe Bernadac","Construire une application XML",1999]
["William J. Pardi","XML en Action",1999] ["William J. Pardi","XML en Action",1999]
SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t1; SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t2;
Json_Object(AUTHOR, TITLE, DATEPUB) Json_Object(AUTHOR, TITLE, DATEPUB)
{"AUTHOR":"Jean-Christophe Bernadac","TITLE":"Construire une application XML","DATEPUB":1999} {"AUTHOR":"Jean-Christophe Bernadac","TITLE":"Construire une application XML","DATEPUB":1999}
{"AUTHOR":"William J. Pardi","TITLE":"XML en Action","DATEPUB":1999} {"AUTHOR":"William J. Pardi","TITLE":"XML en Action","DATEPUB":1999}
SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t1; SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t2;
ERROR HY000: Can't initialize function 'Json_Array_Grp'; Json_Array_Grp can only accept 1 argument ERROR HY000: Can't initialize function 'json_array_grp'; This function can only accept 1 argument
SELECT Json_Array_Grp(TITLE) FROM t1; SELECT Json_Array_Grp(TITLE) FROM t2;
Json_Array_Grp(TITLE) Json_Array_Grp(TITLE)
["Construire une application XML","XML en Action"] ["Construire une application XML","XML en Action"]
DROP TABLE t1; CREATE TABLE t3 (
CREATE TABLE t1 (
SERIALNO CHAR(5) NOT NULL, SERIALNO CHAR(5) NOT NULL,
NAME VARCHAR(12) NOT NULL FLAG=6, NAME VARCHAR(12) NOT NULL FLAG=6,
SEX SMALLINT(1) NOT NULL, SEX SMALLINT(1) NOT NULL,
@@ -93,10 +176,10 @@ DEPARTMENT CHAr(4) NOT NULL FLAG=41,
SECRETARY CHAR(5) DEFAULT NULL FLAG=46, SECRETARY CHAR(5) DEFAULT NULL FLAG=46,
SALARY DOUBLE(8,2) NOT NULL FLAG=52 SALARY DOUBLE(8,2) NOT NULL FLAG=52
) ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=8 FILE_NAME='employee.dat' ENDING=1; ) ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=8 FILE_NAME='employee.dat' ENDING=1;
SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t1 WHERE NAME = 'MERCHANT'; SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t3 WHERE NAME = 'MERCHANT';
Json_Object(SERIALNO, NAME, TITLE, SALARY) Json_Object(SERIALNO, NAME, TITLE, SALARY)
{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.000000} {"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.000000}
SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t1 GROUP BY DEPARTMENT; SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t3 GROUP BY DEPARTMENT;
DEPARTMENT Json_Array_Grp(NAME) DEPARTMENT Json_Array_Grp(NAME)
0021 ["STRONG","SHORTSIGHT"] 0021 ["STRONG","SHORTSIGHT"]
0318 ["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"] 0318 ["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]
@@ -104,26 +187,26 @@ DEPARTMENT Json_Array_Grp(NAME)
2452 ["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"] 2452 ["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]
Warnings: Warnings:
Warning 1105 Result truncated to json_grp_size values Warning 1105 Result truncated to json_grp_size values
set connect_json_grp_size=30; SET connect_json_grp_size=30;
SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t1 GROUP BY DEPARTMENT; SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t3 GROUP BY DEPARTMENT;
Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) Json_Array(DEPARTMENT, Json_Array_Grp(NAME))
["0021",["STRONG","SHORTSIGHT"]] ["0021",["STRONG","SHORTSIGHT"]]
["0318",["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]] ["0318",["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]]
["0319",["BULLOZER","QUINN","BROWNY","KITTY","MONAPENNY","MARTIN","FUNNIGUY","BUGHAPPY","FODDERMAN","MESSIFUL","GOOSEPEN"]] ["0319",["BULLOZER","QUINN","BROWNY","KITTY","MONAPENNY","MARTIN","FUNNIGUY","BUGHAPPY","FODDERMAN","MESSIFUL","GOOSEPEN"]]
["2452",["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]] ["2452",["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]]
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t1 GROUP BY DEPARTMENT; SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t3 GROUP BY DEPARTMENT;
Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES)
{"DEPARTMENT":"0021","NAMES":["STRONG","SHORTSIGHT"]} {"DEPARTMENT":"0021","NAMES":["STRONG","SHORTSIGHT"]}
{"DEPARTMENT":"0318","NAMES":["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]} {"DEPARTMENT":"0318","NAMES":["BANCROFT","PLUMHEAD","HONEY","TONGHO","WALTER","SHRINKY","WERTHER","MERCHANT","WHEELFOR"]}
{"DEPARTMENT":"0319","NAMES":["BULLOZER","QUINN","BROWNY","KITTY","MONAPENNY","MARTIN","FUNNIGUY","BUGHAPPY","FODDERMAN","MESSIFUL","GOOSEPEN"]} {"DEPARTMENT":"0319","NAMES":["BULLOZER","QUINN","BROWNY","KITTY","MONAPENNY","MARTIN","FUNNIGUY","BUGHAPPY","FODDERMAN","MESSIFUL","GOOSEPEN"]}
{"DEPARTMENT":"2452","NAMES":["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]} {"DEPARTMENT":"2452","NAMES":["BIGHEAD","ORELLY","BIGHORN","SMITH","CHERRY"]}
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t1 GROUP BY DEPARTMENT; SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT;
Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES)
{"DEPARTMENT":"0021","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","TITLE":"DIRECTOR","SALARY":23000.000000},{"SERIALNO":"22222","NAME":"SHORTSIGHT","TITLE":"SECRETARY","SALARY":5500.000000}]} {"DEPARTMENT":"0021","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","TITLE":"DIRECTOR","SALARY":23000.000000},{"SERIALNO":"22222","NAME":"SHORTSIGHT","TITLE":"SECRETARY","SALARY":5500.000000}]}
{"DEPARTMENT":"0318","EMPLOYES":[{"SERIALNO":"74200","NAME":"BANCROFT","TITLE":"SALESMAN","SALARY":9600.000000},{"SERIALNO":"24888","NAME":"PLUMHEAD","TITLE":"TYPIST","SALARY":2800.000000},{"SERIALNO":"27845","NAME":"HONEY","TITLE":"SECRETARY","SALARY":4900.000000},{"SERIALNO":"73452","NAME":"TONGHO","TITLE":"ENGINEER","SALARY":6800.000000},{"SERIALNO":"74234","NAME":"WALTER","TITLE":"ENGINEER","SALARY":7400.000000},{"SERIALNO":"77777","NAME":"SHRINKY","TITLE":"ADMINISTRATOR","SALARY":7500.000000},{"SERIALNO":"70012","NAME":"WERTHER","TITLE":"DIRECTOR","SALARY":14500.000000},{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.000000},{"SERIALNO":"73111","NAME":"WHEELFOR","TITLE":"SALESMAN","SALARY":10030.000000}]} {"DEPARTMENT":"0318","EMPLOYES":[{"SERIALNO":"74200","NAME":"BANCROFT","TITLE":"SALESMAN","SALARY":9600.000000},{"SERIALNO":"24888","NAME":"PLUMHEAD","TITLE":"TYPIST","SALARY":2800.000000},{"SERIALNO":"27845","NAME":"HONEY","TITLE":"SECRETARY","SALARY":4900.000000},{"SERIALNO":"73452","NAME":"TONGHO","TITLE":"ENGINEER","SALARY":6800.000000},{"SERIALNO":"74234","NAME":"WALTER","TITLE":"ENGINEER","SALARY":7400.000000},{"SERIALNO":"77777","NAME":"SHRINKY","TITLE":"ADMINISTRATOR","SALARY":7500.000000},{"SERIALNO":"70012","NAME":"WERTHER","TITLE":"DIRECTOR","SALARY":14500.000000},{"SERIALNO":"78943","NAME":"MERCHANT","TITLE":"SALESMAN","SALARY":8700.000000},{"SERIALNO":"73111","NAME":"WHEELFOR","TITLE":"SALESMAN","SALARY":10030.000000}]}
{"DEPARTMENT":"0319","EMPLOYES":[{"SERIALNO":"76543","NAME":"BULLOZER","TITLE":"SALESMAN","SALARY":14800.000000},{"SERIALNO":"40567","NAME":"QUINN","TITLE":"DIRECTOR","SALARY":14000.000000},{"SERIALNO":"00137","NAME":"BROWNY","TITLE":"ENGINEER","SALARY":10500.000000},{"SERIALNO":"12345","NAME":"KITTY","TITLE":"TYPIST","SALARY":3000.450000},{"SERIALNO":"33333","NAME":"MONAPENNY","TITLE":"SECRETARY","SALARY":3800.000000},{"SERIALNO":"00023","NAME":"MARTIN","TITLE":"ENGINEER","SALARY":10000.000000},{"SERIALNO":"07654","NAME":"FUNNIGUY","TITLE":"ADMINISTRATOR","SALARY":8500.000000},{"SERIALNO":"45678","NAME":"BUGHAPPY","TITLE":"PROGRAMMER","SALARY":8500.000000},{"SERIALNO":"56789","NAME":"FODDERMAN","TITLE":"SALESMAN","SALARY":7000.000000},{"SERIALNO":"55555","NAME":"MESSIFUL","TITLE":"SECRETARY","SALARY":5000.500000},{"SERIALNO":"98765","NAME":"GOOSEPEN","TITLE":"ADMINISTRATOR","SALARY":4700.000000}]} {"DEPARTMENT":"0319","EMPLOYES":[{"SERIALNO":"76543","NAME":"BULLOZER","TITLE":"SALESMAN","SALARY":14800.000000},{"SERIALNO":"40567","NAME":"QUINN","TITLE":"DIRECTOR","SALARY":14000.000000},{"SERIALNO":"00137","NAME":"BROWNY","TITLE":"ENGINEER","SALARY":10500.000000},{"SERIALNO":"12345","NAME":"KITTY","TITLE":"TYPIST","SALARY":3000.450000},{"SERIALNO":"33333","NAME":"MONAPENNY","TITLE":"SECRETARY","SALARY":3800.000000},{"SERIALNO":"00023","NAME":"MARTIN","TITLE":"ENGINEER","SALARY":10000.000000},{"SERIALNO":"07654","NAME":"FUNNIGUY","TITLE":"ADMINISTRATOR","SALARY":8500.000000},{"SERIALNO":"45678","NAME":"BUGHAPPY","TITLE":"PROGRAMMER","SALARY":8500.000000},{"SERIALNO":"56789","NAME":"FODDERMAN","TITLE":"SALESMAN","SALARY":7000.000000},{"SERIALNO":"55555","NAME":"MESSIFUL","TITLE":"SECRETARY","SALARY":5000.500000},{"SERIALNO":"98765","NAME":"GOOSEPEN","TITLE":"ADMINISTRATOR","SALARY":4700.000000}]}
{"DEPARTMENT":"2452","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","TITLE":"SCIENTIST","SALARY":8000.000000},{"SERIALNO":"31416","NAME":"ORELLY","TITLE":"ENGINEER","SALARY":13400.000000},{"SERIALNO":"36666","NAME":"BIGHORN","TITLE":"SCIENTIST","SALARY":11000.000000},{"SERIALNO":"02345","NAME":"SMITH","TITLE":"ENGINEER","SALARY":9000.000000},{"SERIALNO":"11111","NAME":"CHERRY","TITLE":"SECRETARY","SALARY":4500.000000}]} {"DEPARTMENT":"2452","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","TITLE":"SCIENTIST","SALARY":8000.000000},{"SERIALNO":"31416","NAME":"ORELLY","TITLE":"ENGINEER","SALARY":13400.000000},{"SERIALNO":"36666","NAME":"BIGHORN","TITLE":"SCIENTIST","SALARY":11000.000000},{"SERIALNO":"02345","NAME":"SMITH","TITLE":"ENGINEER","SALARY":9000.000000},{"SERIALNO":"11111","NAME":"CHERRY","TITLE":"SECRETARY","SALARY":4500.000000}]}
SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t1 GROUP BY DEPARTMENT, TITLE; SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT, TITLE;
Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES)
{"DEPARTMENT":"0021","TITLE":"DIRECTOR","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","SALARY":23000.000000}]} {"DEPARTMENT":"0021","TITLE":"DIRECTOR","EMPLOYES":[{"SERIALNO":"87777","NAME":"STRONG","SALARY":23000.000000}]}
{"DEPARTMENT":"0021","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"22222","NAME":"SHORTSIGHT","SALARY":5500.000000}]} {"DEPARTMENT":"0021","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"22222","NAME":"SHORTSIGHT","SALARY":5500.000000}]}
@@ -143,25 +226,372 @@ Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY
{"DEPARTMENT":"2452","TITLE":"ENGINEER","EMPLOYES":[{"SERIALNO":"31416","NAME":"ORELLY","SALARY":13400.000000},{"SERIALNO":"02345","NAME":"SMITH","SALARY":9000.000000}]} {"DEPARTMENT":"2452","TITLE":"ENGINEER","EMPLOYES":[{"SERIALNO":"31416","NAME":"ORELLY","SALARY":13400.000000},{"SERIALNO":"02345","NAME":"SMITH","SALARY":9000.000000}]}
{"DEPARTMENT":"2452","TITLE":"SCIENTIST","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","SALARY":8000.000000},{"SERIALNO":"36666","NAME":"BIGHORN","SALARY":11000.000000}]} {"DEPARTMENT":"2452","TITLE":"SCIENTIST","EMPLOYES":[{"SERIALNO":"34567","NAME":"BIGHEAD","SALARY":8000.000000},{"SERIALNO":"36666","NAME":"BIGHORN","SALARY":11000.000000}]}
{"DEPARTMENT":"2452","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"11111","NAME":"CHERRY","SALARY":4500.000000}]} {"DEPARTMENT":"2452","TITLE":"SECRETARY","EMPLOYES":[{"SERIALNO":"11111","NAME":"CHERRY","SALARY":4500.000000}]}
SELECT Json_Object_Grp(SALARY) FROM t1; SELECT Json_Object_Grp(SALARY) FROM t3;
ERROR HY000: Can't initialize function 'Json_Object_Grp'; Json_Array_Grp can only accept 2 arguments ERROR HY000: Can't initialize function 'json_object_grp'; This function requires 2 arguments (value, key)
SELECT Json_Object_Grp(SALARY, NAME) FROM t1; SELECT Json_Object_Grp(SALARY, NAME) FROM t3;
Json_Object_Grp(SALARY, NAME) Json_Object_Grp(SALARY, NAME)
{"BANCROFT":9600.000000,"SMITH":9000.000000,"MERCHANT":8700.000000,"FUNNIGUY":8500.000000,"BUGHAPPY":8500.000000,"BIGHEAD":8000.000000,"SHRINKY":7500.000000,"WALTER":7400.000000,"FODDERMAN":7000.000000,"TONGHO":6800.000000,"SHORTSIGHT":5500.000000,"MESSIFUL":5000.500000,"HONEY":4900.000000,"GOOSEPEN":4700.000000,"CHERRY":4500.000000,"MONAPENNY":3800.000000,"KITTY":3000.450000,"PLUMHEAD":2800.000000,"STRONG":23000.000000,"BULLOZER":14800.000000,"WERTHER":14500.000000,"QUINN":14000.000000,"ORELLY":13400.000000,"BIGHORN":11000.000000,"BROWNY":10500.000000,"WHEELFOR":10030.000000,"MARTIN":10000.000000} {"BANCROFT":9600.000000,"SMITH":9000.000000,"MERCHANT":8700.000000,"FUNNIGUY":8500.000000,"BUGHAPPY":8500.000000,"BIGHEAD":8000.000000,"SHRINKY":7500.000000,"WALTER":7400.000000,"FODDERMAN":7000.000000,"TONGHO":6800.000000,"SHORTSIGHT":5500.000000,"MESSIFUL":5000.500000,"HONEY":4900.000000,"GOOSEPEN":4700.000000,"CHERRY":4500.000000,"MONAPENNY":3800.000000,"KITTY":3000.450000,"PLUMHEAD":2800.000000,"STRONG":23000.000000,"BULLOZER":14800.000000,"WERTHER":14500.000000,"QUINN":14000.000000,"ORELLY":13400.000000,"BIGHORN":11000.000000,"BROWNY":10500.000000,"WHEELFOR":10030.000000,"MARTIN":10000.000000}
SELECT Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES") FROM t1 GROUP BY DEPARTMENT; SELECT Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES") FROM t3 GROUP BY DEPARTMENT;
Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES") Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES")
{"DEPARTMENT":"0021","SALARIES":{"STRONG":23000.000000,"SHORTSIGHT":5500.000000}} {"DEPARTMENT":"0021","SALARIES":{"STRONG":23000.000000,"SHORTSIGHT":5500.000000}}
{"DEPARTMENT":"0318","SALARIES":{"BANCROFT":9600.000000,"PLUMHEAD":2800.000000,"HONEY":4900.000000,"TONGHO":6800.000000,"WALTER":7400.000000,"SHRINKY":7500.000000,"WERTHER":14500.000000,"MERCHANT":8700.000000,"WHEELFOR":10030.000000}} {"DEPARTMENT":"0318","SALARIES":{"BANCROFT":9600.000000,"PLUMHEAD":2800.000000,"HONEY":4900.000000,"TONGHO":6800.000000,"WALTER":7400.000000,"SHRINKY":7500.000000,"WERTHER":14500.000000,"MERCHANT":8700.000000,"WHEELFOR":10030.000000}}
{"DEPARTMENT":"0319","SALARIES":{"BULLOZER":14800.000000,"QUINN":14000.000000,"BROWNY":10500.000000,"KITTY":3000.450000,"MONAPENNY":3800.000000,"MARTIN":10000.000000,"FUNNIGUY":8500.000000,"BUGHAPPY":8500.000000,"FODDERMAN":7000.000000,"MESSIFUL":5000.500000,"GOOSEPEN":4700.000000}} {"DEPARTMENT":"0319","SALARIES":{"BULLOZER":14800.000000,"QUINN":14000.000000,"BROWNY":10500.000000,"KITTY":3000.450000,"MONAPENNY":3800.000000,"MARTIN":10000.000000,"FUNNIGUY":8500.000000,"BUGHAPPY":8500.000000,"FODDERMAN":7000.000000,"MESSIFUL":5000.500000,"GOOSEPEN":4700.000000}}
{"DEPARTMENT":"2452","SALARIES":{"BIGHEAD":8000.000000,"ORELLY":13400.000000,"BIGHORN":11000.000000,"SMITH":9000.000000,"CHERRY":4500.000000}} {"DEPARTMENT":"2452","SALARIES":{"BIGHEAD":8000.000000,"ORELLY":13400.000000,"BIGHORN":11000.000000,"SMITH":9000.000000,"CHERRY":4500.000000}}
SELECT Json_Array_Grp(NAME) from t1; SELECT Json_Array_Grp(NAME) FROM t3;
Json_Array_Grp(NAME) Json_Array_Grp(NAME)
["BANCROFT","SMITH","MERCHANT","FUNNIGUY","BUGHAPPY","BIGHEAD","SHRINKY","WALTER","FODDERMAN","TONGHO","SHORTSIGHT","MESSIFUL","HONEY","GOOSEPEN","CHERRY","MONAPENNY","KITTY","PLUMHEAD","STRONG","BULLOZER","WERTHER","QUINN","ORELLY","BIGHORN","BROWNY","WHEELFOR","MARTIN"] ["BANCROFT","SMITH","MERCHANT","FUNNIGUY","BUGHAPPY","BIGHEAD","SHRINKY","WALTER","FODDERMAN","TONGHO","SHORTSIGHT","MESSIFUL","HONEY","GOOSEPEN","CHERRY","MONAPENNY","KITTY","PLUMHEAD","STRONG","BULLOZER","WERTHER","QUINN","ORELLY","BIGHORN","BROWNY","WHEELFOR","MARTIN"]
#
# Test value getting UDF's
#
SELECT JsonGet_String(Json_Array_Grp(name),'[#]') FROM t3;
JsonGet_String(Json_Array_Grp(name),'[#]')
27
SELECT JsonGet_String(Json_Array_Grp(name),'[","]') FROM t3;
JsonGet_String(Json_Array_Grp(name),'[","]')
BANCROFT,SMITH,MERCHANT,FUNNIGUY,BUGHAPPY,BIGHEAD,SHRINKY,WALTER,FODDERMAN,TONGHO,SHORTSIGHT,MESSIFUL,HONEY,GOOSEPEN,CHERRY,MONAPENNY,KITTY,PLUMHEAD,STRONG,BULLOZER,WERTHER,QUINN,ORELLY,BIGHORN,BROWNY,WHEELFOR,MARTIN
SELECT JsonGet_String(Json_Array_Grp(name),'[>]') FROM t3;
JsonGet_String(Json_Array_Grp(name),'[>]')
WHEELFOR
SET @j1 = '[45,28,36,45,89]';
SELECT JsonGet_String(@j1,'[1]');
JsonGet_String(@j1,'[1]')
28
SELECT JsonGet_String(@j1 json_,'[3]');
JsonGet_String(@j1 json_,'[3]')
45
SELECT JsonGet_String(Json_Array(45,28,36,45,89),'[3]');
JsonGet_String(Json_Array(45,28,36,45,89),'[3]')
45
SELECT JsonGet_String(Json_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",JsonGet_String(Json_Array(45,28,36,45,89),'[+]') "sum";
list egal sum
45+28+36+45+89 = 243.00
SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]')
36
SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:*');
JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:*')
[36,45,89]
SELECT JsonGet_String(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc');
JsonGet_String(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc')
machin
SET @j2 = '{"qty":56,"price":3.141600,"truc":"machin","garanty":null}';
SELECT JsonGet_String(@j2 json_,'truc');
JsonGet_String(@j2 json_,'truc')
machin
SELECT JsonGet_String(@j2,'truc');
JsonGet_String(@j2,'truc')
machin
SELECT JsonGet_String(@j2,'chose');
JsonGet_String(@j2,'chose')
NULL
SELECT JsonGet_String(NULL json_, NULL);
JsonGet_String(NULL json_, NULL)
NULL
Warnings:
Warning 1105
SELECT department, JsonGet_String(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal
0021 28500.00
0318 72230.00
0319 89800.95
2452 45900.00
SELECT JsonGet_Int(@j1, '[4]');
JsonGet_Int(@j1, '[4]')
89
SELECT JsonGet_Int(@j1, '[#]');
JsonGet_Int(@j1, '[#]')
5
SELECT JsonGet_Int(@j1, '[+]');
JsonGet_Int(@j1, '[+]')
243
SELECT JsonGet_Int(@j1 json_,'[3]');
JsonGet_Int(@j1 json_,'[3]')
45
SELECT JsonGet_Int(Json_Array(45,28,36,45,89),'[3]');
JsonGet_Int(Json_Array(45,28,36,45,89),'[3]')
45
SELECT JsonGet_Int(Json_Array(45,28,36,45,89),'["+"]');
JsonGet_Int(Json_Array(45,28,36,45,89),'["+"]')
45
SELECT JsonGet_Int(Json_Array(45,28,36,45,89),'[+]');
JsonGet_Int(Json_Array(45,28,36,45,89),'[+]')
243
SELECT JsonGet_Int(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
JsonGet_Int(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]')
36
SELECT JsonGet_Int(Json_Array(json_array(45,28),json_array(36,45,89)),'[0]:[1]');
JsonGet_Int(Json_Array(json_array(45,28),json_array(36,45,89)),'[0]:[1]')
28
SELECT JsonGet_Int(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'qty');
JsonGet_Int(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'qty')
56
SELECT JsonGet_Int(@j2 json_,'price');
JsonGet_Int(@j2 json_,'price')
3
SELECT JsonGet_Int(@j2,'qty');
JsonGet_Int(@j2,'qty')
56
SELECT JsonGet_Int('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','chose');
JsonGet_Int('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','chose')
NULL
Warnings:
Warning 1105 Value not found
SELECT JsonGet_Int(JsonGet_String(Json_Array(Json_Array(45,28),Json_Array(36,45,89)),'[1]:*'),'[+]') sum;
sum
170
SELECT department, JsonGet_Int(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal
0021 28500
0318 72230
0319 89800
2452 45900
SELECT JsonGet_Real(@j1, '[2]');
JsonGet_Real(@j1, '[2]')
36.000000000000000
SELECT JsonGet_Real(@j1 json_,'[3]',2);
JsonGet_Real(@j1 json_,'[3]',2)
45.00
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'[3]');
JsonGet_Real(Json_Array(45,28,36,45,89),'[3]')
45.000000000000000
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'["+"]');
JsonGet_Real(Json_Array(45,28,36,45,89),'["+"]')
45.000000000000000
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'[+]');
JsonGet_Real(Json_Array(45,28,36,45,89),'[+]')
243.000000000000000
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'[!]');
JsonGet_Real(Json_Array(45,28,36,45,89),'[!]')
48.600000000000000
SELECT JsonGet_Real(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
JsonGet_Real(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]')
36.000000000000000
SELECT JsonGet_Real(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'price');
JsonGet_Real(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'price')
3.141600000000000
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}' json_,'qty');
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}' json_,'qty')
56.000000000000000
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','price');
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','price')
3.141600000000000
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','price', 4);
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','price', 4)
3.1416
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','chose');
JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','chose')
NULL
Warnings:
Warning 1105 Value not found
SELECT department, JsonGet_Real(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
department Sumsal
0021 28500.000000000000000
0318 72230.000000000000000
0319 89800.950000000000000
2452 45900.000000000000000
#
# Documentation examples
#
SELECT
JsonGet_Int(Json_Array(45,28,36,45,89), '[4]') "Rank",
JsonGet_Int(Json_Array(45,28,36,45,89), '[#]') "Number",
JsonGet_String(Json_Array(45,28,36,45,89), '[","]') "Concat",
JsonGet_Int(Json_Array(45,28,36,45,89), '[+]') "Sum",
JsonGet_Real(Json_Array(45,28,36,45,89), '[!]', 2) "Avg";
Rank Number Concat Sum Avg
89 5 45,28,36,45,89 243 48.60
SELECT
JsonGet_String('{"qty":7,"price":29.50,"garanty":null}','price') "String",
JsonGet_Int('{"qty":7,"price":29.50,"garanty":null}','price') "Int",
JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}','price') "Real";
String Int Real
29.50 29 29.500000000000000
SELECT JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}','price',3) "Real";
Real
29.500
#
# Testing Locate
#
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin');
JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin')
truc
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56);
JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56)
qty
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416);
JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416)
price
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose');
JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose')
NULL
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'Jack') Path;
Path
AUTHORS:[1]:FN
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'jack' ci) Path;
Path
AUTHORS:[1]:FN
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"Jack", "LN":"London"}' json_) Path;
Path
AUTHORS:[1]
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"jack", "LN":"London"}' json_) Path;
Path
NULL
SELECT JsonLocate('[45,28,36,45,89]',36);
JsonLocate('[45,28,36,45,89]',36)
[2]
SELECT JsonLocate('[45,28,36,45,89]' json_,28.0);
JsonLocate('[45,28,36,45,89]' json_,28.0)
NULL
SELECT Json_Locate_All('[45,28,36,45,89]',10);
Json_Locate_All('[45,28,36,45,89]',10)
[]
SELECT Json_Locate_All('[45,28,36,45,89]',45);
Json_Locate_All('[45,28,36,45,89]',45)
["[0]","[3]"]
SELECT Json_Locate_All('[[45,28],36,45,89]',45);
Json_Locate_All('[[45,28],36,45,89]',45)
["[0]:[0]","[2]"]
SELECT Json_Locate_All('[[45,28,45],36,45,89]',45);
Json_Locate_All('[[45,28,45],36,45,89]',45)
["[0]:[0]","[0]:[2]","[2]"]
SELECT Json_Locate_All('[[45,28,45],36,45,89]',JsonGet_Int('[3,45]','[1]'));
Json_Locate_All('[[45,28,45],36,45,89]',JsonGet_Int('[3,45]','[1]'))
["[0]:[0]","[0]:[2]","[2]"]
SELECT JsonLocate('[[45,28,45],36,45,89]',45,n) from t1;
JsonLocate('[[45,28,45],36,45,89]',45,n)
[0]:[0]
[0]:[2]
[2]
NULL
NULL
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) FROM t1;
JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']'))
[0]:[0]
[0]:[2]
[2]
NULL
NULL
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) AS `Path` FROM t1 GROUP BY n HAVING `Path` IS NOT NULL;
Path
[0]:[0]
[0]:[2]
[2]
SELECT Json_Locate_All('[45,28,[36,45,89]]',45);
Json_Locate_All('[45,28,[36,45,89]]',45)
["[0]","[2]:[1]"]
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',JsonValue(45.0));
Json_Locate_All('[[45,28],[36,45.0,89]]',JsonValue(45.0))
[]
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',45.0);
Json_Locate_All('[[45,28],[36,45.0,89]]',45.0)
["[1]:[1]"]
SELECT JsonLocate('[[45,28],[36,45,89]]','[36,45,89]' json_);
JsonLocate('[[45,28],[36,45,89]]','[36,45,89]' json_)
[1]
SELECT JsonLocate('[[45,28],[36,45,89]]','[45,28]' json_);
JsonLocate('[[45,28],[36,45,89]]','[45,28]' json_)
[0]
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','45') "All paths";
All paths
[]
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','[36,45]' json_);
Json_Locate_All('[[45,28],[[36,45],89]]','[36,45]' json_)
["[1]:[0]"]
SELECT JsonGet_Int(Json_Locate_All('[[45,28],[[36,45],89]]',45), '[#]') "Nb of occurs";
Nb of occurs
2
SELECT Json_Locate_All('[[45,28],[[36,45],89]]',45,2);
Json_Locate_All('[[45,28],[[36,45],89]]',45,2)
["[0]:[0]"]
SELECT JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'[0]');
JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'[0]')
[0]
SELECT JsonLocate(Json_File('test/biblio.json'), 'Knab');
JsonLocate(Json_File('test/biblio.json'), 'Knab')
[0]:AUTHOR:[1]:LASTNAME
SELECT Json_Locate_All('test/biblio.json' jfile_, 'Knab');
Json_Locate_All('test/biblio.json' jfile_, 'Knab')
["[0]:AUTHOR:[1]:LASTNAME"]
#
# Testing json files
#
select Jfile_Make('[{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},
{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},
{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}]', 'test/fx.json', 0) AS NewFile;
NewFile
test/fx.json
SELECT Jfile_Make('test/fx.json', 1);
Jfile_Make('test/fx.json', 1)
test/fx.json
SELECT Jfile_Make('test/fx.json' jfile_);
Jfile_Make('test/fx.json' jfile_)
test/fx.json
SELECT Jfile_Make(Jbin_File('test/fx.json'), 0);
Jfile_Make(Jbin_File('test/fx.json'), 0)
test/fx.json
SELECT Json_File('test/fx.json', 1);
Json_File('test/fx.json', 1)
[{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}]
Warnings:
Warning 1105 File pretty format doesn't match the specified pretty value
SELECT Json_File('test/fx.json', 2);
Json_File('test/fx.json', 2)
[{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}]
Warnings:
Warning 1105 File pretty format doesn't match the specified pretty value
SELECT Json_File('test/fx.json', 0);
Json_File('test/fx.json', 0)
[{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}]
SELECT Json_File('test/fx.json', '[0]');
Json_File('test/fx.json', '[0]')
{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]}
SELECT Json_File('test/fx.json', '[?]');
Json_File('test/fx.json', '[?]')
NULL
Warnings:
Warning 1105 Invalid function specification ?
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]:*');
JsonGet_String(Json_File('test/fx.json'), '[1]:*')
{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]}
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]');
JsonGet_String(Json_File('test/fx.json'), '[1]')
6 car roadster 56000 ???
SELECT JsonGet_Int(Json_File('test/fx.json'), '[1]:mileage') AS Mileage;
Mileage
56000
SELECT JsonGet_Real(Json_File('test/fx.json'), '[0]:price', 2) AS Price;
Price
5.65
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings');
Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings')
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4,6]}
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 1, 'ratings');
Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 1, 'ratings')
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,6,4]}
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings', 1);
Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings', 1)
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,6,4]}
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]:ratings'), 6, 0);
Json_Array_Add(Json_File('test/fx.json', '[2]:ratings'), 6, 0)
[6,2,4]
SELECT Json_Array_Delete(Json_File('test/fx.json', '[2]'), 'ratings', 1);
Json_Array_Delete(Json_File('test/fx.json', '[2]'), 'ratings', 1)
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2]}
SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 'france' origin);
Json_Object_Add(Json_File('test/fx.json', '[2]'), 'france' origin)
{"_id":7,"type":"food","item":"meat","origin":"france","ratings":[2,4]}
SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 70 H, 'size');
Json_Object_Add(Json_File('test/fx.json', '[2]'), 70 H, 'size')
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]}
Warnings:
Warning 1105 No sub-item at 'size'
SELECT Json_Object_Add(Json_File('test/fx.json', '[3]'), 70 H, 'size');
Json_Object_Add(Json_File('test/fx.json', '[3]'), 70 H, 'size')
{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":70},"ratings":[5,8,7]}
SELECT Json_Object_List(Json_File('test/fx.json', '[3]:size'));
Json_Object_List(Json_File('test/fx.json', '[3]:size'))
["W","L","H"]
DROP TABLE t1; DROP TABLE t1;
DROP FUNCTION Json_Array; DROP TABLE t2;
DROP FUNCTION Json_Array_Add; DROP TABLE t3;
DROP FUNCTION Json_Object;
DROP FUNCTION Json_Object_Nonull;
DROP FUNCTION Json_Value;
DROP FUNCTION Json_Array_Grp;
DROP FUNCTION Json_Object_Grp;

View File

@@ -0,0 +1,100 @@
SET NAMES utf8;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='Bad connection string';
ERROR HY000: SQLDriverConnect: [unixODBC][Driver Manager]Data source name not found, and no default driver specified
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Sources;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`Name` varchar(256) NOT NULL,
`Description` varchar(256) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Sources'
SELECT * FROM t1;
Name Description
Firebird Firebird
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Drivers;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`Description` char(128) NOT NULL,
`Attributes` varchar(256) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers'
SELECT * FROM t1;
Description Attributes
Firebird Description=Firebird ODBC Driver in usr;Driver=/usr/local/lib/libOdbcFb.so;Setup=/usr/local/lib/libOdbcFb.so;FileUsage=1;
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Tables CONNECTION='Not important';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`Table_Cat` char(128) NOT NULL,
`Table_Schema` char(128) NOT NULL,
`Table_Name` char(128) NOT NULL,
`Table_Type` char(16) NOT NULL,
`Remark` char(255) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='Not important' `TABLE_TYPE`='ODBC' `CATFUNC`='Tables'
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Columns CONNECTION='Not important';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`Table_Cat` char(128) NOT NULL,
`Table_Schema` char(128) NOT NULL,
`Table_Name` char(128) NOT NULL,
`Column_Name` char(128) NOT NULL,
`Data_Type` smallint(6) NOT NULL,
`Type_Name` char(30) NOT NULL,
`Column_Size` int(10) NOT NULL,
`Buffer_Length` int(10) NOT NULL,
`Decimal_Digits` smallint(6) NOT NULL,
`Radix` smallint(6) NOT NULL,
`Nullable` smallint(6) NOT NULL,
`Remarks` char(255) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='Not important' `TABLE_TYPE`='ODBC' `CATFUNC`='Columns'
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC TABNAME='EMPLOYEE' CONNECTION='DSN=Firebird;UID=SYSDBA;PWD=manager';
SELECT * FROM t1;
EMP_NO FIRST_NAME LAST_NAME PHONE_EXT HIRE_DATE DEPT_NO JOB_CODE JOB_GRADE JOB_COUNTRY SALARY FULL_NAME
2 Robert Nelson 250 1988-12-28 00:00:00 600 VP 2 USA 105900.00 Nelson, Robert
4 Bruce Young 233 1988-12-28 00:00:00 621 Eng 2 USA 97500.00 Young, Bruce
5 Kim Lambert 22 1989-02-06 00:00:00 130 Eng 2 USA 102750.00 Lambert, Kim
8 Leslie Johnson 410 1989-04-05 00:00:00 180 Mktg 3 USA 64635.00 Johnson, Leslie
9 Phil Forest 229 1989-04-17 00:00:00 622 Mngr 3 USA 75060.00 Forest, Phil
11 K. J. Weston 34 1990-01-17 00:00:00 130 SRep 4 USA 86292.94 Weston, K. J.
12 Terri Lee 256 1990-05-01 00:00:00 000 Admin 4 USA 53793.00 Lee, Terri
14 Stewart Hall 227 1990-06-04 00:00:00 900 Finan 3 USA 69482.63 Hall, Stewart
15 Katherine Young 231 1990-06-14 00:00:00 623 Mngr 3 USA 67241.25 Young, Katherine
20 Chris Papadopoulos 887 1990-01-01 00:00:00 671 Mngr 3 USA 89655.00 Papadopoulos, Chris
24 Pete Fisher 888 1990-09-12 00:00:00 671 Eng 3 USA 81810.19 Fisher, Pete
28 Ann Bennet 5 1991-02-01 00:00:00 120 Admin 5 England 22935.00 Bennet, Ann
29 Roger De Souza 288 1991-02-18 00:00:00 623 Eng 3 USA 69482.63 De Souza, Roger
34 Janet Baldwin 2 1991-03-21 00:00:00 110 Sales 3 USA 61637.81 Baldwin, Janet
36 Roger Reeves 6 1991-04-25 00:00:00 120 Sales 3 England 33620.63 Reeves, Roger
37 Willie Stansbury 7 1991-04-25 00:00:00 120 Eng 4 England 39224.06 Stansbury, Willie
44 Leslie Phong 216 1991-06-03 00:00:00 623 Eng 4 USA 56034.38 Phong, Leslie
45 Ashok Ramanathan 209 1991-08-01 00:00:00 621 Eng 3 USA 80689.50 Ramanathan, Ashok
46 Walter Steadman 210 1991-08-09 00:00:00 900 CFO 1 USA 116100.00 Steadman, Walter
52 Carol Nordstrom 420 1991-10-02 00:00:00 180 PRel 4 USA 42742.50 Nordstrom, Carol
61 Luke Leung 3 1992-02-18 00:00:00 110 SRep 4 USA 68805.00 Leung, Luke
65 Sue Anne O'Brien 877 1992-03-23 00:00:00 670 Admin 5 USA 31275.00 O'Brien, Sue Anne
71 Jennifer M. Burbank 289 1992-04-15 00:00:00 622 Eng 3 USA 53167.50 Burbank, Jennifer M.
72 Claudia Sutherland NULL 1992-04-20 00:00:00 140 SRep 4 Canada 100914.00 Sutherland, Claudia
83 Dana Bishop 290 1992-06-01 00:00:00 621 Eng 3 USA 62550.00 Bishop, Dana
85 Mary S. MacDonald 477 1992-06-01 00:00:00 100 VP 2 USA 111262.50 MacDonald, Mary S.
94 Randy Williams 892 1992-08-08 00:00:00 672 Mngr 4 USA 56295.00 Williams, Randy
105 Oliver H. Bender 255 1992-10-08 00:00:00 000 CEO 1 USA 212850.00 Bender, Oliver H.
107 Kevin Cook 894 1993-02-01 00:00:00 670 Dir 2 USA 111262.50 Cook, Kevin
109 Kelly Brown 202 1993-02-04 00:00:00 600 Admin 5 USA 27000.00 Brown, Kelly
110 Yuki Ichida 22 1993-02-04 00:00:00 115 Eng 3 Japan 6000000.00 Ichida, Yuki
113 Mary Page 845 1993-04-12 00:00:00 671 Eng 4 USA 48000.00 Page, Mary
114 Bill Parker 247 1993-06-01 00:00:00 623 Eng 5 USA 35000.00 Parker, Bill
118 Takashi Yamamoto 23 1993-07-01 00:00:00 115 SRep 4 Japan 7480000.00 Yamamoto, Takashi
121 Roberto Ferrari 1 1993-07-12 00:00:00 125 SRep 4 Italy 99000000.00 Ferrari, Roberto
127 Michael Yanowski 492 1993-08-09 00:00:00 100 SRep 4 USA 44000.00 Yanowski, Michael
134 Jacques Glon NULL 1993-08-23 00:00:00 123 SRep 4 France 390500.00 Glon, Jacques
136 Scott Johnson 265 1993-09-13 00:00:00 623 Doc 3 USA 60000.00 Johnson, Scott
138 T.J. Green 218 1993-11-01 00:00:00 621 Eng 4 USA 36000.00 Green, T.J.
141 Pierre Osborne NULL 1994-01-03 00:00:00 121 SRep 4 Switzerland 110000.00 Osborne, Pierre
144 John Montgomery 820 1994-03-30 00:00:00 672 Eng 5 USA 35000.00 Montgomery, John
145 Mark Guckenheimer 221 1994-05-02 00:00:00 622 Eng 5 USA 32000.00 Guckenheimer, Mark
DROP TABLE t1;

View File

@@ -0,0 +1,2 @@
{"ISBN":"9782212090819","LANG":"fr","SUBJECT":"applications","AUTHOR":[{"FIRSTNAME":"Jean-Michel","LASTNAME":"Bernadac"},{"FIRSTNAME":"Fran<61>ois","LASTNAME":"Knab"}],"TITLE":"Construire une application XML","PUBLISHER":{"NAME":"Eyrolles","PLACE":"Paris"},"DATEPUB":1999}
{"ISBN":"9782840825685","LANG":"fr","SUBJECT":"applications","AUTHOR":[{"FIRSTNAME":"William J.","LASTNAME":"Pardi"}],"TITLE":"XML en Action","TRANSLATED":{"PREFIX":"adapt<70> de l'anglais par","TRANSLATOR":{"FIRSTNAME":"James","LASTNAME":"Guerin"}},"PUBLISHER":{"NAME":"Microsoft Press","PLACE":"Paris"},"DATEPUB":2001}

View File

@@ -24,12 +24,10 @@
"ISBN": "9782840825685", "ISBN": "9782840825685",
"LANG": "fr", "LANG": "fr",
"SUBJECT": "applications", "SUBJECT": "applications",
"AUTHOR": [ "AUTHOR": {
{ "FIRSTNAME": "William J.",
"FIRSTNAME": "William J.", "LASTNAME": "Pardi"
"LASTNAME": "Pardi" },
}
],
"TITLE": "XML en Action", "TITLE": "XML en Action",
"TRANSLATION": "adapt<70> de l'anglais par", "TRANSLATION": "adapt<70> de l'anglais par",
"TRANSLATOR": { "TRANSLATOR": {

View File

@@ -14,3 +14,15 @@ SELECT id, DAYNAME(dat) FROM t1;
SELECT id, DAYNAME(datim) FROM t1 LIMIT 1; SELECT id, DAYNAME(datim) FROM t1 LIMIT 1;
SELECT id, TIME(tim) FROM t1 LIMIT 1; SELECT id, TIME(tim) FROM t1 LIMIT 1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Testing use of dates in where clause (MDEV-8926)
--echo #
CREATE TABLE t1 (col1 DATE) ENGINE=CONNECT TABLE_TYPE=CSV;
INSERT INTO t1 VALUES('2015-01-01'),('2015-02-01'),('2015-03-01'),('2015-04-01');
SELECT * FROM t1 WHERE col1 = '2015-02-01';
SELECT * FROM t1 WHERE col1 > '2015-02-01';
SELECT * FROM t1 WHERE col1 >= '2015-02-01';
SELECT * FROM t1 WHERE col1 < '2015-02-01';
SELECT * FROM t1 WHERE col1 <= '2015-02-01';
DROP TABLE t1;

View File

@@ -4,6 +4,7 @@
let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/biblio.json $MYSQLD_DATADIR/test/biblio.json --copy_file $MTR_SUITE_DIR/std_data/biblio.json $MYSQLD_DATADIR/test/biblio.json
--copy_file $MTR_SUITE_DIR/std_data/bib0.json $MYSQLD_DATADIR/test/bib0.json
--copy_file $MTR_SUITE_DIR/std_data/expense.json $MYSQLD_DATADIR/test/expense.json --copy_file $MTR_SUITE_DIR/std_data/expense.json $MYSQLD_DATADIR/test/expense.json
--copy_file $MTR_SUITE_DIR/std_data/mulexp3.json $MYSQLD_DATADIR/test/mulexp3.json --copy_file $MTR_SUITE_DIR/std_data/mulexp3.json $MYSQLD_DATADIR/test/mulexp3.json
--copy_file $MTR_SUITE_DIR/std_data/mulexp4.json $MYSQLD_DATADIR/test/mulexp4.json --copy_file $MTR_SUITE_DIR/std_data/mulexp4.json $MYSQLD_DATADIR/test/mulexp4.json
@@ -115,6 +116,33 @@ ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='biblio.json';
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Testing a pretty=0 file
--echo #
CREATE TABLE t1
(
ISBN CHAR(15) NOT NULL,
Language CHAR(2) FIELD_FORMAT='LANG',
Subject CHAR(32) FIELD_FORMAT='SUBJECT',
AuthorFN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:FIRSTNAME',
AuthorLN CHAR(128) FIELD_FORMAT='AUTHOR:[X]:LASTNAME',
Title CHAR(32) FIELD_FORMAT='TITLE',
Translation CHAR(32) FIELD_FORMAT='TRANSLATED:PREFIX',
TranslatorFN CHAR(80) FIELD_FORMAT='TRANSLATED:TRANSLATOR:FIRSTNAME',
TranslatorLN CHAR(80) FIELD_FORMAT='TRANSLATED:TRANSLATOR:LASTNAME',
Publisher CHAR(20) FIELD_FORMAT='PUBLISHER:NAME',
Location CHAR(16) FIELD_FORMAT='PUBLISHER:PLACE',
Year int(4) FIELD_FORMAT='DATEPUB',
INDEX IX(ISBN)
)
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bib0.json' LRECL=350 OPTION_LIST='Pretty=0';
SHOW INDEX FROM t1;
SELECT * FROM t1;
DESCRIBE SELECT * FROM t1 WHERE ISBN = '9782212090819';
--error ER_GET_ERRMSG
UPDATE t1 SET AuthorFN = 'Philippe' WHERE ISBN = '9782212090819';
DROP TABLE t1;
--echo # --echo #
--echo # A file with 2 arrays --echo # A file with 2 arrays
--echo # --echo #
@@ -258,6 +286,8 @@ DROP TABLE t1, t2, t3, t4;
# Clean up # Clean up
# #
--remove_file $MYSQLD_DATADIR/test/biblio.json --remove_file $MYSQLD_DATADIR/test/biblio.json
--remove_file $MYSQLD_DATADIR/test/bib0.dnx
--remove_file $MYSQLD_DATADIR/test/bib0.json
--remove_file $MYSQLD_DATADIR/test/expense.json --remove_file $MYSQLD_DATADIR/test/expense.json
--remove_file $MYSQLD_DATADIR/test/mulexp3.json --remove_file $MYSQLD_DATADIR/test/mulexp3.json
--remove_file $MYSQLD_DATADIR/test/mulexp4.json --remove_file $MYSQLD_DATADIR/test/mulexp4.json

View File

@@ -9,28 +9,40 @@ if (!$HA_CONNECT_SO) {
--skip Needs a dynamically built ha_connect.so --skip Needs a dynamically built ha_connect.so
} }
let $is_win = `select convert(@@version_compile_os using latin1) IN ("Win32","Win64","Windows")`; CREATE FUNCTION json_array RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_array_add RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_array_add_values RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_array_delete RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_object RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_object_nonull RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_object_add RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_object_delete RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_object_list RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jsonvalue RETURNS STRING SONAME 'ha_connect';
CREATE AGGREGATE FUNCTION json_array_grp RETURNS STRING SONAME 'ha_connect';
CREATE AGGREGATE FUNCTION json_object_grp RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_item_merge RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_get_item RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jsonget_string RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jsonget_int RETURNS INTEGER SONAME 'ha_connect';
CREATE FUNCTION jsonget_real RETURNS REAL SONAME 'ha_connect';
CREATE FUNCTION jsonlocate RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_locate_all RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_file RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jfile_make RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION json_serialize RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_array RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_array_add_values RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_array_add RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_array_delete RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_object RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_object_nonull RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_object_add RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_object_delete RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_object_list RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_get_item RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_item_merge RETURNS STRING SONAME 'ha_connect';
CREATE FUNCTION jbin_file RETURNS STRING SONAME 'ha_connect';
if ($is_win)
{
--eval CREATE FUNCTION Json_Array RETURNS STRING SONAME 'ha_connect.dll';
--eval CREATE FUNCTION Json_Array_Add RETURNS STRING SONAME 'ha_connect.dll';
--eval CREATE FUNCTION Json_Object RETURNS STRING SONAME 'ha_connect.dll';
--eval CREATE FUNCTION Json_Object_Nonull RETURNS STRING SONAME 'ha_connect.dll';
--eval CREATE FUNCTION Json_Value returns STRING SONAME 'ha_connect.dll';
--eval CREATE AGGREGATE FUNCTION Json_Array_Grp RETURNS STRING SONAME 'ha_connect.dll';
--eval CREATE AGGREGATE FUNCTION Json_Object_Grp RETURNS STRING SONAME 'ha_connect.dll';
}
if (!$is_win)
{
--eval CREATE FUNCTION Json_Array RETURNS STRING SONAME 'ha_connect.so';
--eval CREATE FUNCTION Json_Array_Add RETURNS STRING SONAME 'ha_connect.so';
--eval CREATE FUNCTION Json_Object RETURNS STRING SONAME 'ha_connect.so';
--eval CREATE FUNCTION Json_Object_Nonull RETURNS STRING SONAME 'ha_connect.so';
--eval CREATE FUNCTION Json_Value returns STRING SONAME 'ha_connect.so';
--eval CREATE AGGREGATE FUNCTION Json_Array_Grp RETURNS STRING SONAME 'ha_connect.so';
--eval CREATE AGGREGATE FUNCTION Json_Object_Grp RETURNS STRING SONAME 'ha_connect.so';
}
--enable_query_log --enable_query_log

View File

@@ -5,35 +5,62 @@ let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MTR_SUITE_DIR/std_data/biblio.json $MYSQLD_DATADIR/test/biblio.json --copy_file $MTR_SUITE_DIR/std_data/biblio.json $MYSQLD_DATADIR/test/biblio.json
--copy_file $MTR_SUITE_DIR/std_data/employee.dat $MYSQLD_DATADIR/test/employee.dat --copy_file $MTR_SUITE_DIR/std_data/employee.dat $MYSQLD_DATADIR/test/employee.dat
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=VIR BLOCK_SIZE=5;
--echo # --echo #
--echo # Test UDF's with constant arguments --echo # Test UDF's with constant arguments
--echo # --echo #
--error ER_CANT_INITIALIZE_UDF
SELECT JsonValue(56,3.1416,'foo',NULL);
SELECT JsonValue(3.1416);
SELECT JsonValue('foo');
SELECT JsonValue(9223372036854775807);
SELECT JsonValue(NULL);
SELECT JsonValue(TRUE);
SELECT JsonValue(FALSE);
SELECT JsonValue();
SELECT JsonValue('[11,22,33]' json_) FROM t1;
#
SELECT Json_Array(); SELECT Json_Array();
SELECT Json_Object(56,3.1416,'foo',NULL);
SELECT Json_Object(56 qty,3.1416 price,'foo' truc, NULL garanty);
SELECT Json_Array(56,3.1416,'My name is "Foo"',NULL); SELECT Json_Array(56,3.1416,'My name is "Foo"',NULL);
SELECT Json_Array(Json_Array(56,3.1416,'foo'),NULL);
--error ER_CANT_INITIALIZE_UDF --error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL)) Array; SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL)) Array;
SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL),'One more') Array; SELECT Json_Array_Add(Json_Array(56,3.1416,'foo',NULL),'One more') Array;
SELECT Json_Array_Add(Json_Value('one value'),'One more'); --error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add(JsonValue('one value'),'One more');
--error ER_CANT_INITIALIZE_UDF --error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add('one value','One more'); SELECT Json_Array_Add('one value','One more');
SELECT Json_Array_Add('one value' json_,'One more'); SELECT Json_Array_Add('one value' json_,'One more');
--error ER_CANT_INITIALIZE_UDF SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 0);
SELECT Json_Value(56,3.1416,'foo',NULL); SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 2) Array;
SELECT Json_Value(3.1416); SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 9);
SELECT Json_Value('foo'); SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin', NULL), 'One more', 'Two more') Array;
SELECT Json_Value(NULL); SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), 'One more', 'Two more') Array FROM t1;
SELECT Json_Value(); SELECT Json_Array_Add_Values(Json_Array(56, 3.1416, 'machin'), n) Array FROM t1;
SELECT Json_Array_Add_Values(Json_Array(n, 3.1416, 'machin'), n) Array FROM t1;
SELECT Json_Array_Add_Values('[56]', 3.1416, 'machin') Array;
#
SELECT Json_Array_Delete(Json_Array(56,3.1416,'My name is "Foo"',NULL),0);
SELECT Json_Array_Delete(Json_Object(56,3.1416,'My name is Foo',NULL),2);
SELECT Json_Array_Delete(Json_Array(56,3.1416,'My name is "Foo"',NULL),'2');
#
SELECT Json_Object(56, 3.1416, 'foo', NULL);
SELECT Json_Object(56 qty, 3.1416 price, 'foo' truc, NULL garanty);
SELECT Json_Object(); SELECT Json_Object();
SELECT Json_Object(Json_Array(56,3.1416,'foo'),NULL); SELECT Json_Object(Json_Array(56, 3.1416, 'foo'), NULL);
SELECT Json_Array(Json_Array(56,3.1416,'foo'),NULL); SELECT Json_Array(Json_Object(56 "qty", 3.1416 "price", 'foo') ,NULL);
SELECT Json_Array(Json_Object(56 "qty",3.1416 "price",'foo'),NULL); SELECT Json_Object_Add(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'blue' color);
SELECT Json_Object_Add(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 45.99 price);
SELECT Json_Object_Delete(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'truc');
SELECT Json_Object_Delete(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty), 'chose');
SELECT Json_Object_List(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty)) "Key List";
SELECT Json_Object_List('{"qty":56, "price":3.1416, "truc":"machin", "garanty":null}') "Key List";
--echo # --echo #
--echo # Test UDF's with column arguments --echo # Test UDF's with column arguments
--echo # --echo #
CREATE TABLE t1 CREATE TABLE t2
( (
ISBN CHAR(15), ISBN CHAR(15),
LANG CHAR(2), LANG CHAR(2),
@@ -46,14 +73,13 @@ CREATE TABLE t1
DATEPUB int(4) DATEPUB int(4)
) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json'; ) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='biblio.json';
SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t1; SELECT Json_Array(AUTHOR, TITLE, DATEPUB) FROM t2;
SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t1; SELECT Json_Object(AUTHOR, TITLE, DATEPUB) FROM t2;
--error ER_CANT_INITIALIZE_UDF --error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t1; SELECT Json_Array_Grp(TITLE, DATEPUB) FROM t2;
SELECT Json_Array_Grp(TITLE) FROM t1; SELECT Json_Array_Grp(TITLE) FROM t2;
DROP TABLE t1;
CREATE TABLE t1 ( CREATE TABLE t3 (
SERIALNO CHAR(5) NOT NULL, SERIALNO CHAR(5) NOT NULL,
NAME VARCHAR(12) NOT NULL FLAG=6, NAME VARCHAR(12) NOT NULL FLAG=6,
SEX SMALLINT(1) NOT NULL, SEX SMALLINT(1) NOT NULL,
@@ -64,30 +90,156 @@ CREATE TABLE t1 (
SALARY DOUBLE(8,2) NOT NULL FLAG=52 SALARY DOUBLE(8,2) NOT NULL FLAG=52
) ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=8 FILE_NAME='employee.dat' ENDING=1; ) ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=8 FILE_NAME='employee.dat' ENDING=1;
SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t1 WHERE NAME = 'MERCHANT'; SELECT Json_Object(SERIALNO, NAME, TITLE, SALARY) FROM t3 WHERE NAME = 'MERCHANT';
SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t1 GROUP BY DEPARTMENT; SELECT DEPARTMENT, Json_Array_Grp(NAME) FROM t3 GROUP BY DEPARTMENT;
set connect_json_grp_size=30; SET connect_json_grp_size=30;
SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t1 GROUP BY DEPARTMENT; SELECT Json_Array(DEPARTMENT, Json_Array_Grp(NAME)) FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t1 GROUP BY DEPARTMENT; SELECT Json_Object(DEPARTMENT, Json_Array_Grp(NAME) json_NAMES) FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t1 GROUP BY DEPARTMENT; SELECT Json_Object(DEPARTMENT, Json_Array_Grp(Json_Object(SERIALNO, NAME, TITLE, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t1 GROUP BY DEPARTMENT, TITLE; SELECT Json_Object(DEPARTMENT, TITLE, Json_Array_Grp(Json_Object(SERIALNO, NAME, SALARY)) json_EMPLOYES) FROM t3 GROUP BY DEPARTMENT, TITLE;
--error ER_CANT_INITIALIZE_UDF --error ER_CANT_INITIALIZE_UDF
SELECT Json_Object_Grp(SALARY) FROM t1; SELECT Json_Object_Grp(SALARY) FROM t3;
SELECT Json_Object_Grp(SALARY, NAME) FROM t1; SELECT Json_Object_Grp(SALARY, NAME) FROM t3;
SELECT Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES") FROM t1 GROUP BY DEPARTMENT; SELECT Json_Object(DEPARTMENT, Json_Object_Grp(SALARY, NAME) "Json_SALARIES") FROM t3 GROUP BY DEPARTMENT;
SELECT Json_Array_Grp(NAME) from t1; SELECT Json_Array_Grp(NAME) FROM t3;
DROP TABLE t1;
DROP FUNCTION Json_Array; --echo #
DROP FUNCTION Json_Array_Add; --echo # Test value getting UDF's
DROP FUNCTION Json_Object; --echo #
DROP FUNCTION Json_Object_Nonull; SELECT JsonGet_String(Json_Array_Grp(name),'[#]') FROM t3;
DROP FUNCTION Json_Value; SELECT JsonGet_String(Json_Array_Grp(name),'[","]') FROM t3;
DROP FUNCTION Json_Array_Grp; SELECT JsonGet_String(Json_Array_Grp(name),'[>]') FROM t3;
DROP FUNCTION Json_Object_Grp; SET @j1 = '[45,28,36,45,89]';
SELECT JsonGet_String(@j1,'[1]');
SELECT JsonGet_String(@j1 json_,'[3]');
SELECT JsonGet_String(Json_Array(45,28,36,45,89),'[3]');
SELECT JsonGet_String(Json_Array(45,28,36,45,89),'["+"]') "list",'=' as "egal",JsonGet_String(Json_Array(45,28,36,45,89),'[+]') "sum";
SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
SELECT JsonGet_String(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:*');
SELECT JsonGet_String(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'truc');
SET @j2 = '{"qty":56,"price":3.141600,"truc":"machin","garanty":null}';
SELECT JsonGet_String(@j2 json_,'truc');
SELECT JsonGet_String(@j2,'truc');
SELECT JsonGet_String(@j2,'chose');
SELECT JsonGet_String(NULL json_, NULL);
SELECT department, JsonGet_String(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
#
SELECT JsonGet_Int(@j1, '[4]');
SELECT JsonGet_Int(@j1, '[#]');
SELECT JsonGet_Int(@j1, '[+]');
SELECT JsonGet_Int(@j1 json_,'[3]');
SELECT JsonGet_Int(Json_Array(45,28,36,45,89),'[3]');
SELECT JsonGet_Int(Json_Array(45,28,36,45,89),'["+"]');
SELECT JsonGet_Int(Json_Array(45,28,36,45,89),'[+]');
SELECT JsonGet_Int(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
SELECT JsonGet_Int(Json_Array(json_array(45,28),json_array(36,45,89)),'[0]:[1]');
SELECT JsonGet_Int(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'qty');
SELECT JsonGet_Int(@j2 json_,'price');
SELECT JsonGet_Int(@j2,'qty');
SELECT JsonGet_Int('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','chose');
SELECT JsonGet_Int(JsonGet_String(Json_Array(Json_Array(45,28),Json_Array(36,45,89)),'[1]:*'),'[+]') sum;
SELECT department, JsonGet_Int(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
#
SELECT JsonGet_Real(@j1, '[2]');
SELECT JsonGet_Real(@j1 json_,'[3]',2);
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'[3]');
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'["+"]');
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'[+]');
SELECT JsonGet_Real(Json_Array(45,28,36,45,89),'[!]');
SELECT JsonGet_Real(Json_Array(json_array(45,28),json_array(36,45,89)),'[1]:[0]');
SELECT JsonGet_Real(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'price');
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}' json_,'qty');
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','price');
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','price', 4);
SELECT JsonGet_Real('{"qty":56,"price":3.141600,"truc":"machin","garanty":null}','chose');
SELECT department, JsonGet_Real(Json_Object(department, Json_Array_Grp(salary) "Json_salaries"),'salaries:[+]') Sumsal FROM t3 GROUP BY department;
--echo #
--echo # Documentation examples
--echo #
SELECT
JsonGet_Int(Json_Array(45,28,36,45,89), '[4]') "Rank",
JsonGet_Int(Json_Array(45,28,36,45,89), '[#]') "Number",
JsonGet_String(Json_Array(45,28,36,45,89), '[","]') "Concat",
JsonGet_Int(Json_Array(45,28,36,45,89), '[+]') "Sum",
JsonGet_Real(Json_Array(45,28,36,45,89), '[!]', 2) "Avg";
SELECT
JsonGet_String('{"qty":7,"price":29.50,"garanty":null}','price') "String",
JsonGet_Int('{"qty":7,"price":29.50,"garanty":null}','price') "Int",
JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}','price') "Real";
SELECT JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}','price',3) "Real";
--echo #
--echo # Testing Locate
--echo #
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'machin');
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),56);
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),3.1416);
SELECT JsonLocate(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty),'chose');
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'Jack') Path;
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, 'jack' ci) Path;
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"Jack", "LN":"London"}' json_) Path;
SELECT JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, {"FN":"Jack", "LN":"London"}]}' json_, '{"FN":"jack", "LN":"London"}' json_) Path;
SELECT JsonLocate('[45,28,36,45,89]',36);
SELECT JsonLocate('[45,28,36,45,89]' json_,28.0);
SELECT Json_Locate_All('[45,28,36,45,89]',10);
SELECT Json_Locate_All('[45,28,36,45,89]',45);
SELECT Json_Locate_All('[[45,28],36,45,89]',45);
SELECT Json_Locate_All('[[45,28,45],36,45,89]',45);
SELECT Json_Locate_All('[[45,28,45],36,45,89]',JsonGet_Int('[3,45]','[1]'));
SELECT JsonLocate('[[45,28,45],36,45,89]',45,n) from t1;
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) FROM t1;
SELECT JsonGet_String(Json_Locate_All('[[45,28,45],36,45,89]',45),concat('[',n-1,']')) AS `Path` FROM t1 GROUP BY n HAVING `Path` IS NOT NULL;
SELECT Json_Locate_All('[45,28,[36,45,89]]',45);
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',JsonValue(45.0));
SELECT Json_Locate_All('[[45,28],[36,45.0,89]]',45.0);
SELECT JsonLocate('[[45,28],[36,45,89]]','[36,45,89]' json_);
SELECT JsonLocate('[[45,28],[36,45,89]]','[45,28]' json_);
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','45') "All paths";
SELECT Json_Locate_All('[[45,28],[[36,45],89]]','[36,45]' json_);
SELECT JsonGet_Int(Json_Locate_All('[[45,28],[[36,45],89]]',45), '[#]') "Nb of occurs";
SELECT Json_Locate_All('[[45,28],[[36,45],89]]',45,2);
SELECT JsonGet_String(Json_Locate_All('[45,28,36,45,89]',45),'[0]');
SELECT JsonLocate(Json_File('test/biblio.json'), 'Knab');
SELECT Json_Locate_All('test/biblio.json' jfile_, 'Knab');
--echo #
--echo # Testing json files
--echo #
select Jfile_Make('[{"_id":5,"type":"food","item":"beer","taste":"light","price":5.65,"ratings":[5,8,9]},
{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]},
{"_id":7,"type":"food","item":"meat","origin":"argentina","ratings":[2,4]},
{"_id":8,"type":"furniture","item":"table","size":{"W":60,"L":80,"H":40},"ratings":[5,8,7]}]', 'test/fx.json', 0) AS NewFile;
SELECT Jfile_Make('test/fx.json', 1);
SELECT Jfile_Make('test/fx.json' jfile_);
SELECT Jfile_Make(Jbin_File('test/fx.json'), 0);
SELECT Json_File('test/fx.json', 1);
SELECT Json_File('test/fx.json', 2);
SELECT Json_File('test/fx.json', 0);
SELECT Json_File('test/fx.json', '[0]');
SELECT Json_File('test/fx.json', '[?]');
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]:*');
SELECT JsonGet_String(Json_File('test/fx.json'), '[1]');
SELECT JsonGet_Int(Json_File('test/fx.json'), '[1]:mileage') AS Mileage;
SELECT JsonGet_Real(Json_File('test/fx.json'), '[0]:price', 2) AS Price;
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings');
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 1, 'ratings');
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]'), 6, 'ratings', 1);
SELECT Json_Array_Add(Json_File('test/fx.json', '[2]:ratings'), 6, 0);
SELECT Json_Array_Delete(Json_File('test/fx.json', '[2]'), 'ratings', 1);
SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 'france' origin);
SELECT Json_Object_Add(Json_File('test/fx.json', '[2]'), 70 H, 'size');
SELECT Json_Object_Add(Json_File('test/fx.json', '[3]'), 70 H, 'size');
SELECT Json_Object_List(Json_File('test/fx.json', '[3]:size'));
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
# #
# Clean up # Clean up
# #
--source json_udf2.inc
--remove_file $MYSQLD_DATADIR/test/biblio.json --remove_file $MYSQLD_DATADIR/test/biblio.json
--remove_file $MYSQLD_DATADIR/test/employee.dat --remove_file $MYSQLD_DATADIR/test/employee.dat
--remove_file $MYSQLD_DATADIR/test/fx.json

View File

@@ -0,0 +1,39 @@
--disable_query_log
DROP FUNCTION jsonvalue;
DROP FUNCTION json_array;
DROP FUNCTION json_array_add;
DROP FUNCTION json_array_add_values;
DROP FUNCTION json_array_delete;
DROP FUNCTION json_object;
DROP FUNCTION json_object_nonull;
DROP FUNCTION json_object_add;
DROP FUNCTION json_object_delete;
DROP FUNCTION json_object_list;
DROP FUNCTION json_array_grp;
DROP FUNCTION json_object_grp;
DROP FUNCTION json_item_merge;
DROP FUNCTION json_get_item;
DROP FUNCTION JsonGet_string;
DROP FUNCTION JsonGet_int;
DROP FUNCTION JsonGet_real;
DROP FUNCTION jsonlocate;
DROP FUNCTION json_locate_all;
DROP FUNCTION json_file;
DROP FUNCTION json_serialize;
DROP FUNCTION jfile_make;
DROP FUNCTION jbin_array;
DROP FUNCTION jbin_array_add_values;
DROP FUNCTION jbin_array_add;
DROP FUNCTION jbin_array_delete;
DROP FUNCTION jbin_object;
DROP FUNCTION jbin_object_nonull;
DROP FUNCTION jbin_object_add;
DROP FUNCTION jbin_object_delete;
DROP FUNCTION jbin_object_list;
DROP FUNCTION jbin_get_item;
DROP FUNCTION jbin_item_merge;
DROP FUNCTION jbin_file;
--enable_query_log

View File

@@ -0,0 +1,31 @@
--source have_odbc.inc
SET NAMES utf8;
# MS ODBC and unixODBC return different error message text,
# so disable displaying error messages
#--disable_result_log ONCE
--error ER_UNKNOWN_ERROR
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='Bad connection string';
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Sources;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Drivers;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Tables CONNECTION='Not important';
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CATFUNC=Columns CONNECTION='Not important';
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC TABNAME='EMPLOYEE' CONNECTION='DSN=Firebird;UID=SYSDBA;PWD=manager';
SELECT * FROM t1;
DROP TABLE t1;

38
storage/connect/noconst.c Normal file
View File

@@ -0,0 +1,38 @@
/***********************************************************************/
/* (C) Copyright to the author Olivier BERTRAND 2015 */
/***********************************************************************/
#include <my_global.h>
#include <mysqld.h>
#include <string.h>
#if defined(__WIN__)
#define DllExport __declspec( dllexport )
#else // !__WIN__
#define DllExport
#endif // !__WIN__
extern "C" {
DllExport my_bool noconst_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *noconst(UDF_INIT*, UDF_ARGS*, char*, unsigned long*, char*, char*);
} // extern "C"
/***********************************************************************/
/* Returns its argument saying it is not a constant. */
/***********************************************************************/
my_bool noconst_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) {
strcpy(message, "noconst unique argument must be a string");
return true;
} // endif arg
initid->const_item = false; // The trick!
return false;
} // end of noconst_init
char *noconst(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *, char *)
{
return args->args[0];
} // end of noconst

View File

@@ -143,7 +143,7 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL)); fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL));
return NULL; return NULL;
} else { } else {
g->Sarea_Size = worksize; g->Sarea = NULL;
g->Createas = 0; g->Createas = 0;
g->Alchecked = 0; g->Alchecked = 0;
g->Mrr = 0; g->Mrr = 0;
@@ -155,7 +155,7 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
/*******************************************************************/ /*******************************************************************/
/* Allocate the main work segment. */ /* Allocate the main work segment. */
/*******************************************************************/ /*******************************************************************/
if (!(g->Sarea = PlugAllocMem(g, worksize))) { if (worksize && !(g->Sarea = PlugAllocMem(g, worksize))) {
char errmsg[256]; char errmsg[256];
sprintf(errmsg, MSG(WORK_AREA), g->Message); sprintf(errmsg, MSG(WORK_AREA), g->Message);
strcpy(g->Message, errmsg); strcpy(g->Message, errmsg);
@@ -163,7 +163,7 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
} else } else
g->Sarea_Size = worksize; g->Sarea_Size = worksize;
} /* endif g */ } /* endif g */
g->jump_level = -1; /* New setting to allow recursive call of Plug */ g->jump_level = -1; /* New setting to allow recursive call of Plug */
return(g); return(g);

View File

@@ -57,6 +57,7 @@ extern handlerton *connect_hton;
/* External function. */ /* External function. */
/***********************************************************************/ /***********************************************************************/
USETEMP UseTemp(void); USETEMP UseTemp(void);
char *GetPluginDir(void);
/* --------------------------- Class RELDEF -------------------------- */ /* --------------------------- Class RELDEF -------------------------- */

View File

@@ -2019,7 +2019,7 @@ int TDBDOS::EstimatedLength(void)
dep = 1 + cdp->GetLong() / 20; // Why 20 ????? dep = 1 + cdp->GetLong() / 20; // Why 20 ?????
} else for (; cdp; cdp = cdp->GetNext()) } else for (; cdp; cdp = cdp->GetNext())
if (!(cdp->Flags & (U_VIRTUAL|U_SPECIAL))) if (!(cdp->Flags & (U_VIRTUAL|U_SPECIAL)))
dep = MY_MAX(dep, cdp->GetOffset()); dep = MY_MAX(dep, cdp->GetOffset());
return (int)dep; return (int)dep;
} // end of Estimated Length } // end of Estimated Length
@@ -2204,7 +2204,7 @@ bool TDBDOS::PrepareWriting(PGLOBAL)
} // endif Mode } // endif Mode
return false; return false;
} // end of WriteDB } // end of PrepareWriting
/***********************************************************************/ /***********************************************************************/
/* WriteDB: Data Base write routine for DOS access method. */ /* WriteDB: Data Base write routine for DOS access method. */
@@ -2216,7 +2216,7 @@ int TDBDOS::WriteDB(PGLOBAL g)
// Make the line to write // Make the line to write
if (PrepareWriting(g)) if (PrepareWriting(g))
return true; return RC_FX;
if (trace > 1) if (trace > 1)
htrc("Write: line is='%s'\n", To_Line); htrc("Write: line is='%s'\n", To_Line);

View File

@@ -659,7 +659,7 @@ int TDBJSN::ReadDB(PGLOBAL g)
if (!IsRead() && ((rc = ReadBuffer(g)) != RC_OK)) { if (!IsRead() && ((rc = ReadBuffer(g)) != RC_OK)) {
// Deferred reading failed // Deferred reading failed
} else if (!(Row = ParseJson(g, To_Line, } else if (!(Row = ParseJson(g, To_Line,
strlen(To_Line), Pretty, &Comma))) { strlen(To_Line), &Pretty, &Comma))) {
rc = (Pretty == 1 && !strcmp(To_Line, "]")) ? RC_EF : RC_FX; rc = (Pretty == 1 && !strcmp(To_Line, "]")) ? RC_EF : RC_FX;
} else { } else {
Row = FindRow(g); Row = FindRow(g);
@@ -755,7 +755,6 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
} else } else
strcpy(To_Line, s); strcpy(To_Line, s);
// Row->Clear();
return false; return false;
} else } else
return true; return true;
@@ -980,7 +979,7 @@ bool JSONCOL::ParseJpath(PGLOBAL g)
Nod = colp->Nod; Nod = colp->Nod;
Nodes = colp->Nodes; Nodes = colp->Nodes;
Xpd = colp->Xpd; Xpd = colp->Xpd;
goto fin; goto fin;
} // endif Name } // endif Name
sprintf(g->Message, "Cannot parse updated column %s", Name); sprintf(g->Message, "Cannot parse updated column %s", Name);
@@ -1046,7 +1045,8 @@ void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
switch (val->GetValType()) { switch (val->GetValType()) {
case TYPE_STRG: case TYPE_STRG:
case TYPE_INTG: case TYPE_INTG:
case TYPE_DBL: case TYPE_BINT:
case TYPE_DBL:
vp->SetValue_pval(val->GetValue()); vp->SetValue_pval(val->GetValue());
break; break;
case TYPE_BOOL: case TYPE_BOOL:
@@ -1353,7 +1353,7 @@ void JSONCOL::WriteColumn(PGLOBAL g)
longjmp(g->jumper[g->jump_level], 666); longjmp(g->jumper[g->jump_level], 666);
} // endif Xpd } // endif Xpd
/*********************************************************************/ /*********************************************************************/
/* Check whether this node must be written. */ /* Check whether this node must be written. */
/*********************************************************************/ /*********************************************************************/
if (Value != To_Val) if (Value != To_Val)
@@ -1384,7 +1384,7 @@ void JSONCOL::WriteColumn(PGLOBAL g)
if (Nodes[Nod-1].Op == OP_XX) { if (Nodes[Nod-1].Op == OP_XX) {
s = Value->GetCharValue(); s = Value->GetCharValue();
if (!(jsp = ParseJson(g, s, (int)strlen(s), 0))) { if (!(jsp = ParseJson(g, s, (int)strlen(s)))) {
strcpy(g->Message, s); strcpy(g->Message, s);
longjmp(g->jumper[g->jump_level], 666); longjmp(g->jumper[g->jump_level], 666);
} // endif jsp } // endif jsp
@@ -1522,7 +1522,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
/* Parse the json file and allocate its tree structure. */ /* Parse the json file and allocate its tree structure. */
/*********************************************************************/ /*********************************************************************/
g->Message[0] = 0; g->Message[0] = 0;
jsp = Top = ParseJson(g, memory, len, Pretty); jsp = Top = ParseJson(g, memory, len, &Pretty);
Txfp->CloseTableFile(g, false); Txfp->CloseTableFile(g, false);
Mode = mode; // Restore saved Mode Mode = mode; // Restore saved Mode
@@ -1540,7 +1540,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
if (*objpath != '[') { // objpass is a key if (*objpath != '[') { // objpass is a key
if (jsp->GetType() != TYPE_JOB) { if (jsp->GetType() != TYPE_JOB) {
strcpy(g->Message, "Table path does no match json file"); strcpy(g->Message, "Table path does not match the json file");
return RC_FX; return RC_FX;
} // endif Type } // endif Type
@@ -1556,7 +1556,7 @@ int TDBJSON::MakeDocument(PGLOBAL g)
} else if (objpath[strlen(objpath)-1] == ']') { } else if (objpath[strlen(objpath)-1] == ']') {
if (jsp->GetType() != TYPE_JAR) { if (jsp->GetType() != TYPE_JAR) {
strcpy(g->Message, "Table path does no match json file"); strcpy(g->Message, "Table path does not match the json file");
return RC_FX; return RC_FX;
} // endif Type } // endif Type
@@ -1837,7 +1837,6 @@ void TDBJSON::CloseDB(PGLOBAL g)
// Save the modified document // Save the modified document
char filename[_MAX_PATH]; char filename[_MAX_PATH];
PSZ msg; PSZ msg;
FILE *fop;
Doc->InitArray(g); Doc->InitArray(g);
@@ -1845,11 +1844,7 @@ void TDBJSON::CloseDB(PGLOBAL g)
PlugSetPath(filename, ((PJDEF)To_Def)->Fn, GetPath()); PlugSetPath(filename, ((PJDEF)To_Def)->Fn, GetPath());
// Serialize the modified table // Serialize the modified table
if (!(fop = fopen(filename, "wb"))) { if ((msg = Serialize(g, Top, filename, Pretty)))
sprintf(g->Message, MSG(OPEN_MODE_ERROR),
"w", (int)errno, filename);
strcat(strcat(g->Message, ": "), strerror(errno));
} else if ((msg = Serialize(g, Top, fop, Pretty)))
puts(msg); puts(msg);
} // end of CloseDB } // end of CloseDB

View File

@@ -1054,32 +1054,14 @@ int TDBMYSQL::SendCommand(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
/* Data Base indexed read routine for MYSQL access method. */ /* Data Base indexed read routine for MYSQL access method. */
/***********************************************************************/ /***********************************************************************/
bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len) bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
{ {
bool oom;
int oldlen = Query->GetLength(); int oldlen = Query->GetLength();
PHC hc = To_Def->GetHandler(); PHC hc = To_Def->GetHandler();
if (op == OP_FIRST && hc->end_range) { if (!(kr || hc->end_range) || op == OP_NEXT ||
#ifdef _DEBUG Mode == MODE_UPDATE || Mode == MODE_DELETE) {
assert(!key); if (!kr && Mode == MODE_READX) {
#endif
key_range *end_key = &hc->save_end_range;
key = end_key->key;
len = end_key->length;
switch (end_key->flag) {
case HA_READ_BEFORE_KEY: op = OP_LT; break;
case HA_READ_AFTER_KEY: op = OP_LE; break;
default: key = NULL;
} // endswitch flag
} // endif OP_FIRST
if (!key || op == OP_NEXT ||
Mode == MODE_UPDATE || Mode == MODE_DELETE) {
if (!key && Mode == MODE_READX) {
// This is a false indexed read // This is a false indexed read
m_Rc = Myc.ExecSQL(g, Query->GetStr()); m_Rc = Myc.ExecSQL(g, Query->GetStr());
Mode = MODE_READ; Mode = MODE_READ;
@@ -1091,23 +1073,35 @@ bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
if (Myc.m_Res) if (Myc.m_Res)
Myc.FreeResult(); Myc.FreeResult();
if (hc->MakeKeyWhere(g, Query, op, '`', key, len)) if (hc->MakeKeyWhere(g, Query, op, '`', kr))
return true; return true;
if (To_CondFil) { if (To_CondFil) {
oom = Query->Append(" AND ("); if (To_CondFil->Idx != hc->active_index) {
oom |= Query->Append(To_CondFil->Body); To_CondFil->Idx = hc->active_index;
To_CondFil->Body= (char*)PlugSubAlloc(g, NULL, 0);
*To_CondFil->Body= 0;
if ((oom |= Query->Append(')'))) { if ((To_CondFil = hc->CheckCond(g, To_CondFil, To_CondFil->Cond)))
strcpy(g->Message, "Readkey: Out of memory"); PlugSubAlloc(g, NULL, strlen(To_CondFil->Body) + 1);
return true;
} // endif oom
} // endif To_Condfil } // endif active_index
} // endif's op if (To_CondFil)
if (Query->Append(" AND ") || Query->Append(To_CondFil->Body)) {
strcpy(g->Message, "Readkey: Out of memory");
return true;
} // endif Append
m_Rc = Myc.ExecSQL(g, Query->GetStr()); } // endif To_Condfil
Mode = MODE_READ;
} // endif's op
if (trace)
htrc("MYSQL ReadKey: Query=%s\n", Query->GetStr());
m_Rc = Myc.ExecSQL(g, Query->GetStr());
Query->Truncate(oldlen); Query->Truncate(oldlen);
return (m_Rc == RC_FX) ? true : false; return (m_Rc == RC_FX) ? true : false;
} // end of ReadKey } // end of ReadKey

View File

@@ -99,7 +99,7 @@ class TDBMYSQL : public TDBASE {
virtual int WriteDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc); virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g); virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len); virtual bool ReadKey(PGLOBAL g, OPVAL op, const key_range *kr);
// Specific routines // Specific routines
bool SetColumnRanks(PGLOBAL g); bool SetColumnRanks(PGLOBAL g);

View File

@@ -1,7 +1,7 @@
/************* Tabodbc C++ Program Source Code File (.CPP) *************/ /************* Tabodbc C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABODBC */ /* PROGRAM NAME: TABODBC */
/* ------------- */ /* ------------- */
/* Version 2.9 */ /* Version 3.0 */
/* */ /* */
/* COPYRIGHT: */ /* COPYRIGHT: */
/* ---------- */ /* ---------- */
@@ -35,6 +35,7 @@
/* Include relevant MariaDB header file. */ /* Include relevant MariaDB header file. */
/***********************************************************************/ /***********************************************************************/
#include "my_global.h" #include "my_global.h"
#include "sql_class.h"
#if defined(__WIN__) #if defined(__WIN__)
#include <io.h> #include <io.h>
#include <fcntl.h> #include <fcntl.h>
@@ -72,6 +73,7 @@
#include "reldef.h" #include "reldef.h"
#include "tabcol.h" #include "tabcol.h"
#include "valblk.h" #include "valblk.h"
#include "ha_connect.h"
#include "sql_string.h" #include "sql_string.h"
@@ -322,7 +324,7 @@ PSZ TDBODBC::GetFile(PGLOBAL g)
if (Connect) { if (Connect) {
char *p1, *p2; char *p1, *p2;
int i; int i;
size_t n; size_t n;
if (!(p1 = strstr(Connect, "DBQ="))) { if (!(p1 = strstr(Connect, "DBQ="))) {
char *p, *lc = strlwr(PlugDup(g, Connect)); char *p, *lc = strlwr(PlugDup(g, Connect));
@@ -334,8 +336,8 @@ PSZ TDBODBC::GetFile(PGLOBAL g)
} else } else
i = 4; i = 4;
if (p1) { if (p1) {
p1 += i; // Beginning of file name p1 += i; // Beginning of file name
p2 = strchr(p1, ';'); // End of file path/name p2 = strchr(p1, ';'); // End of file path/name
// Make the File path/name from the connect string // Make the File path/name from the connect string
@@ -397,176 +399,209 @@ int TDBODBC::Decode(char *txt, char *buf, size_t n)
/* Note: when implementing EOM filtering, column only used in local */ /* Note: when implementing EOM filtering, column only used in local */
/* filter should be removed from column list. */ /* filter should be removed from column list. */
/***********************************************************************/ /***********************************************************************/
char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt) bool TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
{ {
char *colist, *tabname, *sql, buf[NAM_LEN * 3]; char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
LPCSTR schmp = NULL, catp = NULL; int len;
int len, ncol = 0; bool oom = false, first = true;
bool first = true; PTABLE tablep = To_Table;
PTABLE tablep = To_Table; PCOL colp;
PCOL colp;
if (Srcdef) if (Srcdef) {
return Srcdef; Query = new(g)STRING(g, 0, Srcdef);
return false;
} // endif Srcdef
if (!cnt) { // Allocate the string used to contain the Query
// Normal SQL statement to retrieve results Query = new(g)STRING(g, 1023, "SELECT ");
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial())
ncol++;
if (ncol) { if (!cnt) {
colist = (char*)PlugSubAlloc(g, NULL, (NAM_LEN + 4) * ncol); if (Columns) {
// Normal SQL statement to retrieve results
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial()) {
if (!first)
oom |= Query->Append(", ");
else
first = false;
for (colp = Columns; colp; colp = colp->GetNext()) // Column name can be encoded in UTF-8
if (!colp->IsSpecial()) { Decode(colp->GetName(), buf, sizeof(buf));
// Column name can be in UTF-8 encoding
/*rc=*/ Decode(colp->GetName(), buf, sizeof(buf));
if (Quote) { if (Quote) {
if (first) { // Put column name between identifier quotes in case in contains blanks
strcat(strcat(strcpy(colist, Quote), buf), Quote); oom |= Query->Append(Quote);
first = false; oom |= Query->Append(buf);
} else oom |= Query->Append(Quote);
strcat(strcat(strcat(strcat(colist, ", "), } else
Quote), buf), Quote); oom |= Query->Append(buf);
} else { } // endif colp
if (first) {
strcpy(colist, buf);
first = false;
} else
strcat(strcat(colist, ", "), buf);
} // endif Quote } else
// !Columns can occur for queries such that sql count(*) from...
} // endif !Special
} else {
// ncol == 0 can occur for queries such that sql count(*) from...
// for which we will count the rows from sql * from... // for which we will count the rows from sql * from...
colist = (char*)PlugSubAlloc(g, NULL, 2); oom |= Query->Append('*');
strcpy(colist, "*");
} // endif ncol
} else { } else
// SQL statement used to retrieve the size of the result // SQL statement used to retrieve the size of the result
colist = (char*)PlugSubAlloc(g, NULL, 9); oom |= Query->Append("count(*)");
strcpy(colist, "count(*)");
} // endif cnt
// Table name can be encoded in UTF-8 oom |= Query->Append(" FROM ");
/*rc = */Decode(TableName, buf, sizeof(buf));
// Put table name between identifier quotes in case in contains blanks
tabname = (char*)PlugSubAlloc(g, NULL, strlen(buf) + 3);
if (Quote)
strcat(strcat(strcpy(tabname, Quote), buf), Quote);
else
strcpy(tabname, buf);
// Below 14 is length of 'select ' + length of ' from ' + 1
len = (strlen(colist) + strlen(buf) + 14);
len += (To_CondFil ? strlen(To_CondFil->Body) + 7 : 0);
if (Catalog && *Catalog) if (Catalog && *Catalog)
catp = Catalog; catp = Catalog;
if (catp)
len += (strlen(catp) + 2);
if (tablep->GetSchema()) if (tablep->GetSchema())
schmp = tablep->GetSchema(); schmp = (char*)tablep->GetSchema();
else if (Schema && *Schema) else if (Schema && *Schema)
schmp = Schema; schmp = Schema;
if (schmp)
len += (strlen(schmp) + 1);
sql = (char*)PlugSubAlloc(g, NULL, len);
strcat(strcat(strcpy(sql, "SELECT "), colist), " FROM ");
if (catp) { if (catp) {
strcat(sql, catp); oom |= Query->Append(catp);
if (schmp) if (schmp) {
strcat(strcat(sql, "."), schmp); oom |= Query->Append('.');
else oom |= Query->Append(schmp);
strcat(sql, "."); } // endif schmp
strcat(sql, "."); oom |= Query->Append('.');
} else if (schmp) } else if (schmp) {
strcat(strcat(sql, schmp), "."); oom |= Query->Append(schmp);
oom |= Query->Append('.');
} // endif schmp
strcat(sql, tabname); // Table name can be encoded in UTF-8
Decode(TableName, buf, sizeof(buf));
if (To_CondFil) if (Quote) {
strcat(strcat(sql, " WHERE "), To_CondFil->Body); // Put table name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
if (trace) oom |= Query->Append(buf);
htrc("sql: '%s'\n", sql); oom |= Query->Append(Quote);
} else
oom |= Query->Append(buf);
return sql; len = Query->GetLength();
if (To_CondFil) {
if (Mode == MODE_READ) {
oom |= Query->Append(" WHERE ");
oom |= Query->Append(To_CondFil->Body);
len = Query->GetLength() + 1;
} else
len += (strlen(To_CondFil->Body) + 256);
} else
len += ((Mode == MODE_READX) ? 256 : 1);
if (oom || Query->Resize(len)) {
strcpy(g->Message, "MakeSQL: Out of memory");
return true;
} // endif oom
if (trace)
htrc("Query=%s\n", Query->GetStr());
return false;
} // end of MakeSQL } // end of MakeSQL
/***********************************************************************/ /***********************************************************************/
/* MakeInsert: make the Insert statement used with ODBC connection. */ /* MakeInsert: make the Insert statement used with ODBC connection. */
/***********************************************************************/ /***********************************************************************/
char *TDBODBC::MakeInsert(PGLOBAL g) bool TDBODBC::MakeInsert(PGLOBAL g)
{ {
char *stmt, *colist, *valist, buf[NAM_LEN * 3]; char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
// char *tk = "`"; int len = 0;
int len = 0; bool b = false, oom = false;
bool b = FALSE; PTABLE tablep = To_Table;
PCOL colp; PCOL colp;
for (colp = Columns; colp; colp = colp->GetNext()) for (colp = Columns; colp; colp = colp->GetNext())
if (colp->IsSpecial()) { if (colp->IsSpecial()) {
strcpy(g->Message, MSG(NO_ODBC_SPECOL)); strcpy(g->Message, MSG(NO_ODBC_SPECOL));
return NULL; return true;
} else { } else {
len += (strlen(colp->GetName()) + 4); // Column name can be encoded in UTF-8
Decode(colp->GetName(), buf, sizeof(buf));
len += (strlen(buf) + 6); // comma + quotes + valist
((PODBCCOL)colp)->Rank = ++Nparm; ((PODBCCOL)colp)->Rank = ++Nparm;
} // endif colp } // endif colp
colist = (char*)PlugSubAlloc(g, NULL, len); // Below 32 is enough to contain the fixed part of the query
*colist = '\0'; if (Catalog && *Catalog)
valist = (char*)PlugSubAlloc(g, NULL, 2 * Nparm); catp = Catalog;
*valist = '\0';
for (colp = Columns; colp; colp = colp->GetNext()) { if (catp)
if (b) { len += strlen(catp) + 1;
strcat(colist, ", ");
strcat(valist, ",");
} else
b = true;
// Column name can be in UTF-8 encoding if (tablep->GetSchema())
Decode(colp->GetName(), buf, sizeof(buf)); schmp = (char*)tablep->GetSchema();
else if (Schema && *Schema)
schmp = Schema;
if (Quote) if (schmp)
strcat(strcat(strcat(colist, Quote), buf), Quote); len += strlen(schmp) + 1;
else
strcat(colist, buf);
strcat(valist, "?"); // Parameter marker // Column name can be encoded in UTF-8
} // endfor colp Decode(TableName, buf, sizeof(buf));
len += (strlen(buf) + 32);
Query = new(g) STRING(g, len, "INSERT INTO ");
// Below 32 is enough to contain the fixed part of the query if (catp) {
len = (strlen(TableName) + strlen(colist) + strlen(valist) + 32); oom |= Query->Append(catp);
stmt = (char*)PlugSubAlloc(g, NULL, len);
strcpy(stmt, "INSERT INTO ");
if (Quote) if (schmp) {
strcat(strcat(strcat(stmt, Quote), TableName), Quote); oom |= Query->Append('.');
else oom |= Query->Append(schmp);
strcat(stmt, TableName); } // endif schmp
strcat(strcat(strcat(stmt, " ("), colist), ") VALUES ("); oom |= Query->Append('.');
strcat(strcat(stmt, valist), ")"); } else if (schmp) {
oom |= Query->Append(schmp);
oom |= Query->Append('.');
} // endif schmp
return stmt; if (Quote) {
// Put table name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
} else
oom |= Query->Append(buf);
oom |= Query->Append('(');
for (colp = Columns; colp; colp = colp->GetNext()) {
if (b)
oom |= Query->Append(", ");
else
b = true;
// Column name can be in UTF-8 encoding
Decode(colp->GetName(), buf, sizeof(buf));
if (Quote) {
// Put column name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
} else
oom |= Query->Append(buf);
} // endfor colp
oom |= Query->Append(") VALUES (");
for (int i = 0; i < Nparm; i++)
oom |= Query->Append("?,");
if (oom)
strcpy(g->Message, "MakeInsert: Out of memory");
else
Query->RepLast(')');
return oom;
} // end of MakeInsert } // end of MakeInsert
/***********************************************************************/ /***********************************************************************/
@@ -591,7 +626,7 @@ bool TDBODBC::BindParameters(PGLOBAL g)
/* MakeCommand: make the Update or Delete statement to send to the */ /* MakeCommand: make the Update or Delete statement to send to the */
/* MySQL server. Limited to remote values and filtering. */ /* MySQL server. Limited to remote values and filtering. */
/***********************************************************************/ /***********************************************************************/
char *TDBODBC::MakeCommand(PGLOBAL g) bool TDBODBC::MakeCommand(PGLOBAL g)
{ {
char *p, *stmt, name[68], *body = NULL, *qc = Ocp->GetQuoteChar(); char *p, *stmt, name[68], *body = NULL, *qc = Ocp->GetQuoteChar();
char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1); char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1);
@@ -649,7 +684,8 @@ char *TDBODBC::MakeCommand(PGLOBAL g)
return NULL; return NULL;
} // endif p } // endif p
return stmt; Query = new(g) STRING(g, 0, stmt);
return (!Query->GetSize());
} // end of MakeCommand } // end of MakeCommand
#if 0 #if 0
@@ -826,10 +862,12 @@ bool TDBODBC::OpenDB(PGLOBAL g)
if (Memory < 3) { if (Memory < 3) {
// Method will depend on cursor type // Method will depend on cursor type
if ((Rbuf = Ocp->Rewind(Query, (PODBCCOL)Columns)) < 0) { if ((Rbuf = Ocp->Rewind(Query->GetStr(), (PODBCCOL)Columns)) < 0)
Ocp->Close(); if (Mode != MODE_READX) {
return true; Ocp->Close();
} // endif Rewind return true;
} else
Rbuf = 0;
} else } else
Rbuf = Qrp->Nblin; Rbuf = Qrp->Nblin;
@@ -864,15 +902,14 @@ bool TDBODBC::OpenDB(PGLOBAL g)
/*********************************************************************/ /*********************************************************************/
if (Mode == MODE_READ || Mode == MODE_READX) { if (Mode == MODE_READ || Mode == MODE_READX) {
if (Memory > 1 && !Srcdef) { if (Memory > 1 && !Srcdef) {
char *Sql; int n;
int n;
if ((Sql = MakeSQL(g, true))) { if (!MakeSQL(g, true)) {
// Allocate a Count(*) column // Allocate a Count(*) column
Cnp = new(g) ODBCCOL; Cnp = new(g) ODBCCOL;
Cnp->InitValue(g); Cnp->InitValue(g);
if ((n = Ocp->GetResultSize(Sql, Cnp)) < 0) { if ((n = Ocp->GetResultSize(Query->GetStr(), Cnp)) < 0) {
strcpy(g->Message, "Cannot get result size"); strcpy(g->Message, "Cannot get result size");
return true; return true;
} // endif n } // endif n
@@ -882,36 +919,36 @@ bool TDBODBC::OpenDB(PGLOBAL g)
if ((Qrp = Ocp->AllocateResult(g))) if ((Qrp = Ocp->AllocateResult(g)))
Memory = 2; // Must be filled Memory = 2; // Must be filled
else { else {
strcpy(g->Message, "Memory allocation failed"); strcpy(g->Message, "Result set memory allocation failed");
return true; return true;
} // endif n } // endif n
Ocp->m_Rows = 0; Ocp->m_Rows = 0;
} else { } else
strcpy(g->Message, "MakeSQL failed");
return true; return true;
} // endif Sql
} // endif Memory } // endif Memory
if ((Query = MakeSQL(g, false))) { if (!(rc = MakeSQL(g, false))) {
for (PODBCCOL colp = (PODBCCOL)Columns; colp; for (PODBCCOL colp = (PODBCCOL)Columns; colp;
colp = (PODBCCOL)colp->GetNext()) colp = (PODBCCOL)colp->GetNext())
if (!colp->IsSpecial()) if (!colp->IsSpecial())
colp->AllocateBuffers(g, Rows); colp->AllocateBuffers(g, Rows);
rc = ((Rows = Ocp->ExecDirectSQL(Query, (PODBCCOL)Columns)) < 0); rc = (Mode == MODE_READ)
} // endif Query ? ((Rows = Ocp->ExecDirectSQL(Query->GetStr(), (PODBCCOL)Columns)) < 0)
: false;
} // endif rc
} else if (Mode == MODE_INSERT) { } else if (Mode == MODE_INSERT) {
if ((Query = MakeInsert(g))) { if (!(rc = MakeInsert(g))) {
if (Nparm != Ocp->PrepareSQL(Query)) { if (Nparm != Ocp->PrepareSQL(Query->GetStr())) {
strcpy(g->Message, MSG(PARM_CNT_MISS)); strcpy(g->Message, MSG(PARM_CNT_MISS));
rc = true; rc = true;
} else } else
rc = BindParameters(g); rc = BindParameters(g);
} // endif Query } // endif rc
} else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) { } else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
rc = false; // wait for CheckCond before calling MakeCommand(g); rc = false; // wait for CheckCond before calling MakeCommand(g);
@@ -969,6 +1006,59 @@ bool TDBODBC::SetRecpos(PGLOBAL g, int recpos)
return false; return false;
} // end of SetRecpos } // end of SetRecpos
/***********************************************************************/
/* Data Base indexed read routine for MYSQL access method. */
/***********************************************************************/
bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
{
char c = Quote ? *Quote : 0;
int oldlen = Query->GetLength();
PHC hc = To_Def->GetHandler();
if (!(kr || hc->end_range) || op == OP_NEXT ||
Mode == MODE_UPDATE || Mode == MODE_DELETE) {
if (!kr && Mode == MODE_READX) {
// This is a false indexed read
Rows = Ocp->ExecDirectSQL((char*)Query->GetStr(), (PODBCCOL)Columns);
Mode = MODE_READ;
return (Rows < 0);
} // endif key
return false;
} else {
if (To_Def->GetHandler()->MakeKeyWhere(g, Query, op, c, kr))
return true;
if (To_CondFil) {
if (To_CondFil->Idx != hc->active_index) {
To_CondFil->Idx = hc->active_index;
To_CondFil->Body= (char*)PlugSubAlloc(g, NULL, 0);
*To_CondFil->Body= 0;
if ((To_CondFil = hc->CheckCond(g, To_CondFil, To_CondFil->Cond)))
PlugSubAlloc(g, NULL, strlen(To_CondFil->Body) + 1);
} // endif active_index
if (To_CondFil)
if (Query->Append(" AND ") || Query->Append(To_CondFil->Body)) {
strcpy(g->Message, "Readkey: Out of memory");
return true;
} // endif Append
} // endif To_Condfil
Mode = MODE_READ;
} // endif's op
if (trace)
htrc("ODBC ReadKey: Query=%s\n", Query->GetStr());
Rows = Ocp->ExecDirectSQL((char*)Query->GetStr(), (PODBCCOL)Columns);
Query->Truncate(oldlen);
return (Rows < 0);
} // end of ReadKey
/***********************************************************************/ /***********************************************************************/
/* VRDNDOS: Data Base read routine for odbc access method. */ /* VRDNDOS: Data Base read routine for odbc access method. */
/***********************************************************************/ /***********************************************************************/
@@ -981,11 +1071,11 @@ int TDBODBC::ReadDB(PGLOBAL g)
GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex); GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex);
if (Mode == MODE_UPDATE || Mode == MODE_DELETE) { if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
if (!Query && !(Query = MakeCommand(g))) if (!Query && MakeCommand(g))
return RC_FX; return RC_FX;
// Send the UPDATE/DELETE command to the remote table // Send the UPDATE/DELETE command to the remote table
if (!Ocp->ExecSQLcommand(Query)) { if (!Ocp->ExecSQLcommand(Query->GetStr())) {
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows); sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
if (trace) if (trace)
@@ -1063,11 +1153,11 @@ int TDBODBC::WriteDB(PGLOBAL g)
int TDBODBC::DeleteDB(PGLOBAL g, int irc) int TDBODBC::DeleteDB(PGLOBAL g, int irc)
{ {
if (irc == RC_FX) { if (irc == RC_FX) {
if (!Query && !(Query = MakeCommand(g))) if (!Query && MakeCommand(g))
return RC_FX; return RC_FX;
// Send the DELETE (all) command to the remote table // Send the DELETE (all) command to the remote table
if (!Ocp->ExecSQLcommand(Query)) { if (!Ocp->ExecSQLcommand(Query->GetStr())) {
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows); sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
if (trace) if (trace)
@@ -1279,12 +1369,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
} // endif Buf_Type } // endif Buf_Type
// Nulls are handled by StrLen[n] == SQL_NULL_DATA if (trace > 1) {
// MDEV-8561
//if (Value->IsZero())
// Value->SetNull(Nullable);
if (trace) {
char buf[64]; char buf[64];
htrc("ODBC Column %s: rows=%d buf=%p type=%d value=%s\n", htrc("ODBC Column %s: rows=%d buf=%p type=%d value=%s\n",
@@ -1572,9 +1657,12 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
int TDBXDBC::ReadDB(PGLOBAL g) int TDBXDBC::ReadDB(PGLOBAL g)
{ {
if (Cmdlist) { if (Cmdlist) {
Query = Cmdlist->Cmd; if (!Query)
Query = new(g)STRING(g, 0, Cmdlist->Cmd);
else
Query->Set(Cmdlist->Cmd);
if (Ocp->ExecSQLcommand(Query)) if (Ocp->ExecSQLcommand(Query->GetStr()))
Nerr++; Nerr++;
Fpos++; // Used for progress info Fpos++; // Used for progress info
@@ -1632,10 +1720,10 @@ void XSRCCOL::ReadColumn(PGLOBAL g)
PTDBXDBC tdbp = (PTDBXDBC)To_Tdb; PTDBXDBC tdbp = (PTDBXDBC)To_Tdb;
switch (Flag) { switch (Flag) {
case 0: Value->SetValue_psz(tdbp->Query); break; case 0: Value->SetValue_psz(tdbp->Query->GetStr()); break;
case 1: Value->SetValue(tdbp->AftRows); break; case 1: Value->SetValue(tdbp->AftRows); break;
case 2: Value->SetValue_psz(g->Message); break; case 2: Value->SetValue_psz(g->Message); break;
default: Value->SetValue_psz("Invalid Flag"); break; default: Value->SetValue_psz("Invalid Flag"); break;
} // endswitch Flag } // endswitch Flag
} // end of ReadColumn } // end of ReadColumn

View File

@@ -42,7 +42,8 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
int GetOptions(void) {return Options;} int GetOptions(void) {return Options;}
// Methods // Methods
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); virtual int Indexable(void) {return 2;}
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m); virtual PTDB GetTable(PGLOBAL g, MODE m);
protected: protected:
@@ -111,15 +112,14 @@ class TDBODBC : public TDBASE {
virtual int WriteDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc); virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g); virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len) virtual bool ReadKey(PGLOBAL g, OPVAL op, const key_range *kr);
{return true;}
protected: protected:
// Internal functions // Internal functions
int Decode(char *utf, char *buf, size_t n); int Decode(char *utf, char *buf, size_t n);
char *MakeSQL(PGLOBAL g, bool cnt); bool MakeSQL(PGLOBAL g, bool cnt);
char *MakeInsert(PGLOBAL g); bool MakeInsert(PGLOBAL g);
char *MakeCommand(PGLOBAL g); bool MakeCommand(PGLOBAL g);
//bool MakeFilter(PGLOBAL g, bool c); //bool MakeFilter(PGLOBAL g, bool c);
bool BindParameters(PGLOBAL g); bool BindParameters(PGLOBAL g);
//char *MakeUpdate(PGLOBAL g); //char *MakeUpdate(PGLOBAL g);
@@ -129,14 +129,14 @@ class TDBODBC : public TDBASE {
ODBConn *Ocp; // Points to an ODBC connection class ODBConn *Ocp; // Points to an ODBC connection class
ODBCCOL *Cnp; // Points to count(*) column ODBCCOL *Cnp; // Points to count(*) column
ODBCPARM Ops; // Additional parameters ODBCPARM Ops; // Additional parameters
char *Connect; // Points to connection string PSTRG Query; // Constructed SQL query
char *Connect; // Points to connection string
char *TableName; // Points to ODBC table name char *TableName; // Points to ODBC table name
char *Schema; // Points to ODBC table Schema char *Schema; // Points to ODBC table Schema
char *User; // User connect info char *User; // User connect info
char *Pwd; // Password connect info char *Pwd; // Password connect info
char *Catalog; // Points to ODBC table Catalog char *Catalog; // Points to ODBC table Catalog
char *Srcdef; // The source table SQL definition char *Srcdef; // The source table SQL definition
char *Query; // Points to SQL statement
char *Count; // Points to count(*) SQL statement char *Count; // Points to count(*) SQL statement
//char *Where; // Points to local where clause //char *Where; // Points to local where clause
char *Quote; // The identifier quoting character char *Quote; // The identifier quoting character

View File

@@ -60,6 +60,7 @@ extern "C" char version[];
#endif // !__WIN__ #endif // !__WIN__
#define TYPE_UNKNOWN 12 /* Must be greater than other types */ #define TYPE_UNKNOWN 12 /* Must be greater than other types */
#define XSTR(M) sizeof(M) - strlen(M) - 1 /* To avoid overflow*/
/***********************************************************************/ /***********************************************************************/
/* Class and structure used by XMLColumns. */ /* Class and structure used by XMLColumns. */
@@ -225,30 +226,30 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
more: more:
if (vp->atp) { if (vp->atp) {
strncpy(colname, vp->atp->GetName(g), sizeof(colname)); strncpy(colname, vp->atp->GetName(g), sizeof(colname));
strncat(xcol->Name, colname, 64); strncat(xcol->Name, colname, XSTR(xcol->Name));
switch (vp->atp->GetText(g, buf, sizeof(buf))) { switch (vp->atp->GetText(g, buf, sizeof(buf))) {
case RC_INFO: case RC_INFO:
PushWarning(g, txmp); PushWarning(g, txmp);
case RC_OK: case RC_OK:
strncat(fmt, "@", sizeof(fmt)); strncat(fmt, "@", XSTR(fmt));
break; break;
default: default:
goto err; goto err;
} // enswitch rc } // enswitch rc
if (j) if (j)
strncat(fmt, colname, sizeof(fmt)); strncat(fmt, colname, XSTR(fmt));
} else { } else {
if (tdp->Usedom && node->GetType() != 1) if (tdp->Usedom && node->GetType() != 1)
continue; continue;
strncpy(colname, node->GetName(g), sizeof(colname)); strncpy(colname, node->GetName(g), sizeof(colname));
strncat(xcol->Name, colname, 64); strncat(xcol->Name, colname, XSTR(xcol->Name));
if (j) if (j)
strncat(fmt, colname, sizeof(fmt)); strncat(fmt, colname, XSTR(fmt));
if (j < lvl && ok) { if (j < lvl && ok) {
vp = lvlp[j+1]; vp = lvlp[j+1];
@@ -266,9 +267,10 @@ PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
if (!vp->atp) if (!vp->atp)
node = vp->nl->GetItem(g, vp->k++, node); node = vp->nl->GetItem(g, vp->k++, node);
strncat(strncat(fmt, colname, 125), "/", 125); strncat(fmt, colname, XSTR(fmt));
strncat(xcol->Name, "_", 64); strncat(fmt, "/", XSTR(fmt));
j++; strncat(xcol->Name, "_", XSTR(xcol->Name));
j++;
vp->n = (int)strlen(xcol->Name); vp->n = (int)strlen(xcol->Name);
vp->m = (int)strlen(fmt); vp->m = (int)strlen(fmt);
goto more; goto more;

View File

@@ -340,7 +340,7 @@ PVAL AllocateValue(PGLOBAL g, void *value, short type, short prec)
switch (type) { switch (type) {
case TYPE_STRING: case TYPE_STRING:
valp = new(g) TYPVAL<PSZ>((PSZ)value); valp = new(g) TYPVAL<PSZ>((PSZ)value, prec);
break; break;
case TYPE_SHORT: case TYPE_SHORT:
valp = new(g) TYPVAL<short>(*(short*)value, TYPE_SHORT); valp = new(g) TYPVAL<short>(*(short*)value, TYPE_SHORT);
@@ -1209,12 +1209,12 @@ void TYPVAL<TYPE>::Print(PGLOBAL g, char *ps, uint z)
/***********************************************************************/ /***********************************************************************/
/* STRING public constructor from a constant string. */ /* STRING public constructor from a constant string. */
/***********************************************************************/ /***********************************************************************/
TYPVAL<PSZ>::TYPVAL(PSZ s) : VALUE(TYPE_STRING) TYPVAL<PSZ>::TYPVAL(PSZ s, short c) : VALUE(TYPE_STRING)
{ {
Strp = s; Strp = s;
Len = strlen(s); Len = strlen(s);
Clen = Len; Clen = Len;
Ci = false; Ci = (c == 1);
} // end of STRING constructor } // end of STRING constructor
/***********************************************************************/ /***********************************************************************/
@@ -2440,6 +2440,7 @@ void DTVAL::SetTimeShift(void)
} // end of SetTimeShift } // end of SetTimeShift
#if defined(connect_EXPORTS)
// Added by Alexander Barkov // Added by Alexander Barkov
static void TIME_to_localtime(struct tm *tm, const MYSQL_TIME *ltime) static void TIME_to_localtime(struct tm *tm, const MYSQL_TIME *ltime)
{ {
@@ -2461,6 +2462,9 @@ static struct tm *gmtime_mysql(const time_t *timep, struct tm *tm)
TIME_to_localtime(tm, &ltime); TIME_to_localtime(tm, &ltime);
return tm; return tm;
} // end of gmtime_mysql } // end of gmtime_mysql
#else
#define gmtime_mysql(T,B) gmtime((const time_t *)T)
#endif
/***********************************************************************/ /***********************************************************************/
/* GetGmTime: returns a pointer to a static tm structure obtained */ /* GetGmTime: returns a pointer to a static tm structure obtained */
@@ -2489,6 +2493,7 @@ struct tm *DTVAL::GetGmTime(struct tm *tm_buffer)
return datm; return datm;
} // end of GetGmTime } // end of GetGmTime
#if defined(connect_EXPORTS)
// Added by Alexander Barkov // Added by Alexander Barkov
static time_t mktime_mysql(struct tm *ptm) static time_t mktime_mysql(struct tm *ptm)
{ {
@@ -2499,6 +2504,9 @@ static time_t mktime_mysql(struct tm *ptm)
time_t t= TIME_to_timestamp(current_thd, &ltime, &error_code); time_t t= TIME_to_timestamp(current_thd, &ltime, &error_code);
return error_code ? (time_t) -1 : t; return error_code ? (time_t) -1 : t;
} }
#else
#define mktime_mysql mktime
#endif
/***********************************************************************/ /***********************************************************************/
/* MakeTime: calculates a date value from a tm structures using the */ /* MakeTime: calculates a date value from a tm structures using the */

View File

@@ -236,7 +236,7 @@ template <>
class DllExport TYPVAL<PSZ>: public VALUE { class DllExport TYPVAL<PSZ>: public VALUE {
public: public:
// Constructors // Constructors
TYPVAL(PSZ s); TYPVAL(PSZ s, short c = 0);
TYPVAL(PGLOBAL g, PSZ s, int n, int c); TYPVAL(PGLOBAL g, PSZ s, int n, int c);
// Implementation // Implementation

View File

@@ -291,14 +291,14 @@ bool STRING::Set(char *s, uint n)
} // end of Set } // end of Set
/***********************************************************************/ /***********************************************************************/
/* Append a char* to a STRING. */ /* Append a char* to a STRING. */
/***********************************************************************/ /***********************************************************************/
bool STRING::Append(const char *s, uint ln) bool STRING::Append(const char *s, uint ln, bool nq)
{ {
if (!s) if (!s)
return false; return false;
uint len = Length + ln + 1; uint i, len = Length + ln + 1;
if (len > Size) { if (len > Size) {
char *p = Realloc(len); char *p = Realloc(len);
@@ -312,8 +312,22 @@ bool STRING::Append(const char *s, uint ln)
} // endif n } // endif n
strncpy(Strp + Length, s, ln); if (nq) {
Length = len - 1; for (i = 0; i < ln; i++)
switch (s[i]) {
case '\\': Strp[Length++] = '\\'; Strp[Length++] = '\\'; break;
case '\0': Strp[Length++] = '\\'; Strp[Length++] = '0'; break;
case '\'': Strp[Length++] = '\\'; Strp[Length++] = '\''; break;
case '\n': Strp[Length++] = '\\'; Strp[Length++] = 'n'; break;
case '\r': Strp[Length++] = '\\'; Strp[Length++] = 'r'; break;
case '\032': Strp[Length++] = '\\'; Strp[Length++] = 'Z'; break;
default: Strp[Length++] = s[i];
} // endswitch s[i]
} else
for (i = 0; i < ln && s[i]; i++)
Strp[Length++] = s[i];
Strp[Length] = 0; Strp[Length] = 0;
return false; return false;
} // end of Append } // end of Append

View File

@@ -134,7 +134,7 @@ class DllExport STRING : public BLOCK {
inline void Reset(void) {*Strp = 0;} inline void Reset(void) {*Strp = 0;}
bool Set(PSZ s); bool Set(PSZ s);
bool Set(char *s, uint n); bool Set(char *s, uint n);
bool Append(const char *s, uint ln); bool Append(const char *s, uint ln, bool nq = false);
bool Append(PSZ s); bool Append(PSZ s);
bool Append(STRING &str); bool Append(STRING &str);
bool Append(char c); bool Append(char c);

View File

@@ -19,6 +19,7 @@
#include "m_ctype.h" #include "m_ctype.h"
typedef class CMD *PCMD; typedef class CMD *PCMD;
typedef struct st_key_range key_range;
// Commands executed by XDBC and MYX tables // Commands executed by XDBC and MYX tables
class CMD : public BLOCK { class CMD : public BLOCK {
@@ -32,12 +33,24 @@ class CMD : public BLOCK {
}; // end of class CMD }; // end of class CMD
// Condition filter structure // Condition filter structure
typedef struct _cond_filter { class CONDFIL : public BLOCK {
char *Body; public:
OPVAL Op; // Constructor
PCMD Cmds; CONDFIL(const Item *cond, uint idx, AMT type)
} CONDFIL, *PCFIL; {
Cond = cond; Idx = idx; Type = type; Body = NULL; Op = OP_XX; Cmds = NULL;
}
// Members
const Item *Cond;
AMT Type;
uint Idx;
char *Body;
OPVAL Op;
PCMD Cmds;
}; // end of class CONDFIL
typedef class CONDFIL *PCFIL;
typedef class TDBCAT *PTDBCAT; typedef class TDBCAT *PTDBCAT;
typedef class CATCOL *PCATCOL; typedef class CATCOL *PCATCOL;
@@ -109,7 +122,7 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
virtual int DeleteDB(PGLOBAL, int) = 0; virtual int DeleteDB(PGLOBAL, int) = 0;
virtual void CloseDB(PGLOBAL) = 0; virtual void CloseDB(PGLOBAL) = 0;
virtual int CheckWrite(PGLOBAL) {return 0;} virtual int CheckWrite(PGLOBAL) {return 0;}
virtual bool ReadKey(PGLOBAL, OPVAL, const void *, int) = 0; virtual bool ReadKey(PGLOBAL, OPVAL, const key_range *) = 0;
protected: protected:
// Members // Members
@@ -188,7 +201,7 @@ class DllExport TDBASE : public TDB {
virtual void MarkDB(PGLOBAL g, PTDB tdb2); virtual void MarkDB(PGLOBAL g, PTDB tdb2);
virtual int MakeIndex(PGLOBAL g, PIXDEF, bool) virtual int MakeIndex(PGLOBAL g, PIXDEF, bool)
{strcpy(g->Message, "Remote index"); return RC_INFO;} {strcpy(g->Message, "Remote index"); return RC_INFO;}
virtual bool ReadKey(PGLOBAL, OPVAL, const void *, int) virtual bool ReadKey(PGLOBAL, OPVAL, const key_range *)
{assert(false); return true;} {assert(false); return true;}
protected: protected:

View File

@@ -112,6 +112,7 @@ UNIV_INTERN ulint os_innodb_umask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
#else #else
/** Umask for creating files */ /** Umask for creating files */
UNIV_INTERN ulint os_innodb_umask = 0; UNIV_INTERN ulint os_innodb_umask = 0;
#define ECANCELED 125
#endif /* __WIN__ */ #endif /* __WIN__ */
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP

View File

@@ -117,6 +117,7 @@ UNIV_INTERN ulint os_innodb_umask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
#else #else
/** Umask for creating files */ /** Umask for creating files */
UNIV_INTERN ulint os_innodb_umask = 0; UNIV_INTERN ulint os_innodb_umask = 0;
#define ECANCELED 125
#endif /* __WIN__ */ #endif /* __WIN__ */
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP

View File

@@ -4,7 +4,7 @@ SET(HEIDISQL_URL "http://www.heidisql.com/downloads/releases/${HEIDISQL_ZIP}")
SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME}) SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME})
IF(NOT EXISTS ${HEIDISQL_DOWNLOAD_DIR}/${HEIDISQL_ZIP}) IF(NOT EXISTS ${HEIDISQL_DOWNLOAD_DIR}/${HEIDISQL_ZIP})
MAKE_DIRECTORY(${HEIDISQL_DOWNLOAD_DIR}) MAKE_DIRECTORY(${HEIDISQL_DOWNLOAD_DIR})
MESSAGE(STATUS "Downloading ${HEIDISQL_URL} to ${HEIDISQL_DOWNLOAD_DIR}/${HEIDISQL_ZIP}") MESSAGE(STATUS "Downloading ${HEIDISQL_URL} to ${HEIDISQL_DOWNLOAD_DIR}/${HEIDISQL_ZIP}")
FILE(DOWNLOAD ${HEIDISQL_URL} ${HEIDISQL_DOWNLOAD_DIR}/${HEIDISQL_ZIP} TIMEOUT 60) FILE(DOWNLOAD ${HEIDISQL_URL} ${HEIDISQL_DOWNLOAD_DIR}/${HEIDISQL_ZIP} TIMEOUT 60)
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E chdir ${HEIDISQL_DOWNLOAD_DIR} EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E chdir ${HEIDISQL_DOWNLOAD_DIR}

View File

@@ -10,16 +10,16 @@
</Property> </Property>
<DirectoryRef Id="MariaDBShared"> <DirectoryRef Id="MariaDBShared">
<Directory Id="D.HeidiSQL" Name="HeidiSQL"> <Directory Id="D.HeidiSQL" Name="HeidiSQL">
<Component Id="component.HeidiSQL" Guid="96ea3879-5320-4098-8f26-2f655d2f716c" Win64="no"> <Component Id="component.HeidiSQL" Guid="96ea3879-5320-4098-8f26-2f655d2f716c" Win64="no">
<File Id="heidisql.gpl.txt" Name="gpl.txt" Source="${HEIDISQL_DOWNLOAD_DIR}\gpl.txt" /> <File Id="heidisql.gpl.txt" Name="gpl.txt" Source="${HEIDISQL_DOWNLOAD_DIR}\gpl.txt" />
<File Id="heidisql.heidisql.exe" Name="heidisql.exe" Source="${HEIDISQL_DOWNLOAD_DIR}\heidisql.exe" KeyPath="yes"> <File Id="heidisql.heidisql.exe" Name="heidisql.exe" Source="${HEIDISQL_DOWNLOAD_DIR}\heidisql.exe" KeyPath="yes">
<Shortcut Id="desktopHeidiSQL" Directory="DesktopFolder" Name="HeidiSQL" Advertise="yes"/> <Shortcut Id="desktopHeidiSQL" Directory="DesktopFolder" Name="HeidiSQL" Advertise="yes"/>
</File> </File>
<!-- <!--
Forced file removal for heidisql.exe might be required. Forced file removal for heidisql.exe might be required.
HeidiSQL is self-updating, thus the version that was installed by MSI not necessarily matches HeidiSQL is self-updating, thus the version that was installed by MSI not necessarily matches
the version of the file on uninstall. MSI would not touch such file by default and leave it after the version of the file on uninstall. MSI would not touch such file by default and leave it after
uninstallation. We use RemoveFile to force delete in any case. uninstallation. We use RemoveFile to force delete in any case.
--> -->
<RemoveFile Id="Remove_HeidiSQL_exe" Name="heidisql.exe" On="uninstall" /> <RemoveFile Id="Remove_HeidiSQL_exe" Name="heidisql.exe" On="uninstall" />