Skip to content

Commit cbe0f53

Browse files
authored
v2.0.4 - Fixing issue with incorrect query results when querying only some columns of a primary key table (#154)
* Fixed issue with Invoke-SqlQuery not returning all data when querying a portion of a primary key table in either MySql or SQLite. * Fix issue with -Stream where it didn't handle results with duplicate column names
1 parent 7b9dabe commit cbe0f53

8 files changed

Lines changed: 173 additions & 7 deletions

File tree

ModuleManifest/SimplySql.psd1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#
44
# Generated by: Mithrandyr
55
#
6-
# Generated on: 5/11/2024
6+
# Generated on: 6/14/2024
77
#
88

99
@{
@@ -12,7 +12,7 @@
1212
RootModule = 'SimplySql.Cmdlets.dll'
1313

1414
# Version number of this module.
15-
ModuleVersion = '2.0.3.73'
15+
ModuleVersion = '2.0.4.75'
1616

1717
# Supported PSEditions
1818
# CompatiblePSEditions = @()

Tests/mssql.tests.ps1

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,32 @@ Describe "MSSQL" {
8080
Select-Object -ExpandProperty Count |
8181
Should -Be 1000
8282
}
83+
84+
It "Invoke-SqlQuery (with Primary Key)" {
85+
Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2));" | Out-Null
86+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1" | Out-Null
87+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2" | Out-Null
88+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3" | Out-Null
89+
90+
Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" |
91+
Measure-Object |
92+
Select-Object -ExpandProperty Count |
93+
Should -Be 3
94+
}
95+
96+
It "Invoke-SqlQuery (multiple columns of same name)" {
97+
$val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a"
98+
$val.a | Should -Be 1
99+
$val.a1 | Should -Be 2
100+
$val.a2 | Should -Be 3
101+
}
102+
103+
It "Invoke-SqlQuery (multiple columns of same name) -stream" {
104+
$val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" -Stream
105+
$val.a | Should -Be 1
106+
$val.a1 | Should -Be 2
107+
$val.a2 | Should -Be 3
108+
}
83109

84110
It "Invoke-SqlQuery -stream" {
85111
Invoke-SqlQuery -Query "SELECT TOP 1000 * FROM tmpTable" -Stream |

Tests/mysql.tests.ps1

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Describe "MySql" {
3030
DROP TABLE IF EXISTS $db.tmpTable;
3131
DROP TABLE IF EXISTS $db.tmpTable2;
3232
DROP TABLE IF EXISTS $db.tmpTable3;
33+
DROP TABLE IF EXISTS $db.tmpPK;
3334
DROP VIEW IF EXISTS $db.generator_64k;
3435
DROP VIEW IF EXISTS $db.generator_256;
3536
DROP VIEW IF EXISTS $db.generator_16;"
@@ -86,6 +87,32 @@ Describe "MySql" {
8687
Should -Be 1000
8788
}
8889

90+
It "Invoke-SqlQuery (with Primary Key)" {
91+
Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2));" | Out-Null
92+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1" | Out-Null
93+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2" | Out-Null
94+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3" | Out-Null
95+
96+
Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" |
97+
Measure-Object |
98+
Select-Object -ExpandProperty Count |
99+
Should -Be 3
100+
}
101+
102+
It "Invoke-SqlQuery (multiple columns of same name)" {
103+
$val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a"
104+
$val.a | Should -Be 1
105+
$val.a1 | Should -Be 2
106+
$val.a2 | Should -Be 3
107+
}
108+
109+
It "Invoke-SqlQuery (multiple columns of same name) -stream" {
110+
$val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" -Stream
111+
$val.a | Should -Be 1
112+
$val.a1 | Should -Be 2
113+
$val.a2 | Should -Be 3
114+
}
115+
89116
It "Invoke-SqlQuery -stream" {
90117
Invoke-SqlQuery -Query "
91118
SELECT rand() AS colDec

Tests/oracle.tests.ps1

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Describe "Oracle" {
99
AfterEach { Show-SqlConnection -all | Close-SqlConnection }
1010
AfterAll {
1111
Open-OracleConnection -DataSource $srvName -ServiceName xe -Credential $c
12-
foreach($tbl in @("transactionTest", "tmpTable", "tmpTable2","t")) {
12+
foreach($tbl in @("transactionTest", "tmpTable", "tmpTable2","t", "tmpPK")) {
1313
$query = "BEGIN
1414
EXECUTE IMMEDIATE 'DROP TABLE $tbl';
1515
EXCEPTION
@@ -79,6 +79,32 @@ Describe "Oracle" {
7979
Should -Be 1000
8080
}
8181

82+
It "Invoke-SqlQuery (with Primary Key)" {
83+
Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2))" | Out-Null
84+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1 FROM dual" | Out-Null
85+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2 FROM dual" | Out-Null
86+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3 FROM dual" | Out-Null
87+
88+
Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" |
89+
Measure-Object |
90+
Select-Object -ExpandProperty Count |
91+
Should -Be 3
92+
}
93+
94+
It "Invoke-SqlQuery (multiple columns of same name)" {
95+
$val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a FROM dual"
96+
$val.a | Should -Be 1
97+
$val.a1 | Should -Be 2
98+
$val.a2 | Should -Be 3
99+
}
100+
101+
It "Invoke-SqlQuery (multiple columns of same name) -stream" {
102+
$val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a FROM dual" -Stream
103+
$val.a | Should -Be 1
104+
$val.a1 | Should -Be 2
105+
$val.a2 | Should -Be 3
106+
}
107+
82108
It "Invoke-SqlQuery -stream" {
83109
Invoke-SqlQuery -Stream -Query "SELECT dbms_random.random /1000000000000. AS colDec
84110
, dbms_random.random AS colInt

Tests/postgre.tests.ps1

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Describe "PostGre" {
1313
}
1414
AfterAll {
1515
Open-PostGreConnection -Server $srvName -Database $db -Credential $c
16-
Invoke-SqlUpdate "DROP TABLE IF EXISTS transactionTest, tmpTable, tmpTable2, t;"
16+
Invoke-SqlUpdate "DROP TABLE IF EXISTS transactionTest, tmpTable, tmpTable2, t, tmpPK;"
1717
Close-SqlConnection
1818
}
1919

@@ -65,6 +65,32 @@ Describe "PostGre" {
6565
Should -Be 1000
6666
}
6767

68+
It "Invoke-SqlQuery (with Primary Key)" {
69+
Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2));" | Out-Null
70+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1" | Out-Null
71+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2" | Out-Null
72+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3" | Out-Null
73+
74+
Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" |
75+
Measure-Object |
76+
Select-Object -ExpandProperty Count |
77+
Should -Be 3
78+
}
79+
80+
It "Invoke-SqlQuery (multiple columns of same name)" {
81+
$val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a"
82+
$val.a | Should -Be 1
83+
$val.a1 | Should -Be 2
84+
$val.a2 | Should -Be 3
85+
}
86+
87+
It "Invoke-SqlQuery (multiple columns of same name) -stream" {
88+
$val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" -Stream
89+
$val.a | Should -Be 1
90+
$val.a1 | Should -Be 2
91+
$val.a2 | Should -Be 3
92+
}
93+
6894
It "Invoke-SqlQuery -stream" {
6995
Invoke-SqlQuery -Query "SELECT * FROM tmpTable LIMIT 1000" -Stream |
7096
Measure-Object |

Tests/sqlite.tests.ps1

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,32 @@ Describe "SQLite" {
5757
Select-Object -ExpandProperty Count |
5858
Should -Be 1000
5959
}
60+
61+
It "Invoke-SqlQuery (with Primary Key)" {
62+
Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2));" | Out-Null
63+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1" | Out-Null
64+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2" | Out-Null
65+
Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3" | Out-Null
66+
67+
Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" |
68+
Measure-Object |
69+
Select-Object -ExpandProperty Count |
70+
Should -Be 3
71+
}
72+
73+
It "Invoke-SqlQuery (multiple columns of same name)" {
74+
$val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a"
75+
$val.a | Should -Be 1
76+
$val.a1 | Should -Be 2
77+
$val.a2 | Should -Be 3
78+
}
79+
80+
It "Invoke-SqlQuery (multiple columns of same name) -stream" {
81+
$val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" -Stream
82+
$val.a | Should -Be 1
83+
$val.a1 | Should -Be 2
84+
$val.a2 | Should -Be 3
85+
}
6086

6187
It "Invoke-SqlQuery -stream" {
6288
Invoke-SqlQuery -Query "WITH a(n) AS (SELECT 1 UNION ALL SELECT 1)

source/SimplySql.Cmdlets/DataReaderToPSObject.vb

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ Public Class DataReaderToPSObject
88
Dim columns = map.CreateMappings(theDataReader)
99
While theDataReader.Read
1010
Dim pso As New PSObject
11-
11+
Dim nameList As New Dictionary(Of String, Integer)
1212
For Each col In columns
13+
14+
15+
16+
1317
If theDataReader.IsDBNull(col.Ordinal) Then
1418
pso.Properties.Add(New PSNoteProperty(col.Name, Nothing), True)
1519
Else
@@ -62,7 +66,18 @@ Public Class DataReaderToPSObject
6266
Public Name As String
6367
Public Type As String
6468
Shared Function CreateMappings(dr As IDataReader) As Generic.List(Of map)
65-
Return Linq.Enumerable.Range(0, dr.FieldCount).Select(Function(ord) New map With {.Ordinal = ord, .Name = dr.GetName(ord), .Type = dr.GetFieldType(ord).ToString}).ToList
69+
Dim nameList As New Dictionary(Of String, Integer)
70+
Return Linq.Enumerable.Range(0, dr.FieldCount).Select(Function(ord)
71+
Dim n As String = dr.GetName(ord)
72+
Dim ni As Integer
73+
If nameList.TryGetValue(n, ni) Then
74+
nameList(n) += 1
75+
n += ni.ToString
76+
Else
77+
nameList.Add(n, 1)
78+
End If
79+
Return New map With {.Ordinal = ord, .Name = n, .Type = dr.GetFieldType(ord).ToString}
80+
End Function).ToList
6681
End Function
6782

6883
Shared Function CreateFunction(dr As IDataReader) As Func(Of IDataRecord, PSObject)

source/SimplySql.Engine/ProviderBase.vb

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,27 @@ Public MustInherit Class ProviderBase
9999
Using dr As IDataReader = cmd.ExecuteReader
100100
Do
101101
Dim dt As New DataTable
102-
dt.Load(dr)
102+
Dim nameList As New Dictionary(Of String, Integer)
103+
For i As Integer = 0 To dr.FieldCount - 1
104+
Dim n As String = dr.GetName(i)
105+
Dim ni As Integer = 0
106+
If nameList.TryGetValue(n, ni) Then
107+
nameList(n) += 1
108+
n += ni.ToString
109+
Else
110+
nameList.Add(n, 1)
111+
End If
112+
dt.Columns.Add(n, dr.GetFieldType(i))
113+
Next
114+
115+
' Read data and add rows
116+
While dr.Read()
117+
Dim row As DataRow = dt.NewRow()
118+
For i As Integer = 0 To dr.FieldCount - 1
119+
row(i) = dr(i)
120+
Next
121+
dt.Rows.Add(row)
122+
End While
103123
If dt.Rows.Count > 0 Then ds.Tables.Add(dt)
104124
Loop While Not dr.IsClosed AndAlso dr.NextResult()
105125
End Using

0 commit comments

Comments
 (0)