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 <[email protected]>
+- 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
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list