* This is the slow part of plpgsql_compile(). * * The passed-in "function" pointer is either NULL or an already-allocated * function struct to overwrite. * * While compiling a function, the CurrentMemoryContext is the * per-function memory context of the function we are compiling. That * means a palloc() will allocate storage with the same lifetime as * the function itself. * * Because p
| 261 | * result in the invocation of another plpgsql function. |
| 262 | */ |
| 263 | static PLpgSQL_function * |
| 264 | do_compile(FunctionCallInfo fcinfo, |
| 265 | HeapTuple procTup, |
| 266 | PLpgSQL_function *function, |
| 267 | PLpgSQL_func_hashkey *hashkey, |
| 268 | bool forValidator) |
| 269 | { |
| 270 | Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup); |
| 271 | bool is_dml_trigger = CALLED_AS_TRIGGER(fcinfo); |
| 272 | bool is_event_trigger = CALLED_AS_EVENT_TRIGGER(fcinfo); |
| 273 | Datum prosrcdatum; |
| 274 | bool isnull; |
| 275 | char *proc_source; |
| 276 | HeapTuple typeTup; |
| 277 | Form_pg_type typeStruct; |
| 278 | PLpgSQL_variable *var; |
| 279 | PLpgSQL_rec *rec; |
| 280 | int i; |
| 281 | ErrorContextCallback plerrcontext; |
| 282 | int parse_rc; |
| 283 | Oid rettypeid; |
| 284 | int numargs; |
| 285 | int num_in_args = 0; |
| 286 | int num_out_args = 0; |
| 287 | Oid *argtypes; |
| 288 | char **argnames; |
| 289 | char *argmodes; |
| 290 | int *in_arg_varnos = NULL; |
| 291 | PLpgSQL_variable **out_arg_variables; |
| 292 | MemoryContext func_cxt; |
| 293 | |
| 294 | /* |
| 295 | * Setup the scanner input and error info. We assume that this function |
| 296 | * cannot be invoked recursively, so there's no need to save and restore |
| 297 | * the static variables used here. |
| 298 | */ |
| 299 | prosrcdatum = SysCacheGetAttr(PROCOID, procTup, |
| 300 | Anum_pg_proc_prosrc, &isnull); |
| 301 | if (isnull) |
| 302 | elog(ERROR, "null prosrc"); |
| 303 | proc_source = TextDatumGetCString(prosrcdatum); |
| 304 | plpgsql_scanner_init(proc_source); |
| 305 | |
| 306 | plpgsql_error_funcname = pstrdup(NameStr(procStruct->proname)); |
| 307 | |
| 308 | /* |
| 309 | * Setup error traceback support for ereport() |
| 310 | */ |
| 311 | plerrcontext.callback = plpgsql_compile_error_callback; |
| 312 | plerrcontext.arg = forValidator ? proc_source : NULL; |
| 313 | plerrcontext.previous = error_context_stack; |
| 314 | error_context_stack = &plerrcontext; |
| 315 | |
| 316 | /* |
| 317 | * Do extra syntax checks when validating the function definition. We skip |
| 318 | * this when actually compiling functions for execution, for performance |
| 319 | * reasons. |
| 320 | */ |
no test coverage detected