aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/catalog/pg_proc.c31
-rw-r--r--src/backend/commands/functioncmds.c11
-rw-r--r--src/backend/executor/execMain.c2
-rw-r--r--src/backend/executor/functions.c20
-rw-r--r--src/backend/optimizer/util/clauses.c66
5 files changed, 66 insertions, 64 deletions
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index cd13e63852a..478dbde3fe6 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -121,7 +121,7 @@ ProcedureCreate(const char *procedureName,
/*
* sanity checks
*/
- Assert(PointerIsValid(prosrc) || PointerIsValid(prosqlbody));
+ Assert(PointerIsValid(prosrc));
parameterCount = parameterTypes->dim1;
if (parameterCount < 0 || parameterCount > FUNC_MAX_ARGS)
@@ -336,10 +336,7 @@ ProcedureCreate(const char *procedureName,
values[Anum_pg_proc_protrftypes - 1] = trftypes;
else
nulls[Anum_pg_proc_protrftypes - 1] = true;
- if (prosrc)
- values[Anum_pg_proc_prosrc - 1] = CStringGetTextDatum(prosrc);
- else
- nulls[Anum_pg_proc_prosrc - 1] = true;
+ values[Anum_pg_proc_prosrc - 1] = CStringGetTextDatum(prosrc);
if (probin)
values[Anum_pg_proc_probin - 1] = CStringGetTextDatum(probin);
else
@@ -874,26 +871,29 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
/* Postpone body checks if !check_function_bodies */
if (check_function_bodies)
{
+ tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
+ if (isnull)
+ elog(ERROR, "null prosrc");
+
+ prosrc = TextDatumGetCString(tmp);
+
/*
* Setup error traceback support for ereport().
*/
callback_arg.proname = NameStr(proc->proname);
- callback_arg.prosrc = NULL;
+ callback_arg.prosrc = prosrc;
sqlerrcontext.callback = sql_function_parse_error_callback;
sqlerrcontext.arg = (void *) &callback_arg;
sqlerrcontext.previous = error_context_stack;
error_context_stack = &sqlerrcontext;
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
- if (isnull)
+ /* If we have prosqlbody, pay attention to that not prosrc */
+ tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosqlbody, &isnull);
+ if (!isnull)
{
Node *n;
- tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosqlbody, &isnull);
- if (isnull)
- elog(ERROR, "null prosrc and prosqlbody");
-
n = stringToNode(TextDatumGetCString(tmp));
if (IsA(n, List))
querytree_list = castNode(List, n);
@@ -902,10 +902,6 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
}
else
{
- prosrc = TextDatumGetCString(tmp);
-
- callback_arg.prosrc = prosrc;
-
/*
* We can't do full prechecking of the function definition if there
* are any polymorphic input types, because actual datatypes of
@@ -1001,9 +997,6 @@ function_parse_error_transpose(const char *prosrc)
int newerrposition;
const char *queryText;
- if (!prosrc)
- return false;
-
/*
* Nothing to do unless we are dealing with a syntax error that has a
* cursor position.
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 199029b7a85..dc317c83afc 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -958,8 +958,17 @@ interpret_AS_clause(Oid languageOid, const char *languageName,
*sql_body_out = (Node *) q;
}
+ /*
+ * We must put something in prosrc. For the moment, just record an
+ * empty string. It might be useful to store the original text of the
+ * CREATE FUNCTION statement --- but to make actual use of that in
+ * error reports, we'd also have to adjust readfuncs.c to not throw
+ * away node location fields when reading prosqlbody.
+ */
+ *prosrc_str_p = pstrdup("");
+
+ /* But we definitely don't need probin. */
*probin_str_p = NULL;
- *prosrc_str_p = NULL;
}
else
{
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index b2e2df87733..2cf6dad7685 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -195,6 +195,8 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
palloc0(nParamExec * sizeof(ParamExecData));
}
+ /* We now require all callers to provide sourceText */
+ Assert(queryDesc->sourceText != NULL);
estate->es_sourceText = queryDesc->sourceText;
/*
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 642683843ed..39580f7d577 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -667,6 +667,15 @@ init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK)
procedureTuple,
Anum_pg_proc_prosrc,
&isNull);
+ if (isNull)
+ elog(ERROR, "null prosrc for function %u", foid);
+ fcache->src = TextDatumGetCString(tmp);
+
+ /* If we have prosqlbody, pay attention to that not prosrc. */
+ tmp = SysCacheGetAttr(PROCOID,
+ procedureTuple,
+ Anum_pg_proc_prosqlbody,
+ &isNull);
/*
* Parse and rewrite the queries in the function text. Use sublists to
@@ -678,18 +687,11 @@ init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK)
* plancache.c.
*/
queryTree_list = NIL;
- if (isNull)
+ if (!isNull)
{
Node *n;
List *stored_query_list;
- tmp = SysCacheGetAttr(PROCOID,
- procedureTuple,
- Anum_pg_proc_prosqlbody,
- &isNull);
- if (isNull)
- elog(ERROR, "null prosrc and prosqlbody for function %u", foid);
-
n = stringToNode(TextDatumGetCString(tmp));
if (IsA(n, List))
stored_query_list = linitial_node(List, castNode(List, n));
@@ -710,8 +712,6 @@ init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK)
{
List *raw_parsetree_list;
- fcache->src = TextDatumGetCString(tmp);
-
raw_parsetree_list = pg_parse_query(fcache->src);
foreach(lc, raw_parsetree_list)
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 526997327c6..d9ad4efc5ea 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -4317,32 +4317,37 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
ALLOCSET_DEFAULT_SIZES);
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 = NULL;
+ callback_arg.prosrc = src;
sqlerrcontext.callback = sql_inline_error_callback;
sqlerrcontext.arg = (void *) &callback_arg;
sqlerrcontext.previous = error_context_stack;
error_context_stack = &sqlerrcontext;
- /* Fetch the function body */
+ /* If we have prosqlbody, pay attention to that not prosrc */
tmp = SysCacheGetAttr(PROCOID,
func_tuple,
- Anum_pg_proc_prosrc,
+ Anum_pg_proc_prosqlbody,
&isNull);
- if (isNull)
+ if (!isNull)
{
Node *n;
List *querytree_list;
- tmp = SysCacheGetAttr(PROCOID, func_tuple, Anum_pg_proc_prosqlbody, &isNull);
- if (isNull)
- elog(ERROR, "null prosrc and prosqlbody for function %u", funcid);
-
n = stringToNode(TextDatumGetCString(tmp));
if (IsA(n, List))
querytree_list = linitial_node(List, castNode(List, n));
@@ -4354,10 +4359,6 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
}
else
{
- src = TextDatumGetCString(tmp);
-
- callback_arg.prosrc = src;
-
/*
* Set up to handle parameters while parsing the function body. We need a
* dummy FuncExpr node containing the already-simplified arguments to pass
@@ -4658,15 +4659,12 @@ sql_inline_error_callback(void *arg)
int syntaxerrposition;
/* If it's a syntax error, convert to internal syntax error report */
- if (callback_arg->prosrc)
+ syntaxerrposition = geterrposition();
+ if (syntaxerrposition > 0)
{
- syntaxerrposition = geterrposition();
- if (syntaxerrposition > 0)
- {
- errposition(0);
- internalerrposition(syntaxerrposition);
- internalerrquery(callback_arg->prosrc);
- }
+ errposition(0);
+ internalerrposition(syntaxerrposition);
+ internalerrquery(callback_arg->prosrc);
}
errcontext("SQL function \"%s\" during inlining", callback_arg->proname);
@@ -4778,6 +4776,7 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
Oid func_oid;
HeapTuple func_tuple;
Form_pg_proc funcform;
+ char *src;
Datum tmp;
bool isNull;
MemoryContext oldcxt;
@@ -4886,31 +4885,36 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
ALLOCSET_DEFAULT_SIZES);
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 = NULL;
+ callback_arg.prosrc = src;
sqlerrcontext.callback = sql_inline_error_callback;
sqlerrcontext.arg = (void *) &callback_arg;
sqlerrcontext.previous = error_context_stack;
error_context_stack = &sqlerrcontext;
- /* Fetch the function body */
+ /* If we have prosqlbody, pay attention to that not prosrc */
tmp = SysCacheGetAttr(PROCOID,
func_tuple,
- Anum_pg_proc_prosrc,
+ Anum_pg_proc_prosqlbody,
&isNull);
- if (isNull)
+ if (!isNull)
{
Node *n;
- tmp = SysCacheGetAttr(PROCOID, func_tuple, Anum_pg_proc_prosqlbody, &isNull);
- if (isNull)
- elog(ERROR, "null prosrc and prosqlbody for function %u", func_oid);
-
n = stringToNode(TextDatumGetCString(tmp));
if (IsA(n, List))
querytree_list = linitial_node(List, castNode(List, n));
@@ -4927,12 +4931,6 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
}
else
{
- char *src;
-
- src = TextDatumGetCString(tmp);
-
- callback_arg.prosrc = src;
-
/*
* Set up to handle parameters while parsing the function body. We can
* use the FuncExpr just created as the input for