|
33 | 33 | * ENHANCEMENTS, OR MODIFICATIONS.
|
34 | 34 | *
|
35 | 35 | * IDENTIFICATION
|
36 |
| - * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.81 2005/07/06 22:44:49 momjian Exp $ |
| 36 | + * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.82 2005/07/10 15:19:43 momjian Exp $ |
37 | 37 | *
|
38 | 38 | **********************************************************************/
|
39 | 39 |
|
@@ -118,6 +118,7 @@ Datum plperl_validator(PG_FUNCTION_ARGS);
|
118 | 118 | void plperl_init(void);
|
119 | 119 |
|
120 | 120 | HV *plperl_spi_exec(char *query, int limit);
|
| 121 | +SV *plperl_spi_query(char *); |
121 | 122 |
|
122 | 123 | static Datum plperl_func_handler(PG_FUNCTION_ARGS);
|
123 | 124 |
|
@@ -229,6 +230,7 @@ plperl_safe_init(void)
|
229 | 230 | "$PLContainer->permit_only(':default');"
|
230 | 231 | "$PLContainer->permit(qw[:base_math !:base_io sort time]);"
|
231 | 232 | "$PLContainer->share(qw[&elog &spi_exec_query &return_next "
|
| 233 | + "&spi_query &spi_fetchrow " |
232 | 234 | "&DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %_SHARED ]);"
|
233 | 235 | ;
|
234 | 236 |
|
@@ -1525,3 +1527,77 @@ plperl_return_next(SV *sv)
|
1525 | 1527 | heap_freetuple(tuple);
|
1526 | 1528 | MemoryContextSwitchTo(cxt);
|
1527 | 1529 | }
|
| 1530 | + |
| 1531 | + |
| 1532 | +SV * |
| 1533 | +plperl_spi_query(char *query) |
| 1534 | +{ |
| 1535 | + SV *cursor; |
| 1536 | + |
| 1537 | + MemoryContext oldcontext = CurrentMemoryContext; |
| 1538 | + ResourceOwner oldowner = CurrentResourceOwner; |
| 1539 | + |
| 1540 | + BeginInternalSubTransaction(NULL); |
| 1541 | + MemoryContextSwitchTo(oldcontext); |
| 1542 | + |
| 1543 | + PG_TRY(); |
| 1544 | + { |
| 1545 | + void *plan; |
| 1546 | + Portal portal = NULL; |
| 1547 | + |
| 1548 | + plan = SPI_prepare(query, 0, NULL); |
| 1549 | + if (plan) |
| 1550 | + portal = SPI_cursor_open(NULL, plan, NULL, NULL, false); |
| 1551 | + if (portal) |
| 1552 | + cursor = newSVpv(portal->name, 0); |
| 1553 | + else |
| 1554 | + cursor = newSV(0); |
| 1555 | + |
| 1556 | + ReleaseCurrentSubTransaction(); |
| 1557 | + MemoryContextSwitchTo(oldcontext); |
| 1558 | + CurrentResourceOwner = oldowner; |
| 1559 | + SPI_restore_connection(); |
| 1560 | + } |
| 1561 | + PG_CATCH(); |
| 1562 | + { |
| 1563 | + ErrorData *edata; |
| 1564 | + |
| 1565 | + MemoryContextSwitchTo(oldcontext); |
| 1566 | + edata = CopyErrorData(); |
| 1567 | + FlushErrorState(); |
| 1568 | + |
| 1569 | + RollbackAndReleaseCurrentSubTransaction(); |
| 1570 | + MemoryContextSwitchTo(oldcontext); |
| 1571 | + CurrentResourceOwner = oldowner; |
| 1572 | + |
| 1573 | + SPI_restore_connection(); |
| 1574 | + croak("%s", edata->message); |
| 1575 | + return NULL; |
| 1576 | + } |
| 1577 | + PG_END_TRY(); |
| 1578 | + |
| 1579 | + return cursor; |
| 1580 | +} |
| 1581 | + |
| 1582 | + |
| 1583 | +SV * |
| 1584 | +plperl_spi_fetchrow(char *cursor) |
| 1585 | +{ |
| 1586 | + SV *row = newSV(0); |
| 1587 | + Portal p = SPI_cursor_find(cursor); |
| 1588 | + |
| 1589 | + if (!p) |
| 1590 | + return row; |
| 1591 | + |
| 1592 | + SPI_cursor_fetch(p, true, 1); |
| 1593 | + if (SPI_processed == 0) { |
| 1594 | + SPI_cursor_close(p); |
| 1595 | + return row; |
| 1596 | + } |
| 1597 | + |
| 1598 | + row = plperl_hash_from_tuple(SPI_tuptable->vals[0], |
| 1599 | + SPI_tuptable->tupdesc); |
| 1600 | + SPI_freetuptable(SPI_tuptable); |
| 1601 | + |
| 1602 | + return row; |
| 1603 | +} |
0 commit comments