Commit 9729f6ca authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

CREATE/DROP SEQUENCE ...

Check nextval/currval permission in analyze.c.
parent e276d8a1
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -29,14 +29,18 @@
#include "utils/palloc.h" #include "utils/palloc.h"
#include "utils/mcxt.h" #include "utils/mcxt.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#include "utils/acl.h"
#include "parser/parse_query.h" #include "parser/parse_query.h"
#include "parser/parse_state.h" #include "parser/parse_state.h"
#include "nodes/makefuncs.h" /* for makeResdom(), etc. */ #include "nodes/makefuncs.h" /* for makeResdom(), etc. */
#include "nodes/nodeFuncs.h" #include "nodes/nodeFuncs.h"
#include "commands/sequence.h"
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "miscadmin.h"
#include "port-protos.h" /* strdup() */ #include "port-protos.h" /* strdup() */
/* convert the parse tree into a query tree */ /* convert the parse tree into a query tree */
...@@ -65,6 +69,7 @@ static List *transformTargetList(ParseState *pstate, List *targetlist); ...@@ -65,6 +69,7 @@ static List *transformTargetList(ParseState *pstate, List *targetlist);
static TargetEntry *make_targetlist_expr(ParseState *pstate, static TargetEntry *make_targetlist_expr(ParseState *pstate,
char *colname, Node *expr, char *colname, Node *expr,
List *arrayRef); List *arrayRef);
static bool inWhereClause = false;
static Node *transformWhereClause(ParseState *pstate, Node *a_expr); static Node *transformWhereClause(ParseState *pstate, Node *a_expr);
static List *transformGroupClause(ParseState *pstate, List *grouplist, static List *transformGroupClause(ParseState *pstate, List *grouplist,
List *targetlist); List *targetlist);
...@@ -134,6 +139,8 @@ parse_analyze(List *pl) ...@@ -134,6 +139,8 @@ parse_analyze(List *pl)
result->len = length(pl); result->len = length(pl);
result->qtrees = (Query**)malloc(result->len * sizeof(Query*)); result->qtrees = (Query**)malloc(result->len * sizeof(Query*));
inWhereClause = false; /* to avoid nextval(sequence) in WHERE */
while(pl!=NIL) { while(pl!=NIL) {
pstate = makeParseState(); pstate = makeParseState();
result->qtrees[i++] = transformStmt(pstate, lfirst(pl)); result->qtrees[i++] = transformStmt(pstate, lfirst(pl));
...@@ -1446,7 +1453,9 @@ transformWhereClause(ParseState *pstate, Node *a_expr) ...@@ -1446,7 +1453,9 @@ transformWhereClause(ParseState *pstate, Node *a_expr)
if (a_expr == NULL) if (a_expr == NULL)
return (Node *)NULL; /* no qualifiers */ return (Node *)NULL; /* no qualifiers */
inWhereClause = true;
qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST); qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST);
inWhereClause = false;
if (exprType(qual) != BOOLOID) { if (exprType(qual) != BOOLOID) {
elog(WARN, elog(WARN,
"where clause must return type bool, not %s", "where clause must return type bool, not %s",
...@@ -2182,6 +2191,34 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno) ...@@ -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 = makeNode(Expr);
expr->typeOid = rettype; expr->typeOid = rettype;
expr->opType = FUNC_EXPR; expr->opType = FUNC_EXPR;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -100,7 +100,7 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr); ...@@ -100,7 +100,7 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
%type <node> stmt, %type <node> stmt,
AddAttrStmt, ClosePortalStmt, AddAttrStmt, ClosePortalStmt,
CopyStmt, CreateStmt, DefineStmt, DestroyStmt, CopyStmt, CreateStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
ExtendStmt, FetchStmt, GrantStmt, ExtendStmt, FetchStmt, GrantStmt,
IndexStmt, MoveStmt, ListenStmt, OptimizableStmt, IndexStmt, MoveStmt, ListenStmt, OptimizableStmt,
ProcedureStmt, PurgeStmt, ProcedureStmt, PurgeStmt,
...@@ -141,6 +141,9 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr); ...@@ -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 <ival> OptLocation, opt_move_where, fetch_how_many
%type <list> OptSeqList
%type <defelt> OptSeqElem
%type <dstmt> def_rest %type <dstmt> def_rest
%type <pstmt> purge_quals %type <pstmt> purge_quals
%type <astmt> insert_rest %type <astmt> insert_rest
...@@ -190,7 +193,7 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr); ...@@ -190,7 +193,7 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
SELECT, SET, SETOF, STDIN, STDOUT, STORE, SELECT, SET, SETOF, STDIN, STDOUT, STORE,
TABLE, TO, TRANSACTION, UNIQUE, UPDATE, USING, VACUUM, VALUES TABLE, TO, TRANSACTION, UNIQUE, UPDATE, USING, VACUUM, VALUES
VERBOSE, VERSION, VIEW, WHERE, WITH, WORK 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 */ /* Special keywords, not in the query language - see the "lex" file */
%token <str> IDENT, SCONST, Op %token <str> IDENT, SCONST, Op
...@@ -243,6 +246,7 @@ stmt : AddAttrStmt ...@@ -243,6 +246,7 @@ stmt : AddAttrStmt
| ClosePortalStmt | ClosePortalStmt
| CopyStmt | CopyStmt
| CreateStmt | CreateStmt
| CreateSeqStmt
| ClusterStmt | ClusterStmt
| DefineStmt | DefineStmt
| DestroyStmt | DestroyStmt
...@@ -425,6 +429,43 @@ OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; } ...@@ -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 : * QUERY :
...@@ -505,6 +546,14 @@ DestroyStmt: DROP TABLE relation_name_list ...@@ -505,6 +546,14 @@ DestroyStmt: DROP TABLE relation_name_list
{ {
DestroyStmt *n = makeNode(DestroyStmt); DestroyStmt *n = makeNode(DestroyStmt);
n->relNames = $3; 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; $$ = (Node *)n;
} }
; ;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment