Обсуждение: Throw error and ErrorContext question.

Поиск
Список
Период
Сортировка

Throw error and ErrorContext question.

От
"Gevik Babakhani"
Дата:
Hi,

Regarding the function parameter ref TODO:

I am trying to catch and copy an error to be re-thrown later.
I have the following questions:

1. Is the catch part in the following safe?
2. How do I re-throw the copied error when I am not in ErrorContext anymore?  I cannot use ReThrowError because of
Assert.

3. If I have to use something like: ereport(ERROR,mysaved_error->message ...
mysaved_error->detail ...... );  then how do I FreeErrorData(mysaved_error) after calling the ereport
above?

First:
....
MemoryContext parseMemCtx = CurrentMemoryContext;
....

Then:

/* Try to identify as a once-qualified column */
PG_TRY();
{node = qualifiedNameToVar(pstate, NULL, name1, name2, true,    cref->location);/* status set to 0 or 1
*/qualified_status= (node != NULL);
 
}
PG_CATCH();
{/* copy this error for later use */errorMemCtx =
CurrentMemoryContext;MemoryContextSwitchTo(parseMemCtx);qualifiedErrData=
CopyErrorData();FlushErrorState();MemoryContextSwitchTo(errorMemCtx);
/* status is set to error */qualified_status = 2;
}
PG_END_TRY();

------------------------------------------------
Gevik Babakhani

PostgreSQL NL       http://www.postgresql.nl
TrueSoftware BV     http://www.truesoftware.nl
------------------------------------------------



Re: Throw error and ErrorContext question.

От
Tom Lane
Дата:
"Gevik Babakhani" <pgdev@xs4all.nl> writes:
> I am trying to catch and copy an error to be re-thrown later.

This is certainly not the right way to go about solving your problem.
If you need to refactor some of the column lookup routines to make
this patch work, then do so, but don't try to make an already-thrown
error not be an error.  (One good reason for that is that you don't
really know what error you are catching --- it might be a report
of some low-level problem such as out-of-memory, for instance.)

The pattern you might want to follow is adding a noError boolean
parameter to functions you want to be able to get failure returns
back from.
        regards, tom lane


Re: Throw error and ErrorContext question.

От
"Gevik Babakhani"
Дата:
Thank you Tom.

I have considered a noError boolean too.

but please considered the following:

step 1: call qualifiedNameToVar(noError = true), which generates an error 
but gets suppressed by noError parameter.

step 2: process function parameter name for 
funct1.param1, check "funct1" == <the name of the current function>,
which "funct1" is unknown/ambiguous (the name of the current function was
"func" for example).

In the case above I thought I somehow re-throw the error that
was originally generated at step 1.
Regards,
Gevik.

------------------------------------------------
Gevik Babakhani

PostgreSQL NL       http://www.postgresql.nl
TrueSoftware BV     http://www.truesoftware.nl
------------------------------------------------

> -----Original Message-----
> From: pgsql-hackers-owner@postgresql.org 
> [mailto:pgsql-hackers-owner@postgresql.org] On Behalf Of Tom Lane
> Sent: Thursday, November 08, 2007 12:25 AM
> To: Gevik Babakhani
> Cc: pgsql-hackers@postgresql.org
> Subject: Re: [HACKERS] Throw error and ErrorContext question. 
> 
> "Gevik Babakhani" <pgdev@xs4all.nl> writes:
> > I am trying to catch and copy an error to be re-thrown later.
> 
> This is certainly not the right way to go about solving your problem.
> If you need to refactor some of the column lookup routines to 
> make this patch work, then do so, but don't try to make an 
> already-thrown error not be an error.  (One good reason for 
> that is that you don't really know what error you are 
> catching --- it might be a report of some low-level problem 
> such as out-of-memory, for instance.)
> 
> The pattern you might want to follow is adding a noError 
> boolean parameter to functions you want to be able to get 
> failure returns back from.
> 
>             regards, tom lane
> 
> ---------------------------(end of 
> broadcast)---------------------------
> TIP 6: explain analyze is your friend
> 



Re: Throw error and ErrorContext question.

От
Tom Lane
Дата:
"Gevik Babakhani" <pgdev@xs4all.nl> writes:
> I have considered a noError boolean too.

> but please considered the following:

> step 1: call qualifiedNameToVar(noError = true), which generates an error 
> but gets suppressed by noError parameter.

> step 2: process function parameter name for 
> funct1.param1, check "funct1" == <the name of the current function>,
> which "funct1" is unknown/ambiguous (the name of the current function was
> "func" for example).

> In the case above I thought I somehow re-throw the error that
> was originally generated at step 1.

Yeah, you'd throw the same error number and message as that routine
would have thrown, but matching that is not rocket science ;-).
I don't see any value in trying to have only one instance of the
ereport() call instead of two --- it's going to cost you *more*
lines of code and *more* intellectual complexity to try to trap
and re-throw the error than it will cost to just have two identical
ereport() calls.

Although quite frankly I don't see any need to be touching
qualifiedNameToVar at all.  It's already defined to return NULL if it
doesn't find the name anyplace in the query, which seems to me to be
what you want anyway.  The only non-internal error it might raise is
"ambiguous name" which is fine.  That's an error condition, and the
possibility that there is a function variable visible at an outer name
scoping level doesn't make it not an error.

The place where you need to be refactoring is probably in or around
the transformWholeRowRef/ParseFuncOrColumn sequence.

One thing that we need to think about is what is the priority of
function-variable matching compared to implicit RTE creation.  I'm
inclined to think we should allow function variables to go first...
        regards, tom lane


Re: Throw error and ErrorContext question.

От
"Gevik Babakhani"
Дата:
Hello Tom,

I have a solution by adding two parameters (skip_error and
skipped_sqlerrorcode)
to qualifiedNameToVar,transformWholeRowRef,addImplicitRTE,warnAutoRange.

It still needs a bit of refining before I can send the patch for full
review.

When in context of parsing functions for refname.colname:
If refname is unknown, skip_error=true makes sure the error is skipped. 
I use skipped_sqlerrorcode to record what went wrong in qualifiedNameToVar
and transformWholeRowRef.
The effect is that de default behavior, including implicit RTE is kept.

For example, when parsing the function below:

1. qualifiedNameToVar skips the error for the unknown refx and sets
skipped_sqlerrorcode.
2. transformWholeRowRef also skips the error for the unknown refx and sets
skipped_sqlerrorcode.
3. at this point the callabck also returns with error, because refx is not
the function's name (myfunc)

So I think an error like "missing FROM-clause entry for table "refx" would
be appropriate here
In normal circumstance qualifiedNameToVar would have reported the same.

create function myfunc(par1 integer)
$$ select refx.par1 from tbl1 a where a.field1 = 1;
$$          
language sql;

I am working on all possible test scenarios I can think of to be sure the
implementations is
working correctly.

Regards,
Gevik.




------------------------------------------------
Gevik Babakhani

PostgreSQL NL       http://www.postgresql.nl
TrueSoftware BV     http://www.truesoftware.nl
------------------------------------------------

> -----Original Message-----
> From: Tom Lane [mailto:tgl@sss.pgh.pa.us] 
> Sent: Thursday, November 08, 2007 2:32 AM
> To: Gevik Babakhani
> Cc: pgsql-hackers@postgresql.org
> Subject: Re: [HACKERS] Throw error and ErrorContext question. 
> 
> "Gevik Babakhani" <pgdev@xs4all.nl> writes:
> > I have considered a noError boolean too.
> 
> > but please considered the following:
> 
> > step 1: call qualifiedNameToVar(noError = true), which generates an 
> > error but gets suppressed by noError parameter.
> 
> > step 2: process function parameter name for funct1.param1, check 
> > "funct1" == <the name of the current function>, which "funct1" is 
> > unknown/ambiguous (the name of the current function was "func" for 
> > example).
> 
> > In the case above I thought I somehow re-throw the error that was 
> > originally generated at step 1.
> 
> Yeah, you'd throw the same error number and message as that 
> routine would have thrown, but matching that is not rocket 
> science ;-).
> I don't see any value in trying to have only one instance of the
> ereport() call instead of two --- it's going to cost you 
> *more* lines of code and *more* intellectual complexity to 
> try to trap and re-throw the error than it will cost to just 
> have two identical
> ereport() calls.
> 
> Although quite frankly I don't see any need to be touching 
> qualifiedNameToVar at all.  It's already defined to return 
> NULL if it doesn't find the name anyplace in the query, which 
> seems to me to be what you want anyway.  The only 
> non-internal error it might raise is "ambiguous name" which 
> is fine.  That's an error condition, and the possibility that 
> there is a function variable visible at an outer name scoping 
> level doesn't make it not an error.
> 
> The place where you need to be refactoring is probably in or 
> around the transformWholeRowRef/ParseFuncOrColumn sequence.
> 
> One thing that we need to think about is what is the priority 
> of function-variable matching compared to implicit RTE 
> creation.  I'm inclined to think we should allow function 
> variables to go first...
> 
>             regards, tom lane
>