| 194 | } |
| 195 | |
| 196 | PyObject * |
| 197 | PLy_spi_execute_plan(PyObject *ob, PyObject *list, int64 limit) |
| 198 | { |
| 199 | volatile int nargs; |
| 200 | int i, |
| 201 | rv; |
| 202 | PLyPlanObject *plan; |
| 203 | volatile MemoryContext oldcontext; |
| 204 | volatile ResourceOwner oldowner; |
| 205 | PyObject *ret; |
| 206 | |
| 207 | if (list != NULL) |
| 208 | { |
| 209 | if (!PySequence_Check(list) || PyString_Check(list) || PyUnicode_Check(list)) |
| 210 | { |
| 211 | PLy_exception_set(PyExc_TypeError, "plpy.execute takes a sequence as its second argument"); |
| 212 | return NULL; |
| 213 | } |
| 214 | nargs = PySequence_Length(list); |
| 215 | } |
| 216 | else |
| 217 | nargs = 0; |
| 218 | |
| 219 | plan = (PLyPlanObject *) ob; |
| 220 | |
| 221 | if (nargs != plan->nargs) |
| 222 | { |
| 223 | char *sv; |
| 224 | PyObject *so = PyObject_Str(list); |
| 225 | |
| 226 | if (!so) |
| 227 | PLy_elog(ERROR, "could not execute plan"); |
| 228 | sv = PyString_AsString(so); |
| 229 | PLy_exception_set_plural(PyExc_TypeError, |
| 230 | "Expected sequence of %d argument, got %d: %s", |
| 231 | "Expected sequence of %d arguments, got %d: %s", |
| 232 | plan->nargs, |
| 233 | plan->nargs, nargs, sv); |
| 234 | Py_DECREF(so); |
| 235 | |
| 236 | return NULL; |
| 237 | } |
| 238 | |
| 239 | oldcontext = CurrentMemoryContext; |
| 240 | oldowner = CurrentResourceOwner; |
| 241 | |
| 242 | if(!PLy_spi_subtransaction_begin(oldcontext, oldowner)) |
| 243 | return NULL; |
| 244 | |
| 245 | PG_TRY(); |
| 246 | { |
| 247 | PLyExecutionContext *exec_ctx = PLy_current_execution_context(); |
| 248 | char *volatile nulls; |
| 249 | volatile int j; |
| 250 | |
| 251 | if (nargs > 0) |
| 252 | nulls = palloc(nargs * sizeof(char)); |
| 253 | else |
no test coverage detected