|
1 |
| -/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.87 2009/09/03 10:24:48 meskes Exp $ */ |
| 1 | +/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.88 2010/01/05 16:38:23 meskes Exp $ */ |
2 | 2 |
|
3 | 3 | /*
|
4 | 4 | * The aim is to get a simpler inteface to the database routines.
|
|
25 | 25 | #include"ecpgerrno.h"
|
26 | 26 | #include"extern.h"
|
27 | 27 | #include"sqlca.h"
|
| 28 | +#include"sqlda-native.h" |
| 29 | +#include"sqlda-compat.h" |
28 | 30 | #include"sql3types.h"
|
29 | 31 | #include"pgtypes_numeric.h"
|
30 | 32 | #include"pgtypes_date.h"
|
@@ -1033,6 +1035,7 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
|
1033 | 1035 | break;
|
1034 | 1036 |
|
1035 | 1037 | caseECPGt_descriptor:
|
| 1038 | +caseECPGt_sqlda: |
1036 | 1039 | break;
|
1037 | 1040 |
|
1038 | 1041 | default:
|
@@ -1172,6 +1175,120 @@ ecpg_execute(struct statement * stmt)
|
1172 | 1175 | if (desc->count==desc_counter)
|
1173 | 1176 | desc_counter=0;
|
1174 | 1177 | }
|
| 1178 | +elseif (var->type==ECPGt_sqlda) |
| 1179 | +{ |
| 1180 | +if (INFORMIX_MODE(stmt->compat)) |
| 1181 | +{ |
| 1182 | +structsqlda_compat*sqlda=*(structsqlda_compat**)var->pointer; |
| 1183 | +structvariabledesc_inlist; |
| 1184 | +inti; |
| 1185 | + |
| 1186 | +if (sqlda==NULL) |
| 1187 | +return false; |
| 1188 | + |
| 1189 | +desc_counter++; |
| 1190 | +for (i=0;i<sqlda->sqld;i++) |
| 1191 | +{ |
| 1192 | +if (i+1==desc_counter) |
| 1193 | +{ |
| 1194 | +desc_inlist.type=sqlda->sqlvar[i].sqltype; |
| 1195 | +desc_inlist.value=sqlda->sqlvar[i].sqldata; |
| 1196 | +desc_inlist.pointer=&(sqlda->sqlvar[i].sqldata); |
| 1197 | +switch (desc_inlist.type) |
| 1198 | +{ |
| 1199 | +caseECPGt_char: |
| 1200 | +caseECPGt_varchar: |
| 1201 | +desc_inlist.varcharsize=strlen(sqlda->sqlvar[i].sqldata); |
| 1202 | +break; |
| 1203 | +default: |
| 1204 | +desc_inlist.varcharsize=0; |
| 1205 | +break; |
| 1206 | +} |
| 1207 | +desc_inlist.arrsize=1; |
| 1208 | +desc_inlist.offset=0; |
| 1209 | +if (sqlda->sqlvar[i].sqlind) |
| 1210 | +{ |
| 1211 | +desc_inlist.ind_type=ECPGt_short; |
| 1212 | +/* ECPG expects indicator value < 0 */ |
| 1213 | +if (*(sqlda->sqlvar[i].sqlind)) |
| 1214 | +*(sqlda->sqlvar[i].sqlind)=-1; |
| 1215 | +desc_inlist.ind_value=sqlda->sqlvar[i].sqlind; |
| 1216 | +desc_inlist.ind_pointer=&(sqlda->sqlvar[i].sqlind); |
| 1217 | +desc_inlist.ind_varcharsize=desc_inlist.ind_arrsize=1; |
| 1218 | +desc_inlist.ind_offset=0; |
| 1219 | +} |
| 1220 | +else |
| 1221 | +{ |
| 1222 | +desc_inlist.ind_type=ECPGt_NO_INDICATOR; |
| 1223 | +desc_inlist.ind_value=desc_inlist.ind_pointer=NULL; |
| 1224 | +desc_inlist.ind_varcharsize=desc_inlist.ind_arrsize=desc_inlist.ind_offset=0; |
| 1225 | +} |
| 1226 | +if (!ecpg_store_input(stmt->lineno,stmt->force_indicator,&desc_inlist,&tobeinserted, false)) |
| 1227 | +return false; |
| 1228 | + |
| 1229 | +break; |
| 1230 | +} |
| 1231 | +} |
| 1232 | +if (sqlda->sqld==desc_counter) |
| 1233 | +desc_counter=0; |
| 1234 | +} |
| 1235 | +else |
| 1236 | +{ |
| 1237 | +structsqlda_struct*sqlda=*(structsqlda_struct**)var->pointer; |
| 1238 | +structvariabledesc_inlist; |
| 1239 | +inti; |
| 1240 | + |
| 1241 | +if (sqlda==NULL) |
| 1242 | +return false; |
| 1243 | + |
| 1244 | +desc_counter++; |
| 1245 | +for (i=0;i<sqlda->sqln;i++) |
| 1246 | +{ |
| 1247 | +if (i+1==desc_counter) |
| 1248 | +{ |
| 1249 | +desc_inlist.type=sqlda->sqlvar[i].sqltype; |
| 1250 | +desc_inlist.value=sqlda->sqlvar[i].sqldata; |
| 1251 | +desc_inlist.pointer=&(sqlda->sqlvar[i].sqldata); |
| 1252 | +switch (desc_inlist.type) |
| 1253 | +{ |
| 1254 | +caseECPGt_char: |
| 1255 | +caseECPGt_varchar: |
| 1256 | +desc_inlist.varcharsize=strlen(sqlda->sqlvar[i].sqldata); |
| 1257 | +break; |
| 1258 | +default: |
| 1259 | +desc_inlist.varcharsize=0; |
| 1260 | +break; |
| 1261 | +} |
| 1262 | +desc_inlist.arrsize=1; |
| 1263 | +desc_inlist.offset=0; |
| 1264 | +if (sqlda->sqlvar[i].sqlind) |
| 1265 | +{ |
| 1266 | +desc_inlist.ind_type=ECPGt_short; |
| 1267 | +/* ECPG expects indicator value < 0 */ |
| 1268 | +if (*(sqlda->sqlvar[i].sqlind)) |
| 1269 | +*(sqlda->sqlvar[i].sqlind)=-1; |
| 1270 | +desc_inlist.ind_value=sqlda->sqlvar[i].sqlind; |
| 1271 | +desc_inlist.ind_pointer=&(sqlda->sqlvar[i].sqlind); |
| 1272 | +desc_inlist.ind_varcharsize=desc_inlist.ind_arrsize=1; |
| 1273 | +desc_inlist.ind_offset=0; |
| 1274 | +} |
| 1275 | +else |
| 1276 | +{ |
| 1277 | +desc_inlist.ind_type=ECPGt_NO_INDICATOR; |
| 1278 | +desc_inlist.ind_value=desc_inlist.ind_pointer=NULL; |
| 1279 | +desc_inlist.ind_varcharsize=desc_inlist.ind_arrsize=desc_inlist.ind_offset=0; |
| 1280 | +} |
| 1281 | +if (!ecpg_store_input(stmt->lineno,stmt->force_indicator,&desc_inlist,&tobeinserted, false)) |
| 1282 | +return false; |
| 1283 | + |
| 1284 | +break; |
| 1285 | +} |
| 1286 | +} |
| 1287 | +if (sqlda->sqln==desc_counter) |
| 1288 | +desc_counter=0; |
| 1289 | +} |
| 1290 | + |
| 1291 | +} |
1175 | 1292 | else
|
1176 | 1293 | {
|
1177 | 1294 | if (!ecpg_store_input(stmt->lineno,stmt->force_indicator,var,&tobeinserted, false))
|
@@ -1353,6 +1470,111 @@ ecpg_execute(struct statement * stmt)
|
1353 | 1470 | }
|
1354 | 1471 | var=var->next;
|
1355 | 1472 | }
|
| 1473 | +elseif (var!=NULL&&var->type==ECPGt_sqlda) |
| 1474 | +{ |
| 1475 | +if (INFORMIX_MODE(stmt->compat)) |
| 1476 | +{ |
| 1477 | +structsqlda_compat**_sqlda= (structsqlda_compat**)var->pointer; |
| 1478 | +structsqlda_compat*sqlda=*_sqlda; |
| 1479 | +structsqlda_compat*sqlda_new; |
| 1480 | +inti; |
| 1481 | + |
| 1482 | +/* If we are passed in a previously existing sqlda (chain) then free it. */ |
| 1483 | +while (sqlda) |
| 1484 | +{ |
| 1485 | +sqlda_new=sqlda->desc_next; |
| 1486 | +free(sqlda); |
| 1487 | +sqlda=sqlda_new; |
| 1488 | +} |
| 1489 | +*_sqlda=sqlda=sqlda_new=NULL; |
| 1490 | +for (i=ntuples-1;i >=0;i--) |
| 1491 | +{ |
| 1492 | +/* Build a new sqlda structure. Note that only fetching 1 record is supported */ |
| 1493 | +sqlda_new=ecpg_build_compat_sqlda(stmt->lineno,results,i,stmt->compat); |
| 1494 | + |
| 1495 | +if (!sqlda_new) |
| 1496 | +{ |
| 1497 | +/* cleanup all SQLDAs we created up */ |
| 1498 | +while (sqlda) |
| 1499 | +{ |
| 1500 | +sqlda_new=sqlda->desc_next; |
| 1501 | +free(sqlda); |
| 1502 | +sqlda=sqlda_new; |
| 1503 | +} |
| 1504 | +*_sqlda=NULL; |
| 1505 | + |
| 1506 | +ecpg_log("ecpg_execute on line %d: out of memory allocating a new sqlda\n",stmt->lineno); |
| 1507 | +status= false; |
| 1508 | +break; |
| 1509 | +} |
| 1510 | +else |
| 1511 | +{ |
| 1512 | +ecpg_log("ecpg_execute on line %d: new sqlda was built\n",stmt->lineno); |
| 1513 | + |
| 1514 | +*_sqlda=sqlda_new; |
| 1515 | + |
| 1516 | +ecpg_set_compat_sqlda(stmt->lineno,_sqlda,results,i,stmt->compat); |
| 1517 | +ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n", |
| 1518 | +stmt->lineno,PQnfields(results)); |
| 1519 | + |
| 1520 | +sqlda_new->desc_next=sqlda; |
| 1521 | +sqlda=sqlda_new; |
| 1522 | +} |
| 1523 | +} |
| 1524 | +} |
| 1525 | +else |
| 1526 | +{ |
| 1527 | +structsqlda_struct**_sqlda= (structsqlda_struct**)var->pointer; |
| 1528 | +structsqlda_struct*sqlda=*_sqlda; |
| 1529 | +structsqlda_struct*sqlda_new; |
| 1530 | +inti; |
| 1531 | + |
| 1532 | +/* If we are passed in a previously existing sqlda (chain) then free it. */ |
| 1533 | +while (sqlda) |
| 1534 | +{ |
| 1535 | +sqlda_new=sqlda->desc_next; |
| 1536 | +free(sqlda); |
| 1537 | +sqlda=sqlda_new; |
| 1538 | +} |
| 1539 | +*_sqlda=sqlda=sqlda_new=NULL; |
| 1540 | +for (i=ntuples-1;i >=0;i--) |
| 1541 | +{ |
| 1542 | +/* Build a new sqlda structure. Note that only fetching 1 record is supported */ |
| 1543 | +sqlda_new=ecpg_build_native_sqlda(stmt->lineno,results,i,stmt->compat); |
| 1544 | + |
| 1545 | +if (!sqlda_new) |
| 1546 | +{ |
| 1547 | +/* cleanup all SQLDAs we created up */ |
| 1548 | +while (sqlda) |
| 1549 | +{ |
| 1550 | +sqlda_new=sqlda->desc_next; |
| 1551 | +free(sqlda); |
| 1552 | +sqlda=sqlda_new; |
| 1553 | +} |
| 1554 | +*_sqlda=NULL; |
| 1555 | + |
| 1556 | +ecpg_log("ecpg_execute on line %d: out of memory allocating a new sqlda\n",stmt->lineno); |
| 1557 | +status= false; |
| 1558 | +break; |
| 1559 | +} |
| 1560 | +else |
| 1561 | +{ |
| 1562 | +ecpg_log("ecpg_execute on line %d: new sqlda was built\n",stmt->lineno); |
| 1563 | + |
| 1564 | +*_sqlda=sqlda_new; |
| 1565 | + |
| 1566 | +ecpg_set_native_sqlda(stmt->lineno,_sqlda,results,i,stmt->compat); |
| 1567 | +ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n", |
| 1568 | +stmt->lineno,PQnfields(results)); |
| 1569 | + |
| 1570 | +sqlda_new->desc_next=sqlda; |
| 1571 | +sqlda=sqlda_new; |
| 1572 | +} |
| 1573 | +} |
| 1574 | +} |
| 1575 | + |
| 1576 | +var=var->next; |
| 1577 | +} |
1356 | 1578 | else
|
1357 | 1579 | for (act_field=0;act_field<nfields&&status;act_field++)
|
1358 | 1580 | {
|
|