diff --git a/lib/modules/Sql.pmod/tds.pike b/lib/modules/Sql.pmod/tds.pike
index 78d3bc0b1a0551347ec24145a53d2636292c0b9d..2ded473d2906f2c4207f853f61f65c9631248346 100644
--- a/lib/modules/Sql.pmod/tds.pike
+++ b/lib/modules/Sql.pmod/tds.pike
@@ -1,5 +1,5 @@
 /*
- * $Id: tds.pike,v 1.6 2006/02/10 14:45:56 grubba Exp $
+ * $Id: tds.pike,v 1.7 2006/02/10 16:03:52 grubba Exp $
  *
  * A Pike implementation of the TDS protocol.
  *
@@ -175,7 +175,6 @@ static {
 
   string server_data;
   string last_error;
-  array(mapping(string:mixed)) column_info;
 
   void tds_error(string msg, mixed ... args)
   {
@@ -228,6 +227,7 @@ static {
 	if (done) {
 	  TDS_WERROR("Filling buffer on finished packet!\n"
 		     "%s\n", hex_dump(inbuf));
+	  tds_error("Filling buffer on finished packet!\n");
 	}
 
 	string header = socket->read(8);
@@ -257,6 +257,16 @@ static {
 	inpos = 0;
       }
 
+      static void destroy()
+      {
+	// Return the connection to the idle state.
+	while (!done) {
+	  inbuf = "";
+	  inpos = 0;
+	  fill_buf();
+	}
+      }
+
       string get_raw(int bytes)
       {
 	while (inpos + bytes > sizeof(inbuf)) {
@@ -319,9 +329,10 @@ static {
 
       static void create()
       {
-	if (!busy) {
-	  TDS_WERROR("Creating input packet on idle connection!\n");
+	if (busy) {
+	  tds_error("Creating InPacket on busy connection!\n");
 	}
+	busy = 1;
       }
     }
 
@@ -436,30 +447,31 @@ static {
       }
     }
 
-    static void send_packet(Packet p, int flag, int|void last)
+    InPacket send_packet(Packet p, int flag, int|void last)
     {
-      string raw = (string) p;
-
       if (busy) {
-	TDS_WERROR("Sending packet on busy connection!\n");
+	tds_error("Sending packet on busy connection!\n");
       }
-      busy = last;
-
-      // FIXME: Split large packets!
-
-      // NOTE: Network byteorder!!
-      raw =
-	sprintf("%-1c%-1c%2c\0\0%-1c\0%s",
-		flag, last,
-		sizeof(raw) + 8,
-		1,		/* TDS 7 or 8. */
-		(string)raw);
-      TDS_WERROR("Wrapped packet: %O\n%s\n", raw, hex_dump(raw));
-      if (socket->write(raw) != sizeof(raw)) {
-	tds_error("Failed to send packet.\n"
-		  "raw: %O\n", raw);
+
+      string packet = (string) p;
+      foreach(packet/512.0, string raw) {
+	// NOTE: Network byteorder!!
+	raw = sprintf("%1c%1c%2c\0\0%1c\0%s",
+		      flag, last,
+		      sizeof(raw) + 8,
+		      1,		/* TDS 7 or 8. */
+		      raw);
+	TDS_WERROR("Wrapped packet: %O\n%s\n", raw, hex_dump(raw));
+	if (socket->write(raw) != sizeof(raw)) {
+	  socket->close();
+	  socket = 0;
+	  tds_error("Failed to send packet.\n"
+		    "raw: %O\n", raw);
+	}
       }
       //Stdio.write_file("packet.bin", raw);
+      if (last) return InPacket();
+      return 0;
     }
 
     static string crypt_pass(string password)
@@ -515,8 +527,7 @@ static {
       p->put_string("");
       
       TDS_WERROR("Sending login packet.\n");
-      send_packet(p, 0x10, 1);
-      return InPacket();
+      return send_packet(p, 0x10, 1);
     }
 
     string ecb_encrypt(string data, string key)
@@ -860,33 +871,19 @@ static {
       return res;
     }
 
-    static void tds7_process_result(InPacket inp)
+    static array(mapping(string:mixed)) tds7_process_result(InPacket inp)
     {
       int num_cols = inp->get_smallint();
       if (num_cols == 0xffff) {
 	TDS_WERROR("No meta data.\n");
-	column_info = 0;
-	return;
+	return 0;
       }
       TDS_WERROR("%d columns in result.\n", num_cols);
-      column_info = allocate(num_cols);
-      //busy = 1;
-      int offset = 0;
+      array(mapping(string:mixed)) column_info = allocate(num_cols);
       foreach(column_info; int col; ) {
 	column_info[col] = tds7_get_data_info(inp);
-	column_info[col]->column_offset = offset;
-	TDS_WERROR("Offset: 0x%04x\n", offset);
-	if (is_numeric_type(column_info[col]->cardinal_type)) {
-	  offset += 35;		// sizeof(TDS_NUMERIC)
-	} else if (is_blob_type(column_info[col]->cardinal_type)) {
-	  offset += 32;		// sizeof(TDSBLOB)
-	} else {
-	  offset += column_info[col]->column_size;
-	}
-	offset += (~(offset - 1) & 0x3);	// Align.
-	TDS_WERROR("Next offset: 0x%04x\n", offset);
       }
-      
+      return column_info;
     }
 
     static void process_default_tokens(InPacket inp, int token_type)
@@ -904,7 +901,8 @@ static {
 	process_env_chg(inp);
 	return;
       case TDS7_RESULT_TOKEN:
-	tds7_process_result(inp);
+	tds_error("TDS7_RESULT_TOKEN in default handler!\n");
+	//tds7_process_result(inp);
 	break;
       case TDS5_DYNAMIC_TOKEN:
       case TDS_LOGINACK_TOKEN:
@@ -921,11 +919,9 @@ static {
       }
     }
 
-    int process_result_tokens(InPacket inp)
+    array(mapping(string:mixed)) process_result_tokens(InPacket inp)
     {
-      if (!busy) {
-	//return TDS_NO_MORE_RESULTS;
-      }
+      array(mapping(string:mixed)) column_info;
       while (1) {
 	int token_type = inp->peek_byte();
 	TDS_WERROR("Got result token %d\n", token_type);
@@ -933,7 +929,7 @@ static {
 	case TDS7_RESULT_TOKEN:
 	  TDS_WERROR("TDS7_RESULT_TOKEN\n");
 	  inp->get_byte();
-	  tds7_process_result(inp);
+	  column_info = tds7_process_result(inp);
 	  if (inp->peek_byte() == TDS_TABNAME_TOKEN) {
 	    TDS_WERROR("TDS_TABNAME_TOKEN\n");
 	    process_default_tokens(inp, inp->get_byte());
@@ -943,19 +939,20 @@ static {
 	      //process_colinfo();	// FIXME!
 	    }
 	  }
-	  TDS_WERROR("==> TDS_ROWFMT_RESULT\n");
-	  return TDS_ROWFMT_RESULT;
+	  break;
 	case TDS_DONE_TOKEN:
+	  TDS_WERROR("  TDS_DONE_TOKEN pending\n");
+	  return column_info;
 	case TDS_ROW_TOKEN:
-	  TDS_WERROR("==> TDS_ROW_RESULT\n");
-	  return TDS_ROW_RESULT;
+	  TDS_WERROR("  TDS_ROW_TOKEN pending\n");
+	  return column_info;
 	default:
 	  TDS_WERROR("==> FIXME: process_result_tokens\n");
 	  // FALL_THROUGH
 	case TDS_ORDERBY_TOKEN:
+	  /* Ignore. */
 	  inp->get_byte();
 	  process_default_tokens(inp, token_type);
-	  return 0;		/***** FIXME:::::: *****/
 	  break;
 	}
       }
@@ -1162,17 +1159,19 @@ static {
       return raw;
     }
 
-    static array(string|int) process_row(InPacket inp)
+    static array(string|int) process_row(InPacket inp,
+					 array(mapping(string:mixed)) col_info)
     {
-      if (!column_info) return 0;
-      array(string|int) res = allocate(sizeof(column_info));
-      foreach(column_info; int i; mapping(string:mixed) info) {
+      if (!col_info) return 0;
+      array(string|int) res = allocate(sizeof(col_info));
+      foreach(col_info; int i; mapping(string:mixed) info) {
 	res[i] = convert(get_data(inp, info, i), info);
       }
       return res;
     }
 
     array(string|int) process_row_tokens(InPacket inp,
+					 array(mapping(string:mixed)) col_info,
 					 int|void leave_end_token)
     {
       //if (!busy) return 0;	// No more rows.
@@ -1188,7 +1187,7 @@ static {
 	  return 0;
 	case TDS_ROW_TOKEN:
 	  inp->get_byte();
-	  return process_row(inp);
+	  return process_row(inp, col_info);
 	  break;
 	case TDS_DONE_TOKEN:
 	case TDS_DONEPROC_TOKEN:
@@ -1264,8 +1263,7 @@ static {
       if (!query->n_param || !params || !sizeof(params)) {
 	string raw = query->splitted_query*"?";
 	p->put_raw(raw, sizeof(raw));
-	send_packet(p, 0x01, 1);
-	return InPacket();
+	return send_packet(p, 0x01, 1);
       } else {
 	tds_error("parametrized queries not supported yet.\n");
       }
@@ -1326,38 +1324,6 @@ static {
     con = Connection(server, port, database, uid, password);
   }
 
-  Connection.InPacket Execute(compile_query query)
-  {
-    query->parse_prepared_query();
-    if (busy) {
-      tds_error("Connection not idle.\n");
-    }
-    Connection.InPacket res;
-    if (!query->params) {
-      res = con->submit_query(query);
-    } else {
-      res = con->submit_execdirect(query, query->params);
-    }
-    int done = 0;
-    int res_type;
-    while (!done) {
-      res_type = con->process_result_tokens(res);
-      switch(res_type) {
-      case TDS_COMPUTE_RESULT:
-      case TDS_ROW_RESULT:
-	done = 1;
-	break;
-      default:
-	TDS_WERROR("res_type: %d\n", res_type);
-	break;
-      }
-    }
-    // populate_ird
-    switch(res_type) {
-      //case TDS_NO_MORE_RESULTS:
-    }
-    return res;
-  }
 #if (__REAL_MAJOR__ > 7) || ((__REAL_MAJOR__ == 7) && (__REAL_MINOR__ >= 6))
 };
 #endif /* Pike 7.6 or later */
@@ -1444,12 +1410,14 @@ class big_query
   static int eot;
 
   static Connection.InPacket result_packet;
+  static array(mapping(string:mixed)) column_info;
 
   int|array(string|int) fetch_row()
   {
     if (eot) return 0;
     TDS_WERROR("fetch_row()::::::::::::::::::::::::::::::::::::::::::\n");
-    int|array(string|int) res = con->process_row_tokens(result_packet);
+    int|array(string|int) res = con->process_row_tokens(result_packet,
+							column_info);
     eot = !res;
     row_no++;
     return res;
@@ -1458,7 +1426,7 @@ class big_query
   array(mapping(string:mixed)) fetch_fields()
   {
     TDS_WERROR("fetch_fields()::::::::::::::::::::::::::::::::::::::::::\n");
-    return copy_value(column_info || ({}));
+    return copy_value(column_info);
   }
 
   static void create(string|compile_query query)
@@ -1466,7 +1434,18 @@ class big_query
     if (stringp(query)) {
       query = compile_query(query);
     }
-    result_packet = Execute(query);
+
+    query->parse_prepared_query();
+    if (busy) {
+      tds_error("Connection not idle.\n");
+    }
+    if (!query->params) {
+      result_packet = con->submit_query(query);
+    } else {
+      result_packet = con->submit_execdirect(query, query->params);
+    }
+    column_info = con->process_result_tokens(result_packet);
+    if (!column_info) destruct();
   }
 }