[Review] Prevent the specification of conflicting transaction read/write options

From: Amit Kapila <amit(dot)kapila(at)huawei(dot)com>
To: <chetan(dot)suttraway(at)enterprisedb(dot)com>, "'Pg Hackers'" <pgsql-hackers(at)postgresql(dot)org>
Subject: [Review] Prevent the specification of conflicting transaction read/write options
Date: 2012-06-18 19:47:07
Message-ID: 00bf01cd4d8b$2558c560$700a5020$@kapila@huawei.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

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

Browse pgsql-hackers by date

  From Date Subject
Next Message Jeff Davis 2012-06-18 19:55:27 Re: initdb and fsync
Previous Message Alvaro Herrera 2012-06-18 19:43:52 Re: initdb and fsync