Skip to content

Commit c555d02

Browse files
committed
Work on query buffer space optimization
1 parent 9675ffe commit c555d02

File tree

7 files changed

+129
-79
lines changed

7 files changed

+129
-79
lines changed

src/dpi/include/dpiConn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class Conn
6363
// properties
6464
virtual void stmtCacheSize(unsigned int stmtCacheSize) = 0;
6565
virtual unsigned int stmtCacheSize() const = 0;
66+
virtual int getByteExpansionRation () = 0;
6667

6768
virtual void lobPrefetchSize(unsigned int lobPrefetchSize) = 0;
6869
virtual unsigned int lobPrefetchSize() const = 0;

src/dpi/include/dpiEnv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
# include <dpiConn.h>
4242
#endif
4343

44+
#define DPI_AL32UTF8 873
4445

4546
using std::string;
4647

src/dpi/src/dpiConnImpl.cpp

Lines changed: 105 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -84,45 +84,10 @@ try : env_(env), pool_(NULL),
8484
envh_(envh), errh_(NULL), auth_(NULL), svch_(NULL), sessh_(NULL),
8585
hasTxn_(false)
8686
{
87-
ub4 mode = externalAuth ? OCI_SESSGET_CREDEXT : OCI_DEFAULT;
8887

89-
ociCallEnv(OCIHandleAlloc((void *)envh_, (dvoid **)&errh_,
90-
OCI_HTYPE_ERROR, 0, (dvoid **)0), envh_);
91-
92-
ociCallEnv(OCIHandleAlloc((void *)envh_, (dvoid **)&auth_,
93-
OCI_HTYPE_AUTHINFO, 0, (dvoid **)0), envh_);
94-
95-
if (externalAuth)
96-
{
97-
if (password.length() || user.length())
98-
throw ExceptionImpl(DpiErrExtAuth);
99-
}
100-
else
101-
{
102-
ociCall(OCIAttrSet((void *)auth_, OCI_HTYPE_AUTHINFO,
103-
(void *)user.data(), (ub4) user.length(),
104-
OCI_ATTR_USERNAME, errh_), errh_);
105-
106-
ociCall(OCIAttrSet((void *)auth_, OCI_HTYPE_AUTHINFO,
107-
(void *)password.data(), (ub4) password.length(),
108-
OCI_ATTR_PASSWORD, errh_), errh_);
109-
}
110-
111-
// If connection class provided, set it on auth handle
112-
if (connClass.length() )
113-
{
114-
ociCall (OCIAttrSet ((void*)auth_, OCI_HTYPE_AUTHINFO,
115-
(void *)connClass.data(), (ub4) connClass.length(),
116-
OCI_ATTR_CONNECTION_CLASS, errh_), errh_);
117-
}
118-
119-
ociCall(OCISessionGet(envh_, errh_, &svch_, auth_,
120-
(OraText *)connString.data(),
121-
(ub4) connString.length(), NULL, 0, NULL, NULL, NULL,
122-
mode), errh_);
123-
124-
ociCall(OCIAttrGet(svch_, OCI_HTYPE_SVCCTX, &sessh_, 0,
125-
OCI_ATTR_SESSION, errh_),errh_);
88+
this->initConnImpl ( false, externalAuth, connClass,
89+
( OraText * ) connString.data (),
90+
( ub4 ) connString.length (), user, password );
12691

12792
this->stmtCacheSize(stmtCacheSize);
12893
}
@@ -133,8 +98,6 @@ catch (...)
13398
throw;
13499
}
135100

136-
137-
138101
/*****************************************************************************/
139102
/*
140103
DESCRIPTION
@@ -163,28 +126,8 @@ try : env_(NULL), pool_(pool),
163126
envh_(envh), errh_(NULL), auth_(NULL),
164127
svch_(NULL), sessh_(NULL), hasTxn_(false)
165128
{
166-
ub4 mode = externalAuth ? (OCI_SESSGET_CREDEXT | OCI_SESSGET_SPOOL) :
167-
OCI_SESSGET_SPOOL;
168-
ociCallEnv(OCIHandleAlloc((void *)envh_, (dvoid **)&errh_,
169-
OCI_HTYPE_ERROR, 0, (dvoid **)0), envh_);
170-
ociCallEnv(OCIHandleAlloc((void *)envh_, (dvoid **)&auth_,
171-
OCI_HTYPE_AUTHINFO, 0, (dvoid **)0), envh_);
172-
173-
// If connection class provided, set it on auth handle
174-
if (connClass.length() )
175-
{
176-
ociCall (OCIAttrSet ((void*)auth_, OCI_HTYPE_AUTHINFO,
177-
(void *)connClass.data(), (ub4) connClass.length(),
178-
OCI_ATTR_CONNECTION_CLASS, errh_), errh_);
179-
}
180-
181-
ociCall(OCISessionGet(envh_, errh_, &svch_, auth_,
182-
poolName, poolNameLen,
183-
NULL, 0, NULL, NULL, NULL,
184-
mode), errh_);
185-
186-
ociCall(OCIAttrGet(svch_, OCI_HTYPE_SVCCTX, &sessh_, 0, OCI_ATTR_SESSION,
187-
errh_), errh_);
129+
this->initConnImpl ( true, externalAuth, connClass, poolName, poolNameLen,
130+
"", "" );
188131
}
189132

190133
catch (...)
@@ -292,6 +235,21 @@ void ConnImpl::stmtCacheSize(unsigned int stmtCacheSize)
292235
}
293236

294237

238+
/*****************************************************************************/
239+
/*
240+
DESCRIPTION
241+
Get the DBCHARSET ID
242+
243+
PARAMETERS:
244+
-NONE-
245+
246+
RETURNS:
247+
Byte expansion ratio (int)
248+
*/
249+
int ConnImpl::getByteExpansionRation ()
250+
{
251+
return lxgratio_;
252+
}
295253

296254
/*****************************************************************************/
297255
/*
@@ -522,6 +480,91 @@ void ConnImpl::breakExecution()
522480
PRIVATE METHODS
523481
---------------------------------------------------------------------------*/
524482

483+
/*****************************************************************************/
484+
/*
485+
DESCRIPTION
486+
Constructor for the ConnImpl class created from an Env object.
487+
488+
PARAMETERS:
489+
pool - This flag says whether pool scenario or not
490+
externalAuth - flag for externalAuth
491+
connClass - connClass name
492+
poolNmRconnStr - poolName or connectString
493+
user - userid in case of non-pool scenario
494+
password - password in case of non-pool scenario
495+
496+
RETURNS:
497+
nothing
498+
*/
499+
500+
void ConnImpl::initConnImpl ( bool pool, bool externalAuth,
501+
const string& connClass, OraText *poolNmRconnStr,
502+
ub4 nameLen, const string &user, const string &password )
503+
{
504+
OCIServer *srvh = NULL;
505+
ub4 mode = 0;
506+
ub2 csid_ = 0;
507+
508+
if ( pool )
509+
mode = externalAuth ? ( OCI_SESSGET_CREDEXT | OCI_SESSGET_SPOOL ) :
510+
OCI_SESSGET_SPOOL;
511+
else
512+
mode = externalAuth ? OCI_SESSGET_CREDEXT : OCI_DEFAULT;
513+
514+
ociCallEnv ( OCIHandleAlloc ( ( void * ) envh_, ( dvoid ** )&errh_,
515+
OCI_HTYPE_ERROR, 0, ( dvoid ** ) 0 ), envh_ );
516+
517+
ociCallEnv ( OCIHandleAlloc ( ( void * ) envh_, ( dvoid ** ) &auth_,
518+
OCI_HTYPE_AUTHINFO, 0, ( dvoid ** ) 0 ),
519+
envh_ );
520+
521+
if ( externalAuth && ( !pool ) )
522+
{
523+
if ( password.length () || user.length () )
524+
throw ExceptionImpl ( DpiErrExtAuth );
525+
}
526+
527+
if ( !pool )
528+
{
529+
ociCall ( OCIAttrSet ( ( void * ) auth_, OCI_HTYPE_AUTHINFO,
530+
( void * ) user.data (), ( ub4 ) user.length (),
531+
OCI_ATTR_USERNAME, errh_ ), errh_ );
532+
533+
ociCall ( OCIAttrSet ( ( void * ) auth_, OCI_HTYPE_AUTHINFO,
534+
( void * ) password.data (),
535+
( ub4 ) password.length (),
536+
OCI_ATTR_PASSWORD, errh_ ), errh_ );
537+
}
538+
539+
// If connection class provided, set it on auth handle
540+
if ( connClass.length () )
541+
{
542+
ociCall ( OCIAttrSet ( ( void* ) auth_, OCI_HTYPE_AUTHINFO,
543+
( void * ) connClass.data (),
544+
( ub4 ) connClass.length (),
545+
OCI_ATTR_CONNECTION_CLASS, errh_ ), errh_ );
546+
}
547+
548+
ociCall ( OCISessionGet ( envh_, errh_, &svch_, auth_, poolNmRconnStr,
549+
( ub4 ) nameLen, NULL, 0, NULL, NULL, NULL,
550+
mode ), errh_ );
551+
552+
ociCall ( OCIAttrGet ( svch_, OCI_HTYPE_SVCCTX, &sessh_, 0,
553+
OCI_ATTR_SESSION, errh_ ), errh_ );
554+
555+
// Initialize the server handle from service handle
556+
ociCall ( OCIAttrGet ( svch_, OCI_HTYPE_SVCCTX, ( void * ) &srvh, 0,
557+
( ub4 ) OCI_ATTR_SERVER, errh_ ), errh_ );
558+
559+
// Get the DBCHARSET from server
560+
ociCall ( OCIAttrGet ( srvh, ( ub4 ) OCI_HTYPE_SERVER, ( void * ) &csid_,
561+
( ub4 * ) 0, ( ub4 ) OCI_ATTR_CHARSET_ID, errh_ ),
562+
errh_ );
563+
if ( csid_ == DPI_AL32UTF8 )
564+
lxgratio_ = 1;
565+
else
566+
lxgratio_ = 3;
567+
}
525568

526569
/*****************************************************************************/
527570
/*

src/dpi/src/dpiConnImpl.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ class ConnImpl : public Conn
8989
virtual void module(const string &module);
9090

9191
virtual void action(const string &action);
92+
virtual int getByteExpansionRation ();
9293

93-
94-
// interface methods
94+
// interface methods
9595
virtual Stmt* getStmt(const string &sql);
9696

9797
virtual void releaseStmt(Stmt *stmt);
@@ -121,6 +121,9 @@ class ConnImpl : public Conn
121121

122122
private:
123123

124+
void initConnImpl( bool pool, bool externalAuth, const string& connClass,
125+
OraText *poolNmRconnStr, ub4 nameLen,
126+
const string &user, const string &password );
124127
void cleanup();
125128

126129

@@ -133,6 +136,7 @@ class ConnImpl : public Conn
133136
OCISvcCtx *svch_; // OCI service handle
134137
OCISession *sessh_; // OCI Session handle. Do not free this.
135138
boolean hasTxn_; // set if transaction is in progress
139+
int lxgratio_; // Caches DBCharset ID
136140
};
137141

138142

src/dpi/src/dpiEnvImpl.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,6 @@ static const int kStmtCacheSize = 60;
9393
9494
*/
9595

96-
#ifndef NJS_AL32UTF8
97-
#define NJS_AL32UTF8 873
98-
#endif /* NJS_AL32UTF8 */
99-
10096
EnvImpl::EnvImpl()
10197

10298
try : envh_(NULL), poolMax_(kPoolMax), poolMin_(kPoolMin),
@@ -105,7 +101,7 @@ try : envh_(NULL), poolMax_(kPoolMax), poolMin_(kPoolMin),
105101
{
106102

107103
sword rc = OCIEnvNlsCreate (&envh_, OCI_THREADED | OCI_OBJECT, NULL, NULL,
108-
NULL, NULL, 0, NULL, NJS_AL32UTF8, NJS_AL32UTF8);
104+
NULL, NULL, 0, NULL, DPI_AL32UTF8, DPI_AL32UTF8);
109105

110106
if (rc)
111107
{

src/njs/src/njsConnection.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,6 @@ Persistent<FunctionTemplate> Connection::connectionTemplate_s;
6868
// number of rows prefetched by non-ResultSet queries
6969
#define NJS_PREFETCH_NON_RESULTSET 2
7070

71-
// max byte size for a AL32UTF8 char is 4
72-
#define NJS_CHAR_CONVERSION_RATIO 4
73-
7471
#define NJS_SIZE_T_MAX std::numeric_limits<std::size_t>::max()
7572

7673
#define NJS_SIZE_T_OVERFLOW(maxSize,maxRows) \
@@ -743,6 +740,13 @@ void Connection::GetInBindParams (Handle<Value> v8val, Bind* bind,
743740
if(size)
744741
{
745742
bind->value = (char*)malloc((size_t)size);
743+
if( !bind->value )
744+
{
745+
executeBaton->error = NJSMessages::getErrorMsg(
746+
errInsufficientMemory );
747+
return;
748+
}
749+
746750
if(str.length())
747751
memcpy(bind->value, *str, str.length());
748752
}
@@ -1366,6 +1370,7 @@ void Connection::DoDefines ( eBaton* executeBaton, const dpi::MetaData* meta,
13661370
unsigned int numCols )
13671371
{
13681372
Define *defines = executeBaton->defines = new Define[numCols];
1373+
int lxgratio = executeBaton->dpiconn->getByteExpansionRation ();
13691374

13701375
for (unsigned int col = 0; col < numCols; col++)
13711376
{
@@ -1381,8 +1386,6 @@ void Connection::DoDefines ( eBaton* executeBaton, const dpi::MetaData* meta,
13811386
defines[col].maxSize = ( defines[col].fetchType == dpi::DpiVarChar) ?
13821387
NJS_MAX_FETCH_AS_STRING_SIZE : sizeof (double);
13831388

1384-
defines[col].maxSize = sizeof(double);
1385-
13861389
if ( NJS_SIZE_T_OVERFLOW ( defines[col].maxSize,
13871390
executeBaton->maxRows ) )
13881391
{
@@ -1409,12 +1412,14 @@ void Connection::DoDefines ( eBaton* executeBaton, const dpi::MetaData* meta,
14091412
executeBaton->columnNames[col],
14101413
meta[col].dbType );
14111414
/*
1412-
* For fetching non-ascii/utf8 characters, it may take up to
1413-
* four times the buffer size on DB
1414-
* TODO: optimize ratio when DB character set is already UTF8
1415+
* While fetching non-ascii characters, each byte on the server
1416+
* can take upto maximum of 3 bytes when it converted to AL32UTF8
1417+
* because the client character set is always set to AL32UTF8
1418+
* in node-oracledb. If server has AL32UTF8 then ratio is 1.
14151419
*/
14161420

1417-
defines[col].maxSize = (meta[col].dbSize) * NJS_CHAR_CONVERSION_RATIO;
1421+
defines[col].maxSize = (meta[col].dbSize) * lxgratio;
1422+
14181423

14191424
if ( NJS_SIZE_T_OVERFLOW ( defines[col].maxSize,
14201425
executeBaton->maxRows ) )

src/njs/src/njsMessages.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static const char *errMsg[] =
5959
"NJS-022: invalid LOB",
6060
"NJS-023: concurrent operations on LOB are not allowed",
6161
"NJS-024: memory allocation failed",
62-
"NJS-025: results area too large to allocate memory"
62+
"NJS-025: overflow when calculating results area size"
6363
};
6464

6565
string NJSMessages::getErrorMsg ( NJSErrorType err, ... )

0 commit comments

Comments
 (0)