<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>SQL Differences on BareSQL.com</title>
    <link>https://baresql.com/tags/sql-differences/</link>
    <description>Recent content in SQL Differences on BareSQL.com</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 26 Oct 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://baresql.com/tags/sql-differences/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>A Backslash in LIKE Escapes Percent and Underscore Everywhere Except SQLite</title>
      <link>https://baresql.com/a-backslash-in-like-escapes-percent-and-underscore-everywhere-except-sqlite/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/a-backslash-in-like-escapes-percent-and-underscore-everywhere-except-sqlite/</guid>
      <description>&lt;p&gt;Searching for the text 50_off with &lt;code&gt;LIKE &#39;50\_off&#39;&lt;/code&gt; works on PostgreSQL, MySQL and MariaDB, where the backslash escapes the underscore. SQLite treats the backslash as an ordinary character, and the search finds nothing.&lt;/p&gt;&#xA;&lt;p&gt;&#39;a_b&#39; LIKE &#39;a\_b&#39; is true on PostgreSQL, MySQL and MariaDB, where \_ matches an underscore, and false on SQLite, where the pattern asks for a backslash followed by any one character.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-like-escape.png&#34; alt=&#34;SELECT &#39;a_b&#39; LIKE &#39;a\_b&#39;, run on four engines: SQLite 3.45.1 0; PostgreSQL 16.15 true; MySQL 8.0.46 1; MariaDB 10.11.14 1.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Backslash Is an Escape Character in MySQL Strings and a Plain Character in PostgreSQL</title>
      <link>https://baresql.com/a-backslash-is-an-escape-character-in-mysql-strings-and-a-plain-character-in-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/a-backslash-is-an-escape-character-in-mysql-strings-and-a-plain-character-in-postgresql/</guid>
      <description>&lt;p&gt;A Windows path written as &lt;code&gt;&#39;C:\temp\new&#39;&lt;/code&gt; reads back on MySQL and MariaDB with a tab and a line break in it. PostgreSQL and SQLite keep the backslashes as typed.&lt;/p&gt;&#xA;&lt;p&gt;&#39;C:\\temp&#39; is C:\\temp, two backslashes, on SQLite and PostgreSQL and C:\temp on MySQL and MariaDB. &#39;\t&#39; is a tab and &#39;\&#39;&#39; a quote there, while PostgreSQL needs its E&#39;...&#39; strings for escapes, which no other engine reads. MySQL’s NO_BACKSLASH_ESCAPES mode makes it read backslashes like the others.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Adding 1 to a Date Gives the Next Day on PostgreSQL and a Number on MySQL and SQLite</title>
      <link>https://baresql.com/adding-1-to-a-date-gives-the-next-day-on-postgresql-and-a-number-on-mysql-and-sqlite/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/adding-1-to-a-date-gives-the-next-day-on-postgresql-and-a-number-on-mysql-and-sqlite/</guid>
      <description>&lt;p&gt;&lt;code&gt;due_date + 1&lt;/code&gt; reads like the day after, and on PostgreSQL that is what it gives. On MySQL, MariaDB and SQLite the answer is a plain number.&lt;/p&gt;&#xA;&lt;p&gt;MySQL and MariaDB turn the date into the number 20240131 and add 1. SQLite turns the text into the number 2024. PostgreSQL adds a day. Subtracting two dates goes the same way: PostgreSQL counts days and MySQL and MariaDB subtract the numbers. INTERVAL arithmetic works on PostgreSQL, MySQL and MariaDB, with different result types, and SQLite has no INTERVAL. PostgreSQL’s usual INTERVAL &#39;1 day&#39;, with the unit inside the quotes, works on PostgreSQL only.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Backticks Around Names Work on MySQL and SQLite and Fail on PostgreSQL</title>
      <link>https://baresql.com/backticks-around-names-work-on-mysql-and-sqlite-and-fail-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/backticks-around-names-work-on-mysql-and-sqlite-and-fail-on-postgresql/</guid>
      <description>&lt;p&gt;MySQL examples often quote every name in backticks, as in &lt;code&gt;SELECT `name` FROM `people`&lt;/code&gt;. Copied into a PostgreSQL project, the query fails.&lt;/p&gt;&#xA;&lt;p&gt;`name` is MySQL’s way of quoting a name, and SQLite and MariaDB accept it too. PostgreSQL reads the backtick as a syntax error.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-backticks.png&#34; alt=&#34;SELECT `name` FROM people, run on four engines: SQLite 3.45.1 &#39;Ann&#39;; PostgreSQL 16.15 error: syntax error at or near &amp;quot;FROM&amp;quot;; MySQL 8.0.46 &#39;Ann&#39;; MariaDB 10.11.14 &#39;Ann&#39;.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>CAST to CHAR Cuts a Value to One Character on PostgreSQL</title>
      <link>https://baresql.com/cast-to-char-cuts-a-value-to-one-character-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/cast-to-char-cuts-a-value-to-one-character-on-postgresql/</guid>
      <description>&lt;p&gt;&lt;code&gt;CAST(order_id AS CHAR)&lt;/code&gt; looks like a safe way to turn a number into text. On PostgreSQL CHAR without a length means one character, so order 123 comes back as &lt;code&gt;&#39;1&#39;&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;PostgreSQL reads CHAR without a length as CHAR(1) and cuts the value to fit. With a length, CHAR(10), it pads the value with spaces. MySQL accepts CHAR in CAST but neither VARCHAR nor TEXT, and MariaDB accepts VARCHAR but not TEXT.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CAST to DATE Returns the Number 2024 on SQLite Because It Has No Date Type</title>
      <link>https://baresql.com/cast-to-date-returns-the-number-2024-on-sqlite-because-it-has-no-date-type/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/cast-to-date-returns-the-number-2024-on-sqlite-because-it-has-no-date-type/</guid>
      <description>&lt;p&gt;Filtering orders with &lt;code&gt;CAST(created_at AS DATE) = &#39;2024-05-06&#39;&lt;/code&gt; works on PostgreSQL, MySQL and MariaDB. SQLite has no date type, turns the CAST into a number and keeps only the year, so the filter never matches.&lt;/p&gt;&#xA;&lt;p&gt;SQLite keeps dates as text or numbers and reads a CAST to DATE, DATETIME or TIMESTAMP as a conversion to a number, which keeps only the leading digits. MySQL and MariaDB also refuse CAST(x AS TIMESTAMP), and PostgreSQL refuses DATETIME.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CAST to INTEGER Fails on MySQL and Rounds Differently on SQLite and PostgreSQL</title>
      <link>https://baresql.com/cast-to-integer-fails-on-mysql-and-rounds-differently-on-sqlite-and-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/cast-to-integer-fails-on-mysql-and-rounds-differently-on-sqlite-and-postgresql/</guid>
      <description>&lt;p&gt;Turning a price into a whole number with &lt;code&gt;CAST(5.7 AS INTEGER)&lt;/code&gt; gives 5 on SQLite and 6 on PostgreSQL and MariaDB. MySQL doesn’t run it at all.&lt;/p&gt;&#xA;&lt;p&gt;SQLite drops the fraction and PostgreSQL and MariaDB round it. MySQL takes only SIGNED and UNSIGNED as integer types in CAST, and PostgreSQL refuses both. Decimals differ as well: SQLite ignores the scale of CAST(x AS DECIMAL(10, 1)) and keeps every digit, and MySQL and MariaDB read DECIMAL without a precision as DECIMAL(10, 0), a whole number.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CHAR Columns Come Back Padded With Spaces on PostgreSQL</title>
      <link>https://baresql.com/char-columns-come-back-padded-with-spaces-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/char-columns-come-back-padded-with-spaces-on-postgresql/</guid>
      <description>&lt;p&gt;An order status kept in a &lt;code&gt;CHAR(10)&lt;/code&gt; column compares as expected in SQL on every engine. In the application code, though, a check for paid orders fails on PostgreSQL alone.&lt;/p&gt;&#xA;&lt;p&gt;A CHAR(5) column holding &#39;a&#39; returns &#39;a    &#39; on PostgreSQL. Comparisons there ignore the padding, so WHERE c = &#39;a&#39; still matches, but the spaces reach the application and CONCAT. MySQL and MariaDB strip trailing spaces when they read CHAR values, and SQLite does not apply the length at all.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Column Types Like DATETIME and BYTEA Exist on Some SQL Engines Only</title>
      <link>https://baresql.com/column-types-like-datetime-and-bytea-exist-on-some-sql-engines-only/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/column-types-like-datetime-and-bytea-exist-on-some-sql-engines-only/</guid>
      <description>&lt;p&gt;A schema with DATETIME and JSONB columns runs on SQLite without complaint. Both types fail on at least one of the other engines.&lt;/p&gt;&#xA;&lt;p&gt;SQLite accepts nearly any type name, so a schema that works there can still fail elsewhere. Each type in the table was used in a CREATE TABLE on all four engines.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-type-not-everywhere.png&#34; alt=&#34;CREATE TABLE t (d DATETIME); SELECT COUNT(*) FROM t, run on four engines: SQLite 3.45.1 0; PostgreSQL 16.15 error: type &amp;quot;datetime&amp;quot; does not exist; MySQL 8.0.46 0; MariaDB 10.11.14 0.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Columns Missing From GROUP BY Work on SQLite and MariaDB and Fail on PostgreSQL and MySQL</title>
      <link>https://baresql.com/columns-missing-from-group-by-work-on-sqlite-and-mariadb-and-fail-on-postgresql-and-mysql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/columns-missing-from-group-by-work-on-sqlite-and-mariadb-and-fail-on-postgresql-and-mysql/</guid>
      <description>&lt;p&gt;&lt;code&gt;SELECT customer_id, name, SUM(total) FROM orders GROUP BY customer_id&lt;/code&gt; is the kind of query that runs for years on SQLite or MariaDB. Point the same code at PostgreSQL or MySQL and it stops with an error, because name is neither grouped nor summed.&lt;/p&gt;&#xA;&lt;p&gt;SELECT a, b FROM t GROUP BY a asks for one b per group without saying which. SQLite and MariaDB pick one (MariaDB’s default mode leaves out ONLY_FULL_GROUP_BY). PostgreSQL and MySQL stop with an error, unless the grouped column is the table’s primary key, which fixes every other column of that table.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Comparing a Boolean With 1 Works on MySQL and SQLite and Fails on PostgreSQL</title>
      <link>https://baresql.com/comparing-a-boolean-with-1-works-on-mysql-and-sqlite-and-fails-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/comparing-a-boolean-with-1-works-on-mysql-and-sqlite-and-fails-on-postgresql/</guid>
      <description>&lt;p&gt;&lt;code&gt;WHERE active = 1&lt;/code&gt; is the usual way to test a flag on MySQL, and SQLite and MariaDB read it the same way. Moved to PostgreSQL, the query stops with an error.&lt;/p&gt;&#xA;&lt;p&gt;On SQLite, MySQL and MariaDB a boolean is the number 0 or 1, and TRUE is another way to write 1. PostgreSQL has a real boolean type with no automatic conversion from integers, so code written for MySQL that compares flags with 1 stops there.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Comparing a Text Column With the Number 0 Matches Codes Like abc on MySQL and Fails on PostgreSQL</title>
      <link>https://baresql.com/comparing-a-text-column-with-the-number-0-matches-codes-like-abc-on-mysql-and-fails-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/comparing-a-text-column-with-the-number-0-matches-codes-like-abc-on-mysql-and-fails-on-postgresql/</guid>
      <description>&lt;p&gt;Product codes are text, and a query that forgets the quotes, &lt;code&gt;WHERE code = 0&lt;/code&gt;, still runs on MySQL and MariaDB. There it returns codes that have nothing to do with 0.&lt;/p&gt;&#xA;&lt;p&gt;MySQL and MariaDB turn the text into a number, and text that does not start with digits becomes 0, so WHERE code = 0 finds every code like &#39;abc&#39;. SQLite compares the number as text and finds nothing. PostgreSQL refuses to compare character varying with integer. &#39;1&#39; = 1 trips over the same thing in another way: false on SQLite, true on the other three.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CONCAT With a NULL Argument Returns NULL on MySQL and Skips It on PostgreSQL</title>
      <link>https://baresql.com/concat-with-a-null-argument-returns-null-on-mysql-and-skips-it-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/concat-with-a-null-argument-returns-null-on-mysql-and-skips-it-on-postgresql/</guid>
      <description>&lt;p&gt;A customer list built with &lt;code&gt;CONCAT(first_name, &#39; &#39;, last_name)&lt;/code&gt; looks complete on PostgreSQL and SQLite. Moved to MySQL or MariaDB, the same query returns NULL for some customers.&lt;/p&gt;&#xA;&lt;p&gt;A person without a last name comes out as &#39;Ann &#39; on SQLite and PostgreSQL and as NULL on MySQL and MariaDB, so a list of names quietly loses entries there. CONCAT_WS skips NULL arguments on all four engines.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-concat-null.png&#34; alt=&#34;SELECT CONCAT(first_name, &#39; &#39;, last_name) FROM people, run on four engines: SQLite 3.45.1 &#39;Ann &#39;; PostgreSQL 16.15 &#39;Ann &#39;; MySQL 8.0.46 NULL; MariaDB 10.11.14 NULL.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>COUNT DISTINCT With Two Columns Works on MySQL and Fails on PostgreSQL and SQLite</title>
      <link>https://baresql.com/count-distinct-with-two-columns-works-on-mysql-and-fails-on-postgresql-and-sqlite/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/count-distinct-with-two-columns-works-on-mysql-and-fails-on-postgresql-and-sqlite/</guid>
      <description>&lt;p&gt;&lt;code&gt;COUNT(DISTINCT customer_id, product_id)&lt;/code&gt; counts the distinct pairs on MySQL and MariaDB. SQLite and PostgreSQL take a single expression in &lt;code&gt;COUNT(DISTINCT ...)&lt;/code&gt; and refuse it.&lt;/p&gt;&#xA;&lt;p&gt;SQLite reports the wrong number of arguments and PostgreSQL a missing function.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-count-distinct-columns.png&#34; alt=&#34;SELECT COUNT(DISTINCT a, b) FROM t, run on four engines: SQLite 3.45.1 error: wrong number of arguments to function COUNT(); PostgreSQL 16.15 error: function count(integer, integer) does not exist; MySQL 8.0.46 2; MariaDB 10.11.14 2.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>DISTINCT ON Works on PostgreSQL Only</title>
      <link>https://baresql.com/distinct-on-works-on-postgresql-only/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/distinct-on-works-on-postgresql-only/</guid>
      <description>&lt;p&gt;&lt;code&gt;DISTINCT ON (customer_id)&lt;/code&gt; is a neat way to keep each customer’s latest order on PostgreSQL, and none of the other three engines has it.&lt;/p&gt;&#xA;&lt;p&gt;SQLite, MySQL and MariaDB report a syntax error. Window functions say the same thing on all four (SQLite 3.25, MySQL 8.0 and MariaDB 10.2 and later).&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-distinct-on.png&#34; alt=&#34;SELECT DISTINCT ON (a) a, b FROM t ORDER BY a, b, run on four engines: SQLite 3.45.1 error: near &amp;quot;ON&amp;quot;: syntax error; PostgreSQL 16.15 1, 3; 2, 4; MySQL 8.0.46 error: You have an error in your SQL syntax ... near &#39;ON (a) a, b FROM t ORDER BY a, b&#39; at line 1; MariaDB 10.11.14 error: You have an error in your SQL syntax ... near &#39;ON (a) a, b FROM t ORDER BY a, b&#39; at line 1.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Dividing Decimals Gives Six Decimal Places on MySQL and Sixteen on PostgreSQL</title>
      <link>https://baresql.com/dividing-decimals-gives-six-decimal-places-on-mysql-and-sixteen-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/dividing-decimals-gives-six-decimal-places-on-mysql-and-sixteen-on-postgresql/</guid>
      <description>&lt;p&gt;Split an invoice of 80.50 three ways and MySQL and MariaDB hand back 26.833333, PostgreSQL 26.8333333333333333 and SQLite a floating point number. Most of the time nobody notices. Then a report that adds the shares back up gets a different total on MySQL than on PostgreSQL.&lt;/p&gt;&#xA;&lt;p&gt;MySQL and MariaDB give the result of a decimal division four more decimal places than the dividend has (the div_precision_increment setting) and cut it there. PostgreSQL keeps at least 16 significant digits, and SQLite divides as floating point numbers. Shares of an amount and averages of a DECIMAL column then differ in their last digits.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Division by Zero Is NULL on SQLite and MySQL and an Error on PostgreSQL</title>
      <link>https://baresql.com/division-by-zero-is-null-on-sqlite-and-mysql-and-an-error-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/division-by-zero-is-null-on-sqlite-and-mysql-and-an-error-on-postgresql/</guid>
      <description>&lt;p&gt;A report that divides revenue by visits fails on PostgreSQL the first time a page has no visits. On SQLite, MySQL and MariaDB the same row quietly shows NULL.&lt;/p&gt;&#xA;&lt;p&gt;PostgreSQL stops the whole statement. SQLite, MySQL and MariaDB answer NULL, MySQL and MariaDB with a warning, and in INSERT and UPDATE with an error when the strict mode includes ERROR_FOR_DIVISION_BY_ZERO (the default). The remainder operator % behaves the same way.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Double Dash Comments Need a Space After Them on MySQL and MariaDB</title>
      <link>https://baresql.com/double-dash-comments-need-a-space-after-them-on-mysql-and-mariadb/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/double-dash-comments-need-a-space-after-them-on-mysql-and-mariadb/</guid>
      <description>&lt;p&gt;In a line like &lt;code&gt;SELECT price --discount&lt;/code&gt;, left over from debugging, SQLite and PostgreSQL read &lt;code&gt;--discount&lt;/code&gt; as a comment. MySQL and MariaDB add the discount to the price instead.&lt;/p&gt;&#xA;&lt;p&gt;SQLite and PostgreSQL treat every -- as the start of a comment. MySQL and MariaDB need a space, a tab or a line break after the dashes; otherwise they are two minus signs.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-dash-comment.png&#34; alt=&#34;SELECT 1 --1, run on four engines: SQLite 3.45.1 1; PostgreSQL 16.15 1; MySQL 8.0.46 2; MariaDB 10.11.14 2.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Double Quotes Name a Column on PostgreSQL and Make a String on MySQL</title>
      <link>https://baresql.com/double-quotes-name-a-column-on-postgresql-and-make-a-string-on-mysql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/double-quotes-name-a-column-on-postgresql-and-make-a-string-on-mysql/</guid>
      <description>&lt;p&gt;A query copied from PostgreSQL that puts a column name in double quotes runs on MySQL without an error, and never reads the column.&lt;/p&gt;&#xA;&lt;p&gt;Standard SQL quotes names with double quotes, and SQLite and PostgreSQL follow it. MySQL and MariaDB read &amp;quot;...&amp;quot; like &#39;...&#39; unless the ANSI_QUOTES mode is on: the query still runs and returns the same text on every row. SQLite also turns a double-quoted word into a string when no column has that name.&lt;/p&gt;</description>
    </item>
    <item>
      <title>FETCH FIRST ROWS ONLY Works on PostgreSQL and MariaDB and Fails on MySQL and SQLite</title>
      <link>https://baresql.com/fetch-first-rows-only-works-on-postgresql-and-mariadb-and-fails-on-mysql-and-sqlite/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/fetch-first-rows-only-works-on-postgresql-and-mariadb-and-fails-on-mysql-and-sqlite/</guid>
      <description>&lt;p&gt;&lt;code&gt;FETCH FIRST 10 ROWS ONLY&lt;/code&gt; is the standard way to ask for the top ten, and PostgreSQL and MariaDB accept it. SQLite and MySQL refuse the query.&lt;/p&gt;&#xA;&lt;p&gt;MariaDB added FETCH FIRST in version 10.6. SQLite and MySQL know only LIMIT, and they refuse OFFSET n ROWS for the same reason.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-fetch-first.png&#34; alt=&#34;SELECT x FROM t ORDER BY x FETCH FIRST 2 ROWS ONLY, run on four engines: SQLite 3.45.1 error: near &amp;quot;FETCH&amp;quot;: syntax error; PostgreSQL 16.15 1; 2; MySQL 8.0.46 error: You have an error in your SQL syntax ... near &#39;FETCH FIRST 2 ROWS ONLY&#39; at line 1; MariaDB 10.11.14 1; 2.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>FULL OUTER JOIN Works on PostgreSQL and SQLite and Fails on MySQL and MariaDB</title>
      <link>https://baresql.com/full-outer-join-works-on-postgresql-and-sqlite-and-fails-on-mysql-and-mariadb/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/full-outer-join-works-on-postgresql-and-sqlite-and-fails-on-mysql-and-mariadb/</guid>
      <description>&lt;p&gt;Matching two lists, such as invoices and payments, to see what is missing on either side calls for a FULL OUTER JOIN. PostgreSQL and SQLite run it, and MySQL and MariaDB refuse it.&lt;/p&gt;&#xA;&lt;p&gt;MySQL and MariaDB have LEFT and RIGHT joins only. SQLite added RIGHT and FULL joins in version 3.39.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-full-outer-join.png&#34; alt=&#34;SELECT a.x, b.x FROM a FULL OUTER JOIN b ON a.x = b.x, run on four engines: SQLite 3.45.1 1, NULL; 2, 2; NULL, 3; PostgreSQL 16.15 1, NULL; 2, 2; NULL, 3; MySQL 8.0.46 error: You have an error in your SQL syntax ... near &#39;OUTER JOIN b ON a.x = b.x&#39; at line 1; MariaDB 10.11.14 error: You have an error in your SQL syntax ... near &#39;OUTER JOIN b ON a.x = b.x&#39; at line 1.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>GREATEST Skips NULL on PostgreSQL and Returns NULL on MySQL</title>
      <link>https://baresql.com/greatest-skips-null-on-postgresql-and-returns-null-on-mysql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/greatest-skips-null-on-postgresql-and-returns-null-on-mysql/</guid>
      <description>&lt;p&gt;&lt;code&gt;GREATEST(sale_price, list_price)&lt;/code&gt; picks the larger of two prices. When one of them is NULL, PostgreSQL still picks the other price, and no other engine does.&lt;/p&gt;&#xA;&lt;p&gt;GREATEST(1, NULL) is 1 on PostgreSQL and NULL on MySQL and MariaDB. SQLite has the same idea under the names MAX(a, b) and MIN(a, b) with two or more arguments; they return NULL when any argument is NULL, and the other engines read MAX and MIN as aggregates.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hash Comments Work on MySQL and MariaDB and Become an Operator on PostgreSQL</title>
      <link>https://baresql.com/hash-comments-work-on-mysql-and-mariadb-and-become-an-operator-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/hash-comments-work-on-mysql-and-mariadb-and-become-an-operator-on-postgresql/</guid>
      <description>&lt;p&gt;MySQL and MariaDB skip everything from a &lt;code&gt;#&lt;/code&gt; to the end of the line. On SQLite and PostgreSQL that &lt;code&gt;#&lt;/code&gt; is still part of the statement.&lt;/p&gt;&#xA;&lt;p&gt;Scripts written for the mysql client often use # comments. SQLite stops with a syntax error. On PostgreSQL # is a bitwise exclusive or, so the rest of the line becomes part of the expression.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-hash-comment.png&#34; alt=&#34;SELECT 1 # one, run on four engines: SQLite 3.45.1 error: unrecognized token: &amp;quot;#&amp;quot;; PostgreSQL 16.15 error: column &amp;quot;one&amp;quot; does not exist; MySQL 8.0.46 1; MariaDB 10.11.14 1.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>INSERT IGNORE Becomes INSERT OR IGNORE on SQLite and ON CONFLICT DO NOTHING on PostgreSQL</title>
      <link>https://baresql.com/insert-ignore-becomes-insert-or-ignore-on-sqlite-and-on-conflict-do-nothing-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/insert-ignore-becomes-insert-or-ignore-on-sqlite-and-on-conflict-do-nothing-on-postgresql/</guid>
      <description>&lt;p&gt;Loading a file of events that may hold rows you already have calls for an insert that skips duplicates. MySQL and MariaDB spell it &lt;code&gt;INSERT IGNORE&lt;/code&gt; and SQLite &lt;code&gt;INSERT OR IGNORE&lt;/code&gt;, while PostgreSQL and SQLite take &lt;code&gt;ON CONFLICT DO NOTHING&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Each form skips rows that would break a unique key, and each fails on the engines that use another one. INSERT IGNORE also hides other errors on MySQL and MariaDB, such as values that do not fit the column.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Integer Division Drops the Fraction on SQLite and PostgreSQL and Keeps It on MySQL</title>
      <link>https://baresql.com/integer-division-drops-the-fraction-on-sqlite-and-postgresql-and-keeps-it-on-mysql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/integer-division-drops-the-fraction-on-sqlite-and-postgresql-and-keeps-it-on-mysql/</guid>
      <description>&lt;p&gt;You write an average as &lt;code&gt;SUM(stock) / COUNT(*)&lt;/code&gt;, try it on SQLite and get 3. MySQL gives 3.3333 for the same rows. Both are doing what they were built to do, and they disagree about what dividing two integers means.&lt;/p&gt;&#xA;&lt;p&gt;SQLite and PostgreSQL give an integer result when both sides of / are integers, so 7 / 2 is 3. MySQL and MariaDB always divide as decimals and answer 3.5000. Averages written as SUM(x) / COUNT(*) are where this usually bites: the sum of an integer column is an integer on SQLite and PostgreSQL, so the average loses its fraction there.&lt;/p&gt;</description>
    </item>
    <item>
      <title>LENGTH Counts Bytes on MySQL and MariaDB and Characters on PostgreSQL and SQLite</title>
      <link>https://baresql.com/length-counts-bytes-on-mysql-and-mariadb-and-characters-on-postgresql-and-sqlite/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/length-counts-bytes-on-mysql-and-mariadb-and-characters-on-postgresql-and-sqlite/</guid>
      <description>&lt;p&gt;A check that a name is at most 20 characters long, written with &lt;code&gt;LENGTH(name)&lt;/code&gt;, lets 20 letters through on SQLite and PostgreSQL. MySQL and MariaDB count bytes instead, so a name with accents reaches the limit sooner.&lt;/p&gt;&#xA;&lt;p&gt;In UTF-8 a letter outside A to Z takes two to four bytes. MySQL and MariaDB count characters with CHAR_LENGTH, which SQLite lacks. Length checks and cut-offs drift apart on names and addresses with accents.&lt;/p&gt;</description>
    </item>
    <item>
      <title>LIKE Ignores Letter Case on SQLite and MySQL and Respects It on PostgreSQL</title>
      <link>https://baresql.com/like-ignores-letter-case-on-sqlite-and-mysql-and-respects-it-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/like-ignores-letter-case-on-sqlite-and-mysql-and-respects-it-on-postgresql/</guid>
      <description>&lt;p&gt;A search box that runs &lt;code&gt;WHERE name LIKE &#39;ann%&#39;&lt;/code&gt; finds Ann on SQLite, MySQL and MariaDB. On PostgreSQL it misses her, because LIKE there compares letters exactly.&lt;/p&gt;&#xA;&lt;p&gt;SQLite’s LIKE ignores case for the letters A to Z only. MySQL and MariaDB follow the collation, which ignores case by default. PostgreSQL’s LIKE is exact; its ILIKE ignores case, and exists on PostgreSQL only.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-like-case.png&#34; alt=&#34;SELECT &#39;abc&#39; LIKE &#39;ABC&#39;, run on four engines: SQLite 3.45.1 1; PostgreSQL 16.15 false; MySQL 8.0.46 1; MariaDB 10.11.14 1.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>LIMIT With a Comma Works on MySQL and SQLite and Fails on PostgreSQL</title>
      <link>https://baresql.com/limit-with-a-comma-works-on-mysql-and-sqlite-and-fails-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/limit-with-a-comma-works-on-mysql-and-sqlite-and-fails-on-postgresql/</guid>
      <description>&lt;p&gt;Paging code written for MySQL often says &lt;code&gt;LIMIT 20, 10&lt;/code&gt;: skip 20 rows, return 10. SQLite and MariaDB read it the same way. PostgreSQL refuses it.&lt;/p&gt;&#xA;&lt;p&gt;In LIMIT a, b the first number is the offset and the second the count, the reverse of the order in which LIMIT ... OFFSET reads.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-limit-comma.png&#34; alt=&#34;SELECT x FROM t ORDER BY x LIMIT 1, 2, run on four engines: SQLite 3.45.1 2; 3; PostgreSQL 16.15 error: LIMIT #,# syntax is not supported; MySQL 8.0.46 2; 3; MariaDB 10.11.14 2; 3.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>LOG With One Argument Is Base 10 on PostgreSQL and the Natural Logarithm on MySQL</title>
      <link>https://baresql.com/log-with-one-argument-is-base-10-on-postgresql-and-the-natural-logarithm-on-mysql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/log-with-one-argument-is-base-10-on-postgresql-and-the-natural-logarithm-on-mysql/</guid>
      <description>&lt;p&gt;A score or a scale built on &lt;code&gt;LOG()&lt;/code&gt; shifts when the code moves to another engine, because &lt;code&gt;LOG(100)&lt;/code&gt; doesn’t mean the same logarithm everywhere.&lt;/p&gt;&#xA;&lt;p&gt;LOG(100) is 2 on SQLite and PostgreSQL and 4.605 on MySQL and MariaDB. With two arguments, LOG(b, x) is the logarithm of x to base b on all four. SQLite has LOG, LN, LOG10 and POWER only when it is built with its math functions: the sqlite3 program is by default since version 3.35, and some systems ship it without them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL and MariaDB on Linux Treat Table Names as Case Sensitive</title>
      <link>https://baresql.com/mysql-and-mariadb-on-linux-treat-table-names-as-case-sensitive/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/mysql-and-mariadb-on-linux-treat-table-names-as-case-sensitive/</guid>
      <description>&lt;p&gt;Code that creates a table as Users and later reads users works on SQLite and PostgreSQL. On MySQL or MariaDB running on Linux it fails, since users is another table that doesn’t exist, while the same code on a Mac works, which makes the bug easy to miss.&lt;/p&gt;&#xA;&lt;p&gt;MySQL and MariaDB keep each table in files named after it, and file names on Linux are case-sensitive (lower_case_table_names = 0, the default there). On Windows and macOS the default makes names case-insensitive. SQLite and PostgreSQL ignore case in unquoted names.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL and MariaDB Refuse LIMIT Inside an IN Subquery</title>
      <link>https://baresql.com/mysql-and-mariadb-refuse-limit-inside-an-in-subquery/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/mysql-and-mariadb-refuse-limit-inside-an-in-subquery/</guid>
      <description>&lt;p&gt;Finding the customers behind the ten latest orders with &lt;code&gt;WHERE id IN (SELECT customer_id FROM orders ORDER BY created_at DESC LIMIT 10)&lt;/code&gt; works on SQLite and PostgreSQL. MySQL and MariaDB refuse it.&lt;/p&gt;&#xA;&lt;p&gt;Both report that this version doesn’t yet support &#39;LIMIT &amp;amp; IN/ALL/ANY/SOME subquery&#39;. LIMIT is fine in a subquery used as a table and in one that returns a single value.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-limit-in-subquery.png&#34; alt=&#34;SELECT x FROM t WHERE x IN (SELECT x FROM t ORDER BY x LIMIT 1), run on four engines: SQLite 3.45.1 1; PostgreSQL 16.15 1; MySQL 8.0.46 error: This version of MySQL doesn&#39;t yet support &#39;LIMIT &amp;amp; IN/ALL/ANY/SOME subquery&#39;; MariaDB 10.11.14 error: This version of MariaDB doesn&#39;t yet support &#39;LIMIT &amp;amp; IN/ALL/ANY/SOME subquery&#39;.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL Compares Text Without Regard to Letter Case and PostgreSQL Compares It Exactly</title>
      <link>https://baresql.com/mysql-compares-text-without-regard-to-letter-case-and-postgresql-compares-it-exactly/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/mysql-compares-text-without-regard-to-letter-case-and-postgresql-compares-it-exactly/</guid>
      <description>&lt;p&gt;Sign-ups as &lt;code&gt;ann@example.com&lt;/code&gt; and &lt;code&gt;Ann@example.com&lt;/code&gt; are two users on PostgreSQL and SQLite. On MySQL and MariaDB a unique key on the email column refuses the second sign-up.&lt;/p&gt;&#xA;&lt;p&gt;The default collations of MySQL and MariaDB ignore case and accents, so &#39;abc&#39; = &#39;ABC&#39; and &#39;e&#39; = &#39;é&#39; are true there and false on SQLite and PostgreSQL. The same goes for joins, GROUP BY, DISTINCT and unique keys: two values that differ only in case count as one on MySQL and as two elsewhere. Whether an answer changes depends on the data, so lint reports this as information.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL Refuses a Key on a TEXT Column Without a Prefix Length</title>
      <link>https://baresql.com/mysql-refuses-a-key-on-a-text-column-without-a-prefix-length/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/mysql-refuses-a-key-on-a-text-column-without-a-prefix-length/</guid>
      <description>&lt;p&gt;A TEXT column as a primary key is ordinary on SQLite and PostgreSQL. MySQL and MariaDB refuse it, and MySQL refuses a plain index or unique key on TEXT as well.&lt;/p&gt;&#xA;&lt;p&gt;SQLite and PostgreSQL index TEXT columns as they are. MySQL wants a prefix length, INDEX (x(100)), which the others reject. MariaDB 10.4 and later accept plain indexes and unique keys on TEXT columns.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-index-on-text.png&#34; alt=&#34;CREATE TABLE t (x TEXT PRIMARY KEY); SELECT COUNT(*) FROM t, run on four engines: SQLite 3.45.1 0; PostgreSQL 16.15 0; MySQL 8.0.46 error: BLOB/TEXT column &#39;x&#39; used in key specification without a key length; MariaDB 10.11.14 error: BLOB/TEXT column &#39;x&#39; used in key specification without a key length.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL Refuses a Plain DEFAULT Value on TEXT Columns</title>
      <link>https://baresql.com/mysql-refuses-a-plain-default-value-on-text-columns/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/mysql-refuses-a-plain-default-value-on-text-columns/</guid>
      <description>&lt;p&gt;A notes column declared as &lt;code&gt;TEXT DEFAULT &#39;&#39;&lt;/code&gt; works on SQLite, PostgreSQL and MariaDB. MySQL refuses the CREATE TABLE.&lt;/p&gt;&#xA;&lt;p&gt;MySQL 8.0.13 and later accept a default written as an expression in parentheses, DEFAULT (&#39;a&#39;), which the other three engines accept as well.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-text-default.png&#34; alt=&#34;CREATE TABLE t (id INTEGER, x TEXT DEFAULT &#39;a&#39;); INSERT INTO t (id) VALUES (1); SELECT x FROM t, run on four engines: SQLite 3.45.1 &#39;a&#39;; PostgreSQL 16.15 &#39;a&#39;; MySQL 8.0.46 error: BLOB, TEXT, GEOMETRY or JSON column &#39;x&#39; can&#39;t have a default value; MariaDB 10.11.14 &#39;a&#39;.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL Refuses an UPDATE Whose Subquery Reads the Same Table</title>
      <link>https://baresql.com/mysql-refuses-an-update-whose-subquery-reads-the-same-table/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/mysql-refuses-an-update-whose-subquery-reads-the-same-table/</guid>
      <description>&lt;p&gt;Marking rows with &lt;code&gt;UPDATE t SET flag = 1 WHERE id IN (SELECT id FROM t WHERE ...)&lt;/code&gt; works on SQLite, PostgreSQL and MariaDB. MySQL refuses an UPDATE or DELETE whose subquery reads the table being changed.&lt;/p&gt;&#xA;&lt;p&gt;MySQL says you can’t specify target table &#39;t&#39; for update in FROM clause. MariaDB lifted the limit in version 10.3.2. A subquery used as a table works on MySQL too, because MySQL then computes its rows before it changes anything.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL Refuses CREATE INDEX IF NOT EXISTS</title>
      <link>https://baresql.com/mysql-refuses-create-index-if-not-exists/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/mysql-refuses-create-index-if-not-exists/</guid>
      <description>&lt;p&gt;Migrations that may run twice often say &lt;code&gt;CREATE INDEX IF NOT EXISTS&lt;/code&gt;, and SQLite, PostgreSQL and MariaDB accept it. MySQL stops the migration with a syntax error.&lt;/p&gt;&#xA;&lt;p&gt;MySQL accepts IF NOT EXISTS for tables and databases, and not for indexes.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-index-if-not-exists.png&#34; alt=&#34;CREATE TABLE t (x INTEGER); CREATE INDEX IF NOT EXISTS t_x ON t (x); SELECT COUNT(*) FROM t, run on four engines: SQLite 3.45.1 0; PostgreSQL 16.15 0; MySQL 8.0.46 error: You have an error in your SQL syntax ... near &#39;IF NOT EXISTS t_x ON t (x)&#39; at line 1; MariaDB 10.11.14 0.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL Refuses INSERT RETURNING While PostgreSQL and SQLite Accept It</title>
      <link>https://baresql.com/mysql-refuses-insert-returning-while-postgresql-and-sqlite-accept-it/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/mysql-refuses-insert-returning-while-postgresql-and-sqlite-accept-it/</guid>
      <description>&lt;p&gt;&lt;code&gt;INSERT ... RETURNING id&lt;/code&gt; hands back the new row’s id in the same round trip on SQLite, PostgreSQL and MariaDB. MySQL has no RETURNING and refuses the statement.&lt;/p&gt;&#xA;&lt;p&gt;SQLite added RETURNING in version 3.35, and MariaDB in 10.5 for INSERT and DELETE (MariaDB refuses it on UPDATE). Each engine also has its own function for the last generated id: LAST_INSERT_ID() on MySQL and MariaDB, last_insert_rowid() on SQLite and lastval() on PostgreSQL.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL Table Options Like ENGINE and CHARSET Fail on PostgreSQL and SQLite</title>
      <link>https://baresql.com/mysql-table-options-like-engine-and-charset-fail-on-postgresql-and-sqlite/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/mysql-table-options-like-engine-and-charset-fail-on-postgresql-and-sqlite/</guid>
      <description>&lt;p&gt;A MySQL schema ends its CREATE TABLE statements with options such as &lt;code&gt;ENGINE=InnoDB DEFAULT CHARSET=utf8mb4&lt;/code&gt;. SQLite and PostgreSQL refuse the statement at the first option.&lt;/p&gt;&#xA;&lt;p&gt;Dumps made with mysqldump carry these options on every table. SQLite’s own options, WITHOUT ROWID and STRICT, fail on the other three engines in the same way.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-table-options.png&#34; alt=&#34;CREATE TABLE t (x INTEGER) ENGINE=InnoDB; SELECT COUNT(*) FROM t, run on four engines: SQLite 3.45.1 error: near &amp;quot;=&amp;quot;: syntax error; PostgreSQL 16.15 error: syntax error at or near &amp;quot;ENGINE&amp;quot;; MySQL 8.0.46 0; MariaDB 10.11.14 0.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>No Auto Increment Column Syntax Works on Every SQL Engine</title>
      <link>https://baresql.com/no-auto-increment-column-syntax-works-on-every-sql-engine/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/no-auto-increment-column-syntax-works-on-every-sql-engine/</guid>
      <description>&lt;p&gt;A schema meant for several engines needs ids that number themselves, and no single way of asking for that works on all four. SERIAL comes closest, and on SQLite it fails without a word.&lt;/p&gt;&#xA;&lt;p&gt;AUTO_INCREMENT belongs to MySQL and MariaDB, AUTOINCREMENT to SQLite, and GENERATED BY DEFAULT AS IDENTITY to PostgreSQL. SERIAL is PostgreSQL’s as well, and MySQL and MariaDB accept it as BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE. SQLite accepts any type name, so SERIAL is only a name there and the column stays NULL: SQLite numbers rows for a column declared INTEGER PRIMARY KEY and nothing else.&lt;/p&gt;</description>
    </item>
    <item>
      <title>NULL Sorts First on SQLite and MySQL and Last on PostgreSQL</title>
      <link>https://baresql.com/null-sorts-first-on-sqlite-and-mysql-and-last-on-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/null-sorts-first-on-sqlite-and-mysql-and-last-on-postgresql/</guid>
      <description>&lt;p&gt;Sort customers by the date of their last order and the ones who never ordered come first on SQLite, MySQL and MariaDB and last on PostgreSQL. The first page of the same report shows different people.&lt;/p&gt;&#xA;&lt;p&gt;The standard leaves the place of NULL in ORDER BY to the engine. PostgreSQL treats NULL as larger than every value, the others as smaller, and descending order turns both around. Paged results change when the column holds NULL, and so do window functions such as ROW_NUMBER() OVER (ORDER BY x).&lt;/p&gt;</description>
    </item>
    <item>
      <title>NULLS FIRST and NULLS LAST Fail on MySQL and MariaDB</title>
      <link>https://baresql.com/nulls-first-and-nulls-last-fail-on-mysql-and-mariadb/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/nulls-first-and-nulls-last-fail-on-mysql-and-mariadb/</guid>
      <description>&lt;p&gt;&lt;code&gt;ORDER BY shipped_at NULLS LAST&lt;/code&gt; is the tidy way to put unshipped orders at the end on PostgreSQL and SQLite. MySQL and MariaDB have no such syntax and refuse the query.&lt;/p&gt;&#xA;&lt;p&gt;SQLite added them in version 3.30. MySQL and MariaDB have no syntax for choosing where NULL sorts.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-nulls-first-last.png&#34; alt=&#34;SELECT x FROM t ORDER BY x NULLS LAST, run on four engines: SQLite 3.45.1 1; 2; NULL; PostgreSQL 16.15 1; 2; NULL; MySQL 8.0.46 error: You have an error in your SQL syntax ... near &#39;NULLS LAST&#39; at line 1; MariaDB 10.11.14 error: You have an error in your SQL syntax ... near &#39;NULLS LAST&#39; at line 1.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Only SQLite Lets WHERE Use a Name From the Select List</title>
      <link>https://baresql.com/only-sqlite-lets-where-use-a-name-from-the-select-list/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/only-sqlite-lets-where-use-a-name-from-the-select-list/</guid>
      <description>&lt;p&gt;A query that names &lt;code&gt;price * quantity&lt;/code&gt; as total in the select list and then filters on total in WHERE runs on SQLite. PostgreSQL, MySQL and MariaDB refuse it, since the table has no column named total.&lt;/p&gt;&#xA;&lt;p&gt;WHERE is worked out before the select list, so in standard SQL the y of SELECT x * 2 AS y does not exist yet. SQLite looks it up anyway.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-alias-in-where.png&#34; alt=&#34;SELECT x * 2 AS y FROM t WHERE y &amp;gt; 2, run on four engines: SQLite 3.45.1 4; PostgreSQL 16.15 error: column &amp;quot;y&amp;quot; does not exist; MySQL 8.0.46 error: Unknown column &#39;y&#39; in &#39;where clause&#39;; MariaDB 10.11.14 error: Unknown column &#39;y&#39; in &#39;WHERE&#39;.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>PostgreSQL Refuses Select List Names in HAVING</title>
      <link>https://baresql.com/postgresql-refuses-select-list-names-in-having/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/postgresql-refuses-select-list-names-in-having/</guid>
      <description>&lt;p&gt;A report of repeat customers names its count of orders n in the select list and filters on that name in HAVING. SQLite, MySQL and MariaDB run it, and PostgreSQL refuses the query.&lt;/p&gt;&#xA;&lt;p&gt;PostgreSQL looks up names in HAVING among the table’s columns only, so HAVING n &amp;gt; 1 fails when n is the name of COUNT(*).&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-alias-in-having.png&#34; alt=&#34;SELECT a, COUNT(*) AS n FROM t GROUP BY a HAVING n &amp;gt; 1, run on four engines: SQLite 3.45.1 1, 2; PostgreSQL 16.15 error: column &amp;quot;n&amp;quot; does not exist; MySQL 8.0.46 1, 2; MariaDB 10.11.14 1, 2.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>PostgreSQL Returns Column Names in Lower Case Unless You Quote Them</title>
      <link>https://baresql.com/postgresql-returns-column-names-in-lower-case-unless-you-quote-them/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/postgresql-returns-column-names-in-lower-case-unless-you-quote-them/</guid>
      <description>&lt;p&gt;&lt;code&gt;SELECT SUM(amount) AS Total&lt;/code&gt; gives a column named Total on SQLite, MySQL and MariaDB. PostgreSQL calls it total.&lt;/p&gt;&#xA;&lt;p&gt;SQLite, MySQL and MariaDB return names as written. PostgreSQL folds unquoted names to lower case, in aliases and in CREATE TABLE alike, so code that reads columns by name (row[&amp;quot;Total&amp;quot;]) finds nothing on PostgreSQL.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-column-name-case.png&#34; alt=&#34;SELECT 1 AS Total, run on four engines: SQLite 3.45.1 columns Total: 1; PostgreSQL 16.15 columns total: 1; MySQL 8.0.46 columns Total: 1; MariaDB 10.11.14 columns Total: 1.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>REAL on PostgreSQL and FLOAT on MySQL Are 4-Byte Floats That Drop Digits</title>
      <link>https://baresql.com/real-on-postgresql-and-float-on-mysql-are-4-byte-floats-that-drop-digits/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/real-on-postgresql-and-float-on-mysql-are-4-byte-floats-that-drop-digits/</guid>
      <description>&lt;p&gt;Measurements kept in a REAL column on PostgreSQL, or in a FLOAT column on MySQL or MariaDB, come back with fewer digits than went in. The same type names keep them all on the other engines.&lt;/p&gt;&#xA;&lt;p&gt;PostgreSQL’s REAL is a 4-byte float, and so is FLOAT on MySQL and MariaDB, while the other engines store 8 bytes for the same name. 1.23456789 comes back as 1.2345679 or 1.23457.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-float-precision.png&#34; alt=&#34;CREATE TABLE t (r REAL, f FLOAT); INSERT INTO t VALUES (1.23456789, 1.23456789); SELECT r, f FROM t, run on four engines: SQLite 3.45.1 1.23456789, 1.23456789; PostgreSQL 16.15 1.2345679, 1.23456789; MySQL 8.0.46 1.23456789, 1.23457; MariaDB 10.11.14 1.23456789, 1.23457.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQL Functions That Exist on Some Engines Only and What to Write Instead</title>
      <link>https://baresql.com/sql-functions-that-exist-on-some-engines-only-and-what-to-write-instead/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/sql-functions-that-exist-on-some-engines-only-and-what-to-write-instead/</guid>
      <description>&lt;p&gt;IFNULL, NOW, LEFT and STRING_AGG are everyday functions, and each one is missing on at least one of SQLite, PostgreSQL, MySQL and MariaDB. BareSQL Portable knows 78 functions like these.&lt;/p&gt;&#xA;&lt;p&gt;Each function in the table was called on all four engines, and the table shows where the call ran and what to write instead.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-function-not-everywhere.png&#34; alt=&#34;SELECT IFNULL(NULL, &#39;x&#39;), run on four engines: SQLite 3.45.1 &#39;x&#39;; PostgreSQL 16.15 error: function ifnull(unknown, unknown) does not exist; MySQL 8.0.46 &#39;x&#39;; MariaDB 10.11.14 &#39;x&#39;.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQL Operators That Exist on Some Engines Only and What to Write Instead</title>
      <link>https://baresql.com/sql-operators-that-exist-on-some-engines-only-and-what-to-write-instead/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/sql-operators-that-exist-on-some-engines-only-and-what-to-write-instead/</guid>
      <description>&lt;p&gt;Operators such as &lt;code&gt;::&lt;/code&gt;, &lt;code&gt;ILIKE&lt;/code&gt;, &lt;code&gt;DIV&lt;/code&gt; and &lt;code&gt;XOR&lt;/code&gt; belong to one or two engines, and the others refuse them. BareSQL Portable knows 16 operators like these.&lt;/p&gt;&#xA;&lt;p&gt;Each operator in the table was used on all four engines, and the table shows where it ran and what to write instead.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-operator-not-everywhere.png&#34; alt=&#34;SELECT &#39;abc&#39; ILIKE &#39;ABC&#39;, run on four engines: SQLite 3.45.1 error: near &amp;quot;&#39;ABC&#39;&amp;quot;: syntax error; PostgreSQL 16.15 true; MySQL 8.0.46 error: You have an error in your SQL syntax ... near &#39;&#39;ABC&#39;&#39; at line 1; MariaDB 10.11.14 error: You have an error in your SQL syntax ... near &#39;&#39;ABC&#39;&#39; at line 1.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQLite Has No CREATE OR REPLACE VIEW</title>
      <link>https://baresql.com/sqlite-has-no-create-or-replace-view/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/sqlite-has-no-create-or-replace-view/</guid>
      <description>&lt;p&gt;&lt;code&gt;CREATE OR REPLACE VIEW&lt;/code&gt; lets a migration change a view in one step on PostgreSQL, MySQL and MariaDB. On SQLite the statement is a syntax error.&lt;/p&gt;&#xA;&lt;p&gt;SQLite can only drop a view and create it again.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-create-or-replace.png&#34; alt=&#34;CREATE OR REPLACE VIEW v AS SELECT x FROM t; SELECT COUNT(*) FROM v, run on four engines: SQLite 3.45.1 error: near &amp;quot;OR&amp;quot;: syntax error; PostgreSQL 16.15 0; MySQL 8.0.46 0; MariaDB 10.11.14 0.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQLite Has No TRUNCATE Statement</title>
      <link>https://baresql.com/sqlite-has-no-truncate-statement/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/sqlite-has-no-truncate-statement/</guid>
      <description>&lt;p&gt;Test setups often empty their tables with &lt;code&gt;TRUNCATE TABLE&lt;/code&gt; between runs. PostgreSQL, MySQL and MariaDB have it, and SQLite refuses it.&lt;/p&gt;&#xA;&lt;p&gt;SQLite empties a table quickly with a DELETE FROM t that has no WHERE clause. On MySQL and MariaDB, TRUNCATE also resets the AUTO_INCREMENT counter, which DELETE leaves alone.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-truncate.png&#34; alt=&#34;TRUNCATE TABLE t; SELECT COUNT(*) FROM t, run on four engines: SQLite 3.45.1 error: near &amp;quot;TRUNCATE&amp;quot;: syntax error; PostgreSQL 16.15 0; MySQL 8.0.46 0; MariaDB 10.11.14 0.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQLite Keeps DECIMAL Values as Floats and Sums of Prices Pick Up Rounding Errors</title>
      <link>https://baresql.com/sqlite-keeps-decimal-values-as-floats-and-sums-of-prices-pick-up-rounding-errors/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/sqlite-keeps-decimal-values-as-floats-and-sums-of-prices-pick-up-rounding-errors/</guid>
      <description>&lt;p&gt;A shop keeps its prices in a &lt;code&gt;DECIMAL(10, 2)&lt;/code&gt; column and checks that an order’s lines add up to its total. On SQLite that check can fail for an order of 0.10 and 0.20.&lt;/p&gt;&#xA;&lt;p&gt;PostgreSQL, MySQL and MariaDB keep DECIMAL values exact, so the sum of 0.1 and 0.2 equals 0.3 there. SQLite has no exact decimal type: it stores 0.1 as the nearest binary fraction, the sum is 0.30000000000000004, and the comparison is false.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQLite LOWER and UPPER Change Only the Letters A to Z</title>
      <link>https://baresql.com/sqlite-lower-and-upper-change-only-the-letters-a-to-z/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/sqlite-lower-and-upper-change-only-the-letters-a-to-z/</guid>
      <description>&lt;p&gt;Searching names with &lt;code&gt;LOWER(name) = LOWER(&#39;Émile&#39;)&lt;/code&gt; works on PostgreSQL, MySQL and MariaDB. On SQLite, LOWER changes only A to Z, so É stays É and a stored émile never matches.&lt;/p&gt;&#xA;&lt;p&gt;SQLite folds case for ASCII letters only, and so do its LIKE and COLLATE NOCASE, unless it is built with the ICU extension, as some systems ship it. Comparisons that use LOWER() to ignore case work on the other engines and fail on SQLite for names like Émile or Ødegaard.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQLite Stores Text in INTEGER Columns and Ignores VARCHAR Lengths</title>
      <link>https://baresql.com/sqlite-stores-text-in-integer-columns-and-ignores-varchar-lengths/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/sqlite-stores-text-in-integer-columns-and-ignores-varchar-lengths/</guid>
      <description>&lt;p&gt;A test suite on SQLite passes with a quantity of &lt;code&gt;&#39;abc&#39;&lt;/code&gt;, or &lt;code&gt;&#39;Germany&#39;&lt;/code&gt; in a &lt;code&gt;VARCHAR(2)&lt;/code&gt; country column. PostgreSQL, MySQL and MariaDB refuse both values, so the bug shows up in production instead.&lt;/p&gt;&#xA;&lt;p&gt;Column types on SQLite are preferences: a value that does not fit is stored as it is, and lengths are never checked. Tests that run on SQLite then pass with data the production engine rejects. SQLite’s STRICT tables (version 3.37 and later) check types but not lengths, and the other engines do not accept the STRICT keyword.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SUBSTR From Position 0 Returns Text on SQLite and PostgreSQL and Nothing on MySQL</title>
      <link>https://baresql.com/substr-from-position-0-returns-text-on-sqlite-and-postgresql-and-nothing-on-mysql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/substr-from-position-0-returns-text-on-sqlite-and-postgresql-and-nothing-on-mysql/</guid>
      <description>&lt;p&gt;Code ported from a language that counts from 0 often ends up with &lt;code&gt;SUBSTR(code, 0, 3)&lt;/code&gt;. SQLite and PostgreSQL return the first two characters. MySQL and MariaDB return an empty string.&lt;/p&gt;&#xA;&lt;p&gt;Positions start at 1. SQLite and PostgreSQL count position 0 as part of the requested length, while MySQL and MariaDB return nothing for a start of 0. Negative starts differ as well: SQLite, MySQL and MariaDB count them from the end, and PostgreSQL counts them before the first character.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Caret Operator Is a Power on PostgreSQL and a Bitwise XOR on MySQL</title>
      <link>https://baresql.com/the-caret-operator-is-a-power-on-postgresql-and-a-bitwise-xor-on-mysql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/the-caret-operator-is-a-power-on-postgresql-and-a-bitwise-xor-on-mysql/</guid>
      <description>&lt;p&gt;A growth formula written as &lt;code&gt;rate ^ years&lt;/code&gt; works on PostgreSQL. On MySQL and MariaDB it still runs and gives numbers that have nothing to do with growth: &lt;code&gt;2 ^ 3&lt;/code&gt; is 1 there.&lt;/p&gt;&#xA;&lt;p&gt;PostgreSQL raises the left side to the power of the right one. MySQL and MariaDB combine the bits of both numbers. SQLite has no ^ operator.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-caret-operator.png&#34; alt=&#34;SELECT 2 ^ 3, run on four engines: SQLite 3.45.1 error: unrecognized token: &amp;quot;^&amp;quot;; PostgreSQL 16.15 8; MySQL 8.0.46 1; MariaDB 10.11.14 1.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Double Pipe Operator Joins Text on PostgreSQL and SQLite and Means OR on MySQL</title>
      <link>https://baresql.com/the-double-pipe-operator-joins-text-on-postgresql-and-sqlite-and-means-or-on-mysql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/the-double-pipe-operator-joins-text-on-postgresql-and-sqlite-and-means-or-on-mysql/</guid>
      <description>&lt;p&gt;Code that builds labels with &lt;code&gt;first_name || &#39; &#39; || last_name&lt;/code&gt; works on PostgreSQL and SQLite. Move it to MySQL or MariaDB and every label comes back as 0, with no error to say why.&lt;/p&gt;&#xA;&lt;p&gt;The SQL standard joins strings with ||, and SQLite and PostgreSQL follow it. MySQL and MariaDB read || as a logical OR unless the server runs in the PIPES_AS_CONCAT mode, so both strings are turned into numbers and the answer is 0. The warnings they give for it seldom reach the application.&lt;/p&gt;</description>
    </item>
    <item>
      <title>UPDATE With a Join Needs Different Syntax on MySQL and PostgreSQL</title>
      <link>https://baresql.com/update-with-a-join-needs-different-syntax-on-mysql-and-postgresql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/update-with-a-join-needs-different-syntax-on-mysql-and-postgresql/</guid>
      <description>&lt;p&gt;Copying prices from a staging table with a join takes &lt;code&gt;UPDATE ... FROM&lt;/code&gt; on SQLite and PostgreSQL and &lt;code&gt;UPDATE ... JOIN&lt;/code&gt; on MySQL and MariaDB, and neither runs on all four.&lt;/p&gt;&#xA;&lt;p&gt;The engines use different syntax for changing rows based on another table. DELETE differs the same way: DELETE ... USING on PostgreSQL, DELETE t FROM t JOIN ... on MySQL and MariaDB.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-update-join.png&#34; alt=&#34;UPDATE t SET x = u.x FROM u WHERE u.id = t.id; SELECT x FROM t ORDER BY id, run on four engines: SQLite 3.45.1 7; 0; PostgreSQL 16.15 7; 0; MySQL 8.0.46 error: You have an error in your SQL syntax ... near &#39;FROM u WHERE u.id = t.id&#39; at line 1; MariaDB 10.11.14 error: You have an error in your SQL syntax ... near &#39;FROM u WHERE u.id = t.id&#39; at line 1.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Upsert Needs ON CONFLICT on PostgreSQL and ON DUPLICATE KEY UPDATE on MySQL</title>
      <link>https://baresql.com/upsert-needs-on-conflict-on-postgresql-and-on-duplicate-key-update-on-mysql/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/upsert-needs-on-conflict-on-postgresql-and-on-duplicate-key-update-on-mysql/</guid>
      <description>&lt;p&gt;Saving a setting that may or may not exist yet takes one statement on every engine, though not the same one on all four. SQLite and PostgreSQL use &lt;code&gt;ON CONFLICT ... DO UPDATE&lt;/code&gt;, MySQL and MariaDB &lt;code&gt;ON DUPLICATE KEY UPDATE&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;REPLACE INTO works on SQLite, MySQL and MariaDB, but it deletes the old row and inserts a new one, which fires delete triggers and resets the columns the statement leaves out. Of these four engines, MERGE exists on PostgreSQL 15 and later only.&lt;/p&gt;</description>
    </item>
    <item>
      <title>VARCHAR Without a Length Fails on MySQL and MariaDB</title>
      <link>https://baresql.com/varchar-without-a-length-fails-on-mysql-and-mariadb/</link>
      <pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://baresql.com/varchar-without-a-length-fails-on-mysql-and-mariadb/</guid>
      <description>&lt;p&gt;Schemas written for PostgreSQL often declare names and notes as plain &lt;code&gt;VARCHAR&lt;/code&gt;, with no length. MySQL and MariaDB refuse that CREATE TABLE, since they want a length on every VARCHAR column.&lt;/p&gt;&#xA;&lt;p&gt;PostgreSQL reads VARCHAR without a length as text of any length, and SQLite ignores lengths anyway.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://baresql.com/images/rule-varchar-length.png&#34; alt=&#34;CREATE TABLE t (x VARCHAR); SELECT COUNT(*) FROM t, run on four engines: SQLite 3.45.1 0; PostgreSQL 16.15 0; MySQL 8.0.46 error: You have an error in your SQL syntax ... near &#39;)&#39; at line 1; MariaDB 10.11.14 error: You have an error in your SQL syntax ... near &#39;)&#39; at line 1.&#34;&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
