Procdure support COMMIT/ROLLBACK grammer.

This commit is contained in:
chenyanfei
2020-08-06 10:57:58 +08:00
parent 937bc72dec
commit b093b4d858
8 changed files with 183 additions and 5 deletions

View File

@ -263,6 +263,7 @@ static List *read_raise_options(void);
%type <stmt> stmt_return stmt_raise stmt_execsql
%type <stmt> stmt_dynexecute stmt_for stmt_perform stmt_getdiag
%type <stmt> stmt_open stmt_fetch stmt_move stmt_close stmt_null
%type <stmt> stmt_commit stmt_rollback
%type <stmt> stmt_case stmt_foreach_a
%type <list> proc_exceptions
@ -338,6 +339,7 @@ static List *read_raise_options(void);
%token <keyword> K_CASE
%token <keyword> K_CLOSE
%token <keyword> K_COLLATE
%token <keyword> K_COMMIT
%token <keyword> K_CONSTANT
%token <keyword> K_CONTINUE
%token <keyword> K_CURRENT
@ -405,6 +407,7 @@ static List *read_raise_options(void);
%token <keyword> K_RETURN
%token <keyword> K_RETURNED_SQLSTATE
%token <keyword> K_REVERSE
%token <keyword> K_ROLLBACK
%token <keyword> K_ROWTYPE
%token <keyword> K_ROW_COUNT
%token <keyword> K_SAVEPOINT
@ -1079,6 +1082,10 @@ label_stmt : stmt_assign
{ $$ = $1; }
| stmt_null
{ $$ = $1; }
| stmt_commit
{ $$ = $1; }
| stmt_rollback
{ $$ = $1; }
;
stmt_perform : K_PERFORM expr_until_semi
@ -2619,6 +2626,32 @@ stmt_null : K_NULL ';'
}
;
stmt_commit : K_COMMIT ';'
{
/* We do building a node for NULL for GOTO */
PLpgSQL_stmt_commit *newp;
newp = (PLpgSQL_stmt_commit *)palloc(sizeof(PLpgSQL_stmt_commit));
newp->cmd_type = PLPGSQL_STMT_COMMIT;
newp->lineno = plpgsql_location_to_lineno(@1);
$$ = (PLpgSQL_stmt_commit *)newp;
}
;
stmt_rollback : K_ROLLBACK ';'
{
/* We do building a node for NULL for GOTO */
PLpgSQL_stmt_rollback *newp;
newp = (PLpgSQL_stmt_rollback *)palloc(sizeof(PLpgSQL_stmt_rollback));
newp->cmd_type = PLPGSQL_STMT_ROLLBACK;
newp->lineno = plpgsql_location_to_lineno(@1);
$$ = (PLpgSQL_stmt_rollback *)newp;
}
;
cursor_variable : T_DATUM
{
if ($1.datum->dtype != PLPGSQL_DTYPE_VAR)
@ -2896,6 +2929,7 @@ unreserved_keyword :
| K_BACKWARD
| K_CONSTANT
| K_CONTINUE
| K_COMMIT
| K_CURRENT
| K_DEBUG
| K_DETAIL
@ -2926,6 +2960,7 @@ unreserved_keyword :
| K_RESULT_OID
| K_RETURNED_SQLSTATE
| K_REVERSE
| K_ROLLBACK
| K_ROW_COUNT
| K_ROWTYPE
| K_SCROLL

View File

@ -122,6 +122,8 @@ static int exec_stmt_return_query(PLpgSQL_execstate* estate, PLpgSQL_stmt_return
static int exec_stmt_raise(PLpgSQL_execstate* estate, PLpgSQL_stmt_raise* stmt);
static int exec_stmt_execsql(PLpgSQL_execstate* estate, PLpgSQL_stmt_execsql* stmt);
static int exec_stmt_dynexecute(PLpgSQL_execstate* estate, PLpgSQL_stmt_dynexecute* stmt);
static int exec_stmt_commit(PLpgSQL_execstate* estate, PLpgSQL_stmt_commit* stmt);
static int exec_stmt_rollback(PLpgSQL_execstate* estate, PLpgSQL_stmt_rollback* stmt);
static int exchange_parameters(
PLpgSQL_execstate* estate, PLpgSQL_stmt_dynexecute* dynstmt, List* stmts, int* ppdindex, int* datumindex);
static bool is_anonymous_block(const char* query);
@ -2002,6 +2004,14 @@ static int exec_stmt(PLpgSQL_execstate* estate, PLpgSQL_stmt* stmt)
rc = exec_stmt_null(estate, (PLpgSQL_stmt*)stmt);
break;
case PLPGSQL_STMT_COMMIT:
rc = exec_stmt_commit(estate, (PLpgSQL_stmt_commit*)stmt);
break;
case PLPGSQL_STMT_ROLLBACK:
rc = exec_stmt_rollback(estate, (PLpgSQL_stmt_rollback*)stmt);
break;
default:
estate->err_stmt = save_estmt;
ereport(ERROR,
@ -4878,6 +4888,26 @@ static int exec_stmt_null(PLpgSQL_execstate* estate, PLpgSQL_stmt* stmt)
return PLPGSQL_RC_OK;
}
/*
* exec_stmt_commit
*
* Commit the transaction.
*/
static int exec_stmt_commit(PLpgSQL_execstate* estate, PLpgSQL_stmt_commit* stmt)
{
return PLPGSQL_RC_OK;
}
/*
* exec_stmt_rollback
*
* Abort the transaction.
*/
static int exec_stmt_rollback(PLpgSQL_execstate* estate, PLpgSQL_stmt_rollback* stmt)
{
return PLPGSQL_RC_OK;
}
/*
* @Description: copy cursor data from estate->datums to estate->datums
* @in estate - estate

View File

@ -222,6 +222,10 @@ const char* plpgsql_stmt_typename(PLpgSQL_stmt* stmt)
return "PERFORM";
case PLPGSQL_STMT_NULL:
return "NULL";
case PLPGSQL_STMT_COMMIT:
return "COMMIT";
case PLPGSQL_STMT_ROLLBACK:
return "ROLLBACK";
default:
break;
}
@ -291,6 +295,8 @@ static void free_fetch(PLpgSQL_stmt_fetch* stmt);
static void free_close(PLpgSQL_stmt_close* stmt);
static void free_null(PLpgSQL_stmt* stmt);
static void free_perform(PLpgSQL_stmt_perform* stmt);
static void free_commit(PLpgSQL_stmt_commit* stmt);
static void free_rollback(PLpgSQL_stmt_rollback* stmt);
static void free_stmt(PLpgSQL_stmt* stmt)
{
@ -370,6 +376,12 @@ static void free_stmt(PLpgSQL_stmt* stmt)
case PLPGSQL_STMT_NULL:
free_null((PLpgSQL_stmt*)stmt);
break;
case PLPGSQL_STMT_COMMIT:
free_commit((PLpgSQL_stmt_commit*)stmt);
break;
case PLPGSQL_STMT_ROLLBACK:
free_rollback((PLpgSQL_stmt_rollback*)stmt);
break;
default:
ereport(ERROR,
(errmodule(MOD_PLSQL),
@ -509,6 +521,13 @@ static void free_perform(PLpgSQL_stmt_perform* stmt)
free_expr(stmt->expr);
}
static void free_commit(PLpgSQL_stmt_commit* stmt)
{
}
static void free_rollback(PLpgSQL_stmt_rollback* stmt)
{
}
static void free_exit(PLpgSQL_stmt_exit* stmt)
{
free_expr(stmt->cond);
@ -687,6 +706,8 @@ static void dump_cursor_direction(PLpgSQL_stmt_fetch* stmt);
static void dump_close(PLpgSQL_stmt_close* stmt);
static void dump_perform(PLpgSQL_stmt_perform* stmt);
static void dump_null(PLpgSQL_stmt* stmt);
static void dump_commit(PLpgSQL_stmt_commit* stmt);
static void dump_rollback(PLpgSQL_stmt_rollback* stmt);
static void dump_expr(PLpgSQL_expr* expr);
static void dump_ind(void)
@ -777,6 +798,12 @@ static void dump_stmt(PLpgSQL_stmt* stmt)
case PLPGSQL_STMT_NULL:
dump_null((PLpgSQL_stmt*)stmt);
break;
case PLPGSQL_STMT_COMMIT:
dump_commit((PLpgSQL_stmt_commit*)stmt);
break;
case PLPGSQL_STMT_ROLLBACK:
dump_rollback((PLpgSQL_stmt_rollback*)stmt);
break;
default:
ereport(ERROR,
(errmodule(MOD_PLSQL),
@ -1137,6 +1164,18 @@ static void dump_null(PLpgSQL_stmt* stmt)
printf("NULL\n");
}
static void dump_commit(PLpgSQL_stmt_commit* stmt)
{
dump_ind();
printf("COMMIT\n");
}
static void dump_rollback(PLpgSQL_stmt_rollback* stmt)
{
dump_ind();
printf("ROLLBACK\n");
}
static void dump_exit(PLpgSQL_stmt_exit* stmt)
{
dump_ind();

View File

@ -86,8 +86,8 @@ static const int num_reserved_keywords = lengthof(reserved_keywords);
static const ScanKeyword unreserved_keywords[] = {
PG_KEYWORD("absolute", K_ABSOLUTE, UNRESERVED_KEYWORD) PG_KEYWORD("alias", K_ALIAS, UNRESERVED_KEYWORD) PG_KEYWORD(
"alter", K_ALTER, UNRESERVED_KEYWORD) PG_KEYWORD("array", K_ARRAY, UNRESERVED_KEYWORD) PG_KEYWORD("backward",
K_BACKWARD, UNRESERVED_KEYWORD) PG_KEYWORD("constant", K_CONSTANT, UNRESERVED_KEYWORD) PG_KEYWORD("continue",
K_CONTINUE, UNRESERVED_KEYWORD) PG_KEYWORD("current", K_CURRENT, UNRESERVED_KEYWORD) PG_KEYWORD("cursor",
K_BACKWARD, UNRESERVED_KEYWORD) PG_KEYWORD("constant", K_CONSTANT, UNRESERVED_KEYWORD) PG_KEYWORD("commit", K_COMMIT, UNRESERVED_KEYWORD)
PG_KEYWORD("continue", K_CONTINUE, UNRESERVED_KEYWORD) PG_KEYWORD("current", K_CURRENT, UNRESERVED_KEYWORD) PG_KEYWORD("cursor",
K_CURSOR, UNRESERVED_KEYWORD) PG_KEYWORD("debug", K_DEBUG, UNRESERVED_KEYWORD) PG_KEYWORD("detail", K_DETAIL,
UNRESERVED_KEYWORD) PG_KEYWORD("dump", K_DUMP, UNRESERVED_KEYWORD) PG_KEYWORD("errcode", K_ERRCODE,
UNRESERVED_KEYWORD) PG_KEYWORD("error", K_ERROR, UNRESERVED_KEYWORD) PG_KEYWORD("first", K_FIRST,
@ -104,7 +104,7 @@ static const ScanKeyword unreserved_keywords[] = {
PG_KEYWORD("query", K_QUERY, UNRESERVED_KEYWORD) PG_KEYWORD("record", K_RECORD, UNRESERVED_KEYWORD)
PG_KEYWORD("relative", K_RELATIVE, UNRESERVED_KEYWORD) PG_KEYWORD("result_oid", K_RESULT_OID,
UNRESERVED_KEYWORD) PG_KEYWORD("returned_sqlstate", K_RETURNED_SQLSTATE, UNRESERVED_KEYWORD)
PG_KEYWORD("reverse", K_REVERSE, UNRESERVED_KEYWORD) PG_KEYWORD("row_count", K_ROW_COUNT,
PG_KEYWORD("reverse", K_REVERSE, UNRESERVED_KEYWORD) PG_KEYWORD("rollback", K_ROLLBACK, UNRESERVED_KEYWORD) PG_KEYWORD("row_count", K_ROW_COUNT,
UNRESERVED_KEYWORD) PG_KEYWORD("rowtype", K_ROWTYPE, UNRESERVED_KEYWORD)
PG_KEYWORD("savepoint", K_SAVEPOINT, UNRESERVED_KEYWORD) PG_KEYWORD(
"scroll", K_SCROLL, UNRESERVED_KEYWORD) PG_KEYWORD("slice", K_SLICE, UNRESERVED_KEYWORD)

View File

@ -116,7 +116,9 @@ enum PLpgSQL_stmt_types {
PLPGSQL_STMT_FETCH,
PLPGSQL_STMT_CLOSE,
PLPGSQL_STMT_PERFORM,
PLPGSQL_STMT_NULL
PLPGSQL_STMT_NULL,
PLPGSQL_STMT_COMMIT,
PLPGSQL_STMT_ROLLBACK
};
/* ----------
@ -399,6 +401,23 @@ typedef struct { /* PERFORM statement */
PLpgSQL_expr* expr;
} PLpgSQL_stmt_perform;
/*
* COMMIT statement
*/
typedef struct PLpgSQL_stmt_commit {
int cmd_type;
int lineno;
} PLpgSQL_stmt_commit;
/*
* ROLLBACK statement
*/
typedef struct PLpgSQL_stmt_rollback {
int cmd_type;
int lineno;
} PLpgSQL_stmt_rollback;
typedef struct { /* Get Diagnostics item */
int kind; /* id for diagnostic value desired */
int target; /* where to assign it */

View File

@ -114,7 +114,9 @@ enum PLpgSQL_stmt_types {
PLPGSQL_STMT_FETCH,
PLPGSQL_STMT_CLOSE,
PLPGSQL_STMT_PERFORM,
PLPGSQL_STMT_NULL
PLPGSQL_STMT_NULL,
PLPGSQL_STMT_COMMIT,
PLPGSQL_STMT_ROLLBACK
};
/* ----------
@ -397,6 +399,22 @@ typedef struct { /* PERFORM statement */
PLpgSQL_expr* expr;
} PLpgSQL_stmt_perform;
/*
* COMMIT statement
*/
typedef struct PLpgSQL_stmt_commit {
int cmd_type;
int lineno;
} PLpgSQL_stmt_commit;
/*
* ROLLBACK statement
*/
typedef struct PLpgSQL_stmt_rollback {
int cmd_type;
int lineno;
} PLpgSQL_stmt_commit;
typedef struct { /* Get Diagnostics item */
int kind; /* id for diagnostic value desired */
int target; /* where to assign it */

View File

@ -369,6 +369,25 @@ BEGIN
END;
/
--CREATE USER USER2 PASSWORD 'ttest@123';
-------------------------------------------------------
-- Test COMMIT/ROLLBACK
-------------------------------------------------------
CREATE TABLE t_transaction(id INTEGER);
CREATE OR REPLACE PROCDURE proc_callas_transaction
AS
BEGIN
INSERT INTO t_transaction VALUES(1);
COMMIT;
INSERT INTO t_transaction VALUES(10);
ROLLBACK;
END;
/
CALL proc_callas_transaction();
proc_callas_transaction
-------------------------
(1 row)
-------------------------------------------------------
-- Clean up Test envirment
-------------------------------------------------------
@ -377,7 +396,9 @@ DROP FUNCTION func_def_arg;
DROP PROCEDURE test_multi_level;
DROP PROCEDURE proc_callas_definer;
DROP PROCEDURE proc_callas_curr_user;
DROP PROCEDURE proc_callas_transaction;
DROP TABLE t_priv;
DROP TABLE t_transaction;
create or replace procedure test_blank (a int)
as

View File

@ -266,6 +266,20 @@ END;
/
--CREATE USER USER2 PASSWORD 'ttest@123';
-------------------------------------------------------
-- Test COMMIT/ROLLBACK
-------------------------------------------------------
CREATE TABLE t_transaction(id INTEGER);
CREATE OR REPLACE PROCDURE proc_callas_transaction
AS
BEGIN
INSERT INTO t_transaction VALUES(1);
COMMIT;
INSERT INTO t_transaction VALUES(10);
ROLLBACK;
END;
/
CALL proc_callas_transaction();
-------------------------------------------------------
-- Clean up Test envirment
-------------------------------------------------------
@ -274,7 +288,9 @@ DROP FUNCTION func_def_arg;
DROP PROCEDURE test_multi_level;
DROP PROCEDURE proc_callas_definer;
DROP PROCEDURE proc_callas_curr_user;
DROP PROCDURE proc_callas_transaction;
DROP TABLE t_priv;
DROP TABLE t_transaction;
create or replace procedure test_blank (a int)