Introduction
A common source of confusion in SQL arises from the distinction between the syntactic (coding) order in which a query is written and the logical execution order in which the database management system (DBMS) processes that query. Although SQL queries are written in a declarative form beginning with SELECT, the logical processing model evaluates clauses in a different order.
This distinction is essential for:
- Correct query formulation
- Avoidance of semantic errors
- Proper use of aggregation and filtering
- Reasoning about query optimization and relational algebra equivalences
This lesson presents the logical query processing model with examples in R and SQLite, although the discussion is agnostic of the specific relational database used.
Declarative Nature of SQL
SQL is a declarative language grounded in relational algebra. The programmer specifies what result is desired rather than how it is to be computed. Internally, the database query engine translates the SQL statement into an algebraic expression and generates an execution plan. For more information on query planning and execution, see 60.551 – Query Planning and Processing in Relational Databases
Importantly, the textual order of clauses does not correspond to the logical evaluation order.
Syntax Order vs. Logical Processing Order
SQL queries are written in the following canonical form:
SELECT ...
FROM ...
WHERE ...
GROUP BY ...
HAVING ...
ORDER BY ...
LIMIT ...
While a programmer might think that the syntactic order of the clauses is the execution order of the clauses by the database query engine, that is not the case. The query engine evaluates the query in the following logical order:
- FROM – Identify source relations and compute joins
- WHERE – Apply tuple-level predicates
- GROUP BY – Partition tuples into groups
- HAVING – Apply group-level predicates
- SELECT – Compute projection and expressions plus window functions
- DISTINCT – Eliminate duplicates (if specified)
- ORDER BY – Sort the result
- LIMIT / OFFSET – Restrict the result set
This order reflects the relational algebra transformation pipeline rather than physical execution details. Not understanding the execution (or evaluation) order is a common source of mistakes. The graphic below summarizes the syntax vs logical order of SQL clauses:

Example in SQLite using R
For expediency, the example below uses a (temporary) in-memory database rather than an on-disk database.
library(RSQLite)
conn <- dbConnect(RSQLite::SQLite(), ":memory:")
Nest, we will create a table and insert sample data into the table.
s <- dbExecute(conn, "
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
department TEXT,
salary INTEGER
);
")
s <- dbExecute(conn, "
INSERT INTO employees (department, salary) VALUES
('Engineering', 90000),
('Engineering', 110000),
('HR', 60000),
('HR', 65000),
('Marketing', 70000);
")
Example 1: Tuple-Level Filtering
The SQL statement below filters tuples (rows) based on a logical expression. Of course, the expression could be more complex using a combination of AND, OR, NOT, and IS NULL, alongside <, >, and =.
SELECT department, salary AS wage
FROM employees
WHERE salary > 80000;
Table 1: 2 records
| Engineering |
90000 |
| Engineering |
110000 |
The query engine evaluates the query in the following order:
FROM employees Construct the base relation.
WHERE salary > 80000 Apply selection predicate ( _{salary > 80000}(R) ).
SELECT department, salary Project specified attributes.
N.B.: The WHERE clause cannot reference the alias wage defined in SELECT because projection occurs after selection in the logical processing order.
Example 2: Aggregation and Group-Level Filtering
Let’s evaluate the query below which contains two filtering clauses: a WHERE clause and a HAVING clause. The WHERE clause is executed first before any grouping is done. Once the groupings has been done, the HAVING clause is executed on the groups to filter the partitions. The ORDER BY clause is executed last, after the columns specified in the SELECT have been projected out.
SELECT department, AVG(salary) AS avg_salary
FROM employees
WHERE salary > 60000
GROUP BY department
HAVING AVG(salary) > 80000
ORDER BY avg_salary DESC;
Table 2: 1 records
| Engineering |
1e+05 |
To summarize, the query is evaluated in the following sequence:
FROM employees Construct base relation.
WHERE salary > 60000 Filter tuples.
GROUP BY department Partition tuples by department.
Aggregate Computation Compute AVG(salary) per group.
HAVING AVG(salary) > 80000 Filter groups.
SELECT department, AVG(salary) Project attributes and computed aggregates.
ORDER BY avg_salary DESC Sort final result.
Alias Scope
This query fails because any alias defined in the SELECT clause is not available in the WHERE since the WHERE clause is evaluated before the SELECT. However, an alias for a table is available as the FROM is executed first:
SELECT salary * 1.1 AS increased_salary
FROM employees AS e
WHERE e.increased_salary > 80000;
So, because WHERE is logically evaluated before SELECT, the alias increased_salary does not yet exist.
The correct formulation should be:
SELECT salary * 1.1 AS increased_salary
FROM employees
WHERE salary * 1.1 > 80000;
WHERE vs. HAVING
A common confusion is misunderstanding WHERE versus HAVING: WHERE filters tuples prior to grouping whereas HAVING filters groups after grouping.
Thus, the clause:
is valid, while:
is not.
Logical vs. Physical Execution
It is important to distinguish between:
- Logical processing order (semantic model)
- Physical execution plan (optimizer-dependent)
SQLite, like other DBMSs, may reorder operations for efficiency (predicate pushdown, index scans, join reordering). However, these transformations preserve logical equivalence under relational algebra rules. See 60.551 – Query Planning and Processing in Relational Databases for more information on query planning and execution.
Summary
Understanding logical query processing is key to virtually every aspect of working with relational databases, especially for writing semantically correct analytical queries, and being able to correct alternative, and perhaps more efficient, query formulations.
The apparent contradiction between SQL’s textual structure and its logical processing order is not accidental; it reflects SQL’s declarative foundation in relational algebra.
Acknowledgement
Claude 4.6 (Sonnet) was used to assist in the preparation of this lesson.
LS0tCnRpdGxlOiAiRXhlY3V0aW9uIHZzIFN5bnRheCBPcmRlciBvZiBTUUwgU3RhdGVtZW50cyIKcGFyYW1zOgogIGNhdGVnb3J5OiA3MAogIG51bWJlcjogMTE4CiAgdGltZTogMzAKICBsZXZlbDogYmVnaW5uZXIKICB0YWdzOiAic3FsLG9yZGVyLGdyb3VwIGJ5LGhhdmluZyx3aGVyZSIKICBkZXNjcmlwdGlvbjogIkV4YW1pbmVzIHRoZSBkaXN0aW5jdGlvbiBiZXR3ZWVuIHRoZSBzeW50YWN0aWMgc3RydWN0dXJlIG9mIFNRTCAKICAgICAgICAgICAgICAgIHF1ZXJpZXMgYW5kIHRoZWlyIGxvZ2ljYWwgcXVlcnkgcHJvY2Vzc2luZyBvcmRlciwgZ3JvdW5kaW5nIAogICAgICAgICAgICAgICAgdGhlIGRpc2N1c3Npb24gaW4gcmVsYXRpb25hbCBhbGdlYnJhIGFuZCBkYXRhYmFzZSB0aGVvcnkuIAogICAgICAgICAgICAgICAgUHJvdmlkZXMgcHJhY3RpY2FsIFNRTGl0ZSBleGFtcGxlcyBpbiBSLiIKZGF0ZTogIjxzbWFsbD5gciBTeXMuRGF0ZSgpYDwvc21hbGw+IgphdXRob3I6ICI8c21hbGw+TWFydGluIFNjaGVkbGJhdWVyPC9zbWFsbD4iCmVtYWlsOiAibS5zY2hlZGxiYXVlckBuZXUuZWR1IgphZmZpbGl0YXRpb246ICJOb3J0aGVhc3Rlcm4gVW5pdmVyc2l0eSIKb3V0cHV0OiAKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29sbGFwc2VkOiBmYWxzZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IGpvdXJuYWwKICAgIGhpZ2hsaWdodDogdGFuZ28KLS0tCgotLS0KdGl0bGU6ICI8c21hbGw+YHIgcGFyYW1zJGNhdGVnb3J5YC5gciBwYXJhbXMkbnVtYmVyYDwvc21hbGw+PGJyLz48c3BhbiBzdHlsZT0nY29sb3I6ICMyRTQwNTM7IGZvbnQtc2l6ZTogMC45ZW0nPmByIHJtYXJrZG93bjo6bWV0YWRhdGEkdGl0bGVgPC9zcGFuPiIKLS0tCgpgYGB7ciBlY2hvPUZ9CiMgUGFja2FnZSBuYW1lcwpwYWNrYWdlcyA8LSBjKCJoZXJlIiwgIlJTUUxpdGUiKQoKIyBJbnN0YWxsIHBhY2thZ2VzIG5vdCB5ZXQgaW5zdGFsbGVkCmluc3RhbGxlZF9wYWNrYWdlcyA8LSBwYWNrYWdlcyAlaW4lIHJvd25hbWVzKGluc3RhbGxlZC5wYWNrYWdlcygpKQppZiAoYW55KGluc3RhbGxlZF9wYWNrYWdlcyA9PSBGQUxTRSkpIHsKICBpbnN0YWxsLnBhY2thZ2VzKHBhY2thZ2VzWyFpbnN0YWxsZWRfcGFja2FnZXNdLCByZXBvcyA9ICJodHRwczovL2Nsb3VkLnItcHJvamVjdC5vcmciKQp9CgojIFBhY2thZ2VzIGxvYWRpbmcKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGludmlzaWJsZShsYXBwbHkocGFja2FnZXMsIGxpYnJhcnksIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkpKQpgYGAKCmBgYHtyIGNvZGU9eGZ1bjo6cmVhZF91dGY4KHBhc3RlMChoZXJlOjpoZXJlKCksJy9SL19pbnNlcnQyREIuUicpKSwgaW5jbHVkZSA9IEZBTFNFfQpgYGAKCiMjIEludHJvZHVjdGlvbgoKQSBjb21tb24gc291cmNlIG9mIGNvbmZ1c2lvbiBpbiBTUUwgYXJpc2VzIGZyb20gdGhlIGRpc3RpbmN0aW9uIGJldHdlZW4gdGhlICoqc3ludGFjdGljIChjb2RpbmcpIG9yZGVyKiogaW4gd2hpY2ggYSBxdWVyeSBpcyB3cml0dGVuIGFuZCB0aGUgKipsb2dpY2FsIGV4ZWN1dGlvbiBvcmRlcioqIGluIHdoaWNoIHRoZSBkYXRhYmFzZSBtYW5hZ2VtZW50IHN5c3RlbSAoREJNUykgcHJvY2Vzc2VzIHRoYXQgcXVlcnkuIEFsdGhvdWdoIFNRTCBxdWVyaWVzIGFyZSB3cml0dGVuIGluIGEgZGVjbGFyYXRpdmUgZm9ybSBiZWdpbm5pbmcgd2l0aCAqU0VMRUNUKiwgdGhlIGxvZ2ljYWwgcHJvY2Vzc2luZyBtb2RlbCBldmFsdWF0ZXMgY2xhdXNlcyBpbiBhIGRpZmZlcmVudCBvcmRlci4KClRoaXMgZGlzdGluY3Rpb24gaXMgZXNzZW50aWFsIGZvcjoKCi0gICBDb3JyZWN0IHF1ZXJ5IGZvcm11bGF0aW9uCi0gICBBdm9pZGFuY2Ugb2Ygc2VtYW50aWMgZXJyb3JzCi0gICBQcm9wZXIgdXNlIG9mIGFnZ3JlZ2F0aW9uIGFuZCBmaWx0ZXJpbmcKLSAgIFJlYXNvbmluZyBhYm91dCBxdWVyeSBvcHRpbWl6YXRpb24gYW5kIHJlbGF0aW9uYWwgYWxnZWJyYSBlcXVpdmFsZW5jZXMKClRoaXMgbGVzc29uIHByZXNlbnRzIHRoZSBsb2dpY2FsIHF1ZXJ5IHByb2Nlc3NpbmcgbW9kZWwgd2l0aCBleGFtcGxlcyBpbiBSIGFuZCBTUUxpdGUsIGFsdGhvdWdoIHRoZSBkaXNjdXNzaW9uIGlzIGFnbm9zdGljIG9mIHRoZSBzcGVjaWZpYyByZWxhdGlvbmFsIGRhdGFiYXNlIHVzZWQuCgojIyBEZWNsYXJhdGl2ZSBOYXR1cmUgb2YgU1FMCgpTUUwgaXMgYSAqKmRlY2xhcmF0aXZlIGxhbmd1YWdlKiogZ3JvdW5kZWQgaW4gcmVsYXRpb25hbCBhbGdlYnJhLiBUaGUgcHJvZ3JhbW1lciBzcGVjaWZpZXMgKndoYXQqIHJlc3VsdCBpcyBkZXNpcmVkIHJhdGhlciB0aGFuICpob3cqIGl0IGlzIHRvIGJlIGNvbXB1dGVkLiBJbnRlcm5hbGx5LCB0aGUgZGF0YWJhc2UgcXVlcnkgZW5naW5lIHRyYW5zbGF0ZXMgdGhlIFNRTCBzdGF0ZW1lbnQgaW50byBhbiBhbGdlYnJhaWMgZXhwcmVzc2lvbiBhbmQgZ2VuZXJhdGVzIGFuIGV4ZWN1dGlvbiBwbGFuLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBxdWVyeSBwbGFubmluZyBhbmQgZXhlY3V0aW9uLCBzZWUgWzYwLjU1MSAtLSBRdWVyeSBQbGFubmluZyBhbmQgUHJvY2Vzc2luZyBpbiBSZWxhdGlvbmFsIERhdGFiYXNlc10oaHR0cDovL2FydGlmaWNpdW0udXMvbGVzc29ucy82MC5kYmRlc2lnbi9sLTYwLTU1MS1xdWVyeS1wcm9jZXNzaW5nL2wtNjAtNTUxLmh0bWwpCgpJbXBvcnRhbnRseSwgdGhlIHRleHR1YWwgb3JkZXIgb2YgY2xhdXNlcyAqKmRvZXMgbm90KiogY29ycmVzcG9uZCB0byB0aGUgbG9naWNhbCBldmFsdWF0aW9uIG9yZGVyLgoKIyMgU3ludGF4IE9yZGVyIHZzLiBMb2dpY2FsIFByb2Nlc3NpbmcgT3JkZXIKClNRTCBxdWVyaWVzIGFyZSB3cml0dGVuIGluIHRoZSBmb2xsb3dpbmcgY2Fub25pY2FsIGZvcm06CgpgYGAgc3FsClNFTEVDVCAuLi4KRlJPTSAuLi4KV0hFUkUgLi4uCkdST1VQIEJZIC4uLgpIQVZJTkcgLi4uCk9SREVSIEJZIC4uLgpMSU1JVCAuLi4KYGBgCgpXaGlsZSBhIHByb2dyYW1tZXIgbWlnaHQgdGhpbmsgdGhhdCB0aGUgc3ludGFjdGljIG9yZGVyIG9mIHRoZSBjbGF1c2VzIGlzIHRoZSBleGVjdXRpb24gb3JkZXIgb2YgdGhlIGNsYXVzZXMgYnkgdGhlIGRhdGFiYXNlIHF1ZXJ5IGVuZ2luZSwgdGhhdCBpcyBub3QgdGhlIGNhc2UuIFRoZSBxdWVyeSBlbmdpbmUgZXZhbHVhdGVzIHRoZSBxdWVyeSBpbiB0aGUgZm9sbG93aW5nIGxvZ2ljYWwgb3JkZXI6CgoxLiAgKipGUk9NKiog4oCTIElkZW50aWZ5IHNvdXJjZSByZWxhdGlvbnMgYW5kIGNvbXB1dGUgam9pbnMKMi4gICoqV0hFUkUqKiDigJMgQXBwbHkgdHVwbGUtbGV2ZWwgcHJlZGljYXRlcwozLiAgKipHUk9VUCBCWSoqIOKAkyBQYXJ0aXRpb24gdHVwbGVzIGludG8gZ3JvdXBzCjQuICAqKkhBVklORyoqIOKAkyBBcHBseSBncm91cC1sZXZlbCBwcmVkaWNhdGVzCjUuICAqKlNFTEVDVCoqIOKAkyBDb21wdXRlIHByb2plY3Rpb24gYW5kIGV4cHJlc3Npb25zIHBsdXMgd2luZG93IGZ1bmN0aW9ucwo2LiAgKipESVNUSU5DVCoqIOKAkyBFbGltaW5hdGUgZHVwbGljYXRlcyAoaWYgc3BlY2lmaWVkKQo3LiAgKipPUkRFUiBCWSoqIOKAkyBTb3J0IHRoZSByZXN1bHQKOC4gICoqTElNSVQgLyBPRkZTRVQqKiDigJMgUmVzdHJpY3QgdGhlIHJlc3VsdCBzZXQKClRoaXMgb3JkZXIgcmVmbGVjdHMgdGhlIHJlbGF0aW9uYWwgYWxnZWJyYSB0cmFuc2Zvcm1hdGlvbiBwaXBlbGluZSByYXRoZXIgdGhhbiBwaHlzaWNhbCBleGVjdXRpb24gZGV0YWlscy4gTm90IHVuZGVyc3RhbmRpbmcgdGhlIGV4ZWN1dGlvbiAob3IgZXZhbHVhdGlvbikgb3JkZXIgaXMgYSBjb21tb24gc291cmNlIG9mIG1pc3Rha2VzLiBUaGUgZ3JhcGhpYyBiZWxvdyBzdW1tYXJpemVzIHRoZSBzeW50YXggdnMgbG9naWNhbCBvcmRlciBvZiBTUUwgY2xhdXNlczoKCiFbXShpbWFnZXMvc3FsLWV4ZWN1dGlvbi12cy1sb2dpY2FsLW9yZGVyLnBuZyl7d2lkdGg9IjcwJSJ9CgojIyBGb3JtYWwgSW50ZXJwcmV0YXRpb24gaW4gUmVsYXRpb25hbCBUZXJtcwoKR2l2ZW4gYSBiYXNlIHJlbGF0aW9uICggKlIqICk6CgotICAgKkZST00qIGNvcnJlc3BvbmRzIHRvIHJlbGF0aW9uIGNvbnN0cnVjdGlvbiAoaW5jbHVkaW5nIGpvaW5zKS4KLSAgICpXSEVSRSogY29ycmVzcG9uZHMgdG8gKipzZWxlY3Rpb24gKM+DKSoqLgotICAgKkdST1VQIEJZKiBjb3JyZXNwb25kcyB0byBwYXJ0aXRpb25pbmcgcHJpb3IgdG8gYWdncmVnYXRpb24uCi0gICBBZ2dyZWdhdGlvbiBvcGVyYXRvcnMgKGUuZy4sIGBDT1VOVGAsIGBTVU1gKSBhcHBseSBvdmVyIGVhY2ggcGFydGl0aW9uL2dyb3VwLgotICAgKkhBVklORyogY29ycmVzcG9uZHMgdG8gc2VsZWN0aW9uIG92ZXIgZ3JvdXBlZCByZXN1bHRzLgotICAgKlNFTEVDVCogY29ycmVzcG9uZHMgdG8gKipwcm9qZWN0aW9uICjPgCkqKiBhbmQgY29tcHV0ZWQgYXR0cmlidXRlcy4KLSAgICpPUkRFUiBCWSogaW50cm9kdWNlcyBhIHRvdGFsIG9yZGVyaW5nIChub24tcmVsYXRpb25hbCBvcGVyYXRpb24pLgoKVGh1cywgU1FM4oCZcyBsb2dpY2FsIHByb2Nlc3NpbmcgbW9kZWwgYWxpZ25zIGNsb3NlbHkgd2l0aCBjbGFzc2ljYWwgcmVsYXRpb25hbCBhbGdlYnJhLiBOb3RlIHRoYXQgYW55IGFnZ3JlZ2F0aW9uIGZ1bmN0aW9uIGlzIGFwcGxpZWQgdG8gZWFjaCBwYXJ0aXRpb24gaWYgYSBQQVJUSVRJT04gQlkgb3IgR1JPVVAgQlkgY2xhdXNlIGlzIHByZXNlbnQsIG90aGVyd2lzZSwgaW4gdGhlIGFic2VuY2Ugb2Ygc3VjaCBhIGNsYXVzZSwgaXQgaXMgYXBwbGllZCB0byB0aGUgZW50aXJlIHRhYmxlLiBJdCBpcyBub3QgcG9zc2libGUgdG8gY29tYmluZSB0YWJsZS1sZXZlbCBhbmQgcGFydGl0aW9uLWxldmVsIGFnZ3JlZ2F0aW9uIGluIHRoZSBzYW1lIHF1ZXJ5LgoKQSBxdWVyeSBtYXkgaGF2ZSBib3RoIGEgR1JPVVAgQlkgYW5kIGEgUEFSVElUSU9OIEJZIGNsYXVzZTsgaW4gc3VjaCBhIHNjZW5hcmlvLCB0aGUgR1JPVVAgQlkgaXMgZXhlY3V0ZWQgYmVmb3JlIHRoZSBQQVJUSVRJT04gQlkuCgojIyBFeGFtcGxlIGluIFNRTGl0ZSB1c2luZyBSCgpGb3IgZXhwZWRpZW5jeSwgdGhlIGV4YW1wbGUgYmVsb3cgdXNlcyBhICh0ZW1wb3JhcnkpIGluLW1lbW9yeSBkYXRhYmFzZSByYXRoZXIgdGhhbiBhbiBvbi1kaXNrIGRhdGFiYXNlLgoKYGBge3J9CmxpYnJhcnkoUlNRTGl0ZSkKCmNvbm4gPC0gZGJDb25uZWN0KFJTUUxpdGU6OlNRTGl0ZSgpLCAiOm1lbW9yeToiKQpgYGAKCk5lc3QsIHdlIHdpbGwgY3JlYXRlIGEgdGFibGUgYW5kIGluc2VydCBzYW1wbGUgZGF0YSBpbnRvIHRoZSB0YWJsZS4KCmBgYHtyfQpzIDwtIGRiRXhlY3V0ZShjb25uLCAiCkNSRUFURSBUQUJMRSBlbXBsb3llZXMgKAogIGlkIElOVEVHRVIgUFJJTUFSWSBLRVksCiAgZGVwYXJ0bWVudCBURVhULAogIHNhbGFyeSBJTlRFR0VSCik7CiIpCgpzIDwtIGRiRXhlY3V0ZShjb25uLCAiCklOU0VSVCBJTlRPIGVtcGxveWVlcyAoZGVwYXJ0bWVudCwgc2FsYXJ5KSBWQUxVRVMKKCdFbmdpbmVlcmluZycsIDkwMDAwKSwKKCdFbmdpbmVlcmluZycsIDExMDAwMCksCignSFInLCA2MDAwMCksCignSFInLCA2NTAwMCksCignTWFya2V0aW5nJywgNzAwMDApOwoiKQpgYGAKCiMjIEV4YW1wbGUgMTogVHVwbGUtTGV2ZWwgRmlsdGVyaW5nCgpUaGUgU1FMIHN0YXRlbWVudCBiZWxvdyBmaWx0ZXJzIHR1cGxlcyAocm93cykgYmFzZWQgb24gYSBsb2dpY2FsIGV4cHJlc3Npb24uIE9mIGNvdXJzZSwgdGhlIGV4cHJlc3Npb24gY291bGQgYmUgbW9yZSBjb21wbGV4IHVzaW5nIGEgY29tYmluYXRpb24gb2YgKkFORCosICpPUiosICpOT1QqLCBhbmQgKklTIE5VTEwqLCBhbG9uZ3NpZGUgXDwsIFw+LCBhbmQgPS4KCmBgYHtzcWwgY29ubmVjdGlvbj1jb25ufQpTRUxFQ1QgZGVwYXJ0bWVudCwgc2FsYXJ5IEFTIHdhZ2UKRlJPTSBlbXBsb3llZXMKV0hFUkUgc2FsYXJ5ID4gODAwMDA7CmBgYAoKVGhlIHF1ZXJ5IGVuZ2luZSBldmFsdWF0ZXMgdGhlIHF1ZXJ5IGluIHRoZSBmb2xsb3dpbmcgb3JkZXI6CgoxLiAgKipGUk9NIGVtcGxveWVlcyoqIENvbnN0cnVjdCB0aGUgYmFzZSByZWxhdGlvbi4KCjIuICAqKldIRVJFIHNhbGFyeSBcPiA4MDAwMCoqIEFwcGx5IHNlbGVjdGlvbiBwcmVkaWNhdGUgKCBcc2lnbWFcX3tzYWxhcnkgXD4gODAwMDB9KFIpICkuCgozLiAgKipTRUxFQ1QgZGVwYXJ0bWVudCwgc2FsYXJ5KiogUHJvamVjdCBzcGVjaWZpZWQgYXR0cmlidXRlcy4KCioqTi5CLioqOiBUaGUgKldIRVJFKiBjbGF1c2UgY2Fubm90IHJlZmVyZW5jZSB0aGUgYWxpYXMgKndhZ2UqIGRlZmluZWQgaW4gKlNFTEVDVCogYmVjYXVzZSBwcm9qZWN0aW9uIG9jY3VycyBhZnRlciBzZWxlY3Rpb24gaW4gdGhlIGxvZ2ljYWwgcHJvY2Vzc2luZyBvcmRlci4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgRXhhbXBsZSAyOiBBZ2dyZWdhdGlvbiBhbmQgR3JvdXAtTGV2ZWwgRmlsdGVyaW5nCgpMZXQncyBldmFsdWF0ZSB0aGUgcXVlcnkgYmVsb3cgd2hpY2ggY29udGFpbnMgdHdvIGZpbHRlcmluZyBjbGF1c2VzOiBhICpXSEVSRSogY2xhdXNlIGFuZCBhICpIQVZJTkcqIGNsYXVzZS4gVGhlICpXSEVSRSogY2xhdXNlIGlzIGV4ZWN1dGVkIGZpcnN0IGJlZm9yZSBhbnkgZ3JvdXBpbmcgaXMgZG9uZS4gT25jZSB0aGUgZ3JvdXBpbmdzIGhhcyBiZWVuIGRvbmUsIHRoZSAqSEFWSU5HKiBjbGF1c2UgaXMgZXhlY3V0ZWQgb24gdGhlIGdyb3VwcyB0byBmaWx0ZXIgdGhlIHBhcnRpdGlvbnMuIFRoZSAqT1JERVIgQlkqIGNsYXVzZSBpcyBleGVjdXRlZCBsYXN0LCBhZnRlciB0aGUgY29sdW1ucyBzcGVjaWZpZWQgaW4gdGhlICpTRUxFQ1QqIGhhdmUgYmVlbiBwcm9qZWN0ZWQgb3V0LgoKYGBge3NxbCBjb25uZWN0aW9uPWNvbm59ClNFTEVDVCBkZXBhcnRtZW50LCBBVkcoc2FsYXJ5KSBBUyBhdmdfc2FsYXJ5CkZST00gZW1wbG95ZWVzCldIRVJFIHNhbGFyeSA+IDYwMDAwCkdST1VQIEJZIGRlcGFydG1lbnQKSEFWSU5HIEFWRyhzYWxhcnkpID4gODAwMDAKT1JERVIgQlkgYXZnX3NhbGFyeSBERVNDOwpgYGAKClRvIHN1bW1hcml6ZSwgdGhlIHF1ZXJ5IGlzIGV2YWx1YXRlZCBpbiB0aGUgZm9sbG93aW5nIHNlcXVlbmNlOgoKMS4gICoqRlJPTSBlbXBsb3llZXMqKiBDb25zdHJ1Y3QgYmFzZSByZWxhdGlvbi4KCjIuICAqKldIRVJFIHNhbGFyeSBcPiA2MDAwMCoqIEZpbHRlciB0dXBsZXMuCgozLiAgKipHUk9VUCBCWSBkZXBhcnRtZW50KiogUGFydGl0aW9uIHR1cGxlcyBieSBkZXBhcnRtZW50LgoKNC4gICoqQWdncmVnYXRlIENvbXB1dGF0aW9uKiogQ29tcHV0ZSBgQVZHKHNhbGFyeSlgIHBlciBncm91cC4KCjUuICAqKkhBVklORyBBVkcoc2FsYXJ5KSBcPiA4MDAwMCoqIEZpbHRlciBncm91cHMuCgo2LiAgKipTRUxFQ1QgZGVwYXJ0bWVudCwgQVZHKHNhbGFyeSkqKiBQcm9qZWN0IGF0dHJpYnV0ZXMgYW5kIGNvbXB1dGVkIGFnZ3JlZ2F0ZXMuCgo3LiAgKipPUkRFUiBCWSBhdmdfc2FsYXJ5IERFU0MqKiBTb3J0IGZpbmFsIHJlc3VsdC4KCiMjIEFsaWFzIFNjb3BlCgpUaGlzIHF1ZXJ5IGZhaWxzIGJlY2F1c2UgYW55IGFsaWFzIGRlZmluZWQgaW4gdGhlICpTRUxFQ1QqIGNsYXVzZSBpcyBub3QgYXZhaWxhYmxlIGluIHRoZSAqV0hFUkUqIHNpbmNlIHRoZSAqV0hFUkUqIGNsYXVzZSBpcyBldmFsdWF0ZWQgYmVmb3JlIHRoZSAqU0VMRUNUKi4gSG93ZXZlciwgYW4gYWxpYXMgZm9yIGEgdGFibGUgaXMgYXZhaWxhYmxlIGFzIHRoZSAqRlJPTSogaXMgZXhlY3V0ZWQgZmlyc3Q6CgpgYGAgc3FsClNFTEVDVCBzYWxhcnkgKiAxLjEgQVMgaW5jcmVhc2VkX3NhbGFyeQpGUk9NIGVtcGxveWVlcyBBUyBlCldIRVJFIGUuaW5jcmVhc2VkX3NhbGFyeSA+IDgwMDAwOwpgYGAKClNvLCBiZWNhdXNlICpXSEVSRSogaXMgbG9naWNhbGx5IGV2YWx1YXRlZCBiZWZvcmUgKlNFTEVDVCosIHRoZSBhbGlhcyAqaW5jcmVhc2VkX3NhbGFyeSogZG9lcyBub3QgeWV0IGV4aXN0LgoKVGhlIGNvcnJlY3QgZm9ybXVsYXRpb24gc2hvdWxkIGJlOgoKYGBgIHNxbApTRUxFQ1Qgc2FsYXJ5ICogMS4xIEFTIGluY3JlYXNlZF9zYWxhcnkKRlJPTSBlbXBsb3llZXMKV0hFUkUgc2FsYXJ5ICogMS4xID4gODAwMDA7CmBgYAoKIyMgV0hFUkUgdnMuIEhBVklORwoKQSBjb21tb24gY29uZnVzaW9uIGlzIG1pc3VuZGVyc3RhbmRpbmcgKldIRVJFKiB2ZXJzdXMgKkhBVklORyo6ICpXSEVSRSogZmlsdGVycyAqKnR1cGxlcyBwcmlvciB0byBncm91cGluZyoqIHdoZXJlYXMgKkhBVklORyogZmlsdGVycyAqKmdyb3VwcyBhZnRlciBncm91cGluZyoqLgoKVGh1cywgdGhlIGNsYXVzZToKCmBgYCBzcWwKSEFWSU5HIENPVU5UKCopID4gMQpgYGAKCmlzIHZhbGlkLCB3aGlsZToKCmBgYCBzcWwKV0hFUkUgQ09VTlQoKikgPiAxCmBgYAoKaXMgbm90LgoKIyMgTG9naWNhbCB2cy4gUGh5c2ljYWwgRXhlY3V0aW9uCgpJdCBpcyBpbXBvcnRhbnQgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbjoKCi0gICAqKkxvZ2ljYWwgcHJvY2Vzc2luZyBvcmRlcioqIChzZW1hbnRpYyBtb2RlbCkKLSAgICoqUGh5c2ljYWwgZXhlY3V0aW9uIHBsYW4qKiAob3B0aW1pemVyLWRlcGVuZGVudCkKClNRTGl0ZSwgbGlrZSBvdGhlciBEQk1TcywgbWF5IHJlb3JkZXIgb3BlcmF0aW9ucyBmb3IgZWZmaWNpZW5jeSAocHJlZGljYXRlIHB1c2hkb3duLCBpbmRleCBzY2Fucywgam9pbiByZW9yZGVyaW5nKS4gSG93ZXZlciwgdGhlc2UgdHJhbnNmb3JtYXRpb25zIHByZXNlcnZlIGxvZ2ljYWwgZXF1aXZhbGVuY2UgdW5kZXIgcmVsYXRpb25hbCBhbGdlYnJhIHJ1bGVzLiBTZWUgWzYwLjU1MSAtLSBRdWVyeSBQbGFubmluZyBhbmQgUHJvY2Vzc2luZyBpbiBSZWxhdGlvbmFsIERhdGFiYXNlc10oaHR0cDovL2FydGlmaWNpdW0udXMvbGVzc29ucy82MC5kYmRlc2lnbi9sLTYwLTU1MS1xdWVyeS1wcm9jZXNzaW5nL2wtNjAtNTUxLmh0bWwpIGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHF1ZXJ5IHBsYW5uaW5nIGFuZCBleGVjdXRpb24uCgojIyBTdW1tYXJ5CgpVbmRlcnN0YW5kaW5nIGxvZ2ljYWwgcXVlcnkgcHJvY2Vzc2luZyBpcyBrZXkgdG8gdmlydHVhbGx5IGV2ZXJ5IGFzcGVjdCBvZiB3b3JraW5nIHdpdGggcmVsYXRpb25hbCBkYXRhYmFzZXMsIGVzcGVjaWFsbHkgZm9yIHdyaXRpbmcgc2VtYW50aWNhbGx5IGNvcnJlY3QgYW5hbHl0aWNhbCBxdWVyaWVzLCBhbmQgYmVpbmcgYWJsZSB0byBjb3JyZWN0IGFsdGVybmF0aXZlLCBhbmQgcGVyaGFwcyBtb3JlIGVmZmljaWVudCwgcXVlcnkgZm9ybXVsYXRpb25zLgoKVGhlIGFwcGFyZW50IGNvbnRyYWRpY3Rpb24gYmV0d2VlbiBTUUzigJlzIHRleHR1YWwgc3RydWN0dXJlIGFuZCBpdHMgbG9naWNhbCBwcm9jZXNzaW5nIG9yZGVyIGlzIG5vdCBhY2NpZGVudGFsOyBpdCByZWZsZWN0cyBTUUzigJlzIGRlY2xhcmF0aXZlIGZvdW5kYXRpb24gaW4gcmVsYXRpb25hbCBhbGdlYnJhLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBGaWxlcyAmIFJlc291cmNlcwoKYGBge3IgemlwRmlsZXMsIGVjaG89RkFMU0V9CnppcE5hbWUgPSBzcHJpbnRmKCJMZXNzb25GaWxlcy0lcy0lcy56aXAiLCAKICAgICAgICAgICAgICAgICBwYXJhbXMkY2F0ZWdvcnksCiAgICAgICAgICAgICAgICAgcGFyYW1zJG51bWJlcikKCnRleHRBTGluayA9IHBhc3RlMCgiQWxsIEZpbGVzIGZvciBMZXNzb24gIiwgCiAgICAgICAgICAgICAgIHBhcmFtcyRjYXRlZ29yeSwiLiIscGFyYW1zJG51bWJlcikKCiMgZG93bmxvYWRGaWxlc0xpbmsoKSBpcyBpbmNsdWRlZCBmcm9tIF9pbnNlcnQyREIuUgprbml0cjo6cmF3X2h0bWwoZG93bmxvYWRGaWxlc0xpbmsoIi4iLCB6aXBOYW1lLCB0ZXh0QUxpbmspKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgQWNrbm93bGVkZ2VtZW50CgpDbGF1ZGUgNC42IChTb25uZXQpIHdhcyB1c2VkIHRvIGFzc2lzdCBpbiB0aGUgcHJlcGFyYXRpb24gb2YgdGhpcyBsZXNzb24uCgojIyBFcnJhdGEKCltMZXQgdXMga25vd10oaHR0cHM6Ly9mb3JtLmpvdGZvcm0uY29tLzIxMjE4NzA3Mjc4NDE1Nyl7dGFyZ2V0PSJfYmxhbmsifS4K