]> granicus.if.org Git - postgresql/commitdiff
CREATE/DROP SEQUENCE ...
authorVadim B. Mikheev <vadim4o@yahoo.com>
Wed, 2 Apr 1997 04:01:03 +0000 (04:01 +0000)
committerVadim B. Mikheev <vadim4o@yahoo.com>
Wed, 2 Apr 1997 04:01:03 +0000 (04:01 +0000)
Check nextval/currval permission in analyze.c.

src/backend/parser/analyze.c
src/backend/parser/gram.y

index 2cbe2c4a66d29b2c4f9570d1d0f36dea20067085..ce96e13bb1052aa76b38a4e6988398b25981a605 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 #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;
index 0b62bdb8433080b228d66d3e0facb884c0b82531..15fc14e9b13df189fd548b163e4893410e915eac 100644 (file)
@@ -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 <node>   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 <ival>   OptLocation, opt_move_where, fetch_how_many 
 
+%type <list>   OptSeqList
+%type <defelt> OptSeqElem
+
 %type <dstmt>  def_rest
 %type <pstmt>  purge_quals
 %type <astmt>  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 <str>   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;
                }
        ;