Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1c2jMK-0001OL-FX for pgsql-hackers@arkaria.postgresql.org; Fri, 04 Nov 2016 18:37:00 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1c2jMI-0000I3-F2 for pgsql-hackers@arkaria.postgresql.org; Fri, 04 Nov 2016 18:36:58 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1c2jMH-0000HL-AP for pgsql-hackers@postgresql.org; Fri, 04 Nov 2016 18:36:57 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1c2jMB-00011j-8t for pgsql-hackers@postgresql.org; Fri, 04 Nov 2016 18:36:56 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.4/8.14.4) with ESMTP id uA4Iabjx008745; Fri, 4 Nov 2016 14:36:37 -0400 From: Tom Lane To: Artur Zakirov cc: amul sul , Pavel Stehule , Robert Haas , "David G. Johnston" , Alex Ignatov , Bruce Momjian , amul sul , PostgreSQL-development Subject: Re: Bug in to_timestamp(). In-reply-to: References: <1873520224.1784572.1465833145330.JavaMail.yahoo.ref@mail.yahoo.com> <1873520224.1784572.1465833145330.JavaMail.yahoo@mail.yahoo.com> <884791796.213185.1466667686999.JavaMail.yahoo@mail.yahoo.com> <20160623133001.GF21246@momjian.us> <1877e60a-a970-18b5-453c-e342f96150e6@postgrespro.ru> <31915.1466703655@sss.pgh.pa.us> <32684.1466704957@sss.pgh.pa.us> <734e50cd-c563-4afd-d1c8-80f244b3265e@postgrespro.ru> <29142.1475097531@sss.pgh.pa.us> Comments: In-reply-to Artur Zakirov message dated "Thu, 29 Sep 2016 14:53:34 +0500" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <8743.1478284597.1@sss.pgh.pa.us> Date: Fri, 04 Nov 2016 14:36:37 -0400 Message-ID: <8744.1478284597@sss.pgh.pa.us> X-Pg-Spam-Score: -4.2 (----) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-hackers Precedence: bulk Sender: pgsql-hackers-owner@postgresql.org Artur Zakirov writes: > I attached new version of the patch, which fix is_char_separator() > declaration too. I did some experimenting using http://rextester.com/l/oracle_online_compiler It appears that Oracle will consider a single space in the pattern to match zero or more spaces in the input, as all of these produce the expected result: SELECT to_timestamp('2000JUN', 'YYYY MON') FROM dual SELECT to_timestamp('2000 JUN', 'YYYY MON') FROM dual SELECT to_timestamp('2000 JUN', 'YYYY MON') FROM dual Also, a space in the pattern will match a single separator character in the input, but not multiple separators: SELECT to_timestamp('2000-JUN', 'YYYY MON') FROM dual -- ok SELECT to_timestamp('2000--JUN', 'YYYY MON') FROM dual ORA-01843: not a valid month And you can have whitespace along with that single separator: SELECT to_timestamp('2000 + JUN', 'YYYY MON') FROM dual -- ok SELECT to_timestamp('2000 + JUN', 'YYYY MON') FROM dual -- ok SELECT to_timestamp('2000 ++ JUN', 'YYYY MON') FROM dual ORA-01843: not a valid month You can have leading whitespace, but not leading separators: SELECT to_timestamp(' 2000 JUN', 'YYYY MON') FROM dual -- ok SELECT to_timestamp('/2000 JUN', 'YYYY MON') FROM dual ORA-01841: (full) year must be between -4713 and +9999, and not be 0 These all work: SELECT to_timestamp('2000 JUN', 'YYYY/MON') FROM dual SELECT to_timestamp('2000JUN', 'YYYY/MON') FROM dual SELECT to_timestamp('2000/JUN', 'YYYY/MON') FROM dual SELECT to_timestamp('2000-JUN', 'YYYY/MON') FROM dual but not SELECT to_timestamp('2000//JUN', 'YYYY/MON') FROM dual ORA-01843: not a valid month SELECT to_timestamp('2000--JUN', 'YYYY/MON') FROM dual ORA-01843: not a valid month which makes it look a lot like Oracle treats separator characters in the pattern the same as spaces (but I haven't checked their documentation to confirm that). The proposed patch doesn't seem to me to be trying to follow these Oracle behaviors, but I think there is very little reason for changing any of this stuff unless we move it closer to Oracle. Some other nitpicking: * I think the is-separator function would be better coded like static bool is_separator_char(const char *str) { /* ASCII printable character, but not letter or digit */ return (*str > 0x20 && *str < 0x7F && !(*str >= 'A' && *str <= 'Z') && !(*str >= 'a' && *str <= 'z') && !(*str >= '0' && *str <= '9')); } The previous way is neither readable nor remarkably efficient, and it knows much more about the ASCII character set than it needs to. * Don't forget the cast to unsigned char when using isspace() or other functions. * I do not see the reason for throwing an error here: + /* Previous character was a backslash */ + if (in_backslash) + { + /* After backslash should go non-space character */ + if (isspace(*str)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid escape sequence"))); + in_backslash = false; Why shouldn't backslash-space be a valid quoting sequence? I'll set this back to Waiting on Author. regards, tom lane -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers