Skip to content

Commit c884b29

Browse files
committed
readlob with length and offset
1 parent 1d60dad commit c884b29

File tree

9 files changed

+305
-59
lines changed

9 files changed

+305
-59
lines changed

src/rwl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*
1414
* History
1515
*
16+
* johnkenn 18-dec-2023 - Lob size and offset for streaming
1617
* bengsig 9-nov-2023 - Increase RWL_MAX_VAR
1718
* johnkenn 02-nov-2023 - trignometry sin, cos, atan2
1819
* bengsig 3-oct-2023 - Now development for 3.1.1
@@ -858,6 +859,12 @@ struct rwl_main
858859
sb4 filvarn; /* fine variable number for write/writeline */
859860
text *lobnam; /* LOB variable name for readlob/rwitelob */
860861
sb4 lobvarn; /* LOB variable number for readlob/rwitelob */
862+
text *lobwritenam;
863+
sb4 lobwritevarn;
864+
text *loblengthnam;
865+
sb4 loblengthvarn;
866+
rwl_estack *loboffset; /* LOB offset to start at for data stream */
867+
861868
rwl_sql *sqsav; /* temporary save of sql */
862869
sb4 sqsavvarn; // and its variable number
863870
rwl_cinfo *dbsav; /* temporary save of db (cinfo) used during database declaration */
@@ -1493,6 +1500,7 @@ enum rwl_code_t
14931500
, RWL_CODE_GETRUSAGE // call rwlgetrusage - no args
14941501
, RWL_CODE_RETURN // return statement - ceptr1/ceint2 is name/guess of procedure/function where return is from
14951502
, RWL_CODE_READLOB // Read a LOB into a string - ceptr1/ceint2 is name/guess of LOB, ceptr3/ceint4 of string variable
1503+
, RWL_CODE_READLOB_LO // Read a LOB into a string with offset and read length - ceptr5 of int - ceptr of int
14961504
, RWL_CODE_WRITELOB // Write a LOB from an expression - ceptr1/ceint2 is name/guess of LOB, ceptr3 is rwl_estack* to write to it
14971505
// control control block execution does not nest
14981506
, RWL_CODE_CBLOCK_BEG // Begin of control block - no arguments
@@ -1698,6 +1706,7 @@ extern void rwlcodeadd(rwl_main *, rwl_code_t, void *, ub4 , void *, ub4, void *
16981706
* - a u means an ub4 (well, it really is sb4)
16991707
* - x means ignored arg
17001708
*/
1709+
#define rwlcodeaddpupupup(rwlp,ctype,parg1,arg2,parg3,arg4,parg5,arg6,parg7) rwlcodeadd(rwlp,ctype,parg1,arg2,parg3,arg4,parg5,arg6,parg7)
17011710
#define rwlcodeaddpupupu(rwlp,ctype,parg1,arg2,parg3,arg4,parg5,arg6) rwlcodeadd(rwlp,ctype,parg1,arg2,parg3,arg4,parg5,arg6,0)
17021711
#define rwlcodeaddpuppp(rwlp,ctype,parg1,arg2,parg3,parg5,parg7) rwlcodeadd(rwlp,(ctype),parg1,arg2,parg3,0,parg5,0,parg7)
17031712
#define rwlcodeaddpupp(rwlp,ctype,parg1,arg2,parg3,parg5) rwlcodeadd(rwlp,ctype,parg1,arg2,parg3,0,parg5,0,0)
@@ -1834,6 +1843,7 @@ extern void rwlalloclob(rwl_xeqenv *, rwl_location *, OCILobLocator **);
18341843
extern void rwlfreelob(rwl_xeqenv *, rwl_location *, OCILobLocator *);
18351844
extern void rwlwritelob(rwl_xeqenv *, OCILobLocator *, rwl_cinfo *, rwl_value *, rwl_location *, text *);
18361845
extern void rwlreadlob(rwl_xeqenv *, OCILobLocator *, rwl_cinfo *, rwl_value *, rwl_location *, text *);
1846+
extern void rwlreadloblo(rwl_xeqenv *, OCILobLocator *, rwl_cinfo *, rwl_value *, rwl_value *, ub8, rwl_location *, text *);
18371847
extern void rwldummyonbad(rwl_xeqenv *, text *); // Use dummy database if default is bad
18381848
extern ub4 rwldebugconv(rwl_main *,text *);
18391849

src/rwlcodeadd.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*
1414
* History
1515
*
16+
* johnkenn 18-dec-2023 - readlob length offset
1617
* bengsig 20-sep-2023 - list iterator loop
1718
* bengsig 10-aug-2023 - session pool timeout then action
1819
* bengsig 15-may-2023 - statisticsonly, incorrect RWL-239
@@ -132,6 +133,7 @@ void rwlcodeadd(rwl_main *rwm, rwl_code_t ctype, void *parg1
132133
case RWL_CODE_DYNSREL: rwm->code[rwm->ccount].cname = "dqrel"; break;
133134
case RWL_CODE_DYNBINDEF: rwm->code[rwm->ccount].cname = "dqbd"; break;
134135
case RWL_CODE_READLOB: rwm->code[rwm->ccount].cname = "rdlob"; break;
136+
case RWL_CODE_READLOB_LO: rwm->code[rwm->ccount].cname = "rdloblo"; break;
135137
case RWL_CODE_WRITELOB: rwm->code[rwm->ccount].cname = "wrlob"; break;
136138
case RWL_CODE_REGEX: rwm->code[rwm->ccount].cname = "regex"; break;
137139
case RWL_CODE_REGEXTRACT: rwm->code[rwm->ccount].cname = "reext"; break;
@@ -613,7 +615,16 @@ void rwlcodeadd(rwl_main *rwm, rwl_code_t ctype, void *parg1
613615
rwm->code[rwm->ccount].ceint2 = (sb4) arg2; // guess of lob var#
614616
rwm->code[rwm->ccount].ceptr3 = parg3; // string name
615617
rwm->code[rwm->ccount].ceint4 = (sb4) arg4; // guess of string var#
616-
rwm->code[rwm->ccount].ceptr5 = parg5; // codename
618+
break;
619+
620+
case RWL_CODE_READLOB_LO:
621+
rwm->code[rwm->ccount].ceptr1 = parg1; // lob name
622+
rwm->code[rwm->ccount].ceint2 = (sb4) arg2; // guess of lob var#
623+
rwm->code[rwm->ccount].ceptr3 = parg3; // string name
624+
rwm->code[rwm->ccount].ceint4 = (sb4) arg4; // guess of string var#
625+
rwm->code[rwm->ccount].ceptr5 = parg5; // int name
626+
rwm->code[rwm->ccount].ceint6 = (sb4) arg6; // guess of int var#
627+
rwm->code[rwm->ccount].ceptr7 = parg7; // expression
617628
break;
618629

619630
case RWL_CODE_WRITELOB:

src/rwlcoderun.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*
1515
* History
1616
*
17+
* johnkenn 18-dec-2023 - Add lobstreaming to readlob
1718
* bengsig 25-sep-2023 - fix if doublevar then
1819
* bengsig 22-sep-2023 - ampersand needs thread local sql
1920
* bengsig 20-sep-2023 - list iterator loop
@@ -1145,6 +1146,7 @@ void *rwlcoderun ( rwl_xeqenv *xev)
11451146
// and the string
11461147
l2 = rwlfindvarug2(xev, xev->rwm->code[pc].ceptr3, &xev->rwm->code[pc].ceint4
11471148
, codename);
1149+
11481150
/*assert*/
11491151
if (xev->evar[l].vtype != RWL_TYPE_CLOB
11501152
&& xev->evar[l].vtype != RWL_TYPE_BLOB)
@@ -1171,6 +1173,58 @@ void *rwlcoderun ( rwl_xeqenv *xev)
11711173
}
11721174
break;
11731175

1176+
case RWL_CODE_READLOB_LO:
1177+
{
1178+
sb4 l, l2, l3;
1179+
if (bit(xev->rwm->mflags, RWL_DEBUG_EXECUTE))
1180+
rwldebug(xev->rwm, "pc=%d executing readlob_lo", pc);
1181+
// find the LOB
1182+
l = rwlfindvarug2(xev, xev->rwm->code[pc].ceptr1, &xev->rwm->code[pc].ceint2
1183+
, codename);
1184+
// and the string
1185+
l2 = rwlfindvarug2(xev, xev->rwm->code[pc].ceptr3, &xev->rwm->code[pc].ceint4
1186+
, codename);
1187+
// and the length int
1188+
l3 = rwlfindvarug2(xev, xev->rwm->code[pc].ceptr5, &xev->rwm->code[pc].ceint6
1189+
, codename);
1190+
/* evaluate the offset expression */
1191+
rwlexpreval(xev->rwm->code[pc].ceptr7, &xev->rwm->code[pc].cloc, xev, &xev->xqnum);
1192+
/*assert*/
1193+
if (xev->evar[l].vtype != RWL_TYPE_CLOB
1194+
&& xev->evar[l].vtype != RWL_TYPE_BLOB)
1195+
{
1196+
rwlexecsevere(xev, &xev->rwm->code[pc].cloc
1197+
, "[rwlcoderun-readlob1:%s;%s;%d]", xev->evar[l].vname, xev->evar[l].stype, l);
1198+
}
1199+
else if (xev->evar[l2].vtype != RWL_TYPE_STR)
1200+
{
1201+
rwlexecsevere(xev, &xev->rwm->code[pc].cloc
1202+
, "[rwlcoderun-readlob2:%s;%s;%d]", xev->evar[l2].vname, xev->evar[l2].stype, l2);
1203+
}
1204+
else if (xev->evar[l3].vtype != RWL_TYPE_INT)
1205+
{
1206+
rwlexecsevere(xev, &xev->rwm->code[pc].cloc
1207+
, "[rwlcoderun-readlob2:%s;%s;%d]", xev->evar[l3].vname, xev->evar[l3].stype, l3);
1208+
}
1209+
else
1210+
{
1211+
rwl_identifier *ri = rwlidgetmx(xev, &xev->rwm->code[pc].cloc, l2);
1212+
rwl_identifier *ri2 = rwlidgetmx(xev, &xev->rwm->code[pc].cloc, l3);
1213+
rwlreadloblo(xev
1214+
, rwlnuminvar(xev, xev->evar+l)->vptr // the OCILob *
1215+
, xev->evar[l].vdata // the db (i.e. rwl_cinfo *)
1216+
, rwlnuminvar(xev, ri) // the string to read into
1217+
, rwlnuminvar(xev, ri2) // the int to read the length from
1218+
, (ub8) xev->xqnum.ival // offset value
1219+
, &xev->rwm->code[pc].cloc
1220+
, codename);
1221+
rwlidrelmx(xev, &xev->rwm->code[pc].cloc, l2);
1222+
rwlidrelmx(xev, &xev->rwm->code[pc].cloc, l3);
1223+
}
1224+
pc++;
1225+
}
1226+
break;
1227+
11741228
case RWL_CODE_STACK:
11751229
{
11761230
if (bit(xev->rwm->mflags, RWL_DEBUG_EXECUTE))

src/rwlparser.y

Lines changed: 89 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,63 +2972,20 @@ statement:
29722972
}
29732973
}
29742974

2975-
| RWL_T_READLOB { bis(rwm->m2flags, RWL_P2_MAYBECOMMAW); } RWL_T_IDENTIFIER maybecomma
2976-
{
2977-
sb4 l;
2978-
rwm->lobvarn = RWL_VAR_NOTFOUND;
2979-
rwm->lobnam = (yychar == RWL_T_IDENTIFIER)
2980-
? rwm->previnam
2981-
: rwm->inam;
2982-
if (bit(rwm->m2flags, RWL_P2_MAYBECOMMAW))
2983-
rwlerror(rwm, RWL_ERROR_COMMA_IS_RECOMMENDED, rwm->lobnam, "readlob");
2984-
/* lookup the file and check it is a lob */
2985-
l = rwlfindvar2(rwm->mxq, rwm->lobnam, RWL_VAR_NOGUESS, rwm->codename);
2986-
if (l>=0)
2987-
{
2988-
switch (rwm->mxq->evar[l].vtype)
2989-
{
2990-
case RWL_TYPE_BLOB:
2991-
case RWL_TYPE_CLOB:
2992-
rwm->lobvarn = l;
2993-
break;
2994-
2995-
default:
2996-
rwlerror(rwm,RWL_ERROR_INCORRECT_TYPE2, rwm->mxq->evar[l].stype, rwm->lobnam, "lob");
2997-
break;
2998-
}
2999-
}
3000-
}
3001-
RWL_T_IDENTIFIER terminator
3002-
{
3003-
sb4 l;
3004-
/* lookup the variable and check it is a string */
3005-
l = rwlfindvar2(rwm->mxq, rwm->inam, RWL_VAR_NOGUESS, rwm->codename);
3006-
if (l>=0)
3007-
{
3008-
switch (rwm->mxq->evar[l].vtype)
3009-
{
3010-
case RWL_TYPE_STR:
3011-
if (rwm->codename)
3012-
rwlcodeaddpupu(rwm, RWL_CODE_READLOB
3013-
, rwm->lobnam, rwm->lobvarn, rwm->inam, l);
3014-
else
3015-
if (!bit(rwm->m2flags, RWL_P2_NOEXEC))
3016-
{
3017-
if (rwm->maindb)
3018-
rwlreadlob(rwm->mxq, rwm->mxq->evar[rwm->lobvarn].num.vptr, rwm->maindb
3019-
, &rwm->mxq->evar[l].num, &rwm->loc, 0);
3020-
else
3021-
rwlerror(rwm, RWL_ERROR_NOT_DONE_IN_MAIN, "readlob");
3022-
}
3023-
break;
3024-
3025-
default:
3026-
rwlerror(rwm,RWL_ERROR_INCORRECT_TYPE2
3027-
, rwm->mxq->evar[l].stype, rwm->inam, "string");
3028-
break;
3029-
}
3030-
}
3031-
}
2975+
| RWL_T_READLOB readlobhead maybereadlobtail terminator
2976+
{
2977+
if (rwm->loblengthvarn && rwm->loboffset)
2978+
{
2979+
2980+
rwlcodeaddpupupup(rwm, RWL_CODE_READLOB_LO, rwm->lobnam, rwm->lobvarn,
2981+
rwm->lobwritenam, rwm->lobwritevarn, rwm->loblengthnam, rwm->loblengthvarn, rwm->loboffset);
2982+
}
2983+
else
2984+
{
2985+
rwlcodeaddpupu(rwm, RWL_CODE_READLOB, rwm->lobnam, rwm->lobvarn, rwm->lobwritenam, rwm->lobwritevarn);
2986+
}
2987+
}
2988+
30322989
| RWL_T_WRITELOB { bis(rwm->m2flags, RWL_P2_MAYBECOMMAW); } RWL_T_IDENTIFIER maybecomma
30332990
{
30342991
sb4 l;
@@ -3149,6 +3106,81 @@ maybecomma:
31493106
| ',' { bic(rwm->m2flags, RWL_P2_MAYBECOMMAW); }
31503107
;
31513108

3109+
readlobhead:
3110+
RWL_T_IDENTIFIER ','
3111+
{
3112+
sb4 l;
3113+
rwm->lobvarn = RWL_VAR_NOTFOUND;
3114+
rwm->lobnam = (yychar == RWL_T_IDENTIFIER)
3115+
? rwm->previnam
3116+
: rwm->inam;
3117+
l = rwlfindvar2(rwm->mxq, rwm->lobnam, RWL_VAR_NOGUESS, rwm->codename);
3118+
if (l>=0)
3119+
{
3120+
switch (rwm->mxq->evar[l].vtype)
3121+
{
3122+
case RWL_TYPE_BLOB:
3123+
case RWL_TYPE_CLOB:
3124+
rwm->lobvarn = l;
3125+
break;
3126+
3127+
default:
3128+
rwlerror(rwm,RWL_ERROR_INCORRECT_TYPE2, rwm->mxq->evar[l].stype, rwm->lobnam, "lob");
3129+
break;
3130+
}
3131+
}
3132+
}
3133+
RWL_T_IDENTIFIER
3134+
{
3135+
sb4 l;
3136+
rwm->lobwritevarn = 0;
3137+
rwm->loblengthvarn = 0;
3138+
rwm->loboffset = 0;
3139+
rwm->lobwritenam = (yychar == RWL_T_IDENTIFIER)
3140+
? rwm->previnam
3141+
: rwm->inam;
3142+
l = rwlfindvar2(rwm->mxq, rwm->lobwritenam, RWL_VAR_NOGUESS, rwm->codename);
3143+
if (l>=0)
3144+
{
3145+
switch (rwm->mxq->evar[l].vtype)
3146+
{
3147+
case RWL_TYPE_STR:
3148+
rwm->lobwritevarn = l;
3149+
break;
3150+
default:
3151+
rwlerror(rwm,RWL_ERROR_INCORRECT_TYPE2, rwm->mxq->evar[l].stype, rwm->lobwritenam, "string");
3152+
break;
3153+
}
3154+
}
3155+
}
3156+
maybereadlobtail:
3157+
/*empty*/
3158+
| ',' RWL_T_IDENTIFIER
3159+
{
3160+
sb4 l;
3161+
rwm->loblengthvarn = 0;
3162+
rwm->loblengthnam = (yychar == RWL_T_IDENTIFIER)
3163+
? rwm->previnam
3164+
: rwm->inam;
3165+
l = rwlfindvar2(rwm->mxq, rwm->loblengthnam, RWL_VAR_NOGUESS, rwm->codename);
3166+
if (l >= 0)
3167+
{
3168+
switch (rwm->mxq->evar[l].vtype)
3169+
{
3170+
case RWL_TYPE_INT:
3171+
rwm->loblengthvarn = l;
3172+
break;
3173+
default:
3174+
rwlerror(rwm,RWL_ERROR_INCORRECT_TYPE2, rwm->mxq->evar[l].stype, rwm->loblengthnam, "int");
3175+
break;
3176+
}
3177+
}
3178+
}
3179+
',' expression
3180+
{
3181+
rwm->loboffset = rwlexprfinish(rwm);
3182+
}
3183+
31523184
docallonesql:
31533185
{
31543186
/* simple sql execute */

src/rwlsql.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*
1212
* History
1313
*
14+
* johnkenn 18-dec-2023 - Stream with length and offset from lob locator
1415
* bengsig 4-oct-2023 - Only set cclass on sessionpool if explict
1516
* bengsig 4-oct-2023 - Don't drop session after banner print with session pool
1617
* bengsig 27-sep-2023 - 24496 is possible with session pool timeout
@@ -4276,6 +4277,57 @@ void rwlreadlob(rwl_xeqenv *xev
42764277
pnum->isnull = 0;
42774278
}
42784279

4280+
void rwlreadloblo(rwl_xeqenv *xev
4281+
, OCILobLocator *lobp
4282+
, rwl_cinfo *db
4283+
, rwl_value *pnum
4284+
, rwl_value *pnum2
4285+
, ub8 offset
4286+
, rwl_location *loc
4287+
, text *fname
4288+
)
4289+
{
4290+
ub8 amtp = pnum->slen;
4291+
ub8 b_ampt = (ub8) pnum2->ival;
4292+
4293+
4294+
if (!db)
4295+
{
4296+
rwlexecsevere(xev, loc, "[rwlreadlob-nodb]");
4297+
return;
4298+
}
4299+
rwlinitstrvar(xev, pnum);
4300+
if (OCI_SUCCESS != (xev->status=
4301+
OCILobRead2(db->svchp
4302+
, xev->errhp
4303+
, lobp
4304+
, &b_ampt /*byte_ampt*/
4305+
, 0 /*char_amtp*/
4306+
, (ub8)offset /*offset*/
4307+
, pnum->sval, amtp
4308+
, OCI_ONE_PIECE
4309+
, 0,0
4310+
, (ub2) 0, (ub1) SQLCS_IMPLICIT)))
4311+
{
4312+
rwldberror1(xev, loc, fname);
4313+
pnum->sval[0] = 0;
4314+
pnum->ival=0;
4315+
pnum->dval=0.0;
4316+
pnum2->sval[0] = 0;
4317+
pnum2->ival=0;
4318+
pnum2->dval=0.0;
4319+
}
4320+
else
4321+
{
4322+
pnum->sval[pnum2->ival] = 0;
4323+
pnum->ival=rwlatosb8(pnum->sval);
4324+
pnum->dval=rwlatof(pnum->sval);
4325+
}
4326+
pnum->isnull = 0;
4327+
pnum2->isnull = 0;
4328+
}
4329+
4330+
42794331
/* This routine will do the checking of an rwl_cinfo
42804332
* that has been allocated and put into rwm->dbsav
42814333
*

0 commit comments

Comments
 (0)