velocity-python 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of velocity-python might be problematic. Click here for more details.

@@ -0,0 +1,575 @@
1
+ import re
2
+ import hashlib
3
+ import decimal
4
+ import datetime
5
+ from velocity.db import exceptions
6
+
7
+ def initialize(config):
8
+ from velocity.db.core.engine import Engine
9
+ import mysql.connector
10
+ return Engine(mysql.connector, config, SQL)
11
+
12
+ def make_where(where, sql, vals, is_join=False):
13
+ if not where:
14
+ return
15
+ sql.append('WHERE')
16
+ if isinstance(where, str):
17
+ sql.append(where)
18
+ return
19
+ if isinstance(where,dict):
20
+ where = where.items()
21
+ if isinstance(where,list):
22
+ join = ''
23
+ for key,val in where:
24
+ if join: sql.append(join)
25
+ if is_join:
26
+ if '.' not in key:
27
+ key = 'A.' + key
28
+ if val == None:
29
+ if '!' in key:
30
+ key = key.replace('!','')
31
+ sql.append('{} is not NULL'.format(quote(key.lower())))
32
+ else:
33
+ sql.append('{} is NULL'.format(quote(key.lower())))
34
+ elif isinstance(val,(list,tuple)):
35
+ if '!' in key:
36
+ key = key.replace('!','')
37
+ sql.append('{} not in %s'.format(quote(key.lower())))
38
+ vals.append(tuple(val))
39
+ else:
40
+ sql.append('{} in %s'.format(quote(key.lower())))
41
+ vals.append(tuple(val))
42
+ else:
43
+ if '<>' in key:
44
+ key = key.replace('<>','')
45
+ op = '<>'
46
+ elif '!=' in key:
47
+ key = key.replace('!=','')
48
+ op = '<>'
49
+ elif '!%' in key:
50
+ key = key.replace('!%','')
51
+ op = 'not like'
52
+ elif '%%' in key:
53
+ key = key.replace('%%','')
54
+ op = '%'
55
+ elif '%>' in key:
56
+ key = key.replace('%>','')
57
+ op = '%>'
58
+ elif '<%' in key:
59
+ key = key.replace('<%','')
60
+ op = '<%'
61
+ elif '==' in key:
62
+ key = key.replace('==','')
63
+ op = '='
64
+ elif '<=' in key:
65
+ key = key.replace('<=','')
66
+ op = '<='
67
+ elif '>=' in key:
68
+ key = key.replace('>=','')
69
+ op = '>='
70
+ elif '<' in key:
71
+ key = key.replace('<','')
72
+ op = '<'
73
+ elif '>' in key:
74
+ key = key.replace('>','')
75
+ op = '>'
76
+ elif '%' in key:
77
+ key = key.replace('%','')
78
+ op = 'like'
79
+ elif '!' in key:
80
+ key = key.replace('!','')
81
+ op = '<>'
82
+ elif '=' in key:
83
+ key = key.replace('=','')
84
+ op = '='
85
+ else:
86
+ op = '='
87
+ if isinstance(val,str) and val[:2] == '@@':
88
+ sql.append('{} {} {}'.format(quote(key.lower()), op, val[2:]))
89
+ else:
90
+ if 'like' in op:
91
+ sql.append('lower({}) {} lower(%s)'.format(quote(key.lower()), op))
92
+ else:
93
+ sql.append('{} {} %s'.format(quote(key.lower()), op))
94
+ vals.append(val)
95
+ join = 'AND'
96
+
97
+ def quote(data):
98
+ if isinstance(data, list):
99
+ new = []
100
+ for item in data:
101
+ new.append(quote(item))
102
+ return new
103
+ else:
104
+ parts = data.split('.')
105
+ new = []
106
+ for part in parts:
107
+ if '`' in part:
108
+ new.append(part)
109
+ elif part.upper() in reserved_words:
110
+ new.append('`'+part+'`')
111
+ elif re.findall('[/]',part):
112
+ new.append('`'+part+'`')
113
+ else:
114
+ new.append(part)
115
+ return '.'.join(new)
116
+
117
+ class SQL:
118
+ server = "MySQL"
119
+ type_column_identifier = 'DATA_TYPE'
120
+ is_nullable = 'IS_NULLABLE'
121
+
122
+ default_schema = 'mydb'
123
+
124
+ ApplicationErrorCodes = []
125
+
126
+ DatabaseMissingErrorCodes = []
127
+ TableMissingErrorCodes = [1146]
128
+ ColumnMissingErrorCodes = [1054]
129
+ ForeignKeyMissingErrorCodes =[]
130
+
131
+ ConnectionErrorCodes = []
132
+ DuplicateKeyErrorCodes = [] # Handled in regex check.
133
+ RetryTransactionCodes = []
134
+ TruncationErrorCodes = []
135
+ LockTimeoutErrorCodes = []
136
+ DatabaseObjectExistsErrorCodes = []
137
+
138
+ @classmethod
139
+ def __has_pointer(cls,columns):
140
+ if columns:
141
+ if isinstance(columns,list):
142
+ columns = ','.join(columns)
143
+ if '>' in columns:
144
+ return True
145
+ return False
146
+
147
+ @classmethod
148
+ def alter_add(cls, table, columns, null_allowed=True):
149
+ sql = []
150
+ null = 'NOT NULL' if not null_allowed else ''
151
+ if isinstance(columns,dict):
152
+ for key,val in columns.items():
153
+ key = re.sub('<>!=%', '', key.lower())
154
+ sql.append("ALTER TABLE {} ADD {} {} {};".format(quote(table), quote(key), cls.get_type(val), null))
155
+ return '\n\t'.join(sql), tuple()
156
+
157
+ @classmethod
158
+ def columns(cls, name):
159
+ if '.' in name:
160
+ return """
161
+ SELECT COLUMN_NAME
162
+ FROM INFORMATION_SCHEMA.columns
163
+ WHERE TABLE_SCHEMA = %s
164
+ AND TABLE_NAME = %s
165
+ """, tuple(name.split('.'))
166
+ else:
167
+ return """
168
+ SELECT COLUMN_NAME
169
+ FROM INFORMATION_SCHEMA.columns
170
+ WHERE TABLE_SCHEMA = %s
171
+ """, tuple([name,])
172
+
173
+ @classmethod
174
+ def create_foreign_key(cls, table, columns, key_to_table, key_to_columns, name=None, schema=None):
175
+ if '.' not in table and schema:
176
+ if schema == None:
177
+ schema = cls.default_schema
178
+ table = "{}.{}".format(schema,table)
179
+ if isinstance(key_to_columns, str):
180
+ key_to_columns = [key_to_columns]
181
+ if isinstance(columns, str):
182
+ columns = [columns]
183
+ if not name:
184
+ m = hashlib.md5()
185
+ m.update(table)
186
+ m.update(' '.join(columns))
187
+ m.update(key_to_table)
188
+ m.update(' ' .join(key_to_columns))
189
+ name = 'FK_' + m.hexdigest()
190
+ sql = "ALTER TABLE {} ADD CONSTRAINT {} FOREIGN KEY ({}) REFERENCES {} ({}) ON DELETE CASCADE ON UPDATE CASCADE;".format(table, name, ','.join(columns), key_to_table, ','.join(key_to_columns))
191
+
192
+ return sql, tuple()
193
+
194
+ @classmethod
195
+ def create_index(cls, table=None, columns=None, unique=False, direction=None, where=None, name=None, schema=None, trigram=None, tbl=None):
196
+ if '.' not in table and schema:
197
+ table = "{}.{}".format(schema,table)
198
+ if isinstance(columns,(list,set)):
199
+ columns = ','.join([quote(c.lower()) for c in sorted(columns)])
200
+ else:
201
+ columns = quote(columns)
202
+ sql = ['CREATE']
203
+ if unique:
204
+ sql.append('UNIQUE')
205
+ sql.append('INDEX')
206
+ tablename = quote(table)
207
+ if not name:
208
+ name = re.sub(r'\([^)]*\)', '', columns.replace(',','_'))
209
+ sql.append('IDX__{}__{}'.format(table.replace('.','_'),name))
210
+ sql.append('ON')
211
+ sql.append(tablename)
212
+ sql.append('(')
213
+ sql.append(columns)
214
+ sql.append(')')
215
+ return ' '.join(sql), tuple()
216
+
217
+ @classmethod
218
+ def create_table(cls, name, columns={}, drop=False):
219
+ trigger = ''.format(name)
220
+ sql = []
221
+ if drop:
222
+ sql.append(cls.drop_table(name))
223
+ sql.append("""
224
+ CREATE TABLE {0} (
225
+ sys_id SERIAL PRIMARY KEY AUTO_INCREMENT,
226
+ sys_modified TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
227
+ sys_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
228
+ )ENGINE=InnoDB AUTO_INCREMENT=1000;
229
+ """.format(quote(name)))
230
+
231
+ for key,val in columns.items():
232
+ key = re.sub('<>!=%', '', key.lower())
233
+ if key in ['sys_id','sys_created','sys_modified']:
234
+ continue
235
+ sql.append("ALTER TABLE {} ADD COLUMN {} {};".format(quote(name),quote(key),cls.get_type(val)))
236
+ return '\n\t'.join(sql), tuple()
237
+
238
+ @classmethod
239
+ def delete(cls, table, where):
240
+ sql = ['DELETE FROM {}'.format(table)]
241
+ vals = []
242
+ make_where(where, sql, vals)
243
+ return ' '.join(sql), tuple(vals)
244
+
245
+ @classmethod
246
+ def drop_table(cls, name):
247
+ return "DROP TABLE IF EXISTS %s CASCADE;" % quote(name), tuple()
248
+
249
+ @classmethod
250
+ def foreign_key_info(cls,table=None,column=None,schema=None):
251
+ if '.' in table:
252
+ schema, table = table.split('.')
253
+
254
+ sql = ["""
255
+ SELECT
256
+ TABLE_NAME AS FK_TABLE_NAME
257
+ ,COLUMN_NAME AS FK_COLUMN_NAME
258
+ ,CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME
259
+ ,REFERENCED_TABLE_NAME
260
+ ,REFERENCED_COLUMN_NAME
261
+ FROM
262
+ INFORMATION_SCHEMA.KEY_COLUMN_USAGE
263
+ """]
264
+ vals = []
265
+ where = {}
266
+ if schema:
267
+ where['LOWER(REFERENCED_TABLE_SCHEMA)'] = schema.lower()
268
+ if table:
269
+ where['LOWER(REFERENCED_TABLE_NAME)'] = table.lower()
270
+ if column:
271
+ where['LOWER(REFERENCED_COLUMN_NAME)'] = column.lower()
272
+ make_where(where, sql, vals)
273
+ return ' '.join(sql), tuple(vals)
274
+
275
+ @classmethod
276
+ def get_type(cls, v):
277
+ if isinstance(v, str):
278
+ if v[:2] == '@@':
279
+ return v[2:] or cls.TYPES.TEXT
280
+ elif isinstance(v, (str, bytes)) \
281
+ or v is str \
282
+ or v is bytes:
283
+ return cls.TYPES.TEXT
284
+ elif isinstance(v, bool) \
285
+ or v is bool:
286
+ return cls.TYPES.BOOLEAN
287
+ elif isinstance(v, int) \
288
+ or v is int:
289
+ if v is int:
290
+ return cls.TYPES.INTEGER
291
+ if v > 2147483647 or v < -2147483648:
292
+ return cls.TYPES.BIGINT
293
+ else:
294
+ return cls.TYPES.INTEGER
295
+ elif isinstance(v, float) \
296
+ or v is float:
297
+ return cls.TYPES.NUMERIC + '(19, 6)'
298
+ elif isinstance(v, decimal.Decimal) \
299
+ or v is decimal.Decimal:
300
+ return cls.TYPES.NUMERIC + '(19, 6)'
301
+ elif isinstance (v, datetime.datetime) \
302
+ or v is datetime.datetime:
303
+ return cls.TYPES.DATETIME
304
+ elif isinstance (v, datetime.date) \
305
+ or v is datetime.date:
306
+ return cls.TYPES.DATE
307
+ elif isinstance(v, datetime.time) \
308
+ or v is datetime.time:
309
+ return cls.TYPES.TIME
310
+ elif isinstance(v, datetime.timedelta) \
311
+ or v is datetime.timedelta:
312
+ return cls.TYPES.INTERVAL
313
+ elif isinstance (v, bytearray) \
314
+ or v is bytearray:
315
+ return cls.TYPES.BINARY
316
+ # Everything else defaults to TEXT, incl. None
317
+ return cls.TYPES.TEXT
318
+
319
+ @classmethod
320
+ def insert(cls, table, data):
321
+ keys = []
322
+ vals = []
323
+ args = []
324
+ for key,val in data.items():
325
+ keys.append(quote(key.lower()))
326
+ if isinstance(val,str) \
327
+ and len(val) > 2 \
328
+ and val[:2] == '@@':
329
+ vals.append(val[2:])
330
+ else:
331
+ vals.append('%s')
332
+ args.append(val)
333
+
334
+ sql = ['INSERT INTO']
335
+ sql.append(quote(table))
336
+ sql.append('(')
337
+ sql.append(','.join(keys))
338
+ sql.append(')')
339
+ sql.append('VALUES')
340
+ sql.append('(')
341
+ sql.append(','.join(vals))
342
+ sql.append(')')
343
+ sql = ' '.join(sql)
344
+ return sql, tuple(args)
345
+
346
+ @classmethod
347
+ def last_id(cls, table):
348
+ return "SELECT LAST_INSERT_ID();",tuple()
349
+
350
+ @classmethod
351
+ def create_savepoint(cls, sp):
352
+ return None, tuple()
353
+
354
+ @classmethod
355
+ def rollback_savepoint(cls, sp):
356
+ return None, tuple()
357
+
358
+ @classmethod
359
+ def release_savepoint(cls, sp):
360
+ return None, tuple()
361
+
362
+ @classmethod
363
+ def create_view(cls, name, query, temp=False, silent=True):
364
+ sql = ['CREATE']
365
+ if silent:
366
+ sql.append('OR REPLACE')
367
+ if temp:
368
+ sql.append('TEMPORARY')
369
+ sql.append('VIEW')
370
+ sql.append(name)
371
+ sql.append('AS')
372
+ sql.append(query)
373
+ return ' '.join(sql),tuple()
374
+
375
+ @classmethod
376
+ def drop_view(cls, name, silent=True):
377
+ sql = ['DROP VIEW']
378
+ if silent:
379
+ sql.append('IF EXISTS')
380
+ sql.append(name)
381
+ return ' '.join(sql),tuple()
382
+
383
+ @classmethod
384
+ def rename_column(cls, table, orig, new):
385
+ return "ALTER TABLE {} RENAME COLUMN {} TO {};".format(quote(table), quote(orig), quote(new)), tuple()
386
+
387
+ @classmethod
388
+ def select(cls,columns=None,table=None,where=None,orderby=None,groupby=None,having=None,start=None,qty=None,tbl=None):
389
+ is_join = False
390
+
391
+ if isinstance(columns,str)\
392
+ and 'distinct' in columns.lower():
393
+ sql = [
394
+ 'SELECT',
395
+ columns,
396
+ 'FROM',
397
+ quote(table),
398
+ ]
399
+ elif cls.__has_pointer(columns):
400
+ is_join = True
401
+ if isinstance(columns,str):
402
+ columns = columns.split(',')
403
+ letter = 65
404
+ tables = {table: chr(letter)}
405
+ letter += 1
406
+ __select = []
407
+ __from = ['{} AS {}'.format(quote(table),tables.get(table))]
408
+ __left_join = []
409
+
410
+ for column in columns:
411
+ if '>' in column:
412
+ is_join = True
413
+ parts = column.split('>')
414
+ foreign = tbl.foreign_key_info(parts[0])
415
+ if not foreign:
416
+ raise exceptions.DbApplicationError("Foreign key not defined")
417
+ ref_table = foreign['referenced_table_name']
418
+ ref_schema = foreign['referenced_table_schema']
419
+ ref_column = foreign['referenced_column_name']
420
+ lookup = "{}:{}".format(ref_table,parts[0])
421
+ if tables.has_key(lookup):
422
+ __select.append('{}."{}" as "{}"'.format(tables.get(lookup),parts[1],'_'.join(parts)))
423
+ else:
424
+ tables[lookup] = chr(letter)
425
+ letter += 1
426
+ __select.append('{}."{}" as "{}"'.format(tables.get(lookup),parts[1],'_'.join(parts)))
427
+ __left_join.append('LEFT OUTER JOIN "{}"."{}" AS {}'.format(ref_schema,ref_table,tables.get(lookup)))
428
+ __left_join.append('ON {}."{}" = {}."{}"'.format(
429
+ tables.get(table),
430
+ parts[0],
431
+ tables.get(lookup),
432
+ ref_column
433
+ ))
434
+ if orderby and column in orderby:
435
+ orderby = orderby.replace(column,"{}.{}".format(tables.get(lookup),parts[1]))
436
+
437
+ else:
438
+ if '(' in column:
439
+ __select.append(column)
440
+ else:
441
+ __select.append("{}.{}".format(tables.get(table),column))
442
+ sql = ['SELECT']
443
+ sql.append(','.join(__select))
444
+ sql.append('FROM')
445
+ sql.extend(__from)
446
+ sql.extend(__left_join)
447
+ else:
448
+ if columns:
449
+ if isinstance(columns,str):
450
+ columns = columns.split(',')
451
+ if isinstance(columns,list):
452
+ columns = quote(columns)
453
+ columns = ','.join(columns)
454
+ else:
455
+ columns = '*'
456
+ sql = [
457
+ 'SELECT',
458
+ columns,
459
+ 'FROM',
460
+ quote(table),
461
+ ]
462
+ vals = []
463
+ make_where(where, sql, vals, is_join)
464
+ if groupby:
465
+ sql.append('GROUP BY')
466
+ if isinstance(groupby,(list,tuple)):
467
+ groupby = ','.join(groupby)
468
+ sql.append(groupby)
469
+ if having:
470
+ sql.append('HAVING')
471
+ if isinstance(having,(list,tuple)):
472
+ having = ','.join(having)
473
+ sql.append(having)
474
+ if orderby:
475
+ sql.append('ORDER BY')
476
+ if isinstance(orderby,(list,tuple)):
477
+ orderby = ','.join(orderby)
478
+ sql.append(orderby)
479
+ if start and qty:
480
+ sql.append('OFFSET {} ROWS FETCH NEXT {} ROWS ONLY'.format(start,qty))
481
+ elif start:
482
+ sql.append('OFFSET {} ROWS'.format(start))
483
+ elif qty:
484
+ sql.append('FETCH NEXT {} ROWS ONLY'.format(qty))
485
+ sql = ' '.join(sql)
486
+ return sql, tuple(vals)
487
+
488
+ @classmethod
489
+ def update(cls, table, data, pk):
490
+ sql = ['UPDATE']
491
+ sql.append(quote(table))
492
+ sql.append('SET')
493
+ vals = []
494
+ join = ''
495
+ for key in data.keys():
496
+ val = data[key]
497
+ if join:
498
+ sql.append(join)
499
+ if isinstance(val,str) and val[:2] == '@@':
500
+ sql.append("{} = {}".format(quote(key.lower()),val[2:]))
501
+ else:
502
+ sql.append('{} = %s'.format(quote(key.lower())))
503
+ vals.append(val)
504
+ join = ','
505
+ make_where(pk, sql, vals)
506
+ return ' '.join(sql), tuple(vals)
507
+
508
+ @classmethod
509
+ def upsert(cls, table, data, pk):
510
+ keys = []
511
+ vals = []
512
+ args = []
513
+ for key,val in data.items():
514
+ keys.append(quote(key.lower()))
515
+ if isinstance(val,str) \
516
+ and len(val) > 2 \
517
+ and val[:2] == '@@':
518
+ vals.append(val[2:])
519
+ else:
520
+ vals.append('%s')
521
+ args.append(val)
522
+ for key,val in pk.items():
523
+ keys.append(quote(key.lower()))
524
+ if isinstance(val,str) \
525
+ and len(val) > 2 \
526
+ and val[:2] == '@@':
527
+ vals.append(val[2:])
528
+ else:
529
+ vals.append('%s')
530
+ args.append(val)
531
+ sql = ['INSERT INTO']
532
+ sql.append(quote(table))
533
+ sql.append('(')
534
+ sql.append(','.join(keys))
535
+ sql.append(')')
536
+ sql.append('VALUES')
537
+ sql.append('(')
538
+ sql.append(','.join(vals))
539
+ sql.append(')')
540
+ sql.append('ON DUPLICATE KEY UPDATE')
541
+ join = ''
542
+ for key in data.keys():
543
+ val = data[key]
544
+ if join:
545
+ sql.append(join)
546
+ if isinstance(val,str) and val[:2] == '@@':
547
+ sql.append("{} = {}".format(quote(key.lower()),val[2:]))
548
+ else:
549
+ sql.append('{} = %s'.format(quote(key.lower())))
550
+ args.append(val)
551
+ join = ','
552
+ return ' '.join(sql), tuple(args)
553
+
554
+ @classmethod
555
+ def views(cls, system=False):
556
+ if system:
557
+ return "SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.tables WHERE TABLE_TYPE LIKE 'VIEW';", tuple()
558
+ else:
559
+ return "SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.tables WHERE TABLE_TYPE LIKE 'VIEW';", tuple()
560
+
561
+ class TYPES(object):
562
+ TEXT = 'TEXT'
563
+ INTEGER = 'INTEGER'
564
+ NUMERIC = 'NUMERIC'
565
+ DATETIME = 'DATETIME'
566
+ TIMESTAMP = 'TIMESTAMP'
567
+ DATE = 'DATE'
568
+ TIME = 'TIME'
569
+ BIGINT = 'BIGINT'
570
+ SMALLINT = 'SMALLINT'
571
+ BOOLEAN = 'BIT'
572
+ BINARY = 'BLOB'
573
+ INTERVAL = 'INTERVAL'
574
+
575
+ reserved_words = ['ACCESSIBLE','ADD','ALL','ALTER','ANALYZE','AND','AS','ASC','ASENSITIVE','BEFORE','BETWEEN','BIGINT','BINARY','BLOB','BOTH','BY','CALL','CASCADE','CASE','CHANGE','CHAR','CHARACTER','CHECK','COLLATE','COLUMN','CONDITION','CONSTRAINT','CONTINUE','CONVERT','CREATE','CROSS','CURRENT_DATE','CURRENT_TIME','CURRENT_TIMESTAMP','CURRENT_USER','CURSOR','DATABASE','DATABASES','DAY_HOUR','DAY_MICROSECOND','DAY_MINUTE','DAY_SECOND','DEC','DECIMAL','DECLARE','DEFAULT','DELAYED','DELETE','DESC','DESCRIBE','DETERMINISTIC','DISTINCT','DISTINCTROW','DIV','DOUBLE','DROP','DUAL','EACH','ELSE','ELSEIF','ENCLOSED','ESCAPED','EXISTS','EXIT','EXPLAIN','FALSE','FETCH','FLOAT','FLOAT4','FLOAT8','FOR','FORCE','FOREIGN','FROM','FULLTEXT','GENERAL','GRANT','GROUP','HAVING','HIGH_PRIORITY','HOUR_MICROSECOND','HOUR_MINUTE','HOUR_SECOND','IF','IGNORE','IGNORE_SERVER_IDS','IN','INDEX','INFILE','INNER','INOUT','INSENSITIVE','INSERT','INT','INT1','INT2','INT3','INT4','INT8','INTEGER','INTERVAL','INTO','IS','ITERATE','JOIN','KEY','KEYS','KILL','LEADING','LEAVE','LEFT','LIKE','LIMIT','LINEAR','LINES','LOAD','LOCALTIME','LOCALTIMESTAMP','LOCK','LONG','LONGBLOB','LONGTEXT','LOOP','LOW_PRIORITY','MASTER_HEARTBEAT_PERIOD','MASTER_SSL_VERIFY_SERVER_CERT','MATCH','MAXVALUE','MEDIUMBLOB','MEDIUMINT','MEDIUMTEXT','MIDDLEINT','MINUTE_MICROSECOND','MINUTE_SECOND','MOD','MODIFIES','NATURAL','NOT','NO_WRITE_TO_BINLOG','NULL','NUMERIC','ON','OPTIMIZE','OPTION','OPTIONALLY','OR','ORDER','OUT','OUTER','OUTFILE','PRECISION','PRIMARY','PROCEDURE','PROXY','PURGE','RANGE','READ','READS','READ_WRITE','REAL','REFERENCES','REGEXP','RELAY','RELEASE','RENAME','REPEAT','REPLACE','REQUIRE','RESIGNAL','RESTRICT','RETURN','REVOKE','RIGHT','RLIKE','SCHEMA','SCHEMAS','SECOND_MICROSECOND','SELECT','SENSITIVE','SEPARATOR','SET','SHOW','SIGNAL','SLOW','SMALLINT','SPATIAL','SPECIFIC','SQL','SQLEXCEPTION','SQLSTATE','SQLWARNING','SQL_BIG_RESULT','SQL_CALC_FOUND_ROWS','SQL_SMALL_RESULT','SSL','STARTING','STRAIGHT_JOIN','TABLE','TERMINATED','THEN','TIMESTAMP','TINYBLOB','TINYINT','TINYTEXT','TO','TRAILING','TRIGGER','TRUE','UNDO','UNION','UNIQUE','UNLOCK','UNSIGNED','UPDATE','USAGE','USE','USING','UTC_DATE','UTC_TIME','UTC_TIMESTAMP','VALUES','VARBINARY','VARCHAR','VARCHARACTER','VARYING','WHEN','WHERE','WHILE','WITH','WRITE','XOR','YEAR_MONTH','ZEROFILL']