Chetan Suttraway <chetan(dot)suttraway(at)enterprisedb(dot)com> wrote:

> This is regarding the TODO item:

> "Prevent the specification of conflicting transaction read/write

> options"

> 

> listed at:

> http://wiki.postgresql.org/wiki/Todo

 

Here's my review of this patch. 

Basic stuff: 
------------ 

- Patch applies OK 
- Compiles cleanly with no warnings 
- changes in gram.y do not introduce any conflicts. 
- Regression tests pass. 
- Documentation changes not required as the scenario is obvious. 

What it does: 
----------------------------- 
Prevent the specification of conflicting transaction mode options 
in the commands such as 
START/BEGIN TRANSACTION, SET TRANSACTION, SET SESSION CHARACTERISTICS AS
TRANSACTION transaction_mode. 

Conflicting transaction modes include 
1. READ WRITE | READ ONLY 

2. ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ
UNCOMMITTED } 

3. DEFERRABLE | NOT DEFERABLE 

 

The changes are done in gram.y file to add a new function which checks for
conflicting transaction modes.
  

Testing: 
------------ 

postgres=# BEGIN TRANSACTION read only read write; 
ERROR:  conflicting options 
LINE 1: BEGIN TRANSACTION read only read write; 

postgres=# SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ
COMMITTED ISOLATION LEVEL READ unCOMMITTED; 
ERROR:  conflicting options 
LINE 1: ...ON CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMI... 

postgres=# start transaction deferrable not deferrable; 
ERROR:  conflicting options 
LINE 1: start transaction deferrable not deferrable; 
                          ^ 
postgres=# start transaction deferrable read only not deferrable; 
ERROR:  conflicting options 
LINE 1: start transaction deferrable read only not deferrable; 
                          ^ 
postgres=# start transaction deferrable, read only not deferrable; 
ERROR:  conflicting options 
LINE 1: start transaction deferrable, read only not deferrable; 
                          ^ 
postgres=# start transaction deferrable, read only, not deferrable; 
ERROR:  conflicting options 
LINE 1: start transaction deferrable, read only, not deferrable; 


postgres=# start transaction deferrable, read only, ISOLATION LEVEL READ
COMMITTED; 
START TRANSACTION 
postgres=# commit; 
COMMIT 
postgres=# start transaction deferrable, read only, ISOLATION LEVEL READ
UNCOMMITTED; 
START TRANSACTION 
postgres=# commit; 
COMMIT 
postgres=# start transaction deferrable, read only, ISOLATION LEVEL READ
UNCOMMITTED, read only; 
START TRANSACTION 
                                                             ^ 
postgres=# SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ
COMMITTED ISOLATION LEVEL READ COMMITTED; 
SET 
                          ^ 


Code Review Comments
---------------------------------------------- 

1. Complexity of function check_trans_mode is high (n^2) can be changed to n

   we shall not add the duplicate elements in 
   transaction_mode_list: 
                        transaction_mode_item 
                                        { $$ = list_make1($1); } 
                        | transaction_mode_list ',' transaction_mode_item 
                                        { 
                                                check_trans_mode((List *)$1,
(DefElem *)$3, yyscanner); 
                                                $$ = lappend($1, $3); 
                                        } 

                        | transaction_mode_list transaction_mode_item 
                                        { 
                                                check_trans_mode((List *)$1,
(DefElem *)$2, yyscanner); 
                                                $$ = lappend($1, $2); 
                                        } 

   i,e if "start transaction read only read only" is given then add the mode
"read only" to the list only for the first time. 
   If so length of the valid list is limited to maximum 3 elements(modes) (1
ISOLATION LEVEL, 1 READ WRITE/READ ONLY, 1 DEFERRABLE). 
   This will reduce the search complexity of check_trans_mode to 3n = n. 

2. during parse when you call check_trans_mode((List *)$1, (DefElem *)$3,
yyscanner); what is the need 
   of casting first and second parameter? 

3. The comment describing function can be more specific 
   patch - checks for conflicting transaction modes by looking up current
element in the given list. 
   suggested - checks for conflicting transaction modes by looking current
transaction mode element 
               in the given transaction mode list. 
  
4. names used for function parameters and variables can be more meaningful. 
   a. check_trans_mode(List *list, DefElem *elem, core_yyscan_t yyscanner) 
   for first parameter instead of list, you can use modes, it can better
suggest the meaning of parameter. 
   for second parameter instead of elem, you can use mode or input_mode; or
if something better is coming to your which can better suggest the meaning. 
    
   b. A_Const *elem_arg; can be changed input_mode_arg 
   c. DefElem *next; - mode_item 
      A_Const *arg;  - mode_item_arg 

5. elem_arg->val.val.str, other places in code access the string or integer
by using strVal or intVal. 

6. Code which checks duplicate value should be as follows. Please refer
function ExecSetVariableStmt, case VAR_SET_MULTI 
    if (strcmp(elem->defname,"transaction_isolation") == 0) 
     ... 
    else if (strcmp(elem->defname,"transaction_read_only") == 0) 
      ... 
    else if (strcmp(elem->defname,"transaction_deferrable") == 0) 
      ... 
    else 
         elog(ERROR, "option \"%s\" not recognized", 
                                 elem->defname) 

7. Cursor which indicates where the error has occurred is pointing to first
occurrence of the parameter rather than where exactly the conflict happened.
In below example the cursor should point to read only.   

I am not sure whether this is okay or not. Committer can give suggestions if
it needs to be corrected


postgres=# start transaction deferrable, read write, ISOLATION LEVEL READ
UNCOMMITTED, read only; 
ERROR:  conflicting options 
LINE 1: start transaction deferrable, read write, ISOLATION LEVEL RE... 

                                      ^ 

Conclusion

----------------------------------------------

 

The patch needs to updated. 

1. Regression suite should be updated with test cases.

2.  Code should be modified for Code Review Comments.

 

So I am marking this as Waiting on Author

 

With Regards,

Amit Kapila

Reply via email to