Objectives

Upon completion of this lesson, you will be able to:

  • define a trigger in MySQL
  • remove a trigger from a table

Overview

MySQL, like most relational database management systems, supports triggers. Triggers in MySQL are essentially database “callbacks”, which means they are automatically executed (“fired” or “triggered”) by the MySQL SQL execution engine in response to certain events on a particular table or view. These events generally are modification events and include INSERT, UPDATE, and DELETE operations. Triggers can be defined to execute before or after the specified event, providing a useful mechanism for enforcing data integrity, maintaining audit trails, and implementing complex business logic directly within the database. The benefit is that business logic is centralized. However, triggers are written in a proprietary programming language unique to each database and thus can be difficult to maintain and reduce database mobility.

Key Features of Triggers in MySQL

  • Automatic Execution: Triggers run automatically in response to specified data modification events, without the need for explicit invocation.
  • Event Types: Triggers can be set to fire before or after INSERT, UPDATE, and DELETE operations.
  • Row-Level and Statement-Level Triggers: MySQL supports row-level triggers, which execute once for each row affected by the triggering event. Statement-level triggers, as seen in some other RDBMS systems, execute once per SQL statement, are not directly supported but can be simulated using control structures within the trigger.
  • Support for WHEN Clause: Triggers in MySQL can include a WHEN clause to specify a condition for the trigger’s execution, allowing for more precise control over when the trigger fires.
  • Nested Triggers: MySQL allows triggers to fire other triggers (nested execution), which can be controlled by the PRAGMA recursive_triggers setting.

Common Uses of Triggers in MySQL

  • Data Validation: To enforce complex data validation rules that cannot be defined through standard MySQL constraints.
  • Integrity Constraints: To implement complex integrity constraints or to enforce referential actions (like cascading deletes or updates) that go beyond MySQL’s foreign key constraints.
  • Auditing: To automatically record changes to data, such as logging modifications to certain tables for auditing purposes.
  • Automatic Modification: To automatically update or transform data in response to database operations, such as updating a “last modified” timestamp column whenever a row is updated.

Tutorial I

In this video tutorial, Khoury Boston’s Prof. Durant explains triggers and how they are used to define and enforce user defined constraints and business logic. While the tutorial discusses MySQL as the example database, the concepts apply to most other relational database management systems, although the syntax for trigger definitions is often vendor specific. Triggers are now part of the SQL standard, so many aspects of triggers are supported by most databases. Nevertheless, each vendor has restrictions on what triggers can and cannot do and whether they support row-level or table-level triggers or both.

Triggers are one of several database programming objects. In addition to triggers most databases also support stored procedures for building business and transactional logic directly as part of the database. Most database also support views as a way to create virtual tables in order to enforce user level security restrictions on data and to separate query design from the underlying database schema.

Handout: MySQL Triggers (Dr. Durant)

Tutorial II

In these two video tutorials below, Khoury Boston’s Prof. Feinberg demonstrates via code how triggers are defined in MySQL and how they can be tested in MySQL Workbench.

Summary

Triggers in MySQL, like other databases, offer a flexible mechanism for implementing automatic responses to database events, making them a valuable feature for developers looking to enforce data integrity, automate database logic, and manage complex relationships within their MySQL databases.


Files & Resources

All Files for Lesson 70.906

References

None yet.

Errata

None collected yet. Let us know.

Let us know.

LS0tCnRpdGxlOiAiRGVmaW5pbmcgVHJpZ2dlcnMgaW4gTXlTUUwiCnBhcmFtczoKICBjYXRlZ29yeTogNzAKICBudW1iZXI6IDkwNgogIHRpbWU6IDYwCiAgbGV2ZWw6IGludGVybWVkaWF0ZQogIHRhZ3M6ICJ0cmlnZ2VycyxteXNxbCxidXNpbmVzcyBsb2dpYyIKICBkZXNjcmlwdGlvbjogIlRoaXMgbGVzc29uIGV4cGxhaW5zIGhvdyB0byBkZWZpbmUgdHJpZ2dlcnMgb24gdGFibGVzIGluIE15U1FMLiAKICAgICAgICAgICAgICAgIERlbW9uc3RyYXRlcyB0aGUgc3ludGF4IG9mIHRoZSB0cmlnZ2VycwogICAgICAgICAgICAgICAgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgZm9yIE15U1FMLiBFeHBsYWlucyB3aGVuIHRvIHVzZSB0cmlnZ2VycwogICAgICAgICAgICAgICAgZm9yIGVuZm9yY2luZyBidXNpbmVzcyBkb21haW4gY29uc3RyYWludHMgYW5kIHJ1bGVzLiIKZGF0ZTogIjxzbWFsbD5gciBTeXMuRGF0ZSgpYDwvc21hbGw+IgphdXRob3I6ICI8c21hbGw+TWFydGluIFNjaGVkbGJhdWVyPC9zbWFsbD4iCmVtYWlsOiAibS5zY2hlZGxiYXVlckBuZXUuZWR1IgphZmZpbGl0YXRpb246ICJOb3J0aGVhc3Rlcm4gVW5pdmVyc2l0eSIKb3V0cHV0OiAKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29sbGFwc2VkOiBmYWxzZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IHNwYWNlbGFiCiAgICBoaWdobGlnaHQ6IHRhbmdvCi0tLQoKLS0tCnRpdGxlOiAiPHNtYWxsPmByIHBhcmFtcyRjYXRlZ29yeWAuYHIgcGFyYW1zJG51bWJlcmA8L3NtYWxsPjxici8+PHNwYW4gc3R5bGU9J2NvbG9yOiAjMkU0MDUzOyBmb250LXNpemU6IDAuOWVtJz5gciBybWFya2Rvd246Om1ldGFkYXRhJHRpdGxlYDwvc3Bhbj4iCi0tLQoKYGBge3IgY29kZT14ZnVuOjpyZWFkX3V0ZjgocGFzdGUwKGhlcmU6OmhlcmUoKSwnL1IvX2luc2VydDJEQi5SJykpLCBpbmNsdWRlID0gRkFMU0V9CmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBPYmplY3RpdmVzCgpVcG9uIGNvbXBsZXRpb24gb2YgdGhpcyBsZXNzb24sIHlvdSB3aWxsIGJlIGFibGUgdG86CgotICAgZGVmaW5lIGEgdHJpZ2dlciBpbiBNeVNRTAotICAgcmVtb3ZlIGEgdHJpZ2dlciBmcm9tIGEgdGFibGUKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgT3ZlcnZpZXcKCk15U1FMLCBsaWtlIG1vc3QgcmVsYXRpb25hbCBkYXRhYmFzZSBtYW5hZ2VtZW50IHN5c3RlbXMsIHN1cHBvcnRzIHRyaWdnZXJzLiBUcmlnZ2VycyBpbiBNeVNRTCBhcmUgZXNzZW50aWFsbHkgZGF0YWJhc2UgImNhbGxiYWNrcyIsIHdoaWNoIG1lYW5zIHRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgZXhlY3V0ZWQgKCJmaXJlZCIgb3IgInRyaWdnZXJlZCIpIGJ5IHRoZSBNeVNRTCBTUUwgZXhlY3V0aW9uIGVuZ2luZSBpbiByZXNwb25zZSB0byBjZXJ0YWluIGV2ZW50cyBvbiBhIHBhcnRpY3VsYXIgdGFibGUgb3Igdmlldy4gVGhlc2UgZXZlbnRzIGdlbmVyYWxseSBhcmUgbW9kaWZpY2F0aW9uIGV2ZW50cyBhbmQgaW5jbHVkZSBJTlNFUlQsIFVQREFURSwgYW5kIERFTEVURSBvcGVyYXRpb25zLiBUcmlnZ2VycyBjYW4gYmUgZGVmaW5lZCB0byBleGVjdXRlIGJlZm9yZSBvciBhZnRlciB0aGUgc3BlY2lmaWVkIGV2ZW50LCBwcm92aWRpbmcgYSB1c2VmdWwgbWVjaGFuaXNtIGZvciBlbmZvcmNpbmcgZGF0YSBpbnRlZ3JpdHksIG1haW50YWluaW5nIGF1ZGl0IHRyYWlscywgYW5kIGltcGxlbWVudGluZyBjb21wbGV4IGJ1c2luZXNzIGxvZ2ljIGRpcmVjdGx5IHdpdGhpbiB0aGUgZGF0YWJhc2UuIFRoZSBiZW5lZml0IGlzIHRoYXQgYnVzaW5lc3MgbG9naWMgaXMgY2VudHJhbGl6ZWQuIEhvd2V2ZXIsIHRyaWdnZXJzIGFyZSB3cml0dGVuIGluIGEgcHJvcHJpZXRhcnkgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgdW5pcXVlIHRvIGVhY2ggZGF0YWJhc2UgYW5kIHRodXMgY2FuIGJlIGRpZmZpY3VsdCB0byBtYWludGFpbiBhbmQgcmVkdWNlIGRhdGFiYXNlIG1vYmlsaXR5LgoKIyMgS2V5IEZlYXR1cmVzIG9mIFRyaWdnZXJzIGluIE15U1FMCgotICAgKipBdXRvbWF0aWMgRXhlY3V0aW9uKio6IFRyaWdnZXJzIHJ1biBhdXRvbWF0aWNhbGx5IGluIHJlc3BvbnNlIHRvIHNwZWNpZmllZCBkYXRhIG1vZGlmaWNhdGlvbiBldmVudHMsIHdpdGhvdXQgdGhlIG5lZWQgZm9yIGV4cGxpY2l0IGludm9jYXRpb24uCi0gICAqKkV2ZW50IFR5cGVzKio6IFRyaWdnZXJzIGNhbiBiZSBzZXQgdG8gZmlyZSBiZWZvcmUgb3IgYWZ0ZXIgSU5TRVJULCBVUERBVEUsIGFuZCBERUxFVEUgb3BlcmF0aW9ucy4KLSAgICoqUm93LUxldmVsIGFuZCBTdGF0ZW1lbnQtTGV2ZWwgVHJpZ2dlcnMqKjogTXlTUUwgc3VwcG9ydHMgcm93LWxldmVsIHRyaWdnZXJzLCB3aGljaCBleGVjdXRlIG9uY2UgZm9yIGVhY2ggcm93IGFmZmVjdGVkIGJ5IHRoZSB0cmlnZ2VyaW5nIGV2ZW50LiBTdGF0ZW1lbnQtbGV2ZWwgdHJpZ2dlcnMsIGFzIHNlZW4gaW4gc29tZSBvdGhlciBSREJNUyBzeXN0ZW1zLCBleGVjdXRlIG9uY2UgcGVyIFNRTCBzdGF0ZW1lbnQsIGFyZSBub3QgZGlyZWN0bHkgc3VwcG9ydGVkIGJ1dCBjYW4gYmUgc2ltdWxhdGVkIHVzaW5nIGNvbnRyb2wgc3RydWN0dXJlcyB3aXRoaW4gdGhlIHRyaWdnZXIuCi0gICAqKlN1cHBvcnQgZm9yIFdIRU4gQ2xhdXNlKio6IFRyaWdnZXJzIGluIE15U1FMIGNhbiBpbmNsdWRlIGEgV0hFTiBjbGF1c2UgdG8gc3BlY2lmeSBhIGNvbmRpdGlvbiBmb3IgdGhlIHRyaWdnZXIncyBleGVjdXRpb24sIGFsbG93aW5nIGZvciBtb3JlIHByZWNpc2UgY29udHJvbCBvdmVyIHdoZW4gdGhlIHRyaWdnZXIgZmlyZXMuCi0gICAqKk5lc3RlZCBUcmlnZ2VycyoqOiBNeVNRTCBhbGxvd3MgdHJpZ2dlcnMgdG8gZmlyZSBvdGhlciB0cmlnZ2VycyAobmVzdGVkIGV4ZWN1dGlvbiksIHdoaWNoIGNhbiBiZSBjb250cm9sbGVkIGJ5IHRoZSBgUFJBR01BIHJlY3Vyc2l2ZV90cmlnZ2Vyc2Agc2V0dGluZy4KCiMjIENvbW1vbiBVc2VzIG9mIFRyaWdnZXJzIGluIE15U1FMCgotICAgKipEYXRhIFZhbGlkYXRpb24qKjogVG8gZW5mb3JjZSBjb21wbGV4IGRhdGEgdmFsaWRhdGlvbiBydWxlcyB0aGF0IGNhbm5vdCBiZSBkZWZpbmVkIHRocm91Z2ggc3RhbmRhcmQgTXlTUUwgY29uc3RyYWludHMuCi0gICAqKkludGVncml0eSBDb25zdHJhaW50cyoqOiBUbyBpbXBsZW1lbnQgY29tcGxleCBpbnRlZ3JpdHkgY29uc3RyYWludHMgb3IgdG8gZW5mb3JjZSByZWZlcmVudGlhbCBhY3Rpb25zIChsaWtlIGNhc2NhZGluZyBkZWxldGVzIG9yIHVwZGF0ZXMpIHRoYXQgZ28gYmV5b25kIE15U1FMJ3MgZm9yZWlnbiBrZXkgY29uc3RyYWludHMuCi0gICAqKkF1ZGl0aW5nKio6IFRvIGF1dG9tYXRpY2FsbHkgcmVjb3JkIGNoYW5nZXMgdG8gZGF0YSwgc3VjaCBhcyBsb2dnaW5nIG1vZGlmaWNhdGlvbnMgdG8gY2VydGFpbiB0YWJsZXMgZm9yIGF1ZGl0aW5nIHB1cnBvc2VzLgotICAgKipBdXRvbWF0aWMgTW9kaWZpY2F0aW9uKio6IFRvIGF1dG9tYXRpY2FsbHkgdXBkYXRlIG9yIHRyYW5zZm9ybSBkYXRhIGluIHJlc3BvbnNlIHRvIGRhdGFiYXNlIG9wZXJhdGlvbnMsIHN1Y2ggYXMgdXBkYXRpbmcgYSAibGFzdCBtb2RpZmllZCIgdGltZXN0YW1wIGNvbHVtbiB3aGVuZXZlciBhIHJvdyBpcyB1cGRhdGVkLgoKIyMgVHV0b3JpYWwgSQoKSW4gdGhpcyB2aWRlbyB0dXRvcmlhbCwgS2hvdXJ5IEJvc3RvbidzIFByb2YuIER1cmFudCBleHBsYWlucyB0cmlnZ2VycyBhbmQgaG93IHRoZXkgYXJlIHVzZWQgdG8gZGVmaW5lIGFuZCBlbmZvcmNlIHVzZXIgZGVmaW5lZCBjb25zdHJhaW50cyBhbmQgYnVzaW5lc3MgbG9naWMuIFdoaWxlIHRoZSB0dXRvcmlhbCBkaXNjdXNzZXMgTXlTUUwgYXMgdGhlIGV4YW1wbGUgZGF0YWJhc2UsIHRoZSBjb25jZXB0cyBhcHBseSB0byBtb3N0IG90aGVyIHJlbGF0aW9uYWwgZGF0YWJhc2UgbWFuYWdlbWVudCBzeXN0ZW1zLCBhbHRob3VnaCB0aGUgc3ludGF4IGZvciB0cmlnZ2VyIGRlZmluaXRpb25zIGlzIG9mdGVuIHZlbmRvciBzcGVjaWZpYy4gVHJpZ2dlcnMgYXJlIG5vdyBwYXJ0IG9mIHRoZSBTUUwgc3RhbmRhcmQsIHNvIG1hbnkgYXNwZWN0cyBvZiB0cmlnZ2VycyBhcmUgc3VwcG9ydGVkIGJ5IG1vc3QgZGF0YWJhc2VzLiBOZXZlcnRoZWxlc3MsIGVhY2ggdmVuZG9yIGhhcyByZXN0cmljdGlvbnMgb24gd2hhdCB0cmlnZ2VycyBjYW4gYW5kIGNhbm5vdCBkbyBhbmQgd2hldGhlciB0aGV5IHN1cHBvcnQgcm93LWxldmVsIG9yIHRhYmxlLWxldmVsIHRyaWdnZXJzIG9yIGJvdGguCgpUcmlnZ2VycyBhcmUgb25lIG9mIHNldmVyYWwgZGF0YWJhc2UgcHJvZ3JhbW1pbmcgb2JqZWN0cy4gSW4gYWRkaXRpb24gdG8gdHJpZ2dlcnMgbW9zdCBkYXRhYmFzZXMgYWxzbyBzdXBwb3J0IHN0b3JlZCBwcm9jZWR1cmVzIGZvciBidWlsZGluZyBidXNpbmVzcyBhbmQgdHJhbnNhY3Rpb25hbCBsb2dpYyBkaXJlY3RseSBhcyBwYXJ0IG9mIHRoZSBkYXRhYmFzZS4gTW9zdCBkYXRhYmFzZSBhbHNvIHN1cHBvcnQgdmlld3MgYXMgYSB3YXkgdG8gY3JlYXRlIHZpcnR1YWwgdGFibGVzIGluIG9yZGVyIHRvIGVuZm9yY2UgdXNlciBsZXZlbCBzZWN1cml0eSByZXN0cmljdGlvbnMgb24gZGF0YSBhbmQgdG8gc2VwYXJhdGUgcXVlcnkgZGVzaWduIGZyb20gdGhlIHVuZGVybHlpbmcgZGF0YWJhc2Ugc2NoZW1hLgoKPGlmcmFtZSBzdHlsZT0iYm9yZGVyOiAxcHggc29saWQgIzQ2NDY0NjsiIHNyYz0iaHR0cHM6Ly9ub3J0aGVhc3Rlcm4uaG9zdGVkLnBhbm9wdG8uY29tL1Bhbm9wdG8vUGFnZXMvRW1iZWQuYXNweD9pZD1kZmIzN2M0ZS1jMmQ5LTQ2MzEtOGNhYi1hYmY0MDExOTQ0NmQmYW1wO2F1dG9wbGF5PWZhbHNlJmFtcDtvZmZlcnZpZXdlcj10cnVlJmFtcDtzaG93dGl0bGU9ZmFsc2UmYW1wO3Nob3dicmFuZD1mYWxzZSZhbXA7c3RhcnQ9MCZhbXA7aW50ZXJhY3Rpdml0eT1hbGwiIHdpZHRoPSI1NjAiIGhlaWdodD0iMzE1IiBhbGxvd2Z1bGxzY3JlZW49ImFsbG93ZnVsbHNjcmVlbiIgYWxsb3c9ImF1dG9wbGF5IiBkYXRhLWV4dGVybmFsPSIxIj4KCjwvaWZyYW1lPgoKKipIYW5kb3V0Kio6IFtNeVNRTCBUcmlnZ2VycyAoRHIuIER1cmFudCldKGQtNzAtOTA2LU15U1FMLXRyaWdnZXJzLUR1cmFudC5wZGYpCgojIyBUdXRvcmlhbCBJSQoKSW4gdGhlc2UgdHdvIHZpZGVvIHR1dG9yaWFscyBiZWxvdywgS2hvdXJ5IEJvc3RvbidzIFByb2YuIEZlaW5iZXJnIGRlbW9uc3RyYXRlcyB2aWEgY29kZSBob3cgdHJpZ2dlcnMgYXJlIGRlZmluZWQgaW4gTXlTUUwgYW5kIGhvdyB0aGV5IGNhbiBiZSB0ZXN0ZWQgaW4gTXlTUUwgV29ya2JlbmNoLgoKPGlmcmFtZSBzcmM9Imh0dHBzOi8vbm9ydGhlYXN0ZXJuLmhvc3RlZC5wYW5vcHRvLmNvbS9QYW5vcHRvL1BhZ2VzL0VtYmVkLmFzcHg/aWQ9NTY5MzI2N2UtMzViOS00NThhLWEwNjYtYWM1MjAxMjY1YmU4JmFtcDthdXRvcGxheT1mYWxzZSZhbXA7b2ZmZXJ2aWV3ZXI9dHJ1ZSZhbXA7c2hvd3RpdGxlPWZhbHNlJmFtcDtzaG93YnJhbmQ9ZmFsc2UmYW1wO3N0YXJ0PTAmYW1wO2ludGVyYWN0aXZpdHk9YWxsIiB3aWR0aD0iNTYwIiBoZWlnaHQ9IjMxNSIgYWxsb3dmdWxsc2NyZWVuPSJhbGxvd2Z1bGxzY3JlZW4iIGFsbG93PSJhdXRvcGxheSIgZGF0YS1leHRlcm5hbD0iMSI+Cgo8L2lmcmFtZT4KCjxpZnJhbWUgc3JjPSJodHRwczovL25vcnRoZWFzdGVybi5ob3N0ZWQucGFub3B0by5jb20vUGFub3B0by9QYWdlcy9FbWJlZC5hc3B4P2lkPTY1OTA0MGY0LTZiZTItNDIzMy1iNTQ4LWFjNTIwMTI2NWJiMCZhbXA7YXV0b3BsYXk9ZmFsc2UmYW1wO29mZmVydmlld2VyPWZhbHNlJmFtcDtzaG93dGl0bGU9ZmFsc2UmYW1wO3Nob3dicmFuZD1mYWxzZSZhbXA7c3RhcnQ9MCZhbXA7aW50ZXJhY3Rpdml0eT1hbGwiIHdpZHRoPSI1NjAiIGhlaWdodD0iMzE1IiBhbGxvd2Z1bGxzY3JlZW49ImFsbG93ZnVsbHNjcmVlbiIgYWxsb3c9ImF1dG9wbGF5IiBkYXRhLWV4dGVybmFsPSIxIj4KCjwvaWZyYW1lPgoKIyMgU3VtbWFyeQoKVHJpZ2dlcnMgaW4gTXlTUUwsIGxpa2Ugb3RoZXIgZGF0YWJhc2VzLCBvZmZlciBhIGZsZXhpYmxlIG1lY2hhbmlzbSBmb3IgaW1wbGVtZW50aW5nIGF1dG9tYXRpYyByZXNwb25zZXMgdG8gZGF0YWJhc2UgZXZlbnRzLCBtYWtpbmcgdGhlbSBhIHZhbHVhYmxlIGZlYXR1cmUgZm9yIGRldmVsb3BlcnMgbG9va2luZyB0byBlbmZvcmNlIGRhdGEgaW50ZWdyaXR5LCBhdXRvbWF0ZSBkYXRhYmFzZSBsb2dpYywgYW5kIG1hbmFnZSBjb21wbGV4IHJlbGF0aW9uc2hpcHMgd2l0aGluIHRoZWlyIE15U1FMIGRhdGFiYXNlcy4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgRmlsZXMgJiBSZXNvdXJjZXMgeyNmaWxlcy1yZXNvdXJjZXN9CgpgYGB7ciB6aXBGaWxlcywgZWNobz1GQUxTRX0KemlwTmFtZSA9IHNwcmludGYoIkxlc3NvbkZpbGVzLSVzLSVzLnppcCIsIAogICAgICAgICAgICAgICAgIHBhcmFtcyRjYXRlZ29yeSwKICAgICAgICAgICAgICAgICBwYXJhbXMkbnVtYmVyKQoKdGV4dEFMaW5rID0gcGFzdGUwKCJBbGwgRmlsZXMgZm9yIExlc3NvbiAiLCAKICAgICAgICAgICAgICAgcGFyYW1zJGNhdGVnb3J5LCIuIixwYXJhbXMkbnVtYmVyKQoKIyBkb3dubG9hZEZpbGVzTGluaygpIGlzIGluY2x1ZGVkIGZyb20gX2luc2VydDJEQi5SCmtuaXRyOjpyYXdfaHRtbChkb3dubG9hZEZpbGVzTGluaygiLiIsIHppcE5hbWUsIHRleHRBTGluaykpCmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBSZWZlcmVuY2VzCgpOb25lIHlldC4KCiMjIEVycmF0YQoKTm9uZSBjb2xsZWN0ZWQgeWV0LiBMZXQgdXMga25vdy4KCltMZXQgdXMga25vd10oaHR0cHM6Ly9mb3JtLmpvdGZvcm0uY29tLzIxMjE4NzA3Mjc4NDE1Nyl7dGFyZ2V0PSJfYmxhbmsifS4K