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