Skip to content
Snippets Groups Projects
Commit 78031e79 authored by Konstantin Osipov's avatar Konstantin Osipov
Browse files

Merge branch 'bug944708'

parents 84fa06dc bc47c5e3
No related branches found
No related tags found
No related merge requests found
return_code: 0
return_code: ER_ILLEGAL_PARAMS, Illegal parameters, tuple count must be positive
return_code: ER_NO_SUCH_INDEX, No index #1 is defined in space 0
delete from t0 where k0 = 1
Delete OK, 1 row affected
# encoding: tarantool
#
import subprocess
import sys
import os
......@@ -7,3 +9,6 @@ p = subprocess.Popen([ os.path.join(builddir, "test/box/protocol") ],
p.wait()
for line in p.stdout.readlines():
sys.stdout.write(line)
exec sql "delete from t0 where k0 = 1"
# vim: syntax=python
......@@ -53,8 +53,8 @@ An error occurred: ER_NO_SUCH_FIELD, 'Field 1000 was not found in the tuple'
select * from t0 where k0 = 1
Found 1 tuple:
[1, 'Huh', 'I am a new field! I was added via append']
insert into t0 values (1, 'I am a new tuple', 'stub')
Insert OK, 1 row affected
replace into t0 values (1, 'I am a new tuple', 'stub')
Replace OK, 1 row affected
update t0 set k1 = 'Huh', k2 = 'Oh-ho-ho' where k0=1
Update OK, 1 row affected
select * from t0 where k0 = 1
......
......@@ -30,7 +30,7 @@ exec sql "select * from t0 where k0 = 1"
# this is illegal
exec sql "update t0 set k1 = 'Huh', k1000 = 'invalid field' where k0=1"
exec sql "select * from t0 where k0 = 1"
exec sql "insert into t0 values (1, 'I am a new tuple', 'stub')"
exec sql "replace into t0 values (1, 'I am a new tuple', 'stub')"
exec sql "update t0 set k1 = 'Huh', k2 = 'Oh-ho-ho' where k0=1"
exec sql "select * from t0 where k0 = 1"
# check empty strings
......
......@@ -76,8 +76,8 @@ Delete OK, 1 row affected
#
insert into t1 values ('key1', 'part1', 'part2')
Insert OK, 1 row affected
insert into t1 values ('key1', 'part1', 'part2')
Insert OK, 1 row affected
replace into t1 values ('key1', 'part1', 'part2')
Replace OK, 1 row affected
insert into t1 values ('key2', 'part1', 'part2_a')
Insert OK, 1 row affected
insert into t1 values ('key3', 'part1', 'part2_b')
......@@ -241,7 +241,7 @@ Found 1 tuple:
select * from t4 where k1='Britney'
Found 1 tuple:
['Spears', 'Britney']
insert into t4 values ('Spears')
replace into t4 values ('Spears')
An error occurred: ER_ILLEGAL_PARAMS, 'Illegal parameters, tuple must have all indexed fields'
select * from t4 where k0='Spears'
Found 1 tuple:
......
......@@ -53,7 +53,7 @@ print """#
#"""
exec sql "insert into t1 values ('key1', 'part1', 'part2')"
# Test a duplicate insert on unique index that once resulted in a crash (bug #926080)
exec sql "insert into t1 values ('key1', 'part1', 'part2')"
exec sql "replace into t1 values ('key1', 'part1', 'part2')"
exec sql "insert into t1 values ('key2', 'part1', 'part2_a')"
exec sql "insert into t1 values ('key3', 'part1', 'part2_b')"
exec admin "lua for k, v in box.space[1]:pairs() do print(v) end"
......@@ -125,7 +125,7 @@ exec sql "insert into t4 values ('Spears', 'Britney')"
exec sql "select * from t4 where k0='Spears'"
exec sql "select * from t4 where k1='Britney'"
# try to insert the incoplete tuple
exec sql "insert into t4 values ('Spears')"
exec sql "replace into t4 values ('Spears')"
# check that nothing has been updated
exec sql "select * from t4 where k0='Spears'"
# cleanup
......
......@@ -18,6 +18,7 @@ parser sql:
token STR: '\'([^\']+|\\\\.)*\''
token PING: 'ping'
token INSERT: 'insert'
token REPLACE: 'replace'
token UPDATE: 'update'
token DELETE: 'delete'
token SELECT: 'select'
......@@ -32,6 +33,7 @@ parser sql:
token END: '\\s*$'
rule sql: (insert {{ stmt = insert }} |
replace {{ stmt = replace }} |
update {{ stmt = update }} |
delete {{ stmt = delete }} |
select {{ stmt = select }} |
......@@ -40,6 +42,8 @@ parser sql:
rule insert: INSERT [INTO] ident VALUES value_list
{{ return sql_ast.StatementInsert(ident, value_list) }}
rule replace: REPLACE [INTO] ident VALUES value_list
{{ return sql_ast.StatementReplace(ident, value_list) }}
rule update: UPDATE ident SET update_list opt_simple_where
{{ return sql_ast.StatementUpdate(ident, update_list, opt_simple_where) }}
rule delete: DELETE FROM ident opt_simple_where
......
......@@ -23,6 +23,7 @@ class sqlScanner(runtime.Scanner):
('STR', re.compile("'([^']+|\\\\.)*'")),
('PING', re.compile('ping')),
('INSERT', re.compile('insert')),
('REPLACE', re.compile('replace')),
('UPDATE', re.compile('update')),
('DELETE', re.compile('delete')),
('SELECT', re.compile('select')),
......@@ -43,10 +44,13 @@ class sql(runtime.Parser):
Context = runtime.Context
def sql(self, _parent=None):
_context = self.Context(_parent, self._scanner, 'sql', [])
_token = self._peek('INSERT', 'UPDATE', 'DELETE', 'SELECT', 'CALL', 'PING', context=_context)
_token = self._peek('INSERT', 'REPLACE', 'UPDATE', 'DELETE', 'SELECT', 'CALL', 'PING', context=_context)
if _token == 'INSERT':
insert = self.insert(_context)
stmt = insert
elif _token == 'REPLACE':
replace = self.replace(_context)
stmt = replace
elif _token == 'UPDATE':
update = self.update(_context)
stmt = update
......@@ -75,6 +79,16 @@ class sql(runtime.Parser):
value_list = self.value_list(_context)
return sql_ast.StatementInsert(ident, value_list)
def replace(self, _parent=None):
_context = self.Context(_parent, self._scanner, 'replace', [])
REPLACE = self._scan('REPLACE', context=_context)
if self._peek('INTO', 'ID', context=_context) == 'INTO':
INTO = self._scan('INTO', context=_context)
ident = self.ident(_context)
VALUES = self._scan('VALUES', context=_context)
value_list = self.value_list(_context)
return sql_ast.StatementReplace(ident, value_list)
def update(self, _parent=None):
_context = self.Context(_parent, self._scanner, 'update', [])
UPDATE = self._scan('UPDATE', context=_context)
......
......@@ -210,7 +210,7 @@ class StatementInsert(StatementPing):
def __init__(self, table_name, value_list):
self.space_no = table_name
self.flags = 0
self.flags = 0x02 # ADD
self.value_list = value_list
def pack(self):
......@@ -226,6 +226,26 @@ class StatementInsert(StatementPing):
(tuple_count,) = struct.unpack("<L", response[4:8])
return "Insert OK, {0} row affected".format(tuple_count)
class StatementReplace(StatementPing):
reqeust_type = INSERT_REQUEST_TYPE
def __init__(self, table_name, value_list):
self.space_no = table_name
self.flags = 0x04 # REPLACE
self.value_list = value_list
def pack(self):
buf = ctypes.create_string_buffer(PACKET_BUF_LEN)
(buf, offset) = pack_tuple(self.value_list, buf, INSERT_REQUEST_FIXED_LEN)
struct.pack_into("<LL", buf, 0, self.space_no, self.flags)
return buf[:offset]
def unpack(self, response):
(return_code,) = struct.unpack("<L", response[:4])
if return_code:
return format_error(return_code, response)
(tuple_count,) = struct.unpack("<L", response[4:8])
return "Replace OK, {0} row affected".format(tuple_count)
class StatementUpdate(StatementPing):
reqeust_type = UPDATE_REQUEST_TYPE
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment