*/
else if (!is_select_query(node, query))
{
+ /* However, if the query is "SET TRANSACTION READ ONLY" or its variant,
+ * don't set it.
+ */
+ if (!pool_is_transaction_read_only(node))
+ {
+ pool_debug("not SET TRANSACTION READ ONLY");
+ pool_set_writing_transaction();
+ }
+
pool_set_writing_transaction();
}
}
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
*
- * Copyright (c) 2003-2014 PgPool Global Development Group
+ * Copyright (c) 2003-2015 PgPool Global Development Group
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
return rewritten_contents;
}
+
+/*
+ * Return true if one of followings is true
+ *
+ * SET transaction_read_only TO on
+ * SET TRANSACTION READ ONLY
+ * SET TRANSACTION CHARACTERISTICS AS TRANSACTION READ ONLY
+ *
+ * Note that if the node is not a variable statement, returns false.
+ */
+bool pool_is_transaction_read_only(Node *node)
+{
+ ListCell *list_item;
+ bool ret = false;
+
+ if (!IsA(node, VariableSetStmt))
+ return ret;
+
+ /*
+ * SET transaction_read_only TO on
+ */
+ if (((VariableSetStmt *)node)->kind == VAR_SET_VALUE &&
+ !strcmp(((VariableSetStmt *)node)->name, "transaction_read_only"))
+ {
+ List *options = ((VariableSetStmt *)node)->args;
+ foreach(list_item, options)
+ {
+ A_Const *v = (A_Const *)lfirst(list_item);
+
+ switch (v->val.type)
+ {
+ case T_String:
+ if (!strcasecmp(v->val.val.str, "on") ||
+ !strcasecmp(v->val.val.str, "t") ||
+ !strcasecmp(v->val.val.str, "true"))
+ ret = true;
+ break;
+ case T_Integer:
+ if (v->val.val.ival)
+ ret = true;
+ default:
+ break;
+ }
+ }
+ }
+
+ /*
+ * SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY
+ * SET TRANSACTION READ ONLY
+ */
+ else if (((VariableSetStmt *)node)->kind == VAR_SET_MULTI &&
+ (!strcmp(((VariableSetStmt *)node)->name, "TRANSACTION") ||
+ !strcmp(((VariableSetStmt *)node)->name, "SESSION CHARACTERISTICS")))
+ {
+ List *options = ((VariableSetStmt *)node)->args;
+ foreach(list_item, options)
+ {
+ DefElem *opt = (DefElem *) lfirst(list_item);
+
+ if (!strcmp("transaction_read_only", opt->defname))
+ {
+ bool read_only;
+
+ read_only = ((A_Const *)opt->arg)->val.val.ival;
+ if (read_only)
+ {
+ ret = true;
+ break;
+ }
+ }
+ }
+ }
+ return ret;
+}
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
*
- * Copyright (c) 2003-2011 PgPool Global Development Group
+ * Copyright (c) 2003-2015 PgPool Global Development Group
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
extern bool is_2pc_transaction_query(Node *node);
extern void pool_set_query_state(POOL_QUERY_CONTEXT *query_context, POOL_QUERY_STATE state);
extern int statecmp(POOL_QUERY_STATE s1, POOL_QUERY_STATE s2);
+extern bool pool_is_transaction_read_only(Node *node);
#endif /* POOL_QUERY_CONTEXT_H */