@@ -695,24 +695,44 @@ int dpiConn__getServerVersion(dpiConn *conn, int wantReleaseString,
695695 dpiError * error )
696696{
697697 char buffer [512 ], * releaseString ;
698+ dpiVersionInfo * tempVersionInfo ;
698699 uint32_t serverRelease , mode ;
699700 uint32_t releaseStringLength ;
701+ int ociCanCache ;
700702
701703 // nothing to do if the server version has been cached earlier
702704 if (conn -> releaseString ||
703705 (conn -> versionInfo .versionNum > 0 && !wantReleaseString ))
704706 return DPI_SUCCESS ;
705707
706- // the server version is not available in the cache so a call is required
707- // to get it; as of Oracle Client 20.3, a special mode is available that
708- // causes OCI to cache server version information; this mode can be used
709- // exclusively once 20.3 is the minimum version supported by ODPI-C; until
710- // that time, since ODPI-C already caches server version information
711- // itself, this mode is only used when the release string is not requested,
712- // in order to avoid the round-trip in that particular case
713- if ((conn -> env -> versionInfo -> versionNum > 20 ||
708+ // the server version is not available in the cache so it must be
709+ // determined; as of Oracle Client 20.3, a special mode is available that
710+ // causes OCI to cache the server version information, so this mode can be
711+ // used if the release string information is not desired and the client
712+ // supports it
713+ ociCanCache = ((conn -> env -> versionInfo -> versionNum > 20 ||
714714 (conn -> env -> versionInfo -> versionNum == 20 &&
715- conn -> env -> versionInfo -> releaseNum >= 3 )) && !wantReleaseString ) {
715+ conn -> env -> versionInfo -> releaseNum >= 3 )) && !wantReleaseString );
716+
717+ // for earlier versions where the OCI cache is not available, pooled
718+ // connections can cache the information on the session in order to avoid
719+ // the round trip, but again only if the release string is not desired;
720+ // nothing further needs to be done if this cache is present
721+ if (conn -> pool && !ociCanCache && !wantReleaseString ) {
722+ tempVersionInfo = NULL ;
723+ if (dpiOci__contextGetValue (conn , DPI_CONTEXT_SERVER_VERSION ,
724+ (uint32_t ) (sizeof (DPI_CONTEXT_SERVER_VERSION ) - 1 ),
725+ (void * * ) & tempVersionInfo , 1 , error ) < 0 )
726+ return DPI_FAILURE ;
727+ if (tempVersionInfo ) {
728+ memcpy (& conn -> versionInfo , tempVersionInfo ,
729+ sizeof (conn -> versionInfo ));
730+ return DPI_SUCCESS ;
731+ }
732+ }
733+
734+ // calculate the server version by making the appropriate call
735+ if (ociCanCache ) {
716736 mode = DPI_OCI_SRVRELEASE2_CACHED ;
717737 releaseString = NULL ;
718738 releaseStringLength = 0 ;
@@ -756,6 +776,21 @@ int dpiConn__getServerVersion(dpiConn *conn, int wantReleaseString,
756776 conn -> versionInfo .portReleaseNum ,
757777 conn -> versionInfo .portUpdateNum );
758778
779+ // for earlier versions where the OCI cache is not available, store the
780+ // version information on the session in order to avoid the round-trip the
781+ // next time the pooled session is acquired from the pool
782+ if (conn -> pool && !ociCanCache ) {
783+ if (dpiOci__memoryAlloc (conn , (void * * ) & tempVersionInfo ,
784+ sizeof (conn -> versionInfo ), 1 , error ) < 0 )
785+ return DPI_FAILURE ;
786+ memcpy (tempVersionInfo , & conn -> versionInfo , sizeof (conn -> versionInfo ));
787+ if (dpiOci__contextSetValue (conn , DPI_CONTEXT_SERVER_VERSION ,
788+ (uint32_t ) (sizeof (DPI_CONTEXT_SERVER_VERSION ) - 1 ),
789+ tempVersionInfo , 1 , error ) < 0 ) {
790+ dpiOci__memoryFree (conn , tempVersionInfo , error );
791+ }
792+ }
793+
759794 return DPI_SUCCESS ;
760795}
761796
0 commit comments