| 139 | } |
| 140 | |
| 141 | PyObject * |
| 142 | PLy_cursor_plan(PyObject *ob, PyObject *args) |
| 143 | { |
| 144 | PLyCursorObject *cursor; |
| 145 | volatile int nargs; |
| 146 | int i; |
| 147 | PLyPlanObject *plan; |
| 148 | PLyExecutionContext *exec_ctx = PLy_current_execution_context(); |
| 149 | volatile MemoryContext oldcontext; |
| 150 | volatile ResourceOwner oldowner; |
| 151 | |
| 152 | if (args) |
| 153 | { |
| 154 | if (!PySequence_Check(args) || PyString_Check(args) || PyUnicode_Check(args)) |
| 155 | { |
| 156 | PLy_exception_set(PyExc_TypeError, "plpy.cursor takes a sequence as its second argument"); |
| 157 | return NULL; |
| 158 | } |
| 159 | nargs = PySequence_Length(args); |
| 160 | } |
| 161 | else |
| 162 | nargs = 0; |
| 163 | |
| 164 | plan = (PLyPlanObject *) ob; |
| 165 | |
| 166 | if (nargs != plan->nargs) |
| 167 | { |
| 168 | char *sv; |
| 169 | PyObject *so = PyObject_Str(args); |
| 170 | |
| 171 | if (!so) |
| 172 | PLy_elog(ERROR, "could not execute plan"); |
| 173 | sv = PyString_AsString(so); |
| 174 | PLy_exception_set_plural(PyExc_TypeError, |
| 175 | "Expected sequence of %d argument, got %d: %s", |
| 176 | "Expected sequence of %d arguments, got %d: %s", |
| 177 | plan->nargs, |
| 178 | plan->nargs, nargs, sv); |
| 179 | Py_DECREF(so); |
| 180 | |
| 181 | return NULL; |
| 182 | } |
| 183 | |
| 184 | if ((cursor = PyObject_New(PLyCursorObject, &PLy_CursorType)) == NULL) |
| 185 | return NULL; |
| 186 | cursor->portalname = NULL; |
| 187 | cursor->closed = false; |
| 188 | cursor->mcxt = AllocSetContextCreate(TopMemoryContext, |
| 189 | "PL/Python cursor context", |
| 190 | ALLOCSET_DEFAULT_SIZES); |
| 191 | |
| 192 | /* Initialize for converting result tuples to Python */ |
| 193 | PLy_input_setup_func(&cursor->result, cursor->mcxt, |
| 194 | RECORDOID, -1, |
| 195 | exec_ctx->curr_proc); |
| 196 | |
| 197 | oldcontext = CurrentMemoryContext; |
| 198 | oldowner = CurrentResourceOwner; |
no test coverage detected