*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.172 2010/02/26 02:00:37 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.173 2010/03/19 22:54:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
Datum fmgr_c_validator(PG_FUNCTION_ARGS);
Datum fmgr_sql_validator(PG_FUNCTION_ARGS);
+typedef struct
+{
+ char *proname;
+ char *prosrc;
+} parse_error_callback_arg;
+
static void sql_function_parse_error_callback(void *arg);
static int match_prosrc_to_query(const char *prosrc, const char *queryText,
int cursorpos);
bool isnull;
Datum tmp;
char *prosrc;
+ parse_error_callback_arg callback_arg;
ErrorContextCallback sqlerrcontext;
bool haspolyarg;
int i;
/*
* Setup error traceback support for ereport().
*/
+ callback_arg.proname = NameStr(proc->proname);
+ callback_arg.prosrc = prosrc;
+
sqlerrcontext.callback = sql_function_parse_error_callback;
- sqlerrcontext.arg = tuple;
+ sqlerrcontext.arg = (void *) &callback_arg;
sqlerrcontext.previous = error_context_stack;
error_context_stack = &sqlerrcontext;
static void
sql_function_parse_error_callback(void *arg)
{
- HeapTuple tuple = (HeapTuple) arg;
- Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(tuple);
- bool isnull;
- Datum tmp;
- char *prosrc;
+ parse_error_callback_arg *callback_arg = (parse_error_callback_arg *) arg;
/* See if it's a syntax error; if so, transpose to CREATE FUNCTION */
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
- prosrc = TextDatumGetCString(tmp);
-
- if (!function_parse_error_transpose(prosrc))
+ if (!function_parse_error_transpose(callback_arg->prosrc))
{
/* If it's not a syntax error, push info onto context stack */
- errcontext("SQL function \"%s\"", NameStr(proc->proname));
+ errcontext("SQL function \"%s\"", callback_arg->proname);
}
-
- pfree(prosrc);
}
/*
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.142 2010/02/26 02:00:41 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.143 2010/03/19 22:54:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*/
typedef struct
{
+ char *fname; /* function name (for error msgs) */
char *src; /* function body text (for error msgs) */
Oid *argtypes; /* resolved types of arguments */
bool isNull;
fcache = (SQLFunctionCachePtr) palloc0(sizeof(SQLFunctionCache));
+ finfo->fn_extra = (void *) fcache;
/*
* get the procedure tuple corresponding to the given function Oid
elog(ERROR, "cache lookup failed for function %u", foid);
procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
+ /*
+ * copy function name immediately for use by error reporting callback
+ */
+ fcache->fname = pstrdup(NameStr(procedureStruct->proname));
+
/*
* get the result type from the procedure tuple, and check for polymorphic
* result type; if so, find out the actual result type.
lazyEvalOK);
ReleaseSysCache(procedureTuple);
-
- finfo->fn_extra = (void *) fcache;
}
/* Start up execution of one execution_state node */
{
FmgrInfo *flinfo = (FmgrInfo *) arg;
SQLFunctionCachePtr fcache = (SQLFunctionCachePtr) flinfo->fn_extra;
- HeapTuple func_tuple;
- Form_pg_proc functup;
- char *fn_name;
int syntaxerrposition;
- /* Need access to function's pg_proc tuple */
- func_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(flinfo->fn_oid));
- if (!HeapTupleIsValid(func_tuple))
- return; /* shouldn't happen */
- functup = (Form_pg_proc) GETSTRUCT(func_tuple);
- fn_name = NameStr(functup->proname);
+ /*
+ * We can do nothing useful if init_sql_fcache() didn't get as far as
+ * saving the function name
+ */
+ if (fcache == NULL || fcache->fname == NULL)
+ return;
/*
* If there is a syntax error position, convert to internal syntax error
*/
syntaxerrposition = geterrposition();
- if (syntaxerrposition > 0)
+ if (syntaxerrposition > 0 && fcache->src != NULL)
{
- bool isnull;
- Datum tmp;
- char *prosrc;
-
- tmp = SysCacheGetAttr(PROCOID, func_tuple, Anum_pg_proc_prosrc,
- &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
- prosrc = TextDatumGetCString(tmp);
errposition(0);
internalerrposition(syntaxerrposition);
- internalerrquery(prosrc);
- pfree(prosrc);
+ internalerrquery(fcache->src);
}
/*
* ExecutorEnd are blamed on the appropriate query; see postquel_start and
* postquel_end.)
*/
- if (fcache)
+ if (fcache->func_state)
{
execution_state *es;
int query_num;
if (es->qd)
{
errcontext("SQL function \"%s\" statement %d",
- fn_name, query_num);
+ fcache->fname, query_num);
break;
}
es = es->next;
* couldn't identify a running query; might be function entry,
* function exit, or between queries.
*/
- errcontext("SQL function \"%s\"", fn_name);
+ errcontext("SQL function \"%s\"", fcache->fname);
}
}
else
{
- /* must have failed during init_sql_fcache() */
- errcontext("SQL function \"%s\" during startup", fn_name);
+ /*
+ * Assume we failed during init_sql_fcache(). (It's possible that
+ * the function actually has an empty body, but in that case we may
+ * as well report all errors as being "during startup".)
+ */
+ errcontext("SQL function \"%s\" during startup", fcache->fname);
}
-
- ReleaseSysCache(func_tuple);
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.286 2010/02/26 02:00:46 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.287 2010/03/19 22:54:41 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
int sublevels_up;
} substitute_actual_srf_parameters_context;
+typedef struct
+{
+ char *proname;
+ char *prosrc;
+} inline_error_callback_arg;
+
static bool contain_agg_clause_walker(Node *node, void *context);
static bool pull_agg_clause_walker(Node *node, List **context);
static bool count_agg_clauses_walker(Node *node, AggClauseCounts *counts);
bool modifyTargetList;
MemoryContext oldcxt;
MemoryContext mycxt;
+ inline_error_callback_arg callback_arg;
ErrorContextCallback sqlerrcontext;
List *raw_parsetree_list;
Query *querytree;
if (pg_proc_aclcheck(funcid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
return NULL;
- /*
- * Setup error traceback support for ereport(). This is so that we can
- * finger the function that bad information came from.
- */
- sqlerrcontext.callback = sql_inline_error_callback;
- sqlerrcontext.arg = func_tuple;
- sqlerrcontext.previous = error_context_stack;
- error_context_stack = &sqlerrcontext;
-
/*
* Make a temporary memory context, so that we don't leak all the stuff
* that parsing might create.
ALLOCSET_DEFAULT_MAXSIZE);
oldcxt = MemoryContextSwitchTo(mycxt);
+ /* Fetch the function body */
+ tmp = SysCacheGetAttr(PROCOID,
+ func_tuple,
+ Anum_pg_proc_prosrc,
+ &isNull);
+ if (isNull)
+ elog(ERROR, "null prosrc for function %u", funcid);
+ src = TextDatumGetCString(tmp);
+
+ /*
+ * Setup error traceback support for ereport(). This is so that we can
+ * finger the function that bad information came from.
+ */
+ callback_arg.proname = NameStr(funcform->proname);
+ callback_arg.prosrc = src;
+
+ sqlerrcontext.callback = sql_inline_error_callback;
+ sqlerrcontext.arg = (void *) &callback_arg;
+ sqlerrcontext.previous = error_context_stack;
+ error_context_stack = &sqlerrcontext;
+
/* Check for polymorphic arguments, and substitute actual arg types */
argtypes = (Oid *) palloc(funcform->pronargs * sizeof(Oid));
memcpy(argtypes, funcform->proargtypes.values,
}
}
- /* Fetch and parse the function body */
- tmp = SysCacheGetAttr(PROCOID,
- func_tuple,
- Anum_pg_proc_prosrc,
- &isNull);
- if (isNull)
- elog(ERROR, "null prosrc for function %u", funcid);
- src = TextDatumGetCString(tmp);
-
/*
* We just do parsing and parse analysis, not rewriting, because rewriting
* will not affect table-free-SELECT-only queries, which is all that we
static void
sql_inline_error_callback(void *arg)
{
- HeapTuple func_tuple = (HeapTuple) arg;
- Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
+ inline_error_callback_arg *callback_arg = (inline_error_callback_arg *) arg;
int syntaxerrposition;
/* If it's a syntax error, convert to internal syntax error report */
syntaxerrposition = geterrposition();
if (syntaxerrposition > 0)
{
- bool isnull;
- Datum tmp;
- char *prosrc;
-
- tmp = SysCacheGetAttr(PROCOID, func_tuple, Anum_pg_proc_prosrc,
- &isnull);
- if (isnull)
- elog(ERROR, "null prosrc");
- prosrc = TextDatumGetCString(tmp);
errposition(0);
internalerrposition(syntaxerrposition);
- internalerrquery(prosrc);
+ internalerrquery(callback_arg->prosrc);
}
- errcontext("SQL function \"%s\" during inlining",
- NameStr(funcform->proname));
+ errcontext("SQL function \"%s\" during inlining", callback_arg->proname);
}
/*
bool modifyTargetList;
MemoryContext oldcxt;
MemoryContext mycxt;
+ inline_error_callback_arg callback_arg;
ErrorContextCallback sqlerrcontext;
List *raw_parsetree_list;
List *querytree_list;
return NULL;
}
- /*
- * Setup error traceback support for ereport(). This is so that we can
- * finger the function that bad information came from.
- */
- sqlerrcontext.callback = sql_inline_error_callback;
- sqlerrcontext.arg = func_tuple;
- sqlerrcontext.previous = error_context_stack;
- error_context_stack = &sqlerrcontext;
-
/*
* Make a temporary memory context, so that we don't leak all the stuff
* that parsing might create.
ALLOCSET_DEFAULT_MAXSIZE);
oldcxt = MemoryContextSwitchTo(mycxt);
+ /* Fetch the function body */
+ tmp = SysCacheGetAttr(PROCOID,
+ func_tuple,
+ Anum_pg_proc_prosrc,
+ &isNull);
+ if (isNull)
+ elog(ERROR, "null prosrc for function %u", func_oid);
+ src = TextDatumGetCString(tmp);
+
+ /*
+ * Setup error traceback support for ereport(). This is so that we can
+ * finger the function that bad information came from.
+ */
+ callback_arg.proname = NameStr(funcform->proname);
+ callback_arg.prosrc = src;
+
+ sqlerrcontext.callback = sql_inline_error_callback;
+ sqlerrcontext.arg = (void *) &callback_arg;
+ sqlerrcontext.previous = error_context_stack;
+ error_context_stack = &sqlerrcontext;
+
/*
* Run eval_const_expressions on the function call. This is necessary to
* ensure that named-argument notation is converted to positional notation
}
}
- /* Fetch and parse the function body */
- tmp = SysCacheGetAttr(PROCOID,
- func_tuple,
- Anum_pg_proc_prosrc,
- &isNull);
- if (isNull)
- elog(ERROR, "null prosrc for function %u", func_oid);
- src = TextDatumGetCString(tmp);
-
/*
* Parse, analyze, and rewrite (unlike inline_function(), we can't skip
* rewriting here). We can fail as soon as we find more than one query,