Skip to content

Commit cede7b7

Browse files
Copilotshueybubbles
andcommitted
Fix OUT parameter support for nullable civil types (pointer handling)
Co-authored-by: shueybubbles <[email protected]>
1 parent 1e514a0 commit cede7b7

File tree

2 files changed

+131
-0
lines changed

2 files changed

+131
-0
lines changed

civil_null_test.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,4 +381,109 @@ func TestNullCivilTypesParameterEncoding(t *testing.T) {
381381
t.Errorf("Expected Scale 7 for NULL NullTime, got %v", param.ti.Scale)
382382
}
383383
})
384+
385+
// Test pointer types (as used in OUT parameters)
386+
t.Run("Pointer NullDate parameter encoding", func(t *testing.T) {
387+
// Test valid *NullDate
388+
validDate := &NullDate{Date: civil.Date{Year: 2023, Month: time.December, Day: 25}, Valid: true}
389+
param, err := s.makeParam(validDate)
390+
if err != nil {
391+
t.Errorf("Unexpected error for valid *NullDate: %v", err)
392+
}
393+
if param.ti.TypeId != typeDateN {
394+
t.Errorf("Expected TypeId %v for valid *NullDate, got %v", typeDateN, param.ti.TypeId)
395+
}
396+
if len(param.buffer) == 0 {
397+
t.Error("Expected non-empty buffer for valid *NullDate")
398+
}
399+
400+
// Test invalid *NullDate (NULL)
401+
nullDate := &NullDate{Valid: false}
402+
param, err = s.makeParam(nullDate)
403+
if err != nil {
404+
t.Errorf("Unexpected error for NULL *NullDate: %v", err)
405+
}
406+
if param.ti.TypeId != typeDateN {
407+
t.Errorf("Expected TypeId %v for NULL *NullDate, got %v", typeDateN, param.ti.TypeId)
408+
}
409+
if param.ti.TypeId == typeNull {
410+
t.Error("NULL *NullDate should not use untyped NULL (typeNull)")
411+
}
412+
if len(param.buffer) != 0 {
413+
t.Error("Expected empty buffer for NULL *NullDate")
414+
}
415+
if param.ti.Size != 3 {
416+
t.Errorf("Expected Size 3 for NULL *NullDate, got %v", param.ti.Size)
417+
}
418+
})
419+
420+
t.Run("Pointer NullDateTime parameter encoding", func(t *testing.T) {
421+
// Test valid *NullDateTime
422+
testTime := time.Date(2023, time.December, 25, 14, 30, 45, 0, time.UTC)
423+
validDateTime := &NullDateTime{DateTime: civil.DateTimeOf(testTime), Valid: true}
424+
param, err := s.makeParam(validDateTime)
425+
if err != nil {
426+
t.Errorf("Unexpected error for valid *NullDateTime: %v", err)
427+
}
428+
if param.ti.TypeId != typeDateTime2N {
429+
t.Errorf("Expected TypeId %v for valid *NullDateTime, got %v", typeDateTime2N, param.ti.TypeId)
430+
}
431+
if len(param.buffer) == 0 {
432+
t.Error("Expected non-empty buffer for valid *NullDateTime")
433+
}
434+
435+
// Test invalid *NullDateTime (NULL)
436+
nullDateTime := &NullDateTime{Valid: false}
437+
param, err = s.makeParam(nullDateTime)
438+
if err != nil {
439+
t.Errorf("Unexpected error for NULL *NullDateTime: %v", err)
440+
}
441+
if param.ti.TypeId != typeDateTime2N {
442+
t.Errorf("Expected TypeId %v for NULL *NullDateTime, got %v", typeDateTime2N, param.ti.TypeId)
443+
}
444+
if param.ti.TypeId == typeNull {
445+
t.Error("NULL *NullDateTime should not use untyped NULL (typeNull)")
446+
}
447+
if len(param.buffer) != 0 {
448+
t.Error("Expected empty buffer for NULL *NullDateTime")
449+
}
450+
if param.ti.Scale != 7 {
451+
t.Errorf("Expected Scale 7 for NULL *NullDateTime, got %v", param.ti.Scale)
452+
}
453+
})
454+
455+
t.Run("Pointer NullTime parameter encoding", func(t *testing.T) {
456+
// Test valid *NullTime
457+
testTime := time.Date(2023, time.December, 25, 14, 30, 45, 0, time.UTC)
458+
validTime := &NullTime{Time: civil.TimeOf(testTime), Valid: true}
459+
param, err := s.makeParam(validTime)
460+
if err != nil {
461+
t.Errorf("Unexpected error for valid *NullTime: %v", err)
462+
}
463+
if param.ti.TypeId != typeTimeN {
464+
t.Errorf("Expected TypeId %v for valid *NullTime, got %v", typeTimeN, param.ti.TypeId)
465+
}
466+
if len(param.buffer) == 0 {
467+
t.Error("Expected non-empty buffer for valid *NullTime")
468+
}
469+
470+
// Test invalid *NullTime (NULL)
471+
nullTime := &NullTime{Valid: false}
472+
param, err = s.makeParam(nullTime)
473+
if err != nil {
474+
t.Errorf("Unexpected error for NULL *NullTime: %v", err)
475+
}
476+
if param.ti.TypeId != typeTimeN {
477+
t.Errorf("Expected TypeId %v for NULL *NullTime, got %v", typeTimeN, param.ti.TypeId)
478+
}
479+
if param.ti.TypeId == typeNull {
480+
t.Error("NULL *NullTime should not use untyped NULL (typeNull)")
481+
}
482+
if len(param.buffer) != 0 {
483+
t.Error("Expected empty buffer for NULL *NullTime")
484+
}
485+
if param.ti.Scale != 7 {
486+
t.Errorf("Expected Scale 7 for NULL *NullTime, got %v", param.ti.Scale)
487+
}
488+
})
384489
}

mssql.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,18 @@ func (s *Stmt) makeParam(val driver.Value) (res param, err error) {
10081008
if valuer.Valid {
10091009
return s.makeParamExtra(valuer.Time)
10101010
}
1011+
case *NullDate:
1012+
if valuer.Valid {
1013+
return s.makeParamExtra(valuer.Date)
1014+
}
1015+
case *NullDateTime:
1016+
if valuer.Valid {
1017+
return s.makeParamExtra(valuer.DateTime)
1018+
}
1019+
case *NullTime:
1020+
if valuer.Valid {
1021+
return s.makeParamExtra(valuer.Time)
1022+
}
10111023
case UniqueIdentifier:
10121024
case NullUniqueIdentifier:
10131025
default:
@@ -1169,6 +1181,20 @@ func (s *Stmt) makeParam(val driver.Value) (res param, err error) {
11691181
res.ti.Scale = 7
11701182
res.ti.Size = calcTimeSize(int(res.ti.Scale))
11711183
res.buffer = []byte{}
1184+
case *NullDate: // only null values reach here
1185+
res.ti.TypeId = typeDateN
1186+
res.ti.Size = 3
1187+
res.buffer = []byte{}
1188+
case *NullDateTime: // only null values reach here
1189+
res.ti.TypeId = typeDateTime2N
1190+
res.ti.Scale = 7
1191+
res.ti.Size = calcTimeSize(int(res.ti.Scale)) + 3
1192+
res.buffer = []byte{}
1193+
case *NullTime: // only null values reach here
1194+
res.ti.TypeId = typeTimeN
1195+
res.ti.Scale = 7
1196+
res.ti.Size = calcTimeSize(int(res.ti.Scale))
1197+
res.buffer = []byte{}
11721198
case driver.Valuer:
11731199
// We have a custom Valuer implementation with a nil value
11741200
return s.makeParam(nil)

0 commit comments

Comments
 (0)