From 953dfefeaa715365b28f833e4d1298985114ba1d Mon Sep 17 00:00:00 2001 From: Samy Sultan Date: Tue, 14 May 2024 08:11:34 +0300 Subject: [PATCH] fix reading empty array fix reading sql.Nullfloat --- v2/TestIssues/array_test.go | 111 ++++-- v2/command.go | 29 +- v2/parameter.go | 722 +----------------------------------- v2/utils.go | 2 +- 4 files changed, 104 insertions(+), 760 deletions(-) diff --git a/v2/TestIssues/array_test.go b/v2/TestIssues/array_test.go index 03e17869..0a891526 100644 --- a/v2/TestIssues/array_test.go +++ b/v2/TestIssues/array_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "database/sql" + "fmt" go_ora "github.com/sijms/go-ora/v2" "strings" "testing" @@ -43,45 +44,53 @@ func TestArray(t *testing.T) { var createPackage = func(db *sql.DB) error { sqlText := `create or replace package GOORA_TEMP_PKG as - type t_visit_id is table of TTB_MAIN.id%type index by binary_integer; - type t_visit_name is table of TTB_MAIN.name%type index by binary_integer; - type t_visit_val is table of TTB_MAIN.val%type index by binary_integer; - type t_visit_date is table of TTB_MAIN.ldate%type index by binary_integer; - - procedure test_get1(p_visit_id t_visit_id, l_cursor out SYS_REFCURSOR); - procedure test_get2(p_visit_id t_visit_id, p_visit_name out t_visit_name, - p_visit_val out t_visit_val, p_visit_date out t_visit_date); -end GOORA_TEMP_PKG; -` + type t_visit_id is table of TTB_MAIN.id%type index by binary_integer; + type t_visit_name is table of TTB_MAIN.name%type index by binary_integer; + type t_visit_val is table of TTB_MAIN.val%type index by binary_integer; + type t_visit_date is table of TTB_MAIN.ldate%type index by binary_integer; + + procedure test_get1(p_visit_id t_visit_id, l_cursor out SYS_REFCURSOR); + procedure test_get2(p_visit_id t_visit_id, p_visit_name out t_visit_name, + p_visit_val out t_visit_val, p_visit_date out t_visit_date); + procedure test_empty_array(p_visit_id t_visit_id, p_visit_name out t_visit_name, + p_visit_val out t_visit_val, p_visit_date out t_visit_date); + end GOORA_TEMP_PKG; + ` err := execCmd(db, sqlText) if err != nil { return err } sqlText = `create or replace PACKAGE BODY GOORA_TEMP_PKG as - procedure test_get1(p_visit_id t_visit_id, l_cursor out SYS_REFCURSOR) as - temp t_visit_id := p_visit_id; - begin - OPEN l_cursor for select id, name, val, ldate from TTB_MAIN - where id in (select column_value from table(temp)); - end test_get1; - - procedure test_get2(p_visit_id t_visit_id, p_visit_name out t_visit_name, - p_visit_val out t_visit_val, p_visit_date out t_visit_date) as - temp t_visit_id := p_visit_id; - cursor tempCur is select id, name, val, ldate from TTB_MAIN - where id in (select column_value from table(temp)); - tempRow tempCur%rowtype; - idx number := 1; - begin - for tempRow in tempCur loop - p_visit_name(idx) := tempRow.name; - p_visit_val(idx) := tempRow.val; - p_visit_date(idx) := tempRow.ldate; - idx := idx + 1; - end loop; - end test_get2; -end GOORA_TEMP_PKG; -` + procedure test_get1(p_visit_id t_visit_id, l_cursor out SYS_REFCURSOR) as + temp t_visit_id := p_visit_id; + begin + OPEN l_cursor for select id, name, val, ldate from TTB_MAIN + where id in (select column_value from table(temp)); + end test_get1; + + procedure test_get2(p_visit_id t_visit_id, p_visit_name out t_visit_name, + p_visit_val out t_visit_val, p_visit_date out t_visit_date) as + temp t_visit_id := p_visit_id; + cursor tempCur is select id, name, val, ldate from TTB_MAIN + where id in (select column_value from table(temp)); + tempRow tempCur%rowtype; + idx number := 1; + begin + for tempRow in tempCur loop + p_visit_name(idx) := tempRow.name; + p_visit_val(idx) := tempRow.val; + p_visit_date(idx) := tempRow.ldate; + idx := idx + 1; + end loop; + end test_get2; + + procedure test_empty_array(p_visit_id t_visit_id, p_visit_name out t_visit_name, + p_visit_val out t_visit_val, p_visit_date out t_visit_date) as + BEGIN + NULL; + END test_empty_array; + end GOORA_TEMP_PKG; + ` return execCmd(db, sqlText) } @@ -127,7 +136,7 @@ end GOORA_TEMP_PKG; ) // note size here is important and equal to max number of items that array can accommodate _, err := db.Exec(`BEGIN GOORA_TEMP_PKG.TEST_GET2(:1, :2, :3, :4); END;`, - []int{1, 3, 5}, go_ora.Out{Dest: &nameArray, Size: 10}, + []int{1, 3, 4, 5, 7, 8}, go_ora.Out{Dest: &nameArray, Size: 10}, go_ora.Out{Dest: &valArray, Size: 10}, go_ora.Out{Dest: &dateArray, Size: 10}) if err != nil { @@ -138,6 +147,33 @@ end GOORA_TEMP_PKG; t.Log(dateArray) return nil } + + var query3 = func(db *sql.DB) error { + var ( + nameArray []sql.NullString + valArray []sql.NullFloat64 + dateArray []sql.NullTime + ) + // note size here is important and equal to max number of items that array can accommodate + _, err := db.Exec(`BEGIN GOORA_TEMP_PKG.test_empty_array(:1, :2, :3, :4); END;`, + []int{1, 3, 5}, go_ora.Out{Dest: &nameArray, Size: 10}, + go_ora.Out{Dest: &valArray, Size: 10}, + go_ora.Out{Dest: &dateArray, Size: 10}) + if err != nil { + return err + } + if len(nameArray) != 0 { + return fmt.Errorf("expected empty array for name value and got: %d array size", len(nameArray)) + } + if len(valArray) != 0 { + return fmt.Errorf("expected empty array for numeric value and got: %d array size", len(valArray)) + } + if len(dateArray) != 0 { + return fmt.Errorf("expected empty array for date value and got: %d array size", len(dateArray)) + } + return nil + } + db, err := getDB() if err != nil { t.Error(err) @@ -187,4 +223,9 @@ end GOORA_TEMP_PKG; t.Error(err) return } + err = query3(db) + if err != nil { + t.Error(err) + return + } } diff --git a/v2/command.go b/v2/command.go index 9e0217ea..69deee3b 100644 --- a/v2/command.go +++ b/v2/command.go @@ -803,10 +803,6 @@ func (stmt *defaultStmt) read(dataSet *DataSet) (err error) { if err != nil { return err } - _, err = session.GetInt(2, true, true) - if err != nil { - return err - } } } } @@ -842,13 +838,6 @@ func (stmt *defaultStmt) read(dataSet *DataSet) (err error) { if err != nil { return err } - if stmt.Pars[x].DataType == XMLType && stmt.Pars[x].IsNull { - continue - } - _, err = session.GetInt(2, true, true) - if err != nil { - return err - } } else { //_, err = session.GetClr() } @@ -1234,10 +1223,24 @@ func (stmt *defaultStmt) calculateColumnValue(col *ParameterInfo, udt bool) erro // get values of rows and output parameter according to DataType and binary value (bValue) func (stmt *defaultStmt) calculateParameterValue(param *ParameterInfo) error { - if param.DataType == OCIBlobLocator || param.DataType == OCIClobLocator || param.DataType == OCIFileLocator { + if param.isLobType() { stmt._hasBLOB = true } - return param.decodeParameterValue(stmt.connection, &stmt.temporaryLobs) + err := param.decodeParameterValue(stmt.connection, &stmt.temporaryLobs) + if err != nil { + return err + } + if param.DataType == XMLType && param.IsNull { + return nil + } + if param.DataType != XMLType && param.MaxNoOfArrayElements > 0 { + return nil + } + _, err = stmt.connection.session.GetInt(2, true, true) + if err != nil { + return err + } + return nil } // Close stmt cursor in the server diff --git a/v2/parameter.go b/v2/parameter.go index 12c2154a..2b5333e8 100644 --- a/v2/parameter.go +++ b/v2/parameter.go @@ -44,12 +44,9 @@ type Out struct { //go:generate stringer -type=TNSType const ( - NCHAR TNSType = 1 - NUMBER TNSType = 2 - BInteger TNSType = 3 - //SB1 TNSType = 3 - //SB2 TNSType = 3 - //SB4 TNSType = 3 + NCHAR TNSType = 1 + NUMBER TNSType = 2 + BInteger TNSType = 3 FLOAT TNSType = 4 NullStr TNSType = 5 VarNum TNSType = 6 @@ -383,543 +380,6 @@ func (par *ParameterInfo) write(session *network.Session) error { return nil } -//func (par *ParameterInfo) setParameterValue(newValue driver.Value) error { -// if par.Value == nil { -// par.Value = newValue -// return nil -// } -// -// if temp, ok := par.Value.(sql.Scanner); ok { -// if temp != nil && !reflect.ValueOf(temp).IsNil() { -// return temp.Scan(newValue) -// } -// } -// switch value := par.Value.(type) { -// case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: -// par.Value = newValue -// case float32, float64, string, []byte: -// par.Value = newValue -// case bool: -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// par.Value = temp != 0 -// case *int: -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// *value = int(temp) -// case *int8: -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// *value = int8(temp) -// case *int16: -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// *value = int16(temp) -// case *int32: -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// *value = int32(temp) -// case *int64: -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// *value = temp -// case *uint: -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// *value = uint(temp) -// case *uint8: -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// *value = uint8(temp) -// case *uint16: -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// *value = uint16(temp) -// case *uint32: -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// *value = uint32(temp) -// case *uint64: -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// *value = uint64(temp) -// case *float32: -// temp, err := getFloat(newValue) -// if err != nil { -// return err -// } -// *value = float32(temp) -// case *float64: -// temp, err := getFloat(newValue) -// if err != nil { -// return err -// } -// *value = temp -// case time.Time: -// if tempNewVal, ok := newValue.(time.Time); ok { -// par.Value = tempNewVal -// } else { -// return errors.New("time.Time col/par need time.Time value") -// } -// case *time.Time: -// if tempNewVal, ok := newValue.(time.Time); ok { -// *value = tempNewVal -// } else { -// return errors.New("*time.Time col/par need time.Time value") -// } -// case TimeStamp: -// if tempNewVal, ok := newValue.(TimeStamp); ok { -// par.Value = tempNewVal -// } else if tempNewVal, ok := newValue.(time.Time); ok { -// par.Value = TimeStamp(tempNewVal) -// } else { -// return errors.New("TimeStamp col/par need TimeStamp or time.Time value") -// } -// case *TimeStamp: -// if tempNewVal, ok := newValue.(TimeStamp); ok { -// *value = tempNewVal -// } else if tempNewVal, ok := newValue.(time.Time); ok { -// *value = TimeStamp(tempNewVal) -// } else { -// return errors.New("*TimeStamp col/par need TimeStamp or time.Time value") -// } -// case BFile: -// if tempNewVal, ok := newValue.(BFile); ok { -// par.Value = tempNewVal -// } else { -// return errors.New("BFile col/par requires BFile value") -// } -// case *BFile: -// var tempVal BFile -// if tempNewVal, ok := newValue.(BFile); ok { -// tempVal = tempNewVal -// } else { -// return errors.New("*BFile col/par requires BFile value") -// } -// if value == nil { -// par.Value = &tempVal -// } else { -// *value = tempVal -// } -// case Clob: -// if tempNewVal, ok := newValue.(Clob); ok { -// par.Value = tempNewVal -// } else { -// return errors.New("Clob col/par requires Clob value") -// } -// -// case *Clob: -// var tempVal Clob -// if tempNewVal, ok := newValue.(Clob); ok { -// tempVal = tempNewVal -// } else { -// return errors.New("*Clob col/par requires Clob value") -// } -// if value == nil { -// par.Value = &tempVal -// } else { -// *value = tempVal -// } -// case NClob: -// if tempNewVal, ok := newValue.(NClob); ok { -// par.Value = tempNewVal -// } else { -// return errors.New("NClob col/par requires NClob value") -// } -// case *NClob: -// var tempVal NClob -// if tempNewVal, ok := newValue.(NClob); ok { -// tempVal = tempNewVal -// } else { -// return errors.New("*NClob col/par requires NClob value") -// } -// if value == nil { -// par.Value = &tempVal -// } else { -// *value = tempVal -// } -// case Blob: -// if tempNewVal, ok := newValue.(Blob); ok { -// par.Value = tempNewVal -// } else { -// return errors.New("Blob clo/par requires Blob value") -// } -// case *Blob: -// var tempVal Blob -// if tempNewVal, ok := newValue.(Blob); ok { -// tempVal = tempNewVal -// } else { -// return errors.New("*Blob col/par requires Blob value") -// } -// if value == nil { -// par.Value = &tempVal -// } else { -// *value = tempVal -// } -// case *[]byte: -// var tempVal []byte -// if tempNewVal, ok := newValue.([]byte); ok { -// tempVal = tempNewVal -// } else { -// return errors.New("[]byte col/par requires []byte or nil value") -// } -// if value == nil { -// par.Value = &tempVal -// } else { -// *value = tempVal -// } -// case *string: -// *value = getString(newValue) -// case *bool: -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// *value = temp != 0 -// case NVarChar: -// par.Value = NVarChar(getString(newValue)) -// case *NVarChar: -// *value = NVarChar(getString(newValue)) -// case sql.NullByte: -// if newValue == nil { -// value.Valid = false -// } else { -// value.Valid = true -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// value.Byte = uint8(temp) -// } -// par.Value = value -// case sql.NullInt16: -// if newValue == nil { -// value.Valid = false -// } else { -// value.Valid = true -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// value.Int16 = int16(temp) -// } -// par.Value = value -// case sql.NullInt32: -// if newValue == nil { -// value.Valid = false -// } else { -// value.Valid = true -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// value.Int32 = int32(temp) -// } -// par.Value = value -// case sql.NullInt64: -// if newValue == nil { -// value.Valid = false -// } else { -// value.Valid = true -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// value.Int64 = temp -// } -// par.Value = value -// case sql.NullBool: -// if newValue == nil { -// value.Valid = false -// } else { -// value.Valid = true -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// value.Bool = temp != 0 -// } -// par.Value = value -// case sql.NullFloat64: -// if newValue == nil { -// value.Valid = false -// } else { -// value.Valid = true -// temp, err := getFloat(newValue) -// if err != nil { -// return err -// } -// value.Float64 = temp -// } -// par.Value = value -// case *sql.NullByte: -// var tempValue sql.NullByte -// if newValue == nil { -// tempValue.Valid = false -// } else { -// tempValue.Valid = true -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// tempValue.Byte = uint8(temp) -// } -// if value == nil { -// par.Value = &tempValue -// } else { -// *value = tempValue -// } -// case *sql.NullInt16: -// var tempValue sql.NullInt16 -// if newValue == nil { -// tempValue.Valid = false -// } else { -// tempValue.Valid = true -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// tempValue.Int16 = int16(temp) -// } -// if value == nil { -// par.Value = &tempValue -// } else { -// *value = tempValue -// } -// case *sql.NullInt32: -// var tempValue sql.NullInt32 -// if newValue == nil { -// tempValue.Valid = false -// } else { -// tempValue.Valid = true -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// tempValue.Int32 = int32(temp) -// } -// if value == nil { -// par.Value = &tempValue -// } else { -// *value = tempValue -// } -// case *sql.NullInt64: -// var tempValue sql.NullInt64 -// if newValue == nil { -// tempValue.Valid = false -// } else { -// tempValue.Valid = true -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// tempValue.Int64 = temp -// } -// if value == nil { -// par.Value = &tempValue -// } else { -// *value = tempValue -// } -// case *sql.NullFloat64: -// var tempValue sql.NullFloat64 -// if newValue == nil { -// tempValue.Valid = false -// } else { -// tempValue.Valid = true -// temp, err := getFloat(newValue) -// if err != nil { -// return err -// } -// tempValue.Float64 = temp -// } -// if value == nil { -// par.Value = &tempValue -// } else { -// *value = tempValue -// } -// case *sql.NullBool: -// var tempValue sql.NullBool -// if newValue == nil { -// tempValue.Valid = false -// } else { -// tempValue.Valid = true -// temp, err := getInt(newValue) -// if err != nil { -// return err -// } -// tempValue.Bool = temp != 0 -// } -// if value == nil { -// par.Value = &tempValue -// } else { -// *value = tempValue -// } -// case sql.NullTime: -// if newValue == nil { -// value.Valid = false -// } else { -// value.Valid = true -// if tempNewVal, ok := newValue.(time.Time); ok { -// value.Time = tempNewVal -// } else { -// return errors.New("sql.NullTime col/par need time.Time or Nil value") -// } -// } -// par.Value = value -// case *sql.NullTime: -// var tempVal sql.NullTime -// if newValue == nil { -// tempVal.Valid = false -// } else { -// tempVal.Valid = true -// if tempNewVal, ok := newValue.(time.Time); ok { -// tempVal.Time = tempNewVal -// } else { -// return errors.New("*sql.NullTime col/par need time.Time or Nil value") -// } -// } -// if value == nil { -// par.Value = &tempVal -// } else { -// *value = tempVal -// } -// case NullTimeStampTZ: -// if newValue == nil { -// value.Valid = false -// } else { -// value.Valid = true -// if tempNewVal, ok := newValue.(TimeStampTZ); ok { -// value.TimeStampTZ = tempNewVal -// } else if tempNewVal, ok := newValue.(time.Time); ok { -// value.TimeStampTZ = TimeStampTZ(tempNewVal) -// } else { -// return errors.New("NullTimeStampTZ col/par need TimeStamp, time.Time or Nil value") -// } -// } -// par.Value = value -// case *NullTimeStampTZ: -// var tempVal NullTimeStampTZ -// if newValue == nil { -// tempVal.Valid = false -// } else { -// tempVal.Valid = true -// if tempNewVal, ok := newValue.(TimeStampTZ); ok { -// tempVal.TimeStampTZ = tempNewVal -// } else if tempNewVal, ok := newValue.(time.Time); ok { -// tempVal.TimeStampTZ = TimeStampTZ(tempNewVal) -// } else { -// return errors.New("*NullTimeStampTZ col/par need TimeStampTZ, time.Time or Nil value") -// } -// } -// if value == nil { -// par.Value = &tempVal -// } else { -// *value = tempVal -// } -// case NullTimeStamp: -// if newValue == nil { -// value.Valid = false -// } else { -// value.Valid = true -// if tempNewVal, ok := newValue.(TimeStamp); ok { -// value.TimeStamp = tempNewVal -// } else if tempNewVal, ok := newValue.(time.Time); ok { -// value.TimeStamp = TimeStamp(tempNewVal) -// } else { -// return errors.New("NullTimeStamp col/par need TimeStampTZ, time.Time or Nil value") -// } -// } -// par.Value = value -// case *NullTimeStamp: -// var tempVal NullTimeStamp -// if newValue == nil { -// tempVal.Valid = false -// } else { -// tempVal.Valid = true -// if tempNewVal, ok := newValue.(TimeStamp); ok { -// tempVal.TimeStamp = tempNewVal -// } else if tempNewVal, ok := newValue.(time.Time); ok { -// tempVal.TimeStamp = TimeStamp(tempNewVal) -// } else { -// return errors.New("*NullTimeStamp col/par need TimeStamp, time.Time or Nil value") -// } -// } -// if value == nil { -// par.Value = &tempVal -// } else { -// *value = tempVal -// } -// case sql.NullString: -// if newValue == nil { -// value.Valid = false -// } else { -// value.Valid = true -// value.String = getString(newValue) -// } -// par.Value = value -// case *sql.NullString: -// var tempVal sql.NullString -// if newValue == nil { -// tempVal.Valid = false -// } else { -// tempVal.Valid = true -// tempVal.String = getString(newValue) -// } -// if value == nil { -// par.Value = &tempVal -// } else { -// *value = tempVal -// } -// case NullNVarChar: -// if newValue == nil { -// value.Valid = false -// } else { -// value.Valid = true -// value.NVarChar = NVarChar(getString(newValue)) -// } -// par.Value = value -// case *NullNVarChar: -// var tempVal NullNVarChar -// if newValue == nil { -// tempVal.Valid = false -// } else { -// tempVal.Valid = true -// tempVal.NVarChar = NVarChar(getString(newValue)) -// } -// if value == nil { -// par.Value = &tempVal -// } else { -// *value = tempVal -// } -// default: -// typ := reflect.TypeOf(par.Value) -// return errors.New("unsupported type: " + typ.Name()) -// } -// return nil -//} - func (par *ParameterInfo) clone() ParameterInfo { tempPar := ParameterInfo{} tempPar.DataType = par.DataType @@ -957,9 +417,11 @@ func (par *ParameterInfo) collectLocators() [][]byte { func (par *ParameterInfo) isLongType() bool { return par.DataType == LONG || par.DataType == LongRaw || par.DataType == LongVarChar || par.DataType == LongVarRaw } + func (par *ParameterInfo) isLobType() bool { return par.DataType == OCIBlobLocator || par.DataType == OCIClobLocator || par.DataType == OCIFileLocator } + func (par *ParameterInfo) decodePrimValue(conn *Connection, temporaryLobs *[][]byte, udt bool) error { session := conn.session var err error @@ -970,8 +432,8 @@ func (par *ParameterInfo) decodePrimValue(conn *Connection, temporaryLobs *[][]b if err != nil { return err } - par.MaxNoOfArrayElements = size if size > 0 { + par.MaxNoOfArrayElements = size pars := make([]ParameterInfo, 0, size) for x := 0; x < size; x++ { tempPar := par.clone() @@ -980,12 +442,12 @@ func (par *ParameterInfo) decodePrimValue(conn *Connection, temporaryLobs *[][]b return err } //, err = tempPar.decodeValue(stmt.connection, false) - if x < size-1 { - _, err = session.GetInt(2, true, true) - if err != nil { - return err - } + //if x < size-1 { + _, err = session.GetInt(2, true, true) + if err != nil { + return err } + //} pars = append(pars, tempPar) } par.oPrimValue = pars @@ -1245,170 +707,8 @@ func (par *ParameterInfo) decodePrimValue(conn *Connection, temporaryLobs *[][]b return nil } -//func (par *ParameterInfo) decodeValue(connection *Connection, udt bool) (driver.Value, error) { -// session := connection.session -// var tempVal driver.Value -// var err error -// if par.DataType == ROWID { -// rowid, err := newRowID(session) -// if err != nil { -// return nil, err -// } -// if rowid == nil { -// tempVal = nil -// } else { -// tempVal = string(rowid.getBytes()) -// } -// return tempVal, nil -// } -// if par.DataType == UROWID { -// rowid, err := newURowID(session) -// if err != nil { -// return nil, err -// } -// if rowid == nil { -// tempVal = nil -// } else { -// tempVal = string(rowid.getBytes()) -// } -// return tempVal, nil -// } -// if (par.DataType == NCHAR || par.DataType == CHAR) && par.MaxCharLen == 0 { -// par.BValue = nil -// return nil, nil -// } -// if par.DataType == RAW && par.MaxLen == 0 { -// par.BValue = nil -// return nil, nil -// } -// par.BValue, err = session.GetClr() -// if err != nil { -// return nil, err -// } -// if par.BValue == nil { -// switch par.DataType { -// case OCIClobLocator: -// if par.CharsetForm == 1 { -// tempVal = Clob{locator: nil, Valid: false} -// } else { -// tempVal = NClob{locator: nil, Valid: false} -// } -// case OCIBlobLocator: -// tempVal = Blob{locator: nil, Valid: false} -// case OCIFileLocator: -// tempVal = BFile{lob: Lob{sourceLocator: nil, connection: connection}} -// default: -// tempVal = nil -// } -// } else { -// switch par.DataType { -// case NCHAR, CHAR, LONG: -// strConv, err := connection.getStrConv(par.CharsetID) -// if err != nil { -// return nil, err -// } -// tempVal = strConv.Decode(par.BValue) -// case NUMBER: -// // Scale = 0 and Precision <18 --> int64 -// if par.Scale == 0 && par.Precision <= 18 { -// tempVal, err = converters.NumberToInt64(par.BValue) -// if err != nil { -// return nil, err -// } -// } else if par.Scale == 0 && (converters.CompareBytes(par.BValue, converters.Int64MaxByte) > 0 && -// converters.CompareBytes(par.BValue, converters.Uint64MaxByte) < 0) { -// tempVal, err = converters.NumberToUInt64(par.BValue) -// if err != nil { -// return tempVal, err -// } -// } else if par.Scale > 0 { -// tempVal, err = converters.NumberToString(par.BValue) -// if err != nil { -// return tempVal, err -// } -// } else { -// tempVal = converters.DecodeNumber(par.BValue) -// } -// case TimeStampDTY: -// fallthrough -// case TimeStampeLTZ: -// fallthrough -// case TimeStampLTZ_DTY: -// fallthrough -// case TIMESTAMPTZ: -// fallthrough -// case TimeStampTZ_DTY: -// fallthrough -// case TIMESTAMP: -// fallthrough -// case DATE: -// dateVal, err := converters.DecodeDate(par.BValue) -// if err != nil { -// return nil, err -// } -// tempVal = dateVal -// case OCIBlobLocator, OCIClobLocator: -// var locator []byte -// var err error -// if !udt { -// locator, err = session.GetClr() -// } else { -// locator = par.BValue -// par.BValue = nil -// } -// if err != nil { -// return nil, err -// } -// if par.DataType == OCIClobLocator { -// if par.CharsetForm == 1 { -// tempVal = Clob{locator: locator} -// } else { -// tempVal = NClob{locator: locator} -// } -// } else { -// tempVal = Blob{locator: locator} -// } -// case OCIFileLocator: -// locator, err := session.GetClr() -// if err != nil { -// return nil, err -// } -// tempVal = BFile{ -// isOpened: false, -// lob: Lob{ -// sourceLocator: locator, -// sourceLen: len(locator), -// connection: connection, -// }, -// } -// case IBFloat: -// tempVal = converters.ConvertBinaryFloat(par.BValue) -// case IBDouble: -// tempVal = converters.ConvertBinaryDouble(par.BValue) -// case IntervalYM_DTY: -// tempVal = converters.ConvertIntervalYM_DTY(par.BValue) -// case IntervalDS_DTY: -// tempVal = converters.ConvertIntervalDS_DTY(par.BValue) -// default: -// tempVal = par.BValue -// } -// } -// return tempVal, nil -//} - func (par *ParameterInfo) decodeParameterValue(connection *Connection, temporaryLobs *[][]byte) error { return par.decodePrimValue(connection, temporaryLobs, false) - //if err != nil { - // return err - //} - //fieldValue := reflect.ValueOf(par.Value).Elem() - //return setFieldValue(fieldValue, par.oPrimValue) - - //tempVal, err := par.decodeValue(connection, false) - //if err != nil { - // return err - //} - //return par.setParameterValue(tempVal) } func (par *ParameterInfo) decodeColumnValue(connection *Connection, temporaryLobs *[][]byte, udt bool) error { diff --git a/v2/utils.go b/v2/utils.go index cb0d8255..18efd2aa 100644 --- a/v2/utils.go +++ b/v2/utils.go @@ -864,7 +864,7 @@ func setString(value reflect.Value, input string) error { return intErr case tyNullFloat64: if floatErr == nil { - value.Set(reflect.ValueOf(sql.NullFloat64{float64(tempInt), true})) + value.Set(reflect.ValueOf(sql.NullFloat64{tempFloat, true})) } return floatErr case tyNullBool: