Updated on 2024-05-07 GMT+08:00

DBE_PLDEBUGGER Schema

DBE_PLDEBUGGER Schema system functions are used to debug stored procedures. This chapter describes the APIs supported by DBE_PLDEBUGGER Schema. Only the administrator has the permission to execute these debugging APIs, but does not have the permission to modify or create functions in this schema. Common users can debug only non-system functions in the public schema or user-created schema. Common users are not allowed to debug system functions.

When a user is created in the function body, the plaintext password is returned when attach, next, continue, info_code, step, info_breakpoint, backtrace or finish is called. You are advised not to create a user in the function body.

The administrator can run the following command to grant the gs_role_pldebugger role and debugger permissions to a user:

GRANT gs_role_pldebugger to user;

Two clients are required to connect to the database. One client is responsible for executing the debugging API as the debug end, and the other client is responsible for executing the debugging function to control the execution of stored procedures on the server. Example:

  • Prepare for debugging.

    Use PG_PROC to find the OID of the stored procedure to be debugged and execute DBE_PLDEBUGGER.turn_on(oid). In this case, the client functions as the server.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    gaussdb=# CREATE OR REPLACE PROCEDURE test_debug ( IN  x INT) 
    AS  
    BEGIN
        INSERT INTO t1 (a) VALUES (x);
        DELETE FROM t1 WHERE a = x;
    END;
    /
    CREATE PROCEDURE
    gaussdb=# SELECT OID FROM PG_PROC WHERE PRONAME='test_debug';
      oid
    -------
     16389
    (1 row)
    gaussdb=# SELECT * FROM DBE_PLDEBUGGER.turn_on(16389);
     nodename | port
    ----------+------
     datanode |    0
    (1 row)
    
  • Start debugging.

    When the server executes the stored procedure, the server hangs before the first SQL statement in the stored procedure and waits for the debugging message sent by the debug end. Debugging is supported only by directly executing a stored procedure and cannot be achieved by calling an executed stored procedure through a trigger.

    1
    gaussdb=# call test_debug(1);
    

    Start another client as the debug end and call DBE_PLDEBUGGER.attach to attach with the stored procedure for debugging based on the data returned by turn_on.

    1
    2
    3
    4
    5
    gaussdb=# SELECT * FROM DBE_PLDEBUGGER.attach('datanode',0);
     funcoid |  funcname  | lineno |              query
    ---------+------------+--------+----------------------------------
       16389 | test_debug |      3 |   INSERT INTO t1 (a) VALUES (x);
    (1 row)
    

    Execute the next statement on the client where the attach operation is performed.

    1
    2
    3
    4
    5
    gaussdb=# SELECT * FROM DBE_PLDEBUGGER.next();
     funcoid |  funcname  | lineno |        query
    ---------+------------+--------+----------------------
       16389 | test_debug |      0 | [EXECUTION FINISHED]
    (1 row)
    

    Execute the following variable operations on the client where the attach command is performed.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    gaussdb=# SELECT * FROM DBE_PLDEBUGGER.info_locals(); -- Print all variables.
     varname | vartype | value | package_name | isconst
    ---------+---------+-------+--------------+---------
     x       | int4    | 1     |              | f
    (1 row)
    gaussdb=# SELECT * FROM DBE_PLDEBUGGER.set_var('x', 2); -- Assign a value to a variable.
     set_var
    ---------
     t
    (1 row)
    gaussdb=# SELECT * FROM DBE_PLDEBUGGER.print_var('x'); -- Print a single variable.
     varname | vartype | value | package_name | isconst
    ---------+---------+-------+--------------+---------
     x       | int4    | 2     |              | f
    (1 row)
    

    Directly execute the stored procedure that is being debugged.

    1
    2
    3
    4
    5
    gaussdb=# SELECT * FROM DBE_PLDEBUGGER.continue();
     funcoid |  funcname  | lineno |        query
    ---------+------------+--------+----------------------
       16389 | test_debug |      0 | [EXECUTION FINISHED]
    (1 row)
    

    Exit the stored procedure that is being debugged and do not execute statements that have not been executed before.

    1
    2
    3
    4
    5
    gaussdb=# SELECT * FROM DBE_PLDEBUGGER.abort();
     abort
    -------
     t
    (1 row)
    

    View the code information on the client and identify the line number of the breakpoint that can be set.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    gaussdb=# SELECT * FROM DBE_PLDEBUGGER.info_code(16389);
     lineno |                           query                           | canbreak
    --------+-----------------------------------------------------------+----------
            | CREATE OR REPLACE PROCEDURE public.test_debug( IN  x INT) | f
          1 | AS  DECLARE                                               | f
          2 | BEGIN                                                     | f
          3 |     INSERT INTO t1 (a) VALUES (x);                        | t
          4 |     DELETE FROM t1 WHERE a = x;                           | t
          5 | END;                                                      | f
          6 | /                                                         | f
    (7 rows)
    

    Sets a breakpoint.

    1
    2
    3
    4
    5
    gaussdb=# SELECT * FROM DBE_PLDEBUGGER.add_breakpoint(16389,4);
     breakpointno 
    --------------
                0
    (1 row)
    

    View the breakpoint information.

    1
    2
    3
    4
    5
    gaussdb=# SELECT * FROM DBE_PLDEBUGGER.info_breakpoints();
     breakpointno | funcoid | lineno |              query              | enable
    --------------+---------+--------+---------------------------------+--------
                0 |   16389 |      4 |     DELETE FROM t1 WHERE a = x; | t
    (1 row)
    

    Execute to the breakpoint.

    1
    2
    3
    4
    5
    gaussdb=# SELECT * FROM DBE_PLDEBUGGER.continue();
     funcoid |  funcname  | lineno |              query
    ---------+------------+--------+---------------------------------
       16389 | test_debug |      4 |     DELETE FROM t1 WHERE a = x;
    (1 row)
    

    After the stored procedure is executed, the debugging automatically exits. To debug the stored procedure again, you need to attach again. If the server does not need to be debugged, run the turn_off command to disable the debugging or exit the session. For details about the debugging APIs, see the following table.

    Table 1 DBE_PLDEBUGGER

    API

    Description

    DBE_PLDEBUGGER.turn_on

    Called by the server, indicating that the stored procedure can be debugged. After the API is called, the stored procedure is hung to wait for debugging information.

    DBE_PLDEBUGGER.turn_off

    Called by the server, indicating that debugging the stored procedure is disabled.

    DBE_PLDEBUGGER.local_debug_server_info

    Called by the server to print all stored procedures that have been turned on in the current session.

    DBE_PLDEBUGGER.attach

    Called by the debug end to attach with the stored procedure that is being debugged.

    DBE_PLDEBUGGER.info_locals

    Called by the debug end to print the current values of variables in the stored procedure that is being debugged.

    DBE_PLDEBUGGER.next

    Called by the debug end to execute the next step.

    DBE_PLDEBUGGER.continue

    Called by the debug end to continue the execution until the breakpoint or stored procedure ends.

    DBE_PLDEBUGGER.abort

    Called by the debug end to stop debugging. The server reports a long jump error.

    DBE_PLDEBUGGER.print_var

    Called by the debug end to print the current values of specified variables in the stored procedure that is being debugged.

    DBE_PLDEBUGGER.info_code

    Called by the debug end or server to print the source statement of a specified stored procedure and the line number corresponding to each line.

    DBE_PLDEBUGGER.step

    Called by the debug end to execute step by step.

    DBE_PLDEBUGGER.add_breakpoint

    Called by the debug end to add a breakpoint.

    DBE_PLDEBUGGER.delete_breakpoint

    Called by the debug end to delete a breakpoint.

    DBE_PLDEBUGGER.info_breakpoints

    Called by the debug end to view all breakpoints.

    DBE_PLDEBUGGER.backtrace

    Called by the debug end to check the current call stack.

    DBE_PLDEBUGGER.enable_breakpoint

    Called by the debug end to enable breakpoints.

    DBE_PLDEBUGGER.disable_breakpoint

    Called by the debug end to disable breakpoints.

    DBE_PLDEBUGGER.finish

    Called by the debug end to continue the debugging until the breakpoint is reached or the upper-layer call stack is returned.

    DBE_PLDEBUGGER.set_var

    Called by the debug end to assign a value to a variable.