*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.127 2004/03/02 06:45:05 meskes Exp $
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.128 2004/05/05 15:03:04 meskes Exp $
*
*-------------------------------------------------------------------------
*/
extern YYSTYPE yylval;
static int xcdepth = 0; /* depth of nesting in slash-star comments */
+static char *dolqstart; /* current $foo$ quote start string */
/*
* literalbuf is used to accumulate literal values when multiple rules
* <xd> delimited identifiers (double-quoted identifiers) - thomas 1997-10-27
* <xh> hexadecimal numeric string - thomas 1997-11-16
* <xq> quoted strings - thomas 1997-07-30
+ * <xdolq> $foo$ quoted strings
*/
%x xb
%x xdc
%x xh
%x xq
+%x xdolq
%x xpre
%x xcond
%x xskip
xch 0[xX][0-9A-Fa-f]*
/* Extended quote
- * xqdouble implements SQL92 embedded quote
+ * xqdouble implements embedded quote
* xqcat allows strings to cross input lines
*/
quote '
xqoctesc [\\][0-7]{1,3}
xqcat {quote}{whitespace_with_newline}{quote}
+/* $foo$ style quotes ("dollar quoting")
+ * The quoted string starts with $foo$ where "foo" is an optional string
+ * in the form of an identifier, except that it may not contain "$",
+ * and extends to the first occurrence of an identical string.
+ * There is *no* processing of the quoted text.
+ */
+dolq_start [A-Za-z\200-\377_]
+dolq_cont [A-Za-z\200-\377_0-9]
+dolqdelim \$({dolq_start}{dolq_cont}*)?\$
+dolqinside [^$]+
+
/* Double quote
* Allows embedded spaces and other special characters into identifiers.
*/
* 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.
+ * Dash-dash comments have similar interactions with the operator rule.
*/
xcstart \/\*{op_chars}*
xcstop \*+\/
cppline {space}*#(.*\\{space})+.*
/*
- * Quoted strings must allow some special characters such as single-quote
+ * Dollar quoted strings are totally opaque, and no escaping is done on them.
+ * Other quoted strings must allow some special characters such as single-quote
* and newline.
- * Embedded single-quotes are implemented both in the SQL92-standard
+ * Embedded single-quotes are implemented both in the SQL 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
BEGIN(SQL);
if (literalbuf[strspn(literalbuf, "01") + 1] != '\0')
mmerror(PARSE_ERROR, ET_ERROR, "invalid bit string input.");
- yylval.str = literalbuf;
+ yylval.str = mm_strdup(literalbuf);
return BCONST;
}
addlitchar('x');
}
<xh>{xhstop} {
- yylval.str = literalbuf;
+ yylval.str = mm_strdup(literalbuf);
return XCONST;
}
<xq>{xqescape} { addlit(yytext, yyleng); }
<xq>{xqoctesc} { addlit(yytext, yyleng); }
<xq>{xqcat} { /* ignore */ }
-
+<xq>. {
+ /* This is only needed for \ just before EOF */
+ addlitchar(yytext[0]);
+ }
<xq><<EOF>> { mmerror(PARSE_ERROR, ET_FATAL, "Unterminated quoted string"); }
+<SQL>{dolqdelim} {
+ token_start = yytext;
+ dolqstart = mm_strdup(yytext);
+ BEGIN(xdolq);
+ startlit();
+ }
+<xdolq>{dolqdelim} {
+ if (strcmp(yytext, dolqstart) == 0)
+ {
+ free(dolqstart);
+ BEGIN(SQL);
+ yylval.str = mm_strdup(literalbuf);
+ return SCONST;
+ }
+ else
+ {
+ /*
+ * When we fail to match $...$ to dolqstart, transfer
+ * the $... part to the output, but put back the final
+ * $ for rescanning. Consider $delim$...$junk$delim$
+ */
+ addlit(yytext, yyleng-1);
+ yyless(yyleng-1);
+ }
+ }
+<xdolq>{dolqinside} {
+ addlit(yytext, yyleng);
+ }
+<xdolq>. {
+ /* This is only needed for $ inside the quoted text */
+ addlitchar(yytext[0]);
+ }
+<xdolq><<EOF>> { yyerror("unterminated dollar-quoted string"); }
<SQL>{xdstart} {
state_before = YYSTATE;
BEGIN(state_before);
if (literallen == 0)
mmerror(PARSE_ERROR, ET_ERROR, "zero-length delimited identifier");
+ /* The backend will truncate the idnetifier here. We do not as it does not change the result. */
yylval.str = mm_strdup(literalbuf);
return CSTRING;
}
nchars = slashstar - yytext;
/*
- * For SQL92 compatibility, '+' and '-' cannot be the
+ * For SQL compatibility, '+' and '-' cannot be the
* last char of a multi-char operator unless the operator
- * contains chars that are not in SQL92 operators.
+ * contains chars that are not in SQL operators.
* The idea is to lex '=-' as two operators, but not
* to forbid operator names like '?-' that could not be
- * sequences of SQL92 operators.
+ * sequences of SQL operators.
*/
while (nchars > 1 &&
(yytext[nchars-1] == '+' ||
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.278 2004/04/29 14:08:10 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.279 2004/05/05 15:03:04 meskes Exp $ */
/* Copyright comment */
%{
if (atoi(ptr->variable->type->size) > 1)
{
- ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ECPGtype_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size), 0);
+ ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ECPGtype_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, make_str("1")), ptr->variable->type->size), 0);
sprintf(temp, "%d, (", ecpg_informix_var++);
}
else
%type <str> TableConstraint OptTableElementList Xconst opt_transaction
%type <str> ConstraintElem key_actions ColQualList type_name
%type <str> target_list target_el update_target_list alias_clause
-%type <str> update_target_el qualified_name database_name
+%type <str> update_target_el qualified_name database_name alter_using
%type <str> access_method attr_name index_name name func_name
%type <str> file_name AexprConst c_expr ConstTypename var_list
%type <str> a_expr b_expr TruncateStmt CommentStmt OnCommitOption opt_by
%type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
%type <str> FetchStmt from_in CreateOpClassStmt like_including_defaults
%type <str> ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
-%type <str> opt_full func_arg OptWithOids opt_freeze
+%type <str> opt_full func_arg OptWithOids opt_freeze alter_table_cmd
%type <str> analyze_keyword opt_name_list ExplainStmt index_params
-%type <str> index_elem opt_class access_method_clause
+%type <str> index_elem opt_class access_method_clause alter_table_cmds
%type <str> index_opt_unique IndexStmt func_return ConstInterval
%type <str> func_args_list func_args opt_with def_arg overlay_placing
%type <str> def_elem def_list definition DefineStmt select_with_parens
%type <str> opt_instead event RuleActionList opt_using CreateAssertStmt
%type <str> RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type
-%type <str> RuleStmt opt_column opt_name oper_argtypes NumConst
+%type <str> RuleStmt opt_column oper_argtypes NumConst
%type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause
%type <str> RemoveAggrStmt opt_procedural select_no_parens CreateCastStmt
%type <str> RemoveOperStmt RenameStmt all_Op opt_Trusted opt_lancompiler
*****************************************************************************/
AlterTableStmt:
+ ALTER TABLE relation_expr alter_table_cmds
+ { $$ = cat_str(3, make_str("alter table"), $3, $4); }
+ ;
+
+alter_table_cmds:
+ alter_table_cmd { $$ = $1; }
+ | alter_table_cmds ',' alter_table_cmd { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+alter_table_cmd:
+ ADD opt_column columnDef
/* ALTER TABLE <relation> ADD [COLUMN] <coldef> */
- ALTER TABLE relation_expr ADD opt_column columnDef
- { $$ = cat_str(5, make_str("alter table"), $3, make_str("add"), $5, $6); }
+ { $$ = cat_str(3, make_str("add"), $2, $3); }
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
- | ALTER TABLE relation_expr ALTER opt_column ColId alter_column_default
- { $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, $7); }
+ | ALTER opt_column ColId alter_column_default
+ { $$ = cat_str(4, make_str("alter"), $2, $3, $4); }
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> DROP NOT NULL */
- | ALTER TABLE relation_expr ALTER opt_column ColId DROP NOT NULL_P
- { $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("drop not null")); }
+ | ALTER opt_column ColId DROP NOT NULL_P
+ { $$ = cat_str(4, make_str("alter"), $2, $3, make_str("drop not null")); }
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET NOT NULL */
- | ALTER TABLE relation_expr ALTER opt_column ColId SET NOT NULL_P
- { $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set not null")); }
+ | ALTER opt_column ColId SET NOT NULL_P
+ { $$ = cat_str(4, make_str("alter"), $2, $3, make_str("set not null")); }
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STATISTICS <IntegerOnly> */
- | ALTER TABLE relation_expr ALTER opt_column ColId SET STATISTICS PosIntConst
- { $$ = cat_str(7, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set statistics"), $9); }
+ | ALTER opt_column ColId SET STATISTICS PosIntConst
+ { $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set statistics"), $6); }
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
- | ALTER TABLE relation_expr ALTER opt_column ColId SET STORAGE ColId
- { $$ = cat_str(7, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set storage"), $9); }
+ | ALTER opt_column ColId SET STORAGE ColId
+ { $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set storage"), $6); }
/* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
- | ALTER TABLE relation_expr DROP opt_column ColId opt_drop_behavior
- { $$ = cat_str(6, make_str("alter table"), $3, make_str("drop"), $5, $6, $7); }
+ | DROP opt_column ColId opt_drop_behavior
+ { $$ = cat_str(4, make_str("drop"), $2, $3, $4); }
+/* ALTER TABLE <relation> ALTER [COLUMN] <colname> TYPE <typename> [ USING <expression> ] */
+ | ALTER opt_column ColId TYPE_P Typename alter_using
+ { $$ = cat_str(6, make_str("alter"), $2, $3, make_str("type"), $5, $6); }
/* ALTER TABLE <relation> ADD CONSTRAINT ... */
- | ALTER TABLE relation_expr ADD TableConstraint
- { $$ = cat_str(4, make_str("alter table"), $3, make_str("add"), $5); }
+ | ADD TableConstraint
+ { $$ = cat_str(2, make_str("add"), $2); }
/* ALTER TABLE <relation> DROP CONSTRAINT ... */
- | ALTER TABLE relation_expr DROP CONSTRAINT name opt_drop_behavior
- { $$ = cat_str(5, make_str("alter table"), $3, make_str("drop constraint"), $6, $7); }
+ | DROP CONSTRAINT name opt_drop_behavior
+ { $$ = cat_str(3, make_str("drop constraint"), $3, $4); }
/* ALTER TABLE <relation> SET WITHOUT OIDS */
- | ALTER TABLE relation_expr SET WITHOUT OIDS
- { $$ = cat_str(3, make_str("alter table"), $3, make_str("set without oids")); }
+ | SET WITHOUT OIDS
+ { $$ = make_str("set without oids"); }
/* ALTER TABLE <name> CREATE TOAST TABLE */
- | ALTER TABLE qualified_name CREATE TOAST TABLE
- { $$ = cat_str(3, make_str("alter table"), $3, make_str("create toast table")); }
+ | CREATE TOAST TABLE
+ { $$ = make_str("create toast table"); }
/* ALTER TABLE <name> OWNER TO UserId */
- | ALTER TABLE qualified_name OWNER TO UserId
- { $$ = cat_str(4, make_str("alter table"), $3, make_str("owner to"), $6); }
+ | OWNER TO UserId
+ { $$ = cat_str(2, make_str("owner to"), $3); }
/* ALTER TABLE <name> CLUSTER ON <indexname> */
- | ALTER TABLE qualified_name CLUSTER ON name
- { $$ = cat_str(4, make_str("alter table"), $3, make_str("cluster on"), $6); }
+ | CLUSTER ON name
+ { $$ = cat_str(2, make_str("cluster on"), $3); }
;
alter_column_default:
| /* EMPTY */ { $$ = EMPTY; }
;
+alter_using: USING a_expr { $$ = cat2_str(make_str("using"), $2); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
/*****************************************************************************
*
* QUERY :
{ $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("rename to"), $9); }
| ALTER SCHEMA name RENAME TO name
{ $$ = cat_str(4, make_str("alter schema"), $3, make_str("rename to"), $6); }
- | ALTER TABLE relation_expr RENAME opt_column opt_name TO name
+ | ALTER TABLE relation_expr RENAME TO name
+ { $$ = cat_str(4, make_str("alter table"), $3, make_str("rename to"), $6); }
+ | ALTER TABLE relation_expr RENAME opt_column name TO name
{ $$ = cat_str(7, make_str("alter table"), $3, make_str("rename"), $5, $6, make_str("to"), $8); }
| ALTER TRIGGER name ON relation_expr RENAME TO name
{ $$ = cat_str(6, make_str("alter trigger"), $3, make_str("on"), $5, make_str("rename to"), $8); }
{ $$ = cat_str(4, make_str("alter user"), $3, make_str("rename to"), $6); }
;
-opt_name: name { $$ = $1; }
- | /*EMPTY*/ { $$ = EMPTY; }
- ;
-
opt_column: COLUMN { $$ = make_str("column"); }
| /*EMPTY*/ { $$ = EMPTY; }
;