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.96) (envelope-from ) id 1vXhqW-002Unw-2i for pgsql-hackers@arkaria.postgresql.org; Mon, 22 Dec 2025 15:29:17 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vXhqV-00FJ0V-1B for pgsql-hackers@arkaria.postgresql.org; Mon, 22 Dec 2025 15:29:16 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vXhnK-00FF0b-03 for pgsql-hackers@lists.postgresql.org; Mon, 22 Dec 2025 15:25:58 +0000 Received: from mail-lj1-x235.google.com ([2a00:1450:4864:20::235]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vXhnJ-00214o-19 for pgsql-hackers@lists.postgresql.org; Mon, 22 Dec 2025 15:25:57 +0000 Received: by mail-lj1-x235.google.com with SMTP id 38308e7fff4ca-37fd6e91990so30488391fa.3 for ; Mon, 22 Dec 2025 07:25:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1766417155; x=1767021955; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=OguzywXR2b//uC7cB6J3NpPDrz2tOnUR++BW8D4Anqk=; b=fnM3aWsD3Oooul+JRWB8ZLhvU9gmKVtyQJ5WrduK51AEbUed1yuQLJv3YpF8Hw90st UAOylc8uTzvLmMg9Ok57aKaIW7jzXJentMcyQRUDh/E2vxRsl4Fpb0eN/Roy4dLkcy0a HgclQ7v1y8JnIz/Pp7Uy7e/1MlVYAnE5uvta1Yyf+jKmNQ8XZxhdtdSA/3xgJq2pYTHn vfQI8/wAkv6prlJzJ0M6i34pkY+fmpDK+XAkOz3/HVTT5+i2jJKRmPMUF5C7TzaTZWfr RY78AsLmYVBnnZN/T5fs5gQL0VX2lYf8H3xnTzURPd2u4oh103xYiwTiQu1Npvx8wM8G aSoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766417155; x=1767021955; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=OguzywXR2b//uC7cB6J3NpPDrz2tOnUR++BW8D4Anqk=; b=Pnweps3yFFeMGX/r6HzI1oaJq3IGcTnkYPdKBxcJ2ZRkcPpHc6JkgssLFm3YKLNr3X 3x/qJwgMjjalk7iEeS8cDlDkPzpnrvIMcKRE3wDSUIINrWIx00Eu58l+wWPRrl0qHGXz 5eGEX/x6wj/KiSG0KQcx07glHsG26I1GKWlx01dxljZIb522nL1/bO9Fb/zLbK/p367x 612lBXG49ff3zBIJlBz2VW/wI7Ac1V+IUZ3CCmd7pB/xrN40AwdPdo6M4FsHS81q7ruB 2HHxD2XG+bdXKN3KGqzQX42kGcaur1Kag5guicQhI9XscRqyH3cYwGEZ/8uBTSqTAUV5 gSyA== X-Gm-Message-State: AOJu0YwP0q2suVRmTr/X7l67Lr9sL0GlUj+q4eXwhRJRPwSVys8AIgbJ fN8JnQcJsww4jpdEQDoN6CGrFH72sBVPRJ8drm9/m4eyMY5yknnvUXaDnk/ESTliJvEmvGG5Npa FVk+LdNC+ZEwJfhwizb4wBTBPdHFrislAkA== X-Gm-Gg: AY/fxX4o8Rx/jOtBRRY/OBw2unrSnjRs3pkvTFRyu7UAEv/ZqQXvmutd6KWDclIYaFR m9PvgDe6R3gCueQOOvD+627OYQnHAHHQn/k4xviW0ZUSTmRGOmtoye/aNuPOIMhy3X2VejNOCIX zOO/rwEhmeLUtFa7TH4liBee92iYn0WZCWhuXffOhzsD0w1HfNn/zVvr7wEyI6XQirh7rqfbZJ9 wZEsKoC+J79SmEUOLkt85Z3IGDvNNejKIvLDeDrSSEgHhcXahUTeqhawDhvoZfso7/a53ECDeFc m0h9SsYccWGDoUR18XWUV7YiR08J/sKDsjHFXqzXXfxJlA8GWQ4HrQRFX6w/MlYLuHG4 X-Google-Smtp-Source: AGHT+IFLjn3jUm+XQFe7SaGoYrYSvWZWpczNTs77JH/g+aZpeyweuYil5REJ5Q+4Jq/3YcR6xLnc0v9SP22ZHnd+Sw0= X-Received: by 2002:a2e:a595:0:b0:37a:2d8c:c0a8 with SMTP id 38308e7fff4ca-381216e10f9mr36052401fa.34.1766417155147; Mon, 22 Dec 2025 07:25:55 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Matthias van de Meent Date: Mon, 22 Dec 2025 16:25:43 +0100 X-Gm-Features: AQt7F2pvqdXOJ6s9SxnxambPYHc90Yb_O00KussfVeCp6xMeh94rLF4JSEHl3JU Message-ID: Subject: Re: SQL-level pg_datum_image_equal To: jian he Cc: PostgreSQL Hackers Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Sat, 20 Dec 2025 at 14:15, jian he wrote: > > On Thu, Dec 11, 2025 at 1:46=E2=80=AFAM Matthias van de Meent > wrote: > > > > Hi, > > > > > > > > So, attached is a simple and to-the-point patch that adds the function > > mentioned in $subject, which will tell the user whether two values of > > the same type have an exactly equal binary representation, using > > datum_image_eq. > > > > hi. > > maybe Table 9.76 > (https://www.postgresql.org/docs/current/functions-info.html#FUNCTIONS-IN= FO-CATALOG) > is the right place for this function. I think table 9.3 (https://www.postgresql.org/docs/18/functions-comparison.html#FUNCTIONS-COM= PARISON-FUNC-TABLE) makes more sense, as this is more a compare function than one that exposes catalog information about the input. > corner case confused me, I think this is related to null handling, > maybe not related to this. > create type t1 as (a int, b text); > select pg_datum_image_equal('(,)'::t1, $$(,)$$::t1); > select pg_datum_image_equal('(,)'::t1, NULL::t1); > select '(,)'::t1 is null, NULL::t1 is null; Yes, that's row-type NULL handling for you. '(,)' is a composite value with only NULL values in the attributes, and SQL defines that rows with only NULL columns must return True when `IS NULL` evaluates their NULL-ness. On disk, however, it is still stored as a "composite type; attributes 'a' and 'b' are NULL"; so that a user that casts the value to text will get a different result between (NULL::t1::text) and ('(,)'::t1::text), allowing safe round-trip conversions. Also note that `('(,)'::t1 IS DISTINCT FROM NULL::t1) =3D TRUE, another curious consequence of this SQL rule. So, that output is expected; some methods already expose these differences between the values, so pg_datum_image_equal() *must* also indicate they are different. And now we also have one more reason to have a function that can notice distinctions that go deeper than surface-level SQL. Aside: This new function doesn't actually fully cover the spectrum of possible inequalities detectable through SQL, as there are some very low level datum introspection tools like pg_column_size() whose output depends on the type of toasting applied. My function cover that, because that data should be completely irrelevant to normal data usage, and the user can combine this manually if they really need it. > enforce_generic_type_consistency already resolved generic type. While you are correct to point out that the type system would prevent this from getting called from SQL without a proper type, I'd like to keep the check to make sure that callers from outside the type system don't accidentally fail to provide the function with a correct type. > so > + if (!OidIsValid(typ)) > + { > + ereport(ERROR, > + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), > + errmsg("could not determine type"))); > + } > this part should be elog(ERROR.....) ? Is there a policy on what should _not_ use ereport? I know we don't require ereport for internal errors, but is considered forbidden? Kind regards, Matthias van de Meent Databricks (https://www.databricks.com)