
{"id":3031,"date":"2019-05-07T09:18:29","date_gmt":"2019-05-07T08:18:29","guid":{"rendered":"http:\/\/dasini.net\/blog\/?p=3031"},"modified":"2019-05-07T09:18:36","modified_gmt":"2019-05-07T08:18:36","slug":"constant-folding-optimization-in-mysql-8-0","status":"publish","type":"post","link":"https:\/\/dasini.net\/blog\/2019\/05\/07\/constant-folding-optimization-in-mysql-8-0\/","title":{"rendered":"Constant-Folding Optimization in MySQL 8.0"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">TL;TR<\/h2>\n\n\n\n<p>In MySQL 8.0.<strong>16<\/strong> the optimizer has improved again!<br>Comparisons of columns of numeric types with constant values are checked and folded or removed for invalid or out-of-rage values.<br>The goal is to <strong>speed up query execution<\/strong>. <\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n\n\n<p>The name of this article (<strong><a href=\"https:\/\/en.wikipedia.org\/wiki\/Constant_folding\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Constant-Folding (opens in a new tab)\">Constant-Folding<\/a><\/strong> Optimization), named after this kind of optimization, is quite cryptic. Nevertheless the principle is simple and more important there is nothing to do from the user perspective.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is \u00ab\u00a0Constant-Folding Optimization\u00a0\u00bb ?<\/h2>\n\n\n\n<p>From the <a rel=\"noreferrer noopener\" aria-label=\"MySQL Documentation (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/constant-folding-optimization.html\" target=\"_blank\">MySQL Documentation<\/a> : <br><em>Comparisons between constants and column values in which the constant value is out of range or of the wrong type with respect to the column type are now handled once during query optimization rather row-by-row than during execution<\/em>.<\/p>\n\n\n\n<p>From the <a rel=\"noreferrer noopener\" aria-label=\"MySQL Server Team Blog (opens in a new tab)\" href=\"https:\/\/mysqlserverteam.com\/the-mysql-8-0-16-maintenance-release-is-generally-available\/\" target=\"_blank\">MySQL Server Team Blog<\/a> : <br><em>The goal is to speed up execution at the cost of a little more analysis at optimize time. <br>Always true and false comparisons are detected and eliminated. <br>In other cases, the type of the constant is adjusted to match that of the field if they are not the same, avoiding type conversion at execution time<\/em>.<\/p>\n\n\n\n<p>Clear enough?<\/p>\n\n\n\n<p>One example is worth a thousand words, so let&rsquo;s have a deeper look comparing the old behavior in MySQL 8.0.15 to the new one beginning with MySQL 8.0.16.<\/p>\n\n\n\n<p>I&rsquo;m using the optimized <a rel=\"noreferrer noopener\" aria-label=\"MySQL Server Docker images (opens in a new tab)\" href=\"https:\/\/hub.docker.com\/r\/mysql\/mysql-server\" target=\"_blank\">MySQL Server Docker images<\/a>, created, maintained and supported by the MySQL team at Oracle.<\/p>\n\n\n\n<p>Deployment of MySQL 8.0.15 &amp; MySQL 8.0.16:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker run --name=mysql_8.0.15 -e MYSQL_ROOT_PASSWORD=unsafe -d mysql\/mysql-server:8.0.15<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker run --name=mysql_8.0.16 -e MYSQL_ROOT_PASSWORD=unsafe -d mysql\/mysql-server:8.0.16<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><u>Note<\/u>:<\/p><p>Obviously using a password on the command line interface can be <strong>insecure<\/strong>. <\/p><p>Please read the best practices of <a rel=\"noreferrer noopener\" aria-label=\"deploying MySQL on Linux with Docker (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/linux-installation-docker.html\" target=\"_blank\">deploying MySQL on Linux with Docker<\/a>.<\/p><\/blockquote>\n\n\n\n<p><br>Copy the test table dump file on 8.0.15 &amp; 8.0.16:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker cp .\/testtbl.sql mysql_8.0.15:\/tmp\/testtbl.sql<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker cp .\/testtbl.sql mysql_8.0.16:\/tmp\/testtbl.sql<\/code><\/pre>\n\n\n\n<p><br>Load the test table into 8.0.15 instance:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker exec -it mysql_8.0.15 mysql -u root -p --prompt='mysql_8.0.15> '\n\nEnter password: \nWelcome to the MySQL monitor.  Commands end with ; or \\g.\nYour MySQL connection id is 31\nServer version: 8.0.15 MySQL Community Server - GPL\n\nCopyright (c) 2000, 2019, Oracle and\/or its affiliates. All rights reserved.\n\nOracle is a registered trademark of Oracle Corporation and\/or its\naffiliates. Other names may be trademarks of their respective\nowners.\n\nType 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.\n\nmysql_8.0.15> SELECT VERSION();\n+-----------+\n| VERSION() |\n+-----------+\n| 8.0.15    |\n+-----------+\n\nmysql_8.0.15> CREATE SCHEMA test;\nQuery OK, 1 row affected (0.04 sec)\n\nmysql_8.0.15> USE test\nDatabase changed\n\nmysql_8.0.15> source \/tmp\/testtbl.sql\n... &lt;snip> ...<\/code><\/pre>\n\n\n\n<p><br>Load the test table into 8.0.16 instance:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker exec -it mysql_8.0.16 mysql -u root -p --prompt='mysql_8.0.16> '\n\nEnter password: \nWelcome to the MySQL monitor.  Commands end with ; or \\g.\nYour MySQL connection id is 12\nServer version: 8.0.16 MySQL Community Server - GPL\n\nCopyright (c) 2000, 2019, Oracle and\/or its affiliates. All rights reserved.\n\nOracle is a registered trademark of Oracle Corporation and\/or its\naffiliates. Other names may be trademarks of their respective\nowners.\n\nType 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.\n\nmysql_8.0.16> SELECT VERSION();\n+-----------+\n| VERSION() |\n+-----------+\n| 8.0.16    |\n+-----------+\n\nmysql_8.0.16> CREATE SCHEMA test;\nQuery OK, 1 row affected (0.04 sec)\n\nmysql_8.0.16> USE test\nDatabase changed\n\nmysql_8.0.16> source \/tmp\/testtbl.sql\n... &lt;snip> ...<\/code><\/pre>\n\n\n\n<p><br><br>Let&rsquo;s see what we have loaded:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_8.0.16> SHOW CREATE TABLE testtbl\\G\n*************************** 1. row ***************************\n       Table: testtbl\nCreate Table: CREATE TABLE `testtbl` (\n  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,\n  `val` varchar(36) NOT NULL,\n  `val2` varchar(36) DEFAULT NULL,\n  `val3` varchar(36) DEFAULT NULL,\n  `val4` varchar(36) DEFAULT NULL,\n  `num` int(10) unsigned DEFAULT NULL,\n  PRIMARY KEY (`id`),\n  KEY `idx2` (`val2`),\n  KEY `idx3` (`val3`),\n  KEY `idx4` (`val4`)\n) ENGINE=InnoDB AUTO_INCREMENT=14220001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci\n\n\nmysql_8.0.16> SELECT COUNT(*) FROM testtbl;\n+----------+\n| COUNT(*) |\n+----------+\n|  5000000 |\n+----------+<\/code><\/pre>\n\n\n\n<p>What is important for us here is the non indexed column &#8211; <em>num<\/em> :<br><br><code><em>num<\/em><\/code><em> <\/em><strong><em>int<\/em><\/strong><em>(10) <\/em><strong><em>unsigned<\/em><\/strong><em> DEFAULT NULL<br><\/em><br>It contains only <strong>positive <\/strong>numbers:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_8.0.16> SELECT min(num), max(num) FROM testtbl;\n+----------+----------+\n| min(num) | max(num) |\n+----------+----------+\n|  9130001 | 14130000 |\n+----------+----------+<\/code><\/pre>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">The old behavior<\/h2>\n\n\n\n<p>What happens if I looking for a negative number, let&rsquo;s say <strong>-12345<\/strong>, on the  column <em>num<\/em> ? <br>Remember that it contains only positive numbers and there is no index. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_8.0.15> EXPLAIN SELECT * FROM testtbl WHERE num=-12345\\G\n*************************** 1. row ***************************\n           id: 1\n  select_type: SIMPLE\n        table: testtbl\n   partitions: NULL\n         type: ALL\npossible_keys: NULL\n          key: NULL\n      key_len: NULL\n          ref: NULL\n         rows: 4820634\n     filtered: 10.00\n        Extra: Using where<\/code><\/pre>\n\n\n\n<p>According to the EXPLAIN plan, we have a full table scan. In a way that  makes sense because there is no index on <em>num<\/em>. <br>However we know that there is <u>no negative value<\/u>, so there is certainly some room for improvements \ud83d\ude42<\/p>\n\n\n\n<p>Running the query:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_8.0.15> SELECT * FROM testtbl WHERE num=-12345;\nEmpty set (2.77 sec)<\/code><\/pre>\n\n\n\n<p>Indeed the full table scan could be costly.<\/p>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">The current behavior &#8211; 8.0.16+<\/h2>\n\n\n\n<p>The <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/constant-folding-optimization.html\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Constant-Folding Optimization (opens in a new tab)\">Constant-Folding Optimization<\/a> improves the execution of this type of queries.<\/p>\n\n\n\n<p>The <a rel=\"noreferrer noopener\" aria-label=\"EXPLAIN (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/execution-plan-information.html\" target=\"_blank\">EXPLAIN<\/a> plan for <strong>MySQL 8.0.16<\/strong> is completely different:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_8.0.16> EXPLAIN SELECT * FROM testtbl WHERE num=-12345\\G\n*************************** 1. row ***************************\n           id: 1\n  select_type: SIMPLE\n        table: NULL\n   partitions: NULL\n         type: NULL\npossible_keys: NULL\n          key: NULL\n      key_len: NULL\n          ref: NULL\n         rows: NULL\n     filtered: NULL\n        Extra: Impossible WHERE<\/code><\/pre>\n\n\n\n<p>Did you notice the:<br><br><code><strong>    Extra: Impossible WHERE<\/strong><\/code><\/p>\n\n\n\n<p>Looking for the negative value in a strictly positive column was processed at the optimize time!<br>So they are obviously a <u>positive impact<\/u> on the query execution time:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_8.0.16> SELECT * FROM testtbl WHERE num=-12345;\nEmpty set (0.00 sec)<\/code><\/pre>\n\n\n\n<p>Yay!<\/p>\n\n\n\n<p><br><br>In addition to the <strong>=<\/strong> operator, this optimization is currently possible for <strong>&gt;<\/strong>, <strong>&gt;=<\/strong>, <strong>&lt;<\/strong>, <strong>&lt;=<\/strong>, <strong>=<\/strong>, <strong>&lt;&gt;, !=<\/strong> and <strong>&lt;=&gt;<\/strong> as well.<br>e.g.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_8.0.16> EXPLAIN SELECT * FROM testtbl WHERE num > -42 AND num &lt;= -1 \\G\n*************************** 1. row ***************************\n           id: 1\n  select_type: SIMPLE\n        table: NULL\n   partitions: NULL\n         type: NULL\npossible_keys: NULL\n          key: NULL\n      key_len: NULL\n          ref: NULL\n         rows: NULL\n     filtered: NULL\n        Extra: Impossible WHERE\n\n\nmysql_8.0.16> SELECT * FROM testtbl WHERE num > -42 AND num &lt;=  -1;\nEmpty set (0.00 sec)<\/code><\/pre>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Indexed column<\/h2>\n\n\n\n<p>As a side note, if your column is indexed the optimizer already have the relevant information, so <u>before<\/u> 8.0.16, no need of Constant-Folding Optimization, to have a fast query :).<br><br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_8.0.15> CREATE INDEX idx_num ON testtbl(num);\nQuery OK, 0 rows affected (24.84 sec)\nRecords: 0  Duplicates: 0  Warnings: 0\n\n\nmysql_8.0.15> EXPLAIN SELECT * FROM testtbl WHERE num = -12345\\G\n*************************** 1. row ***************************\n           id: 1\n  select_type: SIMPLE\n        table: NULL\n   partitions: NULL\n         type: NULL\npossible_keys: NULL\n          key: NULL\n      key_len: NULL\n          ref: NULL\n         rows: NULL\n     filtered: NULL\n        Extra: no matching row in const table\n1 row in set, 1 warning (0.00 sec)\n\n\nmysql_8.0.15> SELECT * FROM testtbl WHERE num = -12345;\nEmpty set (0.00 sec)<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">References<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><a rel=\"noreferrer noopener\" aria-label=\"Constant-Folding Optimization (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/constant-folding-optimization.html\" target=\"_blank\">Constant-Folding Optimization<\/a>  <\/li><li><a rel=\"noreferrer noopener\" aria-label=\"WL#11935: Add folding of constants when compared to fields (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/worklog\/task\/?id=11935\" target=\"_blank\">WL#11935: Add folding of constants when compared to fields<\/a> <\/li><li><a rel=\"noreferrer noopener\" aria-label=\"Deploying MySQL on Linux with Docker (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/linux-installation-docker.html\" target=\"_blank\">Deploying MySQL on Linux with Docker<\/a> <\/li><li><a href=\"https:\/\/hub.docker.com\/r\/mysql\/mysql-server\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Optimized MySQL Server Docker images (opens in a new tab)\">Optimized MySQL Server Docker images<\/a> <\/li><\/ul>\n\n\n\n\n\n<div style=\"height:75px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-vivid-red-color has-text-color\"><strong>Thanks for using MySQL!<\/strong><\/p>\n\n\n\n<div style=\"height:25px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><a href=\"https:\/\/www.linkedin.com\/groups\/12524512\/\" target=\"_blank\" rel=\"noopener\" title=\"Olivier DASINI on Linkedin\">Follow me on Linkedin<\/a><\/p>\n\n\n\n<p>Watch my videos on my <a href=\"https:\/\/www.youtube.com\/channel\/UC12TulyJsJZHoCmby3Nm3WQ\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Olivier's MySQL Channel\">YouTube channel<\/a> and <a href=\"https:\/\/www.youtube.com\/channel\/UC12TulyJsJZHoCmby3Nm3WQ\/?sub_confirmation=1\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Subscribe\">subscribe<\/a>.<\/p>\n\n\n\n<p>My <a href=\"https:\/\/www.slideshare.net\/freshdaz\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Olivier DASINI on Slideshare\">Slideshare account<\/a>.<\/p>\n\n\n\n<p>My <a href=\"https:\/\/speakerdeck.com\/freshdaz\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Olivier DASINI on Speaker Deck\">Speaker Deck account<\/a>.<\/p>\n\n\n\n<div style=\"height:25px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-vivid-red-color has-text-color\"><strong>Thanks for using HeatWave &amp; MySQL!<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In MySQL 8.0.16 the optimizer has improved again!<br \/>\nComparisons of columns of numeric types with constant values are checked and folded or removed for invalid or out-of-rage values.<br \/>\nThe goal is to speed up query execution. <\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":""},"categories":[203,34,904],"tags":[320,191,202],"class_list":["post-3031","post","type-post","status-publish","format-standard","hentry","category-mysql-en","category-optimisation","category-performance","tag-docker","tag-optimization","tag-performance"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9LfWW-MT","jetpack-related-posts":[{"id":2746,"url":"https:\/\/dasini.net\/blog\/2019\/03\/14\/mysql-functional-indexes\/","url_meta":{"origin":3031,"position":0},"title":"MySQL Functional Indexes","author":"Olivier DASINI","date":"14 mars 2019","format":false,"excerpt":"Since MySQL 5.7 one can put indexes on expressions, aka functional indexes, using generated columns. Basically you first need to use the generated column to define the functional expression, then indexed this column. Quite useful when dealing with JSON functions, you can find an example here and the documentation there.\u2026","rel":"","context":"Dans &quot;Astuce&quot;","block_context":{"text":"Astuce","link":"https:\/\/dasini.net\/blog\/category\/astuce\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3157,"url":"https:\/\/dasini.net\/blog\/2019\/06\/05\/mysql-8-0-16-new-features-summary\/","url_meta":{"origin":3031,"position":1},"title":"MySQL 8.0.16 New Features Summary","author":"Olivier DASINI","date":"5 juin 2019","format":false,"excerpt":"Presentation of some of the new features of MySQL 8.0.16 released on April 25, 2019","rel":"","context":"Dans &quot;Group Replication&quot;","block_context":{"text":"Group Replication","link":"https:\/\/dasini.net\/blog\/category\/group-replication-en\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/img.youtube.com\/vi\/3_esLnhHHck\/0.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1515,"url":"https:\/\/dasini.net\/blog\/2015\/11\/17\/30-mins-with-json-in-mysql\/","url_meta":{"origin":3031,"position":2},"title":"30 mins with JSON in MySQL","author":"Olivier DASINI","date":"17 novembre 2015","format":false,"excerpt":"MySQL 5.7 is GA and has over than 150 new features. One of them is a Native JSON Data Type and JSON Functions: \"Allows for efficient and flexible storage, search and manipulation of schema-less data. Enhancements include a new internal binary format, support for easy integration within SQL, and index\u2026","rel":"","context":"Dans &quot;json&quot;","block_context":{"text":"json","link":"https:\/\/dasini.net\/blog\/category\/json\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3058,"url":"https:\/\/dasini.net\/blog\/2019\/05\/14\/check-constraints-in-mysql\/","url_meta":{"origin":3031,"position":3},"title":"CHECK constraints in MySQL","author":"Olivier DASINI","date":"14 mai 2019","format":false,"excerpt":"MySQL (really) supports CHECK CONSTRAINT since version 8.0.16. In this article I will show you 2 things: - An elegant way to simulate check constraint in MySQL 5.7 & 8.0. - How easy & convenient it is to use CHECK constraints in 8.0.16.","rel":"","context":"Dans &quot;Astuce&quot;","block_context":{"text":"Astuce","link":"https:\/\/dasini.net\/blog\/category\/astuce\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3166,"url":"https:\/\/dasini.net\/blog\/2019\/06\/11\/check-the-mysql-server-startup-configuration\/","url_meta":{"origin":3031,"position":4},"title":"Check the MySQL server startup configuration","author":"Olivier DASINI","date":"11 juin 2019","format":false,"excerpt":"Since 8.0.16, MySQL Server supports a --validate-config option that enables the startup configuration to be checked for problems without running the server in normal operational mode. --validate-config can be used any time, but is particularly useful after an upgrade, to check whether any options previously used with the older server\u2026","rel":"","context":"Dans &quot;Astuce&quot;","block_context":{"text":"Astuce","link":"https:\/\/dasini.net\/blog\/category\/astuce\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":8393,"url":"https:\/\/dasini.net\/blog\/2025\/10\/07\/let-your-ai-dba-assistant-write-your-mysql-queries\/","url_meta":{"origin":3031,"position":5},"title":"Let Your AI DBA Assistant Write Your MySQL Queries","author":"Olivier DASINI","date":"7 octobre 2025","format":false,"excerpt":"Having explored the innovative MySQL HeatWave technology that converts Natural Language into SQL (Ask Your Database Anything: Natural Language to SQL in MySQL HeatWave), our next article in this series, dives into a practical use case demonstrating how an AI DBA Assistant can significantly simplify your query generation workflow. In\u2026","rel":"","context":"Dans &quot;AI&quot;","block_context":{"text":"AI","link":"https:\/\/dasini.net\/blog\/category\/ai\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/2025\/10\/reltime_monitor.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/2025\/10\/reltime_monitor.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/2025\/10\/reltime_monitor.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/2025\/10\/reltime_monitor.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/3031","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/comments?post=3031"}],"version-history":[{"count":33,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/3031\/revisions"}],"predecessor-version":[{"id":3072,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/3031\/revisions\/3072"}],"wp:attachment":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/media?parent=3031"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/categories?post=3031"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/tags?post=3031"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}