Thread

  1. proposal: enhanced get diagnostics statement

    Pavel Stehule <pavel.stehule@gmail.com> — 2011-05-21T20:05:01Z

    Hello
    
    This proposal is related to exception processing. Inside exception
    handler we can get some basic info about exception - message text and
    message code. There are other fields - but these fields are no
    available now in PL/pgSQL. The cheap access to fields inside ErrorData
    structure can be implemented inside GET DIAGNOSTICS statements - this
    statement is created for this purpose. I propose a new thee
    identifiers, that can be used there: ERROR_DETAIL, ERROR_HINT and
    ERROR_CONTEXT. Using is simple:
    
    CREATE OR REPLACE FUNCTION foo()
    RETURNS void AS $$
    DECLARE
      _detail text;
      _hint text;
      _context text;
    BEGIN
      RAISE EXCEPTION 'some message'
        USING DETAIL = 'some message specific description',
              HINT = 'some hint related to messgae';
    
    EXCEPTION WHEN OTHERS THEN
      GET DIAGNOSTICS _detail = ERROR_DETAIL,
                      _hint = ERROR_HINT,
                      _context = ERROR_CONTEXT;
    
      RAISE WARNING 'caught message: %', SQLERRM
        USING DETAIL = e'\ncaught detail: ' || _detail ||
                       e'\ncaught hint: ' || _hint ||
                       e'\ncaught context: ' || _context;
    
    END;
    $$ LANGUAGE plpgsql;
    SELECT foo();
    
    
    A implementation of ERROR_DETAIL and ERROR_HINT is simple and without
    possible performance issues. It has zero impact on performance.
    
    A implementation of ERROR_CONTEXT is not without impact on
    performance, because context should be collected when exception is
    caught. One solution is removing a ERROR_CONTEXT from proposal. Second
    solution can be a design of enhanced syntax for exception trap like
    (it means - collect CONTEXT when exception is handled)
    
    BEGIN
      EXCEPTION (ERROR_CONTEXT=true) WHEN OTHERS THEN
        ...
    END
    
    Getting a context can be a problem - but it is very important
    information, that can significantly help with exception's explanation.
    
    ideas, notes?
    
    Regards
    
    Pavel Stehule
    
  2. Re: proposal: enhanced get diagnostics statement

    Alvaro Herrera <alvherre@commandprompt.com> — 2011-05-21T21:57:47Z

    Excerpts from Pavel Stehule's message of sáb may 21 16:05:01 -0400 2011:
    
    > A implementation of ERROR_CONTEXT is not without impact on
    > performance, because context should be collected when exception is
    > caught. One solution is removing a ERROR_CONTEXT from proposal. Second
    > solution can be a design of enhanced syntax for exception trap like
    > (it means - collect CONTEXT when exception is handled)
    
    I don't understand why we should worry about this.  I mean, if you don't
    catch the error, you have to form errcontext anyway.  Why is it a
    problem to generate it when the exception is caught?
    
    -- 
    Álvaro Herrera <alvherre@commandprompt.com>
    The PostgreSQL Company - Command Prompt, Inc.
    PostgreSQL Replication, Consulting, Custom Development, 24x7 support
    
    
  3. Re: proposal: enhanced get diagnostics statement

    Pavel Stehule <pavel.stehule@gmail.com> — 2011-05-22T05:06:04Z

    2011/5/21 Alvaro Herrera <alvherre@commandprompt.com>:
    > Excerpts from Pavel Stehule's message of sáb may 21 16:05:01 -0400 2011:
    >
    >> A implementation of ERROR_CONTEXT is not without impact on
    >> performance, because context should be collected when exception is
    >> caught. One solution is removing a ERROR_CONTEXT from proposal. Second
    >> solution can be a design of enhanced syntax for exception trap like
    >> (it means - collect CONTEXT when exception is handled)
    >
    > I don't understand why we should worry about this.  I mean, if you don't
    > catch the error, you have to form errcontext anyway.  Why is it a
    > problem to generate it when the exception is caught?
    
    Generating context means a calling a few functions with some string
    operations - because in this moment is limited functionality, there
    isn't too much operations - but it can be changed - PL/PSM dumps all
    local variables, ...
    
    somebody uses a exception trapping like mechanism for ignoring errors
    
    FOR r IN SELECT ..
    LOOP
      BEGIN
        INSERT INTO ...
      EXCEPTION WHEN OTHERS THEN
        /* do nothing */
      END;
    END LOOP;
    
    or some body can do
    
    BEGIN
      ...
    EXCEPTION WHEN OTHERS THEN
      RAISE WARNING ' .....';
      RAISE;
    END;
    
    In last case the context can wanted - so it cannot be hard problem.
    But first case is problem and we has not different way how to do it.
    
    Maybe we can use a simple optimization
    
    when function doesn't contain a GET DIAGNOSTICS statement with
    ERROR_CONTEXT field, then we can not collect a context. Only when
    function has GET DIAGNOSTICS with ERROR_CONTEXT we will take context
    info. This strategy ensure, so there will not be negative performance
    effect on current applications.
    
    Pavel
    
    >
    > --
    > Álvaro Herrera <alvherre@commandprompt.com>
    > The PostgreSQL Company - Command Prompt, Inc.
    > PostgreSQL Replication, Consulting, Custom Development, 24x7 support
    >
    
    
  4. Re: proposal: enhanced get diagnostics statement

    Tom Lane <tgl@sss.pgh.pa.us> — 2011-05-22T17:58:37Z

    Alvaro Herrera <alvherre@commandprompt.com> writes:
    > Excerpts from Pavel Stehule's message of sb may 21 16:05:01 -0400 2011:
    >> A implementation of ERROR_CONTEXT is not without impact on
    >> performance, because context should be collected when exception is
    >> caught. One solution is removing a ERROR_CONTEXT from proposal. Second
    >> solution can be a design of enhanced syntax for exception trap like
    >> (it means - collect CONTEXT when exception is handled)
    
    > I don't understand why we should worry about this.  I mean, if you don't
    > catch the error, you have to form errcontext anyway.  Why is it a
    > problem to generate it when the exception is caught?
    
    The argument is nonsense anyway, because it's based on an incorrect
    implementation.  exec_stmt_block has no business calling the error
    context stack --- that was already done in errfinish.  Worse, by the time
    you get control back from the longjmp, you probably have popped off some
    of the stack variables that those links would need to use.  If that code
    didn't dump core in testing, it's likely only because it wasn't tested
    very much.
    
    
    A bigger issue is that it seems like this is an abuse of GET
    DIAGNOSTICS.  The existing options of that statement report on the
    results of the immediately preceding command.  If we add options that
    report on the last error, then we will have a situation where some of
    the options have different "lifespan" than others.  That seems pretty
    klugy and confusing to me.
    
    I'm not real sure what to do instead.  If we were actually trying to
    follow precedent here, what we'd be looking to do is add more
    auto-initialized variables like SQLERRM inside recovery blocks.
    That would again have the issue of wasting cycles in code that never
    actually looked at the variables.  (But I wonder if we couldn't tweak
    plpgsql so that we could determine at compile time which variables have
    references and which don't, so that we'd not bother filling in variables
    that weren't used.  Or somehow arrange to only do the work when the
    variable's value is accessed.)
    
    			regards, tom lane
    
    
  5. Re: proposal: enhanced get diagnostics statement

    Pavel Stehule <pavel.stehule@gmail.com> — 2011-05-22T18:27:41Z

    2011/5/22 Tom Lane <tgl@sss.pgh.pa.us>:
    > Alvaro Herrera <alvherre@commandprompt.com> writes:
    >> Excerpts from Pavel Stehule's message of sáb may 21 16:05:01 -0400 2011:
    >>> A implementation of ERROR_CONTEXT is not without impact on
    >>> performance, because context should be collected when exception is
    >>> caught. One solution is removing a ERROR_CONTEXT from proposal. Second
    >>> solution can be a design of enhanced syntax for exception trap like
    >>> (it means - collect CONTEXT when exception is handled)
    >
    >> I don't understand why we should worry about this.  I mean, if you don't
    >> catch the error, you have to form errcontext anyway.  Why is it a
    >> problem to generate it when the exception is caught?
    >
    > The argument is nonsense anyway, because it's based on an incorrect
    > implementation.  exec_stmt_block has no business calling the error
    > context stack --- that was already done in errfinish.  Worse, by the time
    > you get control back from the longjmp, you probably have popped off some
    > of the stack variables that those links would need to use.  If that code
    > didn't dump core in testing, it's likely only because it wasn't tested
    > very much.
    >
    
    It works with copy of ErrorData, that is available in estate - when
    estate->cur_err is NOT NULL. I am not sure about "context" - the my
    implementation is strange, but access to detail and hint is without
    any known problems. Please, can you specify a situation, when access
    to ErrorData fields can be broken?
    
    >
    > A bigger issue is that it seems like this is an abuse of GET
    > DIAGNOSTICS.  The existing options of that statement report on the
    > results of the immediately preceding command.  If we add options that
    > report on the last error, then we will have a situation where some of
    > the options have different "lifespan" than others.  That seems pretty
    > klugy and confusing to me.
    >
    
    It doesn't mean a "last error", it means a error in current handler
    block - because life of cur_err is limited per block. But you has
    true. ANSI SQL defines "stacked diagnostics" statement for access to
    error info about outer exceptions. The expected information is
    available only when GET STATEMENT is first statement of exception
    handler. If isn't first statement, you should to use a stacked GET
    DIAGNOSTICS statement.
    
    > I'm not real sure what to do instead.  If we were actually trying to
    > follow precedent here, what we'd be looking to do is add more
    > auto-initialized variables like SQLERRM inside recovery blocks.
    > That would again have the issue of wasting cycles in code that never
    > actually looked at the variables.  (But I wonder if we couldn't tweak
    > plpgsql so that we could determine at compile time which variables have
    > references and which don't, so that we'd not bother filling in variables
    > that weren't used.  Or somehow arrange to only do the work when the
    > variable's value is accessed.)
    
    Any new magic values are not good - hard to enhance it. The correct
    way is implementation GET DIAGNOSTICS statement based on ANSI/SQL. But
    should be implemented different, it has to return exception info, only
    when GD is first statement of handler block. Is it less confusing for
    you?
    
    Some optimization for SQLERRM can be done still - I am doing some
    similar in PL/PSM and it is possible.
    
    Regards
    
    Pavel Stehule
    
    
    >
    >                        regards, tom lane
    >