pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Andrew Gierth <andrew@tao11.riddles.org.uk>
To: pgsql-hackers@postgresql.org
Subject: A really subtle lexer bug
Date: Mon, 20 Aug 2018 08:38:52 +0100
Message-ID: <87va851ppl.fsf@news-spur.riddles.org.uk> (raw)

Currently in PG, the precedence of = and <> is supposed to be equal, and
the precedence of unary - is very high.

So, (true=1 between 1 and 1) parses as ((true)=(1 between 1 and 1)),
and (true=-1 between 1 and 1) parses as ((true)=((-1) between 1 and 1)).
All good so far.

(true<>-1 between 1 and 1) parses as ((true<>(-1)) between 1 and 1). ???

The fault here is in the lexer. The input "<>-" is being lexed as an Op
followed by '-' rather than as NOT_EQUAL followed by '-' because it
looks like a match for a multi-character operator, with the - being
thrown back into the input afterwards. So the precedence of <> gets
inflated to that of Op, which is higher than BETWEEN.

More seriously, this also breaks named arguments:

create function f(a integer) returns integer language sql
 as $$ select a; $$;

select f(a => 1);  -- works
select f(a => -1);  -- works
select f(a =>-1);  -- ERROR:  column "a" does not exist

I guess the fix is to extend the existing special case code that checks
for one character left after removing trailing [+-] and also check for
the two-character ops "<>" ">=" "<=" "=>" "!=". 

-- 
Andrew (irc:RhodiumToad)




view thread (8+ messages)  latest in thread

Message-ID: <87va851ppl.fsf@news-spur.riddles.org.uk>
Permalink:  ../87va851ppl.fsf@news-spur.riddles.org.uk/
Also on:    postgresql.org/message-id/87va851ppl.fsf@news-spur.riddles.org.uk

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: andrew@tao11.riddles.org.uk
  Subject: Re: A really subtle lexer bug
  In-Reply-To: <87va851ppl.fsf@news-spur.riddles.org.uk>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox