Permalink
Browse files

Add support for real and float data types in result rows.

Issue #5.
  • Loading branch information...
pekim committed Jan 2, 2012
1 parent 4c39c76 commit 231f80e2aad0ff942db950e46853fb3866b6f0d5
View
@@ -1,8 +1,10 @@
TYPE =
- # Fixed-length types
+ # Zero-length types
0x1F:
type: 'NULL'
name: 'Null'
+
+ # Fixed-length types
0x30:
type: 'INT1'
name: 'TinyInt'
@@ -47,17 +49,21 @@ TYPE =
name: 'BitN'
dataLengthLength: 1
0x6A:
- type: 'DECIMALNTYPE'
+ type: 'DECIMALN'
name: 'DecimalN'
dataLengthLength: 1
hasPrecision: true
hasScale: true
0x6C:
- type: 'NUMERICNTYPE'
+ type: 'NUMERICN'
name: 'NumericN'
dataLengthLength: 1
hasPrecision: true
hasScale: true
+ 0x6D:
+ type: 'FLTN'
+ name: 'FloatN'
+ dataLengthLength: 1
0x6F:
type: 'DATETIMN'
name: 'DateTimeN'
@@ -101,7 +107,6 @@ TYPE =
GUIDTYPE: 0x24 # UniqueIdentifier
DECIMALTYPE: 0x37 # Decimal (legacy support)
NUMERICTYPE: 0x3F # Numeric (legacy support)
- FLTNTYPE: 0x6D # (see below)
MONEYNTYPE: 0x6E # (see below)
DATENTYPE: 0x28 # (introduced in TDS 7.3)
TIMENTYPE: 0x29 # (introduced in TDS 7.3)
@@ -65,6 +65,22 @@ parser = (buffer, columnsMetaData) ->
value = buffer.readInt32LE()
when 8
value = buffer.readAsStringInt64LE()
+ else
+ throw new Error("Unsupported dataLength #{dataLength} for IntN")
+ when 'Real'
+ value = buffer.readFloatLE()
+ when 'Float'
+ value = buffer.readDoubleLE()
+ when 'FloatN'
+ switch dataLength
+ when 0
+ isNull = true
+ when 4
+ value = buffer.readFloatLE()
+ when 8
+ value = buffer.readDoubleLE()
+ else
+ throw new Error("Unsupported dataLength #{dataLength} for FloatN")
when 'Bit'
value = !!buffer.readUInt8()
when 'BitN'
@@ -123,7 +139,7 @@ parser = (buffer, columnsMetaData) ->
value *= sign
value /= Math.pow(10, columnMetaData.scale)
else
- throw new Error(sprintf('Unrecognised column type %s at offset 0x%04X', type.name, (buffer.position - 1)))
+ throw new Error(sprintf('Unrecognised column type %s at offset 0x%04X', type.name, buffer.position))
break
columns.push(
@@ -95,6 +95,18 @@ class ReadableTrackingBuffer
@position += length
@buffer.readInt32BE(@position - length)
+ readFloatLE: ->
+ length = 4
+ @assertEnoughLeftFor(length)
+ @position += length
+ @buffer.readFloatLE(@position - length)
+
+ readDoubleLE: ->
+ length = 8
+ @assertEnoughLeftFor(length)
+ @position += length
+ @buffer.readDoubleLE(@position - length)
+
# If value > 53 bits then it will be incorrect (because Javascript uses IEEE_754 for number representation).
readUInt64LE: ->
low = @readUInt32LE()
@@ -29,6 +29,18 @@ exports.int = (test) ->
exports.intNull = (test) ->
execSql(test, 'select cast(null as int)', null)
+exports.real = (test) ->
+ execSql(test, 'select cast(9.5 as real)', 9.5)
+
+exports.realNull = (test) ->
+ execSql(test, 'select cast(null as real)', null)
+
+exports.float = (test) ->
+ execSql(test, 'select cast(9.5 as float)', 9.5)
+
+exports.floatNull = (test) ->
+ execSql(test, 'select cast(null as float)', null)
+
exports.bigint = (test) ->
execSql(test, 'select cast(8 as bigint)', '8')
@@ -3,14 +3,46 @@ dataTypeByName = require('../../../lib/token/data-type').typeByName
ReadableTrackingBuffer = require('../../../lib/tracking-buffer/tracking-buffer').ReadableTrackingBuffer
WritableTrackingBuffer = require('../../../lib/tracking-buffer/tracking-buffer').WritableTrackingBuffer
+module.exports.null = (test) ->
+ colMetaData = [type: dataTypeByName.Null]
+
+ buffer = new WritableTrackingBuffer(0, 'ucs2')
+
+ token = parser(new ReadableTrackingBuffer(buffer.data, 'ucs2'), colMetaData)
+ #console.log(token)
+
+ test.strictEqual(token.columns.length, 1)
+ test.ok(token.columns[0].isNull)
+ test.ok(!token.columns[0].value)
+ test.strictEqual(token.columns[0].metadata, colMetaData[0])
+
+ test.done()
+
+module.exports.int = (test) ->
+ colMetaData = [type: dataTypeByName.Int]
+ value = 3
+
+ buffer = new WritableTrackingBuffer(0, 'ucs2')
+ buffer.writeUInt32LE(value)
+
+ token = parser(new ReadableTrackingBuffer(buffer.data, 'ucs2'), colMetaData)
+ #console.log(token)
+
+ test.strictEqual(token.columns.length, 1)
+ test.ok(!token.columns[0].isNull)
+ test.strictEqual(token.columns[0].value, value)
+ test.strictEqual(token.columns[0].metadata, colMetaData[0])
+
+ test.done()
+
module.exports.bigint = (test) ->
colMetaData = [{type: dataTypeByName.BigInt},
- {type: dataTypeByName.BigInt}]
+ {type: dataTypeByName.BigInt}]
buffer = new WritableTrackingBuffer(0, 'ucs2')
buffer.writeBuffer(new Buffer([
- 1,0,0,0,0,0,0,0,
- 255,255,255,255,255,255,255,127]))
+ 1,0,0,0,0,0,0,0,
+ 255,255,255,255,255,255,255,127]))
token = parser(new ReadableTrackingBuffer(buffer.data, 'ucs2'), colMetaData)
@@ -20,28 +52,29 @@ module.exports.bigint = (test) ->
test.done()
-
-module.exports.null = (test) ->
- colMetaData = [type: dataTypeByName.Null]
+module.exports.real = (test) ->
+ colMetaData = [type: dataTypeByName.Real]
+ value = 9.5
buffer = new WritableTrackingBuffer(0, 'ucs2')
+ buffer.writeBuffer(new Buffer([0x00, 0x00, 0x18, 0x41]))
token = parser(new ReadableTrackingBuffer(buffer.data, 'ucs2'), colMetaData)
#console.log(token)
test.strictEqual(token.columns.length, 1)
- test.ok(token.columns[0].isNull)
- test.ok(!token.columns[0].value)
+ test.ok(!token.columns[0].isNull)
+ test.strictEqual(token.columns[0].value, value)
test.strictEqual(token.columns[0].metadata, colMetaData[0])
test.done()
-module.exports.int = (test) ->
- colMetaData = [type: dataTypeByName.Int]
- value = 3
+module.exports.float = (test) ->
+ colMetaData = [type: dataTypeByName.Float]
+ value = 9.5
buffer = new WritableTrackingBuffer(0, 'ucs2')
- buffer.writeUInt32LE(value)
+ buffer.writeBuffer(new Buffer([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x40]))
token = parser(new ReadableTrackingBuffer(buffer.data, 'ucs2'), colMetaData)
#console.log(token)
@@ -269,33 +302,35 @@ module.exports.varBinaryMaxUnknownLength = (test) ->
test.done()
module.exports.intN = (test) ->
- colMetaData = [{type: dataTypeByName.IntN},
- {type: dataTypeByName.IntN},
- {type: dataTypeByName.IntN},
- {type: dataTypeByName.IntN},
- {type: dataTypeByName.IntN},
- {type: dataTypeByName.IntN},
- {type: dataTypeByName.IntN},
- {type: dataTypeByName.IntN},
- {type: dataTypeByName.IntN},
- {type: dataTypeByName.IntN},
- {type: dataTypeByName.IntN},
- {type: dataTypeByName.IntN}]
+ colMetaData = [
+ {type: dataTypeByName.IntN}
+ {type: dataTypeByName.IntN}
+ {type: dataTypeByName.IntN}
+ {type: dataTypeByName.IntN}
+ {type: dataTypeByName.IntN}
+ {type: dataTypeByName.IntN}
+ {type: dataTypeByName.IntN}
+ {type: dataTypeByName.IntN}
+ {type: dataTypeByName.IntN}
+ {type: dataTypeByName.IntN}
+ {type: dataTypeByName.IntN}
+ {type: dataTypeByName.IntN}
+ ]
buffer = new WritableTrackingBuffer(0, 'ucs2')
buffer.writeBuffer(new Buffer([
- 0,
- 8, 0,0,0,0,0,0,0,0,
- 8, 1,0,0,0,0,0,0,0,
- 8, 255,255,255,255,255,255,255,255,
- 8, 2,0,0,0,0,0,0,0,
- 8, 254,255,255,255,255,255,255,255,
- 8, 255,255,255,255,255,255,255,127,
- 8, 0,0,0,0,0,0,0,128,
- 8, 10,0,0,0,0,0,0,0,
- 8, 100,0,0,0,0,0,0,0,
- 8, 232,3,0,0,0,0,0,0,
- 8, 16,39,0,0,0,0,0,0]))
+ 0,
+ 8, 0,0,0,0,0,0,0,0,
+ 8, 1,0,0,0,0,0,0,0,
+ 8, 255,255,255,255,255,255,255,255,
+ 8, 2,0,0,0,0,0,0,0,
+ 8, 254,255,255,255,255,255,255,255,
+ 8, 255,255,255,255,255,255,255,127,
+ 8, 0,0,0,0,0,0,0,128,
+ 8, 10,0,0,0,0,0,0,0,
+ 8, 100,0,0,0,0,0,0,0,
+ 8, 232,3,0,0,0,0,0,0,
+ 8, 16,39,0,0,0,0,0,0]))
#console.log(buffer.data)
token = parser(new ReadableTrackingBuffer(buffer.data, 'ucs2'), colMetaData)
@@ -318,6 +353,32 @@ module.exports.intN = (test) ->
test.done()
+module.exports.floatN = (test) ->
+ colMetaData = [
+ {type: dataTypeByName.FloatN}
+ {type: dataTypeByName.FloatN}
+ {type: dataTypeByName.FloatN}
+ ]
+
+ buffer = new WritableTrackingBuffer(0, 'ucs2')
+ buffer.writeBuffer(new Buffer([
+ 0,
+ 4, 0x00, 0x00, 0x18, 0x41,
+ 8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x40
+ ]))
+ #console.log(buffer.data)
+
+ token = parser(new ReadableTrackingBuffer(buffer.data, 'ucs2'), colMetaData)
+ #console.log(token)
+
+ test.strictEqual(token.columns.length, 3)
+ test.ok(!token.columns[0].value)
+ test.ok(token.columns[0].isNull)
+ test.strictEqual(9.5, token.columns[1].value)
+ test.strictEqual(9.5, token.columns[2].value)
+
+ test.done()
+
module.exports.datetime = (test) ->
colMetaData = [type: dataTypeByName.DateTime]

0 comments on commit 231f80e

Please sign in to comment.