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 1qgCAE-00Ejjv-8x for pgsql-hackers@arkaria.postgresql.org; Tue, 12 Sep 2023 22:47:22 +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 1qgCAB-00CMtH-IY for pgsql-hackers@arkaria.postgresql.org; Tue, 12 Sep 2023 22:47:19 +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.94.2) (envelope-from ) id 1qgCAA-00CMt3-VG for pgsql-hackers@lists.postgresql.org; Tue, 12 Sep 2023 22:47:18 +0000 Received: from mail-pl1-x62d.google.com ([2607:f8b0:4864:20::62d]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1qgCA6-004EC8-KR for pgsql-hackers@postgresql.org; Tue, 12 Sep 2023 22:47:17 +0000 Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-1c34c9cc9b9so44604495ad.3 for ; Tue, 12 Sep 2023 15:47:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=j-davis-com.20230601.gappssmtp.com; s=20230601; t=1694558832; x=1695163632; darn=postgresql.org; h=mime-version:user-agent:content-transfer-encoding:date:to:from :subject:message-id:from:to:cc:subject:date:message-id:reply-to; bh=cpgLERQ2XzGDZCGBpu0DsVSFJ9uDPLM3DwIsLUMPWRY=; b=Jz0MiRR+rVzScYkQHLTj6g83nyoAM4MNKmEi7r3NjOMFwqJlkXpMBkcet0qXD/s2vO QuN/cOJHl5O4usmGQW0NsTGUbAqXFkll6HX6J0jqzjrSU7/1j3bF0WiYlSIVQDRiBUue zq20BcCUbleOxkUi0cjgvC4F3Na5mJ9+T6wXHAy1ul08gMnaQkHheUE3DAP0Von1m8Ek Pbic8/r3fbPpFQBoHnUBvG/660AakhYzCbNuGoK6N4LF8LSJa3vyHirBudMAYwUjsh4f 1xqZ1LQFJ1O6TsNq2sPpgYtl3rw3jssI3wp4/IOYf6xrZ1bMZZh5Jz+417CbtZrCclnj JhSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694558832; x=1695163632; h=mime-version:user-agent:content-transfer-encoding:date:to:from :subject:message-id:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=cpgLERQ2XzGDZCGBpu0DsVSFJ9uDPLM3DwIsLUMPWRY=; b=nICnsREaGpFKOyRxvPqz+moRG6gLFyL0gqjRleuyrJoBq3nzB/OQJtDeb59fjZ60Gm UkAsjx966znJ/g1qNDq6BDnawVcK7oq+mqZmIRt4y11pC2izNB0gja4nfAnjPDgra7ME JGjbWUDodsbpczFK6QgKFYBGZ+Fq2KS/ydzVO/YVJfK7PfK7YC5Cay2ax6PaH3wcDxYP oqOrC7dw2SGuwPcQUOZQzjPL7TDmVyVCj/EXgdEs3nUJQzJerOebYIqS52ZhlQMR1K+V FqZExBzOzcF032r2gnlVFGfMa/giJFyfF/UDsyn24DwBLvKEYxLKtKU7DePvkJygoy7u /qSw== X-Gm-Message-State: AOJu0YxbXy1DEhlLY9YMOPsTuDl9NVLYs3Qu3L5tcWnSaxCefbl2+nqU hNvgxbdZGhQS+hjxCa6O5w/8kGRHlb1+BDZn8SU= X-Google-Smtp-Source: AGHT+IFZ1i2ezRMGLIwIWU7ZYGiHHJSI3c8nqj+v6q9tNCQa8gZY9dXzhoqYveY3Mj7D+forzOju4g== X-Received: by 2002:a17:903:11cf:b0:1c3:3363:8aea with SMTP id q15-20020a17090311cf00b001c333638aeamr1354174plh.61.1694558832350; Tue, 12 Sep 2023 15:47:12 -0700 (PDT) Received: from [172.18.5.16] ([12.126.244.130]) by smtp.gmail.com with ESMTPSA id o10-20020a170902778a00b001b53953f306sm9061122pll.178.2023.09.12.15.47.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 15:47:11 -0700 (PDT) Message-ID: Subject: Pre-proposal: unicode normalized text From: Jeff Davis To: pgsql-hackers@postgresql.org Date: Tue, 12 Sep 2023 15:47:10 -0700 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.44.4-0ubuntu2 MIME-Version: 1.0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk One of the frustrations with using the "C" locale (or any deterministic locale) is that the following returns false: SELECT 'a=CC=81' =3D '=C3=A1'; -- false because those are the unicode sequences U&'\0061\0301' and U&'\00E1', respectively, so memcmp() returns non-zero. But it's really the same character with just a different representation, and if you normalize them they are equal: SELECT normalize('a=CC=81') =3D normalize('=C3=A1'); -- true The idea is to have a new data type, say "UTEXT", that normalizes the input so that it can have an improved notion of equality while still using memcmp(). Unicode guarantees that "the results of normalizing a string on one version will always be the same as normalizing it on any other version, as long as the string contains only assigned characters according to both versions"[1]. It also guarantees that it "will not reallocate, remove, or reassign" characters[2]. That means that we can normalize in a forward-compatible way as long as we don't allow the use of unassigned code points. I looked at the standard to see what it had to say, and is discusses normalization, but a standard UCS string with an unassigned code point is not an error. Without a data type to enforce the constraint that there are no unassigned code points, we can't guarantee forward compatibility. Some other systems support NVARCHAR, but I didn't see any guarantee of normalization or blocking unassigned code points there, either. UTEXT benefits: * slightly better natural language semantics than TEXT with deterministic collation * still deterministic=3Dtrue * fast memcmp()-based comparisons * no breaking semantic changes as unicode evolves TEXT allows unassigned code points, and generally returns the same byte sequences that were orgiinally entered; therefore UTEXT is not a replacement for TEXT. UTEXT could be built-in or it could be an extension or in contrib. If an extension, we'd probably want to at least expose a function that can detect unassigned code points, so that it's easy to be consistent with the auto-generated unicode tables. I also notice that there already is an unassigned code points table in saslprep.c, but it seems to be frozen as of Unicode 3.2, and I'm not sure why. Questions: * Would this be useful enough to justify a new data type? Would it be confusing about when to choose one versus the other? * Would cross-type comparisons between TEXT and UTEXT become a major problem that would reduce the utility? * Should "some_utext_value =3D some_text_value" coerce the LHS to TEXT or the RHS to UTEXT? * Other comments or am I missing something? Regards, Jeff Davis [1] https://unicode.org/reports/tr15/ [2] https://www.unicode.org/policies/stability_policy.html