From 625a5e64db7177766447dcc207b5c4b8dda904bb Mon Sep 17 00:00:00 2001 From: Hiroshi Inoue Date: Sun, 25 Oct 2009 12:42:43 +0000 Subject: [PATCH] 1. Take WITH cte staments into account. 2. Fix a bug about UTF8 handling. 3. Wait a ReadyForQuery Message after errors correctly. --- connection.c | 3 +-- convert.c | 4 ++-- execute.c | 4 ++-- multibyte.c | 2 +- qresult.c | 6 ++++-- results.c | 6 +++--- statement.c | 5 ++++- statement.h | 2 ++ version.h | 2 +- 9 files changed, 20 insertions(+), 14 deletions(-) diff --git a/connection.c b/connection.c index e75b23d..3080c37 100644 --- a/connection.c +++ b/connection.c @@ -2789,12 +2789,11 @@ inolog("Discarded the first SAVEPOINT\n"); if (!QR_fetch_tuples(res, self, cursor)) { CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(res), func); - ReadyToReturn = TRUE; if (PORES_FATAL_ERROR == QR_get_rstatus(res)) retres = cmdres; else retres = NULL; - break; + aborted = TRUE; } query_completed = TRUE; } diff --git a/convert.c b/convert.c index fbb97d7..f08bcdd 100644 --- a/convert.c +++ b/convert.c @@ -2589,7 +2589,7 @@ inolog("type=%d concur=%d\n", stmt->options.cursor_type, stmt->options.scroll_co SC_no_fetchcursor(stmt); SC_no_pre_executable(stmt); - if (stmt->statement_type == STMT_TYPE_SELECT) + if (SC_returns_rows(stmt)) SC_set_pre_executable(stmt); qb = &query_crt; qb->query_statement = NULL; @@ -2608,7 +2608,7 @@ inolog("type=%d concur=%d\n", stmt->options.cursor_type, stmt->options.scroll_co new_statement = qb->query_statement; /* For selects, prepend a declare cursor to the statement */ - if (stmt->statement_type == STMT_TYPE_SELECT && !stmt->internal) + if (SC_returns_rows(stmt) && !stmt->internal) { const char *opt_scroll = NULL_STRING, *opt_hold = NULL_STRING; diff --git a/execute.c b/execute.c index ff216d7..7f55eb1 100644 --- a/execute.c +++ b/execute.c @@ -231,7 +231,7 @@ inquireHowToPrepare(const StatementClass *stmt) ret = PARSE_REQ_FOR_INFO; else if (PROTOCOL_74(ci)) { - if (STMT_TYPE_SELECT == stmt->statement_type) + if (SC_returns_rows(stmt)) { if (ci->drivers.use_declarefetch) return PARSE_REQ_FOR_INFO; @@ -245,7 +245,7 @@ inquireHowToPrepare(const StatementClass *stmt) } else { - if (STMT_TYPE_SELECT == stmt->statement_type && + if (SC_returns_rows(stmt) && (SQL_CURSOR_FORWARD_ONLY != stmt->options.cursor_type || ci->drivers.use_declarefetch)) ret = PREPARE_BY_THE_DRIVER; diff --git a/multibyte.c b/multibyte.c index 8c18998..1f8ff71 100644 --- a/multibyte.c +++ b/multibyte.c @@ -248,7 +248,7 @@ pg_CS_stat(int stat,unsigned int character,int characterset_code) else if (character >= 0xc0) stat = 2; } - else if (stat > 2 && + else if (stat >= 2 && character > 0x7f) stat--; else diff --git a/qresult.c b/qresult.c index 9b8fd72..3d86cfe 100644 --- a/qresult.c +++ b/qresult.c @@ -686,7 +686,7 @@ QR_get_tupledata(QResultClass *self, BOOL binary) BOOL haskeyset = QR_haskeyset(self); SQLULEN num_total_rows = QR_get_num_total_tuples(self); -inolog("QR_get_tupledata num_fields=%d\n", self->num_fields); +inolog("QR_get_tupledata %p->num_fields=%d\n", self, self->num_fields); if (!QR_get_cursor(self)) { @@ -1229,7 +1229,9 @@ inolog("id='%c' response_length=%d\n", id, response_length); mylog("ERROR from backend in next_tuple: '%s'\n", msgbuffer); qlog("ERROR from backend in next_tuple: '%s'\n", msgbuffer); - rcvend = TRUE; + if (!internally_invoked || + PG_VERSION_LE(conn, 6.3)) + rcvend = TRUE; ret = FALSE; break; diff --git a/results.c b/results.c index 56865c9..4859706 100644 --- a/results.c +++ b/results.c @@ -286,7 +286,7 @@ inolog("answering bookmark info\n"); fi = NULL; if (icol < irdflds->nfields && irdflds->fi) fi = irdflds->fi[icol]; - if (!FI_is_applicable(fi) && !stmt->catalog_result && SC_is_parse_forced(stmt) && STMT_TYPE_SELECT == stmt->statement_type) + if (!FI_is_applicable(fi) && !stmt->catalog_result && SC_is_parse_forced(stmt) && SC_returns_rows(stmt)) { if (SC_parsed_status(stmt) == STMT_PARSE_NONE) { @@ -1171,7 +1171,7 @@ PGAPI_Fetch( if (opts->bindings == NULL) { - if (stmt->statement_type != STMT_TYPE_SELECT) + if (!SC_returns_rows(stmt)) return SQL_NO_DATA_FOUND; /* just to avoid a crash if the user insists on calling this */ /* function even if SQL_ExecDirect has reported an Error */ @@ -1460,7 +1460,7 @@ PGAPI_ExtendedFetch( if (opts->bindings == NULL) { - if (stmt->statement_type != STMT_TYPE_SELECT) + if (!SC_returns_rows(stmt)) return SQL_NO_DATA_FOUND; /* just to avoid a crash if the user insists on calling this */ /* function even if SQL_ExecDirect has reported an Error */ diff --git a/statement.c b/statement.c index 975a81e..28f0c16 100644 --- a/statement.c +++ b/statement.c @@ -150,6 +150,9 @@ static struct ,{ STMT_TYPE_SPECIAL, "CHECKPOINT" } + ,{ + STMT_TYPE_WITH, "WITH" + } ,{ 0, NULL } @@ -993,7 +996,7 @@ SC_pre_execute(StatementClass *self) mylog(" preprocess: status = READY\n"); self->miscinfo = 0; - if (self->statement_type == STMT_TYPE_SELECT) + if (SC_returns_rows(self)) { char old_pre_executing = self->pre_executing; diff --git a/statement.h b/statement.h index 776cef9..37ade26 100644 --- a/statement.h +++ b/statement.h @@ -105,6 +105,7 @@ enum ,STMT_TYPE_INSERT ,STMT_TYPE_UPDATE ,STMT_TYPE_DELETE + ,STMT_TYPE_WITH ,STMT_TYPE_CREATE ,STMT_TYPE_ALTER ,STMT_TYPE_DROP @@ -426,6 +427,7 @@ enum #define SC_unref_CC_error(a) ((a->ref_CC_error) = FALSE) #define SC_ref_CC_error(a) ((a->ref_CC_error) = TRUE) #define SC_forget_unnamed(a) (PREPARED_TEMPORARILY == (a)->prepared ? SC_set_prepared(a, ONCE_DESCRIBED) : (void) 0) +#define SC_returns_rows(a) (STMT_TYPE_SELECT == (a)->statement_type || STMT_TYPE_WITH == (a)->statement_type) /* For Multi-thread */ diff --git a/version.h b/version.h index 1c63e04..02b5504 100644 --- a/version.h +++ b/version.h @@ -12,6 +12,6 @@ #define POSTGRESDRIVERVERSION "08.04.0101" #define POSTGRES_RESOURCE_VERSION "08.04.0101\0" #define PG_DRVFILE_VERSION 8,4,01,01 -#define PG_BUILD_VERSION "200908270001" +#define PG_BUILD_VERSION "200910250001" #endif -- 2.39.5