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
=== modified file 'movetodrizzle/helpers/lexer.py'
--- movetodrizzle/helpers/lexer.py 2010-07-07 22:04:33 +0000
+++ movetodrizzle/helpers/lexer.py 2010-07-22 18:42:46 +0000
@@ -59,9 +59,7 @@
59 'constraint' : 'CONSTRAINT',59 'constraint' : 'CONSTRAINT',
60 'constraint' : 'CONSTRAINT',60 'constraint' : 'CONSTRAINT',
61 'references' : 'REFERENCES',61 'references' : 'REFERENCES',
62 'match' : 'MATCH',
63 'full' : 'FULL',62 'full' : 'FULL',
64 'match' : 'MATCH',
65 'partial' : 'PARTIAL',63 'partial' : 'PARTIAL',
66 'match' : 'MATCH',64 'match' : 'MATCH',
67 'simple' : 'SIMPLE',65 'simple' : 'SIMPLE',
@@ -71,7 +69,8 @@
71 'cascade' : 'CASCADE',69 'cascade' : 'CASCADE',
72 'no' : 'NO',70 'no' : 'NO',
73 'action' : 'ACTION',71 'action' : 'ACTION',
74 'delete' : 'DELETE'72 'delete' : 'DELETE',
73 'comment' : 'COMMENT'
7574
7675
77}76}
@@ -87,7 +86,7 @@
87 'SEMICOLON',86 'SEMICOLON',
88 'NUMBER',87 'NUMBER',
89 'FLOAT_NUMBER',88 'FLOAT_NUMBER',
90 'COMMENT',89 'COMMENT_CODE',
91 'IDENTIFIER',90 'IDENTIFIER',
92 'STRING',91 'STRING',
93 'DOT',92 'DOT',
@@ -102,7 +101,7 @@
102t_RPAREN = r'\)'101t_RPAREN = r'\)'
103t_COMMA = r'\,'102t_COMMA = r'\,'
104t_SEMICOLON = r'\;'103t_SEMICOLON = r'\;'
105t_DOT= r'.'104t_DOT= r'\.'
106t_EQUAL= r'\='105t_EQUAL= r'\='
107106
108def t_NUMBER(t):107def t_NUMBER(t):
@@ -130,7 +129,7 @@
130 return t129 return t
131130
132#Define a rule so that we process comments131#Define a rule so that we process comments
133def t_COMMENT(t):132def t_COMMENT_CODE(t):
134 r'\/\*.*\*\/'133 r'\/\*.*\*\/'
135 pass134 pass
136 135
137136
=== modified file 'movetodrizzle/helpers/parser.py'
--- movetodrizzle/helpers/parser.py 2010-07-15 16:41:56 +0000
+++ movetodrizzle/helpers/parser.py 2010-07-22 18:42:46 +0000
@@ -4,7 +4,6 @@
4from lexer import *4from lexer import *
5import re5import re
6from statement_nodes import *6from statement_nodes import *
7
8# Begin grammar rules7# Begin grammar rules
9def p_statement_list(p):8def p_statement_list(p):
10 '''statement_list : statement_list statement'''9 '''statement_list : statement_list statement'''
@@ -23,7 +22,7 @@
23 p[0]=p[1]22 p[0]=p[1]
2423
25def p_create_table_simple(p):24def p_create_table_simple(p):
26 '''create_table_simple : CREATE temporary TABLE if_not_exists identifier_qualified_opt LPAREN col_list RPAREN table_options'''25 '''create_table_simple : CREATE temporary TABLE if_not_exists identifier_qualified_non_qualified_opt LPAREN col_list RPAREN table_options'''
27 a= CreateTableStatement(p[5], p[7], p[4], p[2])26 a= CreateTableStatement(p[5], p[7], p[4], p[2])
28 a.update_table_options(p[9]);27 a.update_table_options(p[9]);
29 p[0]= a28 p[0]= a
@@ -31,17 +30,23 @@
31def p_table_options(p):30def p_table_options(p):
32 '''table_options : table_option table_options31 '''table_options : table_option table_options
33 | empty'''32 | empty'''
34 if(len(p)>2):33 if (len(p) > 2):
35 p[0]= [p[1]] + p[2]34 p[0]= [p[1]] + p[2]
36 else:35 else:
37 p[0]= []36 p[0]= []
37
38def p_identifier_qualified_non_qualified_opt(p):
39 '''identifier_qualified_non_qualified_opt : identifier_qualified_opt
40 | identifier_non_qualified_opt'''
41 p[0]= p[1]
42
38 43
39def p_qualified_identifier(p):44def p_qualified_identifier(p):
40 '''identifier_qualified_opt : IDENTIFIER DOT IDENTIFIER'''45 '''identifier_qualified_opt : IDENTIFIER DOT IDENTIFIER'''
41 p[0]= Identifier(p[1], p[3])46 p[0]= Identifier(p[1], p[3])
4247
43def p_non_qualified_identifier(p):48def p_non_qualified_identifier(p):
44 '''identifier_qualified_opt : IDENTIFIER 49 '''identifier_non_qualified_opt : IDENTIFIER
45 | STRING'''50 | STRING'''
46 p[0]= Identifier(p[1])51 p[0]= Identifier(p[1])
4752
@@ -57,11 +62,11 @@
57def p_col(p):62def p_col(p):
58 '''col : col_conditional63 '''col : col_conditional
59 | col_normal'''64 | col_normal'''
60 p[0]=p[1]65 p[0]= p[1]
6166
62def p_col_conditional(p):67def p_col_conditional(p):
63 '''col_conditional : foreign_key_constraint'''68 '''col_conditional : foreign_key_constraint'''
64 p[0]=p[1]69 p[0]= p[1]
6570
66def p_foreign_key_constraint(p):71def p_foreign_key_constraint(p):
67 '''foreign_key_constraint : constraint_opt FOREIGN KEY index_name_opt LPAREN index_col_name_list RPAREN reference_definition'''72 '''foreign_key_constraint : constraint_opt FOREIGN KEY index_name_opt LPAREN index_col_name_list RPAREN reference_definition'''
@@ -71,23 +76,29 @@
71 '''constraint_opt : CONSTRAINT76 '''constraint_opt : CONSTRAINT
72 | CONSTRAINT identifier77 | CONSTRAINT identifier
73 | empty'''78 | empty'''
74 if(len(p)>2):79 if (len(p) > 2):
75 p[0]= p[2]80 p[0]= p[2]
76 else:81 else:
77 p[0]= len(p)>282 p[0]= len(p) > 2
78def p_index_name_opt(p):83def p_index_name_opt(p):
79 '''index_name_opt : identifier84 '''index_name_opt : identifier
80 | empty '''85 | empty '''
81 p[0]=p[1]86 if(len(p) > 1):
87 p[0]= p[1]
88 else:
89 p[0]= len(p)>1
90
8291
83def p_index_col_name_list(p):92def p_index_col_name_list(p):
84 '''index_col_name_list : index_col_name COMMA index_col_name_list93 '''index_col_name_list : index_col_name COMMA index_col_name_list
85 | index_col_name'''94 | index_col_name'''
86 if(len(p)>2):95 if (len(p) > 2):
87 p[0]= [p[1]]+ p[3]96 p[0]= [p[1]]+ p[3]
88 else:97 else:
89 p[0]= [p[1]]98 p[0]= [p[1]]
9099
100
101
91def p_index_col_name(p):102def p_index_col_name(p):
92 '''index_col_name : identifier'''103 '''index_col_name : identifier'''
93 p[0]= p[1]104 p[0]= p[1]
@@ -101,26 +112,26 @@
101 | MATCH PARTIAL112 | MATCH PARTIAL
102 | MATCH SIMPLE113 | MATCH SIMPLE
103 | empty'''114 | empty'''
104 if(len(p)>2):115 if (len(p) == 3):
105 p[0]= p[2]116 p[0]= p[2]
106 else:117 else:
107 p[0]= len(p)>2118 p[0]= len(p) > 2
108119
109def p_on_delete_option(p):120def p_on_delete_option(p):
110 '''on_delete_option : ON DELETE reference_options121 '''on_delete_option : ON DELETE reference_options
111 | empty'''122 | empty'''
112 if(len(p)>3):123 if (len(p) > 3):
113 p[0]= p[2]124 p[0]= p[3]
114 else:125 else:
115 p[0]= len(p)>3126 p[0]= len(p) > 3
116127
117def p_on_update_option(p):128def p_on_update_option(p):
118 '''on_update_option : ON UPDATE reference_options129 '''on_update_option : ON UPDATE reference_options
119 | empty'''130 | empty'''
120 if(len(p)>3):131 if (len(p) > 3):
121 p[0]= p[2]132 p[0]= p[3]
122 else:133 else:
123 p[0]= len(p)>3134 p[0]= len(p) > 3
124135
125def p_reference_options(p):136def p_reference_options(p):
126 '''reference_options : RESTRICT 137 '''reference_options : RESTRICT
@@ -128,12 +139,12 @@
128 | SET NULL 139 | SET NULL
129 | NO ACTION140 | NO ACTION
130 | empty'''141 | empty'''
131 if(len(p)==2):142 if (len(p) == 2):
132 p[0]=p[1]143 p[0]= p[1]
133 elif(len(p)==3):144 elif (len(p) == 3):
134 p[0]=str(p[1])+str(p[2])145 p[0]= str(p[1])+str(p[2])
135 else:146 else:
136 p[0]=None147 p[0]= None
137148
138def p_col_normal(p):149def p_col_normal(p):
139 '''col_normal : col_definition'''150 '''col_normal : col_definition'''
@@ -141,8 +152,10 @@
141152
142def p_col_definition(p):153def p_col_definition(p):
143 '''col_definition : identifier data_type nullable_constraint default_p auto_increment_p unique_p primary_key comment_p'''154 '''col_definition : identifier data_type nullable_constraint default_p auto_increment_p unique_p primary_key comment_p'''
155
144 p[0]= ColumnDefinition(p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8])156 p[0]= ColumnDefinition(p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8])
145157
158
146def p_nullable_constraint(p):159def p_nullable_constraint(p):
147 '''nullable_constraint : NOT NULL160 '''nullable_constraint : NOT NULL
148 | NULL161 | NULL
@@ -152,7 +165,7 @@
152def p_default_p(p):165def p_default_p(p):
153 '''default_p : DEFAULT identifier166 '''default_p : DEFAULT identifier
154 | empty'''167 | empty'''
155 if(len(p) > 2):168 if (len(p) > 2):
156 p[0]= p[2]169 p[0]= p[2]
157 else:170 else:
158 p[0]= None171 p[0]= None
@@ -174,15 +187,15 @@
174 p[0]= len(p) > 2187 p[0]= len(p) > 2
175188
176def p_comment_p(p):189def p_comment_p(p):
177 '''comment_p : COMMENT STRING190 '''comment_p : COMMENT STRING
178 | empty'''191 | empty'''
179 if(len(p)>2):192 if (len(p) > 2):
180 p[0]= p[2]193 p[0]= p[2]
181 else:194 else:
182 p[0]= len(p)>2195 p[0]= len(p) > 2
183196
184def p_data_types(p):197def p_data_types_1(p):
185 '''data_type : BIT198 '''data_type : BIT
186 | mathematical length_opt unsigned_opt zerofill_opt199 | mathematical length_opt unsigned_opt zerofill_opt
187 | DATE200 | DATE
188 | TIME201 | TIME
@@ -195,15 +208,34 @@
195 | TINYBLOB208 | TINYBLOB
196 | BLOB209 | BLOB
197 | MEDIUMBLOB210 | MEDIUMBLOB
198 | LONGBLOB211 | LONGBLOB'''
199 | texts binary_opt character_set_opt collate_opt212 p[0]= DataTypeDesc(p[1])
213 if (len(p) == 1):
214 p[0]= [p[1]]
215 if (len(p) == 5):
216 if(p[2] == False):
217 length= None;
218 decimal= None;
219 elif(len(p[2]) == 2):
220 length= p[2][0];
221 decimal= p[2][1];
222 else:
223 length= p[2][0];
224 decimal= None;
225 p[0]=DataTypeDesc(p[1],length,decimal,p[3],p[4])
226 if (len(p) == 4):
227 p[0]= DataTypeDesc(p[1],None,None,None,None,p[2],p[3])
228
229def p_data_types_2(p):
230 '''data_type : texts binary_opt character_set_opt collate_opt
200 | set_enum character_set_opt collate_opt'''231 | set_enum character_set_opt collate_opt'''
201 p[0]= p[1]232 p[0]= DataTypeDesc(p[1]);
202233
203def p_set_enum(p):234def p_set_enum(p):
204 '''set_enum : SET LPAREN value_list RPAREN235 '''set_enum : SET LPAREN value_list RPAREN
205 | ENUM LPAREN value_list RPAREN'''236 | ENUM LPAREN value_list RPAREN'''
206 p[0]=p[1]237 p[0]= p[1]
238
207239
208def p_value_list(p):240def p_value_list(p):
209 '''value_list : STRING COMMA value_list241 '''value_list : STRING COMMA value_list
@@ -229,29 +261,47 @@
229def p_character_set_opt(p):261def p_character_set_opt(p):
230 '''character_set_opt : CHARACTER SET identifier262 '''character_set_opt : CHARACTER SET identifier
231 | empty'''263 | empty'''
232 pass264 if (len(p) > 3):
265 p[0]= p[3]
266 else:
267 p[0]= len(p) > 3
233268
234def p_collate_opt(p):269def p_collate_opt(p):
235 '''collate_opt : COLLATE identifier270 '''collate_opt : COLLATE identifier
236 | empty'''271 | empty'''
237 pass272 if (len(p) > 2):
273 p[0]= p[2]
274 else:
275 p[0]= len(p) > 2
238276
239def p_length_opt(p):277def p_length_opt(p):
240 '''length_opt : LPAREN NUMBER RPAREN 278 '''length_opt : LPAREN NUMBER RPAREN
241 | LPAREN NUMBER COMMA NUMBER RPAREN279 | LPAREN NUMBER COMMA NUMBER RPAREN
242 | empty'''280 | empty'''
243 pass281 if (len(p) >= 6):
282 p[0]= [p[2],p[4]]
283
284 elif (len(p) == 4):
285 p[0]= [p[2]]
286 else:
287 p[0]= len(p) > 6;
288
289
244290
245def p_unsigned_opt(p):291def p_unsigned_opt(p):
246 '''unsigned_opt : UNSIGNED292 '''unsigned_opt : UNSIGNED
247 | empty'''293 | empty'''
248 pass294 p[0]= len(p) > 1
295
249296
250def p_zerofill_opt(p):297def p_zerofill_opt(p):
251 '''zerofill_opt : ZEROFILL298 '''zerofill_opt : ZEROFILL
252 | empty'''299 | empty'''
253 pass300 p[0]= len(p) > 1
254301
302
303
304
255def p_mathematical(p):305def p_mathematical(p):
256 '''mathematical : TINYINT 306 '''mathematical : TINYINT
257 | SMALLINT307 | SMALLINT
@@ -268,7 +318,7 @@
268def p_optional_temporary(p):318def p_optional_temporary(p):
269 '''temporary : TEMPORARY319 '''temporary : TEMPORARY
270 | empty'''320 | empty'''
271 # Returns True if the TEMPORARY phrase appeared, False otherwise321 # Returns True if the TEMPORARY phrase appeared, False otherwise
272 p[0]= len(p) > 1322 p[0]= len(p) > 1
273323
274def p_create_schema(p):324def p_create_schema(p):
@@ -295,41 +345,45 @@
295 p[0]= CreateSchemaStatement(p[4], p[6], p[8], p[3])345 p[0]= CreateSchemaStatement(p[4], p[6], p[8], p[3])
296346
297def p_optional_if_not_exists(p):347def p_optional_if_not_exists(p):
298 '''if_not_exists : IF NOT EXISTS348 '''if_not_exists : IF NOT EXISTS
299 | empty'''349 | empty'''
300 # Returns True if the IF NOT EXISTS phrase appeared, False otherwise350 # Returns True if the IF NOT EXISTS phrase appeared, False otherwise
301 p[0]= len(p) > 2351 p[0]= len(p) > 2
302352
303def p_schema_or_database(p):353def p_schema_or_database(p):
304 '''schema_or_database : SCHEMA354 '''schema_or_database : SCHEMA
305 | DATABASE'''355 | DATABASE'''
306 p[0]= p[1]356 p[0]= p[1]
307357
308def p_identifier(p):358def p_identifier(p):
309 '''identifier : IDENTIFIER359 '''identifier : IDENTIFIER
310 | STRING'''360 | STRING'''
311 p[0]= p[1]361 p[0]= p[1]
312362
313def p_charset(p):363def p_charset(p):
314 '''charset : CHARACTER SET364 '''charset : CHARACTER SET
315 | DEFAULT CHARACTER SET'''365 | DEFAULT CHARACTER SET'''
316 pass366 pass
317367
318def p_table_option(p):368
369def p_table_option_1(p):
319 """table_option : ENGINE opt_equal identifier370 """table_option : ENGINE opt_equal identifier
320 | AUTO_INCREMENT opt_equal NUMBER371 | AUTO_INCREMENT opt_equal NUMBER
321 | COMMENT opt_equal STRING"""372 | COMMENT opt_equal STRING"""
322 temp=[]373 temp= []
323 temp.append(p[1])374 temp.append(p[1])
324 temp.append(p[3])375 temp.append(p[3])
325 p[0]=temp;376 p[0]= temp;
377
326 378
327def p_table_option(p):379def p_table_option_2(p):
328 '''table_option : default_opt CHARACTER SET opt_equal identifier'''380 '''table_option : default_opt CHARACTER SET opt_equal identifier'''
329 temp=[]381 temp= []
330 temp.append("CHARACTER SET",p[5]);382 temp.append("CHARACTER SET");
383 temp.append(p[5]);
331 p[0]= temp;384 p[0]= temp;
332385
386
333def p_default_opt(p):387def p_default_opt(p):
334 '''default_opt : DEFAULT388 '''default_opt : DEFAULT
335 | empty'''389 | empty'''
@@ -338,17 +392,21 @@
338def p_opt_equal(p):392def p_opt_equal(p):
339 ''' opt_equal : EQUAL393 ''' opt_equal : EQUAL
340 | empty'''394 | empty'''
341 if(len(p)>1):395 if (len(p) > 1):
342 p[0]= p[1]396 p[0]= p[1]
343 else:397 else:
344 p[0]= len(p)>1;398 p[0]= len(p) > 1;
399
400
401
345402
346def p_empty(p):403def p_empty(p):
347 'empty : '404 'empty : '
348 pass # an empty rule that represents an optional piece405 pass # an empty rule that represents an optional
406 # piece of a rule
349407
350def p_error(p):408def p_error(p):
351 # Called when a syntax or parse error occurs409 # Called when a syntax or parse error occurs
352 print "A parse error occurred at token %s" % p410 print "A parse error occurred at token %s" % p
353411
354# Create the parser412# Create the parser
@@ -359,3 +417,4 @@
359 return parser.parse(subject)417 return parser.parse(subject)
360 except Exception as e:418 except Exception as e:
361 print e419 print e
420
362421
=== modified file 'movetodrizzle/helpers/statement_nodes.py'
--- movetodrizzle/helpers/statement_nodes.py 2010-07-15 16:41:56 +0000
+++ movetodrizzle/helpers/statement_nodes.py 2010-07-22 18:42:46 +0000
@@ -19,10 +19,32 @@
19 def __repr__(self):19 def __repr__(self):
20 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)20 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)
2121
22class DataTypeDesc():
23 def __init__(self, data_type, length= None, decimals= None, unsigned= None, zerofill= None, charset_name= None, collate_name= None, binary= None):
24 self.data_type= data_type;
25 self.length= length;
26 self.unsigned= unsigned;
27 self.zerofill= zerofill;
28 self.decimals= decimals;
29 self.collation_name= collate_name;
30 self.charset_name= charset_name;
31 self.binary= binary;
32
33 def __repr__(self):
34 return "DataTypeDesc(data_type= %s, length= %s, decimals= %s, zerofill= %s, unsigned= %s, collation_name= %s, charset_name= %s, binary= %s)" %(
35 self.data_type,
36 self.length,
37 self.decimals,
38 self.zerofill,
39 self.unsigned,
40 self.collation_name,
41 self.charset_name,
42 self.binary)
43
22class ColumnDefinition():44class ColumnDefinition():
23 def __init__(self, name, data_type, nullable= True, default= None, auto_increment= False, unique= False, primary_key= False, comment= None):45 def __init__(self, name, data_type_desc, nullable= True, default= None, auto_increment= False, unique= False, primary_key= False, comment= None):
24 self.name= name;46 self.name= name;
25 self.data_type= data_type;47 self.data_type_desc= data_type_desc;
26 self.nullable= nullable;48 self.nullable= nullable;
27 self.default= default;49 self.default= default;
28 self.auto_increment= auto_increment;50 self.auto_increment= auto_increment;
@@ -30,9 +52,9 @@
30 self.primary_key= primary_key;52 self.primary_key= primary_key;
31 self.comment= comment;53 self.comment= comment;
32 def __repr__(self):54 def __repr__(self):
33 return "Column(col_name= %s, data_type= %s, nullable= %s, default= %s, auto_increment= %s, unique= %s, primary_key= %s, comment= %s)" % (55 return "Column(col_name= %s, data_type_desc= %s, nullable= %s, default= %s, auto_increment= %s, unique= %s, primary_key= %s, comment= %s)" % (
34 self.name,56 self.name,
35 self.data_type,57 self.data_type_desc,
36 self.nullable,58 self.nullable,
37 str(self.default),59 str(self.default),
38 self.auto_increment,60 self.auto_increment,
@@ -50,13 +72,12 @@
5072
51class ForeignKeyConstraint():73class ForeignKeyConstraint():
52 def __init__(self, constarint_name, index_name, parent_fields, reference):74 def __init__(self, constarint_name, index_name, parent_fields, reference):
53 print constarint_name;
54 self.constarint_name= constarint_name;75 self.constarint_name= constarint_name;
55 self.index_name= index_name;76 self.index_name= index_name;
56 self.reference= reference;77 self.reference= reference;
57 self.parent_fields= parent_fields;78 self.parent_fields= parent_fields;
58 def __repr__(self):79 def __repr__(self):
59 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)80 return "ForeignKeyConstraint(constraint_name= %s, index_name= %s, parent_fields= %s, reference= %s)" %(self.constarint_name, self.index_name, self.parent_fields, self.reference)
6081
61class ReferenceDefinition():82class ReferenceDefinition():
62 def __init__(self, name, col_name_list, match_option, on_delete, on_update):83 def __init__(self, name, col_name_list, match_option, on_delete, on_update):
@@ -66,7 +87,7 @@
66 self.on_update= on_update;87 self.on_update= on_update;
67 self.on_delete= on_delete;88 self.on_delete= on_delete;
68 def __repr__(self):89 def __repr__(self):
69 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);90 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);
7091
71class CreateTableStatement(SqlStatement):92class CreateTableStatement(SqlStatement):
72 def __init__(self, table_name, list_columns, if_not_exists= False, temporary = False):93 def __init__(self, table_name, list_columns, if_not_exists= False, temporary = False):
@@ -78,4 +99,4 @@
78 def update_table_options(self, options):99 def update_table_options(self, options):
79 self.table_options= options100 self.table_options= options
80 def __repr__(self):101 def __repr__(self):
81 return "CreateTableStatement(table= %s) (if_not_exists= %s) (temporary= %s) (columns= %s)" % (self.table_name, self.if_not_exists, self.temporary, str(self.columns))102 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)
82103
=== modified file 'tests/parser_createtable_test.py'
--- tests/parser_createtable_test.py 2010-07-07 22:04:33 +0000
+++ tests/parser_createtable_test.py 2010-07-22 18:42:46 +0000
@@ -13,7 +13,7 @@
13 self.assertEqual(ct.table_name.qualifier, None)13 self.assertEqual(ct.table_name.qualifier, None)
14 self.assertEqual(ct.table_name.name, "t1")14 self.assertEqual(ct.table_name.name, "t1")
15 self.assertEqual(ct.columns[0].name, "field1")15 self.assertEqual(ct.columns[0].name, "field1")
16 self.assertEqual(str(ct.columns[0].data_type), "INT")16 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
17 self.assertEqual(ct.columns[0].nullable, False)17 self.assertEqual(ct.columns[0].nullable, False)
1818
19 def test_create_table_nullable_explicit(self):19 def test_create_table_nullable_explicit(self):
@@ -23,7 +23,7 @@
23 self.assertEqual(ct.table_name.qualifier, None)23 self.assertEqual(ct.table_name.qualifier, None)
24 self.assertEqual(ct.table_name.name, "t1")24 self.assertEqual(ct.table_name.name, "t1")
25 self.assertEqual(ct.columns[0].name, "field1")25 self.assertEqual(ct.columns[0].name, "field1")
26 self.assertEqual(str(ct.columns[0].data_type), "INT")26 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
27 self.assertEqual(ct.columns[0].nullable, True)27 self.assertEqual(ct.columns[0].nullable, True)
2828
29 def test_create_table_nullable_implicit(self):29 def test_create_table_nullable_implicit(self):
@@ -33,7 +33,7 @@
33 self.assertEqual(ct.table_name.qualifier, None)33 self.assertEqual(ct.table_name.qualifier, None)
34 self.assertEqual(ct.table_name.name, "t1")34 self.assertEqual(ct.table_name.name, "t1")
35 self.assertEqual(ct.columns[0].name, "field1")35 self.assertEqual(ct.columns[0].name, "field1")
36 self.assertEqual(str(ct.columns[0].data_type), "INT")36 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
37 self.assertEqual(ct.columns[0].nullable, True)37 self.assertEqual(ct.columns[0].nullable, True)
3838
39 def test_create_table_no_default(self):39 def test_create_table_no_default(self):
@@ -43,7 +43,7 @@
43 self.assertEqual(ct.table_name.qualifier, None)43 self.assertEqual(ct.table_name.qualifier, None)
44 self.assertEqual(ct.table_name.name, "t1")44 self.assertEqual(ct.table_name.name, "t1")
45 self.assertEqual(ct.columns[0].name, "field1")45 self.assertEqual(ct.columns[0].name, "field1")
46 self.assertEqual(str(ct.columns[0].data_type), "INT")46 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
47 self.assertEqual(ct.columns[0].default, None)47 self.assertEqual(ct.columns[0].default, None)
4848
49 def test_create_table_default_string(self):49 def test_create_table_default_string(self):
@@ -53,7 +53,7 @@
53 self.assertEqual(ct.table_name.qualifier, None)53 self.assertEqual(ct.table_name.qualifier, None)
54 self.assertEqual(ct.table_name.name, "t1")54 self.assertEqual(ct.table_name.name, "t1")
55 self.assertEqual(ct.columns[0].name, "field1")55 self.assertEqual(ct.columns[0].name, "field1")
56 self.assertEqual(str(ct.columns[0].data_type), "INT")56 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
57 self.assertEqual(ct.columns[0].default, "42")57 self.assertEqual(ct.columns[0].default, "42")
5858
59 def test_create_table_default_string_with_nullable(self):59 def test_create_table_default_string_with_nullable(self):
@@ -63,7 +63,7 @@
63 self.assertEqual(ct.table_name.qualifier, None)63 self.assertEqual(ct.table_name.qualifier, None)
64 self.assertEqual(ct.table_name.name, "t1")64 self.assertEqual(ct.table_name.name, "t1")
65 self.assertEqual(ct.columns[0].name, "field1")65 self.assertEqual(ct.columns[0].name, "field1")
66 self.assertEqual(str(ct.columns[0].data_type), "INT")66 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
67 self.assertEqual(ct.columns[0].default, "42")67 self.assertEqual(ct.columns[0].default, "42")
68 self.assertEqual(ct.columns[0].nullable, False)68 self.assertEqual(ct.columns[0].nullable, False)
6969
@@ -96,7 +96,8 @@
96 statements= parser.parse_string(sql)96 statements= parser.parse_string(sql)
97 self.assertNotEqual(statements, None, "using data_type %s" % data_type)97 self.assertNotEqual(statements, None, "using data_type %s" % data_type)
98 ct= statements[0]98 ct= statements[0]
99 self.assertEqual(str(ct.columns[0].data_type), data_type)99 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), data_type)
100
100101
101 def test_create_table_primary_key(self):102 def test_create_table_primary_key(self):
102 sql= "CREATE TABLE t1 (field1 INT NOT NULL PRIMARY KEY);"103 sql= "CREATE TABLE t1 (field1 INT NOT NULL PRIMARY KEY);"
@@ -105,9 +106,220 @@
105 self.assertEqual(ct.table_name.qualifier, None)106 self.assertEqual(ct.table_name.qualifier, None)
106 self.assertEqual(ct.table_name.name, "t1")107 self.assertEqual(ct.table_name.name, "t1")
107 self.assertEqual(ct.columns[0].name, "field1")108 self.assertEqual(ct.columns[0].name, "field1")
108 self.assertEqual(str(ct.columns[0].data_type), "INT")109 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
109 self.assertEqual(ct.columns[0].nullable, False)110 self.assertEqual(ct.columns[0].nullable, False)
110 self.assertEqual(ct.columns[0].primary_key, True)111 self.assertEqual(ct.columns[0].primary_key, True)
112
113 def test_create_table__length(self):
114 sql= "CREATE TABLE t1 (field1 INT (26) NOT NULL PRIMARY KEY);"
115 statements= parser.parse_string(sql)
116 ct= statements[0]
117 self.assertEqual(ct.table_name.qualifier, None)
118 self.assertEqual(ct.table_name.name, "t1")
119 self.assertEqual(ct.columns[0].name, "field1")
120 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
121 self.assertEqual(str(ct.columns[0].data_type_desc.length), "26")
122 self.assertEqual(ct.columns[0].nullable, False)
123 self.assertEqual(ct.columns[0].primary_key, True)
124
125 def test_create_table_length_length(self):
126 sql= "CREATE TABLE t1 (field1 DECIMAL (5,2) NOT NULL PRIMARY KEY);"
127 statements= parser.parse_string(sql)
128 ct= statements[0]
129 self.assertEqual(ct.table_name.qualifier, None)
130 self.assertEqual(ct.table_name.name, "t1")
131 self.assertEqual(ct.columns[0].name, "field1")
132 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "DECIMAL")
133 self.assertEqual(str(ct.columns[0].data_type_desc.length), "5")
134 self.assertEqual(str(ct.columns[0].data_type_desc.decimals), "2")
135 self.assertEqual(ct.columns[0].nullable, False)
136 self.assertEqual(ct.columns[0].primary_key, True)
137
138 def test_create_table_length_length_unsigned_zerofill(self):
139 sql= "CREATE TABLE t1 (field1 DECIMAL (5,2) UNSIGNED ZEROFILL NOT NULL PRIMARY KEY);"
140 statements= parser.parse_string(sql)
141 ct= statements[0]
142 self.assertEqual(ct.table_name.qualifier, None)
143 self.assertEqual(ct.table_name.name, "t1")
144 self.assertEqual(ct.columns[0].name, "field1")
145 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "DECIMAL")
146 self.assertEqual(str(ct.columns[0].data_type_desc.length), "5")
147 self.assertEqual(str(ct.columns[0].data_type_desc.decimals), "2")
148 self.assertEqual(ct.columns[0].data_type_desc.unsigned, True)
149 self.assertEqual(ct.columns[0].data_type_desc.zerofill, True)
150 self.assertEqual(ct.columns[0].nullable, False)
151 self.assertEqual(ct.columns[0].primary_key, True)
152
153 def test_create_table_char_varchar(self):
154 sql= "CREATE TABLE t1 (field1 CHAR CHARACTER SET utf8 COLLATE col1);"
155 statements= parser.parse_string(sql)
156 ct= statements[0]
157 self.assertEqual(ct.table_name.qualifier, None)
158 self.assertEqual(ct.table_name.name, "t1")
159 self.assertEqual(ct.columns[0].name, "field1")
160 self.assertEqual(ct.columns[0].data_type_desc.data_type, "CHAR")
161 self.assertEqual(ct.columns[0].data_type_desc.length, None)
162 self.assertEqual(ct.columns[0].data_type_desc.decimals, None)
163 self.assertEqual(ct.columns[0].data_type_desc.unsigned, None)
164 self.assertEqual(ct.columns[0].data_type_desc.zerofill, None)
165 self.assertEqual(ct.columns[0].data_type_desc.charset_name, 'utf8')
166 self.assertEqual(ct.columns[0].data_type_desc.collation_name, 'col1')
167 self.assertEqual(ct.columns[0].nullable, True)
168 self.assertEqual(ct.columns[0].primary_key, False)
169
170 def test_create_table_foreign_constraint(self):
171 sql= "CREATE TABLE t1 (field1 DECIMAL NOT NULL PRIMARY KEY, FOREIGN KEY (field1) REFERENCES reftable (ref_field1));"
172 statements= parser.parse_string(sql)
173 ct= statements[0]
174 self.assertEqual(ct.table_name.qualifier, None)
175 self.assertEqual(ct.table_name.name, "t1")
176 self.assertEqual(ct.columns[0].name, "field1")
177 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "DECIMAL")
178 self.assertEqual(ct.columns[0].nullable, False)
179 self.assertEqual(ct.columns[0].primary_key, True)
180 self.assertEqual(ct.columns[1].constarint_name, False);
181 self.assertEqual(ct.columns[1].index_name, None);
182 self.assertEqual(ct.columns[1].parent_fields[0],"field1");
183 self.assertEqual(ct.columns[1].reference.name,"reftable");
184 self.assertEqual(ct.columns[1].reference.col_name_list[0],"ref_field1");
185 self.assertEqual(ct.columns[1].reference.on_update,False);
186 self.assertEqual(ct.columns[1].reference.on_delete,False);
187 self.assertEqual(ct.columns[1].reference.match_option,False);
188
189 def test_create_table_foreign_constraint_options(self):
190 sql= "CREATE TABLE t1 (field1 DECIMAL NOT NULL PRIMARY KEY,FOREIGN KEY (field1) REFERENCES reftable (ref_field1) MATCH FULL ON DELETE CASCADE); "
191 statements= parser.parse_string(sql)
192 ct= statements[0]
193 self.assertEqual(ct.table_name.qualifier, None)
194 self.assertEqual(ct.table_name.name, "t1")
195 self.assertEqual(ct.columns[0].name, "field1")
196 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "DECIMAL")
197 self.assertEqual(ct.columns[0].nullable, False)
198 self.assertEqual(ct.columns[0].primary_key, True)
199 self.assertEqual(ct.columns[1].constarint_name, False);
200 self.assertEqual(ct.columns[1].index_name, None);
201 self.assertEqual(ct.columns[1].parent_fields[0],"field1");
202 self.assertEqual(ct.columns[1].reference.name,"reftable");
203 self.assertEqual(ct.columns[1].reference.col_name_list[0],"ref_field1");
204 self.assertEqual(ct.columns[1].reference.on_update,False);
205 self.assertEqual(ct.columns[1].reference.on_delete,"CASCADE");
206 self.assertEqual(ct.columns[1].reference.match_option,"FULL");
207
208
209 def test_create_table_foreign_constraint_options_constraint_name(self):
210 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); "
211 statements= parser.parse_string(sql)
212 ct= statements[0]
213 self.assertEqual(ct.table_name.qualifier, None)
214 self.assertEqual(ct.table_name.name, "t1")
215 self.assertEqual(ct.columns[0].name, "field1")
216 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "DECIMAL")
217 self.assertEqual(ct.columns[0].nullable, False)
218 self.assertEqual(ct.columns[0].primary_key, True)
219 self.assertEqual(ct.columns[1].constarint_name, 'cons1');
220 self.assertEqual(ct.columns[1].index_name, None);
221 self.assertEqual(ct.columns[1].parent_fields[0],"field1");
222 self.assertEqual(ct.columns[1].reference.name,"reftable");
223 self.assertEqual(ct.columns[1].reference.col_name_list[0],"ref_field1");
224 self.assertEqual(ct.columns[1].reference.on_update,"RESTRICT");
225 self.assertEqual(ct.columns[1].reference.on_delete,"CASCADE");
226 self.assertEqual(ct.columns[1].reference.match_option,"FULL");
227
228 def test_create_table_foreign_constraint_options_constraint_no_name(self):
229 sql= "CREATE TABLE t1 (field1 DECIMAL NOT NULL PRIMARY KEY,CONSTRAINT FOREIGN KEY (field1) REFERENCES reftable (ref_field1) MATCH FULL ON DELETE CASCADE); "
230 statements= parser.parse_string(sql)
231 ct= statements[0]
232 self.assertEqual(ct.table_name.qualifier, None)
233 self.assertEqual(ct.table_name.name, "t1")
234 self.assertEqual(ct.columns[0].name, "field1")
235 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "DECIMAL")
236 self.assertEqual(ct.columns[0].nullable, False)
237 self.assertEqual(ct.columns[0].primary_key, True)
238 self.assertEqual(ct.columns[1].constarint_name, False);
239 self.assertEqual(ct.columns[1].index_name, None);
240 self.assertEqual(ct.columns[1].parent_fields[0],"field1");
241 self.assertEqual(ct.columns[1].reference.name,"reftable");
242 self.assertEqual(ct.columns[1].reference.col_name_list[0],"ref_field1");
243 self.assertEqual(ct.columns[1].reference.on_update,False);
244 self.assertEqual(ct.columns[1].reference.on_delete,"CASCADE");
245 self.assertEqual(ct.columns[1].reference.match_option,"FULL");
246
247 def test_create_table_table_option(self):
248 sql= "CREATE TABLE t1 (field1 INT NOT NULL PRIMARY KEY) AUTO_INCREMENT 5;"
249 statements= parser.parse_string(sql)
250 ct= statements[0]
251 self.assertEqual(ct.table_name.qualifier, None)
252 self.assertEqual(ct.table_name.name, "t1")
253 self.assertEqual(ct.columns[0].name, "field1")
254 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
255 self.assertEqual(ct.columns[0].nullable, False)
256 self.assertEqual(ct.columns[0].primary_key, True)
257 self.assertEqual(ct.table_options[0][0],"AUTO_INCREMENT");
258 self.assertEqual(ct.table_options[0][1],5);
259
260 def test_create_table_table_option_multiple(self):
261 sql= "CREATE TABLE t1 (field1 INT NOT NULL PRIMARY KEY) AUTO_INCREMENT 5 CHARACTER SET utf8;"
262 statements= parser.parse_string(sql)
263 ct= statements[0]
264 self.assertEqual(ct.table_name.qualifier, None)
265 self.assertEqual(ct.table_name.name, "t1")
266 self.assertEqual(ct.columns[0].name, "field1")
267 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
268 self.assertEqual(ct.columns[0].nullable, False)
269 self.assertEqual(ct.columns[0].primary_key, True)
270 self.assertEqual(ct.table_options[0][0],"AUTO_INCREMENT");
271 self.assertEqual(ct.table_options[0][1],5);
272 self.assertEqual(ct.table_options[1][0],"CHARACTER SET");
273 self.assertEqual(ct.table_options[1][1],"utf8");
274
275 def test_create_table_table_option_comment(self):
276 sql= "CREATE TABLE t1 (field1 INT) COMMENT 'comment1';"
277 statements= parser.parse_string(sql)
278 ct= statements[0]
279 self.assertEqual(ct.table_name.qualifier, None)
280 self.assertEqual(ct.table_name.name, "t1")
281 self.assertEqual(ct.columns[0].name, "field1")
282 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
283 self.assertEqual(ct.table_options[0][0],"COMMENT");
284 self.assertEqual(ct.table_options[0][1],"comment1");
285
286 def test_create_table_qualified_identifier(self):
287 sql= "CREATE TABLE t2.t1 (field1 INT);"
288 statements= parser.parse_string(sql)
289 ct= statements[0]
290 self.assertEqual(ct.table_name.qualifier, "t1")
291 self.assertEqual(ct.table_name.name, "t2")
292 self.assertEqual(ct.columns[0].name, "field1")
293 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
294
295
296 def test_create_table_col_list_multiple_ol(self):
297 sql= "CREATE TABLE t1 (field1 INT, field2 CHAR,field3 BLOB);"
298 statements= parser.parse_string(sql)
299 ct= statements[0]
300 self.assertEqual(ct.table_name.qualifier, None)
301 self.assertEqual(ct.table_name.name, "t1")
302 self.assertEqual(ct.columns[0].name, "field1")
303 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
304 self.assertEqual(ct.columns[1].name, "field2")
305 self.assertEqual(str(ct.columns[1].data_type_desc.data_type), "CHAR")
306 self.assertEqual(ct.columns[2].name, "field3")
307 self.assertEqual(str(ct.columns[2].data_type_desc.data_type), "BLOB")
308
309 def test_create_table_table_option(self):
310 sql= "CREATE TABLE t1 (field1 INT NOT NULL DEFAULT a AUTO_INCREMENT PRIMARY KEY COMMENT 'comment1');"
311 statements= parser.parse_string(sql)
312 ct= statements[0]
313 self.assertEqual(ct.table_name.qualifier, None)
314 self.assertEqual(ct.table_name.name, "t1")
315 self.assertEqual(ct.columns[0].name, "field1")
316 self.assertEqual(str(ct.columns[0].data_type_desc.data_type), "INT")
317 self.assertEqual(ct.columns[0].nullable, False)
318 self.assertEqual(ct.columns[0].primary_key, True)
319 self.assertEqual(ct.columns[0].auto_increment, True)
320 self.assertEqual(ct.columns[0].comment,"comment1")
321
322
111323
112if __name__ == '__main__':324if __name__ == '__main__':
113 unittest.main()325 unittest.main()

Subscribers

People subscribed via source and target branches

to all changes: