Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tNweL-0037HC-2U for pgsql-general@arkaria.postgresql.org; Wed, 18 Dec 2024 16:11:49 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1tNweK-00GOYJ-7b for pgsql-general@arkaria.postgresql.org; Wed, 18 Dec 2024 16:11:47 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tNweJ-00GOYA-FF for pgsql-general@lists.postgresql.org; Wed, 18 Dec 2024 16:11:47 +0000 Received: from fout-b4-smtp.messagingengine.com ([202.12.124.147]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tNweB-000Qro-DV for pgsql-general@postgresql.org; Wed, 18 Dec 2024 16:11:46 +0000 Received: from phl-compute-11.internal (phl-compute-11.phl.internal [10.202.2.51]) by mailfout.stl.internal (Postfix) with ESMTP id 0300A1140121; Wed, 18 Dec 2024 11:11:36 -0500 (EST) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-11.internal (MEProxy); Wed, 18 Dec 2024 11:11:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aklaver.com; h= cc:content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm3; t=1734538296; x=1734624696; bh=1clWllATR1JaKMLot58KxSIP5X849awoKdfFO73IfCg=; b= ddr+1MdOOARBJxm1007RQWGu9oZWYoAgfj1lO/I0EsWIG0kDMEp2Xe+H7NKJ4pXo hBF7NNE7BwkOTdiN6meMptff3yMG9FjT8mRiSS8lftc/2jMXSpwzYEUljewt0YZa U5DBcXI+e/IS4eerDk2+eO0M/eX7DiTffP1woAHqttJ373PC6BAt0qlVs5MCuHTg QsEl0yBDqiZDzH3HepfsIhYeKzY4LPArimA+J+bV48a30mylsr/JF9LhCa4gJ4iS PpAo7VTxXjcQ0k3rE/uU1feXkCopDgdG7YlgLVTj8c3ZXhmcffkWQaioUunY9f3p uEvgFFsc8CHrf1TQcvunHA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; t=1734538296; x=1734624696; bh=1 clWllATR1JaKMLot58KxSIP5X849awoKdfFO73IfCg=; b=H1Ila3AVF5ooQJUyM PCOQefMDgSmSc1IoFYzw3o7vEfBkel7APGP30y3OIfC1Xcvi9qBdrJ7aZqIdgHH+ n+5GmJd/Ohy1ptPBPlPAR+uJlQe8/DVDiLWX76DkuIerwmJciXMGxP76Uq3aRAo9 D8xOtHsJkqrLquicpoJbXdzPplYzYBVALLdUSe1ijcofK0COmu0of+TJ0pSbrzrV YF9qM3u3tmbV1VyGQI/zBi2TBU7smtUtE5m49q+/d1xQHX8AGrWaxymOVv4qwHxg tx02NHOZn+JCAtGyK1LR1ex6kgNEPJuFcwLaNXBsSzvmogLF8G858v2dc5g8sZu2 WO5iA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrleekgdekgecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdpuffr tefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecunecujfgurhepkfffgggfuf fvfhfhjggtgfesthekredttddvjeenucfhrhhomheptegurhhirghnucfmlhgrvhgvrhcu oegrughrihgrnhdrkhhlrghvvghrsegrkhhlrghvvghrrdgtohhmqeenucggtffrrghtth gvrhhnpeelgeevkeekkeeuiefgtdevieeluefhfedufeetkeejffekjeeujeehgeehgeek tdenucffohhmrghinhepphhoshhtghhrvghsqhhlrdhorhhgnecuvehluhhsthgvrhfuih iivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprggurhhirghnrdhklhgrvhgvrhes rghklhgrvhgvrhdrtghomhdpnhgspghrtghpthhtohepvddpmhhouggvpehsmhhtphhouh htpdhrtghpthhtohepphhoshhtghhrvghsqhhlmhgrihhlihhnghesuggrmhgvthhtohhl uhgtrgdrtghomhdprhgtphhtthhopehpghhsqhhlqdhgvghnvghrrghlsehpohhsthhgrh gvshhqlhdrohhrgh X-ME-Proxy: Feedback-ID: i76984098:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 18 Dec 2024 11:11:36 -0500 (EST) Message-ID: <179fbea7-d621-4456-ad3c-afd82241776f@aklaver.com> Date: Wed, 18 Dec 2024 08:11:35 -0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Documentation enancement regarding NULL and operators To: Luca Dametto , pgsql-general@postgresql.org References: Content-Language: en-US From: Adrian Klaver In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 12/15/24 09:35, Luca Dametto wrote: > Hi All, > I'm coming from hours of debugging a SQL trigger that wasn't working > properly. After a beautiful headache and infinite hours of documentation > reading I've found out that something doesn't work as I would expect. > > Most programming languages return "true" when two null values are > compared, and false when, being the two values nullable, one of them is > null and the other one isn't. > Any developer coming from Python, Javascript, PHP (and many more) would > expected 'example'= null to return false, whilst SQL thanks to 3VL > returns you a gentle ¯\_(ツ)_/¯ . Not a true, not a false, just nothing > - in a boolean statement. > > Python3: > >>> "example" == None > False > >>> None == None > True > > NodeJS: > > "example" == null > false > > null == null > true > > PHP 8: > > var_dump("example" == null); > bool(false) > > var_dump(null == null); > bool(true) > > Whilst I'd love to discuss the reasons of this, I understand that it > would be a waste of time for everyone, as we cannot change the > status-quo even if it made sense, as it would break many thousands of > projects. > > For that reason, I'd just like to improve the documentation to add at > least a note about "hey, this won't work as you might expect, because it > works in a different way than 99% of programming languages out there.". > I've tried to understand how to submit my proposal for the documentation > improvements, but it's way harder than what my brain can handle with the > current headache caused by this stuff, I've attached a git patch to this > email in case it's useful. > > Content: " > PostgreSQL follows SQL's 3VL, due to that some comparisons regarding > NULL values may not work as you might expect. > As an example, two nullable columns that contain NULL, when compared > using the OPERATOR =, will return nothing instead of TRUE like your > programming language may do. In this case, only 'IS NOT DISTINCT FROM' > would return the result you expect. > " See: https://www.postgresql.org/docs/current/functions-comparison.html " Ordinary comparison operators yield null (signifying “unknown”), not true or false, when either input is null. For example, 7 = NULL yields null, as does 7 <> NULL. When this behavior is not suitable, use the IS [ NOT ] DISTINCT FROM predicates:" > > Kind regards, > Luca -- Adrian Klaver adrian.klaver@aklaver.com