From 1bd22f55cf1e5e80ab0b7704adf9678cacaca69b Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 19 Jun 2003 23:22:40 +0000 Subject: [PATCH] Disallow dollar sign in operator names, instead allow it as a non-first character in identifiers. The first change eliminates the current need to put spaces around parameter references, as in "x<=$2". The second change improves compatibility with Oracle and some other RDBMSes. This was discussed and agreed to back in January, but did not get done. --- doc/src/sgml/release.sgml | 4 +++- doc/src/sgml/syntax.sgml | 37 +++++++++++++++++++------------------ src/backend/parser/scan.l | 16 ++++++++-------- src/pl/plpgsql/src/scan.l | 26 ++++++++++++++------------ 4 files changed, 44 insertions(+), 39 deletions(-) diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml index 382029b81f..cc03ae9cbe 100644 --- a/doc/src/sgml/release.sgml +++ b/doc/src/sgml/release.sgml @@ -1,5 +1,5 @@ @@ -24,6 +24,8 @@ CDATA means the content is "SGML-free", so you can write without worries about funny characters. --> @@ -109,10 +109,15 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); (a-z, but also letters with diacritical marks and non-Latin letters) or an underscore (_). Subsequent characters in an identifier or - key word can be letters, digits - (0-9), or underscores, - although the SQL standard will not define a key word that contains - digits or starts or ends with an underscore. + key word can be letters, underscores, digits + (0-9), or dollar signs + ($). Note that dollar signs are not allowed in identifiers + according to the letter of the SQL standard, so their use may render + applications less portable. + The SQL standard will not define a key word that contains + digits or starts or ends with an underscore, so identifiers of this + form are safe against possible conflict with future extensions of the + standard. @@ -478,20 +483,13 @@ CAST ( 'string' AS type ) An operator is a sequence of up to NAMEDATALEN-1 (63 by default) characters from the following list: -+ - * / < > = ~ ! @ # % ^ & | ` ? $ ++ - * / < > = ~ ! @ # % ^ & | ` ? There are a few restrictions on operator names, however: - $ (dollar) cannot be a single-character operator, although it - can be part of a multiple-character operator name. - - - - - -- and /* cannot appear anywhere in an operator name, since they will be taken as the start of a comment. @@ -503,7 +501,7 @@ CAST ( 'string' AS type ) A multiple-character operator name cannot end in + or -, unless the name also contains at least one of these characters: -~ ! @ # % ^ & | ` ? $ +~ ! @ # % ^ & | ` ? For example, @- is an allowed operator name, but *- is not. This restriction allows @@ -539,9 +537,9 @@ CAST ( 'string' AS type ) A dollar sign ($) followed by digits is used - to represent the positional parameters in the body of a function + to represent a positional parameter in the body of a function definition or a prepared statement. In other contexts the - dollar sign may be part of an operator name. + dollar sign may be part of an identifier. @@ -965,9 +963,12 @@ SELECT 3 OPERATOR(pg_catalog.+) 4; Positional Parameters - A positional parameter reference is used to indicate a parameter + A positional parameter reference is used to indicate a value that is supplied externally to an SQL statement. Parameters are - used in SQL function definitions and in prepared queries. + used in SQL function definitions and in prepared queries. Some + client libraries also support specifying data values separately + from the SQL command string, in which case parameters are used to + refer to the out-of-line data values. The form of a parameter reference is: $number diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index 083c19e650..6aa2676e20 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.107 2003/05/29 22:30:02 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.108 2003/06/19 23:22:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -174,10 +174,10 @@ xcstop \*+\/ xcinside [^*/]+ digit [0-9] -letter [\200-\377_A-Za-z] -letter_or_digit [\200-\377_A-Za-z0-9] +ident_start [A-Za-z\200-\377_] +ident_cont [A-Za-z\200-\377_0-9\$] -identifier {letter}{letter_or_digit}* +identifier {ident_start}{ident_cont}* typecast "::" @@ -191,8 +191,8 @@ typecast "::" * If you change either set, adjust the character lists appearing in the * rule for "operator"! */ -self [,()\[\].;$\:\+\-\*\/\%\^\<\>\=] -op_chars [\~\!\@\#\^\&\|\`\?\$\+\-\*\/\%\<\>\=] +self [,()\[\].;\:\+\-\*\/\%\^\<\>\=] +op_chars [\~\!\@\#\^\&\|\`\?\+\-\*\/\%\<\>\=] operator {op_chars}+ /* we no longer allow unary minus in numbers. @@ -461,7 +461,7 @@ other . for (ic = nchars-2; ic >= 0; ic--) { - if (strchr("~!@#^&|`?$%", yytext[ic])) + if (strchr("~!@#^&|`?%", yytext[ic])) break; } if (ic >= 0) @@ -480,7 +480,7 @@ other . * that the "self" rule would have. */ if (nchars == 1 && - strchr(",()[].;$:+-*/%^<>=", yytext[0])) + strchr(",()[].;:+-*/%^<>=", yytext[0])) return yytext[0]; } diff --git a/src/pl/plpgsql/src/scan.l b/src/pl/plpgsql/src/scan.l index 27dcdc2590..2203cdd6b4 100644 --- a/src/pl/plpgsql/src/scan.l +++ b/src/pl/plpgsql/src/scan.l @@ -4,7 +4,7 @@ * procedural language * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/Attic/scan.l,v 1.27 2003/06/17 04:35:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/Attic/scan.l,v 1.28 2003/06/19 23:22:40 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -72,12 +72,14 @@ int plpgsql_SpaceScanned = 0; %x IN_STRING IN_COMMENT digit [0-9] -letter [\200-\377_A-Za-z] -letter_or_digit [\200-\377_A-Za-z0-9] +ident_start [A-Za-z\200-\377_] +ident_cont [A-Za-z\200-\377_0-9\$] quoted_ident (\"[^\"]*\")+ -identifier ({letter}{letter_or_digit}*|{quoted_ident}) +identifier ({ident_start}{ident_cont}*|{quoted_ident}) + +param \${digit}+ space [ \t\n\r\f] @@ -197,28 +199,28 @@ dump { return O_DUMP; } {identifier}{space}*\.{space}*{identifier}{space}*%ROWTYPE { plpgsql_error_lineno = plpgsql_scanner_lineno(); return plpgsql_parse_dblwordrowtype(yytext); } -\${digit}+ { +{param} { plpgsql_error_lineno = plpgsql_scanner_lineno(); return plpgsql_parse_word(yytext); } -\${digit}+{space}*\.{space}*{identifier} { +{param}{space}*\.{space}*{identifier} { plpgsql_error_lineno = plpgsql_scanner_lineno(); return plpgsql_parse_dblword(yytext); } -\${digit}+{space}*\.{space}*{identifier}{space}*\.{space}*{identifier} { +{param}{space}*\.{space}*{identifier}{space}*\.{space}*{identifier} { plpgsql_error_lineno = plpgsql_scanner_lineno(); return plpgsql_parse_tripword(yytext); } -\${digit}+{space}*%TYPE { +{param}{space}*%TYPE { plpgsql_error_lineno = plpgsql_scanner_lineno(); return plpgsql_parse_wordtype(yytext); } -\${digit}+{space}*\.{space}*{identifier}{space}*%TYPE { +{param}{space}*\.{space}*{identifier}{space}*%TYPE { plpgsql_error_lineno = plpgsql_scanner_lineno(); return plpgsql_parse_dblwordtype(yytext); } -\${digit}+{space}*\.{space}*{identifier}{space}*\.{space}*{identifier}{space}*%TYPE { +{param}{space}*\.{space}*{identifier}{space}*\.{space}*{identifier}{space}*%TYPE { plpgsql_error_lineno = plpgsql_scanner_lineno(); return plpgsql_parse_tripwordtype(yytext); } -\${digit}+{space}*%ROWTYPE { +{param}{space}*%ROWTYPE { plpgsql_error_lineno = plpgsql_scanner_lineno(); return plpgsql_parse_wordrowtype(yytext); } -\${digit}+{space}*\.{space}*{identifier}{space}*%ROWTYPE { +{param}{space}*\.{space}*{identifier}{space}*%ROWTYPE { plpgsql_error_lineno = plpgsql_scanner_lineno(); return plpgsql_parse_dblwordrowtype(yytext); } -- 2.11.0