if (FD_ISSET(frontend->fd, &readmask))
{
- pool_debug("XXXX");
status = ProcessFrontendResponse(frontend, backend);
if (status != POOL_CONTINUE)
return status;
}
/* this is the synchronous point */
- if (REPLICATION || first_ready_for_query_received)
+ if (DUAL_MODE || first_ready_for_query_received)
{
if (kind == 0)
{
return POOL_CONTINUE;
}
- if (frontend &&
- (strncasecmp("prepare", string, 7) == 0))
+ if (strncasecmp("prepare", string, 7) == 0)
{
- PreparedStatement *stmt;
-
- stmt = get_prepared_command_portal_and_statement(string);
+ if (DUAL_MODE)
+ force_replication = 1;
- if (stmt != NULL)
+ if (frontend)
{
- pending_function = add_prepared_list;
- pending_prepared_stmt = stmt;
- if (REPLICATION)
- force_replication = 1;
- prepare_in_session = 1;
+ PreparedStatement *stmt;
+
+ stmt = get_prepared_command_portal_and_statement(string);
+
+ if (stmt != NULL)
+ {
+ pending_function = add_prepared_list;
+ pending_prepared_stmt = stmt;
+ if (DUAL_MODE)
+ force_replication = 1;
+ prepare_in_session = 1;
+ }
}
}
- else if (frontend &&
- strncasecmp("deallocate", string, 10) == 0)
+ else if (strncasecmp("deallocate", string, 10) == 0)
{
- char *query = string;
- char *buf, *name;
- query = skip_comment(query);
+ if (DUAL_MODE)
+ force_replication = 1;
- /* skip "prepare" or "deallocate" */
- while (*query && !isspace(*query))
- query++;
+ if (frontend)
+ {
+ char *query = string;
+ char *buf, *name;
+ query = skip_comment(query);
- /* skip spaces */
- while (*query && isspace(*query))
- query++;
+ /* skip "prepare" or "deallocate" */
+ while (*query && !isspace(*query))
+ query++;
- buf = strdup(query);
- name = strtok(buf, "\t\r\n (;");
+ /* skip spaces */
+ while (*query && isspace(*query))
+ query++;
- pending_function = del_prepared_list;
- pending_prepared_stmt = malloc(sizeof(PreparedStatement));
- if (pending_prepared_stmt == NULL)
- {
- pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
- return POOL_END;
- }
+ buf = strdup(query);
+ name = strtok(buf, "\t\r\n (;");
- pending_prepared_stmt->statement_name = normalize_prepared_stmt_name(name);
- pending_prepared_stmt->portal_name = NULL;
- if (pending_prepared_stmt->statement_name == NULL)
- {
- pool_error("SimpleForwardToBackend: strdup failed: %s", strerror(errno));
- return POOL_END;
+ pending_function = del_prepared_list;
+ pending_prepared_stmt = malloc(sizeof(PreparedStatement));
+ if (pending_prepared_stmt == NULL)
+ {
+ pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
+ return POOL_END;
+ }
+
+ pending_prepared_stmt->statement_name = normalize_prepared_stmt_name(name);
+ pending_prepared_stmt->portal_name = NULL;
+ if (pending_prepared_stmt->statement_name == NULL)
+ {
+ pool_error("SimpleForwardToBackend: strdup failed: %s", strerror(errno));
+ return POOL_END;
+ }
+ free(buf);
}
- free(buf);
- if (REPLICATION)
- force_replication = 1;
}
if (frontend &&
else if (send_extended_protocol_message(cp, "P", len, string))
return POOL_END;
- if (!REPLICATION)
+ if (!DUAL_MODE)
break;
else if (pool_config.replication_strict)
{
/* set transaction state */
pool_debug("ReadyForQuery: transaction state: %c", state);
MASTER(backend)->tstate = state;
- if (REPLICATION)
+ if (DUAL_MODE)
SECONDARY(backend)->tstate = state;
for (i = 0;i < backend->num;i++)
pool_debug("ReadyForQuery: message length: %d", len);
- state = pool_read_kind(backend);
- if (state < 0)
- return POOL_END;
- /* set transaction state */
- pool_debug("ReadyForQuery: transaction state: %c", state);
- MASTER(backend)->tstate = state;
- if (REPLICATION)
+ /*
+ * Do not check transaction state in master/slave mode.
+ * Because SET, PREPARE, DEALLOCATE are replicated.
+ * If these queries are executed inside a transaction block,
+ * transation state is inconsistency. But it is no problem.
+ */
+ if (MASTER_SLAVE)
+ {
+ char kind1;
+
+ pool_read(MASTER(backend), &state, 1);
+ MASTER(backend)->tstate = state;
+ pool_read(SECONDARY(backend), &kind1, 1);
SECONDARY(backend)->tstate = state;
+ }
+ else
+ {
+ state = pool_read_kind(backend);
+ if (state < 0)
+ return POOL_END;
+
+ /* set transaction state */
+ pool_debug("ReadyForQuery: transaction state: %c", state);
+ MASTER(backend)->tstate = state;
+ if (REPLICATION)
+ SECONDARY(backend)->tstate = state;
+ }
}
if (send_ready)
default:
if (MAJOR(backend) == PROTO_MAJOR_V3)
{
- if (MASTER_SLAVE)
+ if (MASTER_SLAVE && TSTATE(backend) != 'I')
{
master_slave_was_enabled = 1;
MASTER_SLAVE = 0;
status = SimpleForwardToBackend(fkind, frontend, backend);
if (pool_flush(MASTER(backend)))
status = POOL_ERROR;
- if (REPLICATION)
+ if (DUAL_MODE)
if (pool_flush(SECONDARY(backend)))
status = POOL_ERROR;
}
return POOL_END;
}
- if (REPLICATION)
+ if (REPLICATION || MASTER_SLAVE)
{
status = pool_read(SECONDARY(backend), &len1, sizeof(len1));
if (status < 0)
if (p == NULL)
return POOL_END;
- if (REPLICATION)
+ if (DUAL_MODE)
{
len1 = ntohl(len1) - 4;
if (len1 <= 0)
return POOL_END;
}
- if (!REPLICATION)
+ if (!DUAL_MODE)
break;
}
if (p1 == NULL)
return POOL_END;
- if (REPLICATION)
+ if (DUAL_MODE)
{
status = pool_read(SECONDARY(backend), &res2, sizeof(res2));
if (status < 0)
if (pool_write(MASTER(backend), &kind, 1))
return POOL_END;
- if (REPLICATION)
+ if (DUAL_MODE)
if (pool_write(SECONDARY(backend), &kind, 1))
return POOL_END;
if (pool_write(MASTER(backend), &sendlen, sizeof(sendlen)))
return POOL_END;
- if (REPLICATION)
+ if (DUAL_MODE)
if (pool_write(SECONDARY(backend), &sendlen, sizeof(sendlen)))
return POOL_END;
if (pool_write(MASTER(backend), p, len))
return POOL_END;
- if (REPLICATION)
+ if (DUAL_MODE)
if (pool_write(SECONDARY(backend), p, len))
return POOL_END;
return POOL_END;
}
- if (!REPLICATION)
+ if (!DUAL_MODE)
break;
}
if (pool_flush(MASTER(backend)))
return POOL_END;
- if (REPLICATION)
+ if (DUAL_MODE)
if (pool_flush(SECONDARY(backend)))
return POOL_END;
}