/* * This function is called when a PL/Proxy function is created to * check the syntax. */ Datum plproxy_validator(PG_FUNCTION_ARGS) { Oid oid = PG_GETARG_OID(0); HeapTuple proc_tuple; if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, oid)) PG_RETURN_VOID(); proc_tuple = SearchSysCache(PROCOID, ObjectIdGetDatum(oid), 0, 0, 0); if (!HeapTupleIsValid(proc_tuple)) elog(ERROR, "cache lookup failed for function %u", oid); plproxy_compile(NULL, proc_tuple, true); ReleaseSysCache(proc_tuple); PG_RETURN_VOID(); }
/* * Do compilation and execution under SPI. * * Result conversion will be done without SPI. */ static ProxyFunction * compile_and_execute(FunctionCallInfo fcinfo) { int err; ProxyFunction *func; ProxyCluster *cluster; /* prepare SPI */ err = SPI_connect(); if (err != SPI_OK_CONNECT) elog(ERROR, "SPI_connect: %s", SPI_result_code_string(err)); /* do the initialization also under SPI */ plproxy_startup_init(); /* compile code */ func = plproxy_compile(fcinfo, false); /* get actual cluster to run on */ cluster = plproxy_find_cluster(func, fcinfo); /* Don't allow nested calls on the same cluster */ if (cluster->busy) plproxy_error(func, "Nested PL/Proxy calls to the same cluster are not supported."); /* fetch PGresults */ func->cur_cluster = cluster; plproxy_exec(func, fcinfo); /* done with SPI */ err = SPI_finish(); if (err != SPI_OK_FINISH) elog(ERROR, "SPI_finish: %s", SPI_result_code_string(err)); return func; }