Thread: help with bison

help with bison

From
Neil Conway
Date:
Hi all,

I'm working on a fairly large patch (cleaning up Karel Zak's
PREPARE/EXECUTE work), and I'm having some problems with bison (I'm
a yacc newbie). In fact, my grammar currently has an obscene
20 shift/reduce and 4 reduce/reduce conflicts!

Would someone to be kind enough to let me know what I'm doing wrong,
and what I'll need to change? (Unfortunately, bison isn't very
helpful: it doesn't provide line-numbers when it warns me about
the # of conflicts). The patch for gram.y is below.

Thanks in advance,

Neil

-- 
Neil Conway <neilconway@rogers.com>
PGP Key ID: DB3C29FC

Index: gram.y
===================================================================
RCS file: /var/lib/cvs/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.299
diff -c -r2.299 gram.y
*** gram.y    1 Apr 2002 04:35:38 -0000    2.299
--- gram.y    11 Apr 2002 01:26:21 -0000
***************
*** 133,144 ****         ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt,         CopyStmt, CreateAsStmt,
CreateDomainStmt,CreateGroupStmt, CreatePLangStmt,         CreateSchemaStmt, CreateSeqStmt, CreateStmt,
CreateTrigStmt,
!         CreateUserStmt, CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt,
!         DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt,
!         DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,         GrantStmt, IndexStmt, InsertStmt, ListenStmt,
LoadStmt,LockStmt,
 
!         NotifyStmt, OptimizableStmt, ProcedureStmt, ReindexStmt,
!         RemoveAggrStmt, RemoveFuncStmt, RemoveOperStmt,         RenameStmt, RevokeStmt, RuleActionStmt,
RuleActionStmtOrEmpty,        RuleStmt, SelectStmt, TransactionStmt, TruncateStmt,         UnlistenStmt, UpdateStmt,
VacuumStmt,VariableResetStmt,
 
--- 133,145 ----         ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt,         CopyStmt, CreateAsStmt,
CreateDomainStmt,CreateGroupStmt, CreatePLangStmt,         CreateSchemaStmt, CreateSeqStmt, CreateStmt,
CreateTrigStmt,
!         CreateUserStmt, CreatedbStmt, CursorStmt, DeallocatePrepareStmt,
!         DefineStmt, DeleteStmt, DropGroupStmt,
!         DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt,
!         DropUserStmt, DropdbStmt, ExecuteStmt, ExplainStmt, FetchStmt,         GrantStmt, IndexStmt, InsertStmt,
ListenStmt,LoadStmt, LockStmt,
 
!         NotifyStmt, OptimizableStmt, ProcedureStmt, PrepareStmt, prepare_query,
!         ReindexStmt, RemoveAggrStmt, RemoveFuncStmt, RemoveOperStmt,         RenameStmt, RevokeStmt, RuleActionStmt,
RuleActionStmtOrEmpty,        RuleStmt, SelectStmt, TransactionStmt, TruncateStmt,         UnlistenStmt, UpdateStmt,
VacuumStmt,VariableResetStmt,
 
***************
*** 204,210 ****         any_name, any_name_list, expr_list, dotted_name, attrs,         target_list,
update_target_list,insert_column_list,         def_list, opt_indirection, group_clause, TriggerFuncArgs,
 
!         select_limit, opt_select_limit  %type <range>    into_clause, OptTempTableName 
--- 205,214 ----         any_name, any_name_list, expr_list, dotted_name, attrs,         target_list,
update_target_list,insert_column_list,         def_list, opt_indirection, group_clause, TriggerFuncArgs,
 
!         select_limit, opt_select_limit, types_list,
!         types_prepare_clause, execute_using
! 
! %type <ival>    prepare_store  %type <range>    into_clause, OptTempTableName 
***************
*** 319,325 ****         COALESCE, COLLATE, COLUMN, COMMIT,         CONSTRAINT, CONSTRAINTS, CREATE, CROSS,
CURRENT_DATE,        CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
 
!         DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC,         DISTINCT, DOUBLE, DROP,         ELSE, ENCRYPTED,
END_TRANS,ESCAPE, EXCEPT, EXECUTE, EXISTS, EXTRACT,         FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
 
--- 323,329 ----         COALESCE, COLLATE, COLUMN, COMMIT,         CONSTRAINT, CONSTRAINTS, CREATE, CROSS,
CURRENT_DATE,        CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
 
!         DAY_P, DEALLOCATE, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC,         DISTINCT, DOUBLE, DROP,
ELSE,ENCRYPTED, END_TRANS, ESCAPE, EXCEPT, EXECUTE, EXISTS, EXTRACT,         FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM,
FULL,
***************
*** 329,335 ****         MATCH, MINUTE_P, MONTH_P, NAMES,         NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF,
NULL_P,NUMERIC,         OF, OLD, ON, ONLY, OPTION, OR, ORDER, OUTER_P, OVERLAPS,
 
!         PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,         READ, REFERENCES,
RELATIVE,REVOKE, RIGHT, ROLLBACK,         SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET, SOME,
SUBSTRING,        TABLE, TEMPORARY, THEN, TIME, TIMESTAMP,
 
--- 333,339 ----         MATCH, MINUTE_P, MONTH_P, NAMES,         NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF,
NULL_P,NUMERIC,         OF, OLD, ON, ONLY, OPTION, OR, ORDER, OUTER_P, OVERLAPS,
 
!         PARTIAL, POSITION, PRECISION, PREPARE, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,         READ,
REFERENCES,RELATIVE, REVOKE, RIGHT, ROLLBACK,         SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET,
SOME,SUBSTRING,         TABLE, TEMPORARY, THEN, TIME, TIMESTAMP,
 
***************
*** 363,372 ****         DATABASE, DELIMITERS, DO,         EACH, ENCODING, EXCLUSIVE, EXPLAIN,         FORCE, FORWARD,
FREEZE,FUNCTION, HANDLER,
 
!         ILIKE, INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,         LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION,
LOCK_P,        MAXVALUE, MINVALUE, MODE, MOVE,
 
!         NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,         OFFSET, OIDS, OPERATOR, OWNER,
PASSWORD,PROCEDURAL,         REINDEX, RENAME, RESET, RETURNS, ROW, RULE,         SEQUENCE, SETOF, SHARE, SHOW, START,
STATEMENT,
--- 367,376 ----         DATABASE, DELIMITERS, DO,         EACH, ENCODING, EXCLUSIVE, EXPLAIN,         FORCE, FORWARD,
FREEZE,FUNCTION, HANDLER,
 
!         ILIKE, INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL, INTERNAL,         LANCOMPILER, LIMIT, LISTEN, LOAD,
LOCATION,LOCK_P,         MAXVALUE, MINVALUE, MODE, MOVE,
 
!         NEW, NOCREATEDB, NOCREATEUSER, NONE, NOSHARE, NOTHING, NOTIFY, NOTNULL,         OFFSET, OIDS, OPERATOR,
OWNER,PASSWORD, PROCEDURAL,         REINDEX, RENAME, RESET, RETURNS, ROW, RULE,         SEQUENCE, SETOF, SHARE, SHOW,
START,STATEMENT,
 
***************
*** 460,465 ****
--- 464,470 ----         | CreateTrigStmt         | CreateUserStmt         | ClusterStmt
+         | DeallocatePrepareStmt         | DefineStmt         | DropStmt                 | DropSchemaStmt
***************
*** 469,474 ****
--- 474,480 ----         | DropPLangStmt         | DropTrigStmt         | DropUserStmt
+         | ExecuteStmt         | ExplainStmt         | FetchStmt         | GrantStmt
***************
*** 477,482 ****
--- 483,489 ----         | UnlistenStmt         | LockStmt         | NotifyStmt
+         | PrepareStmt         | ProcedureStmt         | ReindexStmt         | RemoveAggrStmt
***************
*** 3489,3494 ****
--- 3496,3594 ----         | DeleteStmt                    /* by default all are $$=$1 */         ; 
+ /*****************************************************************************
+  *
+  *                PREPARE STATEMENTS
+  *
+  *****************************************************************************/
+ PrepareStmt:  PREPARE name AS prepare_query types_prepare_clause prepare_store
+                   {
+                     PrepareStmt *n = makeNode(PrepareStmt);
+                     n->name = $2;
+                     n->query = (Query *) $4;
+                     n->types = (List *) $5;
+                     n->store = $6;
+                     $$ = (Node *) n;
+                 }
+         ;
+ 
+ prepare_query:  SelectStmt
+         | UpdateStmt
+         | InsertStmt
+         | DeleteStmt
+         ;
+ 
+ types_list:  SimpleTypename
+                 { $$ = makeList1($1); }
+         | types_list ',' SimpleTypename
+                 { $$ = lappend($1, $3); }
+         ;
+ 
+ types_prepare_clause:  USING types_list        { $$ = $2; }
+         | /*EMPTY*/                            { $$ = NIL; }
+         ;
+ 
+ prepare_store: NOSHARE        { $$ = 1; }
+         | GLOBAL            { $$ = 2; }
+         | SHARE                { $$ = 0; }    /* default */
+         | /* EMPTY */        { $$ = 0; }
+         ;    
+ 
+ /*****************************************************************************
+  *
+  *                EXECUTE STATEMENTS
+  *
+  *****************************************************************************/
+ ExecuteStmt: EXECUTE name into_clause USING execute_using prepare_store
+                 {
+                     ExecuteStmt *n = makeNode(ExecuteStmt);
+                     n->name = $2;
+                     n->into = $3;
+                     n->using = $5;
+                     n->store = $6;
+                     $$ = (Node *) n;                    
+                 }
+         ;
+ 
+ execute_using: a_expr
+                 { $$ = makeList1($1); }
+         | execute_using ',' a_expr
+                 { $$ = lappend($1, $3); }
+         ;
+ 
+ /*****************************************************************************
+  *
+  *                DEALLOCATE PREPARE STATEMENTS
+  *
+  *****************************************************************************/
+ DeallocatePrepareStmt: DEALLOCATE PREPARE ALL
+                 {
+                     DeallocatePrepareStmt *n = makeNode(DeallocatePrepareStmt);
+                     n->name = NULL;
+                     n->store = 0;
+                     n->all = TRUE;
+                     n->internal = FALSE;
+                     $$ = (Node *) n;
+                 }
+         | DEALLOCATE PREPARE ALL INTERNAL
+                 {
+                     DeallocatePrepareStmt *n = makeNode(DeallocatePrepareStmt);
+                     n->name = NULL;
+                     n->store = 0;
+                     n->all = FALSE;
+                     n->internal = TRUE;
+                     $$ = (Node *) n;
+                 }
+         | DEALLOCATE PREPARE name prepare_store 
+                 {
+                     DeallocatePrepareStmt *n = makeNode(DeallocatePrepareStmt);
+                     n->name = $3;
+                     n->store = $4;
+                     n->all = FALSE;
+                     n->internal = FALSE;
+                     $$ = (Node *) n;
+                 }
+         ;  /*****************************************************************************  *


Re: help with bison

From
Tom Lane
Date:
Neil Conway <nconway@klamath.dyndns.org> writes:
> Unfortunately, bison isn't very
> helpful: it doesn't provide line-numbers when it warns me about
> the # of conflicts.

Run bison with -v switch (thus, "bison -y -d -v gram.y") and look at
the y.output file it produces.  More detail than you really wanted ;-)
        regards, tom lane


Re: help with bison

From
"Christopher Kings-Lynne"
Date:
I don't see in this patch that you've added your new keywords to any of the
lists of reserved words towards the bottom of gram.y.  Have a look down and
see the lists.  You need to add the keywords to the first list in the file
that doesn't give a shift/reduce error.  (ie. make the words the least
reserved as possible.)

Also, make sure you've put them in keywords.c as well.

Chris

> -----Original Message-----
> From: pgsql-hackers-owner@postgresql.org
> [mailto:pgsql-hackers-owner@postgresql.org]On Behalf Of Neil Conway
> Sent: Thursday, 11 April 2002 9:29 AM
> To: PostgreSQL Hackers
> Subject: [HACKERS] help with bison
>
>
> Hi all,
>
> I'm working on a fairly large patch (cleaning up Karel Zak's
> PREPARE/EXECUTE work), and I'm having some problems with bison (I'm
> a yacc newbie). In fact, my grammar currently has an obscene
> 20 shift/reduce and 4 reduce/reduce conflicts!
>
> Would someone to be kind enough to let me know what I'm doing wrong,
> and what I'll need to change? (Unfortunately, bison isn't very
> helpful: it doesn't provide line-numbers when it warns me about
> the # of conflicts). The patch for gram.y is below.
>
> Thanks in advance,
>
> Neil
>
> --
> Neil Conway <neilconway@rogers.com>
> PGP Key ID: DB3C29FC
>
> Index: gram.y
> ===================================================================
> RCS file: /var/lib/cvs/pgsql/src/backend/parser/gram.y,v
> retrieving revision 2.299
> diff -c -r2.299 gram.y
> *** gram.y    1 Apr 2002 04:35:38 -0000    2.299
> --- gram.y    11 Apr 2002 01:26:21 -0000
> ***************
> *** 133,144 ****
>           ClosePortalStmt, ClusterStmt, CommentStmt,
> ConstraintsSetStmt,
>           CopyStmt, CreateAsStmt, CreateDomainStmt,
> CreateGroupStmt, CreatePLangStmt,
>           CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt,
> !         CreateUserStmt, CreatedbStmt, CursorStmt,
> DefineStmt, DeleteStmt,
> !         DropGroupStmt, DropPLangStmt, DropSchemaStmt,
> DropStmt, DropTrigStmt,
> !         DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
>           GrantStmt, IndexStmt, InsertStmt, ListenStmt,
> LoadStmt, LockStmt,
> !         NotifyStmt, OptimizableStmt, ProcedureStmt, ReindexStmt,
> !         RemoveAggrStmt, RemoveFuncStmt, RemoveOperStmt,
>           RenameStmt, RevokeStmt, RuleActionStmt,
> RuleActionStmtOrEmpty,
>           RuleStmt, SelectStmt, TransactionStmt, TruncateStmt,
>           UnlistenStmt, UpdateStmt, VacuumStmt, VariableResetStmt,
> --- 133,145 ----
>           ClosePortalStmt, ClusterStmt, CommentStmt,
> ConstraintsSetStmt,
>           CopyStmt, CreateAsStmt, CreateDomainStmt,
> CreateGroupStmt, CreatePLangStmt,
>           CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt,
> !         CreateUserStmt, CreatedbStmt, CursorStmt,
> DeallocatePrepareStmt,
> !         DefineStmt, DeleteStmt, DropGroupStmt,
> !         DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt,
> !         DropUserStmt, DropdbStmt, ExecuteStmt, ExplainStmt,
> FetchStmt,
>           GrantStmt, IndexStmt, InsertStmt, ListenStmt,
> LoadStmt, LockStmt,
> !         NotifyStmt, OptimizableStmt, ProcedureStmt,
> PrepareStmt, prepare_query,
> !         ReindexStmt, RemoveAggrStmt, RemoveFuncStmt, RemoveOperStmt,
>           RenameStmt, RevokeStmt, RuleActionStmt,
> RuleActionStmtOrEmpty,
>           RuleStmt, SelectStmt, TransactionStmt, TruncateStmt,
>           UnlistenStmt, UpdateStmt, VacuumStmt, VariableResetStmt,
> ***************
> *** 204,210 ****
>           any_name, any_name_list, expr_list, dotted_name, attrs,
>           target_list, update_target_list, insert_column_list,
>           def_list, opt_indirection, group_clause, TriggerFuncArgs,
> !         select_limit, opt_select_limit
>
>   %type <range>    into_clause, OptTempTableName
>
> --- 205,214 ----
>           any_name, any_name_list, expr_list, dotted_name, attrs,
>           target_list, update_target_list, insert_column_list,
>           def_list, opt_indirection, group_clause, TriggerFuncArgs,
> !         select_limit, opt_select_limit, types_list,
> !         types_prepare_clause, execute_using
> !
> ! %type <ival>    prepare_store
>
>   %type <range>    into_clause, OptTempTableName
>
> ***************
> *** 319,325 ****
>           COALESCE, COLLATE, COLUMN, COMMIT,
>           CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT_DATE,
>           CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
> !         DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC,
>           DISTINCT, DOUBLE, DROP,
>           ELSE, ENCRYPTED, END_TRANS, ESCAPE, EXCEPT,
> EXECUTE, EXISTS, EXTRACT,
>           FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
> --- 323,329 ----
>           COALESCE, COLLATE, COLUMN, COMMIT,
>           CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT_DATE,
>           CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
> !         DAY_P, DEALLOCATE, DEC, DECIMAL, DECLARE, DEFAULT,
> DELETE, DESC,
>           DISTINCT, DOUBLE, DROP,
>           ELSE, ENCRYPTED, END_TRANS, ESCAPE, EXCEPT,
> EXECUTE, EXISTS, EXTRACT,
>           FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
> ***************
> *** 329,335 ****
>           MATCH, MINUTE_P, MONTH_P, NAMES,
>           NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF,
> NULL_P, NUMERIC,
>           OF, OLD, ON, ONLY, OPTION, OR, ORDER, OUTER_P, OVERLAPS,
> !         PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR,
> PRIVILEGES, PROCEDURE, PUBLIC,
>           READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
>           SCHEMA, SCROLL, SECOND_P, SELECT, SESSION,
> SESSION_USER, SET, SOME, SUBSTRING,
>           TABLE, TEMPORARY, THEN, TIME, TIMESTAMP,
> --- 333,339 ----
>           MATCH, MINUTE_P, MONTH_P, NAMES,
>           NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF,
> NULL_P, NUMERIC,
>           OF, OLD, ON, ONLY, OPTION, OR, ORDER, OUTER_P, OVERLAPS,
> !         PARTIAL, POSITION, PRECISION, PREPARE, PRIMARY,
> PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
>           READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
>           SCHEMA, SCROLL, SECOND_P, SELECT, SESSION,
> SESSION_USER, SET, SOME, SUBSTRING,
>           TABLE, TEMPORARY, THEN, TIME, TIMESTAMP,
> ***************
> *** 363,372 ****
>           DATABASE, DELIMITERS, DO,
>           EACH, ENCODING, EXCLUSIVE, EXPLAIN,
>           FORCE, FORWARD, FREEZE, FUNCTION, HANDLER,
> !         ILIKE, INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
>           LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
>           MAXVALUE, MINVALUE, MODE, MOVE,
> !         NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING,
> NOTIFY, NOTNULL,
>           OFFSET, OIDS, OPERATOR, OWNER, PASSWORD, PROCEDURAL,
>           REINDEX, RENAME, RESET, RETURNS, ROW, RULE,
>           SEQUENCE, SETOF, SHARE, SHOW, START, STATEMENT,
> --- 367,376 ----
>           DATABASE, DELIMITERS, DO,
>           EACH, ENCODING, EXCLUSIVE, EXPLAIN,
>           FORCE, FORWARD, FREEZE, FUNCTION, HANDLER,
> !         ILIKE, INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
> INTERNAL,
>           LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
>           MAXVALUE, MINVALUE, MODE, MOVE,
> !         NEW, NOCREATEDB, NOCREATEUSER, NONE, NOSHARE,
> NOTHING, NOTIFY, NOTNULL,
>           OFFSET, OIDS, OPERATOR, OWNER, PASSWORD, PROCEDURAL,
>           REINDEX, RENAME, RESET, RETURNS, ROW, RULE,
>           SEQUENCE, SETOF, SHARE, SHOW, START, STATEMENT,
> ***************
> *** 460,465 ****
> --- 464,470 ----
>           | CreateTrigStmt
>           | CreateUserStmt
>           | ClusterStmt
> +         | DeallocatePrepareStmt
>           | DefineStmt
>           | DropStmt
>           | DropSchemaStmt
> ***************
> *** 469,474 ****
> --- 474,480 ----
>           | DropPLangStmt
>           | DropTrigStmt
>           | DropUserStmt
> +         | ExecuteStmt
>           | ExplainStmt
>           | FetchStmt
>           | GrantStmt
> ***************
> *** 477,482 ****
> --- 483,489 ----
>           | UnlistenStmt
>           | LockStmt
>           | NotifyStmt
> +         | PrepareStmt
>           | ProcedureStmt
>           | ReindexStmt
>           | RemoveAggrStmt
> ***************
> *** 3489,3494 ****
> --- 3496,3594 ----
>           | DeleteStmt                    /*
> by default all are $$=$1 */
>           ;
>
> +
> /*****************************************************************
> ************
> +  *
> +  *                PREPARE STATEMENTS
> +  *
> +
> ******************************************************************
> ***********/
> + PrepareStmt:  PREPARE name AS prepare_query
> types_prepare_clause prepare_store
> +                   {
> +                     PrepareStmt *n =
> makeNode(PrepareStmt);
> +                     n->name = $2;
> +                     n->query = (Query *) $4;
> +                     n->types = (List *) $5;
> +                     n->store = $6;
> +                     $$ = (Node *) n;
> +                 }
> +         ;
> +
> + prepare_query:  SelectStmt
> +         | UpdateStmt
> +         | InsertStmt
> +         | DeleteStmt
> +         ;
> +
> + types_list:  SimpleTypename
> +                 { $$ = makeList1($1); }
> +         | types_list ',' SimpleTypename
> +                 { $$ = lappend($1, $3); }
> +         ;
> +
> + types_prepare_clause:  USING types_list        { $$ = $2; }
> +         | /*EMPTY*/
>     { $$ = NIL; }
> +         ;
> +
> + prepare_store: NOSHARE        { $$ = 1; }
> +         | GLOBAL            { $$ = 2; }
> +         | SHARE                { $$ = 0; }    /*
> default */
> +         | /* EMPTY */        { $$ = 0; }
> +         ;
> +
> +
> /*****************************************************************
> ************
> +  *
> +  *                EXECUTE STATEMENTS
> +  *
> +
> ******************************************************************
> ***********/
> + ExecuteStmt: EXECUTE name into_clause USING execute_using prepare_store
> +                 {
> +                     ExecuteStmt *n =
> makeNode(ExecuteStmt);
> +                     n->name = $2;
> +                     n->into = $3;
> +                     n->using = $5;
> +                     n->store = $6;
> +                     $$ = (Node *) n;
>
> +                 }
> +         ;
> +
> + execute_using: a_expr
> +                 { $$ = makeList1($1); }
> +         | execute_using ',' a_expr
> +                 { $$ = lappend($1, $3); }
> +         ;
> +
> +
> /*****************************************************************
> ************
> +  *
> +  *                DEALLOCATE PREPARE STATEMENTS
> +  *
> +
> ******************************************************************
> ***********/
> + DeallocatePrepareStmt: DEALLOCATE PREPARE ALL
> +                 {
> +                     DeallocatePrepareStmt *n =
> makeNode(DeallocatePrepareStmt);
> +                     n->name = NULL;
> +                     n->store = 0;
> +                     n->all = TRUE;
> +                     n->internal = FALSE;
> +                     $$ = (Node *) n;
> +                 }
> +         | DEALLOCATE PREPARE ALL INTERNAL
> +                 {
> +                     DeallocatePrepareStmt *n =
> makeNode(DeallocatePrepareStmt);
> +                     n->name = NULL;
> +                     n->store = 0;
> +                     n->all = FALSE;
> +                     n->internal = TRUE;
> +                     $$ = (Node *) n;
> +                 }
> +         | DEALLOCATE PREPARE name prepare_store
> +                 {
> +                     DeallocatePrepareStmt *n =
> makeNode(DeallocatePrepareStmt);
> +                     n->name = $3;
> +                     n->store = $4;
> +                     n->all = FALSE;
> +                     n->internal = FALSE;
> +                     $$ = (Node *) n;
> +                 }
> +         ;
>
>
> /*****************************************************************
> ************
>    *
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/users-lounge/docs/faq.html
>



Re: help with bison

From
Bear Giles
Date:
> In fact, my grammar currently has an obscene
> 20 shift/reduce and 4 reduce/reduce conflicts!

A shift/reduce conflict, IIRC, usually indicates a situation where
the grammar is unambiguous but may be inefficient.  Eliminating them
is nice, but not critical.

A R/R conflict, in contrast, is a point where the grammar is ambiguous
and you *must* fix it.

> (Unfortunately, bison isn't very
> helpful: it doesn't provide line-numbers when it warns me about
> the # of conflicts).

Turn on the verbose flag (-v|--verbose).  Near the top it should
list the S/R and R/R states.  You can then examine the states and
rules and see exactly where the problem is.

Cutting to the chase, the R/R problems are due to "TEMP" and
"TEMPORARY" being both "unreserved keywords" and part of
OptTempTableName.  If you comment them out in 'unreserved keywords'
the R/R error goes away but this may introduce errors elsewhere.

What is probably better is to move those tokens someplace else
where there's some context:
 into_clause : INTO OptTempTableName| /* EMPTY */;

needs to be replaced with something like
 into_options : /* EMPTY */| TEMPORARY| TEMP;
 into_clause : INTO into_options OptTempTableName| /* EMPTY */;

with the corresponding modifiers removed from the OptTempTableName

Unfortunately, when I quickly tested that the number of S/R conflicts 
ballooned to 378.

As an aside, is there any reason to treat TEMP and TEMPORARY as two
separate identifiers?  It's common practice to have synonyms mapped
to a single identifier in the lexical analyzer, and the grammar itself
looks like it could benefit from some helper rules such as:
 temporary: TEMPORARY  { $$ = 1; }| TEMP         { $$ = 1; }|          { $$ = 0; };
 scope: GLOBAL     { $$ = 1; }    | LOCAL      { $$ = 2; }|            { $$ = 0; };
 something : scope temporary somethingelse { ... }

Bear


Re: help with bison

From
Gavin Sherry
Date:
On Wed, 10 Apr 2002, Bear Giles wrote:

> > In fact, my grammar currently has an obscene
> > 20 shift/reduce and 4 reduce/reduce conflicts!
> 
> A shift/reduce conflict, IIRC, usually indicates a situation where
> the grammar is unambiguous but may be inefficient.  Eliminating them
> is nice, but not critical.

This is not correct. A shift/reduce conflict is where the grammar is
ambiguous.

> 
> A R/R conflict, in contrast, is a point where the grammar is ambiguous
> and you *must* fix it.

A reduce/reduce conflict is where there is more than one rule which could
be used for the reduction of the grammar.

Gavin



Re: help with bison

From
"Christopher Kings-Lynne"
Date:
Out of interest, since the FE/BE protocol apprently doesn't support prepared
statements (bound variables), what does this patch actually _do_?

Chris

> -----Original Message-----
> From: pgsql-hackers-owner@postgresql.org
> [mailto:pgsql-hackers-owner@postgresql.org]On Behalf Of Neil Conway
> Sent: Thursday, 11 April 2002 9:29 AM
> To: PostgreSQL Hackers
> Subject: [HACKERS] help with bison
>
>
> Hi all,
>
> I'm working on a fairly large patch (cleaning up Karel Zak's
> PREPARE/EXECUTE work), and I'm having some problems with bison (I'm
> a yacc newbie). In fact, my grammar currently has an obscene
> 20 shift/reduce and 4 reduce/reduce conflicts!
>
> Would someone to be kind enough to let me know what I'm doing wrong,
> and what I'll need to change? (Unfortunately, bison isn't very
> helpful: it doesn't provide line-numbers when it warns me about
> the # of conflicts). The patch for gram.y is below.
>
> Thanks in advance,
>
> Neil
>
> --
> Neil Conway <neilconway@rogers.com>
> PGP Key ID: DB3C29FC



Re: help with bison

From
Neil Conway
Date:
On Thu, 11 Apr 2002 10:54:14 +0800
"Christopher Kings-Lynne" <chriskl@familyhealth.com.au> wrote:
> Out of interest, since the FE/BE protocol apprently doesn't support prepared
> statements (bound variables), what does this patch actually _do_?

It implements preparable statements, by adding 3 new SQL statements:

PREPARE <plan> AS <query>;
EXECUTE <plan> USING <parameters>;
DEALLOCATE <plan>;

I didn't write the original patch -- that was done by Karel Zak.
But since that was several years ago, I'm working on cleaning it up,
getting it to apply to current sources (which has taken a while),
and fixing the remaining issues with it. Karel describes his work
here:

http://groups.google.com/groups?q=query+cache+plan&hl=en&selm=8l4jua%242fo0%241%40FreeBSD.csie.NCTU.edu.tw&rnum=1

(If that's messed up due to newlines, search for "query cache plan"
on Google Groups, it's the first result)

Cheers,

Neil

-- 
Neil Conway <neilconway@rogers.com>
PGP Key ID: DB3C29FC


Re: help with bison

From
"Christopher Kings-Lynne"
Date:
> PREPARE <plan> AS <query>;
> EXECUTE <plan> USING <parameters>;
> DEALLOCATE <plan>;
>
> I didn't write the original patch -- that was done by Karel Zak.
> But since that was several years ago, I'm working on cleaning it up,
> getting it to apply to current sources (which has taken a while),
> and fixing the remaining issues with it. Karel describes his work
> here:

OK, fair enough.  What I don't get is how this patch is related to the FE/BE
not supporting variable binding problem?  Am I getting confused here?

Chris



Re: help with bison

From
Tom Lane
Date:
Bear Giles <bgiles@coyotesong.com> writes:
> As an aside, is there any reason to treat TEMP and TEMPORARY as two
> separate identifiers?

Yes: if the lexer folds them together then unreserved_keyword can't
regenerate the equivalent name properly.  (Possibly this could be fixed
by making the lexer pass the input string as the value of a keyword
token, but I've not looked at details.)

You might be right that the grammar could benefit from some refactoring,
though I'm not at all sure if that really helps from an
execution-efficiency (number of states) standpoint.
        regards, tom lane


Re: help with bison

From
Bear Giles
Date:
> > As an aside, is there any reason to treat TEMP and TEMPORARY as two
> > separate identifiers?
> 
> Yes: if the lexer folds them together then unreserved_keyword can't
> regenerate the equivalent name properly.

But if they're synonyms, is that necessary?  I'm not indifferent to the
benefits of being able to recreate an input string exactly when all other
things are equal, but things aren't equal here.  TEMPORARY is a SQL92
keyword, TEMP is described as a "Keyword for Postgres support," but the
grammar shows that one never appears without the other.

So why not deprecate TEMP and always show TEMPORARY when reconstructing
the query?

> You might be right that the grammar could benefit from some refactoring,
> though I'm not at all sure if that really helps from an
> execution-efficiency (number of states) standpoint.

The goal of the refactoring wouldn't be execution efficiency, it would 
be simplifying maintenance of the grammar.  And it looks like it's the
common practice elsewhere, just not in the OptTemp and OptTempTableName
rules.

Bear


Re: help with bison

From
Tom Lane
Date:
Bear Giles <bgiles@coyotesong.com> writes:
>> Yes: if the lexer folds them together then unreserved_keyword can't
>> regenerate the equivalent name properly.

> But if they're synonyms, is that necessary?

If I saycreate table foo (temp int);
I will be annoyed if the system decides that the column is named
"temporary".  Being synonyms in the SQL grammar does not make them
equivalent when used as plain identifiers.
        regards, tom lane


Re: help with bison

From
Gavin Sherry
Date:
On Wed, 10 Apr 2002, Neil Conway wrote:

> Hi all,
> 
> I'm working on a fairly large patch (cleaning up Karel Zak's
> PREPARE/EXECUTE work), and I'm having some problems with bison (I'm
> a yacc newbie). In fact, my grammar currently has an obscene
> 20 shift/reduce and 4 reduce/reduce conflicts!

Your first set of problems is coming from PrepareStmt:

---

PrepareStmt:  PREPARE name AS prepare_query types_prepare_clause
prepare_store

---

There is a reasonably clear problem here. prepare_query encompasses much
of the grammar of the parser so it will definately cause shift/reduce and
reduce/reduce conflicts with the other two productions which follow
it. Easy solution?

PrepareStmt:  PREPARE name types_prepare_clause prepare_store AS
prepare_query

Your second problem is in ExecuteStmt:

ExecuteStmt: EXECUTE name into_clause USING execute_using prepare_store

Here your problem is with execute_using and prepare_store. I am not sure
why.

Gavin



Re: help with bison

From
Barry Lind
Date:
Neil,

Will this allow you to pass bytea data as binary data in the parameters 
section (ability to bind values to parameters) or will this still 
require that the data be passed as a text string that the parser needs 
to parse.  When passing bytea data that is on the order of Megs in size 
(thus the insert/update statement is multiple Megs in size) it takes a 
lot of CPU cycles for the parser to chug through sql statements that 
long.  (In fact a posting to the jdbc mail list in the last couple of 
days shows that postgres is 22 times slower than oracle when handling a 
1Meg value in a bytea column).

thanks,
--Barry

Neil Conway wrote:
> On Thu, 11 Apr 2002 10:54:14 +0800
> "Christopher Kings-Lynne" <chriskl@familyhealth.com.au> wrote:
> 
>>Out of interest, since the FE/BE protocol apprently doesn't support prepared
>>statements (bound variables), what does this patch actually _do_?
> 
> 
> It implements preparable statements, by adding 3 new SQL statements:
> 
> PREPARE <plan> AS <query>;
> EXECUTE <plan> USING <parameters>;
> DEALLOCATE <plan>;
> 
> I didn't write the original patch -- that was done by Karel Zak.
> But since that was several years ago, I'm working on cleaning it up,
> getting it to apply to current sources (which has taken a while),
> and fixing the remaining issues with it. Karel describes his work
> here:
> 
> http://groups.google.com/groups?q=query+cache+plan&hl=en&selm=8l4jua%242fo0%241%40FreeBSD.csie.NCTU.edu.tw&rnum=1
> 
> (If that's messed up due to newlines, search for "query cache plan"
> on Google Groups, it's the first result)
> 
> Cheers,
> 
> Neil
> 




Re: help with bison

From
Tom Lane
Date:
Gavin Sherry <swm@linuxworld.com.au> writes:
> PrepareStmt:  PREPARE name AS prepare_query types_prepare_clause
> prepare_store

> There is a reasonably clear problem here. prepare_query encompasses much
> of the grammar of the parser so it will definately cause shift/reduce and
> reduce/reduce conflicts with the other two productions which follow
> it. Easy solution?

> PrepareStmt:  PREPARE name types_prepare_clause prepare_store AS
> prepare_query

Is there any existing standard to follow for the syntax of these
commands?
        regards, tom lane


Re: help with bison

From
Neil Conway
Date:
On Wed, 10 Apr 2002 22:36:49 -0700
"Barry Lind" <barry@xythos.com> wrote:
> Neil,
> 
> Will this allow you to pass bytea data as binary data in the parameters 
> section (ability to bind values to parameters) or will this still 
> require that the data be passed as a text string that the parser needs 
> to parse.

The patch I'm working on would require that the parameters
are still parsed, so it would likely suffer from the same
performance problems.

I'm unsure how to fix this without a change to the FE/BE
protocol (and even then, it wouldn't be trivial). Suggestions?

Cheers,

Neil

-- 
Neil Conway <neilconway@rogers.com>
PGP Key ID: DB3C29FC


Re: help with bison

From
Neil Conway
Date:
On Thu, 11 Apr 2002 15:02:49 +1000 (EST)
"Gavin Sherry" <swm@linuxworld.com.au> wrote:
> On Wed, 10 Apr 2002, Neil Conway wrote:
> 
> > Hi all,
> > 
> > I'm working on a fairly large patch (cleaning up Karel Zak's
> > PREPARE/EXECUTE work), and I'm having some problems with bison (I'm
> > a yacc newbie). In fact, my grammar currently has an obscene
> > 20 shift/reduce and 4 reduce/reduce conflicts!
> 
> Your first set of problems is coming from PrepareStmt:
> [...]

> Your second problem is in ExecuteStmt:
> [...]

Great, thanks Gavin! (I owe you a beer!)

I re-arranged PrepareStmt as you suggested, as well as
ExecuteStmt, and the conflicts have disappeared. I'm not sure
if the new syntax is ideal, but I'm happy to leave it as it is
until I've got the patch mostly working. I'd welcome any
suggestions for improvements to the syntax that still allow
for sane parsing.

Thanks again,

Neil

-- 
Neil Conway <neilconway@rogers.com>
PGP Key ID: DB3C29FC


Re: help with bison

From
Gavin Sherry
Date:
On Thu, 11 Apr 2002, Tom Lane wrote:

> Gavin Sherry <swm@linuxworld.com.au> writes:
> > PrepareStmt:  PREPARE name AS prepare_query types_prepare_clause
> > prepare_store
> 
> > There is a reasonably clear problem here. prepare_query encompasses much
> > of the grammar of the parser so it will definately cause shift/reduce and
> > reduce/reduce conflicts with the other two productions which follow
> > it. Easy solution?
> 
> > PrepareStmt:  PREPARE name types_prepare_clause prepare_store AS
> > prepare_query
> 
> Is there any existing standard to follow for the syntax of these
> commands?

SQL92 lists:
        <prepare statement> ::=             PREPARE <SQL statement name> FROM <SQL statement variable>

Where <SQL statement variable> can resolve to:
        <preparable statement> ::=               <preparable SQL data statement>             | <preparable SQL schema
statement>            | <preparable SQL transaction statement>             | <preparable SQL session statement>
   | <preparable implementation-defined statement>
 
        <preparable SQL data statement> ::=               <delete statement: searched>             | <dynamic single
rowselect statement>             | <insert statement>             | <dynamic select statement>             | <update
statement:searched>             | <preparable dynamic delete statement: positioned>             | <preparable dynamic
updatestatement: positioned>
 
        <preparable SQL schema statement> ::=               <SQL schema statement>
        <preparable SQL transaction statement> ::=               <SQL transaction statement>
        <preparable SQL session statement> ::=               <SQL session statement>
        <dynamic select statement> ::= <cursor specification>
        <dynamic single row select statement> ::= <query specification>



So, the form is (according to the yacc code):

PREPARE name FROM prepare_query

This seems a lot simpler. What is 'types_prepare_clause' used for? I
presume storage relates to whether or not all backends can see the
prepared statement? (As a note to those interested in statement
preparation, this is not the same as variable binding and so requires no
modification of the FE/BE protocol).

As a side note, I'm not sure I really see the point of preparable SQL. The
only real use I can think of is if the query could be prepared on the
client side. This would require modification of the parser (a few
#ifdefs), a few client side functions, some memory storage and a
modification of the FE/BE protocol to be able to accept parsed query
nodes. This would allow the backend to spend as little time in the parser
as possible, if that is desirable. It removes the ability to share
prepared queries between backends however.

Gavin






Re: help with bison

From
Joe Conway
Date:
Neil Conway wrote:> On Wed, 10 Apr 2002 22:36:49 -0700 "Barry Lind" <barry@xythos.com>> wrote:>>> Neil,>>>> Will this
allowyou to pass bytea data as binary data in the>> parameters section (ability to bind values to parameters) or will>>
thisstill require that the data be passed as a text string that>> the parser needs to parse.>>> The patch I'm working
onwould require that the parameters are still> parsed, so it would likely suffer from the same performance> problems.>>
I'munsure how to fix this without a change to the FE/BE protocol> (and even then, it wouldn't be trivial).
Suggestions?>


The other day there was a discussion around the fact that X'ffff' will
get converted into an integer constant, e.g.

test=# select X'ffff'; ?column?
----------    65535
(1 row)

, while SQL99 says that this syntax *should* be used to specify a 
"binary string". It looks like the hex-to-integer magic actually occurs 
in the lexer, and then the integer value of 65535 is passed to the 
parser as an ICONST. I'm wondering if changing the lexer to make this a 
conversion to a properly escaped bytea input string, and passing it to 
the parser as a string constant would speed things up?

Joe






Re: help with bison

From
Peter Eisentraut
Date:
Joe Conway writes:

> The other day there was a discussion around the fact that X'ffff' will
> get converted into an integer constant, e.g.

> , while SQL99 says that this syntax *should* be used to specify a
> "binary string".

Actually, SQL99 is ambiguous regarding whether it represents a blob or a
bit string.  But either of these would be better than an integer.

-- 
Peter Eisentraut   peter_e@gmx.net



Re: help with bison

From
Thomas Lockhart
Date:
> The other day there was a discussion around the fact that X'ffff' will
> get converted into an integer constant...
> ... while SQL99 says that this syntax *should* be used to specify a
> "binary string". It looks like the hex-to-integer magic actually occurs
> in the lexer, and then the integer value of 65535 is passed to the
> parser as an ICONST. I'm wondering if changing the lexer to make this a
> conversion to a properly escaped bytea input string, and passing it to
> the parser as a string constant would speed things up?

What else is described as a "binary string" in the spec? I would have
guessed that this would map to a bit field type (and maybe even had
looked it up at one time).

Is B'00010001' also described as a "binary string" also, or is it more
explicitly tied to bit fields?
                   - Thomas


Re: help with bison

From
Joe Conway
Date:
Thomas Lockhart wrote:>> The other day there was a discussion around the fact that X'ffff'>> will get converted into an
integerconstant... ... while SQL99>> says that this syntax *should* be used to specify a "binary>> string". It looks
likethe hex-to-integer magic actually occurs in>> the lexer, and then the integer value of 65535 is passed to the
parser>>as an ICONST. I'm wondering if changing the lexer to make this a 
 
conversion>> to a properly escaped bytea input string, and passing it to the>> parser as a string constant would speed
thingsup?>>> What else is described as a "binary string" in the spec? I would> have guessed that this would map to a
bitfield type (and maybe even> had looked it up at one time).>> Is B'00010001' also described as a "binary string"
also,or is it> more explicitly tied to bit fields?>> - Thomas
 

In SQL99, Section "5.3 <literal>", I see this:
  <national character string literal> ::=     N <quote> [ <character representation>... ] <quote>     [ { <separator>
<quote>[ <character representation>... ]     <quote> }... ]  <bit string literal> ::=     B <quote> [ <bit>... ]
<quote>    [ { <separator> <quote> [ <bit>... ] <quote> }... ]  <hex string literal> ::=     X <quote> [ <hexit>... ]
<quote>    [ { <separator> <quote> [ <hexit>... ] <quote> }... ]  <binary string literal> ::=     X <quote> [ { <hexit>
<hexit>}... ] <quote>     [ { <separator> <quote> [ { <hexit> <hexit> }... ] <quote> }... ]  <bit> ::=     0 | 1
<hexit>::=     <digit> | A | B | C | D | E | F | a | b | c | d | e | f
 

and further down:
  11) The declared type of a <bit string literal> is fixed-length      bit string. The length of a <bit string literal>
isthe number      of bits that it contains.  12) The declared type of a <hex string literal> is fixed-length bit
string.Each <hexit> appearing in the literal is equivalent to      a quartet of bits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A,
B,C, D, E,      and F are interpreted as 0000, 0001, 0010, 0011, 0100, 0101,      0110, 0111, 1000, 1001, 1010, 1011,
1100,1101, 1110, and 1111,      respectively. The <hexit>s a, b, c, d, e, and f have respectively      the same values
asthe <hexit>s A, B, C, D, E, and F.  13) The declared type of a <binary string literal> is binary string.      Each
<hexit>appearing in the literal is equivalent to a quartet      of bits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E,
andF are      interpreted as 0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111,      1000, 1001, 1010, 1011, 1100, 1101,
1110,and 1111, respectively.      The <hexit>s a, b, c, d, e, and f have respectively the same      values as the
<hexit>sA, B, C, D, E, and F.
 

So, as Peter pointed out, X'ffff' can be interpreted as a binary string 
*or* a bit string, but ISTM B'1111' is explicitly tied to a bit string.

Joe