conninfo->cvt_null_date_string = -1;
#ifdef _HANDLE_ENLIST_IN_DTC_
conninfo->xa_opt = -1;
- conninfo->autocommit_normal = 0;
+ conninfo->autocommit_public = SQL_AUTOCOMMIT_ON;
#endif /* _HANDLE_ENLIST_IN_DTC_ */
memcpy(&(conninfo->drivers), &globals, sizeof(globals));
}
return ret;
}
+/* This is called by SQLSetConnectOption etc also */
+char
+CC_set_autocommit(ConnectionClass *self, BOOL on)
+{
+ CSTR func = "CC_set_autocommit";
+ BOOL currsts = CC_is_in_autocommit(self);
+
+ if ((on && currsts) ||
+ (!on && !currsts))
+ return on;
+ mylog("%s: %d->%d\n", func, currsts, on);
+ if (CC_is_in_trans(self))
+ CC_commit(self);
+ if (on)
+ self->transact_status |= CONN_IN_AUTOCOMMIT;
+ else
+ self->transact_status &= ~CONN_IN_AUTOCOMMIT;
+
+ return on;
+}
/* This is called by SQLDisconnect also */
char
NULL, IGNORE_ABORT_ON_CONN | ROLLBACK_ON_ERROR, NULL);
if (QR_command_maybe_successful(res) && QR_get_num_cached_tuples(res) > 0)
{
- Oid basetype;
+ OID basetype;
self->lobj_type = QR_get_value_backend_int(res, 0, 0, NULL);
basetype = QR_get_value_backend_int(res, 0, 1, NULL);
#define CONN_IN_ERROR_BEFORE_IDLE (1L<<3)
/* AutoCommit functions */
-#define CC_set_autocommit_off(x) (x->transact_status &= ~CONN_IN_AUTOCOMMIT)
-#define CC_set_autocommit_on(x) (x->transact_status |= CONN_IN_AUTOCOMMIT)
#define CC_is_in_autocommit(x) (x->transact_status & CONN_IN_AUTOCOMMIT)
/* Transaction in/not functions */
signed char cvt_null_date_string;
#ifdef _HANDLE_ENLIST_IN_DTC_
signed char xa_opt;
- signed char autocommit_normal;
+ signed char autocommit_public;
#endif /* _HANDLE_ENLIST_IN_DTC_ */
GLOBAL_VALUES drivers; /* moved from driver's option */
} ConnInfo;
char CC_begin(ConnectionClass *self);
char CC_commit(ConnectionClass *self);
char CC_abort(ConnectionClass *self);
+char CC_set_autocommit(ConnectionClass *self, BOOL on);
int CC_set_translation(ConnectionClass *self);
char CC_connect(ConnectionClass *self, char password_req, char *salt);
char CC_add_statement(ConnectionClass *self, StatementClass *stmt);
stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
else if (stmt->options.scroll_concurrency != SQL_CONCUR_READ_ONLY)
{
- if (SQL_CURSOR_KEYSET_DRIVEN == stmt->options.cursor_type &&
- 0 == (ci->updatable_cursors & ALLOW_KEYSET_DRIVEN_CURSORS))
- stmt->options.cursor_type = SQL_CURSOR_STATIC;
- if (SQL_CURSOR_STATIC == stmt->options.cursor_type &&
- 0 == (ci->updatable_cursors & ALLOW_STATIC_CURSORS))
- stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
- else if (SC_update_not_ready(stmt))
- parse_statement(stmt, TRUE);
+ if (SQL_CURSOR_KEYSET_DRIVEN == stmt->options.cursor_type)
+ {
+ if (0 == (ci->updatable_cursors & ALLOW_KEYSET_DRIVEN_CURSORS))
+ stmt->options.cursor_type = SQL_CURSOR_STATIC;
+ else
+ {
+ if (SC_update_not_ready(stmt))
+ parse_statement(stmt, TRUE);
+ if (stmt->updatable &&
+ stmt->ntab > 0)
+ {
+ if (bestitem = GET_NAME(stmt->ti[0]->bestitem), NULL == bestitem)
+ stmt->options.cursor_type = SQL_CURSOR_STATIC;
+ }
+ }
+ }
+ if (SQL_CURSOR_STATIC == stmt->options.cursor_type)
+ {
+ if (0 == (ci->updatable_cursors & ALLOW_STATIC_CURSORS))
+ stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
+ else if (SC_update_not_ready(stmt))
+ parse_statement(stmt, TRUE);
+ }
if (SC_parsed_status(stmt) == STMT_PARSE_FATAL)
{
stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
qp->from_pos = stmt->from_pos;
qp->where_pos = stmt->where_pos;
}
-inolog("type=%d concur=%d\n",
- stmt->options.cursor_type,
- stmt->options.scroll_concurrency);
+inolog("type=%d concur=%d\n", stmt->options.cursor_type, stmt->options.scroll_concurrency);
}
SC_miscinfo_clear(stmt);
* 2nd query is keyset gathering
*/
CVT_APPEND_STR(qb, " where ctid = '(0,0)';select \"ctid");
- if (stmt && stmt->ntab > 0)
- bestitem = GET_NAME(stmt->ti[0]->bestitem);
- if (!bestitem)
- bestitem = OID_NAME;
- CVT_APPEND_STR(qb, "\", \"");
- CVT_APPEND_STR(qb, bestitem);
+ if (bestitem)
+ {
+ CVT_APPEND_STR(qb, "\", \"");
+ CVT_APPEND_STR(qb, bestitem);
+ }
CVT_APPEND_STR(qb, "\" from ");
CVT_APPEND_DATA(qb, qp->statement + qp->from_pos + 5, npos - qp->from_pos - 5);
}
char qual[32];
STR_TO_NAME(self->bestitem, OID_NAME);
- sprintf(qual, "\"oid\" = %%u");
+ sprintf(qual, "\"%s\" = %%u", OID_NAME);
STR_TO_NAME(self->bestqual, qual);
TI_set_hasoids(self);
TI_set_hasoids_checked(self);
};
+#define SYNC_AUTOCOMMIT(conn) (SQL_AUTOCOMMIT_OFF != conn->connInfo.autocommit_public ? (conn->transact_status |= CONN_IN_AUTOCOMMIT) : (conn->transact_status &= ~CONN_IN_AUTOCOMMIT))
+
IAsyncPG::IAsyncPG(void) : helper(NULL), RMCookie(0), enlist(NULL), conn(NULL), xaconn(NULL), refcnt(1), prepared(false), requestAccepted(false)
{
InterlockedIncrement(&g_cComponents);
if (conn)
{
conn->asdum = NULL;
+ SYNC_AUTOCOMMIT(conn);
conn = NULL;
}
SLOCK_RELEASE();
PGAPI_AllocConnect(conn->henv, (HDBC *) &xaconn);
memcpy(&xaconn->connInfo, &conn->connInfo, sizeof(ConnInfo));
conn->asdum = NULL;
+ SYNC_AUTOCOMMIT(conn);
conn = NULL;
SLOCK_RELEASE();
LIFELOCK_RELEASE;
DWORD rSize;
ret = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, regKey, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &sKey);
+ if (ERROR_SUCCESS != ret)
+ ret = ::RegCreateKeyEx(HKEY_LOCAL_MACHINE, regKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &sKey, NULL);
if (ERROR_SUCCESS == ret)
{
switch (ret = ::RegQueryValueEx(sKey, "XADLL", NULL, NULL, NULL, &rSize))
CC_set_error(conn, CONN_UNSUPPORTED_OPTION, "XARMCreate error:Please register HKLM\\SOFTWARE\\Microsoft\\MSDTC\\XADLL", func);
break;
}
+ ::RegCloseKey(sKey);
}
}
if (!errset)
return SQL_ERROR;
}
- mylog("asdum=%x start transaction\n", asdum);
- CC_set_autocommit_off(conn);
+ mylog("asdum=%p start transaction\n", asdum);
+ CC_set_autocommit(conn, FALSE);
asdum->SetConnection(conn);
conn->asdum = asdum;
EXTERN_C RETCODE EnlistInDtc(ConnectionClass *conn, void *pTra, int method)
{
static ITransactionDispenser *pDtc = NULL;
- ConnInfo *ci = &(conn->connInfo);
if (!pTra)
{
{
/* asdum->Release(); */
}
- if (ci->autocommit_normal)
- CC_set_autocommit_on(conn);
+ else
+ SYNC_AUTOCOMMIT(conn);
return SQL_SUCCESS;
}
if (CC_is_in_trans(conn))
{
CC_abort(conn);
- ci->autocommit_normal = (CC_is_in_autocommit(conn) ? 1 : 0);
}
if (!pDtc)
{
{
CSTR func = "PGAPI_SetConnectOption";
ConnectionClass *conn = (ConnectionClass *) hdbc;
+ ConnInfo *ci = &(conn->connInfo);
char changed = FALSE;
RETCODE retval;
+ BOOL autocomm_on;
mylog("%s: entering fOption = %d vParam = %d\n", func, fOption, vParam);
if (!conn)
break;
case SQL_AUTOCOMMIT:
- if (vParam == SQL_AUTOCOMMIT_ON && CC_is_in_autocommit(conn))
- break;
- else if (vParam == SQL_AUTOCOMMIT_OFF && !CC_is_in_autocommit(conn))
- break;
- if (CC_is_in_trans(conn))
- CC_commit(conn);
-
- mylog("PGAPI_SetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam);
-
switch (vParam)
{
- case SQL_AUTOCOMMIT_OFF:
- CC_set_autocommit_off(conn);
- break;
-
case SQL_AUTOCOMMIT_ON:
- CC_set_autocommit_on(conn);
+ autocomm_on = TRUE;
+ break;
+ case SQL_AUTOCOMMIT_OFF:
+ autocomm_on = FALSE;
break;
-
default:
CC_set_error(conn, CONN_INVALID_ARGUMENT_NO, "Illegal parameter value for SQL_AUTOCOMMIT", func);
return SQL_ERROR;
}
+ if (autocomm_on && SQL_AUTOCOMMIT_OFF != ci->autocommit_public)
+ break;
+ else if (!autocomm_on && SQL_AUTOCOMMIT_OFF == ci->autocommit_public)
+ break;
+ ci->autocommit_public = (autocomm_on ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
+ mylog("%s: AUTOCOMMIT: transact_status=%d, vparam=%d\n", func, conn->transact_status, vParam);
+
+#ifdef _HANDLE_ENLIST_IN_DTC_
+ if (NULL != conn->asdum)
+ {
+ mylog("%s: Ignored AUTOCOMMIT in a distributed transaction, OK ?");
+ break;
+ }
+#endif /* _HANDLE_ENLIST_IN_DTC_ */
+ CC_set_autocommit(conn, autocomm_on);
break;
case SQL_CURRENT_QUALIFIER: /* ignored */
break;
case SQL_AUTOCOMMIT:
- *((SQLUINTEGER *) pvParam) = (SQLUINTEGER) (CC_is_in_autocommit(conn) ?
- SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
+ *((SQLUINTEGER *) pvParam) = ci->autocommit_public;
break;
case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */
TI_set_hasoids(ti);
foundKey = TRUE;
STR_TO_NAME(ti->bestitem, OID_NAME);
- strcpy(query, "\"oid\" = %u");
- /*strcpy(query, "\"oid\" = %%u");*/
+ sprintf(query, "\"%s\" = %u", OID_NAME);
STR_TO_NAME(ti->bestqual, query);
}
TI_set_hasoids_checked(ti);
if (unsupported)
{
char msg[64];
- snprintf(msg, sizeof(msg), "Couldn't set unsupported connect attribute " FORMAT_LPTR, (LONG_PTR) Value);
+ snprintf(msg, sizeof(msg), "Couldn't set unsupported connect attribute " FORMAT_INTEGER, Attribute);
CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER, msg, func);
return SQL_ERROR;
}
}
conn = SC_get_conn(s->stmt);
if (s->auto_commit_needed)
- PGAPI_SetConnectOption(conn, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_ON);
+ CC_set_autocommit(conn, TRUE);
irdflds = SC_get_IRDF(s->stmt);
if (irdflds->rowsFetched)
*(irdflds->rowsFetched) = s->processed;
{
conn = SC_get_conn(s.stmt);
if (s.auto_commit_needed = (char) CC_is_in_autocommit(conn), s.auto_commit_needed)
- PGAPI_SetConnectOption(conn, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF);
+ CC_set_autocommit(conn, FALSE);
}
if (SQL_ADD != s.operation)
{
case PG_TYPE_INT2:
return "int2";
case PG_TYPE_OID:
- return "oid";
+ return OID_NAME;
case PG_TYPE_XID:
return "xid";
case PG_TYPE_INT4:
*
* Comments: See "notice.txt" for copyright and license information.
*
- * $Id: psqlodbc.h,v 1.118 2007/04/11 16:36:47 h-saito Exp $
+ * $Id: psqlodbc.h,v 1.119 2007/05/02 21:44:12 hinoue Exp $
*
*/
* "date+outlet+invoice" */
/* POSIX defines a PATH_MAX.( wondows is _MAX_PATH ..) */
#ifndef PATH_MAX
+#ifdef _MAX_PATH
+#define PATH_MAX _MAX_PATH
+#else
#define PATH_MAX 1024
-#endif
+#endif /* _MAX_PATH */
+#endif /* PATH_MAX */
#define MAX_ROW_SIZE 0 /* Unlimited rowsize with the
* Tuple Toaster */
}
conn = SC_get_conn(s->stmt);
if (s->auto_commit_needed)
- PGAPI_SetConnectOption(conn, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_ON);
+ CC_set_autocommit(conn, TRUE);
if (s->irow > 0)
{
if (SQL_ADD != s->fOption && s->ridx >= 0) /* for SQLGetData */
case SQL_DELETE:
case SQL_ADD:
if (s.auto_commit_needed = CC_is_in_autocommit(conn), s.auto_commit_needed)
- PGAPI_SetConnectOption(conn, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF);
+ CC_set_autocommit(conn, FALSE);
break;
case SQL_POSITION:
break;
getnameinfo_ptr = (getnameinfo_func)GetProcAddress(ws2_hnd, "getnameinfo");
#endif
/*
- * If it is a valid IP address, use it. Otherwise use hostname lookup.
+ * Hostname lookup.
*/
- if (hostname && hostname[0])
+ if (hostname && hostname[0]
+#ifndef WIN32
+ && '/' != hostname[0]
+#endif /* WIN32 */
+ )
{
char portstr[16];
int ret;
{
struct sockaddr_un *un = (struct sockaddr_un *) &(self->sadr_area);
family = un->sun_family = AF_UNIX;
- /* passing NULL means that this only supports the pg default "/tmp" */
- UNIXSOCK_PATH(un, port, ((char *) NULL));
+ /* passing NULL or '' means pg default "/tmp" */
+ UNIXSOCK_PATH(un, port, hostname);
self->sadr_len = UNIXSOCK_LEN(un);
}
#else
#ifndef __VERSION_H__
#define __VERSION_H__
-#define POSTGRESDRIVERVERSION "08.02.0400"
-#define POSTGRES_RESOURCE_VERSION "08.02.0400\0"
-#define PG_DRVFILE_VERSION 8,2,04,00
-#define PG_BUILD_VERSION "200704280001"
+#define POSTGRESDRIVERVERSION "08.02.0401"
+#define POSTGRES_RESOURCE_VERSION "08.02.0401\0"
+#define PG_DRVFILE_VERSION 8,2,04,01
+#define PG_BUILD_VERSION "200704290001"
#endif
LINK32=link.exe
LIB32=lib.exe
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib advapi32.lib odbc32.lib odbccp32.lib wsock32.lib XOleHlp.lib winmm.lib "$(OUTDIR)\$(DTCLIB).lib" msvcrt.lib bufferoverflowu.lib /nologo /dll /machine:$(CPU) /def:"$(DEF_FILE)" /pdb:"$(OUTDIR)\psqlodbc.pdb" /out:"$(OUTDIR)\$(MAINDLL)" /implib:"$(OUTDIR)\$(MAINLIB).lib"
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib advapi32.lib odbc32.lib odbccp32.lib wsock32.lib XOleHlp.lib winmm.lib "$(OUTDIR)\$(DTCLIB).lib" msvcrt.lib bufferoverflowu.lib /nologo /dll /machine:$(CPU) /def:"$(DEF_FILE)"
!IF "$(ANSI_VERSION)" == "yes"
DEF_FILE= "psqlodbca.def"
!ELSE
"$(INTDIR)\psqlodbc.res"
DTCDEF_FILE= "$(DTCLIB).def"
-LIB32_DTCLIBFLAGS=/nologo /machine:$(CPU) /def:"$(DTCDEF_FILE)" /out:"$(OUTDIR)\$(DTCLIB).lib"
+LIB32_DTCLIBFLAGS=/nologo /machine:$(CPU) /def:"$(DTCDEF_FILE)"
-LINK32_DTCFLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib wsock32.lib XOleHlp.lib $(OUTDIR)\$(MAINLIB).lib bufferoverflowu.lib Delayimp.lib /DelayLoad:XOLEHLP.DLL /nologo /dll /incremental:no /pdb:"$(OUTDIR)\$(DTCLIB).pdb" /machine:$(CPU) /out:"$(OUTDIR)\$(DTCDLL)"
+LINK32_DTCFLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib wsock32.lib XOleHlp.lib $(OUTDIR)\$(MAINLIB).lib bufferoverflowu.lib Delayimp.lib /DelayLoad:XOLEHLP.DLL /nologo /dll /incremental:no /machine:$(CPU)
LINK32_DTCOBJS= \
"$(INTDIR)\msdtc_enlist.obj" "$(INTDIR)\xalibname.obj"
XADEF_FILE= "$(XALIB).def"
-LINK32_XAFLAGS=/nodefaultlib:libcmt.lib kernel32.lib user32.lib gdi32.lib advapi32.lib odbc32.lib odbccp32.lib wsock32.lib XOleHlp.lib winmm.lib msvcrt.lib bufferoverflowu.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\$(XALIB).pdb" /machine:$(CPU) /def:"$(XADEF_FILE)" /out:"$(OUTDIR)\$(XADLL)" /implib:"$(OUTDIR)\$(XALIB).lib"
+LINK32_XAFLAGS=/nodefaultlib:libcmt.lib kernel32.lib user32.lib gdi32.lib advapi32.lib odbc32.lib odbccp32.lib wsock32.lib XOleHlp.lib winmm.lib msvcrt.lib bufferoverflowu.lib /nologo /dll /incremental:no /machine:$(CPU) /def:"$(XADEF_FILE)"
LINK32_XAOBJS= \
"$(INTDIR)\pgxalib.obj"
"$(OUTDIR)\$(MAINDLL)" : $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
- $(LINK32_FLAGS) $(LINK32_OBJS)
+ $(LINK32_FLAGS) $(LINK32_OBJS) /pdb:$*.pdb /implib:$*.lib /out:$@
<<
"$(OUTDIR)\$(DTCLIB).lib" : $(DEF_FILE) $(LINK32_DTCOBJS)
$(LIB32) @<<
- $(LIB32_DTCLIBFLAGS) $(LINK32_DTCOBJS)
+ $(LIB32_DTCLIBFLAGS) $(LINK32_DTCOBJS) /out:$@
<<
"$(OUTDIR)\$(DTCDLL)" : $(LINK32_DTCOBJS)
$(LINK32) @<<
- $(LINK32_DTCFLAGS) $(LINK32_DTCOBJS) $(OUTDIR)\$(DTCLIB).exp
+ $(LINK32_DTCFLAGS) $(LINK32_DTCOBJS) $*.exp /pdb:$*.pdb /out:$@
<<
"$(OUTDIR)\$(XADLL)" : $(XADEF_FILE) $(LINK32_XAOBJS)
$(LINK32) @<<
- $(LINK32_XAFLAGS) $(LINK32_XAOBJS)
+ $(LINK32_XAFLAGS) $(LINK32_XAOBJS) /pdb:$*.pdb /implib:$*.lib /out:$@
<<