Giter Site home page Giter Site logo

godror's Introduction

Go PkgGoDev Go Report Card codecov

Go DRiver for ORacle

godror is a package which is a database/sql/driver.Driver for connecting to Oracle DB, using Anthony Tuininga's excellent OCI wrapper, ODPI-C.

Build-time Requirements

  • Go 1.15
  • C compiler with CGO_ENABLED=1 - so cross-compilation is hard

Run-time Requirements

  • Oracle Client libraries - see ODPI-C

Although Oracle Client libraries are NOT required for compiling, they are needed at run time. Download the free Basic or Basic Light package from https://www.oracle.com/database/technologies/instant-client/downloads.html.

Rationale

With Go 1.9, driver-specific things are not needed, everything (I need) can be achieved with the standard database/sql library. Even calling stored procedures with OUT parameters, or sending/retrieving PL/SQL array types - just give a godror.PlSQLArrays Option within the parameters of Exec (but not in sql.Named)! For example, the array size of the returned PL/SQL arrays can be set with godror.ArraySize(2000) (default value is 1024).

Documentation

See Godror API Documentation and the Godror User Guide.

Installation

Run:

go get github.com/godror/godror@latest

Then install Oracle Client libraries and you're ready to go!

godror is cgo package. If you want to build your app using godror, you need gcc (a C compiler).

Important: because this is a CGO enabled package, you are required to set the environment variable CGO_ENABLED=1 and have a gcc compile present within your path.

See Godror Installation for more information.

Connection

To connect to Oracle Database use sql.Open("godror", dataSourceName), where dataSourceName is a logfmt-encoded parameter list. Specify at least "user", "password" and "connectString". For example:

db, err := sql.Open("godror", `user="scott" password="tiger" connectString="dbhost:1521/orclpdb1"`)

The connectString can be ANYTHING that SQL*Plus or Oracle Call Interface (OCI) accepts: a service name, an Easy Connect string like host:port/service_name, or a connect descriptor like (DESCRIPTION=...).

You can specify connection timeout seconds with "?connect_timeout=15" - Ping uses this timeout, NOT the Deadline in Context! Note that connect_timeout requires at least 19c client.

For more connection options, see Godor Connection Handling.

Extras

To use the godror-specific functions, you'll need a *godror.conn. That's what godror.DriverConn is for! See z_qrcn_test.go for using that to reach NewSubscription.

Calling stored procedures

Use ExecContext and mark each OUT parameter with sql.Out.

As sql.DB will close the statement ASAP, for long-lived objects (LOB, REF CURSOR), you have to keep the Stmt alive: Prepare the statement, and Close only after finished with the Lob/Rows.

Using cursors returned by stored procedures

Use ExecContext and an interface{} or a database/sql/driver.Rows as the sql.Out destination, then either use the driver.Rows interface, or transform it into a regular *sql.Rows with godror.WrapRows, or (since Go 1.12) just Scan into *sql.Rows.

As sql.DB will close the statemenet ASAP, you have to keep the Stmt alive: Prepare the statement, and Close only after finished with the Rows.

For examples, see Anthony Tuininga's presentation about Go (page 41)!

Caveats

sql.NullString

sql.NullString is not supported: Oracle DB does not differentiate between an empty string ("") and a NULL, so an

sql.NullString{String:"", Valid:true} == sql.NullString{String:"", Valid:false}

and this would be more confusing than not supporting sql.NullString at all.

Just use plain old string !

NUMBER

NUMBERs are transferred as string to Go under the hood. This ensures that we don't lose any precision (Oracle's NUMBER has 38 decimal digits), and sql.Scan will hide this and Scan into your int64, float64 or string, as you wish.

For PLS_INTEGER and BINARY_INTEGER (PL/SQL data types) you can use int32.

CLOB, BLOB

From 2.9.0, LOBs are returned as string/[]byte by default (before it needed the ClobAsString() option). Now it's reversed, and the default is string, to get a Lob reader, give the LobAsReader() option.

Watch out, Oracle will error out if the CLOB is too large, and you have to use godror.Lob in such cases!

If you return Lob as a reader, watch out with sql.QueryRow, sql.QueryRowContext ! They close the statement right after you Scan from the returned *Row, the returned Lob will be invalid, producing getSize: ORA-00000: DPI-1002: invalid dpiLob handle.

So, use a separate Stmt or sql.QueryContext.

For writing a LOB, the LOB locator returned from the database is valid only till the Stmt is valid! So Prepare the statement for the retrieval, then Exec, and only Close the stmt iff you've finished with your LOB! For example, see z_lob_test.go, TestLOBAppend.

TIMESTAMP

As I couldn't make TIMESTAMP arrays work, all time.Time is bind as DATE, so fractional seconds are lost. A workaround is converting to string:

time.Now().Format("2-Jan-06 3:04:05.000000 PM")

See #121 under the old project.

Timezone

See the documentation - but for short, the database's OS' time zone is used, as that's what SYSDATE/SYSTIMESTAMP uses. If you want something different (because you fill DATE columns differently), then set the "location" in the connection string, or the Timezone in the ConnectionParams accord to your chosen timezone.

Stored procedure returning cursor (result set)

var rset1, rset2 driver.Rows

const query = `BEGIN Package.StoredProcA(123, :1, :2); END;`

stmt, err := db.PrepareContext(ctx, query)
if err != nil {
    return fmt.Errorf("%s: %w", query, err)
}
defer stmt.Close()
if _, err := stmt.ExecContext(ctx, sql.Out{Dest: &rset1}, sql.Out{Dest: &rset2}); err != nil {
	log.Printf("Error running %q: %+v", query, err)
	return
}
defer rset1.Close()
defer rset2.Close()

cols1 := rset1.(driver.RowsColumnTypeScanType).Columns()
dests1 := make([]driver.Value, len(cols1))
for {
	if err := rset1.Next(dests1); err != nil {
		if err == io.EOF {
			break
		}
		rset1.Close()
		return err
	}
	fmt.Println(dests1)
}

cols2 := rset1.(driver.RowsColumnTypeScanType).Columns()
dests2 := make([]driver.Value, len(cols2))
for {
	if err := rset2.Next(dests2); err != nil {
		if err == io.EOF {
			break
		}
		rset2.Close()
		return err
	}
	fmt.Println(dests2)
}

Context with Deadline/Timeout

TL;DR; *always close sql.Rows ASAP!

Creating a watchdog goroutine, done channel for each call of rows.Next kills performance, so we create only one watchdog goroutine, at the first rows.Next call. It is defused after rows.Close (or the cursor is exhausted).

If it is not defused, it will Break the currently executing OCI call on the connection, when the Context is canceled/timeouted. You should always call rows.Close ASAP, but if you experience random Breaks, remember this warning!

Contribute

Just as with other Go projects, you don't want to change the import paths, but you can hack on the library in place, just set up different remotes:

cd $GOPATH/src/github.com/godror/godror
git remote add upstream https://github.com/godror/godror.git
git fetch upstream
git checkout -b master upstream/master

git checkout -f master
git pull upstream master
git remote add fork [email protected]:mygithubacc/godror
git checkout -b newfeature upstream/master

Change, experiment as you wish. Then run

git commit -m 'my great changes' *.go
git push fork newfeature

and you're ready to send a GitHub Pull Request from the github.com/mygithubacc/godror branch called newfeature.

Pre-commit

Download a staticcheck release and add this to .git/hooks/pre-commit:

#!/bin/sh
set -e

output="$(gofmt -l "$@")"

if [ -n "$output" ]; then
    echo >&2 "Go files must be formatted with gofmt. Please run:"
    for f in $output; do
        echo >&2 "  gofmt -w $PWD/$f"
    done
    exit 1
fi

go run ./check
exec staticcheck

Guidelines

As ODPI stores the error buffer in a thread-local-storage, we must ensure that the error is retrieved on the same thread as the prvious function executed on.

This means we have to encapsulate each execute-then-retrieve-error sequence in runtime.LockOSThread() and runtime.UnlockOSThread(). For details, see #120.

This is automatically detected by go run ./check which should be called in the pre-commit hook.

Third-party

  • oracall generates a server for calling stored procedures.

godror's People

Contributors

andrei-liashenko avatar anthony-tuininga avatar cemremengu avatar cjbj avatar dependabot[bot] avatar dinvlad avatar fdc-michael-grosshans avatar ivanpedersen avatar kataras avatar kmtong avatar kurt-google avatar lminoppoli-be avatar mkenney avatar nogoegst avatar novalagung avatar nvx avatar robstradling avatar rvanduiven avatar rvegas avatar sshaplygin avatar stanowawi avatar stevefan1999-personal avatar sudarshan12s avatar tgulacsi avatar tomoyamachi avatar travelliu avatar ubinix-warun avatar veqryn avatar walterwanderley avatar zhuqiuzhi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

godror's Issues

Some connection errors are reported as blank

Describe the bug
func fromErrorInfo(errInfo C.dpiErrorInfo) *OraErr can return an empty string, making debugging difficult.

It assumes errors will be ORA-XXXXX errors but there are cases where it might also be DPI/TNS (I think, we have not captured the specific cause with a debugger yet). Specifically I have noticed it coming from this return statement (technically it's equivalent from goracle)
https://github.com/godror/godror/blob/master/drv.go#L467

Specifically if a dpi context fails to be created it may return a DPI-XXXXX error. If im reading
https://github.com/oracle/odpi/blame/fce6e31a0d6673ad03ef10738f391ba063a9c046/src/dpiContext.c#L207
Correctly. When context is invalid it goes to src/dpiGen.c:dpiGen__checkHandle which creates DPI specific errors that look like they will trigger the blank error codepath.

To Reproduce
Steps to reproduce the behavior:
We see this when initiating connections while networking might be established to a proxy and the proxy accepts packets but the remote instance is never connected so will never respond with data, sometimes we get errors from other parts of the code like"ORA-12547: TNS: lost contact". But typically the error message from this specific return path is blank.

Expected behavior
I expect to see the elements of the error as it was populated at the DPI level. Whether it was a TNS/ORA/DPI error.

Your oracle client version
12.2.0.1.0

Your godror version
v2.23.6

Your go version
1.14

Your gcc version
unknown

Machine (please complete the following information):

  • OS: linux
  • Architecture x86_64
  • Version: EL 7

Additional context

retrieve data from PLSql cursor

Describe the bug
I have a cursor returned by PLSql function. I would want to be able loop on the cursor and retrieve data.
Instead I have this error:
column count mismatch: we have 10 columns, but given 0 destination

To Reproduce

db, err := sql.Open("godror", "api/user@localhost/DEV")
if err != nil {
  fmt.Println(err)
  panic(err)
}
defer db.Close()

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

const query = `
DECLARE
BEGIN
:cursor := pkg_api.my_func(pstr_logn_nm => 'my_name');
END;
`
stmt, err := db.PrepareContext(ctx, query)
if err != nil {
  fmt.Println(err)
  panic(err)
}

var rows driver.Rows
_, err = stmt.ExecContext(ctx, sql.Out{Dest: &rows})
if err != nil {
  fmt.Println(err)
}

var r []driver.Value
err = rows.Next(r)
if err != nil {
  fmt.Println(err) // column count mismatch: we have 10 columns, but given 0 destination
}
defer rows.Close()

fmt.Println(rows.Columns()) // [COL_1 COL_2 COL_3 COL_4 COL_5 COL_6 COL_7 COL_8 COL_9 COL_10]

Your oracle client version
x64-19.3.0.0.0

Your godror version
v0.16.1

Your go version
1.13.3

Your gcc version
10.1.0 (GCC)

Machine

  • OS: Gnu Linux / Archlinux
  • Architecture x86_64

Additional context
If I try to change driver.Rows by sql.Rows I have this error:

arg: unknown type sql.Rows

If I try to create an interface I:

type I interface {
  NM() string
}

var r []I
err = rows.Next(r)

I have this error:

cannot use r (type []I) as type []driver.Value in argument to rows.Next

I'm also new in Golang, if someone has an idea :)

Thank you very much.

scan error on timestamp column if data returns null from query for one of the columns

Hello @tgulacsi , thank you for looking into this.

After we did a -sed of goracle to godror, we came across an issue in one of our API where It was throwing a scan error on one of the columns (expDate), which is a timestamp column and if the query is returning null value for that field then it is throwing an error

*Error: unsupported Scan, storing driver.Value type into type time.Time",

Type struct for that field is defined as time.Time, I changed it sql.NullTime but that didn't help and the error this time we got was

Error - cannot use date.expDate (type sql.Nulltime) as type time.Time in argument to ptimes.TimestampProto.

When we revert the changes back to goracle then we are not getting any errors.

Please let me know if I didn't explain the issue clearly or if I am missing anything to add, we are new to the Go and trying to understand our existing APIs
Thank you.

Connections to heterogeneous pools don't respect usernames and passwords set by godror.ContextWithUserPassw

Describe the bug
When opening a connection to an heterogeneous pool with godror, later changes to the username and password with godror.ContextWithUserPassw are not respected, connection attemps error out with ORA-01017: invalid username/password; logon denied.
This used to work with goracle up to version 1.14.

To Reproduce
Steps to reproduce the behavior:

  1. Open a connection without username and password
	params := godror.ConnectionParams{
		Username: "",
		Password: "",
		SID:  "MYSID",
	}
	db, err := sqlx.Open("godror", params.StringWithPassword())
  1. Provide username and password
ctx := godror.ContextWithUserPassw(
		context.Background(),
		"username",
		"password",
		"",
	)
  1. Ping the generated context
err := db.PingContext(ctx)

Expected behavior
A successful ping.

Your oracle client version
18.4.0.0.0

Your godror version
latest commit

Your go version
1.14

Your gcc version
e.g. 9.2.1

Machine (please complete the following information):

  • OS: ArchLinux
  • Architecture: x86_64
  • Version: up to date

Add ability to set godror.NumberAsString(bool) as a global setting

Hi Tamas,

As discussed in #39 I was planning to use NumberAsString setting. However apparently that setting can be passed along with the new Query, Prepare and Open functions. The problem is I am using jmoiron/sqlx and that library didn't add support for the new db interfaces for the sake of compatibility. Is it possible that you can make NumberAsString as a global setting that I can call directly instead of the driver interfaces. Like goracle.SetAutoCommit(true) as an example.

I tried to use this setting as in the following test, but not only I don't have access to sql.DB type because I use the sqlx.DB wrapper, but I also couldn't find a function QueryContext that takes an Option as a third parameter in database/sql documentation. So I am confused as to how this setting is used.

func TestNumberBool(t *testing.T) {
	t.Parallel()
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()
	const qry = "SELECT 181 id, 1 status FROM DUAL"
	rows, err := testDb.QueryContext(ctx, qry, godror.NumberAsString())
	if err != nil {
		t.Fatal(errors.Errorf("%s: %w", qry, err))
	}

	for rows.Next() {
		var id int
		var status bool
		if err := rows.Scan(&id, &status); err != nil {
			t.Errorf("failed to scan data: %s\n", err)
		}
		t.Logf("Source id=%d, status=%t\n", id, status)
	}
}

Can't work with Logminer

Describe the bug
The current version can't use logminer technology. After opening the database archive, it failed to read redo log changes with logminer

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
conn, err := sourceOracleDb.Conn(ctx)
if err != nil {
	logger.Logger.Error("err:" + err.Error())
}
defer conn.Close()

if err := godror.EnableDbmsOutput(ctx, conn); err != nil {
	logger.Logger.Error("err:" + err.Error())
}
var minScnNumber int64
row:= sourceOracleDb.QueryRow("select min(current_scn) CURRENT_SCN from gv$database")
row.Scan(&minScnNumber)

startLogminerCommand := `BEGIN DBMS_LOGMNR.START_LOGMNR(STARTSCN => ` + strconv.FormatInt(minScnNumber, 10) + `,OPTIONS =>  DBMS_LOGMNR.SKIP_CORRUPTION+DBMS_LOGMNR.NO_SQL_DELIMITER+DBMS_LOGMNR.NO_ROWID_IN_STMT+DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.CONTINUOUS_MINE+DBMS_LOGMNR.COMMITTED_DATA_ONLY+dbms_logmnr.STRING_LITERALS_IN_STMT); END;`

queryScnChangeSQL := "SELECT thread# as threadId, scn,start_scn,commit_scn,timestamp,operation_code,operation,status,SEG_TYPE_NAME,info,seg_owner,table_name,username,sql_redo,row_id,csf,TABLE_SPACE,SESSION_INFO,RS_ID,RBASQN,RBABLK,SEQUENCE#,TX_NAME,SEG_NAME,SEG_TYPE_NAME  FROM v$logmnr_contents WHERE OPERATION_CODE IN (1, 2, 3)"

_, err = conn.ExecContext(ctx,startLogminerCommand)
if err != nil {
	logger.Logger.Error("err:" + err.Error())
	os.Exit(-1)
}

defer func() {
	conn.ExecContext(ctx, "begin DBMS_LOGMNR.END_LOGMNR; end;")
}()

if _, err := conn.ExecContext(ctx, queryScnChangeSQL); err != nil {
	logger.Logger.Error("err:" + err.Error())
}

var buf bytes.Buffer
if err := godror.ReadDbmsOutput(ctx, &buf, conn); err != nil {
	logger.Logger.Error("err:" + err.Error())
}
logger.Logger.Error(buf.String())
if buf.String() != "\n" {
	logger.Logger.Error("err:" + err.Error())
}

Proposal: cast bool type in arguments for insert

Oracle, like others RDBMS, don't have the boolean type, but normally the user use CHAR(1), VARCHAR(1), NUMBER(1,0) (this case less efficient), and others golang sql drivers manage bool in arguments to cast to 1 or 0 depending the value of boolean.

I propose cast the bool type in the driver for avoid the error ORA-00932: inconsistent datatypes: expected CHAR got BOOLEAN when insert a bool.

lob as named param: dpiStmt_execute(mode=32 arrLen=-1): ORA-22922: nonexistent LOB value

Describe the bug
Hello,
I'm trying to send a blob as parameter in a query.

To Reproduce

  if _, err := stmt.ExecContext(
    ctx,
    params...,
  ); err != nil {
    return "", err
  }

image

Your oracle client version
x64-19.3.0.0.0

Your godror version
v0.17.0

Your go version
1.14.4

Your gcc version
e.g. 4.8.3

Additional context
If I try to send with a smaller file it works.

Panic in godror during database failover

Describe the bug
We run a multi-az AWS RDS with Oracle. This means it has 1 replica/clone, that can be failed over to at any time.
We tested a failover today, and immediately received tons of panics from the godror library, bringing down our servers.
If the driver is having trouble connecting for the half-second that the failover is happening, I would normally expect regular errors or something else that can be dealt with gracefully.

To Reproduce
That might be tough...

Expected behavior
Regular errors, while the driver tries to reconnect in the background.

Screenshots

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x158 pc=0xbb6109]

goroutine 99 [running]:
github.com/godror/godror.(*statement).QueryContext(0xc0010b8f00, 0x1148b00, 0xc00335cb40, 0x183d370, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/go/src/github.com/ReturnPath/ecm/vendor/github.com/godror/godror/stmt.go:514 +0x179
database/sql.ctxDriverStmtQuery(0x1148b00, 0xc00335cb40, 0x1148d00, 0xc0010b8f00, 0x183d370, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/usr/local/go/src/database/sql/ctxutil.go:82 +0x210
database/sql.rowsiFromStatement(0x1148b00, 0xc00335cb40, 0x1143080, 0xc0015a84e0, 0xc000c8e280, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/usr/local/go/src/database/sql/sql.go:2604 +0x16a
database/sql.(*Stmt).QueryContext(0xc000134360, 0x1148b00, 0xc00335cb40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/database/sql/sql.go:2556 +0x210
github.com/jmoiron/sqlx.(*qStmt).QueryxContext(0xc000c50dd8, 0x1148b00, 0xc00335cb40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1810440, 0x1148b00, ...)
	/go/src/github.com/ReturnPath/ecm/vendor/github.com/jmoiron/sqlx/sqlx_context.go:332 +0x73
github.com/jmoiron/sqlx.(*Stmt).QueryxContext(0xc0005faa00, 0x1148b00, 0xc00335cb40, 0x0, 0x0, 0x0, 0x0, 0x45cb4e, 0xc015851da0)
	/go/src/github.com/ReturnPath/ecm/vendor/github.com/jmoiron/sqlx/sqlx_context.go:324 +0x88

Your oracle client version
e.g. 12.1.0.2.0

Your godror version
e.g. v0.13.4

Your go version
e.g. 1.14.1

Your gcc version
e.g. 7.3.0

Machine (please complete the following information):

  • OS: linux docker container for golang:1.14.1
  • Architecture x86_64
  • Version: debian buster

Additional context
Our code surrounding the panic is pretty simple.
We have a prepared statement that looks roughly like this:
select ID, OTHER_ID from TABLE_OWNER.ID_TO_ID_T

It gets prepared on startup, then the location of the panic was here:

sqlxConn.selectAllIdAndOtherIDsStmt.QueryxContext(ctx)

Connecting to Oracle Database with password Containing "@"

What version of Go are you using (go version)?

1.13.4 

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
windows/amd64

Connecting to oracle database using sql/database with Open function

Tried both possibilities which didn't work

db, err := sql.Open("goracle", "system/oracle@2019@localhost:1521/orcl")
db, err := sql.Open('goracle', 'system/"oracle@2019"@localhost:1521/orcl')

What did you expect to see?

Successful connection to Database.

What did you see instead?

params=oracle://sytem:SECRET-PfbiAOWC07c=@2019"%40localhost:1521/orcl?connectionClass=GORACLE&poolIncrement=1&poolMaxSessions=1000&poolMinSessions=1&sysdba=0&sysoper=0&sysasm=0&standaloneConnection=0&enableEvents=0&heterogeneousPool=0&prelim=0&poolWaitTimeout=3000&poolSessionMaxLifetime=3600&poolSessionTimeout=300 extAuth=0: ORA-12154: TNS:could not resolve the connect identifier specified

Error with new API for NewConnector at v0.16.0

Describe the bug
After of update to v016.0, I get:

params={{  oracle://demo:***@127.0.0.1:1521/demo0 false 0x6e6eb0 UTC} {0 0 0 0s 0s 0s false false}} extAuth=0: ORA-24415: Missing or null username.

To Reproduce
I've updated my code to use the new API, just like:

import (
	"database/sql"
	"github.com/godror/godror"
)

func OpenDB(dsn string) (*sql.DB) {
	fmtTimeOracle := map[string]string{
		"NLS_DATE_FORMAT": "YYYY-MM-DD",
	}

	conn := godror.NewConnector(godror.ConnectionParams{
		CommonParams: godror.CommonParams{
			DSN:    dsn,
			OnInit: godror.NewSessionIniter(fmtTimeOracle),
		},
	})

	return sql.OpenDB(conn)
}

Your godror version
v0.16.0

Your go version
$ go version
go version go1.14.1 linux/amd64

Your gcc version
$ gcc --version
gcc (GCC) 8.3.1 20190507 (Red Hat 8.3.1-4)

Machine (please complete the following information):

  • OS: CentOs
  • Architecture x86_64
  • Version: 8.1

Additional context
Like you can see, both username and password are passed via DSN.
I'm supposed that the issue is because it expects to get them from CommonParams, but they should be get them from DSN when Username and/or Password are empty at CommonParams.

cannot reset password for DPI backed connection pool

Describe the bug
The driver keys connection pools by {P.Username, P.DSN, P.MinSessions, P.MaxSessions, P.SessionIncrement, P.WaitTimeout, P.MaxLifeTime, P.SessionTimeout, P.Heterogeneous, P.EnableEvents, P.ExternalAuth}. I cannot see any way to re-initialize a pool if the user password changes.

In my use case, I have an HTTP2-fonted gateway for executing SQL commands to various databases which makes it impractical to restart it whenever user credentials change.

To Reproduce

  1. create test user
  2. open pool for user
  3. ping
  4. change user password
  5. close pool
  6. open pool with new password
  7. ping fails
func TestDPIPools(t *testing.T) {

	// godror.Log = func(args ...interface{}) error {
	// 	lbuilder := &strings.Builder{}
	// 	for i, arg := range args {
	// 		if i > 0 {
	// 			lbuilder.WriteString("; ")
	// 		}
	// 		lbuilder.WriteString(fmt.Sprintf("%s", arg))
	// 	}
	// 	fmt.Println(lbuilder.String())
	// 	return nil
	// }

	sysPool, err := sql.Open("godror", "oracle://system:[email protected]:1521/ORCL?poolMinSessions=0&poolMaxSessions=0&standaloneConnection=0")
	if err != nil {
		t.Error(err)
		return
	}
	sysPool.SetMaxIdleConns(0)
	sysPool.SetMaxOpenConns(0)
	defer sysPool.Close()
	if _, err := sysPool.Exec(`alter user c##test identified by "test123" container=all`); err != nil {
		t.Error(err)
		return
	}

	testPool, err := sql.Open("godror", "oracle://c%23%23test:[email protected]:1521/ORCL?poolMinSessions=0&poolMaxSessions=0&poolSessionMaxLifetime=1s&poolSessionTimeout=1s&standaloneConnection=0")
	if err != nil {
		t.Error(err)
		return
	}
	defer testPool.Close()
	testPool.SetMaxIdleConns(0)
	testPool.SetMaxOpenConns(0)

	if err = testPool.Ping(); err != nil {
		t.Error(err)
		return
	}
	sessions, err := sysPool.Query(`select count(*) from v$session where username='C##TEST'`)
	if err != nil {
		t.Error(err)
		return
	}
	for sessions.Next() {
		var (
			count int
		)
		if err := sessions.Scan(&count); err != nil {
			t.Error(err)
			return
		}
		fmt.Println(fmt.Sprintf("c##test sessions: %d", count))
	}
	sessions.Close()

	if _, err := sysPool.Exec(`alter user c##test identified by "test1234" container=all`); err != nil {
		t.Error(err)
		return
	}
	testPool.Close()
	<-time.After(2 * time.Second)
	if testPool, err = sql.Open("godror", "oracle://c%23%23test:[email protected]:1521/ORCL?poolMinSessions=0&poolMaxSessions=0&poolSessionMaxLifetime=1s&poolSessionTimeout=1s&standaloneConnection=0"); err != nil {
		t.Error(err)
	}
	testPool.SetMaxIdleConns(0)
	testPool.SetMaxOpenConns(0)

        // THIS FAILS
	if err = testPool.Ping(); err != nil {
		t.Error(err)
	}
	testPool.Close()

}

Expected behavior
Should have some means to reset a DPI connection pool with similar semantics to sql.DB.Close()

Screenshots

Your oracle client version
19

Your godror version
v0.17.0

Your go version
1.14

Your gcc version
9.3

Machine (please complete the following information):

  • OS: linux
  • Architecture 86_64
  • Version: Ubuntu 20.04 LTS

Additional context

After failover, prepared statements stopped working

Describe the bug
We run a multi-az AWS RDS with Oracle. This means it has 1 replica/clone, that can be failed over to at any time.
We tested a failover today, and a separate bunch of servers (a different application than my other ticket) began to encounter a very weird issue: It began claiming that a prepared statement that needs 1 argument, actually doesn't want any arguments.

To Reproduce
That might be tough...

Expected behavior
Program should continue without issues. If a statement needs to be re-prepared in the background due to connection issues, it should be.

Screenshots
sql: expected 0 arguments, got 1

Your oracle client version
e.g. 12.1.0.2.0

Your godror version
e.g. v0.13.4

Your go version
e.g. 1.14.1

Your gcc version
e.g. 7.3.0

Machine (please complete the following information):

  • OS: linux docker container for golang:1.14.1
  • Architecture x86_64
  • Version: debian buster

Additional context
Our code surrounding the call is pretty simple.
We have a prepared statement that looks roughly like this:
select OTHER_ID from TABLE_OWNER.ID_TO_ID_T where ID = :1

It gets prepared on startup, then the location of the error was here:

sqlxConn.selectOtherIDFromIdStmt.GetContext(ctx, &otherID, id)

ORA-24459: OCISessionGet() timed out waiting for pool to create new connections

@tgulacsi
Describe the bug
we are getting OCISessionGet timeout issue intermittently and we are logging DB stats each time before getconnection. Here is the DB stats.

DB Stats: MaxOpenConnections: 25, OpenConnections: 11, InUse: 11, Idle: 0, WaitCount: 0, WaitDuration: 0, MaxIdleClosed: 0, MaxLifetimeClosed: 0}

To Reproduce
Steps to reproduce the behavior:
Here is my connection string and properties:

connString := fmt.Sprintf("oracle://%s:%s@%s/%s:POOLED", c.User, c.Password, c.Host, c.DatabaseName)
db, err := sql.Open("godror", connString)
if err != nil {
log.Error("Error in sql open ")
return nil, err
}
db.SetMaxOpenConns(25)
db.SetMaxIdleConns(10)
db.SetConnMaxLifetime(0) // and tried also with db.SetConnMaxLifetime(time.Minute*10)

executing query
stmt, err := db.PrepareContext(ctx,query)
if err != nil {
log.Error("Error in PrepareContext ",erro.Error())
}
result, err := stmt.ExecContext(ctx,parameters)

we are getting error in db.PrepareContext below is full error:
Error in PrepareContext, username="" dsn="1528/**:POOLED" params={authMode:0 connectionClass:0x5313c10 connectionClassLength:6 purity:0 newPassword:\u003cnil\u003e newPasswordLength:0 appContext:\u003cnil\u003e numAppContext:0 externalAuth:0 externalHandle:\u003cnil\u003e pool:0xca011c0 tag:\u003cnil\u003e tagLength:0 matchAnyTag:0 outTag:\u003cnil\u003e outTagLength:0 outTagFound:0 shardingKeyColumns:\u003cnil\u003e numShardingKeyColumns:0 superShardingKeyColumns:\u003cnil\u003e numSuperShardingKeyColumns:0 outNewSession:0}: ORA-24459: OCISessionGet() timed out waiting for pool to create new connections","time":"05-15-2020 17:32:37"}

Expected behavior
we set SetMaxOpenConns as 25 and maxIdleconn as 10 expecting shouldn't get timeout waiting for pool to create new connection.

Screenshots

Your oracle client version
PROD ENV: 12.2.0.1.0
TEST ENV: 19

Your godror version
v0.15.0

Your go version
go1.14.2 darwin/amd64

Your gcc version
c++/4.2.1

Machine (please complete the following information):

  • OS: macOS Mojave
  • Architecture [e.g. x86_64]
  • Version: 10.14.6

Additional context
Add any other context about the problem here.

Doesn't currently work with go mod vendor

Describe the bug
So go modules don't appear to contain anything directories that don't have go source files.
This means that when using go get to download this package, all the odpi-C files are not included, causing the package to fail at build time.

To Reproduce

  1. Have a go.mod file at your project's root directory.
  2. From that root directory, run this to download godror: go get -u github.com/godror/godror
  3. Run go mod vendor to have godror vendored.
  4. Build project, get this or similar error:
# github.com/godror/godror
vendor\github.com\godror\godror\conn.go:10:10: fatal error: dpiImpl.h: No such file or directory
 #include "dpiImpl.h"
          ^~~~~~~~~~~
compilation terminated.

Expected behavior
Successful build.

Your oracle client version
18.3.0.0.0

Your godror version
v0.13.2

Your go version
1.14.1

Your gcc version
7.3.0

Machine (please complete the following information):

  • OS: Windows
  • Architecture: x86_64
  • Version: 10

Additional context
There appear to be two possible solutions:

  1. Include a mostly empty go file in all directories containing ODPI-C files.
    Call it required.go or something, and just have some notes in it.
    This will cause go mod to include the whole directory and all files in the directory in the module.

or 2. Include documentation on how to download and install the correct ODPI-C files onto your host or container image, so that this project will work.

Proposal: return INTERVAL YEAR TO MONTH in format y-m

Actually the type INTERVAL YEAR TO MONTH return a string with this style %dy%dm formatted with Sprintf.

This style is easy to read, but Oracle read a y-m style.

Consider returns this type like Oracle can handle it. For example, 12 years 5 months is 12-5

Also, Sprintf is not good for cast int to string.

This line

godror/rows.go

Line 436 in 1b2894c

dest[i] = fmt.Sprintf("%dy%dm", ym.years, ym.months)

Can be replace with

dest[i] = strconv.Itoa(int(ym.years)) + "-" + strconv.Itoa(int(ym.months))

Avoid Go pooling or at least reaquire session when connection got from pool

As discussed in mail and after at https://groups.google.com/forum/#!topic/golang-sql/VkjZeUVS0i4%5B1-25%5D Go's database pooling conflicts with some Oracle session pooling features (failover, for example).

ResetSession is called when the connection has been got freshly from the pool,
IsValid is called when the connections is being put back to the pool.

The idea is to release the session in IsValid,
and acquire a new one in ResetSession.

@anthony-tuininga I've started implementing this (in the "resetsession" branch, 6a95cb5), and seems to work (I don't know how effective is it regarding the OCI session pool), EXCEPT the TestObject test, which reliably (go test -run=TestObject with a poolable connection) fails, so this needs investigation.

Driver Name Exceeds OCI Max

I upgraded from goracle v2.24 to godror v0.0.1 and my code started to fail complaining about OCI_ATTR_DRIVER_NAME

Specifically trying to access the database results in
ORA-24960: the attribute OCI_ATTR_DRIVER_NAME is greater than the maximum allowable length of 30

To Reproduce

package main

import (
        "fmt"
        "database/sql"
        "log"

        _ "github.com/godror/godror"
)

const (
        dbname = "mydb"
        user   = "user"
        pass   = "pass"
)

func main() {
        db, err := sql.Open("godror", fmt.Sprintf("%s/%s@%s", user, pass, dbname))
        if err != nil {
                log.Fatal("Connect Error:\n" + err.Error())
        }
        if err = db.Ping(); err != nil {
                log.Fatal("Ping Error:\n" + err.Error())
        }
        defer db.Close()
        fmt.Println("Connected: ok")
}

Output:
2019/12/13 19:47:51 Ping Error: params=oracle://<sanitized>?connectionClass=GODROR&enableEvents=0&heterogeneousPool=0&poolIncrement=1&poolMaxSessions=1000&poolMinSessions=1&poolSessionMaxLifetime=1h0m0s&poolSessionTimeout=5m0s&poolWaitTimeout=30s&prelim=0&standaloneConnection=0&sysasm=0&sysdba=0&sysoper=0&timezone= extAuth=0: ORA-24960: the attribute OCI_ATTR_DRIVER_NAME is greater than the maximum allowable length of 30

I obviously removed some details of my system here and in the code.

Your oracle client version
12.1.0

Your godror version
v0.0.1

Your go version
go version go1.13.1 windows/amd64

Your gcc version
gcc (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0

Machine (please complete the following information):

  • OS: Windows 10
  • Architecture 64 bit
  • Version: 1903

Additional context
https://docs.oracle.com/database/121/LNOCI/ociaahan.htm#LNOCI17759 seems to indicate that the 30 char limit is set by OCI.

I think this change is the cause of the problem:

godror/drv.go

Line 90 in 446a293

DriverName = "github.com/godror/godror : " + Version

Not sure how you want to adjust the name, but if I shorten to just "godror : " + Version everything is groovy after that.

Also for reasons that aren't entirely clear to me, my Linux box didn't trigger this issue, it is using the 12.2 instantclient

sqlx rebind not works with godror

Describe the bug
Previously while using goracle i had not any problems with sqlx. But after changing to godror i started to receive errors while making requests

how i open connection and make querie:

drv.DBConn, err = sqlx.Connect("goracle", ConnectionString)
var query = drv.DBConn.Rebind("some querie when use ? param")

Which error i receives when makes requests

sql: expected 0 arguments, got 1

After some time researching and tests i found that sqlx.Rebind with godror driver not changing ? to :arg1 or :argN for oracle

I fixed this for my project by returning to gopkg.in/goracle.v2 v2.24.1 and goracle in driverName for sqlx.Connect

Your oracle client version
19.3.0

Your godror version
v0.9.1

Your go version
1.13.5

Machine (please complete the following information):

  • OS: [win]
  • Architecture [x86_64]
  • Version: [10]

Query() returns only the 1st result for an input array

Describe the bug
ExecuteMany query returns only the 1st result for a named parameter of len > 1.

To Reproduce
Steps to reproduce the behavior:

  1. Run a query like the following
rows, err := db.QueryContext(
	godror.ContextWithLog(ctx, logger.Log),
	"SELECT id FROM subjects WHERE id = :id",
	sql.Named("id", []int{1, 2, 3}),
)
if err != nil {
	log.Fatal(err)
}
defer rows.Close()
count := 0
hasNextResult := true
for hasNextResult {
	for rows.Next() {
		var row int
		if err = rows.Scan(&row); err != nil {
			log.Fatal(err)
		}
		fmt.Println(row)
		count++
	}
	hasNextResult = rows.NextResultSet()
}
fmt.Println("count", count)
  1. Observe that only the 1st result is returned:
enter=bindVars args="unsupported value type"
msg=bindVars i=0 in=true out=false value="[]int []int{1, 2, 3}"
doManyCount=3 arrLen=3 doExecMany=true minArrLen=maxArrLen
msg=newVar i=0 plSQLArrays=false typ=2010 natTyp=3000 sliceLen=3 bufSize=0 isSlice=true
1
count 1

Expected behavior
All results must be returned (corresponding to count 3 in the above example).

Your oracle client version
18.1.0.0.0

Your godror version
v0.9.1

Your go version
1.13.7

Your gcc version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)

Machine (please complete the following information):

  • OS: macOS
  • Architecture x86_64
  • Version: 10.14.6

Additional context
Same result is observed when the array is passed as an unnamed parameter.

Heterogeneous Pools are broken AFTER v0.10.3

Until v0.10.3 was working fine, but since v0.10.4 isn't work anymore

To Reproduce

  1. go test -v -count=1 -run TestHeterogeneousPoolIntegration
  2. The tests failed:

Client: 19.3.0.0.0 Timezone: Local
Server: 18.4.0.0.0 [Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production; Version 18.4.0.0.0] Timezone: +00:00
=== RUN TestHeterogeneousPoolIntegration
=== RUN TestHeterogeneousPoolIntegration/noContext
=== RUN TestHeterogeneousPoolIntegration/proxyUser
--- FAIL: TestHeterogeneousPoolIntegration (5.17s)
z_heterogeneous_test.go:36: oracle://System:Oracle18@localhost:1521/xe?connectionClass=POOLED&enableEvents=1&heterogeneousPool=1&newPassword=&poolIncrement=1&poolMaxSessions=16&poolMinSessions=1&poolSessionMaxLifetime=5m0s&poolSessionTimeout=30s&poolWaitTimeout=10s&prelim=0&standaloneConnection=0&sysasm=0&sysdba=0&sysoper=0&timezone=
--- PASS: TestHeterogeneousPoolIntegration/noContext (0.07s)
--- FAIL: TestHeterogeneousPoolIntegration/proxyUser (0.06s)
z_heterogeneous_test.go:77: proxyUser: currentUser got SYSTEM, wanted test_proxyUser
FAIL

Expected behavior
Test pass

Your oracle client version
e.g. 18c-xe

Your godror version
e.g. v0.10.0

Your go version
e.g. 1.13.3

Your gcc version
e.g. 7.0.0

Machine (please complete the following information):

OS: Ubuntu
Architecture x86_64
Version: 18

DSN is not well parsed when the username starts with 'c##'

Describe the bug
The DSN is not well parsed when the username starts with "C##" or "c##"

To Reproduce

package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/godror/godror"
)

const (
	dbname = "DEMO0"
	user      = "c##demo"
	pass      = "***"
)

var (
	dsn  = fmt.Sprintf("oracle://%s:%[email protected]:1521/%s", user, pass, dbname)
)

func main() {
	fmt.Printf("\n== DSN: %s\n", dsn)
	db, err := sql.Open("godror", dsn)
	if err != nil {
		log.Fatal("Connect Error:\n" + err.Error())
	}

	if err = db.Ping(); err != nil {
		db.Close()
		log.Fatal("Ping Error:\n" + err.Error())
	}

	fmt.Println("Connected: ok")
	db.Close()
}
020/06/12 12:31:29 Ping Error:
username="" dsn="c" standalone params={authMode:0 connectionClass:<nil> connectionClassLength:0 purity:0 newPassword:<nil> newPasswordLength:0 appContext:<nil> numAppContext:0 externalAuth:1 externalHandle:<nil> pool:<nil> tag:<nil> tagLength:0 matchAnyTag:0 outTag:<nil> outTagLength:0 outTagFound:0 shardingKeyColumns:<nil> numShardingKeyColumns:0 superShardingKeyColumns:<nil> numSuperShardingKeyColumns:0 outNewSession:0}: ORA-12154: TNS:could not resolve the connect identifier specified
exit status 1

Expected behavior
It should connect to the database.

Your godror version
v0.16.1

Your go version
go version go1.14.1 linux/amd64

Your gcc version
gcc (GCC) 8.3.1 20190507 (Red Hat 8.3.1-4)

Machine (please complete the following information):
CentOS 8.1

Additional context
Both username and database have been created and I can access to them from sqlplus:

$ sqlplus c##demo/***

SQL*Plus: Release 18.0.0.0.0 - Production on Fri Jun 12 12:37:34 2020
Version 18.3.0.0.0

Copyright (c) 1982, 2018, Oracle.  All rights reserved.

Last Successful login time: Fri Jun 12 2020 11:40:36 +01:00

Connected to:
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.3.0.0.0

SQL> select ora_database_name from dual;

ORA_DATABASE_NAME
--------------------------------------------------------------------------------
DEMO0

SQL> 

Make `drv.go: drv` struct exported

Hello, thank u for lib!

We want to use APM for receiving SQL execution spans and faced the following problems.

  1. APM registers the driver of a specific library and wraps it in its "tracing driver".
    https://github.com/elastic/apm-agent-go/blob/master/module/apmsql/mysql/init.go
    https://github.com/elastic/apm-agent-go/blob/master/module/apmsql/pq/init.go
    https://github.com/elastic/apm-agent-go/blob/master/module/apmsql/mysql/init.go
    But godror's driver is not exported :(

  2. With each new connection, we need to do some work, so we use

conn, _ := goracle.NewConnector(...)
db := sql.OpenDB(conn)

We could wrap the driver in a "tracer driver", but there is no way to change the driver for the connection:

conn, _ := goracle.NewConnector(...)
wrappedDrv := apmsql.Wrap(drvConnector.Driver())
conn.d = wrappedDrv // Invalid
db := sql.OpenDB(conn)

Do u have any ideas? Thanks!

Weird line get printed when connecting to oracle successfully

Describe the bug
The following line get printed every time I connect to oracle (the timestamp changes of course).
ODPI [02488] 2020-04-01 08:05:14.574: dlopen(libclntsh.so): OK

To Reproduce
Steps to reproduce the behavior:

package main

import (
	"database/sql"
	"fmt"
	"os"

	_ "github.com/godror/godror"
)

func main() {
	dsn := os.Getenv("USER") + "/" + os.Getenv("PASS") + "@MYSERVICE"
	db, err := sql.Open("godror", dsn)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	defer db.Close()

	rows, err := db.Query("SELECT 1+1 FROM DUAL")
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	for rows.Next() {
		var value int
		rows.Scan(&value)
		fmt.Println("1 + 1 =", value)
	}
}

Expected behavior
No line printed.

Your oracle client version
e.g. 12.1.0.2.0

Your godror version
e.g. v0.13.3

Your go version
e.g. 1.14.1

Your gcc version
e.g. 7.3.0

Machine (please complete the following information):

  • OS: Windows
  • Architecture: x86_64
  • Version: 10

ConvertValue function for godror.Number to bool

Hi Tamas,

Great job on the new driver.
database/sql package allows int to bool value conversion, however I think godror doesn't implement boolType conversions from godror.Number. I am trying to upgrade a legacy code from goraclev1 to godror now, apparently goraclev1 had this feature so the code is riddled with int to bool conversions and I am getting the following error from many queries:

sql/driver: couldn't convert 0 (godror.Number) into type bool

Here is the database/sql ConvertValue implementation for boolType:

func (boolType) ConvertValue(src interface{}) (Value, error) {
	switch s := src.(type) {
	case bool:
		return s, nil
	case string:
		b, err := strconv.ParseBool(s)
		if err != nil {
			return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s)
		}
		return b, nil
	case []byte:
		b, err := strconv.ParseBool(string(s))
		if err != nil {
			return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s)
		}
		return b, nil
	}

	sv := reflect.ValueOf(src)
	switch sv.Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		iv := sv.Int()
		if iv == 1 || iv == 0 {
			return iv == 1, nil
		}
		return nil, fmt.Errorf("sql/driver: couldn't convert %d into type bool", iv)
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		uv := sv.Uint()
		if uv == 1 || uv == 0 {
			return uv == 1, nil
		}
		return nil, fmt.Errorf("sql/driver: couldn't convert %d into type bool", uv)
	}

	return nil, fmt.Errorf("sql/driver: couldn't convert %v (%T) into type bool", src, src)
}

Cross-compile failed in Windows, target Linux

Describe the bug
Got the following message while compiling my code with GOOS=linux, GOARCH=amd64 in Windows,

λ go install goxc
# github.com/godror/godror
..\godror\godror\orahlp.go:452:56: undefined: VersionInfo
..\godror\godror\orahlp.go:461:56: undefined: VersionInfo
..\godror\godror\orahlp.go:479:19: undefined: VersionInfo
..\godror\godror\orahlp.go:480:19: undefined: VersionInfo
..\godror\godror\orahlp.go:481:30: undefined: ObjectType
..\godror\godror\orahlp.go:482:31: undefined: Event
..\godror\godror\orahlp.go:482:42: undefined: SubscriptionOption
..\godror\godror\orahlp.go:482:64: undefined: Subscription
..\godror\godror\orahlp.go:483:10: undefined: StartupMode
..\godror\godror\orahlp.go:484:11: undefined: ShutdownMode
..\godror\godror\orahlp.go:484:11: too many errors

Other than cross-compile, no problems in Windows or Linux platform. I have installed the newest version of Godror.

Select query format problem

Describe the bug
I would like to query data from table,but when I pass time format as parameter,it get wrong.
It will show

dpiStmt_execute: ORA-01841: (full) year must be between -4713 and +9999, and not be 0

If I write time format in sql directly, it runs normally.

To Reproduce
wrong sql:

SELECT
			name,
			to_char(time,:4),
		FROM
			table
		WHERE
                        AND time BETWEEN to_date(:2,'YYYY-MM-DD HH24:mi:ss') AND to_date(:3,'YYYY-MM-DD HH24:mi:ss')
		GROUP BY
			name
			to_char(time,:4)
		ORDER BY
			to_char(time,:4) ASC`, name, begin, end, timefmt)

runnable sql:

SELECT
			name,
			to_char(time,'YYYY-MM-DD HH24:mi:ss'),
		FROM
			table
		WHERE
                        AND time BETWEEN to_date(:2,'YYYY-MM-DD HH24:mi:ss') AND to_date(:3,'YYYY-MM-DD HH24:mi:ss')
		GROUP BY
			name
			to_char(time,'YYYY-MM-DD HH24:mi:ss')
		ORDER BY
			to_char(time,'YYYY-MM-DD HH24:mi:ss') ASC`, name, begin, end)

Expected behavior
like runnable sql's result

Your oracle client version
e.g. 18.4.0.0.0.0

Your godror version
e.g. v0.17.0

Your go version
e.g. 1.13.0

Your gcc version
e.g. 7.4.0

Machine (please complete the following information):

  • OS: ubuntu
  • Architecture x86-64
  • Version: 18.04

How to connect as sysdba

I want to connect as "/ as sysdba"

Can someone help me to draft the string.

I have already set ORACLE_SID and ORACLE_HOME

Tag a stable release to gopkg.in similar to how it was done for goracle.v2

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Select when a column is datatype TIMESTAMP WITH TIMEZONE not return rows in some cases

Describe the bug
Query not return rows when column with TIMESTAMP WITH TIMEZONE is setted like this:
cast(TO_TIMESTAMP_TZ('2018-02-15T14:00:00+01:00','yyyy-mm-dd"T"hh24:mi:ss"+"TZH:TZM') as date)

The rows are returned always when column is data type DATE, TIMESTAMP and TIMESTAMP WITH LOCAL TIMEZONE are setted with same cast

I though that this can be the same with this issue go-goracle/goracle#153 but I if the same then I think this cast will no return rows with data types that cause return rows

To Reproduce
Select a column with data type TIMESTAMP WITH TIMEZONE with this custom cast:
cast(TO_TIMESTAMP_TZ('2018-02-15T14:00:00+01:00','yyyy-mm-dd"T"hh24:mi:ss"+"TZH:TZM') as date)

Expected behavior
Return rows with the time

Your oracle client version
19.3.0.0.0

Your godror version
Tested with 0.9.1 and master commit e99fcf2

Your go version
1.13.5

Your gcc version
9.2.0

Machine (please complete the following information):

  • OS: Windows
  • Architecture x64
  • Version: 10

Additional context
Like issue mentioned, with FROM_TZ(TO_TIMESTAMP('0001-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'), '00:00') works. But this issue is to know why the cast not work with TIMESTAMP WITH TIMEZONE only.

CQN subscription callback not working in Docker

Describe the bug [this might be a feature request after all, please see the next post]
When running inside Docker, CQN subscription query registration seems to crash when the first change is triggered (but before the callback has a chance to run).

To Reproduce
Steps to reproduce the behavior:

  1. Register a QRCN query according to https://github.com/godror/godror/blob/master/z_qrcn_test.go
  2. Build a Docker image using
FROM golang AS build
WORKDIR /build
COPY go.* *.go ./
RUN go build -o main

FROM oraclelinux:7-slim
RUN yum -y -q install oracle-release-el7 && \
    yum-config-manager --enable ol7_oracle_instantclient >/dev/null && \
    yum -y -q install oracle-instantclient19.5-basic
COPY --from=build /build/main /
ENTRYPOINT ["/main"]
  1. Run the Docker image.
  2. Observe that the subscription query is registered successfully (no errors returned):
func printReg() {
	var regID, tableName string
	row := testDb.QueryRow("SELECT regid, table_name FROM USER_CHANGE_NOTIFICATION_REGS")
	row.Scan(&regID, &tableName)
	log.Println(regID, tableName)
}()
testDb.Exec("INSERT INTO test_subscr (i) VALUES (1)")
printReg()
  1. Observe that registration params were printed before the insert, and are missing after. No events are logged either, despite having a log statement in the callback.
  2. Compile and run the same code on macOS or RHEL (without Docker), observe that the events are received and the registration survives.

Expected behavior
Insertion event should be logged, and the registration should remain alive after the event is triggered.

Screenshots

Your oracle client version
19.5 (same issue with 18.3)

Your godror version
v0.9.1

Your go version
1.13.8

Your gcc version
8.3.0

Machine (please complete the following information):

  • OS: Oracle Linux 7 (same behavior on Debian) in a Docker on macOS 10.14.6 and Amazon Linux (AWS Fargate instance)
  • Architecture: x86_64

Additional context
As mentioned, I tried other base images (Debian) but the same behavior is observed.

Additionally, I tried CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build but that didn't help.

Finally, I tried both strace and DPI_DEBUG_LEVEL=100, but they don't reveal any messages/calls after the change is triggered (or maybe I didn't run those with proper options?).

So it appears as if the registration is just dropped silently. Is there any way to diagnose that?

EDIT: strace does show a lot of EAGAIN (Resource temporarily unavailable) and ETIMEDOUT (Connection timed out) before the insert, perhaps those are somehow relevant?

EDIT2: Attempting to re-register after the crash (using the same subscription) leads to

executeStmt: ORA-29970: Specified registration id does not exist

EDIT3: I re-ran the same image with Singularity on RHEL7 (i.e. not a "real" Docker), and to my surprise it worked! So this issue appears to be specific to Docker.

Implement NullTime

Is your feature request related to a problem? Please describe.
When a need to pass a date, timestamp, etc... from Oracle to other database, I need to check time.Time with IsZero() to pass nil to destination, but when Oracle date is 0001-01-01 00:00:00 in the table I need to pass the date but IsZero() is true and nil is assigned.

Describe the solution you'd like
Implementing NullTime can solve this.

Describe alternatives you've considered
IsZero() is a standard alternative but isn't perfect for all solutions like this.

Also, I saw that this mssql driver can return nil when a column is NULL, but I think is better NullTime because this solution, although use your own solution I think can be better, need a lot of work and use NullTime is faster implementation.

Cross compiling fails for 32bit architectures

Describe the bug
compiling for 32 bit architectures fails with folling error:
# github.com/godror/godror ..\github.com\godror\godror\conn.go:380:13: type [214748363]_Ctype_struct_dpiData larger than address space ..\github.com\godror\godror\conn.go:380:13: type [214748363]_Ctype_struct_dpiData too large ..\github.com\godror\godror\rows.go:292:19: type [214748363]_Ctype_struct_dpiData larger than address space ..\github.com\godror\godror\rows.go:292:19: type [214748363]_Ctype_struct_dpiData too large ..\github.com\godror\godror\stmt.go:410:22: type [214748363]_Ctype_struct_dpiData larger than address space ..\github.com\godror\godror\stmt.go:410:22: type [214748363]_Ctype_struct_dpiData too large ..\github.com\godror\godror\subscr.go:49:16: type [214748363]_Ctype_struct_dpiSubscrMessageRow too large ..\github.com\godror\godror\subscr.go:63:17: type [214748363]_Ctype_struct_dpiSubscrMessageTable too large ..\github.com\godror\godror\subscr.go:78:17: type [214748363]_Ctype_struct_dpiSubscrMessageQuery larger than address space ..\github.com\godror\godror\subscr.go:78:17: type [214748363]_Ctype_struct_dpiSubscrMessageQuery too large ..\github.com\godror\godror\subscr.go:78:17: too many errors

To Reproduce
compile your demo program in an 32bit environment, in Windows10 using msys2

  1. pacman -S mingw-w64-i686-toolchain
  2. install 32bit go: pacman -S mingw-w64-i686-go
  3. in mingw32 environment go to your source: cd /e/Daten/go/src/oracletest
  4. start build: go build

Expected behavior
proper compiling

Your oracle client version
12.2.0.1.0

Your godror version
v0.10.2

Your go version
go version go1.13.5 windows/386

Machine (please complete the following information):

  • OS: Windows10 mit mingw32
  • Architecture [64bit mit 32bit Wrapper]

gcc version
gcc -v
Using built-in specs.
COLLECT_GCC=E:\msys64\mingw32\bin\gcc.exe
COLLECT_LTO_WRAPPER=E:/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/9.2.0/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with: ../gcc-9.2.0/configure --prefix=/mingw32 --with-local-prefix=/mingw32/local --build=i686-w64-mingw32 --host=i686-w64-mingw32 --target=i686-w64-mingw32 --with-native-system-header-dir=/mingw32/i686-w64-mingw32/include --libexecdir=/mingw32/lib --enable-bootstrap --with-arch=i686 --with-tune=generic --enable-languages=c,lto,c++,fortran,ada,objc,obj-c++ --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts=yes --enable-libstdcxx-time=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --disable-isl-version-check --enable-lto --enable-libgomp --disable-multilib --enable-checking=release --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --enable-plugin --with-libiconv --with-system-zlib --with-gmp=/mingw32 --with-mpfr=/mingw32 --with-mpc=/mingw32 --with-isl=/mingw32 --with-pkgversion='Rev2, Built by MSYS2 project' --with-bugurl=https://sourceforge.net/projects/msys2 --with-gnu-as --with-gnu-ld --disable-sjlj-exceptions --with-dwarf2
Thread model: posix
gcc version 9.2.0 (Rev2, Built by MSYS2 project)

Additional context
None

Issue with DRCP: connection class is not being used (and purity cannot be set)

Hi,

Firstly, thank you for your outstanding library!

I am trying to test using an Oracle DB which has DRCP enabled. The connections are created but Oracle DB does not create them effectively - There are too many connections being created (v$cpool_cc_stats) with a cclass_name similar to DMPSSDEV.OCI:SP:mDy9YwLLADTgUwIAEawkuB (note the random string at the end)
instead of the connection class being specified.

I think I have identified the problem in the file drv.go line 441:

if err := c.acquireConn("", ""); err != nil { return nil, err }

The connCreateParams variable is not passed to acquireConn therefore empty values are passed down to the OCI wrapper. So, the connection class is never set!
Also, the purity parameter cannot be set and in the case of DRCP the correct value should be SELF instead of NEW otherwise the num_hits will be 0.

// purity values when acquiring a connection from a pool typedef uint32_t dpiPurity; #define DPI_PURITY_DEFAULT 0 #define DPI_PURITY_NEW 1 #define DPI_PURITY_SELF 2

drv.go line 429:

if P.ConnClass != "" { cConnClass := C.CString(P.ConnClass) defer C.free(unsafe.Pointer(cConnClass)) connCreateParams.connectionClass = cConnClass connCreateParams.connectionClassLength = C.uint32_t(len(P.ConnClass)) **connCreateParams.purity =2** }

Could you please let me know if my analysis is correct? If yes, could you please provide a fix?
Thank you,

DPI-1072: the Oracle Client library version is unsupported

Your oracle client version
tried instaclient oci.dll 11_2, 12_2, 18_5, 19_5

windows 10
godror version 0.10.4 (master)
go version go1.13.5 windows/amd64
gcc (Rev2, Built by MSYS2 project) 9.2.0

func init() {
	var err error
	db, err = sql.Open("godror", dbhost)
	if err != nil {
		panic("open: " + err.Error())
	}
	err = db.Ping()
	if err != nil {
		panic("ping: " + err.Error())
	}
}

Heterogeneous Pools are broken in v0.10.0

Heterogeneous Pools are broken in v1.10.0

To Reproduce

  1. go test -v -count=1 -run TestHeterogeneousPoolIntegration
  2. The test is blocked on
    === RUN TestHeterogeneousPoolIntegration/proxyUser

Expected behavior
Test pass

Your oracle client version
e.g. 18c-xe

Your godror version
e.g. v0.10.0

Your go version
e.g. 1.13.3

Your gcc version
e.g. 7.0.0

Machine (please complete the following information):

  • OS: Ubuntu
  • Architecture x86_64
  • Version: 18

conn.Raw introduced in golang 1.13

Describe the bug
Using go1.12.6 and go get with this package causes the following:
../github.com/godror/godror/orahlp.go:510:13: conn.Raw undefined (type *sql.Conn has no field or method Raw)

It appears conn.Raw was introduced in golang 1.13 according to the go docs.

To Reproduce
Steps to reproduce the behavior:

  1. Use golang version 1.12.6 (or presumably any version below 1.13 and at least 1.11)
  2. Run go get on a project with godror, using the latest godror version
  3. View error in console

Expected behavior
Go get does not error out when using godror with go1.11 or go1.12

Your oracle client version
18.1

Your godror version
v0.15.0

Your go version
1.12.6

Your gcc version
4.2.1

Machine (please complete the following information):

  • OS: MacOS
  • Architecture x86_64
  • Version: 10.14.6

Unable to locate Oracle Client Library when run as a systemd service

Describe the bug
I am using godror to get some views from an oracle database. When I run my program through commandline, it uses Oracle DB's own library files in $ORACLE_HOME environment variable. However when I run it as a service, it is unable to use ORACLE_HOME environment variable (which is expected behaviour of systemd) But after I explicitly set it as Environment=ORACLE_HOME=<...>, it still doesn't work.

I'm out of ideas on how to make it find the oracle client files when run as a service.

To Reproduce
Run a program that uses godror as a systemd service.

Expected behavior
For it to work as it works when I run it through bash

oracle client version : 11.2.0.2.0
godror version : v0.11.1
go version : 1.13.3
gcc version : 4.8.5

compiling machine

  • OS: [centos]
  • Architecture [x86_64]
  • Version: [7]

working machine

  • OS: [ubuntu]
  • Architecture [x86_64]
  • Version: [16.04]

Connect a Go Program to Oracle Database using godror

I followed the link below to try to connect to the Oracle Database 12.2 using go and reported an error:
Error running query
username="scott" dsn="orcl" params={authMode:0 connectionClass:0x28087c0 connectionClassLength:6 purity:0 newPassword: newPasswordLength:0 appContext: numAppContext:0 externalAuth:0 externalHandle: pool:0x2808820 tag: tagLength:0 matchAnyTag:0 outTag: outTagLength:0 outTagFound:0 shardingKeyColumns: numShardingKeyColumns:0 superShardingKeyColumns: numSuperShardingKeyColumns:0 outNewSession:0}: ORA-00000: DPI-1012: proxy authentication is not possible with homogeneous pools

Link:
https://blogs.oracle.com/developers/how-to-connect-a-go-program-to-oracle-database-using-goracle

go demo:
`package main

import (
"fmt"
"database/sql"
_ "github.com/godror/godror"
)

func main(){

db, err := sql.Open("godror", "scott/tiger@orcl")
if err != nil {
    fmt.Println(err)
    return
}
defer db.Close()
  
  
rows,err := db.Query("select sysdate from dual")
if err != nil {
    fmt.Println("Error running query")
    fmt.Println(err)
    return
}
defer rows.Close()

var thedate string
for rows.Next() {

    rows.Scan(&thedate)
}
fmt.Printf("The date is: %s\n", thedate)

}`

Oracle Client version:18.3.0.0.0
Oracle Database version: 12.2.0.1.0
godror version:v0.14.0
go version:1.14.2
gcc version:gcc-4.8.5-39.0.3.el7.x86_64

OS: Linux
Architecture:3.10.0-693.el7.x86_64
Version:Red Hat Enterprise Linux Server release 7.4 (Maipo)

Cannot select column of type 'sys.xmltype'

Describe the bug
I prepare a valid SQL statement string. I query. I attempt to read rows,

for rows.Next() {
...
}

However, the inside scope of the for loop never runs. Therefore the code never encounters the work of read+transform the sys.xmltype into GO's target type.

To Reproduce
// xmlColumn is of type 'sys.xmltype'
query := "select xmlColumn from xmlTable where id=123";
rows, err := oracle.Query(query)
if err!=nil {...}
// select xml column and cast to string
var xml string
for rows.Next() {
err = rows.Scan(&xml)
if err!=nil{...}
}
rows.Close()

Expected behavior
Either the xml column is selected as string, or Scan gives me an error. Neither happens now.

Screenshots
N/A

Your oracle client version
e.g. 12.2.0.1.0

Your godror version
e.g. v0.0.1

Your go version
e.g. 1.14.0

Your gcc version
e.g. 7.3.1

Machine (please complete the following information):

  • OS: Redhat Linux
  • Architecture amd x86_64
  • Version: 10

Additional context
I'm not sure if a Lob is needed here, however, as rows.Next() is always false, the inside of the loop is never encountered.

Oracle access regularly crash.

I'm runnin the app in a linux alpine container
To Reproduce

My app is pretty convoluted so I'll just put the stack trace here to see if it looks familiar:
`fatal: morestack on g0
SIGTRAP: trace trap
PC=0x467522 m=7 sigcode=128

goroutine 0 [idle]:
runtime.abort()
/usr/local/go/src/runtime/asm_amd64.s:840 +0x2
runtime.morestack()
/usr/local/go/src/runtime/asm_amd64.s:397 +0x25

goroutine 24 [syscall]:
runtime.cgocall(0x840810, 0xc000600370, 0x29)
/usr/local/go/src/runtime/cgocall.go:128 +0x5e fp=0xc000600338 sp=0xc000600300 pc=0x4136ce
git.tibco.com/git/product/ipaas/wi-dbservice.git/vendor/github.com/godror/godror._Cfunc_dpiPool_create(0x2d8ee80, 0x2d8eec0, 0x5, 0x2d8eee0, 0x9, 0x2d8ef00, 0x5a, 0xc0004c2240, 0xc0004c84b0, 0xc00000e058, ...)
_cgo_gotypes.go:3991 +0x50 fp=0xc000600370 sp=0xc000600338 pc=0x79b480
git.tibco.com/git/product/ipaas/wi-dbservice.git/vendor/github.com/godror/godror.(*drv).openConn.func5(0x2d8ee80, 0x2d8eec0, 0x5, 0x2d8eee0, 0x9, 0x2d8ef00, 0x5a, 0xc0004c2240, 0xc0004c84b0, 0xc00000e058, ...)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/vendor/github.com/godror/godror/drv.go:292 +0x1db fp=0xc0006003d8 sp=0xc000600370 pc=0x7c99bb
git.tibco.com/git/product/ipaas/wi-dbservice.git/vendor/github.com/godror/godror.(*drv).openConn(0xf3c6c0, 0x0, 0x0, 0x0, 0xc0001d79d0, 0x5, 0xc0001d79d6, 0x9, 0xc0001d79e0, 0x5a, ...)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/vendor/github.com/godror/godror/drv.go:292 +0x6b6 fp=0xc000600638 sp=0xc0006003d8 pc=0x7a4456
git.tibco.com/git/product/ipaas/wi-dbservice.git/vendor/github.com/godror/godror.connector.Connect(0xf3c6c0, 0x0, 0x0, 0x0, 0x0, 0xc0001d79d0, 0x5, 0xc0001d79d6, 0x9, 0xc0001d79e0, ...)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/vendor/github.com/godror/godror/drv.go:952 +0x6d fp=0xc000600728 sp=0xc000600638 pc=0x7ab4ed
git.tibco.com/git/product/ipaas/wi-dbservice.git/vendor/github.com/godror/godror.(*connector).Connect(0xc000328240, 0xa73040, 0xc00002c0e0, 0xd1, 0x207, 0xd1, 0x0)
:1 +0x95 fp=0xc000600820 sp=0xc000600728 pc=0x7ce815
database/sql.(*DB).conn(0xc000328300, 0xa73040, 0xc00002c0e0, 0x1, 0x0, 0xc000600a60, 0x47d4ba)
/usr/local/go/src/database/sql/sql.go:1177 +0x135 fp=0xc0006009d8 sp=0xc000600820 pc=0x6ea865
database/sql.(*DB).prepare(0xc000328300, 0xa73040, 0xc00002c0e0, 0xc0004b4510, 0x90, 0x1, 0xc000600ad0, 0x6af9ee, 0xc00009e140)
/usr/local/go/src/database/sql/sql.go:1380 +0x58 fp=0xc000600a58 sp=0xc0006009d8 pc=0x6ebf88
database/sql.(*DB).PrepareContext(0xc000328300, 0xa73040, 0xc00002c0e0, 0xc0004b4510, 0x90, 0xc000600e10, 0x1, 0x1)
/usr/local/go/src/database/sql/sql.go:1353 +0x9b fp=0xc000600ad0 sp=0xc000600a58 pc=0x6ebd2b
database/sql.(*DB).Prepare(0xc000328300, 0xc0004b4510, 0x90, 0x1, 0x1, 0x2)
/usr/local/go/src/database/sql/sql.go:1370 +0x57 fp=0xc000600b20 sp=0xc000600ad0 pc=0x6ebef7
git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/oracle.(*Connection).PreparedQuery(0xc0003ee2a0, 0x9c2727, 0x98, 0xc000601058, 0x0, 0x0, 0x0)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/oracle/oracle.go:358 +0x4e6 fp=0xc000600f20 sp=0xc000600b20 pc=0x7d8e86
git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/oracle.(*Connection).TableSchema(0xc0003ee2a0, 0xc0004623f0, 0x9, 0x0, 0x1007fedfa5976c0, 0x0)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/oracle/oracle.go:223 +0x24f fp=0xc0006012b8 sp=0xc000600f20 pc=0x7d795f
git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/evaluator.(*Evaluator).evalTableLiteral(0xc000603ab8, 0xc0004c21c0, 0x9, 0x0)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/evaluator/evaluator.go:1892 +0xfe fp=0xc0006013f0 sp=0xc0006012b8 pc=0x6cd40e
git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/evaluator.(*Evaluator).Eval(0xc000603ab8, 0xa6fd80, 0xc0004c21c0, 0xc0004ac2a0, 0xc0004c21c0, 0x0)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/evaluator/evaluator.go:275 +0x28e9 fp=0xc000601e38 sp=0xc0006013f0 pc=0x6b4369
git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/evaluator.(*Evaluator).Eval(0xc000603ab8, 0xa6f840, 0xc0004c82d0, 0xc0004ac2a0, 0xc0004c82d0, 0x203000)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/evaluator/evaluator.go:169 +0x31c8 fp=0xc000602880 sp=0xc000601e38 pc=0x6b4c48
git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/evaluator.(*Evaluator).evalSelectStatement(0xc000603ab8, 0xc000090820, 0xc0004ac260, 0x25, 0x0)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/evaluator/evaluator.go:1715 +0x37e fp=0xc000602e48 sp=0xc000602880 pc=0x6caa1e
git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/evaluator.(*Evaluator).evalSQLCommand(0xc000603ab8, 0xc0004ac200, 0xc0004ac260, 0xc0004feea0, 0x8223450d68e2b299)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/evaluator/evaluator.go:1085 +0x598 fp=0xc000602f68 sp=0xc000602e48 pc=0x6c2b78
git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/evaluator.(*Evaluator).Eval(0xc0005ddab8, 0xa6fcc0, 0xc0004ac200, 0xc0004ac260, 0x0, 0x0)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/evaluator/evaluator.go:46 +0x953 fp=0xc0006039b0 sp=0xc000602f68 pc=0x6b23d3
git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice.(*DBService).schema(0xc0005cc710, 0xc000446570, 0x26, 0xa74720, 0xc0003ee2a0, 0xc0003ee2a0, 0x0, 0x0)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/dbservice.go:282 +0x2a7 fp=0xc000603ae0 sp=0xc0006039b0 pc=0x818c37
git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice.(*DBService).Schema(0xc0005cc710, 0xa72d00, 0xc0003ee000, 0xc000156300)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice/dbservice.go:241 +0x1c8 fp=0xc000603c40 sp=0xc000603ae0 pc=0x8183a8
git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/dbservice.(*DBService).Schema-fm(0xa72d00, 0xc0003ee000, 0xc000156300)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/main.go:53 +0x48 fp=0xc000603c70 sp=0xc000603c40 pc=0x81b778
net/http.HandlerFunc.ServeHTTP(0xc0005cc750, 0xa72d00, 0xc0003ee000, 0xc000156300)
/usr/local/go/src/net/http/server.go:1964 +0x44 fp=0xc000603c98 sp=0xc000603c70 pc=0x63d1a4
main.corsHandle.func1(0xa72d00, 0xc0003ee000, 0xc000156300)
/gotmp/src/git.tibco.com/git/product/ipaas/wi-dbservice.git/dbs/main.go:73 +0xa7 fp=0xc000603ce0 sp=0xc000603c98 pc=0x81b577
net/http.HandlerFunc.ServeHTTP(0xc0005ce360, 0xa72d00, 0xc0003ee000, 0xc000156300)
/usr/local/go/src/net/http/server.go:1964 +0x44 fp=0xc000603d08 sp=0xc000603ce0 pc=0x63d1a4
net/http.(*ServeMux).ServeHTTP(0xf3c540, 0xa72d00, 0xc0003ee000, 0xc000156300)
/usr/local/go/src/net/http/server.go:2361 +0x127 fp=0xc000603d48 sp=0xc000603d08 pc=0x63ee57
net/http.serverHandler.ServeHTTP(0xc000091110, 0xa72d00, 0xc0003ee000, 0xc000156300)
/usr/local/go/src/net/http/server.go:2741 +0xab fp=0xc000603d78 sp=0xc000603d48 pc=0x63f90b
net/http.(*conn).serve(0xc0004103c0, 0xa73000, 0xc0004c2000)
/usr/local/go/src/net/http/server.go:1847 +0x646 fp=0xc000603fc8 sp=0xc000603d78 pc=0x63c3f6
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000603fd0 sp=0xc000603fc8 pc=0x467bd1
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2851 +0x2f5
`
The database is oracle 12 xe. The client is 19.1
GO is: go version go1.11.4 linux/amd64

Godror version:
fbfd5ce vendor/github.com/godror/godror (v0.13.1-5-gfbfd5ce)

GCC: gcc version 8.2.0 (Alpine 8.2.0)

Running in an alpine container but I don't know what version of alpine. If someone knows how to get that from a running container or its source image I'll include it here.

The host os is Ubuntu 18.1 server x86_64

I can get this stacktrace with something as simple as db.ping() which leads me to suspect that the alpine libraries may be the problem because I don't see this when just running the driver on my desktop. At least I don't think so. I don't have many tests that do that.
Any ideas?

Errors compiling the latest version of the library

Describe the bug
Errors compiling the latest version of the library.
With version v0.10.4 everything was fine

To Reproduce
Steps to reproduce the behavior:

  1. go get github.com/godror/godror
  2. or add 'github.com/godror/godror v0.11.0' to go.mod file

Expected behavior
Compilation without errors

Your oracle client version
12.2.0.1.0

Your godror version
v0.11.0

Your go version
go1.12.10 linux/amd64

Your gcc version
9.2.1 20191008 (Ubuntu 9.2.1-9ubuntu2)

Machine (please complete the following information):

  • OS: Ubuntu
  • Architecture amd64
  • Version: 19.10

Additional context
The errors that I get:

github.com/godror/godror

../../../../go/pkg/mod/github.com/godror/[email protected]/stmt_go11.go:11:2: imported and not used: "database/sql"
../../../../go/pkg/mod/github.com/godror/[email protected]/stmt_go11.go:32:15: n.Time.Scan undefined (type time.Time has no field or method Scan)
../../../../go/pkg/mod/github.com/godror/[email protected]/stmt_go11.go:38:28: undefined: driver

IN OUT sql.NullString parameter returns []byte instead of sql.NullString

Describe the bug
We have PL/SQL function with IN OUT VARCHAR2 parameter.
In ExecContext we're sending it as
sql.Out{Dest: &sql.NullString{Valid:false, String:""}, In: true}
and getting the following error:
22. get[0]: awaited []byte/string/Number, got *sql.NullString (&sql.NullString{String:"", Valid:true})
And we noticed that bindVarTypeSwitch function in stmt.go doesn't have any handler for sql.NullString type.

To Reproduce
Steps to reproduce the behavior:
Try to call PL/SQL function with VARCHAR2 IN OUT parameter.

Expected behavior
ExecContext executed without any errors.

Your oracle client version
19.6.0.0.0

Your godror version
e.g. v0.14.0

Your go version
e.g. 1.13.5

Your gcc version
e.g. 5.1.0

Machine (please complete the following information):

  • OS: Windows
  • Architecture: x64
  • Version: 10

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.