help with bison

Started by Neil Conwayalmost 24 years ago21 messages
#1Neil Conway
nconway@klamath.dyndns.org

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;
+ 				}
+ 		;

/*****************************************************************************
*

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Neil Conway (#1)
Re: help with bison

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

#3Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Neil Conway (#1)
Re: help with bison

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

Show quoted text

-----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

#4Bear Giles
bgiles@coyotesong.com
In reply to: Neil Conway (#1)
Re: help with bison

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

#5Gavin Sherry
swm@linuxworld.com.au
In reply to: Bear Giles (#4)
Re: help with bison

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

#6Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Neil Conway (#1)
Re: help with bison

Out of interest, since the FE/BE protocol apprently doesn't support prepared
statements (bound variables), what does this patch actually _do_?

Chris

Show quoted text

-----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

#7Neil Conway
nconway@klamath.dyndns.org
In reply to: Christopher Kings-Lynne (#6)
Re: help with bison

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&amp;hl=en&amp;selm=8l4jua%242fo0%241%40FreeBSD.csie.NCTU.edu.tw&amp;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

#8Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Neil Conway (#7)
Re: help with bison

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

#9Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bear Giles (#4)
Re: help with bison

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

#10Bear Giles
bgiles@coyotesong.com
In reply to: Tom Lane (#9)
Re: help with bison

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

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bear Giles (#10)
Re: help with bison

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 say
create 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

#12Gavin Sherry
swm@linuxworld.com.au
In reply to: Neil Conway (#1)
Re: help with bison

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

#13Barry Lind
barry@xythos.com
In reply to: Neil Conway (#1)
Re: help with bison

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:

Show quoted text

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&amp;hl=en&amp;selm=8l4jua%242fo0%241%40FreeBSD.csie.NCTU.edu.tw&amp;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

#14Tom Lane
tgl@sss.pgh.pa.us
In reply to: Gavin Sherry (#12)
Re: help with bison

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

#15Neil Conway
nconway@klamath.dyndns.org
In reply to: Barry Lind (#13)
Re: help with bison

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

#16Neil Conway
nconway@klamath.dyndns.org
In reply to: Gavin Sherry (#12)
Re: help with bison

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

#17Joe Conway
mail@joeconway.com
In reply to: Neil Conway (#1)
Re: help with bison

Neil Conway wrote:

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?

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

#18Gavin Sherry
swm@linuxworld.com.au
In reply to: Tom Lane (#14)
Re: help with bison

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 row select statement>
| <insert statement>
| <dynamic select statement>
| <update statement: searched>
| <preparable dynamic delete statement: positioned>
| <preparable dynamic update statement: 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

#19Peter Eisentraut
peter_e@gmx.net
In reply to: Joe Conway (#17)
Re: help with bison

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

#20Thomas Lockhart
lockhart@fourpalms.org
In reply to: Neil Conway (#1)
Re: help with bison

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

#21Joe Conway
mail@joeconway.com
In reply to: Neil Conway (#1)
Re: help with bison

Thomas Lockhart wrote:

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

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> is the 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 as the <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, 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 as the <hexit>s A, 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