*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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 ([^*]+)|(\*+[^/])
typecast "::"
+/* NB: if you change "self", fix the copy in the operator rule too! */
self [,()\[\].;$\:\+\-\*\/\%\^\<\>\=\|]
op_and_self [\~\!\@\#\^\&\|\`\?\$\:\+\-\*\/\%\<\>\=]
operator {op_and_self}+
*
* 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.
*/
%%
<SQL>{whitespace} { /* ignore */ }
-{xcline} { ECHO; }
-
{xcstart} {
state_before = YYSTATE;
ECHO;
BEGIN(xc);
+ /* Put back any characters past slash-star; see above */
+ yyless(2);
}
<xc>{xcstop} { ECHO; BEGIN(state_before); }
<xc>{xcinside} { ECHO; }
+<xc><<EOF>> { mmerror(ET_ERROR, "Unterminated /* comment"); }
+
<SQL>{xbstart} {
BEGIN(xb);
startlit();
mmerror(ET_ERROR, "Bad binary integer input!");
return ICONST;
}
+<xb><<EOF>> { mmerror(ET_ERROR, "Unterminated binary integer"); }
+
<xh>{xhinside} |
<xb>{xbinside} {
addlit(yytext, yyleng);
return ICONST;
}
+<xb><<EOF>> { mmerror(ET_ERROR, "Unterminated hexadecimal integer"); }
+
{xqstart} {
state_before = YYSTATE;
BEGIN(xq);
/* ignore */
}
+<xq><<EOF>> { mmerror(ET_ERROR, "Unterminated quoted string"); }
+
{xdstart} {
state_before = YYSTATE;
BEGIN(xd);
<xd>{xdinside} {
addlit(yytext, yyleng);
}
+<xq><<EOF>> { mmerror(ET_ERROR, "Unterminated quoted identifier"); }
<SQL>{typecast} { return TYPECAST; }
<SQL>{self} { /*
* We may find a ';' inside a structure
return yytext[0];
}
<SQL>{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);
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,
%right '='
%nonassoc '<' '>'
%nonassoc LIKE
+%nonassoc OVERLAPS
%nonassoc BETWEEN
%nonassoc IN
%left Op /* multi-character ops and user-defined operators */
%type <str> Typename SimpleTypename Generic Numeric generic opt_float opt_numeric
%type <str> opt_decimal Character character opt_varying opt_charset
%type <str> opt_collate Datetime datetime opt_timezone opt_interval
-%type <str> numeric a_expr_or_null row_expr row_descriptor row_list
+%type <str> numeric row_expr row_descriptor row_list
%type <str> SelectStmt SubSelect result OptTemp ConstraintAttributeSpec
%type <str> opt_table opt_all sort_clause sortby_list ConstraintAttr
%type <str> sortby OptUseOp opt_inh_star relation_name_list name_list
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"); }
;
{
$$ = 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);
*
*****************************************************************************/
-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);
}
*
*****************************************************************************/
-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);
}
;
{
$$ = 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"); }
{
$$ = cat2_str(make_str("timestamp"), $2);
}
- | TIME
+ | TIME opt_timezone
{
- $$ = make_str("time");
+ $$ = cat2_str(make_str("time"), $2);
}
| INTERVAL opt_interval
{
*
*****************************************************************************/
-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.
{
$$ = 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
{ $$ = $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
{ $$ = 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
*
* 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.
*/
{
$$ = 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
{ $$ = 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; }
{ $$ = 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); }
{ $$ = $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; }
;
;
/* 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;
}
| '*' { $$ = 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);
}
{
$$ = make_str("false");
}
+ | NULL_P
+ {
+ $$ = make_str("null");
+ }
;
ParamNo: PARAM opt_indirection
| 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"); }