diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index 32bd39b5bd..712a4a02ab 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -861,5 +861,11 @@ Tue Mar 7 10:58:21 CET 2000 Thu Mar 9 10:12:57 CET 2000 - Fixed another memory bug in the parser. + +Wed Mar 15 17:36:02 CET 2000 + + - Synced preproc.y with gram.y. + - Synced pgc.l with scan.l. + - Synced keyword.c. - Set library version to 3.1.0. - Set ecpg version to 2.7.0. diff --git a/src/interfaces/ecpg/preproc/keywords.c b/src/interfaces/ecpg/preproc/keywords.c index a82975056f..ebfeab61f1 100644 --- a/src/interfaces/ecpg/preproc/keywords.c +++ b/src/interfaces/ecpg/preproc/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.23 2000/02/22 19:57:10 meskes Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.24 2000/03/15 19:09:10 meskes Exp $ * *------------------------------------------------------------------------- */ @@ -182,6 +182,7 @@ static ScanKeyword ScanKeywords[] = { {"only", ONLY}, {"operator", OPERATOR}, {"option", OPTION}, + {"overlaps", OVERLAPS}, {"or", OR}, {"order", ORDER}, {"outer", OUTER_P}, diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index a63294dfae..87ca300b13 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -12,7 +12,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.53 2000/03/08 22:03:12 tgl Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.54 2000/03/15 19:09:10 meskes Exp $ * *------------------------------------------------------------------------- */ @@ -147,21 +147,22 @@ xdcother [^"] xdcinside ({xdcqq}|{xdcqdq}|{xdcother}) /* C-Style Comments - * Ignored by the scanner and parser. * The "extended comment" syntax closely resembles allowable operator syntax. * The tricky part here is to get lex to recognize a string starting with * slash-star as a comment, when interpreting it as an operator would produce - * a longer match --- remember lex will prefer a longer match! So, we have - * to provide a special rule for xcline (a complete comment that could - * otherwise look like an operator), as well as append {op_and_self}* to - * xcstart so that it matches at least as much as {operator} would. - * Then the tie-breaker (first matching rule of same length) wins. - * There is still a problem if someone writes, eg, slash-star-star-slash-plus. - * It'll be taken as an xcstart, rather than xcline and an operator as one - * could wish. I don't see any way around that given lex's behavior; - * that someone will just have to write a space after the comment. + * a longer match --- remember lex will prefer a longer match! Also, if we + * have tor whereas we want to see it as a + operator and a comment start. + * The solution is two-fold: + * 1. append {op_and_self}* to xcstart so that it matches as much text as + * {operator} would. Then the tie-breaker (first matching rule of same + * length) ensures xcstart wins. We put back the extra stuff with yyless() + * in case it contains a star-slash that should terminate the comment. + * 2. In the operator rule, check for slash-star within the operator, and + * if found throw it back with yyless(). This handles the plus-slash-star + * problem. + * SQL92-style comments, which start with dash-dash, have similar interactions + * with the operator rule. */ -xcline \/\*{op_and_self}*\*\/ xcstart \/\*{op_and_self}* xcstop \*+\/ xcinside ([^*]+)|(\*+[^/]) @@ -174,6 +175,7 @@ identifier {letter}{letter_or_digit}* typecast "::" +/* NB: if you change "self", fix the copy in the operator rule too! */ self [,()\[\].;$\:\+\-\*\/\%\^\<\>\=\|] op_and_self [\~\!\@\#\^\&\|\`\?\$\:\+\-\*\/\%\<\>\=] operator {op_and_self}+ @@ -252,31 +254,32 @@ cppline {space}*#(.*\\{line_end})*.* * * Quoted strings must allow some special characters such as single-quote * and newline. - * Embedded single-quotes are implemented both in the SQL/92-standard + * Embedded single-quotes are implemented both in the SQL92-standard * style of two adjacent single quotes "''" and in the Postgres/Java style * of escaped-quote "\'". * Other embedded escaped characters are matched explicitly and the leading * backslash is dropped from the string. - thomas 1997-09-24 - * Note that xcline must appear before xcstart, which must appear before - * operator, as explained above! Also whitespace (comment) must appear - * before operator. + * Note that xcstart must appear before operator, as explained above! + * Also whitespace (comment) must appear before operator. */ %% {whitespace} { /* ignore */ } -{xcline} { ECHO; } - {xcstart} { state_before = YYSTATE; ECHO; BEGIN(xc); + /* Put back any characters past slash-star; see above */ + yyless(2); } {xcstop} { ECHO; BEGIN(state_before); } {xcinside} { ECHO; } +<> { mmerror(ET_ERROR, "Unterminated /* comment"); } + {xbstart} { BEGIN(xb); startlit(); @@ -291,6 +294,8 @@ cppline {space}*#(.*\\{line_end})*.* mmerror(ET_ERROR, "Bad binary integer input!"); return ICONST; } +<> { mmerror(ET_ERROR, "Unterminated binary integer"); } + {xhinside} | {xbinside} { addlit(yytext, yyleng); @@ -314,6 +319,8 @@ cppline {space}*#(.*\\{line_end})*.* return ICONST; } +<> { mmerror(ET_ERROR, "Unterminated hexadecimal integer"); } + {xqstart} { state_before = YYSTATE; BEGIN(xq); @@ -333,6 +340,8 @@ cppline {space}*#(.*\\{line_end})*.* /* ignore */ } +<> { mmerror(ET_ERROR, "Unterminated quoted string"); } + {xdstart} { state_before = YYSTATE; BEGIN(xd); @@ -346,6 +355,7 @@ cppline {space}*#(.*\\{line_end})*.* {xdinside} { addlit(yytext, yyleng); } +<> { mmerror(ET_ERROR, "Unterminated quoted identifier"); } {typecast} { return TYPECAST; } {self} { /* * We may find a ';' inside a structure @@ -357,7 +367,33 @@ cppline {space}*#(.*\\{line_end})*.* return yytext[0]; } {operator} { - if (strcmp((char*)yytext,"!=") == 0) + /* Check for embedded slash-star or dash-dash */ + char *slashstar = strstr((char*)yytext, "/*"); + char *dashdash = strstr((char*)yytext, "--"); + + if (slashstar && dashdash) + { + if (slashstar > dashdash) + slashstar = dashdash; + } + else if (!slashstar) + slashstar = dashdash; + + if (slashstar) + { + int nchars = slashstar - ((char*)yytext); + yyless(nchars); + /* If what we have left is only one char, and it's + * one of the characters matching "self", then + * return it as a character token the same way + * that the "self" rule would have. + */ + if (nchars == 1 && + strchr(",()[].;$:+-*/%^<>=|", yytext[0])) + return yytext[0]; + } + + if (strcmp((char*)yytext, "!=") == 0) yylval.str = mm_strdup("<>"); /* compatability */ else yylval.str = mm_strdup((char*)yytext); diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index 78dad88c4f..1a76984c53 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -196,7 +196,7 @@ make_name(void) ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL, MATCH, MINUTE_P, MONTH_P, NAMES, NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC, - OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P, + OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P, OVERLAPS, PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC, READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK, SCROLL, SECOND_P, SELECT, SESSION_USER, SET, SUBSTRING, @@ -253,6 +253,7 @@ make_name(void) %right '=' %nonassoc '<' '>' %nonassoc LIKE +%nonassoc OVERLAPS %nonassoc BETWEEN %nonassoc IN %left Op /* multi-character ops and user-defined operators */ @@ -291,7 +292,7 @@ make_name(void) %type Typename SimpleTypename Generic Numeric generic opt_float opt_numeric %type opt_decimal Character character opt_varying opt_charset %type opt_collate Datetime datetime opt_timezone opt_interval -%type numeric a_expr_or_null row_expr row_descriptor row_list +%type numeric row_expr row_descriptor row_list %type SelectStmt SubSelect result OptTemp ConstraintAttributeSpec %type opt_table opt_all sort_clause sortby_list ConstraintAttr %type sortby OptUseOp opt_inh_star relation_name_list name_list @@ -898,7 +899,6 @@ DEFAULT} */ alter_column_action: SET DEFAULT a_expr { $$ = cat2_str(make_str("set default"), $3); } - | SET DEFAULT NULL_P { $$ = make_str("set default null"); } | DROP DEFAULT { $$ = make_str("drop default"); } ; @@ -1090,10 +1090,6 @@ ColConstraintElem: NOT NULL_P { $$ = cat_str(3, make_str("check ("), $3, make_str(")")); } - | DEFAULT NULL_P - { - $$ = make_str("default null"); - } | DEFAULT b_expr { $$ = cat2_str(make_str("default"), $2); @@ -1529,46 +1525,46 @@ TruncateStmt: TRUNCATE opt_table relation_name * *****************************************************************************/ -FetchStmt: FETCH direction fetch_how_many from_in name INTO into_list +FetchStmt: FETCH direction fetch_how_many from_in name INTO into_list { if (strcmp($2, "relative") == 0 && atol($3) == 0L) mmerror(ET_ERROR, "FETCH/RELATIVE at current position is not supported"); $$ = cat_str(5, make_str("fetch"), $2, $3, $4, $5); } - | FETCH fetch_how_many from_in name INTO into_list + | FETCH fetch_how_many from_in name INTO into_list { $$ = cat_str(4, make_str("fetch"), $2, $3, $4); } - | FETCH direction from_in name INTO into_list + | FETCH direction from_in name INTO into_list { $$ = cat_str(4, make_str("fetch"), $2, $3, $4); } - | FETCH from_in name INTO into_list + | FETCH from_in name INTO into_list { $$ = cat_str(3, make_str("fetch"), $2, $3); } - | FETCH name INTO into_list + | FETCH name INTO into_list { $$ = cat2_str(make_str("fetch"), $2); } - | MOVE direction fetch_how_many from_in name + | MOVE direction fetch_how_many from_in name { $$ = cat_str(5, make_str("move"), $2, $3, $4, $5); } - | MOVE fetch_how_many from_in name + | MOVE fetch_how_many from_in name { $$ = cat_str(4, make_str("move"), $2, $3, $4); } - | MOVE direction from_in name + | MOVE direction from_in name { $$ = cat_str(4, make_str("move"), $2, $3, $4); } - | MOVE from_in name + | MOVE from_in name { $$ = cat_str(3, make_str("move"), $2, $3); } - | MOVE name + | MOVE name { $$ = cat2_str(make_str("move"), $2); } @@ -2119,9 +2115,9 @@ opt_trans: WORK { $$ = ""; } * *****************************************************************************/ -ViewStmt: CREATE VIEW name AS SelectStmt +ViewStmt: CREATE VIEW name opt_column_list AS SelectStmt { - $$ = cat_str(4, make_str("create view"), $3, make_str("as"), $5); + $$ = cat_str(5, make_str("create view"), $3, $4, make_str("as"), $6); } ; @@ -3093,10 +3089,11 @@ character: CHARACTER opt_varying opt_charset { $$ = cat_str(3, make_str("character"), $2, $3); } - | CHAR opt_varying { $$ = cat2_str(make_str("char"), $2); } - | VARCHAR { $$ = make_str("varchar"); } - | NATIONAL CHARACTER opt_varying { $$ = cat2_str(make_str("national character"), $3); } - | NCHAR opt_varying { $$ = cat2_str(make_str("nchar"), $2); } + | CHAR opt_varying { $$ = cat2_str(make_str("char"), $2); } + | VARCHAR { $$ = make_str("varchar"); } + | NATIONAL CHARACTER opt_varying { $$ = cat2_str(make_str("national character"), $3); } + | NATIONAL CHAR opt_varying { $$ = cat2_str(make_str("national char"), $3); } + | NCHAR opt_varying { $$ = cat2_str(make_str("nchar"), $2); } ; opt_varying: VARYING { $$ = make_str("varying"); } @@ -3119,9 +3116,9 @@ Datetime: datetime { $$ = cat2_str(make_str("timestamp"), $2); } - | TIME + | TIME opt_timezone { - $$ = make_str("time"); + $$ = cat2_str(make_str("time"), $2); } | INTERVAL opt_interval { @@ -3159,14 +3156,6 @@ opt_interval: datetime { $$ = $1; } * *****************************************************************************/ -a_expr_or_null: a_expr - { $$ = $1; } - | NULL_P - { - $$ = make_str("null"); - } - ; - /* Expressions using row descriptors * Define row_descriptor to allow yacc to break the reduce/reduce conflict * with singleton expressions. @@ -3191,6 +3180,10 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')' { $$ = cat_str(7, make_str("("), $2, make_str(")"), $4, make_str("("), $6, make_str(")")); } + | '(' row_descriptor ')' OVERLAPS '(' row_descriptor ')' + { + $$ = cat_str(5, make_str("("), $2, make_str(") overlaps ("), $6, make_str(")")); + } ; row_descriptor: row_list ',' a_expr @@ -3248,14 +3241,6 @@ a_expr: c_expr { $$ = $1; } | a_expr TYPECAST Typename { $$ = cat_str(3, $1, make_str("::"), $3); } - /* - * Can't collapse this into prior rule by using a_expr_or_null; - * that creates reduce/reduce conflicts. Grumble. - */ - | NULL_P TYPECAST Typename - { - $$ = cat2_str(make_str("null::"), $3); - } /* * These operators must be called out explicitly in order to make use * of yacc/bison's automatic operator-precedence handling. All other @@ -3302,11 +3287,6 @@ a_expr: c_expr { $$ = cat_str(3, $1, make_str("<"), $3); } | a_expr '>' a_expr { $$ = cat_str(3, $1, make_str(">"), $3); } - | a_expr '=' NULL_P - { $$ = cat2_str($1, make_str("= NULL")); } - /* We allow this for standards-broken SQL products, like MS stuff */ - | NULL_P '=' a_expr - { $$ = cat2_str(make_str("= NULL"), $3); } | a_expr '=' a_expr { $$ = cat_str(3, $1, make_str("="), $3); } | a_expr Op a_expr @@ -3376,7 +3356,7 @@ a_expr: c_expr * * b_expr is a subset of the complete expression syntax * - * Presently, AND, NOT, IS, IN, and NULL are the a_expr keywords that would + * Presently, AND, NOT, IS and IN are the a_expr keywords that would * cause trouble in the places where b_expr is used. For simplicity, we * just eliminate all the boolean-keyword-operator productions from b_expr. */ @@ -3388,10 +3368,6 @@ b_expr: c_expr { $$ = cat_str(3, $1, make_str("::"), $3); } - | NULL_P TYPECAST Typename - { - $$ = cat2_str(make_str("null::"), $3); - } | '-' b_expr %prec UMINUS { $$ = cat2_str(make_str("-"), $2); } | '%' b_expr @@ -3455,9 +3431,9 @@ c_expr: attr { $$ = cat2_str($1, $2); } | AexprConst { $$ = $1; } - | '(' a_expr_or_null ')' + | '(' a_expr ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); } - | CAST '(' a_expr_or_null AS Typename ')' + | CAST '(' a_expr AS Typename ')' { $$ = cat_str(5, make_str("cast("), $3, make_str("as"), $5, make_str(")")); } | case_expr { $$ = $1; } @@ -3539,9 +3515,9 @@ opt_indirection: '[' a_expr ']' opt_indirection { $$ = EMPTY; } ; -expr_list: a_expr_or_null +expr_list: a_expr { $$ = $1; } - | expr_list ',' a_expr_or_null + | expr_list ',' a_expr { $$ = cat_str(3, $1, make_str(","), $3); } | expr_list USING a_expr { $$ = cat_str(3, $1, make_str("using"), $3); } @@ -3648,13 +3624,13 @@ when_clause_list: when_clause_list when_clause { $$ = $1; } ; -when_clause: WHEN a_expr THEN a_expr_or_null +when_clause: WHEN a_expr THEN a_expr { $$ = cat_str(4, make_str("when"), $2, make_str("then"), $4); } ; -case_default: ELSE a_expr_or_null { $$ = cat2_str(make_str("else"), $2); } +case_default: ELSE a_expr { $$ = cat2_str(make_str("else"), $2); } | /*EMPTY*/ { $$ = EMPTY; } ; @@ -3698,11 +3674,11 @@ target_list: target_list ',' target_el ; /* AS is not optional because shift/red conflict with unary ops */ -target_el: a_expr_or_null AS ColLabel +target_el: a_expr AS ColLabel { $$ = cat_str(3, $1, make_str("as"), $3); } - | a_expr_or_null + | a_expr { $$ = $1; } @@ -3724,7 +3700,7 @@ update_target_list: update_target_list ',' update_target_el | '*' { $$ = make_str("*"); } ; -update_target_el: ColId opt_indirection '=' a_expr_or_null +update_target_el: ColId opt_indirection '=' a_expr { $$ = cat_str(4, $1, $2, make_str("="), $4); } @@ -3801,6 +3777,10 @@ AexprConst: Iconst { $$ = make_str("false"); } + | NULL_P + { + $$ = make_str("null"); + } ; ParamNo: PARAM opt_indirection @@ -4935,6 +4915,7 @@ ECPGColId: /* to be used instead of ColId */ | ONLY { $$ = make_str("only"); } | OPERATOR { $$ = make_str("operator"); } | OPTION { $$ = make_str("option"); } + | OVERLAPS { $$ = make_str("overlaps"); } | PASSWORD { $$ = make_str("password"); } | PENDANT { $$ = make_str("pendant"); } | PRIOR { $$ = make_str("prior"); }