Merge lp:~nahiljain/to-drizzle/parse_create_table into lp:to-drizzle

Proposed by neh
Status: Merged
Merged at revision: 8
Proposed branch: lp:~nahiljain/to-drizzle/parse_create_table
Merge into: lp:to-drizzle
Diff against target: 807 lines (+375/-84)
4 files modified
movetodrizzle/helpers/lexer.py (+5/-6)
movetodrizzle/helpers/parser.py (+118/-59)
movetodrizzle/helpers/statement_nodes.py (+30/-9)
tests/parser_createtable_test.py (+222/-10)
To merge this branch: bzr merge lp:~nahiljain/to-drizzle/parse_create_table
Reviewer Review Type Date Requested Status
Jay Pipes Needs Fixing
Review via email: mp+30552@code.launchpad.net

Description of the change

more test cases for parsing create table... made changes and stored values of length,binary etc

To post a comment you must log in.
Revision history for this message
Jay Pipes (jaypipes) wrote :

Hi!

Looks good, Nahil, but there's a few issues to fix up!

1) There is some extra print happening in the parse create table test case, as shown in the output here:

jpipes@serialcoder:~/repos/movetodrizzle/parse_create_table/tests$ ./parser_createtable_test.py
............[['AUTO_INCREMENT', 5]]
.
----------------------------------------------------------------------
Ran 13 tests in 0.009s

OK

Remove the printing of the [[AUTO_INCREMENT', 5]]

2) Remove all commented-out code:

60 +# '''foreign_key_constraint : FOREIGN KEY LPAREN index_col_name_list RPAREN reference_definition'''

174 +
175 +#def p_data_types(p):
176 +# '''data_type : mathematical'''
177 +# p[0]= p[1]
178 +
179 +
180 +

303 +#print parse_string("INSERT INTO neh1 VALUES (123,456,'abc');")
304 +#print parse_string("INSERT INTO neh1 SET a1=10,b2=25;")

491 +# constraint_name= False) (index_name=None) (parent_fields= ['field1']) (reference= Reference(name= reftable) (col_name_list= ['ref_field1']) (match_option= False) (on_delete= False) (on_update= False))])]

3) Please, please be consistent in your code and spacing. :)

134 + if(len(p)>3):
135 + p[0]=p[3]

Please put a single space between if and the (

Please put a single space before and after the >

Please put a single space after the =

There are more places where the style is inconsistent. Please do fix them up :)

4) Tabs and spacing is off in your code. For instance:

188 - '''temporary : TEMPORARY
189 + '''temporary : TEMPORARY
190 | empty'''
191 - # Returns True if the TEMPORARY phrase appeared, False otherwise
192 - p[0]= len(p) > 1
193 + # Returns True if the TEMPORARY phrase appeared, False otherwise
194 + p[0]= len(p) > 1

For some reason, you are re-setting Tabs to a single space. Please make sure all indentation is exactly 2 spaces.

5) Returned data_type should not be a list.

357 - self.assertEqual(str(ct.columns[0].data_type), "INT")
358 + self.assertEqual(str(ct.columns[0].data_type[0]), "INT")

Above, the columns[0].data_type should be "INT", not ["INT"] ...

Cheers!

jay

review: Needs Fixing

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'movetodrizzle/helpers/lexer.py'
2--- movetodrizzle/helpers/lexer.py 2010-07-07 22:04:33 +0000
3+++ movetodrizzle/helpers/lexer.py 2010-07-22 18:42:46 +0000
4@@ -59,9 +59,7 @@
5 'constraint' : 'CONSTRAINT',
6 'constraint' : 'CONSTRAINT',
7 'references' : 'REFERENCES',
8- 'match' : 'MATCH',
9 'full' : 'FULL',
10- 'match' : 'MATCH',
11 'partial' : 'PARTIAL',
12 'match' : 'MATCH',
13 'simple' : 'SIMPLE',
14@@ -71,7 +69,8 @@
15 'cascade' : 'CASCADE',
16 'no' : 'NO',
17 'action' : 'ACTION',
18- 'delete' : 'DELETE'
19+ 'delete' : 'DELETE',
20+ 'comment' : 'COMMENT'
21
22
23 }
24@@ -87,7 +86,7 @@
25 'SEMICOLON',
26 'NUMBER',
27 'FLOAT_NUMBER',
28- 'COMMENT',
29+ 'COMMENT_CODE',
30 'IDENTIFIER',
31 'STRING',
32 'DOT',
33@@ -102,7 +101,7 @@
34 t_RPAREN = r'\)'
35 t_COMMA = r'\,'
36 t_SEMICOLON = r'\;'
37-t_DOT= r'.'
38+t_DOT= r'\.'
39 t_EQUAL= r'\='
40
41 def t_NUMBER(t):
42@@ -130,7 +129,7 @@
43 return t
44
45 #Define a rule so that we process comments
46-def t_COMMENT(t):
47+def t_COMMENT_CODE(t):
48 r'\/\*.*\*\/'
49 pass
50
51
52=== modified file 'movetodrizzle/helpers/parser.py'
53--- movetodrizzle/helpers/parser.py 2010-07-15 16:41:56 +0000
54+++ movetodrizzle/helpers/parser.py 2010-07-22 18:42:46 +0000
55@@ -4,7 +4,6 @@
56 from lexer import *
57 import re
58 from statement_nodes import *
59-
60 # Begin grammar rules
61 def p_statement_list(p):
62 '''statement_list : statement_list statement'''
63@@ -23,7 +22,7 @@
64 p[0]=p[1]
65
66 def p_create_table_simple(p):
67- '''create_table_simple : CREATE temporary TABLE if_not_exists identifier_qualified_opt LPAREN col_list RPAREN table_options'''
68+ '''create_table_simple : CREATE temporary TABLE if_not_exists identifier_qualified_non_qualified_opt LPAREN col_list RPAREN table_options'''
69 a= CreateTableStatement(p[5], p[7], p[4], p[2])
70 a.update_table_options(p[9]);
71 p[0]= a
72@@ -31,17 +30,23 @@
73 def p_table_options(p):
74 '''table_options : table_option table_options
75 | empty'''
76- if(len(p)>2):
77+ if (len(p) > 2):
78 p[0]= [p[1]] + p[2]
79 else:
80 p[0]= []
81+
82+def p_identifier_qualified_non_qualified_opt(p):
83+ '''identifier_qualified_non_qualified_opt : identifier_qualified_opt
84+ | identifier_non_qualified_opt'''
85+ p[0]= p[1]
86+
87
88 def p_qualified_identifier(p):
89 '''identifier_qualified_opt : IDENTIFIER DOT IDENTIFIER'''
90 p[0]= Identifier(p[1], p[3])
91
92 def p_non_qualified_identifier(p):
93- '''identifier_qualified_opt : IDENTIFIER
94+ '''identifier_non_qualified_opt : IDENTIFIER
95 | STRING'''
96 p[0]= Identifier(p[1])
97
98@@ -57,11 +62,11 @@
99 def p_col(p):
100 '''col : col_conditional
101 | col_normal'''
102- p[0]=p[1]
103+ p[0]= p[1]
104
105 def p_col_conditional(p):
106 '''col_conditional : foreign_key_constraint'''
107- p[0]=p[1]
108+ p[0]= p[1]
109
110 def p_foreign_key_constraint(p):
111 '''foreign_key_constraint : constraint_opt FOREIGN KEY index_name_opt LPAREN index_col_name_list RPAREN reference_definition'''
112@@ -71,23 +76,29 @@
113 '''constraint_opt : CONSTRAINT
114 | CONSTRAINT identifier
115 | empty'''
116- if(len(p)>2):
117+ if (len(p) > 2):
118 p[0]= p[2]
119 else:
120- p[0]= len(p)>2
121+ p[0]= len(p) > 2
122 def p_index_name_opt(p):
123 '''index_name_opt : identifier
124 | empty '''
125- p[0]=p[1]
126+ if(len(p) > 1):
127+ p[0]= p[1]
128+ else:
129+ p[0]= len(p)>1
130+
131
132 def p_index_col_name_list(p):
133 '''index_col_name_list : index_col_name COMMA index_col_name_list
134 | index_col_name'''
135- if(len(p)>2):
136+ if (len(p) > 2):
137 p[0]= [p[1]]+ p[3]
138 else:
139 p[0]= [p[1]]
140
141+
142+
143 def p_index_col_name(p):
144 '''index_col_name : identifier'''
145 p[0]= p[1]
146@@ -101,26 +112,26 @@
147 | MATCH PARTIAL
148 | MATCH SIMPLE
149 | empty'''
150- if(len(p)>2):
151+ if (len(p) == 3):
152 p[0]= p[2]
153 else:
154- p[0]= len(p)>2
155+ p[0]= len(p) > 2
156
157 def p_on_delete_option(p):
158 '''on_delete_option : ON DELETE reference_options
159 | empty'''
160- if(len(p)>3):
161- p[0]= p[2]
162+ if (len(p) > 3):
163+ p[0]= p[3]
164 else:
165- p[0]= len(p)>3
166+ p[0]= len(p) > 3
167
168 def p_on_update_option(p):
169 '''on_update_option : ON UPDATE reference_options
170 | empty'''
171- if(len(p)>3):
172- p[0]= p[2]
173+ if (len(p) > 3):
174+ p[0]= p[3]
175 else:
176- p[0]= len(p)>3
177+ p[0]= len(p) > 3
178
179 def p_reference_options(p):
180 '''reference_options : RESTRICT
181@@ -128,12 +139,12 @@
182 | SET NULL
183 | NO ACTION
184 | empty'''
185- if(len(p)==2):
186- p[0]=p[1]
187- elif(len(p)==3):
188- p[0]=str(p[1])+str(p[2])
189+ if (len(p) == 2):
190+ p[0]= p[1]
191+ elif (len(p) == 3):
192+ p[0]= str(p[1])+str(p[2])
193 else:
194- p[0]=None
195+ p[0]= None
196
197 def p_col_normal(p):
198 '''col_normal : col_definition'''
199@@ -141,8 +152,10 @@
200
201 def p_col_definition(p):
202 '''col_definition : identifier data_type nullable_constraint default_p auto_increment_p unique_p primary_key comment_p'''
203+
204 p[0]= ColumnDefinition(p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8])
205
206+
207 def p_nullable_constraint(p):
208 '''nullable_constraint : NOT NULL
209 | NULL
210@@ -152,7 +165,7 @@
211 def p_default_p(p):
212 '''default_p : DEFAULT identifier
213 | empty'''
214- if(len(p) > 2):
215+ if (len(p) > 2):
216 p[0]= p[2]
217 else:
218 p[0]= None
219@@ -174,15 +187,15 @@
220 p[0]= len(p) > 2
221
222 def p_comment_p(p):
223- '''comment_p : COMMENT STRING
224+ '''comment_p : COMMENT STRING
225 | empty'''
226- if(len(p)>2):
227- p[0]= p[2]
228- else:
229- p[0]= len(p)>2
230+ if (len(p) > 2):
231+ p[0]= p[2]
232+ else:
233+ p[0]= len(p) > 2
234
235-def p_data_types(p):
236- '''data_type : BIT
237+def p_data_types_1(p):
238+ '''data_type : BIT
239 | mathematical length_opt unsigned_opt zerofill_opt
240 | DATE
241 | TIME
242@@ -195,15 +208,34 @@
243 | TINYBLOB
244 | BLOB
245 | MEDIUMBLOB
246- | LONGBLOB
247- | texts binary_opt character_set_opt collate_opt
248+ | LONGBLOB'''
249+ p[0]= DataTypeDesc(p[1])
250+ if (len(p) == 1):
251+ p[0]= [p[1]]
252+ if (len(p) == 5):
253+ if(p[2] == False):
254+ length= None;
255+ decimal= None;
256+ elif(len(p[2]) == 2):
257+ length= p[2][0];
258+ decimal= p[2][1];
259+ else:
260+ length= p[2][0];
261+ decimal= None;
262+ p[0]=DataTypeDesc(p[1],length,decimal,p[3],p[4])
263+ if (len(p) == 4):
264+ p[0]= DataTypeDesc(p[1],None,None,None,None,p[2],p[3])
265+
266+def p_data_types_2(p):
267+ '''data_type : texts binary_opt character_set_opt collate_opt
268 | set_enum character_set_opt collate_opt'''
269- p[0]= p[1]
270+ p[0]= DataTypeDesc(p[1]);
271
272 def p_set_enum(p):
273 '''set_enum : SET LPAREN value_list RPAREN
274 | ENUM LPAREN value_list RPAREN'''
275- p[0]=p[1]
276+ p[0]= p[1]
277+
278
279 def p_value_list(p):
280 '''value_list : STRING COMMA value_list
281@@ -229,29 +261,47 @@
282 def p_character_set_opt(p):
283 '''character_set_opt : CHARACTER SET identifier
284 | empty'''
285- pass
286+ if (len(p) > 3):
287+ p[0]= p[3]
288+ else:
289+ p[0]= len(p) > 3
290
291 def p_collate_opt(p):
292 '''collate_opt : COLLATE identifier
293 | empty'''
294- pass
295+ if (len(p) > 2):
296+ p[0]= p[2]
297+ else:
298+ p[0]= len(p) > 2
299
300 def p_length_opt(p):
301 '''length_opt : LPAREN NUMBER RPAREN
302 | LPAREN NUMBER COMMA NUMBER RPAREN
303 | empty'''
304- pass
305+ if (len(p) >= 6):
306+ p[0]= [p[2],p[4]]
307+
308+ elif (len(p) == 4):
309+ p[0]= [p[2]]
310+ else:
311+ p[0]= len(p) > 6;
312+
313+
314
315 def p_unsigned_opt(p):
316 '''unsigned_opt : UNSIGNED
317 | empty'''
318- pass
319+ p[0]= len(p) > 1
320+
321
322 def p_zerofill_opt(p):
323 '''zerofill_opt : ZEROFILL
324 | empty'''
325- pass
326-
327+ p[0]= len(p) > 1
328+
329+
330+
331+
332 def p_mathematical(p):
333 '''mathematical : TINYINT
334 | SMALLINT
335@@ -268,7 +318,7 @@
336 def p_optional_temporary(p):
337 '''temporary : TEMPORARY
338 | empty'''
339- # Returns True if the TEMPORARY phrase appeared, False otherwise
340+ # Returns True if the TEMPORARY phrase appeared, False otherwise
341 p[0]= len(p) > 1
342
343 def p_create_schema(p):
344@@ -295,41 +345,45 @@
345 p[0]= CreateSchemaStatement(p[4], p[6], p[8], p[3])
346
347 def p_optional_if_not_exists(p):
348- '''if_not_exists : IF NOT EXISTS
349+ '''if_not_exists : IF NOT EXISTS
350 | empty'''
351- # Returns True if the IF NOT EXISTS phrase appeared, False otherwise
352+ # Returns True if the IF NOT EXISTS phrase appeared, False otherwise
353 p[0]= len(p) > 2
354
355 def p_schema_or_database(p):
356- '''schema_or_database : SCHEMA
357+ '''schema_or_database : SCHEMA
358 | DATABASE'''
359- p[0]= p[1]
360+ p[0]= p[1]
361
362 def p_identifier(p):
363- '''identifier : IDENTIFIER
364+ '''identifier : IDENTIFIER
365 | STRING'''
366- p[0]= p[1]
367+ p[0]= p[1]
368
369 def p_charset(p):
370- '''charset : CHARACTER SET
371+ '''charset : CHARACTER SET
372 | DEFAULT CHARACTER SET'''
373 pass
374
375-def p_table_option(p):
376+
377+def p_table_option_1(p):
378 """table_option : ENGINE opt_equal identifier
379 | AUTO_INCREMENT opt_equal NUMBER
380 | COMMENT opt_equal STRING"""
381- temp=[]
382+ temp= []
383 temp.append(p[1])
384 temp.append(p[3])
385- p[0]=temp;
386+ p[0]= temp;
387+
388
389-def p_table_option(p):
390+def p_table_option_2(p):
391 '''table_option : default_opt CHARACTER SET opt_equal identifier'''
392- temp=[]
393- temp.append("CHARACTER SET",p[5]);
394+ temp= []
395+ temp.append("CHARACTER SET");
396+ temp.append(p[5]);
397 p[0]= temp;
398
399+
400 def p_default_opt(p):
401 '''default_opt : DEFAULT
402 | empty'''
403@@ -338,17 +392,21 @@
404 def p_opt_equal(p):
405 ''' opt_equal : EQUAL
406 | empty'''
407- if(len(p)>1):
408+ if (len(p) > 1):
409 p[0]= p[1]
410 else:
411- p[0]= len(p)>1;
412+ p[0]= len(p) > 1;
413+
414+
415+
416
417 def p_empty(p):
418 'empty : '
419- pass # an empty rule that represents an optional piece
420+ pass # an empty rule that represents an optional
421+ # piece of a rule
422
423 def p_error(p):
424- # Called when a syntax or parse error occurs
425+ # Called when a syntax or parse error occurs
426 print "A parse error occurred at token %s" % p
427
428 # Create the parser
429@@ -359,3 +417,4 @@
430 return parser.parse(subject)
431 except Exception as e:
432 print e
433+
434
435=== modified file 'movetodrizzle/helpers/statement_nodes.py'
436--- movetodrizzle/helpers/statement_nodes.py 2010-07-15 16:41:56 +0000
437+++ movetodrizzle/helpers/statement_nodes.py 2010-07-22 18:42:46 +0000
438@@ -19,10 +19,32 @@
439 def __repr__(self):
440 return "CreateSchemaStatement(schema= %s) (character_set= %s) (collate= %s) (if_not_exists= %s)" % (self.schema_name, self.character_set, self.collate_name, self.if_not_exists)
441
442+class DataTypeDesc():
443+ def __init__(self, data_type, length= None, decimals= None, unsigned= None, zerofill= None, charset_name= None, collate_name= None, binary= None):
444+ self.data_type= data_type;
445+ self.length= length;
446+ self.unsigned= unsigned;
447+ self.zerofill= zerofill;
448+ self.decimals= decimals;
449+ self.collation_name= collate_name;
450+ self.charset_name= charset_name;
451+ self.binary= binary;
452+
453+ def __repr__(self):
454+ return "DataTypeDesc(data_type= %s, length= %s, decimals= %s, zerofill= %s, unsigned= %s, collation_name= %s, charset_name= %s, binary= %s)" %(
455+ self.data_type,
456+ self.length,
457+ self.decimals,
458+ self.zerofill,
459+ self.unsigned,
460+ self.collation_name,
461+ self.charset_name,
462+ self.binary)
463+
464 class ColumnDefinition():
465- def __init__(self, name, data_type, nullable= True, default= None, auto_increment= False, unique= False, primary_key= False, comment= None):
466+ def __init__(self, name, data_type_desc, nullable= True, default= None, auto_increment= False, unique= False, primary_key= False, comment= None):
467 self.name= name;
468- self.data_type= data_type;
469+ self.data_type_desc= data_type_desc;
470 self.nullable= nullable;
471 self.default= default;
472 self.auto_increment= auto_increment;
473@@ -30,9 +52,9 @@
474 self.primary_key= primary_key;
475 self.comment= comment;
476 def __repr__(self):
477- return "Column(col_name= %s, data_type= %s, nullable= %s, default= %s, auto_increment= %s, unique= %s, primary_key= %s, comment= %s)" % (
478+ return "Column(col_name= %s, data_type_desc= %s, nullable= %s, default= %s, auto_increment= %s, unique= %s, primary_key= %s, comment= %s)" % (
479 self.name,
480- self.data_type,
481+ self.data_type_desc,
482 self.nullable,
483 str(self.default),
484 self.auto_increment,
485@@ -50,13 +72,12 @@
486
487 class ForeignKeyConstraint():
488 def __init__(self, constarint_name, index_name, parent_fields, reference):
489- print constarint_name;
490 self.constarint_name= constarint_name;
491 self.index_name= index_name;
492 self.reference= reference;
493 self.parent_fields= parent_fields;
494- def __repr__(self):
495- return "Foreign Key(constraint_name= %s) (index_name=%s) (parent_fields= %s) (reference= %s)" %(self.constarint_name, self.index_name, self.parent_fields, self.reference)
496+ def __repr__(self):
497+ return "ForeignKeyConstraint(constraint_name= %s, index_name= %s, parent_fields= %s, reference= %s)" %(self.constarint_name, self.index_name, self.parent_fields, self.reference)
498
499 class ReferenceDefinition():
500 def __init__(self, name, col_name_list, match_option, on_delete, on_update):
501@@ -66,7 +87,7 @@
502 self.on_update= on_update;
503 self.on_delete= on_delete;
504 def __repr__(self):
505- return "Reference(name= %s) (col_name_list= %s) (match_option= %s) (on_delete= %s) (on_update= %s)" %(self.name, self.col_name_list, self.match_option, self.on_delete, self.on_update);
506+ return "Reference(name= %s, col_name_list= %s, match_option= %s, on_delete= %s, on_update= %s)" %(self.name, self.col_name_list, self.match_option, self.on_delete, self.on_update);
507
508 class CreateTableStatement(SqlStatement):
509 def __init__(self, table_name, list_columns, if_not_exists= False, temporary = False):
510@@ -78,4 +99,4 @@
511 def update_table_options(self, options):
512 self.table_options= options
513 def __repr__(self):
514- return "CreateTableStatement(table= %s) (if_not_exists= %s) (temporary= %s) (columns= %s)" % (self.table_name, self.if_not_exists, self.temporary, str(self.columns))
515+ return "CreateTableStatement(table= %s) (if_not_exists= %s) (temporary= %s) (columns= %s) (table_options= %s)" % (self.table_name, self.if_not_exists, self.temporary, str(self.columns),self.table_options)
516
517=== modified file 'tests/parser_createtable_test.py'
518--- tests/parser_createtable_test.py 2010-07-07 22:04:33 +0000
519+++ tests/parser_createtable_test.py 2010-07-22 18:42:46 +0000
520@@ -13,7 +13,7 @@
521 self.assertEqual(ct.table_name.qualifier, None)
522 self.assertEqual(ct.table_name.name, "t1")
523 self.assertEqual(ct.columns[0].name, "field1")
524- self.assertEqual(str(ct.columns[0].data_type), "INT")
525+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
526 self.assertEqual(ct.columns[0].nullable, False)
527
528 def test_create_table_nullable_explicit(self):
529@@ -23,7 +23,7 @@
530 self.assertEqual(ct.table_name.qualifier, None)
531 self.assertEqual(ct.table_name.name, "t1")
532 self.assertEqual(ct.columns[0].name, "field1")
533- self.assertEqual(str(ct.columns[0].data_type), "INT")
534+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
535 self.assertEqual(ct.columns[0].nullable, True)
536
537 def test_create_table_nullable_implicit(self):
538@@ -33,7 +33,7 @@
539 self.assertEqual(ct.table_name.qualifier, None)
540 self.assertEqual(ct.table_name.name, "t1")
541 self.assertEqual(ct.columns[0].name, "field1")
542- self.assertEqual(str(ct.columns[0].data_type), "INT")
543+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
544 self.assertEqual(ct.columns[0].nullable, True)
545
546 def test_create_table_no_default(self):
547@@ -43,7 +43,7 @@
548 self.assertEqual(ct.table_name.qualifier, None)
549 self.assertEqual(ct.table_name.name, "t1")
550 self.assertEqual(ct.columns[0].name, "field1")
551- self.assertEqual(str(ct.columns[0].data_type), "INT")
552+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
553 self.assertEqual(ct.columns[0].default, None)
554
555 def test_create_table_default_string(self):
556@@ -53,7 +53,7 @@
557 self.assertEqual(ct.table_name.qualifier, None)
558 self.assertEqual(ct.table_name.name, "t1")
559 self.assertEqual(ct.columns[0].name, "field1")
560- self.assertEqual(str(ct.columns[0].data_type), "INT")
561+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
562 self.assertEqual(ct.columns[0].default, "42")
563
564 def test_create_table_default_string_with_nullable(self):
565@@ -63,7 +63,7 @@
566 self.assertEqual(ct.table_name.qualifier, None)
567 self.assertEqual(ct.table_name.name, "t1")
568 self.assertEqual(ct.columns[0].name, "field1")
569- self.assertEqual(str(ct.columns[0].data_type), "INT")
570+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
571 self.assertEqual(ct.columns[0].default, "42")
572 self.assertEqual(ct.columns[0].nullable, False)
573
574@@ -96,7 +96,8 @@
575 statements= parser.parse_string(sql)
576 self.assertNotEqual(statements, None, "using data_type %s" % data_type)
577 ct= statements[0]
578- self.assertEqual(str(ct.columns[0].data_type), data_type)
579+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), data_type)
580+
581
582 def test_create_table_primary_key(self):
583 sql= "CREATE TABLE t1 (field1 INT NOT NULL PRIMARY KEY);"
584@@ -105,9 +106,220 @@
585 self.assertEqual(ct.table_name.qualifier, None)
586 self.assertEqual(ct.table_name.name, "t1")
587 self.assertEqual(ct.columns[0].name, "field1")
588- self.assertEqual(str(ct.columns[0].data_type), "INT")
589- self.assertEqual(ct.columns[0].nullable, False)
590- self.assertEqual(ct.columns[0].primary_key, True)
591+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
592+ self.assertEqual(ct.columns[0].nullable, False)
593+ self.assertEqual(ct.columns[0].primary_key, True)
594+
595+ def test_create_table__length(self):
596+ sql= "CREATE TABLE t1 (field1 INT (26) NOT NULL PRIMARY KEY);"
597+ statements= parser.parse_string(sql)
598+ ct= statements[0]
599+ self.assertEqual(ct.table_name.qualifier, None)
600+ self.assertEqual(ct.table_name.name, "t1")
601+ self.assertEqual(ct.columns[0].name, "field1")
602+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
603+ self.assertEqual(str(ct.columns[0].data_type_desc.length), "26")
604+ self.assertEqual(ct.columns[0].nullable, False)
605+ self.assertEqual(ct.columns[0].primary_key, True)
606+
607+ def test_create_table_length_length(self):
608+ sql= "CREATE TABLE t1 (field1 DECIMAL (5,2) NOT NULL PRIMARY KEY);"
609+ statements= parser.parse_string(sql)
610+ ct= statements[0]
611+ self.assertEqual(ct.table_name.qualifier, None)
612+ self.assertEqual(ct.table_name.name, "t1")
613+ self.assertEqual(ct.columns[0].name, "field1")
614+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "DECIMAL")
615+ self.assertEqual(str(ct.columns[0].data_type_desc.length), "5")
616+ self.assertEqual(str(ct.columns[0].data_type_desc.decimals), "2")
617+ self.assertEqual(ct.columns[0].nullable, False)
618+ self.assertEqual(ct.columns[0].primary_key, True)
619+
620+ def test_create_table_length_length_unsigned_zerofill(self):
621+ sql= "CREATE TABLE t1 (field1 DECIMAL (5,2) UNSIGNED ZEROFILL NOT NULL PRIMARY KEY);"
622+ statements= parser.parse_string(sql)
623+ ct= statements[0]
624+ self.assertEqual(ct.table_name.qualifier, None)
625+ self.assertEqual(ct.table_name.name, "t1")
626+ self.assertEqual(ct.columns[0].name, "field1")
627+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "DECIMAL")
628+ self.assertEqual(str(ct.columns[0].data_type_desc.length), "5")
629+ self.assertEqual(str(ct.columns[0].data_type_desc.decimals), "2")
630+ self.assertEqual(ct.columns[0].data_type_desc.unsigned, True)
631+ self.assertEqual(ct.columns[0].data_type_desc.zerofill, True)
632+ self.assertEqual(ct.columns[0].nullable, False)
633+ self.assertEqual(ct.columns[0].primary_key, True)
634+
635+ def test_create_table_char_varchar(self):
636+ sql= "CREATE TABLE t1 (field1 CHAR CHARACTER SET utf8 COLLATE col1);"
637+ statements= parser.parse_string(sql)
638+ ct= statements[0]
639+ self.assertEqual(ct.table_name.qualifier, None)
640+ self.assertEqual(ct.table_name.name, "t1")
641+ self.assertEqual(ct.columns[0].name, "field1")
642+ self.assertEqual(ct.columns[0].data_type_desc.data_type, "CHAR")
643+ self.assertEqual(ct.columns[0].data_type_desc.length, None)
644+ self.assertEqual(ct.columns[0].data_type_desc.decimals, None)
645+ self.assertEqual(ct.columns[0].data_type_desc.unsigned, None)
646+ self.assertEqual(ct.columns[0].data_type_desc.zerofill, None)
647+ self.assertEqual(ct.columns[0].data_type_desc.charset_name, 'utf8')
648+ self.assertEqual(ct.columns[0].data_type_desc.collation_name, 'col1')
649+ self.assertEqual(ct.columns[0].nullable, True)
650+ self.assertEqual(ct.columns[0].primary_key, False)
651+
652+ def test_create_table_foreign_constraint(self):
653+ sql= "CREATE TABLE t1 (field1 DECIMAL NOT NULL PRIMARY KEY, FOREIGN KEY (field1) REFERENCES reftable (ref_field1));"
654+ statements= parser.parse_string(sql)
655+ ct= statements[0]
656+ self.assertEqual(ct.table_name.qualifier, None)
657+ self.assertEqual(ct.table_name.name, "t1")
658+ self.assertEqual(ct.columns[0].name, "field1")
659+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "DECIMAL")
660+ self.assertEqual(ct.columns[0].nullable, False)
661+ self.assertEqual(ct.columns[0].primary_key, True)
662+ self.assertEqual(ct.columns[1].constarint_name, False);
663+ self.assertEqual(ct.columns[1].index_name, None);
664+ self.assertEqual(ct.columns[1].parent_fields[0],"field1");
665+ self.assertEqual(ct.columns[1].reference.name,"reftable");
666+ self.assertEqual(ct.columns[1].reference.col_name_list[0],"ref_field1");
667+ self.assertEqual(ct.columns[1].reference.on_update,False);
668+ self.assertEqual(ct.columns[1].reference.on_delete,False);
669+ self.assertEqual(ct.columns[1].reference.match_option,False);
670+
671+ def test_create_table_foreign_constraint_options(self):
672+ sql= "CREATE TABLE t1 (field1 DECIMAL NOT NULL PRIMARY KEY,FOREIGN KEY (field1) REFERENCES reftable (ref_field1) MATCH FULL ON DELETE CASCADE); "
673+ statements= parser.parse_string(sql)
674+ ct= statements[0]
675+ self.assertEqual(ct.table_name.qualifier, None)
676+ self.assertEqual(ct.table_name.name, "t1")
677+ self.assertEqual(ct.columns[0].name, "field1")
678+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "DECIMAL")
679+ self.assertEqual(ct.columns[0].nullable, False)
680+ self.assertEqual(ct.columns[0].primary_key, True)
681+ self.assertEqual(ct.columns[1].constarint_name, False);
682+ self.assertEqual(ct.columns[1].index_name, None);
683+ self.assertEqual(ct.columns[1].parent_fields[0],"field1");
684+ self.assertEqual(ct.columns[1].reference.name,"reftable");
685+ self.assertEqual(ct.columns[1].reference.col_name_list[0],"ref_field1");
686+ self.assertEqual(ct.columns[1].reference.on_update,False);
687+ self.assertEqual(ct.columns[1].reference.on_delete,"CASCADE");
688+ self.assertEqual(ct.columns[1].reference.match_option,"FULL");
689+
690+
691+ def test_create_table_foreign_constraint_options_constraint_name(self):
692+ sql= "CREATE TABLE t1 (field1 DECIMAL NOT NULL PRIMARY KEY,CONSTRAINT cons1 FOREIGN KEY (field1) REFERENCES reftable (ref_field1) MATCH FULL ON DELETE CASCADE ON UPDATE RESTRICT); "
693+ statements= parser.parse_string(sql)
694+ ct= statements[0]
695+ self.assertEqual(ct.table_name.qualifier, None)
696+ self.assertEqual(ct.table_name.name, "t1")
697+ self.assertEqual(ct.columns[0].name, "field1")
698+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "DECIMAL")
699+ self.assertEqual(ct.columns[0].nullable, False)
700+ self.assertEqual(ct.columns[0].primary_key, True)
701+ self.assertEqual(ct.columns[1].constarint_name, 'cons1');
702+ self.assertEqual(ct.columns[1].index_name, None);
703+ self.assertEqual(ct.columns[1].parent_fields[0],"field1");
704+ self.assertEqual(ct.columns[1].reference.name,"reftable");
705+ self.assertEqual(ct.columns[1].reference.col_name_list[0],"ref_field1");
706+ self.assertEqual(ct.columns[1].reference.on_update,"RESTRICT");
707+ self.assertEqual(ct.columns[1].reference.on_delete,"CASCADE");
708+ self.assertEqual(ct.columns[1].reference.match_option,"FULL");
709+
710+ def test_create_table_foreign_constraint_options_constraint_no_name(self):
711+ sql= "CREATE TABLE t1 (field1 DECIMAL NOT NULL PRIMARY KEY,CONSTRAINT FOREIGN KEY (field1) REFERENCES reftable (ref_field1) MATCH FULL ON DELETE CASCADE); "
712+ statements= parser.parse_string(sql)
713+ ct= statements[0]
714+ self.assertEqual(ct.table_name.qualifier, None)
715+ self.assertEqual(ct.table_name.name, "t1")
716+ self.assertEqual(ct.columns[0].name, "field1")
717+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "DECIMAL")
718+ self.assertEqual(ct.columns[0].nullable, False)
719+ self.assertEqual(ct.columns[0].primary_key, True)
720+ self.assertEqual(ct.columns[1].constarint_name, False);
721+ self.assertEqual(ct.columns[1].index_name, None);
722+ self.assertEqual(ct.columns[1].parent_fields[0],"field1");
723+ self.assertEqual(ct.columns[1].reference.name,"reftable");
724+ self.assertEqual(ct.columns[1].reference.col_name_list[0],"ref_field1");
725+ self.assertEqual(ct.columns[1].reference.on_update,False);
726+ self.assertEqual(ct.columns[1].reference.on_delete,"CASCADE");
727+ self.assertEqual(ct.columns[1].reference.match_option,"FULL");
728+
729+ def test_create_table_table_option(self):
730+ sql= "CREATE TABLE t1 (field1 INT NOT NULL PRIMARY KEY) AUTO_INCREMENT 5;"
731+ statements= parser.parse_string(sql)
732+ ct= statements[0]
733+ self.assertEqual(ct.table_name.qualifier, None)
734+ self.assertEqual(ct.table_name.name, "t1")
735+ self.assertEqual(ct.columns[0].name, "field1")
736+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
737+ self.assertEqual(ct.columns[0].nullable, False)
738+ self.assertEqual(ct.columns[0].primary_key, True)
739+ self.assertEqual(ct.table_options[0][0],"AUTO_INCREMENT");
740+ self.assertEqual(ct.table_options[0][1],5);
741+
742+ def test_create_table_table_option_multiple(self):
743+ sql= "CREATE TABLE t1 (field1 INT NOT NULL PRIMARY KEY) AUTO_INCREMENT 5 CHARACTER SET utf8;"
744+ statements= parser.parse_string(sql)
745+ ct= statements[0]
746+ self.assertEqual(ct.table_name.qualifier, None)
747+ self.assertEqual(ct.table_name.name, "t1")
748+ self.assertEqual(ct.columns[0].name, "field1")
749+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
750+ self.assertEqual(ct.columns[0].nullable, False)
751+ self.assertEqual(ct.columns[0].primary_key, True)
752+ self.assertEqual(ct.table_options[0][0],"AUTO_INCREMENT");
753+ self.assertEqual(ct.table_options[0][1],5);
754+ self.assertEqual(ct.table_options[1][0],"CHARACTER SET");
755+ self.assertEqual(ct.table_options[1][1],"utf8");
756+
757+ def test_create_table_table_option_comment(self):
758+ sql= "CREATE TABLE t1 (field1 INT) COMMENT 'comment1';"
759+ statements= parser.parse_string(sql)
760+ ct= statements[0]
761+ self.assertEqual(ct.table_name.qualifier, None)
762+ self.assertEqual(ct.table_name.name, "t1")
763+ self.assertEqual(ct.columns[0].name, "field1")
764+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
765+ self.assertEqual(ct.table_options[0][0],"COMMENT");
766+ self.assertEqual(ct.table_options[0][1],"comment1");
767+
768+ def test_create_table_qualified_identifier(self):
769+ sql= "CREATE TABLE t2.t1 (field1 INT);"
770+ statements= parser.parse_string(sql)
771+ ct= statements[0]
772+ self.assertEqual(ct.table_name.qualifier, "t1")
773+ self.assertEqual(ct.table_name.name, "t2")
774+ self.assertEqual(ct.columns[0].name, "field1")
775+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
776+
777+
778+ def test_create_table_col_list_multiple_ol(self):
779+ sql= "CREATE TABLE t1 (field1 INT, field2 CHAR,field3 BLOB);"
780+ statements= parser.parse_string(sql)
781+ ct= statements[0]
782+ self.assertEqual(ct.table_name.qualifier, None)
783+ self.assertEqual(ct.table_name.name, "t1")
784+ self.assertEqual(ct.columns[0].name, "field1")
785+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
786+ self.assertEqual(ct.columns[1].name, "field2")
787+ self.assertEqual(str(ct.columns[1].data_type_desc.data_type), "CHAR")
788+ self.assertEqual(ct.columns[2].name, "field3")
789+ self.assertEqual(str(ct.columns[2].data_type_desc.data_type), "BLOB")
790+
791+ def test_create_table_table_option(self):
792+ sql= "CREATE TABLE t1 (field1 INT NOT NULL DEFAULT a AUTO_INCREMENT PRIMARY KEY COMMENT 'comment1');"
793+ statements= parser.parse_string(sql)
794+ ct= statements[0]
795+ self.assertEqual(ct.table_name.qualifier, None)
796+ self.assertEqual(ct.table_name.name, "t1")
797+ self.assertEqual(ct.columns[0].name, "field1")
798+ self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
799+ self.assertEqual(ct.columns[0].nullable, False)
800+ self.assertEqual(ct.columns[0].primary_key, True)
801+ self.assertEqual(ct.columns[0].auto_increment, True)
802+ self.assertEqual(ct.columns[0].comment,"comment1")
803+
804+
805
806 if __name__ == '__main__':
807 unittest.main()

Subscribers

People subscribed via source and target branches

to all changes: