Merge lp:~nahiljain/to-drizzle/parser-insert into lp:to-drizzle

Proposed by neh
Status: Merged
Merged at revision: 9
Proposed branch: lp:~nahiljain/to-drizzle/parser-insert
Merge into: lp:to-drizzle
Diff against target: 578 lines (+393/-54)
4 files modified
movetodrizzle/helpers/lexer.py (+30/-18)
movetodrizzle/helpers/parser.py (+119/-8)
movetodrizzle/helpers/statement_nodes.py (+54/-28)
tests/parser_insert_test.py (+190/-0)
To merge this branch: bzr merge lp:~nahiljain/to-drizzle/parser-insert
Reviewer Review Type Date Requested Status
Jay Pipes Approve
Review via email: mp+30958@code.launchpad.net

Description of the change

It has minor change in regular expression for strings in lexer.py.. Please check it..
It has code to parse insert table and test cases for it.

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

Very nice work, Nahil! :)

review: Approve

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-23 00:09:44 +0000
3+++ movetodrizzle/helpers/lexer.py 2010-07-26 17:08:46 +0000
4@@ -70,7 +70,16 @@
5 'no' : 'NO',
6 'action' : 'ACTION',
7 'delete' : 'DELETE',
8- 'comment' : 'COMMENT'
9+ 'comment' : 'COMMENT',
10+ 'insert' : 'INSERT',
11+ 'duplicate' : 'DUPLICATE',
12+ 'values' : 'VALUES',
13+ 'value' : 'VALUE',
14+ 'low_priority' : 'LOW_PRIORITY',
15+ 'delayed' : 'DELAYED',
16+ 'high_priority' : 'HIGH_PRIORITY',
17+ 'ignore' : 'IGNORE',
18+ 'into' : 'INTO'
19
20
21 }
22@@ -124,38 +133,41 @@
23
24
25 def t_STRING(t):
26- r"(\'(.*)\')|(\"(.*)\")|(\`(.*)\`)"
27+ #r"(\'(.*)\')|(\"(.*)\")|(\`(.*)\`)"
28+ r"(\'(.*?)\')|(\"(.*?)\")|(\`(.*?)\`)"
29 t.value= t.value[1:-1]
30 return t
31
32+
33+
34 #Define a rule so that we process comments
35 def t_COMMENT_CODE(t):
36- r'\/\*.*\*\/'
37- pass
38+ r'\/\*.*\*\/'
39+ pass
40
41 # Define a rule so we can track line numbers
42 def t_newline(t):
43- r'\n+'
44- t.lexer.lineno += len(t.value)
45+ r'\n+'
46+ t.lexer.lineno += len(t.value)
47
48 # A string containing ignored characters (spaces and tabs)
49 t_ignore = ' \t'
50
51 # Error handling rule
52 def t_error(t):
53- print "Illegal character '%s'" % t.value[0]
54- t.lexer.skip(1)
55+ print "Illegal character '%s'" % t.value[0]
56+ t.lexer.skip(1)
57
58 # Build the lexer
59-lexer = lex.lex(debug=False)
60+lexer = lex.lex(debug= False)
61
62 def tokenize(subject):
63- """Given a string subject, tokenizes the string into LexToken objects and returns them"""
64- lexer.input(subject)
65- results= []
66- while True:
67- t= lex.token()
68- if not t:
69- break
70- results.append(t)
71- return results
72+ """Given a string subject, tokenizes the string into LexToken objects and returns them"""
73+ lexer.input(subject)
74+ results= []
75+ while True:
76+ t= lex.token()
77+ if not t:
78+ break
79+ results.append(t)
80+ return results
81
82=== modified file 'movetodrizzle/helpers/parser.py'
83--- movetodrizzle/helpers/parser.py 2010-07-23 00:09:44 +0000
84+++ movetodrizzle/helpers/parser.py 2010-07-26 17:08:46 +0000
85@@ -17,9 +17,10 @@
86 '''statement : statement_type SEMICOLON'''
87 p[0]= p[1]
88
89+
90 def p_create_table(p):
91 '''statement_type : create_table_simple'''
92- p[0]=p[1]
93+ p[0]= p[1]
94
95 def p_create_table_simple(p):
96 '''create_table_simple : CREATE temporary TABLE if_not_exists identifier_qualified_non_qualified_opt LPAREN col_list RPAREN table_options'''
97@@ -142,7 +143,7 @@
98 if (len(p) == 2):
99 p[0]= p[1]
100 elif (len(p) == 3):
101- p[0]= str(p[1])+str(p[2])
102+ p[0]= str(p[1]) + str(p[2])
103 else:
104 p[0]= None
105
106@@ -285,21 +286,16 @@
107 p[0]= [p[2]]
108 else:
109 p[0]= len(p) > 6;
110-
111-
112
113 def p_unsigned_opt(p):
114 '''unsigned_opt : UNSIGNED
115 | empty'''
116 p[0]= len(p) > 1
117
118-
119 def p_zerofill_opt(p):
120 '''zerofill_opt : ZEROFILL
121 | empty'''
122 p[0]= len(p) > 1
123-
124-
125
126
127 def p_mathematical(p):
128@@ -365,7 +361,6 @@
129 | DEFAULT CHARACTER SET'''
130 pass
131
132-
133 def p_table_option_1(p):
134 """table_option : ENGINE opt_equal identifier
135 | AUTO_INCREMENT opt_equal NUMBER
136@@ -400,6 +395,122 @@
137
138
139
140+
141+
142+def p_insert(p):
143+ '''statement_type : insert_simple
144+ | insert_set'''
145+ p[0]= p[1]
146+
147+def p_insert_simple(p):
148+ '''insert_simple : INSERT priority_opt ignore_opt into_opt identifier index_col_name_list_opt value_values LPAREN expr_default_list RPAREN on_duplicate_opt'''
149+ p[0]= InsertStatement(p[2],p[3],p[5],p[6],p[9],p[11],None);
150+
151+def p_expr_default_list(p):
152+ '''expr_default_list : expr_default COMMA expr_default_list
153+ | expr_default'''
154+ if(len(p) > 2):
155+ p[0]= [p[1]] + p[3]
156+ else:
157+ p[0]= [p[1]]
158+def p_expr_default(p):
159+ '''expr_default : DEFAULT
160+ | FLOAT
161+ | STRING
162+ | NUMBER'''
163+ p[0]= p[1]
164+
165+def p_expr(p):
166+ '''expr : STRING
167+ | FLOAT
168+ | NUMBER'''
169+
170+ p[0]= p[1]
171+
172+def p_on_duplicate_option(p):
173+ '''on_duplicate_opt : ON DUPLICATE KEY UPDATE col_name_expr_list
174+ | empty'''
175+ if(len(p) > 5):
176+ p[0]= p[5]
177+ else:
178+ p[0]= None
179+
180+
181+def p_col_name_expr_list(p):
182+ '''col_name_expr_list : col_name EQUAL expr COMMA col_name_expr_list
183+ | col_name EQUAL expr'''
184+
185+ if(len(p) <= 4):
186+ p[0]= [ColumnNameExprPair(p[1],p[3])];
187+
188+ else:
189+ p[0]= [ColumnNameExprPair(p[1],p[3])] + p[5]
190+
191+def p_col_name(p):
192+ '''col_name : identifier'''
193+ p[0 = p[1]
194+
195+def p_value_values(p):
196+ '''value_values : VALUES
197+ | VALUE'''
198+ p[0]= p[1]
199+
200+def p_priority_opt(p):
201+ '''priority_opt : LOW_PRIORITY
202+ | DELAYED
203+ | HIGH_PRIORITY
204+ | empty'''
205+ if(len(p) > 1):
206+ p[0]= p[1]
207+ else:
208+ p[0]= len(p) > 1;
209+
210+def p_ignore_opt(p):
211+ '''ignore_opt : IGNORE
212+ | empty'''
213+ if(len(p) > 1):
214+ p[0]= p[1];
215+ else:
216+ p[0]= len(p) > 1;
217+
218+def p_into_opt(p):
219+ '''into_opt : INTO
220+ | empty'''
221+ if(len(p) > 1):
222+ p[0]= p[1];
223+ else:
224+ p[0]= len(p) > 1;
225+
226+
227+
228+
229+def p_index_col_name_list_opt(p):
230+ '''index_col_name_list_opt : LPAREN index_col_name_list RPAREN
231+ | empty '''
232+ if(len(p) == 4):
233+ p[0]= p[2]
234+ else:
235+ p[0]= None
236+
237+def p_insert_set(p):
238+ '''insert_set : INSERT priority_opt ignore_opt into_opt identifier SET col_name_expr_default_list on_duplicate_opt'''
239+ p[0]= InsertStatement(p[2],p[3],p[5],None,None,p[8],p[7]);
240+ '''insert_simple : INSERT priority_opt ignore_opt into_opt identifier index_col_name_list_opt value_values LPAREN expr_default_list RPAREN on_duplicate_opt'''
241+
242+
243+
244+
245+def p_col_name_expr_default_list(p):
246+ '''col_name_expr_default_list : col_name EQUAL expr_default COMMA col_name_expr_default_list
247+ | col_name EQUAL expr_default'''
248+
249+ if(len(p) <= 4):
250+ p[0]= [ColumnNameExprPair(p[1],p[3])];
251+
252+ else:
253+ p[0]= [ColumnNameExprPair(p[1],p[3])] + p[5]
254+
255+
256 def p_empty(p):
257 'empty : '
258 pass # an empty rule that represents an optional
259
260=== modified file 'movetodrizzle/helpers/statement_nodes.py'
261--- movetodrizzle/helpers/statement_nodes.py 2010-07-23 00:09:44 +0000
262+++ movetodrizzle/helpers/statement_nodes.py 2010-07-26 17:08:46 +0000
263@@ -21,14 +21,14 @@
264
265 class DataTypeDesc():
266 def __init__(self, data_type, length= None, decimals= None, unsigned= None, zerofill= None, charset_name= None, collate_name= None, binary= None):
267- self.data_type= data_type;
268- self.length= length;
269- self.unsigned= unsigned;
270- self.zerofill= zerofill;
271- self.decimals= decimals;
272- self.collation_name= collate_name;
273- self.charset_name= charset_name;
274- self.binary= binary;
275+ self.data_type= data_type
276+ self.length= length
277+ self.unsigned= unsigned
278+ self.zerofill= zerofill
279+ self.decimals= decimals
280+ self.collation_name= collate_name
281+ self.charset_name= charset_name
282+ self.binary= binary
283
284 def __repr__(self):
285 return "DataTypeDesc(data_type= %s, length= %s, decimals= %s, zerofill= %s, unsigned= %s, collation_name= %s, charset_name= %s, binary= %s)" %(
286@@ -43,14 +43,14 @@
287
288 class ColumnDefinition():
289 def __init__(self, name, data_type_desc, nullable= True, default= None, auto_increment= False, unique= False, primary_key= False, comment= None):
290- self.name= name;
291- self.data_type_desc= data_type_desc;
292- self.nullable= nullable;
293- self.default= default;
294- self.auto_increment= auto_increment;
295- self.unique= unique;
296- self.primary_key= primary_key;
297- self.comment= comment;
298+ self.name= name
299+ self.data_type_desc= data_type_desc
300+ self.nullable= nullable
301+ self.default= default
302+ self.auto_increment= auto_increment
303+ self.unique= unique
304+ self.primary_key= primary_key
305+ self.comment= comment
306 def __repr__(self):
307 return "Column(col_name= %s, data_type_desc= %s, nullable= %s, default= %s, auto_increment= %s, unique= %s, primary_key= %s, comment= %s)" % (
308 self.name,
309@@ -66,16 +66,16 @@
310 class Identifier():
311 def __init__(self, name, qualifier= None):
312 self.name= name
313- self.qualifier= qualifier;
314+ self.qualifier= qualifier
315 def __repr__(self):
316 return "Identifier(name= %s, qualifier= %s)" % (self.name, str(self.qualifier))
317
318 class ForeignKeyConstraint():
319 def __init__(self, constarint_name, index_name, parent_fields, reference):
320- self.constarint_name= constarint_name;
321- self.index_name= index_name;
322- self.reference= reference;
323- self.parent_fields= parent_fields;
324+ self.constarint_name= constarint_name
325+ self.index_name= index_name
326+ self.reference= reference
327+ self.parent_fields= parent_fields
328 def __repr__(self):
329 return "ForeignKeyConstraint(constraint_name= %s, index_name= %s, parent_fields= %s, reference= %s)" %(self.constarint_name, self.index_name, self.parent_fields, self.reference)
330
331@@ -84,19 +84,45 @@
332 self.name= name
333 self.col_name_list= col_name_list
334 self.match_option= match_option
335- self.on_update= on_update;
336- self.on_delete= on_delete;
337+ self.on_update= on_update
338+ self.on_delete= on_delete
339 def __repr__(self):
340- 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);
341+ 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)
342
343 class CreateTableStatement(SqlStatement):
344 def __init__(self, table_name, list_columns, if_not_exists= False, temporary = False):
345- self.table_name= table_name;
346- self.temporary= temporary;
347- self.if_not_exists= if_not_exists;
348- self.columns= list_columns;
349+ self.table_name= table_name
350+ self.temporary= temporary
351+ self.if_not_exists= if_not_exists
352+ self.columns= list_columns
353 self.table_options= {}
354 def update_table_options(self, options):
355 self.table_options= options
356 def __repr__(self):
357 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)
358+
359+class ColumnNameExprPair():
360+ def __init__(self, col_name, expr):
361+ self.column_name= col_name
362+ self.expr= expr
363+ def __repr__(self):
364+ return "ColumnNameExprPair (column_name= %s, expr= %s)" %(self.column_name, self.expr)
365+
366+class InsertStatement(SqlStatement):
367+ def __init__(self,priority, ignore, table_name, index_col_name_list, list_of_values, on_duplicate,set_list):
368+ self.priority= priority
369+ self.ignore= ignore
370+ self.table_name= table_name
371+ self.index_col_name_list= index_col_name_list
372+ self.list_of_values= list_of_values
373+ self.on_duplicate= on_duplicate
374+ self.set_list= set_list
375+ def __repr__(self):
376+ return "InsertStatement(priority= %s, ignore= %s, table_name= %s, index_col_name_list= %s, list_of_values= %s, on_duplicate= %s, set_list= %s)" % (
377+ self.priority,
378+ self.ignore,
379+ self.table_name,
380+ self.index_col_name_list,
381+ self.list_of_values,
382+ self.on_duplicate,
383+ self.set_list)
384
385=== added file 'tests/parser_insert_test.py'
386--- tests/parser_insert_test.py 1970-01-01 00:00:00 +0000
387+++ tests/parser_insert_test.py 2010-07-26 17:08:46 +0000
388@@ -0,0 +1,190 @@
389+#!/usr/bin/python
390+import sys
391+import unittest
392+sys.path.append("../movetodrizzle")
393+import helpers.parser as parser
394+
395+class Tester( unittest.TestCase ):
396+ def test_insert_table_simple( self ):
397+ sql = "INSERT INTO t1 values (21,22);"
398+ statements = parser.parse_string ( sql )
399+ ct = statements[0]
400+ self.assertEqual( ct.priority, None )
401+ self.assertEqual( ct.ignore, None )
402+ self.assertEqual( ct.table_name, "t1" )
403+ self.assertEqual( ct.index_col_name_list, None )
404+ self.assertEqual( ct.list_of_values, [21, 22] )
405+ self.assertEqual( ct.on_duplicate, None )
406+ self.assertEqual( ct.set_list, None )
407+
408+ def test_insert_table_priority( self ):
409+ sql = "INSERT LOW_PRIORITY INTO t1 values (21,22);"
410+ statements = parser.parse_string ( sql )
411+ ct = statements[0]
412+ self.assertEqual( ct.priority, "LOW_PRIORITY" )
413+ self.assertEqual( ct.ignore, None )
414+ self.assertEqual( ct.table_name, "t1" )
415+ self.assertEqual( ct.index_col_name_list, None )
416+ self.assertEqual( ct.list_of_values, [21, 22] )
417+ self.assertEqual( ct.on_duplicate, None )
418+ self.assertEqual( ct.set_list, None )
419+
420+ def test_insert_table_priority_IGNORE( self ):
421+ sql = "INSERT LOW_PRIORITY IGNORE INTO t1 values (21,22);"
422+ statements = parser.parse_string ( sql )
423+ ct = statements[0]
424+ self.assertEqual( ct.priority, "LOW_PRIORITY" )
425+ self.assertEqual( ct.ignore, "IGNORE" )
426+ self.assertEqual( ct.table_name, "t1" )
427+ self.assertEqual( ct.index_col_name_list, None )
428+ self.assertEqual( ct.list_of_values, [21, 22] )
429+ self.assertEqual( ct.on_duplicate, None )
430+ self.assertEqual( ct.set_list, None )
431+
432+
433+ def test_insert_table_priority_IGNORE( self ):
434+ sql = "INSERT LOW_PRIORITY IGNORE INTO t1 values (21,22);"
435+ statements = parser.parse_string ( sql )
436+ ct = statements[0]
437+ self.assertEqual( ct.priority, "LOW_PRIORITY" )
438+ self.assertEqual( ct.ignore, "IGNORE" )
439+ self.assertEqual( ct.table_name, "t1" )
440+ self.assertEqual( ct.index_col_name_list, None )
441+ self.assertEqual( ct.list_of_values, [21, 22] )
442+ self.assertEqual( ct.on_duplicate, None )
443+ self.assertEqual( ct.set_list, None )
444+
445+ def test_insert_table_priority_IGNORE_opt_column_list( self ):
446+ sql = "INSERT LOW_PRIORITY IGNORE INTO t1 (a1,a2) values (21,22);"
447+ statements = parser.parse_string ( sql )
448+ ct = statements[0]
449+ self.assertEqual( ct.priority, "LOW_PRIORITY" )
450+ self.assertEqual( ct.ignore, "IGNORE" )
451+ self.assertEqual( ct.table_name, "t1" )
452+ self.assertEqual( ct.index_col_name_list, ['a1','a2'] )
453+ self.assertEqual( ct.list_of_values, [21, 22] )
454+ self.assertEqual( ct.on_duplicate, None )
455+ self.assertEqual( ct.set_list, None )
456+
457+ def test_insert_table_column_list_on_duplicate(self):
458+ sql = "INSERT INTO t1 (a1,a2) values (21,22) ON DUPLICATE KEY UPDATE b1=200, b2='abc', b3='some_value';"
459+ statements = parser.parse_string ( sql )
460+ ct = statements[0]
461+ self.assertEqual( ct.priority, None )
462+ self.assertEqual( ct.ignore, None )
463+ self.assertEqual( ct.table_name, "t1" )
464+ self.assertEqual( ct.index_col_name_list, ['a1','a2'] )
465+ self.assertEqual( ct.list_of_values, [21, 22] )
466+ self.assertEqual( ct.on_duplicate[0].column_name,"b1" )
467+ self.assertEqual( ct.on_duplicate[0].expr,200 )
468+ self.assertEqual( ct.on_duplicate[1].column_name,"b2" )
469+ self.assertEqual( ct.on_duplicate[1].expr,'abc' )
470+ self.assertEqual( ct.on_duplicate[2].column_name,"b3" )
471+ self.assertEqual( ct.on_duplicate[2].expr,'some_value' )
472+ self.assertEqual( ct.set_list, None )
473+
474+ def test_insert_table_set_basic_default( self ):
475+ sql = "INSERT INTO t1 SET a1=DEFAULT;"
476+ statements = parser.parse_string (sql)
477+ ct = statements[0]
478+ self.assertEqual( ct.priority, None )
479+ self.assertEqual( ct.ignore, None )
480+ self.assertEqual( ct.table_name, "t1" )
481+ self.assertEqual( ct.index_col_name_list, None )
482+ self.assertEqual( ct.list_of_values, None )
483+ self.assertEqual( ct.on_duplicate, None )
484+ self.assertEqual( ct.set_list[0].column_name, "a1" )
485+ self.assertEqual( ct.set_list[0].expr, "DEFAULT" )
486+
487+
488+ def test_insert_table_set_basic_string( self ):
489+ sql = "INSERT INTO t1 SET a1='abc';"
490+ statements = parser.parse_string ( sql )
491+ ct = statements[0]
492+ self.assertEqual( ct.priority, None )
493+ self.assertEqual( ct.ignore, None )
494+ self.assertEqual( ct.table_name, "t1" )
495+ self.assertEqual( ct.index_col_name_list, None )
496+ self.assertEqual( ct.list_of_values, None )
497+ self.assertEqual( ct.on_duplicate, None )
498+ self.assertEqual( ct.set_list[0].column_name, "a1" )
499+ self.assertEqual( ct.set_list[0].expr, "abc" )
500+
501+
502+ def test_insert_table_set_basic_number( self ):
503+ sql = "INSERT INTO t1 SET a1=10;"
504+ statements = parser.parse_string ( sql )
505+ ct = statements[0]
506+ self.assertEqual( ct.priority, None )
507+ self.assertEqual( ct.ignore, None )
508+ self.assertEqual( ct.table_name, "t1" )
509+ self.assertEqual( ct.index_col_name_list, None )
510+ self.assertEqual( ct.list_of_values, None )
511+ self.assertEqual( ct.on_duplicate, None )
512+ self.assertEqual( ct.set_list[0].column_name, "a1" )
513+ self.assertEqual( ct.set_list[0].expr, 10 )
514+
515+ def test_insert_table_set_basic_number_PRIORITY_IGNORE( self ):
516+ sql = "INSERT LOW_PRIORITY IGNORE INTO t1 SET a1=10;"
517+ statements = parser.parse_string ( sql )
518+ ct = statements[0]
519+ self.assertEqual( ct.priority, "LOW_PRIORITY" )
520+ self.assertEqual( ct.ignore, "IGNORE" )
521+ self.assertEqual( ct.table_name, "t1" )
522+ self.assertEqual( ct.index_col_name_list, None )
523+ self.assertEqual( ct.list_of_values, None)
524+ self.assertEqual( ct.on_duplicate, None )
525+ self.assertEqual( ct.set_list[0].column_name, "a1" )
526+ self.assertEqual( ct.set_list[0].expr, 10 )
527+
528+ def test_insert_table_set_multiple_number_string(self):
529+ sql = "INSERT INTO t1 SET a1= 10,a2='abc',a3=DEFAULT;"
530+ statements = parser.parse_string (sql)
531+ ct = statements[0]
532+ self.assertEqual( ct.priority, None )
533+ self.assertEqual( ct.ignore, None )
534+ self.assertEqual( ct.table_name, "t1" )
535+ self.assertEqual( ct.index_col_name_list, None )
536+ self.assertEqual( ct.list_of_values, None)
537+ self.assertEqual( ct.on_duplicate, None )
538+ self.assertEqual( ct.set_list[0].column_name, "a1" )
539+ self.assertEqual( ct.set_list[0].expr, 10 )
540+ self.assertEqual( ct.set_list[1].column_name, "a2" )
541+ self.assertEqual( ct.set_list[1].expr, 'abc' )
542+ self.assertEqual( ct.set_list[2].column_name, "a3" )
543+ self.assertEqual( ct.set_list[2].expr, 'DEFAULT' )
544+
545+ def test_insert_table_set_basic_number_on_duplicate_single( self ):
546+ sql = "INSERT INTO t1 SET a1=10 ON DUPLICATE KEY UPDATE b1=200;"
547+ statements = parser.parse_string ( sql )
548+ ct = statements[0]
549+ self.assertEqual( ct.priority, None )
550+ self.assertEqual( ct.ignore, None )
551+ self.assertEqual( ct.table_name, "t1" )
552+ self.assertEqual( ct.index_col_name_list, None )
553+ self.assertEqual( ct.list_of_values, None )
554+ self.assertEqual( ct.on_duplicate[0].column_name,"b1" )
555+ self.assertEqual( ct.on_duplicate[0].expr,200 )
556+ self.assertEqual( ct.set_list[0].column_name, "a1" )
557+ self.assertEqual( ct.set_list[0].expr, 10 )
558+
559+ def test_insert_table_set_basic_number_on_duplicate_multiple( self ):
560+ sql = "INSERT INTO t1 SET a1=10 ON DUPLICATE KEY UPDATE b1=200, b2='abc', b3='some_value';"
561+ statements = parser.parse_string ( sql )
562+ ct = statements[0]
563+ self.assertEqual( ct.priority, None )
564+ self.assertEqual( ct.ignore, None )
565+ self.assertEqual( ct.table_name, "t1" )
566+ self.assertEqual( ct.index_col_name_list, None )
567+ self.assertEqual( ct.list_of_values, None)
568+ self.assertEqual( ct.on_duplicate[0].column_name,"b1" )
569+ self.assertEqual( ct.on_duplicate[0].expr,200 )
570+ self.assertEqual( ct.on_duplicate[1].column_name,"b2" )
571+ self.assertEqual( ct.on_duplicate[1].expr,'abc' )
572+ self.assertEqual( ct.on_duplicate[2].column_name,"b3" )
573+ self.assertEqual( ct.on_duplicate[2].expr,'some_value' )
574+ self.assertEqual( ct.set_list[0].column_name, "a1" )
575+ self.assertEqual( ct.set_list[0].expr, 10 )
576+
577+if __name__ == '__main__':
578+ unittest.main()

Subscribers

People subscribed via source and target branches

to all changes: