Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,12 @@ jobs:
run: npm run test-tedious
- name: Run cli tests
run: npm run test-cli
# The msnodesqlv8 tests fail with a segmentation fault
- name: Install tedious 20
if: ${{ matrix.node == '22.x' || matrix.node == '24.x' }}
run: npm install --no-save tedious@^20.0.0
- name: Run tedious 20 tests
if: ${{ matrix.node == '22.x' || matrix.node == '24.x' }}
run: npm run test-tedious
# - name: Install OBDC 17 driver
# run: |
# sudo curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
Expand Down Expand Up @@ -145,6 +150,12 @@ jobs:
run: npm run test-tedious
- name: Run cli tests
run: npm run test-cli
- name: Install tedious 20
if: ${{ matrix.node == '22.x' || matrix.node == '24.x' }}
run: npm install --no-save tedious@^20.0.0
- name: Run tedious 20 tests
if: ${{ matrix.node == '22.x' || matrix.node == '24.x' }}
run: npm run test-tedious
# msnodesqlv8 is exercised across its supported major versions. Each major
# is gated to the Node versions it ships prebuilt win32-x64 binaries for —
# a combo without a prebuild falls back to a node-gyp source build, which is
Expand Down
18 changes: 1 addition & 17 deletions lib/tedious/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,6 @@ const N_TYPES = {
NumericN: 0x6C
}

// Workaround for tedious TVP declaration not including schema name.
// See: https://github.com/tediousjs/node-mssql/issues/1759
const SchemaAwareTVP = Object.create(tds.TYPES.TVP, {
declaration: {
value: function (parameter) {
const value = parameter.value
if (value && value.schema) {
return value.schema + '.' + value.name + ' readonly'
}
return value.name + ' readonly'
},
writable: true,
configurable: true
}
})

const getTediousType = function (type) {
switch (type) {
case TYPES.VarChar: return tds.TYPES.VarChar
Expand Down Expand Up @@ -70,7 +54,7 @@ const getTediousType = function (type) {
case TYPES.Binary: return tds.TYPES.Binary
case TYPES.VarBinary: return tds.TYPES.VarBinary
case TYPES.UDT: case TYPES.Geography: case TYPES.Geometry: return tds.TYPES.UDT
case TYPES.TVP: return SchemaAwareTVP
case TYPES.TVP: return tds.TYPES.TVP
case TYPES.Variant: return tds.TYPES.Variant
default: return type
}
Expand Down
32 changes: 17 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"commander": "^11.0.0",
"debug": "^4.3.3",
"tarn": "^3.0.2",
"tedious": "^19.0.0"
"tedious": "^19.2.2 || ^20.0.0"
},
"devDependencies": {
"@commitlint/cli": "^20.0.0",
Expand Down
85 changes: 4 additions & 81 deletions test/common/unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -1088,27 +1088,7 @@ describe('connection string auth - tedious', () => {
describe('TVP declaration with schema', () => {
const tds = require('tedious')

it('documents upstream tedious bug: schema missing from TVP declaration', () => {
const tvp = new sql.Table('AI.UDT_StringArray')
tvp.columns.add('Name', sql.NVarChar(128), { nullable: false })
tvp.rows.add('TestValue1')

const tvpValue = {
name: tvp.name,
schema: tvp.schema,
columns: [],
rows: tvp.rows
}

// tedious's own TVP type does NOT include schema in declaration
const req = new tds.Request('SELECT 1')
req.addParameter('InputList', tds.TYPES.TVP, tvpValue)
const paramsStr = req.makeParamsParameter(req.parameters)
assert.strictEqual(paramsStr, '@InputList UDT_StringArray readonly',
'tedious itself does not include schema - this documents the upstream bug')
})

it('schema-aware TVP type includes schema in declaration', () => {
it('tedious includes schema in TVP declaration', () => {
const tvp = new sql.Table('AI.UDT_StringArray')
tvp.columns.add('Name', sql.NVarChar(128), { nullable: false })
tvp.rows.add('TestValue1')
Expand All @@ -1123,29 +1103,13 @@ describe('connection string auth - tedious', () => {
assert.strictEqual(tvp.name, 'UDT_StringArray')
assert.strictEqual(tvp.schema, 'AI')

// Use the patched SchemaAwareTVP type from lib/tedious/request.js
// Since it's not exported, recreate the same pattern to verify behavior
const SchemaAwareTVP = Object.create(tds.TYPES.TVP, {
declaration: {
value: function (parameter) {
const value = parameter.value
if (value && value.schema) {
return value.schema + '.' + value.name + ' readonly'
}
return value.name + ' readonly'
},
writable: true,
configurable: true
}
})

const req = new tds.Request('SELECT 1')
req.addParameter('InputList', SchemaAwareTVP, tvpValue)
req.addParameter('InputList', tds.TYPES.TVP, tvpValue)
const paramsStr = req.makeParamsParameter(req.parameters)
assert.strictEqual(paramsStr, '@InputList AI.UDT_StringArray readonly')
})

it('schema-aware TVP works without schema', () => {
it('tedious TVP works without schema', () => {
const tvp = new sql.Table('UDT_StringArray')
tvp.columns.add('Name', sql.NVarChar(128), { nullable: false })

Expand All @@ -1159,52 +1123,11 @@ describe('connection string auth - tedious', () => {
assert.strictEqual(tvp.name, 'UDT_StringArray')
assert.strictEqual(tvp.schema, null)

const SchemaAwareTVP = Object.create(tds.TYPES.TVP, {
declaration: {
value: function (parameter) {
const value = parameter.value
if (value && value.schema) {
return value.schema + '.' + value.name + ' readonly'
}
return value.name + ' readonly'
},
writable: true,
configurable: true
}
})

const req = new tds.Request('SELECT 1')
req.addParameter('InputList', SchemaAwareTVP, tvpValue)
req.addParameter('InputList', tds.TYPES.TVP, tvpValue)
const paramsStr = req.makeParamsParameter(req.parameters)
assert.strictEqual(paramsStr, '@InputList UDT_StringArray readonly')
})

it('schema-aware TVP inherits generateTypeInfo from tedious TVP', () => {
const SchemaAwareTVP = Object.create(tds.TYPES.TVP, {
declaration: {
value: function (parameter) {
const value = parameter.value
if (value && value.schema) {
return value.schema + '.' + value.name + ' readonly'
}
return value.name + ' readonly'
},
writable: true,
configurable: true
}
})

// Verify it inherits all other methods from tedious TVP
assert.strictEqual(SchemaAwareTVP.id, tds.TYPES.TVP.id)
assert.strictEqual(SchemaAwareTVP.type, tds.TYPES.TVP.type)
assert.strictEqual(SchemaAwareTVP.name, tds.TYPES.TVP.name)
assert.strictEqual(SchemaAwareTVP.generateTypeInfo, tds.TYPES.TVP.generateTypeInfo)
assert.strictEqual(SchemaAwareTVP.generateParameterLength, tds.TYPES.TVP.generateParameterLength)
assert.strictEqual(SchemaAwareTVP.generateParameterData, tds.TYPES.TVP.generateParameterData)
assert.strictEqual(SchemaAwareTVP.validate, tds.TYPES.TVP.validate)
// declaration is overridden
assert.notStrictEqual(SchemaAwareTVP.declaration, tds.TYPES.TVP.declaration)
})
})

describe('msnodesqlv8 TVP declaration', () => {
Expand Down