|
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 | case ECPGt_descriptor:
|
| 1038 | + case ECPGt_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 | + else if (var->type == ECPGt_sqlda) |
| 1179 | + { |
| 1180 | + if (INFORMIX_MODE(stmt->compat)) |
| 1181 | + { |
| 1182 | + struct sqlda_compat *sqlda = *(struct sqlda_compat **)var->pointer; |
| 1183 | + struct variable desc_inlist; |
| 1184 | + int i; |
| 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 | + case ECPGt_char: |
| 1200 | + case ECPGt_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 | + struct sqlda_struct *sqlda = *(struct sqlda_struct **)var->pointer; |
| 1238 | + struct variable desc_inlist; |
| 1239 | + int i; |
| 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 | + case ECPGt_char: |
| 1255 | + case ECPGt_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 | + else if (var != NULL && var->type == ECPGt_sqlda) |
| 1474 | + { |
| 1475 | + if (INFORMIX_MODE(stmt->compat)) |
| 1476 | + { |
| 1477 | + struct sqlda_compat **_sqlda = (struct sqlda_compat **)var->pointer; |
| 1478 | + struct sqlda_compat *sqlda = *_sqlda; |
| 1479 | + struct sqlda_compat *sqlda_new; |
| 1480 | + int i; |
| 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 | + struct sqlda_struct **_sqlda = (struct sqlda_struct **)var->pointer; |
| 1528 | + struct sqlda_struct *sqlda = *_sqlda; |
| 1529 | + struct sqlda_struct *sqlda_new; |
| 1530 | + int i; |
| 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 | {
|
|
0 commit comments