Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Elastic simplifies log analytics for SREs and developers with launch of Log Essentials

      August 7, 2025

      OpenAI launches GPT-5

      August 7, 2025

      Melissa brings its data quality solutions to Azure with new SSIS integration

      August 7, 2025

      Automating Design Systems: Tips And Resources For Getting Started

      August 6, 2025

      This $180 mini projector has no business being this good for the price

      August 7, 2025

      GPT-5 is finally here, and you can access it for free today – no subscription needed

      August 7, 2025

      Changing this Android setting instantly doubled my phone speed (Samsung and Google models included)

      August 7, 2025

      ChatGPT can now talk nerdy to you – plus more personalities and other upgrades beyond GPT-5

      August 7, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Advanced Application Architecture through Laravel’s Service Container Management

      August 7, 2025
      Recent

      Advanced Application Architecture through Laravel’s Service Container Management

      August 7, 2025

      Switch Between Personas in Laravel With the MultiPersona Package

      August 7, 2025

      AI-Driven Smart Tagging and Metadata in AEM Assets

      August 7, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      Bill Gates on AI’s Impact: ‘Be Curious, Read, and Use the Latest Tools’

      August 7, 2025
      Recent

      Bill Gates on AI’s Impact: ‘Be Curious, Read, and Use the Latest Tools’

      August 7, 2025

      Halo Infinite’s Fall Update: New Features and Modes to Revive the Game?

      August 7, 2025

      Forza Motorsport’s Future in Jeopardy: Fans Demand Clarity from Microsoft

      August 7, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»Divine Comedy

    Divine Comedy

    August 7, 2025

    “Code should be clear and explain what it does, comments should explain why it does that.” This aphorism is a decent enough guideline, though like any guidance short enough to fit on a bumper sticker, it can easily be overapplied or misapplied.

    Today, we’re going to look at a comment Salagir wrote. This comment does explain what the code does, can’t hope to explain why, and instead serves as a cautionary tale. We’re going to take the comment in sections, because it’s that long.

    This is about a stored procedure in MariaDB. Think of Salagir as our Virgil, a guide showing us around the circles of hell. The first circle? A warning that the dead code will remain in the code base:

    	/************************** Dead code, but don't delete!
    
    	  What follows if the history of a terrible, terrible code.
    	  I keep it for future generations.
    	  Read it in a cold evening in front of the fireplace.
    

    My default stance is “just delete bad, dead code”. But it does mean we get this story out of it, so for now I’ll allow it.

    	  **** XXX ****   This is the story of the stored procedure for getext_fields.   **** XXX ****
    
    	Gets the english and asked language for the field, returns what it finds: it's the translation you want.
    		   Called like this:
    		   " SELECT getext('$table.$field', $key, '$lang') as $label "
    		   The function is only *in the database you work on right now*.
    

    Okay, this seems like a pretty simple function. But why does this say “the function is only in the database you work on right now”? That’s concerning.

    		***** About syntax!!
    			The code below can NOT be used by copy and paste in SQL admin (like phpmyadmin), due to the multiple-query that needs DELIMITER set.
    			The code that works in phpmyadmin is this:
    DELIMITER $$
    DROP FUNCTION IF EXISTS getext$$
    CREATE FUNCTION (...same...)
    		LIMIT 1;
    	RETURN `txt_out`;
    END$$
    			However, DELIMITER breaks the code when executed from PHP.
    

    Am I drowning in the river Styx? Why would I be copy/pasting SQL code into PhpMyAdmin from my PHP code? Is… is this a thing people were doing? Or was it going the opposite way, and people were writing delimited statements and hoping to execute them as a single query? I’m not surprised that didn’t work.

    		***** About configuration!!!
    			IMPORTANT: If you have two MySQL servers bind in Replication mode in order to be able to execute this code, you (or your admin) should set:
    			SET GLOBAL log_bin_trust_function_creators = 1;
    			Without that, adding of this function will fail (without any error).
    

    I don’t know the depths of MariaDB, so I can’t comment on if this is a WTF. What leaps out to me though, is that this likely needs to be in a higher-level form of documentation, since this is a high-level configuration flag. Having it live here is a bit buried. But, this is dead code, so it’s fine, I suppose.

    		***** About indexes!!!!
    			The primary key was not used as index in the first version of this function. No key was used.
    			Because the code you see here is modified for it's execution. And
    				`field`=my_field
    			becomes
    				`field`= NAME_CONST('my_field',_ascii'[value]' COLLATE 'ascii_bin')
    			And if the type of my_field in the function parameter wasn't the exact same as the type of `text`, no index is used!
    			At first, I didn't specify the charset, and it became
    				`field`= NAME_CONST('my_field',_utf8'[value]' COLLATE 'utf8_unicode_ci')
    			Because utf8 is my default, and no index was used, the table `getext_fields` was read entirely each time!
    			Be careful of your types and charsets... Also...
    

    Because the code you see here is modified for its execution. What? NAME_CONST is meant to create synthetic columns not pulled from tables, e.g. SELECT NAME_CONST("foo", "bar") would create a result set with one column (“foo”), with one row (“bar”). I guess this is fine as part of a join- but the idea that the code written in the function gets modified before execution is a skin-peelingly bad idea. And if the query is rewritten before being sent to the database, I bet that makes debugging hard.

    		***** About trying to debug!!!!!
    			To see what the query becomes, there is *no simple way*.
    			I literally looped on a SHOW PROCESSLIST to see it!
    			Bonus: if you created the function with mysql user "root" and use it with user "SomeName", it works.
    			But if you do the show processlist with "SomeName", you won't see it!!
    

    Ah, yes, of course. I love running queries against the database without knowing what they are, and having to use diagnostic tools in the database to hope to understand what I’m doing.

    		***** The final straw!!!!!!
    			When we migrated to MariaDB, when calling this a lot, we had sometimes the procedure call stucked, and UNKILLABLE even on reboot.
    			To fix it, we had to ENTIRELY DESTROY THE DATABASE AND CREATE IT BACK FROM THE SLAVE.
    			Several times in the same month!!!
    

    This is the 9th circle of hell, reserved for traitors and people who mix tabs and spaces in the same file. Unkillable even on reboot? How do you even do that? I have a hunch about the database trying to retain consistency even after failures, but what the hell are they doing inside this function creation statement that can break the database that hard? The good news(?) is the comment(!) contains some of the code that was used:

    		**** XXX ****    The creation actual code, was:   **** XXX ****
    
    		// What DB are we in?
    		$PGf = $Phoenix['Getext']['fields'];
    		$db = $PGf['sql_database']? : (
    				$PGf['sql_connection'][3]? : (
    						$sql->query2cell("SELECT DATABASE()")
    					)
    				);
    
    		$func = $sql->query2assoc("SHOW FUNCTION STATUS WHERE `name`='getext' AND `db`='".$sql->e($db)."'");
    
    		if ( !count($func) ) {
    			$sql->query(<<<MYSQL
    				CREATE FUNCTION {$sql->gt_db}getext(my_field VARCHAR(255) charset {$ascii}, my_id INT(10) UNSIGNED, my_lang VARCHAR(6) charset {$ascii})
    				RETURNS TEXT DETERMINISTIC
    				BEGIN
    					DECLARE `txt_out` TEXT;
    					SELECT `text` INTO `txt_out`
    						FROM {$sql->gt_db}`getext_fields`
    						WHERE `field`=my_field AND `id`=my_id AND `lang` IN ('en',my_lang) AND `text`!=''
    						ORDER BY IF(`lang`=my_lang, 0, 1)
    						LIMIT 1;
    					RETURN `txt_out`;
    				END;
    MYSQL
    			);
    			...
    		}
    

    I hate doing string munging to generate SQL statements, but I especially hate it when the very name of the object created is dynamic. The actual query doesn’t look too unreasonable, but everything about how we got here is terrifying.

    		**** XXX ****    Today, this is not used anymore, because...   **** XXX ****
    
    		Because a simple sub-query perfectly works! And no maria-db bug.
    
    		Thus, in the function selects()
    		The code:
    			//example: getext('character.name', `character_id`, 'fr') as name
    			$sels[] = $this->sql_fields->gt_db."getext('$table.$field', $key, '$lang') as `$label`";
    
    		Is now:
    			$sels[] = "(SELECT `text` FROM {$this->sql_fields->gt_db}`getext_fields`
    				WHERE `field`='$table.$field' AND `lang` IN ('en', '$lang') AND `id`=$key AND `text`!=''
    				ORDER BY IF(`lang`='$lang', 0, 1) LIMIT 1) as `$label`";
    
    		Less nice to look at, but no procedure, all the previous problems GONE!
    
    
    		**** XXX   The end.
    */
    

    Of course a simple subquery (or heck, probably a join!) could handle this. Linking data across two tables is what databases are extremely good at. I agree that, at the call site, this is less readable, but there are plenty of ways one could clean this up to make it more readable. Heck, with this, it looks a heck of a lot like you could have written a much simpler function.

    Salagir did not provide the entirety of the code, just this comment. The comment remains in the code, as a warning sign. That said, it’s a bit verbose. I think a simple “Abandon all hope, ye who enter here,” would have covered it.

    [Advertisement]
    BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

    Source: Read More 

    Facebook Twitter Reddit Email Copy Link
    Previous Articlerewindtty – terminal session recorder and replayer
    Next Article Smart Ways to Pass AI Detection When Writing With AI Help

    Related Posts

    News & Updates

    This $180 mini projector has no business being this good for the price

    August 7, 2025
    News & Updates

    GPT-5 is finally here, and you can access it for free today – no subscription needed

    August 7, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    CVE-2025-32015 – FreshRSS Cross-Site Scripting (XSS) Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    Alert: Malicious RubyGems Impersonate Fastlane Plugins, Steal CI/CD Data

    Security

    CVE-2025-5213 – Projectworlds Responsive E-Learning System SQL Injection Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    Google will announce its next lineup of Pixels on August 20 – Here’s what we know

    News & Updates

    Highlights

    CVE-2025-4474 – WordPress Frontend Dashboard Plugin Privilege Escalation Vulnerability

    May 13, 2025

    CVE ID : CVE-2025-4474

    Published : May 13, 2025, 7:15 a.m. | 1 hour, 23 minutes ago

    Description : The Frontend Dashboard plugin for WordPress is vulnerable to Privilege Escalation due to a missing capability check on the fed_admin_setting_form_function() function in versions 1.0 to 2.2.7. This makes it possible for authenticated attackers, with Subscriber-level access and above, to overwrite the plugin’s ‘register’ role setting to make new user registrations default to the administrator role, leading to an elevation of privileges to that of an administrator.

    Severity: 8.8 | HIGH

    Visit the link for more details, such as CVSS details, affected products, timeline, and more…

    CVE-2025-6706 – MongoDB Server Use After Free Vulnerability

    June 26, 2025

    Access to Care Is Evolving: What Consumer Insights and Behavior Models Reveal

    July 9, 2025

    asdf is an extendable version manager

    April 5, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.