Changeset: ddd19401794d for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ddd19401794d Added Files: sql/test/VOC/Tests/double_is_null.Bug-3116.sql sql/test/VOC/Tests/double_is_null.Bug-3116.stable.err sql/test/VOC/Tests/double_is_null.Bug-3116.stable.out Modified Files: clients/Tests/exports.stable.out clients/python/monetdb/mapi2.py clients/python/monetdb/mapi3.py clients/python/monetdb/sql/connections.py clients/python/monetdb/sql/cursors.py clients/python/test/capabilities.py clients/python/test/runtests.py gdk/ChangeLog.Jul2012 gdk/gdk.h gdk/gdk_bat.c gdk/gdk_logger.c gdk/gdk_search.mx monetdb5/modules/kernel/bat5.mx sql/backends/monet5/datacell/basket.c sql/backends/monet5/datacell/emitter.c sql/backends/monet5/sql.mx sql/server/rel_optimizer.c sql/server/rel_updates.c sql/storage/bat/bat_utils.c sql/storage/bat/bat_utils.h sql/storage/restrict/restrict_storage.h sql/test/VOC/Tests/All Branch: default Log Message:
Merge with Jul2012 branch. diffs (truncated from 620 to 300 lines): diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out --- a/clients/Tests/exports.stable.out +++ b/clients/Tests/exports.stable.out @@ -90,7 +90,7 @@ BAT *BATcalcsub(BAT *b1, BAT *b2, int tp BAT *BATcalcsubcst(BAT *b, const ValRecord *v, int tp, int accum, int abort_on_error); BAT *BATcalcxor(BAT *b1, BAT *b2, int accum); BAT *BATcalcxorcst(BAT *b, const ValRecord *v, int accum); -BAT *BATclear(BAT *b); +BAT *BATclear(BAT *b, int force); BAT *BATcommit(BAT *b); BAT *BATconst(BAT *l, int tt, const void *val); BAT *BATconvert(BAT *b, int tp, int abort_on_error); diff --git a/clients/python/monetdb/mapi2.py b/clients/python/monetdb/mapi2.py --- a/clients/python/monetdb/mapi2.py +++ b/clients/python/monetdb/mapi2.py @@ -63,6 +63,7 @@ class Server: def __init__(self): self.state = STATE_INIT self._result = None + self.socket = None def connect(self, hostname, port, username, password, database, language): """ connect to a MonetDB database using the mapi protocol""" @@ -259,3 +260,7 @@ class Server: raise OperationalError(error[1]) pos += length + + def __del__(self): + if self.socket: + self.socket.close() diff --git a/clients/python/monetdb/mapi3.py b/clients/python/monetdb/mapi3.py --- a/clients/python/monetdb/mapi3.py +++ b/clients/python/monetdb/mapi3.py @@ -62,6 +62,7 @@ class Server: def __init__(self): self.state = STATE_INIT self._result = None + self.socket = None def connect(self, hostname, port, username, password, database, language): """ connect to a MonetDB database using the mapi protocol""" @@ -265,3 +266,8 @@ class Server: raise OperationalError(error[1]) pos += length + + def __del__(self): + if self.socket: + self.socket.close() + diff --git a/clients/python/monetdb/sql/connections.py b/clients/python/monetdb/sql/connections.py --- a/clients/python/monetdb/sql/connections.py +++ b/clients/python/monetdb/sql/connections.py @@ -54,10 +54,10 @@ class Connection: if host is not None: hostname = host self.mapi = mapi.Server() - self.autocommit = autocommit self.mapi.connect(hostname=hostname, port=int(port), username=username, password=password, database=database, language="sql") - self.set_autocommit(self.autocommit) + self.set_autocommit(autocommit) + self.set_sizeheader(True) self.use_unicode=use_unicode @@ -89,6 +89,14 @@ class Connection: self.autocommit = autocommit + def set_sizeheader(self, sizeheader): + """ + Set sizeheader on or off. When enabled monetdb will return + the size a type. 'sizeheader' must be a boolean. + """ + self.command("Xsizeheader %s" % int(sizeheader)) + self.sizeheader = sizeheader + def commit(self): """ diff --git a/clients/python/monetdb/sql/cursors.py b/clients/python/monetdb/sql/cursors.py --- a/clients/python/monetdb/sql/cursors.py +++ b/clients/python/monetdb/sql/cursors.py @@ -407,15 +407,16 @@ class Cursor: rows = [] # set up fields for description - empty = [None]*columns - table_name = empty - column_name = empty - type = empty - display_size = empty - internal_size = empty - precision = empty - scale = empty - null_ok = empty + table_name = [None]*columns + column_name = [None]*columns + type_ = [None]*columns + display_size = [None]*columns + internal_size = [None]*columns + precision = [None]*columns + scale = [None]*columns + null_ok = [None]*columns + + typesizes = [(0,0)]*columns for line in lines[1:]: if line.startswith(mapi.MSG_HEADER): @@ -428,17 +429,23 @@ class Cursor: elif identity == "name": column_name = values elif identity == "type": - type = values + type_ = values elif identity == "length": - internal_size = [int(x) for x in values] - display_size = internal_size + pass # not used + elif identity == "typesizes": + typesizes = [[int(j) for j in i.split()] for i in values] + internal_size = [x[0] for x in typesizes] + for num, typeelem in enumerate(type_): + if typeelem in ['decimal']: + precision[num] = typesizes[num][0] + scale[num] = typesizes[num][1] else: self.messages.append((InterfaceError, "unknown header field")) self.__exception_handler(InterfaceError, "unknown header field") - self.description = list(zip(column_name, type, + self.description = list(zip(column_name, type_, display_size, internal_size, precision, scale, null_ok)) if line.startswith(mapi.MSG_TUPLE): diff --git a/clients/python/test/capabilities.py b/clients/python/test/capabilities.py --- a/clients/python/test/capabilities.py +++ b/clients/python/test/capabilities.py @@ -122,11 +122,11 @@ class DatabaseTest(unittest.TestCase): l = self.cursor.fetchall() if self.debug: print(l) - self.assertEquals(len(l), self.rows) + self.assertEqual(len(l), self.rows) try: for i in range(self.rows): for j in range(len(columndefs)): - self.assertEquals(l[i][j], generator(i,j)) + self.assertEqual(l[i][j], generator(i,j)) finally: if not self.debug: self.cursor.execute('drop table %s' % (self.table)) @@ -148,10 +148,10 @@ class DatabaseTest(unittest.TestCase): self.connection.commit() self.cursor.execute('select * from %s' % self.table) l = self.cursor.fetchall() - self.assertEquals(len(l), self.rows) + self.assertEqual(len(l), self.rows) for i in range(self.rows): for j in range(len(columndefs)): - self.assertEquals(l[i][j], generator(i,j)) + self.assertEqual(l[i][j], generator(i,j)) delete_statement = 'delete from %s where col1=%%s' % self.table self.cursor.execute(delete_statement, (0,)) self.cursor.execute('select col1 from %s where col1=%s' % \ diff --git a/clients/python/test/runtests.py b/clients/python/test/runtests.py --- a/clients/python/test/runtests.py +++ b/clients/python/test/runtests.py @@ -80,6 +80,19 @@ class Test_Capabilities(capabilities.Dat username=TSTUSERNAME, password=TSTPASSWORD, autocommit=False) leak_test = False + def test_description(self): + self.table = self.new_table_name() + self.cursor.execute("create table %s (c VARCHAR(1024), d DECIMAL(9,4), n VARCHAR(1) NOT NULL)" % self.table); + self.cursor.execute("insert into %s VALUES ('test', 12345.1234, 'x')" % self.table) + self.cursor.execute('select * from %s' % self.table) + description = self.cursor.description + shouldbe = [ + ('c', 'varchar', None, 1024, None, None, None), + ('d', 'decimal', None, 9, 9, 4, None), + ('n', 'varchar', None, 1, None, None, None), + ] + self.assertEqual(description, shouldbe, "cursor.description is incorrect") + def test_bigresult(self): self.cursor.execute('select count(*) from tables') r = self.cursor.fetchone() @@ -87,9 +100,7 @@ class Test_Capabilities(capabilities.Dat self.cursor.arraysize=1000 self.cursor.execute('select * from tables, tables') r = self.cursor.fetchall() - self.assertEquals(len(r), n**2) - - + self.assertEqual(len(r), n**2) @@ -122,10 +133,9 @@ class Test_DBAPI20(dbapi20.DatabaseAPI20 def _connect(self): try: con = self.driver.connect( *self.connect_args, **self.connect_kwargs) + return con except AttributeError: self.fail("No connect method found in self.driver module") - finally: - return con def tearDown(self): diff --git a/gdk/ChangeLog.Jul2012 b/gdk/ChangeLog.Jul2012 --- a/gdk/ChangeLog.Jul2012 +++ b/gdk/ChangeLog.Jul2012 @@ -1,3 +1,8 @@ # ChangeLog file for MonetDB # This file is updated with Maddlog +* Mon Jul 9 2012 Niels Nes <ni...@cwi.nl> +- Fixed intermittent problem that joins and selects return incorrect + results and possibly inconsistent databases. The problems only occurred + after a series of queries and updates, therefore it was hard to reproduce. + diff --git a/gdk/gdk.h b/gdk/gdk.h --- a/gdk/gdk.h +++ b/gdk/gdk.h @@ -1501,7 +1501,7 @@ gdk_export int BATgetaccess(BAT *b); * @- BAT manipulation * @multitable @columnfractions 0.08 0.7 * @item BAT * - * @tab BATclear (BAT *b) + * @tab BATclear (BAT *b, int force) * @item BAT * * @tab BATcopy (BAT *b, int ht, int tt, int writeable) * @item BAT * @@ -1532,7 +1532,7 @@ gdk_export int BATgetaccess(BAT *b); * a state change in the BAT (as previously): both views on the BAT * exist at the same time. */ -gdk_export BAT *BATclear(BAT *b); +gdk_export BAT *BATclear(BAT *b, int force); gdk_export BAT *BATcopy(BAT *b, int ht, int tt, int writeable); gdk_export BAT *BATmark(BAT *b, oid base); gdk_export BAT *BATmark_grp(BAT *b, BAT *g, oid *base); diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c --- a/gdk/gdk_bat.c +++ b/gdk/gdk_bat.c @@ -492,7 +492,7 @@ BATextend(BAT *b, BUN newcap) * the heaps by copying a standard small empty image over them. */ BAT * -BATclear(BAT *b) +BATclear(BAT *b, int force) { BUN p, q; int voidbat; @@ -511,7 +511,7 @@ BATclear(BAT *b) } /* small BAT: delete all elements by hand */ - if (!voidbat && b->batCount < 20) { + if (!force && !voidbat && b->batCount < 20) { BATloopDEL(b, p, q) { p = BUNdelete(b, p, FALSE); } @@ -585,7 +585,10 @@ BATclear(BAT *b) } } - b->batFirst = b->batInserted; + if (force) + b->batFirst = b->batDeleted = b->batInserted = 0; + else + b->batFirst = b->batInserted; BATsetcount(b,0); b->batDirty = TRUE; BATsettrivprop(b); diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c --- a/gdk/gdk_logger.c +++ b/gdk/gdk_logger.c @@ -234,7 +234,7 @@ la_bat_clear(logger *lg, logaction *la) if (b) { int access = b->P->restricted; b->P->restricted = BAT_WRITE; - BATclear(b); + BATclear(b, TRUE); b->P->restricted = access; logbat_destroy(b); } @@ -884,7 +884,7 @@ logger_commit(logger *lg) /* cleanup old snapshots */ if (BATcount(lg->snapshots)) { - BATclear(lg->snapshots); + BATclear(lg->snapshots, FALSE); BATcommit(lg->snapshots); _______________________________________________ Checkin-list mailing list Checkin-list@monetdb.org http://mail.monetdb.org/mailman/listinfo/checkin-list