Fix MySQL search_RMTObject and search_RMCObject end-to-end#5
Open
patrickoshaughnessey wants to merge 9 commits into
Open
Fix MySQL search_RMTObject and search_RMCObject end-to-end#5patrickoshaughnessey wants to merge 9 commits into
patrickoshaughnessey wants to merge 9 commits into
Conversation
- call_RMRoot_Event_RMCObject_Close: fix undefined variable twRMCObjectIx_Close (should be twRMCObjectIx), which caused all celestial scene deletion to fail - set_RMCObject_RMTObject_Open: remove DECLARE nResult that shadows OUT parameter, causing NULL return on terrestrial object creation under celestial parents - set_RMRoot_RMTObject_Open: same OUT parameter shadowing fix - set_RMTObject_RMTObject_Open: same OUT parameter shadowing fix - set_RMTObject_Transform: same OUT parameter shadowing fix
Brings the fork current through upstream's 11 commits since Feb 2026: - SA reference updates, version bumps, doc additions - Schema rename tmStart -> tmOrigin plus migration 002 - Upstream 'Bug fix' commits touching Delete_Descendants procs and Database.sql Preserves fork-only fix c3b5458 (stored proc bugs blocking object create/delete) since its four files have no overlap with upstream changes. Pending fork PR MetaversalCorp#2 (fix/rmtsubsurface-delete-wipe) remains on its own branch and is not affected.
Complete the fix described in c3b5458's commit message, which listed this file but didn't include its changes. Applies the same nMatrixResult treatment used in the sibling RMTObject_Open / Transform procs so matrix subcall return codes don't stomp the outer procedure's OUT parameter.
…n changes Reverts the nMatrixResult additions in the four _Open/Transform procs (c3b5458 + a260654) — those were surgical against the pre-79c33e5 shadowing-DECLARE state; upstream dropped the shadow DECLARE directly in 79c33e5 and rerouting matrix subcalls through a second local variable no longer addresses any bug. Reverts the c3b5458 line 60 change in call_RMRoot_Event_RMCObject_Close (which upstream's 79c33e5 made valid by renaming the IN param). Applies the actual remaining bug: line 82 of the same proc still referenced the pre-rename identifier twRMCObjectIx, which is undefined in the current scope. Changes it to the post-rename IN parameter twRMCObjectIx_Close. Mirrors the SQL Server version of the same proc, which uses @twRMCObjectIx_Close at the equivalent position.
The ELSE branch (taken when the parent is not an RMTObject — i.e. for sectors directly under root) used a `SELECT ... INTO ...` pattern with `mr.d23` and `mr.d22` listed in the wrong order against the `d20, d21, d22, d23` INTO list. In MySQL, `SELECT ... INTO ...` is positional, so this silently assigned local `d22 := mr.d23` and `d23 := mr.d22`. The matrix-to-transform extraction then computed `Transform_Scale_dZ = SQRT(... d22²) = 0` and `Transform_Position_dZ = d23` from the wrong column, persisting `scale.z = 0` and `position.z = <translation z>` to the RMTObject row even though the underlying matrix was correct. Reads from the row returned the corrupt values; subscriptions propagated them to clients. The SQL Server version had the same out-of-order textual layout but the syntax there is `@var = column` (assignment by name, not position), so it was cosmetic only. Fix both for consistency so the parallel MySQL bug isn't reintroduced by copying the SQL Server pattern. Verified on a live database: a sector whose row had been corrupted self-healed to the correct values on the next transform update after the procedure was reloaded.
Pass parent context (ObjectHead_Parent_*) to call_RMTObject_Validate_Type from set_RMTObject_Type. Without parent args, validation could not check the parent class/index context. Fixes set_RMTObject_Type validation context bug.
Fix swapped d22/d23 in call_RMTMatrix_Relative ELSE branch. This fix has been hot-patched on production (spatial2) since 2026-05-05; this merge brings it into the official line.
Four related bugs prevented every RMTObject:search and RMCObject:search
call from succeeding on MySQL deployments. This commit fixes all four
at the source level so neither proc requires special sql_mode or
session collation at deploy time.
1. PARAM-COUNT MISMATCH (caught at protocol layer)
The MSF node framework calls every proc with the form:
CALL <proc>(sIPAddress, twRPersonaIx, ...aData..., @Result);
SELECT @Result AS result;
That's 2 + len(aData) + 1 = 8 args for these search procs. Both procs
were declared with 7 IN params and 0 OUT params, so MySQL rejected
every CALL: 'Incorrect number of arguments for PROCEDURE
<schema>.search_RMTObject; expected 7, got 8' (mysql2 errno 1050,
sqlState 42S01).
Fix: add OUT nResult BIGINT to both procs (matches the convention used
by every other MySQL get_*/set_* proc in this repo) and set nResult at
the end with the canonical formula 'SET nResult = bCommit - 1 - nError;'
In search_RMCObject, replace the dead 'SET nError = bCommit - bError - 1;'
line (assigned to a local nothing reads, clearly meant to be the
missing OUT assignment) with the canonical nResult assignment.
2. bError NULL INIT (would prevent success path even after MetaversalCorp#1)
Both procs declared 'bError INT' without a DEFAULT, so bError started
as NULL. The expression 'IF bError = 0' then evaluated to NULL (falsy
in MySQL), which means the success branch was unreachable on the happy
path: every call would have fallen through to call_Error
('twRMTObjectIx is invalid' / 'twRMCObjectIx is invalid') even with
valid input. SQL_Server versions already declared @Berror with
'INT = 0', so this was MySQL-only.
Fix: add 'DEFAULT 0' to bError declaration in both procs, matching the
adjacent bCommit / nError declarations and the SQL_Server convention.
Also added DEFAULT 0 to nError in search_RMTObject for consistency
(search_RMCObject already had it).
3. TRIM ( with space requires IGNORE_SPACE in sql_mode (would prevent
body execution after MetaversalCorp#1 and MetaversalCorp#2 unless deploy-time sql_mode set)
The proc body had 'TRIM (IFNULL (sText, ''))' (note the space after
TRIM). Without IGNORE_SPACE in the routine's stored sql_mode, MySQL
parses 'TRIM (' as a user-defined function call, and the CALL fails
at runtime with 'ERROR 1630: FUNCTION <schema>.TRIM does not exist'.
This made deployment of the procs sql_mode-dependent.
Fix: remove the space in TRIM and IFNULL: 'TRIM(IFNULL(sText, ''))'.
Now the proc parses correctly under any sql_mode. (Other functions
like POW (, IF (, CONCAT(, ArcLength ( do not have this issue and
were left unchanged for minimal diff.)
4. COLLATION MISMATCH ON LIKE (would prevent body execution after
MetaversalCorp#1 MetaversalCorp#2 MetaversalCorp#3 unless DB default collation matches column collation)
The proc body did
'WHERE o.Name_wsRMTObjectId LIKE CONCAT(sText, '%')'.
The column's collation is utf8mb4_unicode_ci (declared on the table)
while the parameter sText inherits the database's DEFAULT_COLLATION
(typically utf8mb4_0900_ai_ci on MySQL 8). Mixing two IMPLICIT
collations of different names raises 'ERROR 1267: Illegal mix of
collations (utf8mb4_unicode_ci,IMPLICIT) and
(utf8mb4_0900_ai_ci,IMPLICIT) for operation like'.
Fix: add explicit 'COLLATE utf8mb4_unicode_ci' on the LIKE expression
to force the comparison to the column's collation. EXPLICIT collation
trumps any IMPLICIT operand, so the LIKE works regardless of the
database default collation.
VERIFICATION
End-to-end CALL on a MySQL 8 instance with the default session
sql_mode (no IGNORE_SPACE) and database default collation
utf8mb4_0900_ai_ci, against a table whose name column is
utf8mb4_unicode_ci, completes with @r=0 (success) and produces
result rows. Pre-fix, the same CALL failed at the protocol layer
with 'expected 7, got 8'. After fixing only MetaversalCorp#1 and MetaversalCorp#2, it failed
with 'FUNCTION TRIM does not exist'. After also fixing MetaversalCorp#3, it
failed with 'Illegal mix of collations'. After all four, search
runs end-to-end.
SQL_Server versions are intentionally untouched (they already work
correctly via T-SQL syntax).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four related bugs prevented every
RMTObject:searchandRMCObject:searchcall from succeeding on MySQL deployments. This PR fixes all four at the
source level so neither proc requires special
sql_modeor sessioncollation at deploy time. SQL_Server versions are unchanged — their
T-SQL equivalents already work correctly.
The four bugs (in order of when they surface)
1. Param-count mismatch — caught at protocol parse
The framework calls every proc as:
That is
2 + len(aData) + 1 = 8args for these search procs. Both procswere declared with 7 IN params and 0 OUT params, so MySQL rejected every
call with:
Fix: add
OUT nResult BIGINTto both procs (matches the conventionused by every other MySQL
get_*/set_*proc in this repo) and assignnResultat the end with the canonical formula(same as
get_RMTObject_Update,get_RMRoot_Update,set_RMTObject_Type,etc.). In
search_RMCObject, replace the deadSET nError = bCommit - bError - 1;line — assigned to a local thatnothing reads, clearly meant to be the missing OUT assignment — with the
canonical
nResultassignment.2.
bErrorNULL init — would prevent success branch even after #1Both procs declared
bError INTwithout aDEFAULT, sobErrorstartedas
NULL. The expressionIF bError = 0then evaluated toNULL(falsyin MySQL), making the success branch unreachable on the happy path:
every call would have fallen through to
call_Error(
'twRMTObjectIx is invalid'/'twRMCObjectIx is invalid') even withvalid input. SQL_Server versions already declared
@bError INT = 0, sothis was MySQL-only.
Fix: add
DEFAULT 0tobErrordeclaration in both procs, matchingthe adjacent
bCommit/nErrordeclarations and the SQL_Serverconvention. Also added
DEFAULT 0tonErrorinsearch_RMTObjectforconsistency (
search_RMCObjectalready had it).3.
TRIM (with space requiresIGNORE_SPACEinsql_modeThe proc body had
TRIM (IFNULL (sText, ''))(note the space afterTRIM). WithoutIGNORE_SPACEin the routine's storedsql_mode,MySQL parses
TRIM (as a user-defined function call, and the callfails at runtime with:
This made deployment of the procs
sql_mode-dependent (works only whenthe session that runs
CREATE PROCEDUREhappens to haveIGNORE_SPACEset).
Fix: remove the space in
TRIMandIFNULL:TRIM(IFNULL(sText, '')).Now the proc parses correctly under any
sql_mode. (Other functionslike
POW (,IF (,ArcLength (do not have this issue and were leftunchanged for minimal diff —
TRIMis one of the specific built-ins forwhich MySQL's parser distinguishes a user-defined call from the built-in
based on whitespace, when
IGNORE_SPACEis off.)4. Collation mismatch on
LIKE— would prevent body executionThe proc body did:
The column
Name_wsRMTObjectIdcarriesutf8mb4_unicode_ci(declaredon the table) while parameter
sTextinherits the database'sDEFAULT_COLLATION(typicallyutf8mb4_0900_ai_cion MySQL 8). Mixingtwo IMPLICIT collations of different names raises:
Fix: add explicit
COLLATE utf8mb4_unicode_cion the LIKE expressionto force the comparison to the column's collation. EXPLICIT collation
trumps any IMPLICIT operand, so the LIKE works regardless of the database
default collation.
Verification
End-to-end
CALLon a MySQL 8 instance with the default sessionsql_mode(noIGNORE_SPACE) and default database collation(
utf8mb4_0900_ai_ci), against a table whose name column isutf8mb4_unicode_ci, completes with@r = 0(success).expected 7, got 8(errno 1318)FUNCTION <schema>.TRIM does not exist(errno 1630)Illegal mix of collations ... for operation 'like'(errno 1267)nResult = 0, results returned