Thread: 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; + } + ; /***************************************************************************** *
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
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 >
> 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
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
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
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
> 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
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
> > 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
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
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
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 >
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
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
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
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
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
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
> 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
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