CREATE/DROP SEQUENCE ...
Check nextval/currval permission in analyze.c.
This commit is contained in:
parent
e276d8a1a6
commit
9729f6ca0d
@ -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 @@
|
|||||||
#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);
|
|||||||
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);
|
||||||
@ -133,6 +138,8 @@ parse_analyze(List *pl)
|
|||||||
result = malloc(sizeof(QueryTreeList));
|
result = malloc(sizeof(QueryTreeList));
|
||||||
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();
|
||||||
@ -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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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);
|
|||||||
|
|
||||||
%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);
|
|||||||
|
|
||||||
%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);
|
|||||||
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
|
|||||||
| ClosePortalStmt
|
| ClosePortalStmt
|
||||||
| CopyStmt
|
| CopyStmt
|
||||||
| CreateStmt
|
| CreateStmt
|
||||||
|
| CreateSeqStmt
|
||||||
| ClusterStmt
|
| ClusterStmt
|
||||||
| DefineStmt
|
| DefineStmt
|
||||||
| DestroyStmt
|
| 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 :
|
* 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);
|
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;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user