Allowing regular identifiers in isolationtester scripts - Mailing list pgsql-hackers
From | Tom Lane |
---|---|
Subject | Allowing regular identifiers in isolationtester scripts |
Date | |
Msg-id | 759113.1623861959@sss.pgh.pa.us Whole thread Raw |
List | pgsql-hackers |
[ new subject, new thread, new patch ] Alvaro Herrera <alvherre@alvh.no-ip.org> writes: > On 2021-Jun-16, Tom Lane wrote: >> BTW, as long as we're thinking of back-patching nontrivial specfile >> changes, I have another modest proposal. What do people think of >> removing the requirement for step/session names to be double-quoted, >> and instead letting them work like SQL identifiers? > Yes *please*. Here's a draft patch for that. I converted one specfile just as proof-of-concept, but I don't want to touch the rest until the other patch has gone in, or I'll have merge problems. (This'll have some merge problems with that anyway I fear, but they'll be minor.) I decided to follow the standard SQL rule that you can use "foo""bar" to include a double-quote in a quoted identifier. This broke one place in test_decoding's oldest_xmin.spec where somebody had left out a space. So maybe there's an argument for not doing that --- but I'd rather not document more inconsistencies than I have to. regards, tom lane diff --git a/contrib/test_decoding/specs/oldest_xmin.spec b/contrib/test_decoding/specs/oldest_xmin.spec index da3a8cd512..88bd30f5ff 100644 --- a/contrib/test_decoding/specs/oldest_xmin.spec +++ b/contrib/test_decoding/specs/oldest_xmin.spec @@ -39,4 +39,4 @@ step "s1_commit" { COMMIT; } # composite type is a rare form of DDL which allows T1 to see the tuple which # will be removed (xmax set) before T1 commits. That is, interlocking doesn't # forbid modifying catalog after someone read it (and didn't commit yet). -permutation "s0_begin" "s0_getxid" "s1_begin" "s1_insert" "s0_alter" "s0_commit" "s0_checkpoint" "s0_get_changes" "s0_get_changes""s1_commit""s0_vacuum" "s0_get_changes" +permutation "s0_begin" "s0_getxid" "s1_begin" "s1_insert" "s0_alter" "s0_commit" "s0_checkpoint" "s0_get_changes" "s0_get_changes""s1_commit" "s0_vacuum" "s0_get_changes" diff --git a/src/test/isolation/README b/src/test/isolation/README index 6ae7152325..439b1d32b2 100644 --- a/src/test/isolation/README +++ b/src/test/isolation/README @@ -75,7 +75,7 @@ teardown { <SQL> } this to clean up in preparation for the next permutation, e.g dropping any test tables created by setup. This part is optional. -session "<name>" +session <name> There are normally several "session" parts in a spec file. Each session is executed in its own connection. A session part consists @@ -86,13 +86,13 @@ session "<name>" Each step has the syntax - step "<name>" { <SQL> } + step <name> { <SQL> } where <name> is a name identifying this step, and SQL is a SQL statement (or statements, separated by semicolons) that is executed in the step. Step names must be unique across the whole spec file. -permutation "<step name>" ... +permutation <step name> ... A permutation line specifies a list of steps that are run in that order. Any number of permutation lines can appear. If no permutation lines are @@ -103,6 +103,13 @@ permutation "<step name>" ... available steps; it could for instance repeat some steps more than once, or leave others out. +Session and step names are SQL identifiers or quoted identifiers. +A difference from standard SQL is that no case-folding occurs, so +FOO and "FOO" are the same name while FOO and Foo are different, +whether you quote them or not. You must use double quotes if you +want to use an isolation test keyword (such as "permutation") as +a name. + Lines beginning with a # are considered comments. For each permutation of the session steps (whether these are manually diff --git a/src/test/isolation/specparse.y b/src/test/isolation/specparse.y index ae3a999961..efdf333b00 100644 --- a/src/test/isolation/specparse.y +++ b/src/test/isolation/specparse.y @@ -39,12 +39,12 @@ TestSpec parseresult; /* result of parsing is left here */ %type <str> opt_setup opt_teardown %type <str> setup %type <ptr_list> step_list session_list permutation_list opt_permutation_list -%type <ptr_list> string_literal_list +%type <ptr_list> identifier_list %type <session> session %type <step> step %type <permutation> permutation -%token <str> sqlblock string_literal +%token <str> sqlblock identifier %token PERMUTATION SESSION SETUP STEP TEARDOWN TEST %% @@ -111,7 +111,7 @@ session_list: ; session: - SESSION string_literal opt_setup step_list opt_teardown + SESSION identifier opt_setup step_list opt_teardown { $$ = pg_malloc(sizeof(Session)); $$->name = $2; @@ -140,7 +140,7 @@ step_list: step: - STEP string_literal sqlblock + STEP identifier sqlblock { $$ = pg_malloc(sizeof(Step)); $$->name = $2; @@ -180,7 +180,7 @@ permutation_list: permutation: - PERMUTATION string_literal_list + PERMUTATION identifier_list { $$ = pg_malloc(sizeof(Permutation)); $$->stepnames = (char **) $2.elements; @@ -188,15 +188,15 @@ permutation: } ; -string_literal_list: - string_literal_list string_literal +identifier_list: + identifier_list identifier { $$.elements = pg_realloc($1.elements, ($1.nelements + 1) * sizeof(void *)); $$.elements[$1.nelements] = $2; $$.nelements = $1.nelements + 1; } - | string_literal + | identifier { $$.nelements = 1; $$.elements = pg_malloc(sizeof(void *)); diff --git a/src/test/isolation/specs/aborted-keyrevoke.spec b/src/test/isolation/specs/aborted-keyrevoke.spec index 08945d8b31..4f6f9027cc 100644 --- a/src/test/isolation/specs/aborted-keyrevoke.spec +++ b/src/test/isolation/specs/aborted-keyrevoke.spec @@ -17,30 +17,30 @@ teardown DROP TABLE foo; } -session "s1" +session s1 setup { BEGIN; } -step "s1s" { SAVEPOINT f; } -step "s1u" { UPDATE foo SET key = 2; } # obtain KEY REVOKE -step "s1r" { ROLLBACK TO f; } # lose KEY REVOKE -step "s1l" { SELECT * FROM foo FOR KEY SHARE; } -step "s1c" { COMMIT; } +step s1s { SAVEPOINT f; } +step s1u { UPDATE foo SET key = 2; } # obtain KEY REVOKE +step s1r { ROLLBACK TO f; } # lose KEY REVOKE +step s1l { SELECT * FROM foo FOR KEY SHARE; } +step s1c { COMMIT; } -session "s2" +session s2 setup { BEGIN; } -step "s2l" { SELECT * FROM foo FOR KEY SHARE; } -step "s2c" { COMMIT; } +step s2l { SELECT * FROM foo FOR KEY SHARE; } +step s2c { COMMIT; } -permutation "s1s" "s1u" "s1r" "s1l" "s1c" "s2l" "s2c" -permutation "s1s" "s1u" "s1r" "s1l" "s2l" "s1c" "s2c" -permutation "s1s" "s1u" "s1r" "s1l" "s2l" "s2c" "s1c" -permutation "s1s" "s1u" "s1r" "s2l" "s1l" "s1c" "s2c" -permutation "s1s" "s1u" "s1r" "s2l" "s1l" "s2c" "s1c" -permutation "s1s" "s1u" "s1r" "s2l" "s2c" "s1l" "s1c" -permutation "s1s" "s1u" "s2l" "s1r" "s1l" "s1c" "s2c" -permutation "s1s" "s1u" "s2l" "s1r" "s1l" "s2c" "s1c" -permutation "s1s" "s1u" "s2l" "s1r" "s2c" "s1l" "s1c" -permutation "s1s" "s2l" "s1u" "s2c" "s1r" "s1l" "s1c" -permutation "s1s" "s2l" "s2c" "s1u" "s1r" "s1l" "s1c" -permutation "s2l" "s1s" "s1u" "s2c" "s1r" "s1l" "s1c" -permutation "s2l" "s1s" "s2c" "s1u" "s1r" "s1l" "s1c" -permutation "s2l" "s2c" "s1s" "s1u" "s1r" "s1l" "s1c" +permutation s1s s1u s1r s1l s1c s2l s2c +permutation s1s s1u s1r s1l s2l s1c s2c +permutation s1s s1u s1r s1l s2l s2c s1c +permutation s1s s1u s1r s2l s1l s1c s2c +permutation s1s s1u s1r s2l s1l s2c s1c +permutation s1s s1u s1r s2l s2c s1l s1c +permutation s1s s1u s2l s1r s1l s1c s2c +permutation s1s s1u s2l s1r s1l s2c s1c +permutation s1s s1u s2l s1r s2c s1l s1c +permutation s1s s2l s1u s2c s1r s1l s1c +permutation s1s s2l s2c s1u s1r s1l s1c +permutation s2l s1s s1u s2c s1r s1l s1c +permutation s2l s1s s2c s1u s1r s1l s1c +permutation s2l s2c s1s s1u s1r s1l s1c diff --git a/src/test/isolation/specscanner.l b/src/test/isolation/specscanner.l index 19883c265b..01f39fe05f 100644 --- a/src/test/isolation/specscanner.l +++ b/src/test/isolation/specscanner.l @@ -34,13 +34,19 @@ static void addlitchar(char c); %x sql -%x qstr +%x qident non_newline [^\n\r] space [ \t\r\f] comment ("#"{non_newline}*) +digit [0-9] +ident_start [A-Za-z\200-\377_] +ident_cont [A-Za-z\200-\377_0-9\$] + +identifier {ident_start}{ident_cont}* + %% %{ @@ -48,32 +54,42 @@ comment ("#"{non_newline}*) litbufsize = LITBUF_INIT; %} + /* Keywords (must appear before the {identifier} rule!) */ permutation { return PERMUTATION; } session { return SESSION; } setup { return SETUP; } step { return STEP; } teardown { return TEARDOWN; } + /* Whitespace and comments */ [\n] { yyline++; } {comment} { /* ignore */ } {space} { /* ignore */ } - /* Quoted strings: "foo" */ + /* Plain identifiers */ +{identifier} { + yylval.str = pg_strdup(yytext); + return(identifier); + } + + /* Quoted identifiers: "foo" */ \" { litbufpos = 0; - BEGIN(qstr); + BEGIN(qident); } -<qstr>\" { +<qident>\"\" { addlitchar(yytext[0]); } +<qident>\" { litbuf[litbufpos] = '\0'; yylval.str = pg_strdup(litbuf); BEGIN(INITIAL); - return(string_literal); + return(identifier); } -<qstr>. { addlitchar(yytext[0]); } -<qstr>\n { yyerror("unexpected newline in quoted string"); } -<qstr><<EOF>> { yyerror("unterminated quoted string"); } +<qident>. { addlitchar(yytext[0]); } +<qident>\n { yyerror("unexpected newline in quoted identifier"); } +<qident><<EOF>> { yyerror("unterminated quoted identifier"); } /* SQL blocks: { UPDATE ... } */ + /* We trim leading/trailing whitespace, otherwise they're unprocessed */ "{"{space}* { litbufpos = 0; @@ -96,6 +112,7 @@ teardown { return TEARDOWN; } yyerror("unterminated sql block"); } + /* Anything else is an error */ . { fprintf(stderr, "syntax error at line %d: unexpected character \"%s\"\n", yyline, yytext); exit(1);
pgsql-hackers by date: