fix_set_trans_mode.patch
text/x-diff
Filename: fix_set_trans_mode.patch
Type: text/x-diff
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/parser/gram.y | 63 | 2 |
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 62fde67..28c987f 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -146,6 +146,9 @@ static void processCASbits(int cas_bits, int location, const char *constrType,
bool *deferrable, bool *initdeferred, bool *not_valid,
core_yyscan_t yyscanner);
+static void
+check_trans_mode(List *list, DefElem *elem, core_yyscan_t yyscanner);
+
%}
%pure-parser
@@ -7510,9 +7513,16 @@ transaction_mode_list:
transaction_mode_item
{ $$ = list_make1($1); }
| transaction_mode_list ',' transaction_mode_item
- { $$ = lappend($1, $3); }
+ {
+ check_trans_mode((List *)$1, (DefElem *)$3, yyscanner);
+ $$ = lappend($1, $3);
+ }
+
| transaction_mode_list transaction_mode_item
- { $$ = lappend($1, $2); }
+ {
+ check_trans_mode((List *)$1, (DefElem *)$2, yyscanner);
+ $$ = lappend($1, $2);
+ }
;
transaction_mode_list_or_empty:
@@ -13215,6 +13225,57 @@ parser_init(base_yy_extra_type *yyext)
}
/*
+ * checks for conflicting transaction modes by looking up current
+ * element in the given list.
+ */
+static void
+check_trans_mode(List *list, DefElem *elem, core_yyscan_t yyscanner)
+{
+ ListCell *lc;
+ A_Const *elem_arg;
+
+ elem_arg =(A_Const *) elem->arg;
+
+ /* cannot specify conflicting value for transaction mode. */
+ foreach (lc, list)
+ {
+ DefElem *next;
+ A_Const *arg;
+
+ next = (DefElem*)lfirst (lc);
+ arg = (A_Const *)next->arg;
+
+ /* check for duplicate value in remaining list */
+ if (strcmp(elem->defname, next->defname) == 0)
+ {
+ /*
+ * isolation level values are stored
+ * as string whereas other modes are
+ * stored as integer values.
+ */
+ if (strcmp(elem->defname,"transaction_isolation") == 0)
+ {
+ /* check for conflicting values */
+ if (strcmp(elem_arg->val.val.str,arg->val.val.str)!= 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("conflicting options"),
+ parser_errposition(arg->location)));
+ }
+ else
+ {
+ /* check for conflicting values */
+ if (elem_arg->val.val.ival != arg->val.val.ival)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("conflicting options"),
+ parser_errposition(arg->location)));
+ }
+ }
+ }
+}
+
+/*
* Must undefine this stuff before including scan.c, since it has different
* definitions for these macros.
*/