Skip to content

fix(seekdb): DIMA-2026051300116077401#896

Open
ep-12221 wants to merge 1 commit into
masterfrom
issue/2026051300116077401
Open

fix(seekdb): DIMA-2026051300116077401#896
ep-12221 wants to merge 1 commit into
masterfrom
issue/2026051300116077401

Conversation

@ep-12221

Copy link
Copy Markdown
Contributor

Task Description

Fix an issue where the detailed error message (including the object name) is lost when a DML statement referencing a non-existent object (e.g., SELECT t.notable.*) is executed inside a trigger or stored procedure body, resulting in a generic "Unknown table" error.

Solution Description

Root Cause: The regression was introduced by commit 676b4e2dc86 (2026-05-06), which added OB_ERR_BAD_TABLE to the deferred-error list in ObPLResolver::resolve. In the deferred-error branch, the failed statement is replaced with a PL_SIGNAL stub, which only saves the error_code_, ob_error_code_, and sql_state_, but does not save the formatted user message already present in the thread-local ObWarningBuffer. Consequently, at runtime, only the generic template from ob_errpkt_strerror ("Unknown table") is used, losing the specific object name.

Fix Details:

  1. src/pl/ob_pl_resolver.cpp: When entering the deferred-error branch, before destroying the failed statement, if wb->get_err_code == save_ret, copy wb->get_err_msg into the PL parsing allocator and store it in a new ObPLSignalStmt::user_msg_ field.
  2. src/pl/ob_pl_stmt.h: Added a common::ObString user_msg_ field and corresponding get_user_msg/set_user_msg/has_user_msg methods to the ObPLSignalStmt class.
  3. src/sql/ob_spi.{h,cpp}: Added ObSPIService::spi_pl_set_user_error_msg(ctx, err_code, sql_state, msg, msg_len) to write the message (truncated to ObWarningBuffer::WarningItem::STR_LEN) back to the current thread-local warning buffer.
  4. src/pl/ob_pl_code_generator.{h,cpp}: Registered the LLVM function in init_spi_service. In visit(ObPLSignalStmt), for signals where has_user_msg is true, generate a call to the new SPI function before generate_exception. The err_code parameter uses s.get_ob_error_code (the OB internal errno, e.g., -5201) to align with the check in send_error_packet.
  5. src/pl/ob_pl.cpp: Registered the symbol spi_pl_set_user_error_msg via WRAP_SPI_CALL for LLVM JIT linking.

Behavior Comparison (macOS, mysql-mode):

  • Before fix: ERROR 42S02: Unknown table
  • After fix: ERROR 42S02: Unknown table 't.notable' (Matches Linux behavior and the expected result in tools/deploy/mysql_test/test_suite/ddl/r/mysql/drop.result:104)

Scope of Impact:

  • Only affects the deferred-error branch for specific error codes (OB_ERR_FUNCTION_UNKNOWN, OB_ERR_SP_WRONG_ARG_NUM, OB_ERR_SP_DOES_NOT_EXIST, OB_ERR_GET_STACKED_DIAGNOSTICS, OB_ERR_RESIGNAL_WITHOUT_ACTIVE_HANDLER, OB_ERR_BAD_TABLE) when a matching user message exists in the warning buffer.
  • When user_msg_ is empty, all code paths behave identically to before the fix.
  • Normal SIGNAL/RESIGNAL paths (with explicit MESSAGE_TEXT) are unaffected.

Passed Regressions

Local Validation Environment: macOS arm64, build_release/src/observer/seekdb, port 12881.

  1. Reproduced and verified the fix (focus test):
    mysqltest < focus.test
    ...
    INSERT INTO table1 VALUES (1);
    ERROR 42S02: Unknown table 't.notable' <-- Correctly includes object name after fix
    DROP TABLE table1,table2;
    ok
    
  2. Full regression for ddl.drop:
    mysqltest --result-file=tools/deploy/mysql_test/test_suite/ddl/r/mysql/drop.result \
    < tools/deploy/mysql_test/test_suite/ddl/t/drop.test
    ddl.drop: exit=0 -- ok
    
  3. Adjacent SIGNAL/RESIGNAL/trigger tests show no new regressions:
    • Running mysql8_t_1/signal.test and mysql8_t_1/signal_demo1.test before and after the patch showed diffs only in timestamps, confirming existing failures are unrelated and no new mismatches were introduced.
    • mysql8_t_1/signal_code.test: exit=0 (ok).
  4. Runtime trace self-check (temporary build with DEBUG logs):
    • Parsing phase log: DEBUG: captured saved_user_msg for deferred SIGNAL(save_ret=-5201, saved_user_msg=Unknown table 't.notable') – Confirmed successful capture from warning buffer.
    • Runtime phase log: DEBUG: spi_pl_set_user_error_msg called(err_code=-5201, msg_len=25, ObString(msg_len, msg)=Unknown table 't.notable') – Confirmed LLVM JIT call to SPI with OB internal errno parameter.
    • These DEBUG logs were removed for the final commit.
      Commit: e4be58867b8 pushed to issue/2026051300116077401, awaiting orchestrator execution of ob flow checkin / merge-review / core-test.

Upgrade Compatibility

Other Information

DIMA: 2026051300116077401

Release Note

Fixed an issue where executing a DML statement referencing a non-existent object inside a trigger or stored procedure body resulted in a generic error message (e.g., "Unknown table") instead of the specific message containing the object name (e.g., "Unknown table 't.notable'").

…st of deferred errors during PL parsing, when a non-existent object is referenced in a trigger/SP body, the formatted user message (e.g., "Unknown table 't.notable'") originally written to the thread-local warning buffer by `ob_select_resolver.cpp` via `LOG_USER_ERROR(OB_ERR_BAD_TABLE, table_name.length, table_name.ptr)` was being discarded at the end of parsing. At runtime, the PL_SIGNAL stub would only regenerate the bare template "Unknown table", losing the object name.

Fix:
1. In `ObPLResolver::resolve`, when entering the deferred-error branch, capture the formatted message from the warning buffer that matches the current errno and store it in the new `ObPLSignalStmt::user_msg_` (held by the PL function allocator).
2. In `ObPLCodeGenerateVisitor::visit(ObPLSignalStmt)`, before generating the exception, for signals that have a `user_msg_`, generate a call to the new SPI `spi_pl_set_user_error_msg` to write the message back to the warning buffer. The error code uses `ob_error_code_` (the internal OB errno) so that the comparison `wb->get_err_code == err` at `ObMPPacketSender::send_error_packet` succeeds and reads this formatted message.
3. Add the implementation for `spi_pl_set_user_error_msg` in `ob_spi.cpp` / `ob_spi.h` and register the LLVM symbol in `ObPL::init`.

Scope of impact: Only affects scenarios under the deferred-error branch (OB_ERR_FUNCTION_UNKNOWN / OB_ERR_SP_WRONG_ARG_NUM / OB_ERR_SP_DOES_NOT_EXIST / OB_ERR_GET_STACKED_DIAGNOSTICS / OB_ERR_RESIGNAL_WITHOUT_ACTIVE_HANDLER / OB_ERR_BAD_TABLE) where there is a user message in the warning buffer during the parsing phase. When `user_msg_` is empty, all paths remain consistent with the pre-change behavior. The regular user SIGNAL/RESIGNAL path is unchanged.

DIMA: 2026051300116077401

Co-Authored-By: Claude Opus 4 <[REDACTED_EMAIL]>
@ep-12221

Copy link
Copy Markdown
Contributor Author

The mapping Dima issue is: [macOS] [introduced after 20260331] [mysqltest] Trigger referencing non-existent table 't.notable' reports an error inconsistent with Linux seekdb.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant