Skip to content

Commit

Permalink
fix insertion of large string/[]byte followed by small string/[]byte …
Browse files Browse the repository at this point in the history
…will produce error
  • Loading branch information
sijms committed Sep 15, 2024
1 parent 7dd03ba commit 9a5e9d5
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 5 deletions.
146 changes: 146 additions & 0 deletions v2/TestIssues/issue_575_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package TestIssues

import (
"bytes"
"database/sql"
"strings"
"testing"
)

func TestIssue575(t *testing.T) {
var create = func(db *sql.DB) error {
return execCmd(db, `CREATE TABLE TTB_575 (
RN NUMBER,
ID_ NVARCHAR2(64) NOT NULL,
REV_ INTEGER,
NAME_ NVARCHAR2(255),
DEPLOYMENT_ID_ NVARCHAR2(64),
BYTES_ BLOB,
STR_ CLOB,
GENERATED_ NUMBER(1)
)`)
}
var drop = func(db *sql.DB) error {
return execCmd(db, `DROP TABLE TTB_575 PURGE`)
}

db, err := getDB()
if err != nil {
t.Error(err)
return
}
defer func() {
err = db.Close()
if err != nil {
t.Error(err)
}
}()
err = create(db)
if err != nil {
t.Error(err)
return
}
defer func() {
err = drop(db)
if err != nil {
t.Error(err)
}
}()
var tx *sql.Tx
tx, err = db.Begin()
if err != nil {
t.Error(err)
return
}
var stmt *sql.Stmt
stmt, err = tx.Prepare(`INSERT INTO TTB_575(RN, ID_, REV_, NAME_, DEPLOYMENT_ID_, BYTES_, STR_, GENERATED_)
VALUES (:1, :2, :3, :4, :5, :6, :7, :8)`)
if err != nil {
t.Error(err)
return
}
defer func() {
err = stmt.Close()
if err != nil {
t.Error(err)
}
}()
largeBytes := bytes.Repeat([]byte{0x3}, 0xFFFF)
smallBytes := bytes.Repeat([]byte{0x2}, 0xFF)
largeString := strings.Repeat("a", 0xFFFF)
smallString := strings.Repeat("b", 0xFF)

// insert large bytes and large string
_, err = stmt.Exec("100",
"1701058348821917698",
"1",
"信息服务接入表.bpmn_64fa805addca7e2d490debe8.png",
"1701058347710427137",
largeBytes,
largeString,
nil)
if err != nil {
t.Error(err)
err = tx.Rollback()
if err != nil {
t.Error(err)
}
return
}
// insert small bytes and small string
_, err = stmt.Exec("101",
"1701078318708568066",
"1",
"var-Activity_1e3bcfyAssigneeList",
nil,
smallBytes,
smallString,
nil)
if err != nil {
t.Error(err)
err = tx.Rollback()
if err != nil {
t.Error(err)
}
return
}
// insert large bytes and small string
_, err = stmt.Exec("102",
"1701058348821917698",
"1",
"信息服务接入表.bpmn_64fa805addca7e2d490debe8.png",
"1701058347710427137",
largeBytes,
smallString,
nil)
if err != nil {
t.Error(err)
err = tx.Rollback()
if err != nil {
t.Error(err)
}
return
}
// insert small bytes and large string
_, err = stmt.Exec("103",
"1701058348821917698",
"1",
"信息服务接入表.bpmn_64fa805addca7e2d490debe8.png",
"1701058347710427137",
smallBytes,
largeString,
nil)
if err != nil {
t.Error(err)
err = tx.Rollback()
if err != nil {
t.Error(err)
}
return
}
err = tx.Commit()
if err != nil {
t.Error(err)
return
}
}
30 changes: 25 additions & 5 deletions v2/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -603,12 +603,10 @@ func (stmt *defaultStmt) fetch(dataSet *DataSet) error {
// m_maxRowSize = m_maxRowSize + m_numOfLOBColumns * Math.Max(86, 86 + (int) lobSize) + m_numOfLONGColumns * Math.Max(2, longSize) + m_numOfBFileColumns * 86;
maxRowSize := 0
for _, col := range stmt.columns {
if col.DataType == OCIClobLocator || col.DataType == OCIBlobLocator {
if col.isLobType() {
maxRowSize += 86
} else if col.DataType == LONG || col.DataType == LongRaw || col.DataType == LongVarChar {
} else if col.isLongType() {
maxRowSize += 2
} else if col.DataType == OCIFileLocator {
maxRowSize += 86
} else {
maxRowSize += col.MaxLen
}
Expand Down Expand Up @@ -1947,9 +1945,31 @@ func (stmt *Stmt) NewParam(name string, val driver.Value, size int, direction Pa

func (stmt *Stmt) setParam(pos int, par ParameterInfo) {
if pos >= 0 && pos < len(stmt.Pars) {
if par.MaxLen > stmt.Pars[pos].MaxLen {
originalPar := stmt.Pars[pos]
if par.MaxLen > originalPar.MaxLen {
stmt.reSendParDef = true
}
// resend parameter definition when string/[]byte length change from long to short and vice versa
switch par.DataType {
case NCHAR:
if originalPar.DataType == LONG || originalPar.DataType == LongVarChar {
stmt.reSendParDef = true
}
case RAW:
if originalPar.DataType == LongRaw {
stmt.reSendParDef = true
}
case LONG:
fallthrough
case LongVarChar:
if originalPar.DataType == NCHAR {
stmt.reSendParDef = true
}
case LongVarRaw:
if originalPar.DataType == RAW {
stmt.reSendParDef = true
}
}
stmt.Pars[pos] = par
} else {
stmt.Pars = append(stmt.Pars, par)
Expand Down

0 comments on commit 9a5e9d5

Please sign in to comment.