Changeset: 58c00c3172e3 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=58c00c3172e3 Modified Files: Branch: default Log Message:
Merged from Dec2011
diffs (truncated from 870 to 300 lines):
diff --git a/buildtools/Mx/Code.c b/buildtools/Mx/Code.c
--- a/buildtools/Mx/Code.c
+++ b/buildtools/Mx/Code.c
@@ -341,8 +341,6 @@ CodeSubBlk(char *sub, char **argv)
outofmem:
Error("Limit of %d characters per block reached.", blk_size);
exit(1);
- return 0;
-
}
void
diff --git a/buildtools/Mx/Mx.c b/buildtools/Mx/Mx.c
--- a/buildtools/Mx/Mx.c
+++ b/buildtools/Mx/Mx.c
@@ -147,7 +147,6 @@ main(int argc, char **argv)
GenForm();
exit(mx_err ? 1 : 0);
- return 1;
}
Directive str2dir[] = {
diff --git a/buildtools/Mx/Tok.c b/buildtools/Mx/Tok.c
--- a/buildtools/Mx/Tok.c
+++ b/buildtools/Mx/Tok.c
@@ -122,7 +122,7 @@ NxtTok(Tok * t)
if (!HideDir(t->t_dir))
for (; t->t_nxt[0]; t->t_nxt++) {
- if ((t->t_nxt[0] == '\n'))
+ if (t->t_nxt[0] == '\n')
break;
if ((t->t_nxt[0] == MARK) && (t->t_nxt[-1] !=
'\\'))
break;
diff --git a/java/ChangeLog.Dec2011 b/java/ChangeLog.Dec2011
--- a/java/ChangeLog.Dec2011
+++ b/java/ChangeLog.Dec2011
@@ -1,6 +1,11 @@
# ChangeLog file for java
# This file is updated with Maddlog
+* Sat Dec 10 2011 Fabian Groffen <[email protected]>
+- Fixed a bug where closing ResultSets and PreparedStatements could lead
+ to errors on concurrent running queries using the same Connection due
+ to a race condition.
+
* Thu Dec 8 2011 Fabian Groffen <[email protected]>
- Changed version scheme of JDBC driver and MCL jar to be more standard,
from monetdb-X.Y-<thing>.jar to monetdb-<thing>-X.Y.jar, bug #2943
diff --git a/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
b/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
--- a/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
+++ b/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
@@ -256,7 +256,7 @@ public class MonetConnection extends Mon
tz += (Math.abs(offset) / 60 < 10 ? "0" : "") +
(Math.abs(offset) / 60) + ":";
offset -= (offset / 60) * 60;
tz += (offset < 10 ? "0" : "") + offset;
- sendIndependantCommand("SET TIME ZONE INTERVAL '" + tz
+ "' HOUR TO MINUTE");
+ sendIndependentCommand("SET TIME ZONE INTERVAL '" + tz
+ "' HOUR TO MINUTE");
}
// we're absolutely not closed, since we're brand new
@@ -1244,7 +1244,7 @@ public class MonetConnection extends Mon
* @param command the exact string to send to MonetDB
* @throws SQLException if an IO exception or a database error occurs
*/
- void sendIndependantCommand(String command) throws SQLException {
+ void sendIndependentCommand(String command) throws SQLException {
synchronized (server) {
try {
out.writeLine(
@@ -1285,46 +1285,6 @@ public class MonetConnection extends Mon
}
/**
- * Sends the given string to MonetDB as data; it is sent using a
- * special Xcopy mode of the server, allowing not to make any
- * changes to the given in String. A Response is returned, just
- * like for a normal query.
- *
- * @param in the exact string to send to MonetDB
- * @param name the name to associate to the data in in
- * @return A Response object, or null if no response
- * @throws SQLException if a database error occurs
- */
- Response copyToServer(String in, String name) throws SQLException {
- synchronized (server) {
- // TODO: maybe in the future add support for a second
- // name which is a convenience "alias" (e.g. in XQuery)
- // tell server we're going to "copy" data over to be
- // stored under the given name, make up something if the
- // caller doesn't know it too
- if (name == null) {
- name = "doc_" + System.currentTimeMillis() +
".xml";
- addWarning("adding new document with name: " +
name);
- }
- sendControlCommand("copy " + name);
- // the server is waiting for data to come
- String[] templ = new String[3]; // empty on everything
- ResponseList l = new ResponseList(
- 0,
- 0,
- ResultSet.FETCH_FORWARD,
- ResultSet.CONCUR_READ_ONLY
- );
- try {
- l.executeQuery(templ, in);
- return(l.getNextResponse()); // don't you love
Java?
- } finally {
- l.close();
- }
- }
- }
-
- /**
* Adds a warning to the pile of warnings this Connection object
* has. If there were no warnings (or clearWarnings was called)
* this warning will be the first, otherwise this warning will get
@@ -2154,216 +2114,218 @@ public class MonetConnection extends Mon
String error = null;
try {
- // make sure we're ready to send query; read
data till we
- // have the prompt it is possible (and most
likely) that we
- // already have the prompt and do not have to
skip any
- // lines. Ignore errors from previous result
sets.
- in.waitForPrompt();
+ synchronized (server) {
+ // make sure we're ready to send query;
read data till we
+ // have the prompt it is possible (and
most likely) that we
+ // already have the prompt and do not
have to skip any
+ // lines. Ignore errors from previous
result sets.
+ in.waitForPrompt();
- int size;
- // {{{ set reply size
- /**
- * Change the reply size of the server. If the
given
- * value is the same as the current value known
to use,
- * then ignore this call. If it is set to 0 we
get a
- * prompt after the server sent it's header.
- */
- size = cachesize == 0 ? DEF_FETCHSIZE :
cachesize;
- size = maxrows != 0 ? Math.min(maxrows, size) :
size;
- // don't do work if it's not needed
- if (lang == LANG_SQL && size != curReplySize &&
templ != commandTempl) {
- sendControlCommand("reply_size " +
size);
+ int size;
+ // {{{ set reply size
+ /**
+ * Change the reply size of the server.
If the given
+ * value is the same as the current
value known to use,
+ * then ignore this call. If it is set
to 0 we get a
+ * prompt after the server sent it's
header.
+ */
+ size = cachesize == 0 ? DEF_FETCHSIZE :
cachesize;
+ size = maxrows != 0 ? Math.min(maxrows,
size) : size;
+ // don't do work if it's not needed
+ if (lang == LANG_SQL && size !=
curReplySize && templ != commandTempl) {
+ sendControlCommand("reply_size
" + size);
- // store the reply size after a
successful change
- curReplySize = size;
- }
- // }}} set reply size
+ // store the reply size after a
successful change
+ curReplySize = size;
+ }
+ // }}} set reply size
- // If the query is larger than the TCP buffer
size, use a
- // special send thread to avoid deadlock with
the server due
- // to blocking behaviour when the buffer is
full. Because
- // the server will be writing back results to
us, it will
- // eventually block as well when its TCP buffer
gets full,
- // as we are blocking an not consuming from it.
The result
- // is a state where both client and server want
to write,
- // but block.
- if (query.length() > MapiSocket.BLOCK) {
- // get a reference to the send thread
- if (sendThread == null) sendThread =
new SendThread(out);
- // tell it to do some work!
- sendThread.runQuery(templ, query);
- sendThreadInUse = true;
- } else {
- // this is a simple call, which is a
lot cheaper and will
- // always succeed for small queries.
- out.writeLine(
- (templ[0] == null ? ""
: templ[0]) +
- query +
- (templ[1] == null ? ""
: templ[1]));
- }
+ // If the query is larger than the TCP
buffer size, use a
+ // special send thread to avoid
deadlock with the server due
+ // to blocking behaviour when the
buffer is full. Because
+ // the server will be writing back
results to us, it will
+ // eventually block as well when its
TCP buffer gets full,
+ // as we are blocking an not consuming
from it. The result
+ // is a state where both client and
server want to write,
+ // but block.
+ if (query.length() > MapiSocket.BLOCK) {
+ // get a reference to the send
thread
+ if (sendThread == null)
sendThread = new SendThread(out);
+ // tell it to do some work!
+ sendThread.runQuery(templ,
query);
+ sendThreadInUse = true;
+ } else {
+ // this is a simple call, which
is a lot cheaper and will
+ // always succeed for small
queries.
+ out.writeLine(
+ (templ[0] ==
null ? "" : templ[0]) +
+ query +
+ (templ[1] ==
null ? "" : templ[1]));
+ }
- // go for new results
- String tmpLine = in.readLine();
- int linetype = in.getLineType();
- Response res = null;
- while (linetype != BufferedMCLReader.PROMPT) {
- // each response should start with a
start of header
- // (or error)
- switch (linetype) {
- case BufferedMCLReader.SOHEADER:
- // make the response
object, and fill it
- try {
- switch
(sohp.parse(tmpLine)) {
- case
StartOfHeaderParser.Q_PARSE:
-
throw new MCLParseException("Q_PARSE header not allowed here", 1);
- case
StartOfHeaderParser.Q_TABLE:
- case
StartOfHeaderParser.Q_PREPARE: {
-
int id = sohp.getNextAsInt();
-
int tuplecount = sohp.getNextAsInt();
-
int columncount = sohp.getNextAsInt();
-
int rowcount = sohp.getNextAsInt();
-
// enforce the maxrows setting
-
if (maxrows != 0 && tuplecount > maxrows)
-
tuplecount = maxrows;
-
res = new ResultSetResponse(
-
id,
-
tuplecount,
-
columncount,
-
rowcount,
-
this,
-
seqnr
-
);
-
// only add this resultset to
-
// the hashmap if it can possibly
-
// have an additional datablock
-
if (rowcount < tuplecount) {
-
if (rsresponses == null)
-
rsresponses = new HashMap();
-
rsresponses.put(
-
new Integer(id),
-
res
+ // go for new results
+ String tmpLine = in.readLine();
+ int linetype = in.getLineType();
+ Response res = null;
+ while (linetype !=
BufferedMCLReader.PROMPT) {
+ // each response should start
with a start of header
+ // (or error)
+ switch (linetype) {
+ case
BufferedMCLReader.SOHEADER:
+ // make the
response object, and fill it
+ try {
+ switch
(sohp.parse(tmpLine)) {
+
case StartOfHeaderParser.Q_PARSE:
+
throw new MCLParseException("Q_PARSE header not allowed here", 1);
+
case StartOfHeaderParser.Q_TABLE:
+
case StartOfHeaderParser.Q_PREPARE: {
+
int id = sohp.getNextAsInt();
+
int tuplecount = sohp.getNextAsInt();
+
int columncount = sohp.getNextAsInt();
+
int rowcount = sohp.getNextAsInt();
+
// enforce the maxrows setting
+
if (maxrows != 0 && tuplecount > maxrows)
+
tuplecount = maxrows;
+
res = new ResultSetResponse(
+
id,
+
tuplecount,
+
columncount,
+
rowcount,
+
this,
+
seqnr
);
-
}
- } break;
- case
StartOfHeaderParser.Q_UPDATE:
-
res = new UpdateResponse(
-
sohp.getNextAsInt(), // count
-
sohp.getNextAsString() // key-id
+
// only add this resultset to
+
// the hashmap if it can possibly
+
// have an additional datablock
+
if (rowcount < tuplecount) {
+
if (rsresponses == null)
+
rsresponses = new HashMap();
+
rsresponses.put(
+
new Integer(id),
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list
