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

Reply via email to