From 9729f6ca0dfe46daeff8c23f7a08c698d034d949 Mon Sep 17 00:00:00 2001 From: "Vadim B. Mikheev" Date: Wed, 2 Apr 1997 04:01:03 +0000 Subject: [PATCH] CREATE/DROP SEQUENCE ... Check nextval/currval permission in analyze.c. --- src/backend/parser/analyze.c | 39 +++++++++++++++++++++++- src/backend/parser/gram.y | 57 +++++++++++++++++++++++++++++++++--- 2 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 2cbe2c4a66..ce96e13bb1 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.23 1997/03/12 20:51:33 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.24 1997/04/02 04:00:55 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -29,14 +29,18 @@ #include "utils/palloc.h" #include "utils/mcxt.h" #include "utils/syscache.h" +#include "utils/acl.h" #include "parser/parse_query.h" #include "parser/parse_state.h" #include "nodes/makefuncs.h" /* for makeResdom(), etc. */ #include "nodes/nodeFuncs.h" +#include "commands/sequence.h" #include "optimizer/clauses.h" #include "access/heapam.h" +#include "miscadmin.h" + #include "port-protos.h" /* strdup() */ /* convert the parse tree into a query tree */ @@ -65,6 +69,7 @@ static List *transformTargetList(ParseState *pstate, List *targetlist); static TargetEntry *make_targetlist_expr(ParseState *pstate, char *colname, Node *expr, List *arrayRef); +static bool inWhereClause = false; static Node *transformWhereClause(ParseState *pstate, Node *a_expr); static List *transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist); @@ -133,6 +138,8 @@ parse_analyze(List *pl) result = malloc(sizeof(QueryTreeList)); result->len = length(pl); result->qtrees = (Query**)malloc(result->len * sizeof(Query*)); + + inWhereClause = false; /* to avoid nextval(sequence) in WHERE */ while(pl!=NIL) { pstate = makeParseState(); @@ -1446,7 +1453,9 @@ transformWhereClause(ParseState *pstate, Node *a_expr) if (a_expr == NULL) return (Node *)NULL; /* no qualifiers */ + inWhereClause = true; qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST); + inWhereClause = false; if (exprType(qual) != BOOLOID) { elog(WARN, "where clause must return type bool, not %s", @@ -2182,6 +2191,34 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno) } } + /* + * Sequence handling. + */ + if ( funcid == SeqNextValueRegProcedure || + funcid == SeqCurrValueRegProcedure ) + { + Const *seq; + char *seqrel; + int32 aclcheck_result = -1; + + Assert ( length(fargs) == 1 ); + seq = (Const*)lfirst(fargs); + if ( ! IsA ((Node*)seq, Const) ) + elog (WARN, "%s: only constant sequence names are acceptable", funcname); + seqrel = textout ((struct varlena *) (seq->constvalue)); + + if ( ( aclcheck_result = pg_aclcheck (seqrel, GetPgUserName(), + ((funcid == SeqNextValueRegProcedure) ? ACL_WR : ACL_RD)) ) + != ACLCHECK_OK ) + elog (WARN, "%s.%s: %s", + seqrel, funcname, aclcheck_error_strings[aclcheck_result]); + + pfree (seqrel); + + if ( funcid == SeqNextValueRegProcedure && inWhereClause ) + elog (WARN, "nextval of a sequence in WHERE disallowed"); + } + expr = makeNode(Expr); expr->typeOid = rettype; expr->opType = FUNC_EXPR; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 0b62bdb843..15fc14e9b1 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.27 1997/03/26 02:52:49 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.28 1997/04/02 04:01:03 vadim Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -100,7 +100,7 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr); %type stmt, AddAttrStmt, ClosePortalStmt, - CopyStmt, CreateStmt, DefineStmt, DestroyStmt, + CopyStmt, CreateStmt, CreateSeqStmt, DefineStmt, DestroyStmt, ExtendStmt, FetchStmt, GrantStmt, IndexStmt, MoveStmt, ListenStmt, OptimizableStmt, ProcedureStmt, PurgeStmt, @@ -141,6 +141,9 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr); %type OptLocation, opt_move_where, fetch_how_many +%type OptSeqList +%type OptSeqElem + %type def_rest %type purge_quals %type insert_rest @@ -190,7 +193,7 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr); SELECT, SET, SETOF, STDIN, STDOUT, STORE, TABLE, TO, TRANSACTION, UNIQUE, UPDATE, USING, VACUUM, VALUES VERBOSE, VERSION, VIEW, WHERE, WITH, WORK -%token EXECUTE, RECIPE, EXPLAIN, LIKE +%token EXECUTE, RECIPE, EXPLAIN, LIKE, SEQUENCE /* Special keywords, not in the query language - see the "lex" file */ %token IDENT, SCONST, Op @@ -243,6 +246,7 @@ stmt : AddAttrStmt | ClosePortalStmt | CopyStmt | CreateStmt + | CreateSeqStmt | ClusterStmt | DefineStmt | DestroyStmt @@ -425,6 +429,43 @@ OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; } ; +/***************************************************************************** + * + * QUERY : + * CREATE SEQUENCE seqname + * + *****************************************************************************/ + +CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList + { + CreateSeqStmt *n = makeNode(CreateSeqStmt); + n->seqname = $3; + n->options = $4; + $$ = (Node *)n; + } + ; + +OptSeqList: + OptSeqList OptSeqElem + { $$ = lappend($1, $2); } + | { $$ = NIL; } + ; + +OptSeqElem: IDENT NumConst + { + $$ = makeNode(DefElem); + $$->defname = $1; + $$->arg = (Node *)$2; + } + | IDENT + { + $$ = makeNode(DefElem); + $$->defname = $1; + $$->arg = (Node *)NULL; + } + ; + + /***************************************************************************** * * QUERY : @@ -501,10 +542,18 @@ def_arg: Id { $$ = (Node *)makeString($1); } * *****************************************************************************/ -DestroyStmt: DROP TABLE relation_name_list +DestroyStmt: DROP TABLE relation_name_list + { + DestroyStmt *n = makeNode(DestroyStmt); + n->relNames = $3; + n->sequence = false; + $$ = (Node *)n; + } + | DROP SEQUENCE relation_name_list { DestroyStmt *n = makeNode(DestroyStmt); n->relNames = $3; + n->sequence = true; $$ = (Node *)n; } ; -- 2.40.0