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 1wDkvj-003KWY-2v for pgsql-bugs@arkaria.postgresql.org; Fri, 17 Apr 2026 15:16:28 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wDkvj-00AWgd-0Q for pgsql-bugs@arkaria.postgresql.org; Fri, 17 Apr 2026 15:16:27 +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 1wDkvi-00AWgV-2s for pgsql-bugs@lists.postgresql.org; Fri, 17 Apr 2026 15:16:26 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1wDkvg-00000001UXo-36kf for pgsql-bugs@postgresql.org; Fri, 17 Apr 2026 15:16:26 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 63HFGKcp3068557; Fri, 17 Apr 2026 11:16:20 -0400 From: Tom Lane To: Leendert Gravendeel cc: pgsql-bugs@postgresql.org Subject: Re: BUG: PL/pgSQL FOREACH misparses variable named "slice" with SLICE clause In-reply-to: References: Comments: In-reply-to Leendert Gravendeel message dated "Wed, 15 Apr 2026 20:56:50 +0200" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <3068555.1776438980.1@sss.pgh.pa.us> Date: Fri, 17 Apr 2026 11:16:20 -0400 Message-ID: <3068556.1776438980@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Leendert Gravendeel writes: > When using FOREACH with the SLICE clause, a loop variable named > `slice` is misinterpreted as the SLICE keyword, causing the statement > to fail. Renaming the variable to anything else makes the function > work as expected. So, um, don't do that. PL/pgSQL will let you use (many of) its keywords as variable names, but once you declare such a variable, the word will be taken as a variable reference not as a keyword for the rest of the block. So what the parser is seeing here is FOREACH variable variable 1 IN ARRAY variable LOOP and it naturally doesn't like that. You could also break this statement by making a variable named "array", for example. (But not "foreach", "in", or "loop", as those are reserved words.) Not sure how well this behavior is documented. I think there are a small number of exceptions, in places where the scanner can know that the next word must be a keyword, but most unreserved keywords work this way. The only other thing we could do is make such keywords fully reserved, which would break legacy code that uses "slice" or whatever as a variable name without knowledge of the new SLICE syntax. So we generally try to make newly-added keywords unreserved; this ambiguity seems the lesser evil. regards, tom lane