cretz / node-tds

Pure JS implementation of TDS protocol for Microsoft SQL Server
http://cretz.github.com/node-tds
MIT License
104 stars 23 forks source link

Result set too big will cause program to hang #32

Open yeeen opened 11 years ago

yeeen commented 11 years ago

I realise if my results return have too much rows, eg 30, the program will hang. When I stepped into the node-tds code, I realised it was cos it hit an error in the method _handleToken() of tds-client.js. The error was StreamIndexOutOfBoundsError. When I stepped further inside, I found that the error came from assertBytesAvailable() of buffer-stream.js. A guess is that the buffer set is not big enough, but I can't understand how the buffer size is set in order to change it.

This is probably the same problem I encountered last time hvg my declared datatype to of max size, I 'fixed' this by setting a feasible size for my datatype. But I can't control my results set, I can hv a lot of results!

I think this is a problem with tds-client, is there any fixes for this bug??

tdarsan commented 11 years ago

This most likely is because of varchar columns. I had the same issue but I noticed that it only happens if varchar columns are present in the select statement. If for example all the columns are int then it did not throw the exception for the same number of rows and columns.

kalifg commented 11 years ago

I have a very long node-tds debug log for a query that hangs at the exact same place every time. The last part of the log reads:

From 0 to 28 offset, remaining:  2
Checking token type:  209
Retrieved token type:  209
Stream incomplete, rolling back

When at the end of completing query it would have:

From 0 to 37 offset, remaining:  68
Checking token type:  209
Retrieved token type:  209
Retrieved token:  { type: 209,
  name: 'ROW',
  handlerFunction: 'row',
  _context: 
   { _handler: 
      { error: [Function],
        message: [Function],
        connect: [Function],
        login: [Function],
        row: [Function],
        colmetadata: [Function],
        done: [Function],
        end: [Function],
        close: [Function] },
     _socketClose: [Function],
     _socketEnd: [Function],
     _socketData: [Function],
     _socketError: [Function],
     _socketConnect: [Function],
     logError: true,
     logDebug: true,
     state: 4,
     _debugFd: 16,
     _preLoginConfig: 
      { appName: '********',
        host: '********',
        port: 1433,
        userName: '********',
        password: '********',
        database: 'MED_902',
        logDebug: true,
        logError: true },
     _socket: 
      { domain: null,
        _events: [Object],
        _maxListeners: 10,
        _handle: [Object],
        _pendingWriteReqs: 0,
        _flags: 0,
        _connectQueueSize: 0,
        destroyed: false,
        errorEmitted: false,
        bytesRead: 2154,
        _bytesDispatched: 2161,
        allowHalfOpen: undefined,
        _connecting: false,
        writable: true,
        readable: true },
     _stream: 
      { _offset: 45,
        _buffer: <Buffer d1 26 00 49 6e 74 65 72 64 69 73 63 69 70 6c 69 6e 61 72 79 20 45 6e 67 69 6e 65 65 72 69 6e 67 20 50 72 6f 67 72 61 6d 20 69 1a 00 00 ff 11 00 c1 00 8c ...>,
        _offsetStart: 0 },
     tdsVersion: 1895825409,
     _tokenStream: { type: 4, name: 'TokenStream' },
     _tokenStreamRemainingLength: 68,
     _pendingTokenStreamBuffer: null,
     _cancelling: undefined,
     colmetadata: 
      { type: 129,
        name: 'COLMETADATA',
        handlerFunction: 'colmetadata',
        columns: [Object],
        columnsByName: [Object] } },
  metadata: 
   { type: 129,
     name: 'COLMETADATA',
     handlerFunction: 'colmetadata',
     columns: [ [Object], [Object] ],
     columnsByName: { department: [Object], department_id: [Object] } },
  values: 
   [ { length: 38,
       buffer: <Buffer 49 6e 74 65 72 64 69 73 63 69 70 6c 69 6e 61 72 79 20 45 6e 67 69 6e 65 65 72 69 6e 67 20 50 72 6f 67 72 61 6d 20> },
     { length: 4, buffer: <Buffer 69 1a 00 00> } ] }
From 0 to 45 offset, remaining:  23
Checking token type:  209
Retrieved token type:  255
Retrieved token:  { type: 253,
  name: 'DONE',
  handlerFunction: 'done',
  hasMore: [Getter],
  isError: [Getter],
  hasRowCount: [Getter],
  isCanceled: [Getter],
  isCancelled: [Getter],
  isFatal: [Getter],
  status: 17,
  currentCommand: 193,
  rowCount: 396 }
From 0 to 9 offset, remaining:  14
Checking token type:  253
Retrieved token type:  121
Retrieved token:  { type: 121,
  name: 'RETURNSTATUS',
  handlerFunction: 'returnstatus',
  value: 0 }
From 0 to 5 offset, remaining:  9
Checking token type:  121
Retrieved token type:  254
Retrieved token:  { type: 253,
  name: 'DONE',
  handlerFunction: 'done',
  hasMore: [Getter],
  isError: [Getter],
  hasRowCount: [Getter],
  isCanceled: [Getter],
  isCancelled: [Getter],
  isFatal: [Getter],
  status: 0,
  currentCommand: 224,
  rowCount: 0 }

I will make a copy of the data and the log for when you have time to get back to this.