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 1ufKDq-005Xp2-C2 for pgsql-general@arkaria.postgresql.org; Fri, 25 Jul 2025 15:20:35 +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 1ufKDo-001sFP-DW for pgsql-general@arkaria.postgresql.org; Fri, 25 Jul 2025 15:20:32 +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 1ufKDn-001sDp-9I for pgsql-general@lists.postgresql.org; Fri, 25 Jul 2025 15:20:32 +0000 Received: from fout-b4-smtp.messagingengine.com ([202.12.124.147]) by makus.postgresql.org with smtp (Exim 4.96) (envelope-from ) id 1ufKDl-000juO-0b for pgsql-general@postgresql.org; Fri, 25 Jul 2025 15:20:30 +0000 Received: from phl-compute-12.internal (phl-compute-12.phl.internal [10.202.2.52]) by mailfout.stl.internal (Postfix) with ESMTP id DBB131D008D5; Fri, 25 Jul 2025 11:20:27 -0400 (EDT) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-12.internal (MEProxy); Fri, 25 Jul 2025 11:20:27 -0400 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=fm1; t=1753456827; x=1753543227; bh=MBfoYcrhmfbDQ6ZvBdGhXsO+vrWzkuEI1Ku4YDbkvHk=; b= DUQQSYL47gu/lu2dJOlbftyB/Tj1YjBdOAQmOnlb9TkP76J26lKb+uB/UHmthfww D0xuXUzcpwF52g2nD2zp4CpmroAX6gD6GQEfx+8H763FkgRrd9EaPxWbhTlEm28p iEd7QhA8jRMgg3wTRfaZllaUEM8VyQbGKWLaxumKW3Umx+vMGx8JnuODRqPLb9lT uNQ3H6YJUk3pQH3MD7KoQPPX3rLRzQoBNgehV5ptXrJhoiOj9ZUSCvRWC1rG+vTz BAw1m5OZq4tRLvAHdqM0Sc6BBNlYGRNBILUrxZ/AieS+EVN9cSylAxMF/wUm7QKF XBZJ0iOGR4XYzz/HwuqL2A== 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=fm2; t=1753456827; x=1753543227; bh=M BfoYcrhmfbDQ6ZvBdGhXsO+vrWzkuEI1Ku4YDbkvHk=; b=CnhSzrycSCiUm0dDs CjAmSE835Is/G5+bYzoM+wPUoYfSWWsivMjPkSkkhSawkjJtf6vvIqtS6bCxzHul hkGxaLPDEoT54FmkjEAQB1UY8JcSJQGTHQPD+tzfoQy71avxHY2XPU6yUbun/cOv Kwf5KjuvYePe/Cv/APeZ6sjYiFDpA5OoHTBXkBw6jES69+T+HnVRs0rMKiRSNtoG je4fOqwheuM/su/pyTDuPdiEbsR7Apf7j5PJjcBWoI7PJaB03sUrrwbmUvR7g9jx dM6vkAQ+FJr5z2O4HH2TDkU6IO3Xg3xfkyPHdj4jcw7t/z3LADvg8RM0u6Biti7Q 4iMrw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdefgdekfeekjecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpuffrtefokffrpgfnqfghnecuuegr ihhlohhuthemuceftddtnecunecujfgurhepkfffgggfuffvfhfhjggtgfesthekredttd dvjeenucfhrhhomheptegurhhirghnucfmlhgrvhgvrhcuoegrughrihgrnhdrkhhlrghv vghrsegrkhhlrghvvghrrdgtohhmqeenucggtffrrghtthgvrhhnpeelgeevkeekkeeuie fgtdevieeluefhfedufeetkeejffekjeeujeehgeehgeektdenucffohhmrghinhepphho shhtghhrvghsqhhlrdhorhhgnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpe hmrghilhhfrhhomheprggurhhirghnrdhklhgrvhgvrhesrghklhgrvhgvrhdrtghomhdp nhgspghrtghpthhtohepvddpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtohepnhhvph hoshhtghhrvghssehgmhgrihhlrdgtohhmpdhrtghpthhtohepphhgshhqlhdqghgvnhgv rhgrlhesphhoshhtghhrvghsqhhlrdhorhhg X-ME-Proxy: Feedback-ID: i76984098:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 25 Jul 2025 11:20:27 -0400 (EDT) Message-ID: Date: Fri, 25 Jul 2025 08:20:26 -0700 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Upper / lower case keys in JSON objects To: Mark , 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 7/25/25 05:26, Mark wrote: > Hi all > > Apologies for any unexpected protocol exceptions, I do not post to > mailing lists very often > > I have been trying to work with JSON objects and noticed I could not get > the function json_to_record to produce results, unless I had the key > values in lower case, through testing what works. > > I completed a search, but could not find any pointer (except for some > front end comments on labels being all upper or all lower case) > > Could anybody comment if the postgres standard is to have key labels in > lower case? Yes and no. It comes down to this: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS "Quoting an identifier also makes it case-sensitive, whereas unquoted names are always folded to lower case. For example, the identifiers FOO, foo, and "foo" are considered the same by PostgreSQL, but "Foo" and "FOO" are different from these three and each other. (The folding of unquoted names to lower case in PostgreSQL is incompatible with the SQL standard, which says that unquoted names should be folded to upper case. Thus, foo should be equivalent to "FOO" not "foo" according to the standard. If you want to write portable applications you are advised to always quote a particular name or never quote it.)" So on the Postgres(SQL) side 'as x(seclvl int, firbal text, firlvl text , thilvl text, fourlvl int)' if you want to match the mixed case keys coming from the JSON object you need to double quote the field names. The yes is that Postgres by default folds identifiers to lower case, but no that does not mean you have to use lower case by default for the JSON keys. > > Many thanks for any help you can provide > > Mark > > query: > select * from json_to_record('{"secLvl": 13, "firBal": "somethi", > "firLvl": "C", "thiLvl": "A", "fourLvl": 2}'::json) as x(seclvl int, > firbal text, firlvl text > , thilvl text, fourlvl int); > > result: > seclvl | firbal | firlvl | thilvl | fourlvl > --------+--------+--------+--------+--------- >        |        |        |        | > (1 row) > > > query: > select * from json_to_record('{"seclvl": 13, "firbal": "somethi", > "firlvl": "C", "thilvl": "A", "fourlvl": 2}'::json) as x(seclvl int, > firbal text, firlvl text > , thilvl text, fourlvl int); > > result: > seclvl | firbal  | firlvl | thilvl | fourlvl > --------+---------+--------+--------+--------- >     13 | somethi | C      | A      |       2 > (1 row) > -- Adrian Klaver adrian.klaver@aklaver.com