Example #1
0
static SQLRETURN
MNDBAllocDesc(ODBCDbc *dbc, SQLHANDLE *OutputHandlePtr)
{
	if (!dbc->Connected) {
		/* Connection does not exist */
		addDbcError(dbc, "08003", NULL, 0);
		return SQL_ERROR;
	}
	if (OutputHandlePtr == NULL) {
		/* Invalid use of null pointer */
		addDbcError(dbc, "HY009", NULL, 0);
		return SQL_ERROR;
	}
	*OutputHandlePtr = (SQLHANDLE *) newODBCDesc(dbc);
#ifdef ODBCDEBUG
	ODBCLOG("new desc %p\n", *OutputHandlePtr);
#endif
	return *OutputHandlePtr == NULL ? SQL_ERROR : SQL_SUCCESS;
}
Example #2
0
static SQLRETURN
ODBCFreeDbc_(ODBCDbc *dbc)
{
	/* check if connection is not active */
	if (dbc->Connected) {
		/* Function sequence error */
		addDbcError(dbc, "HY010", NULL, 0);
		return SQL_ERROR;
	}

	/* check if no associated statements are still active */
	if (dbc->FirstStmt != NULL) {
		/* There are allocated statements should be closed and
		 * freed first */
		/* Function sequence error */
		addDbcError(dbc, "HY010", NULL, 0);
		return SQL_ERROR;
	}

	/* Ready to destroy the dbc handle */
	destroyODBCDbc(dbc);
	return SQL_SUCCESS;
}
Example #3
0
static SQLRETURN
MNDBSetConnectOption(ODBCDbc *dbc,
		     SQLUSMALLINT Option,
		     SQLULEN ValuePtr)
{
	/* use mapping as described in ODBC 3 SDK Help file */
	switch (Option) {
	/* connection attributes (ODBC 1 and 2 only) */
	case SQL_ACCESS_MODE:
	case SQL_AUTOCOMMIT:
	case SQL_LOGIN_TIMEOUT:
	case SQL_ODBC_CURSORS:
	case SQL_OPT_TRACE:
	case SQL_PACKET_SIZE:
	case SQL_TRANSLATE_OPTION:
	case SQL_TXN_ISOLATION:
		/* 32 bit integer argument */
		return MNDBSetConnectAttr(dbc, Option,
					  (SQLPOINTER) (uintptr_t) ValuePtr, 0);
	case SQL_QUIET_MODE:
		/* 32/64 bit integer argument */
		return MNDBSetConnectAttr(dbc, Option,
					  (SQLPOINTER) (uintptr_t) ValuePtr, 0);

	case SQL_CURRENT_QUALIFIER:
	case SQL_OPT_TRACEFILE:
	case SQL_TRANSLATE_DLL:
		/* null terminated string argument */
		return MNDBSetConnectAttr(dbc, Option,
					  (SQLPOINTER) (uintptr_t) ValuePtr,
					  SQL_NTS);

	default:
		/* other options (e.g. ODBC 3) are NOT valid */
		/* Invalid attribute/option identifier */
		addDbcError(dbc, "HY092", NULL, 0);
		break;
	}

	return SQL_ERROR;
}
Example #4
0
SQLRETURN SQL_API
SQLBrowseConnectW(SQLHDBC ConnectionHandle,
		  SQLWCHAR *InConnectionString,
		  SQLSMALLINT StringLength1,
		  SQLWCHAR *OutConnectionString,
		  SQLSMALLINT BufferLength,
		  SQLSMALLINT *StringLength2Ptr)
{
	ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle;
	SQLCHAR *in = NULL, *out;
	SQLSMALLINT n;
	SQLRETURN rc;

#ifdef ODBCDEBUG
	ODBCLOG("SQLBrowseConnectW " PTRFMT, PTRFMTCAST ConnectionHandle);
#endif

	if (!isValidDbc(dbc))
		return SQL_INVALID_HANDLE;

	clearDbcErrors(dbc);

	fixWcharIn(InConnectionString, StringLength1, SQLCHAR, in,
		   addDbcError, dbc, return SQL_ERROR);
	out = malloc(1024);
	if (out == NULL) {
		/* Memory allocation error */
		addDbcError(dbc, "HY001", NULL, 0);
		return SQL_ERROR;
	}
	rc = MNDBBrowseConnect(dbc, in, SQL_NTS, out, 1024, &n);
	if (SQL_SUCCEEDED(rc) || rc == SQL_NEED_DATA) {
		fixWcharOut(rc, out, n, OutConnectionString, BufferLength,
			    StringLength2Ptr, 1, addDbcError, dbc);
	}
	free(out);
	if (in)
		free(in);
	return rc;
}
Example #5
0
SQLRETURN SQL_API
SQLDisconnect(SQLHDBC ConnectionHandle)
{
	ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle;

#ifdef ODBCDEBUG
	ODBCLOG("SQLDisconnect " PTRFMT "\n", PTRFMTCAST ConnectionHandle);
#endif

	if (!isValidDbc(dbc))
		return SQL_INVALID_HANDLE;

	clearDbcErrors(dbc);

	/* check connection state, should be connected */
	if (!dbc->Connected) {
		/* Connection does not exist */
		addDbcError(dbc, "08003", NULL, 0);
		return SQL_ERROR;
	}

	while (dbc->FirstStmt != NULL)
		if (ODBCFreeStmt_(dbc->FirstStmt) == SQL_ERROR)
			return SQL_ERROR;

	/* client waves goodbye */
	mapi_disconnect(dbc->mid);
	mapi_destroy(dbc->mid);

	dbc->mid = NULL;
	dbc->cachelimit = 0;
	dbc->Mdebug = 0;
	dbc->Connected = 0;

	return SQL_SUCCESS;
}
Example #6
0
/*
 * Creates a new allocated ODBCStmt object and initializes it.
 *
 * Precondition: none
 * Postcondition: returns a new ODBCStmt object
 */
ODBCStmt *
newODBCStmt(ODBCDbc *dbc)
{
	ODBCStmt *stmt = (ODBCStmt *) malloc(sizeof(ODBCStmt));
	assert(stmt);

	assert(dbc);
	assert(dbc->mid);

	if (stmt == NULL) {
		/* Memory allocation error */
		addDbcError(dbc, "HY001", NULL, 0);
		return NULL;
	}

	stmt->Dbc = dbc;
	stmt->Error = NULL;
	stmt->RetrievedErrors = 0;

	stmt->State = INITED;
	stmt->hdl = mapi_new_handle(dbc->mid);
	if (stmt->hdl == NULL) {
		/* Memory allocation error */
		addDbcError(dbc, "HY001", NULL, 0);
		free(stmt);
		return NULL;
	}
	assert(stmt->hdl);

	stmt->currentRow = 0;
	stmt->startRow = 0;
	stmt->rowSetSize = 0;
	stmt->queryid = -1;
	stmt->nparams = 0;
	stmt->querytype = -1;
	stmt->rowcount = 0;

	/* add this stmt to the administrative linked stmt list */
	stmt->next = dbc->FirstStmt;
	dbc->FirstStmt = stmt;

	stmt->cursorType = SQL_CURSOR_FORWARD_ONLY;
	stmt->cursorScrollable = SQL_NONSCROLLABLE;
	stmt->retrieveData = SQL_RD_ON;
	stmt->noScan = SQL_NOSCAN_OFF;

	stmt->ApplRowDescr = newODBCDesc(dbc);
	stmt->ApplParamDescr = newODBCDesc(dbc);
	stmt->ImplRowDescr = newODBCDesc(dbc);
	stmt->ImplParamDescr = newODBCDesc(dbc);
	stmt->AutoApplRowDescr = stmt->ApplRowDescr;
	stmt->AutoApplParamDescr = stmt->ApplParamDescr;

	if (stmt->ApplRowDescr == NULL || stmt->ApplParamDescr == NULL ||
	    stmt->ImplRowDescr == NULL || stmt->ImplParamDescr == NULL) {
		destroyODBCStmt(stmt);
		return NULL;
	}

	stmt->ApplRowDescr->sql_desc_alloc_type = SQL_DESC_ALLOC_AUTO;
	stmt->ApplParamDescr->sql_desc_alloc_type = SQL_DESC_ALLOC_AUTO;
	stmt->ImplRowDescr->sql_desc_alloc_type = SQL_DESC_ALLOC_AUTO;
	stmt->ImplParamDescr->sql_desc_alloc_type = SQL_DESC_ALLOC_AUTO;
	stmt->ImplRowDescr->Stmt = stmt;
	stmt->ImplParamDescr->Stmt = stmt;

	stmt->Type = ODBC_STMT_MAGIC_NR;	/* set it valid */

	return stmt;
}
Example #7
0
SQLRETURN
MNDBGetConnectAttr(ODBCDbc *dbc,
		   SQLINTEGER Attribute,
		   SQLPOINTER ValuePtr,
		   SQLINTEGER BufferLength,
		   SQLINTEGER *StringLengthPtr)
{
	/* check input parameters */
	if (ValuePtr == NULL) {
		/* Invalid use of null pointer */
		addDbcError(dbc, "HY009", NULL, 0);
		return SQL_ERROR;
	}

	switch (Attribute) {
	case SQL_ATTR_ACCESS_MODE:		/* SQLUINTEGER */
		/* SQL_ACCESS_MODE */
		WriteData(ValuePtr, SQL_MODE_READ_WRITE, SQLUINTEGER);
		break;
	case SQL_ATTR_ASYNC_ENABLE:		/* SQLULEN */
		WriteData(ValuePtr, SQL_ASYNC_ENABLE_OFF, SQLULEN);
		break;
	case SQL_ATTR_AUTO_IPD:			/* SQLUINTEGER */
		/* TODO implement automatic filling of IPD See also
		 * SQLSetStmtAttr.c for SQL_ATTR_ENABLE_AUTO_IPD */
		WriteData(ValuePtr, SQL_FALSE, SQLUINTEGER);
		break;
	case SQL_ATTR_AUTOCOMMIT:		/* SQLUINTEGER */
		/* SQL_AUTOCOMMIT */
		WriteData(ValuePtr, dbc->sql_attr_autocommit, SQLUINTEGER);
		break;
	case SQL_ATTR_CONNECTION_DEAD:		/* SQLUINTEGER */
		WriteData(ValuePtr, dbc->mid && mapi_is_connected(dbc->mid) ? SQL_CD_FALSE : SQL_CD_TRUE, SQLUINTEGER);
		break;
	case SQL_ATTR_CONNECTION_TIMEOUT:	/* SQLUINTEGER */
		WriteData(ValuePtr, dbc->sql_attr_connection_timeout, SQLUINTEGER);
		break;
	case SQL_ATTR_LOGIN_TIMEOUT:		/* SQLUINTEGER */
		/* SQL_LOGIN_TIMEOUT */
		WriteData(ValuePtr, 0, SQLUINTEGER);	/* no timeout */
		break;
	case SQL_ATTR_METADATA_ID:		/* SQLUINTEGER */
		WriteData(ValuePtr, dbc->sql_attr_metadata_id, SQLUINTEGER);
		break;
	case SQL_ATTR_ODBC_CURSORS:		/* SQLULEN */
		/* SQL_ODBC_CURSORS */
		WriteData(ValuePtr, SQL_CUR_USE_DRIVER, SQLULEN);
		break;
	case SQL_ATTR_TRACE:			/* SQLUINTEGER */
		/* SQL_OPT_TRACE */
		WriteData(ValuePtr, SQL_OPT_TRACE_OFF, SQLUINTEGER);
		break;
	case SQL_ATTR_CURRENT_CATALOG:		/* SQLCHAR* */
		/* SQL_CURRENT_QUALIFIER */
		copyString(dbc->dbname, strlen(dbc->dbname), ValuePtr,
			   BufferLength, StringLengthPtr, SQLINTEGER,
			   addDbcError, dbc, return SQL_ERROR);
		break;
	case SQL_ATTR_TXN_ISOLATION:		/* SQLUINTEGER */
		/* SQL_TXN_ISOLATION */
		WriteData(ValuePtr, SQL_TXN_SERIALIZABLE, SQLUINTEGER);
		break;

/* TODO: implement all the other Connection Attributes */
#ifdef SQL_ATTR_ASYNC_DBC_EVENT
	case SQL_ATTR_ASYNC_DBC_EVENT:		/* SQLPOINTER */
#endif
#ifdef SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE
	case SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE: /* SQLUINTEGER */
#endif
#ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK
	case SQL_ATTR_ASYNC_DBC_PCALLBACK:	/* SQLPOINTER */
#endif
#ifdef SQL_ATTR_ASYNC_DBC_PCONTEXT
	case SQL_ATTR_ASYNC_DBC_PCONTEXT:	/* SQLPOINTER */
#endif
#ifdef SQL_ATTR_DBC_INFO_TOKEN
	case SQL_ATTR_DBC_INFO_TOKEN:		/* SQLPOINTER */
#endif
	case SQL_ATTR_DISCONNECT_BEHAVIOR:
	case SQL_ATTR_ENLIST_IN_DTC:		/* SQLPOINTER */
	case SQL_ATTR_ENLIST_IN_XA:
	case SQL_ATTR_PACKET_SIZE:		/* SQLUINTEGER */
		/* SQL_PACKET_SIZE */
	case SQL_ATTR_QUIET_MODE:		/* HWND (SQLPOINTER) */
		/* SQL_QUIET_MODE */
	case SQL_ATTR_TRACEFILE:		/* SQLCHAR* */
		/* SQL_OPT_TRACEFILE */
	case SQL_ATTR_TRANSLATE_LIB:		/* SQLCHAR* */
		/* SQL_TRANSLATE_DLL */
	case SQL_ATTR_TRANSLATE_OPTION:		/* SQLUINTEGER */
		/* SQL_TRANSLATE_OPTION */
		/* Optional feature not implemented */
		addDbcError(dbc, "HYC00", NULL, 0);
		return SQL_ERROR;
	default:
		/* Invalid attribute/option identifier */
		addDbcError(dbc, "HY092", NULL, 0);
		return SQL_ERROR;
	}

	return dbc->Error ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
}
Example #8
0
SQLRETURN SQL_API
SQLGetConnectAttrW(SQLHDBC ConnectionHandle,
		   SQLINTEGER Attribute,
		   SQLPOINTER ValuePtr,
		   SQLINTEGER BufferLength,
		   SQLINTEGER *StringLengthPtr)
{
	ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle;
	SQLRETURN rc;
	SQLPOINTER ptr;
	SQLINTEGER n;

#ifdef ODBCDEBUG
	ODBCLOG("SQLGetConnectAttrW " PTRFMT " %s " PTRFMT " %d " PTRFMT "\n",
		PTRFMTCAST ConnectionHandle,
		translateConnectAttribute(Attribute),
		PTRFMTCAST ValuePtr, (int) BufferLength,
		PTRFMTCAST StringLengthPtr);
#endif

	if (!isValidDbc(dbc))
		return SQL_INVALID_HANDLE;

	clearDbcErrors(dbc);

	switch (Attribute) {
	/* all string attributes */
	case SQL_ATTR_CURRENT_CATALOG:
		ptr = malloc(BufferLength);
		if (ptr == NULL) {
			/* Memory allocation error */
			addDbcError(dbc, "HY001", NULL, 0);
			return SQL_ERROR;
		}
		break;
	default:
		ptr = ValuePtr;
		break;
	}

	rc = MNDBGetConnectAttr(dbc, Attribute, ptr, BufferLength, &n);

	if (ptr != ValuePtr) {
		if (rc == SQL_SUCCESS_WITH_INFO) {
			clearDbcErrors(dbc);
			free(ptr);
			ptr = malloc(++n); /* add one for NULL byte */
			if (ptr == NULL) {
				/* Memory allocation error */
				addDbcError(dbc, "HY001", NULL, 0);
				return SQL_ERROR;
			}
			rc = MNDBGetConnectAttr(dbc, Attribute, ptr, n, &n);
		}
		if (SQL_SUCCEEDED(rc)) {
			SQLSMALLINT nn = (SQLSMALLINT) n;

			fixWcharOut(rc, ptr, nn, ValuePtr, BufferLength,
				    StringLengthPtr, 2, addDbcError, dbc);
		}
		free(ptr);
	} else if (StringLengthPtr)
		*StringLengthPtr = n;

	return rc;
}
Example #9
0
static SQLRETURN
MNDBBrowseConnect(ODBCDbc *dbc,
		  SQLCHAR *InConnectionString,
		  SQLSMALLINT StringLength1,
		  SQLCHAR *OutConnectionString,
		  SQLSMALLINT BufferLength,
		  SQLSMALLINT *StringLength2Ptr)
{
	char *key, *attr;
	char *dsn, *uid, *pwd, *host, *dbname;
	int port;
	SQLSMALLINT len = 0;
	char buf[256];
	int n;
	SQLRETURN rc;
#ifdef ODBCDEBUG
	int allocated = 0;
#endif

	fixODBCstring(InConnectionString, StringLength1, SQLSMALLINT, addDbcError, dbc, return SQL_ERROR);

#ifdef ODBCDEBUG
	ODBCLOG(" \"%.*s\"\n", (int) StringLength1, (char*) InConnectionString);
#endif

	/* check connection state, should not be connected */
	if (dbc->Connected) {
		/* Connection name in use */
		addDbcError(dbc, "08002", NULL, 0);
		return SQL_ERROR;
	}

	dsn = dbc->dsn ? strdup(dbc->dsn) : NULL;
	uid = dbc->uid ? strdup(dbc->uid) : NULL;
	pwd = dbc->pwd ? strdup(dbc->pwd) : NULL;
	host = dbc->host ? strdup(dbc->host) : NULL;
	port = dbc->port;
	dbname = dbc->dbname ? strdup(dbc->dbname) : NULL;

	while ((n = ODBCGetKeyAttr(&InConnectionString, &StringLength1, &key, &attr)) > 0) {
		if (strcasecmp(key, "dsn") == 0 && dsn == NULL) {
			if (dsn)
				free(dsn);
			dsn = attr;
		} else if (strcasecmp(key, "uid") == 0 && uid == NULL) {
			if (uid)
				free(uid);
			uid = attr;
		} else if (strcasecmp(key, "pwd") == 0 && pwd == NULL) {
			if (pwd)
				free(pwd);
			pwd = attr;
		} else if (strcasecmp(key, "host") == 0 && host == NULL) {
			if (host)
				free(host);
			host = attr;
		} else if (strcasecmp(key, "port") == 0 && port == 0) {
			port = atoi(attr);
			free(attr);
		} else if (strcasecmp(key, "database") == 0 && dbname == NULL) {
			if (dbname)
				free(dbname);
			dbname = attr;
#ifdef ODBCDEBUG
		} else if (strcasecmp(key, "logfile") == 0 &&
			   getenv("ODBCDEBUG") == NULL) {
			/* environment trumps everything */
			if (ODBCdebug)
				free((void *) ODBCdebug); /* discard const */
			ODBCdebug = attr;
			allocated = 1;
#endif
		} else
			free(attr);
		free(key);
	}
	if (n < 0)
		goto nomem;

	if (dsn) {
		if (uid == NULL) {
			n = SQLGetPrivateProfileString(dsn, "uid", "", buf, sizeof(buf), "odbc.ini");
			if (n > 0 && buf[0]) {
				uid = strdup(buf);
				if (uid == NULL)
					goto nomem;
			}
		}
		if (pwd == NULL) {
			n = SQLGetPrivateProfileString(dsn, "pwd", "", buf, sizeof(buf), "odbc.ini");
			if (n > 0 && buf[0]) {
				pwd = strdup(buf);
				if (pwd == NULL)
					goto nomem;
			}
		}
		if (host == NULL) {
			n = SQLGetPrivateProfileString(dsn, "host", "", buf, sizeof(buf), "odbc.ini");
			if (n > 0 && buf[0]) {
				host = strdup(buf);
				if (host == NULL)
					goto nomem;
			}
		}
		if (port == 0) {
			n = SQLGetPrivateProfileString(dsn, "port", "", buf, sizeof(buf), "odbc.ini");
			if (n > 0 && buf[0]) {
				port = atoi(buf);
			}
		}
		if (dbname == NULL) {
			n = SQLGetPrivateProfileString(dsn, "database", "", buf, sizeof(buf), "odbc.ini");
			if (n > 0 && buf[0]) {
				dbname = strdup(buf);
				if (dbname == NULL)
					goto nomem;
			}
		}
#ifdef ODBCDEBUG
		if (!allocated && getenv("ODBCDEBUG") == NULL) {
			/* if not set from InConnectionString argument
			 * or environment, look in profile */
			n = SQLGetPrivateProfileString(dsn, "logfile", "", buf, sizeof(buf), "odbc.ini");
			if (n > 0 && buf[0])
				ODBCdebug = strdup(buf);
		}
#endif
	}

	if (uid != NULL && pwd != NULL) {
		rc = MNDBConnect(dbc, (SQLCHAR *) dsn, SQL_NTS, (SQLCHAR *) uid, SQL_NTS, (SQLCHAR *) pwd, SQL_NTS, host, port, dbname);
		if (SQL_SUCCEEDED(rc)) {
			rc = ODBCConnectionString(rc, dbc, OutConnectionString,
						  BufferLength,
						  StringLength2Ptr,
						  dsn, uid, pwd, host, port,
						  dbname);
		}
	} else {
		if (uid == NULL) {
			if (BufferLength > 0)
				strncpy((char *) OutConnectionString, "UID:Login ID=?;", BufferLength);
			len += 15;
			OutConnectionString += 15;
			BufferLength -= 15;
		}
		if (pwd == NULL) {
			if (BufferLength > 0)
				strncpy((char *) OutConnectionString, "PWD:Password=?;", BufferLength);
			len += 15;
			OutConnectionString += 15;
			BufferLength -= 15;
		}
		if (host == NULL) {
			if (BufferLength > 0)
				strncpy((char *) OutConnectionString, "*HOST:Server=?;", BufferLength);
			len += 15;
			OutConnectionString += 15;
			BufferLength -= 15;
		}
		if (port == 0) {
			if (BufferLength > 0)
				strncpy((char *) OutConnectionString, "*PORT:Port=?;", BufferLength);
			len += 13;
			OutConnectionString += 13;
			BufferLength -= 13;
		}
		if (dbname == NULL) {
			if (BufferLength > 0)
				strncpy((char *) OutConnectionString, "*DATABASE:Database=?;", BufferLength);
			len += 21;
			OutConnectionString += 21;
			BufferLength -= 21;
		}
#ifdef ODBCDEBUG
		if (ODBCdebug == NULL) {
			if (BufferLength > 0)
				strncpy((char *) OutConnectionString, "*LOGFILE:Debug log file=?;", BufferLength);
			len += 26;
			OutConnectionString += 26;
			BufferLength -= 26;
		}
#endif

		if (StringLength2Ptr)
			*StringLength2Ptr = len;

		rc = SQL_NEED_DATA;
	}

  bailout:
	if (dsn)
		free(dsn);
	if (uid)
		free(uid);
	if (pwd)
		free(pwd);
	if (host)
		free(host);
	if (dbname)
		free(dbname);
	return rc;

  nomem:
	/* Memory allocation error */
	addDbcError(dbc, "HY001", NULL, 0);
	rc = SQL_ERROR;
	goto bailout;
}
Example #10
0
static SQLRETURN
MNDBGetInfo(ODBCDbc *dbc,
	    SQLUSMALLINT InfoType,
	    SQLPOINTER InfoValuePtr,
	    SQLSMALLINT BufferLength,
	    SQLSMALLINT *StringLengthPtr)
{
	int nValue = 0;
	char buf[64];
	const char *sValue = NULL;	/* iff non-NULL, return string value */
	int len = sizeof(SQLUINTEGER);	/* most common size to return */

	/* For some info types an active connection is needed */
	if (!dbc->Connected &&
	    (InfoType == SQL_DATA_SOURCE_NAME ||
	     InfoType == SQL_SERVER_NAME ||
	     InfoType == SQL_DATABASE_NAME ||
	     InfoType == SQL_USER_NAME)) {
		/* Connection does not exist */
		addDbcError(dbc, "08003", NULL, 0);
		return SQL_ERROR;
	}

	switch (InfoType) {
	case SQL_ACCESSIBLE_PROCEDURES:
		sValue = "Y";	/* "N" */
		break;
	case SQL_ACCESSIBLE_TABLES:
		sValue = "N";	/* "Y" */
		break;
	case SQL_ACTIVE_ENVIRONMENTS:
		nValue = 0;	/* 0 = no limit */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_AGGREGATE_FUNCTIONS:
		nValue = SQL_AF_ALL |
			SQL_AF_AVG |
			SQL_AF_COUNT |
			SQL_AF_DISTINCT |
			SQL_AF_MAX |
			SQL_AF_MIN |
			SQL_AF_SUM;
		break;
	case SQL_ALTER_DOMAIN:
		/* SQL_AD_ADD_CONSTRAINT_DEFERRABLE |
		 * SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED |
		 * SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE |
		 * SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE |
		 * SQL_AD_ADD_DOMAIN_CONSTRAINT |
		 * SQL_AD_ADD_DOMAIN_DEFAULT |
		 * SQL_AD_CONSTRAINT_NAME_DEFINITION |
		 * SQL_AD_DROP_DOMAIN_CONSTRAINT |
		 * SQL_AD_DROP_DOMAIN_DEFAULT */
		break;
	case SQL_ALTER_TABLE:
		nValue = SQL_AT_ADD_COLUMN | /* ODBC 2.0, deprecated value */
			SQL_AT_ADD_COLUMN_DEFAULT |
			SQL_AT_ADD_COLUMN_SINGLE |
			SQL_AT_ADD_CONSTRAINT |
			SQL_AT_ADD_TABLE_CONSTRAINT |
			SQL_AT_CONSTRAINT_NAME_DEFINITION |
			SQL_AT_DROP_COLUMN | /* ODBC 2.0, deprecated value */
			SQL_AT_DROP_COLUMN_CASCADE |
			SQL_AT_DROP_COLUMN_DEFAULT |
			SQL_AT_DROP_COLUMN_RESTRICT |
			SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE |
			SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT |
			SQL_AT_SET_COLUMN_DEFAULT;
		/* SQL_AT_ADD_COLUMN_COLLATION |
		 * SQL_AT_CONSTRAINT_DEFERRABLE |
		 * SQL_AT_CONSTRAINT_INITIALLY_DEFERRED |
		 * SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE |
		 * SQL_AT_CONSTRAINT_NON_DEFERRABLE */
		break;
#ifdef SQL_ASYNC_DBC_FUNCTIONS
	case SQL_ASYNC_DBC_FUNCTIONS:
		nValue = SQL_ASYNC_DBC_NOT_CAPABLE;
		/* SQL_ASYNC_DBC_CAPABLE */
		break;
#endif
	case SQL_ASYNC_MODE:
		nValue = SQL_AM_NONE;
		/* SQL_AM_CONNECTION, SQL_AM_STATEMENT */
		break;
#ifdef SQL_ASYNC_NOTIFICATION
	case SQL_ASYNC_NOTIFICATION:
		nValue = SQL_ASYNC_NOTIFICATION_NOT_CAPABLE;
		/* SQL_ASYNC_NOTIFICATION_CAPABLE */
		break;
#endif
	case SQL_BATCH_ROW_COUNT:
		nValue = SQL_BRC_EXPLICIT;
		/* SQL_BRC_PROCEDURES | SQL_BRC_ROLLED_UP */
		break;
	case SQL_BATCH_SUPPORT:
		nValue = SQL_BS_ROW_COUNT_EXPLICIT | SQL_BS_SELECT_EXPLICIT;
		/* SQL_BS_ROW_COUNT_PROC |
		 * SQL_BS_SELECT_PROC */
		break;
	case SQL_BOOKMARK_PERSISTENCE:
		/* SQL_BP_CLOSE |
		 * SQL_BP_DELETE |
		 * SQL_BP_DROP |
		 * SQL_BP_OTHER_HSTMT |
		 * SQL_BP_TRANSACTION |
		 * SQL_BP_UPDATE */
		break;
	case SQL_CATALOG_LOCATION:
		/* SQL_CL_END, SQL_CL_START */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_CATALOG_NAME:
		sValue = "N";	/* "Y" */
		break;
	case SQL_CATALOG_NAME_SEPARATOR:
	case SQL_CATALOG_TERM:
		sValue = "";
		break;
	case SQL_CATALOG_USAGE:
		/* SQL_CU_DML_STATEMENTS |
		 * SQL_CU_INDEX_DEFINITION |
		 * SQL_CU_PRIVILEGE_DEFINITION |
		 * SQL_CU_PROCEDURE_INVOCATION |
		 * SQL_CU_TABLE_DEFINITION */
		break;
	case SQL_COLLATION_SEQ:
		sValue = "UTF-8";
		break;
	case SQL_COLUMN_ALIAS:
		sValue = "Y";	/* "N" */
		break;
	case SQL_CONCAT_NULL_BEHAVIOR:
		nValue = SQL_CB_NULL;
		/* SQL_CB_NON_NULL */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_CONVERT_TINYINT:
	case SQL_CONVERT_SMALLINT:
	case SQL_CONVERT_INTEGER:
	case SQL_CONVERT_BIGINT:
		nValue = SQL_CVT_BIGINT |
			SQL_CVT_BIT |
			SQL_CVT_CHAR |
			SQL_CVT_DECIMAL |
			SQL_CVT_DOUBLE |
			SQL_CVT_FLOAT |
			SQL_CVT_INTEGER |
			SQL_CVT_INTERVAL_DAY_TIME |
			SQL_CVT_INTERVAL_YEAR_MONTH |
			SQL_CVT_LONGVARCHAR |
			SQL_CVT_NUMERIC |
			SQL_CVT_REAL |
			SQL_CVT_SMALLINT |
			SQL_CVT_TINYINT |
			SQL_CVT_VARCHAR;
		break;
	case SQL_CONVERT_BINARY:
	case SQL_CONVERT_LONGVARBINARY:
	case SQL_CONVERT_VARBINARY:
		nValue = SQL_CVT_BINARY |
			SQL_CVT_CHAR |
			SQL_CVT_LONGVARBINARY |
			SQL_CVT_LONGVARCHAR |
			SQL_CVT_VARBINARY |
			SQL_CVT_VARCHAR;
		/* SQL_CVT_GUID */
		break;
	case SQL_CONVERT_BIT:
		nValue = SQL_CVT_BIGINT |
			SQL_CVT_BIT |
			SQL_CVT_CHAR |
			SQL_CVT_INTEGER |
			SQL_CVT_LONGVARCHAR |
			SQL_CVT_SMALLINT |
			SQL_CVT_TINYINT |
			SQL_CVT_VARCHAR;
		break;
	case SQL_CONVERT_CHAR:
	case SQL_CONVERT_VARCHAR:
	case SQL_CONVERT_LONGVARCHAR:
		nValue = SQL_CVT_BIGINT |
			SQL_CVT_BINARY |
			SQL_CVT_BIT |
			SQL_CVT_CHAR |
			SQL_CVT_DATE |
			SQL_CVT_DECIMAL |
			SQL_CVT_DOUBLE |
			SQL_CVT_FLOAT |
			SQL_CVT_GUID |
			SQL_CVT_INTEGER |
			SQL_CVT_INTERVAL_DAY_TIME |
			SQL_CVT_INTERVAL_YEAR_MONTH |
			SQL_CVT_LONGVARBINARY |
			SQL_CVT_LONGVARCHAR |
			SQL_CVT_NUMERIC |
			SQL_CVT_REAL |
			SQL_CVT_SMALLINT |
			SQL_CVT_TIME |
			SQL_CVT_TIMESTAMP |
			SQL_CVT_TINYINT |
			SQL_CVT_VARBINARY |
			SQL_CVT_VARCHAR;
		break;
	case SQL_CONVERT_DATE:
		nValue = SQL_CVT_CHAR |
			SQL_CVT_DATE |
			SQL_CVT_LONGVARCHAR |
			SQL_CVT_TIMESTAMP |
			SQL_CVT_VARCHAR;
		break;
	case SQL_CONVERT_DECIMAL:
	case SQL_CONVERT_NUMERIC:
		nValue = SQL_CVT_BIGINT |
			SQL_CVT_CHAR |
			SQL_CVT_DECIMAL |
			SQL_CVT_DOUBLE |
			SQL_CVT_FLOAT |
			SQL_CVT_INTEGER |
			SQL_CVT_INTERVAL_DAY_TIME |
			SQL_CVT_LONGVARCHAR |
			SQL_CVT_NUMERIC |
			SQL_CVT_REAL |
			SQL_CVT_SMALLINT |
			SQL_CVT_TINYINT |
			SQL_CVT_VARCHAR;
		break;
	case SQL_CONVERT_DOUBLE:
	case SQL_CONVERT_REAL:
	case SQL_CONVERT_FLOAT:
		nValue = SQL_CVT_BIGINT |
			SQL_CVT_CHAR |
			SQL_CVT_DECIMAL |
			SQL_CVT_DOUBLE |
			SQL_CVT_FLOAT |
			SQL_CVT_INTEGER |
			SQL_CVT_LONGVARCHAR |
			SQL_CVT_NUMERIC |
			SQL_CVT_REAL |
			SQL_CVT_SMALLINT |
			SQL_CVT_TINYINT |
			SQL_CVT_VARCHAR;
		break;
	case SQL_CONVERT_INTERVAL_DAY_TIME:
		nValue = SQL_CVT_BIGINT |
			SQL_CVT_CHAR |
			SQL_CVT_INTEGER |
			SQL_CVT_INTERVAL_DAY_TIME |
			SQL_CVT_LONGVARCHAR |
			SQL_CVT_SMALLINT |
			SQL_CVT_TIME |
			SQL_CVT_TINYINT |
			SQL_CVT_VARCHAR;
		break;
	case SQL_CONVERT_INTERVAL_YEAR_MONTH:
		nValue = SQL_CVT_BIGINT |
			SQL_CVT_CHAR |
			SQL_CVT_INTEGER |
			SQL_CVT_INTERVAL_YEAR_MONTH |
			SQL_CVT_LONGVARCHAR |
			SQL_CVT_SMALLINT |
			SQL_CVT_TINYINT |
			SQL_CVT_VARCHAR;
		break;
	case SQL_CONVERT_TIME:
		nValue = SQL_CVT_CHAR |
			SQL_CVT_INTERVAL_DAY_TIME |
			SQL_CVT_LONGVARCHAR |
			SQL_CVT_TIME |
			SQL_CVT_VARCHAR;
		break;
	case SQL_CONVERT_TIMESTAMP:
		nValue = SQL_CVT_CHAR |
			SQL_CVT_DATE |
			SQL_CVT_LONGVARCHAR |
			SQL_CVT_TIME |
			SQL_CVT_TIMESTAMP |
			SQL_CVT_VARCHAR;
		break;
	case SQL_CONVERT_GUID:
		nValue =SQL_CVT_CHAR |
			SQL_CVT_GUID |
			SQL_CVT_LONGVARCHAR |
			SQL_CVT_VARCHAR;
		break;
	case SQL_CONVERT_FUNCTIONS:
		nValue = SQL_FN_CVT_CAST | SQL_FN_CVT_CONVERT;
		break;
	case SQL_CORRELATION_NAME:
		nValue = SQL_CN_ANY;
		/* SQL_CN_DIFFERENT, SQL_CN_NONE */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_CREATE_ASSERTION:
		/* SQL_CA_CREATE_ASSERTION |
		 * SQL_CA_CONSTRAINT_DEFERRABLE |
		 * SQL_CA_CONSTRAINT_INITIALLY_DEFERRED |
		 * SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE |
		 * SQL_CA_CONSTRAINT_NON_DEFERRABLE */
	case SQL_CREATE_CHARACTER_SET:
		/* SQL_CCS_CREATE_CHARACTER_SET |
		 * SQL_CCS_COLLATE_CLAUSE |
		 * SQL_CCS_LIMITED_COLLATION */
	case SQL_CREATE_COLLATION:
		/* SQL_CCOL_CREATE_COLLATION */
	case SQL_CREATE_DOMAIN:
		/* SQL_CDO_CREATE_DOMAIN |
		 * SQL_CDO_CONSTRAINT_NAME_DEFINITION |
		 * SQL_CDO_DEFAULT |
		 * SQL_CDO_CONSTRAINT |
		 * SQL_CDO_COLLATION |
		 * SQL_CDO_CONSTRAINT_DEFERRABLE |
		 * SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED |
		 * SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE |
		 * SQL_CDO_CONSTRAINT_NON_DEFERRABLE */
	case SQL_CREATE_TRANSLATION:
		/* SQL_CTR_CREATE_TRANSLATION */
		break;
	case SQL_CREATE_SCHEMA:
		nValue = SQL_CS_CREATE_SCHEMA | SQL_CS_AUTHORIZATION;
		/* SQL_CS_DEFAULT_CHARACTER_SET */
		break;
	case SQL_CREATE_TABLE:
		nValue = SQL_CT_COLUMN_CONSTRAINT |
			SQL_CT_COLUMN_DEFAULT |
			SQL_CT_COMMIT_DELETE |
			SQL_CT_COMMIT_PRESERVE |
			SQL_CT_CONSTRAINT_NAME_DEFINITION |
			SQL_CT_CREATE_TABLE |
			SQL_CT_GLOBAL_TEMPORARY |
			SQL_CT_LOCAL_TEMPORARY |
			SQL_CT_TABLE_CONSTRAINT;
		/* SQL_CT_COLUMN_COLLATION |
		 * SQL_CT_CONSTRAINT_DEFERRABLE |
		 * SQL_CT_CONSTRAINT_INITIALLY_DEFERRED |
		 * SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE |
		 * SQL_CT_CONSTRAINT_NON_DEFERRABLE */
		break;
	case SQL_CREATE_VIEW:
		nValue = SQL_CV_CREATE_VIEW | SQL_CV_CHECK_OPTION;
		/* SQL_CV_CASCADE | SQL_CV_LOCAL */
		break;
	case SQL_CURSOR_COMMIT_BEHAVIOR:
	case SQL_CURSOR_ROLLBACK_BEHAVIOR:
		nValue = SQL_CB_DELETE;
		/* SQL_CB_CLOSE, SQL_CB_DELETE, SQL_CB_PRESERVE */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_CURSOR_SENSITIVITY:
		nValue = SQL_INSENSITIVE;
		/* SQL_SENSITIVE, SQL_UNSPECIFIED */
		break;
	case SQL_DATA_SOURCE_NAME:
		sValue = dbc->dsn ? dbc->dsn : "";
		break;
	case SQL_DATA_SOURCE_READ_ONLY:
		sValue = "N";	/* "Y" */
		break;
	case SQL_DATABASE_NAME:
		sValue = dbc->dbname ? dbc->dbname : "";
		break;
	case SQL_DATETIME_LITERALS:
		nValue = SQL_DL_SQL92_DATE |
			SQL_DL_SQL92_TIME |
			SQL_DL_SQL92_TIMESTAMP |
			SQL_DL_SQL92_INTERVAL_YEAR |
			SQL_DL_SQL92_INTERVAL_MONTH |
			SQL_DL_SQL92_INTERVAL_DAY |
			SQL_DL_SQL92_INTERVAL_HOUR |
			SQL_DL_SQL92_INTERVAL_MINUTE |
			SQL_DL_SQL92_INTERVAL_SECOND |
			SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH |
			SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR |
			SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE |
			SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND |
			SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE |
			SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND |
			SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND;
		len = sizeof(SQLINTEGER);
		break;
	case SQL_DBMS_NAME:
		sValue = PACKAGE_NAME;
		break;
	case SQL_DBMS_VER:
		snprintf(buf, sizeof(buf), "%02d.%02d.%04d",
			 dbc->major, dbc->minor, dbc->patch);
		sValue = buf;
		break;
	case SQL_DDL_INDEX:
		nValue = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX;
		break;
	case SQL_DEFAULT_TXN_ISOLATION:
		nValue = SQL_TXN_SERIALIZABLE;
		break;
	case SQL_DESCRIBE_PARAMETER:
		sValue = "N";	/* "Y" */
		break;
#ifdef SQL_DRIVER_AWARE_POOLING_SUPPORTED
	case SQL_DRIVER_AWARE_POOLING_SUPPORTED:
		nValue = SQL_DRIVER_AWARE_POOLING_NOT_CAPABLE;
		/* SQL_DRIVER_AWARE_POOLING_CAPABLE */
		break;
#endif
	case SQL_DRIVER_NAME:
		sValue = MONETDB_DRIVER_NAME;
		break;
	case SQL_DRIVER_ODBC_VER:
		sValue = MONETDB_ODBC_VER;
		break;
	case SQL_DRIVER_VER: {
		int maj = 0, min = 0, pat = 0;
		sscanf(PACKAGE_VERSION, "%d.%d.%d", &maj, &min, &pat);
		snprintf(buf, sizeof(buf), "%02d.%02d.%04d %s", maj, min, pat,
			 MONETDB_RELEASE);
		sValue = buf;
		break;
	}
	case SQL_DROP_ASSERTION:
		/* SQL_DA_DROP_ASSERION */
		break;
	case SQL_DROP_CHARACTER_SET:
		/* SQL_DCS_DROP_CHARACTER_SET */
		break;
	case SQL_DROP_COLLATION:
		/* SQL_DC_DROP_COLLATION */
		break;
	case SQL_DROP_DOMAIN:
		/* SQL_DD_DROP_DOMAIN | SQL_DD_CASCADE | SQL_DD_RESTRICT */
		break;
	case SQL_DROP_SCHEMA:
		nValue = SQL_DS_DROP_SCHEMA | SQL_DS_CASCADE | SQL_DS_RESTRICT;
		break;
	case SQL_DROP_TABLE:
		nValue = SQL_DT_DROP_TABLE | SQL_DT_CASCADE | SQL_DT_RESTRICT;
		break;
	case SQL_DROP_TRANSLATION:
		/* SQL_DTR_DROP_TRANSLATION */
		break;
	case SQL_DROP_VIEW:
		nValue = SQL_DV_DROP_VIEW | SQL_DV_CASCADE | SQL_DV_RESTRICT;
		break;
	case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
		nValue = SQL_CA1_ABSOLUTE | SQL_CA1_NEXT | SQL_CA1_RELATIVE;
		/* SQL_CA1_BOOKMARK |
		 * SQL_CA1_BULK_ADD |
		 * SQL_CA1_BULK_DELETE_BY_BOOKMARK |
		 * SQL_CA1_BULK_FETCH_BY_BOOKMARK |
		 * SQL_CA1_BULK_UPDATE_BY_BOOKMARK |
		 * SQL_CA1_LOCK_EXCLUSIVE |
		 * SQL_CA1_LOCK_NO_CHANGE |
		 * SQL_CA1_LOCK_UNLOCK |
		 * SQL_CA1_POS_DELETE |
		 * SQL_CA1_POSITIONED_DELETE |
		 * SQL_CA1_POSITIONED_UPDATE |
		 * SQL_CA1_POS_POSITION |
		 * SQL_CA1_POS_REFRESH |
		 * SQL_CA1_POS_UPDATE |
		 * SQL_CA1_SELECT_FOR_UPDATE */
		break;
	case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
		/* SQL_CA2_CRC_APPROXIMATE |
		 * SQL_CA2_CRC_EXACT |
		 * SQL_CA2_LOCK_CONCURRENCY |
		 * SQL_CA2_MAX_ROWS_AFFECTS_ALL |
		 * SQL_CA2_MAX_ROWS_CATALOG |
		 * SQL_CA2_MAX_ROWS_DELETE |
		 * SQL_CA2_MAX_ROWS_INSERT |
		 * SQL_CA2_MAX_ROWS_SELECT |
		 * SQL_CA2_MAX_ROWS_UPDATE |
		 * SQL_CA2_OPT_ROWVER_CONCURRENCY |
		 * SQL_CA2_OPT_VALUES_CONCURRENCY |
		 * SQL_CA2_READ_ONLY_CONCURRENCY |
		 * SQL_CA2_SENSITIVITY_ADDITIONS |
		 * SQL_CA2_SENSITIVITY_DELETIONS |
		 * SQL_CA2_SENSITIVITY_UPDATES |
		 * SQL_CA2_SIMULATE_NON_UNIQUE |
		 * SQL_CA2_SIMULATE_TRY_UNIQUE |
		 * SQL_CA2_SIMULATE_UNIQUE */
		break;
	case SQL_EXPRESSIONS_IN_ORDERBY:
		sValue = "Y";	/* "N" */
		break;
	case SQL_FILE_USAGE:
		nValue = SQL_FILE_NOT_SUPPORTED;
		/* SQL_FILE_TABLE, SQL_FILE_CATALOG */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
		nValue = SQL_CA1_NEXT;
		/* SQL_CA1_BULK_ADD |
		 * SQL_CA1_BULK_DELETE_BY_BOOKMARK |
		 * SQL_CA1_BULK_FETCH_BY_BOOKMARK |
		 * SQL_CA1_BULK_UPDATE_BY_BOOKMARK |
		 * SQL_CA1_LOCK_EXCLUSIVE |
		 * SQL_CA1_LOCK_NO_CHANGE |
		 * SQL_CA1_LOCK_UNLOCK |
		 * SQL_CA1_POS_DELETE |
		 * SQL_CA1_POSITIONED_DELETE |
		 * SQL_CA1_POSITIONED_UPDATE |
		 * SQL_CA1_POS_POSITION |
		 * SQL_CA1_POS_REFRESH |
		 * SQL_CA1_POS_UPDATE |
		 * SQL_CA1_SELECT_FOR_UPDATE */
		break;
	case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
		/* SQL_CA2_CRC_APPROXIMATE |
		 * SQL_CA2_CRC_EXACT |
		 * SQL_CA2_LOCK_CONCURRENCY |
		 * SQL_CA2_MAX_ROWS_AFFECTS_ALL |
		 * SQL_CA2_MAX_ROWS_CATALOG |
		 * SQL_CA2_MAX_ROWS_DELETE |
		 * SQL_CA2_MAX_ROWS_INSERT |
		 * SQL_CA2_MAX_ROWS_SELECT |
		 * SQL_CA2_MAX_ROWS_UPDATE |
		 * SQL_CA2_OPT_ROWVER_CONCURRENCY |
		 * SQL_CA2_OPT_VALUES_CONCURRENCY |
		 * SQL_CA2_READ_ONLY_CONCURRENCY |
		 * SQL_CA2_SENSITIVITY_ADDITIONS |
		 * SQL_CA2_SENSITIVITY_DELETIONS |
		 * SQL_CA2_SENSITIVITY_UPDATES |
		 * SQL_CA2_SIMULATE_NON_UNIQUE |
		 * SQL_CA2_SIMULATE_TRY_UNIQUE |
		 * SQL_CA2_SIMULATE_UNIQUE */
		break;
	case SQL_GETDATA_EXTENSIONS:
		nValue = SQL_GD_ANY_COLUMN |
			SQL_GD_ANY_ORDER |
			SQL_GD_BLOCK |
			SQL_GD_BOUND;
		/* SQL_GD_OUTPUT_PARAMS */
		break;
	case SQL_GROUP_BY:
		nValue = SQL_GB_NO_RELATION;
		/* SQL_GB_COLLATE, SQL_GB_NOT_SUPPORTED,
		 * SQL_GB_BROUP_BY_EQUALS_SELECT,
		 * SQL_GB_GROUP_BY_CONTAINS_SELECT */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_IDENTIFIER_CASE:
		nValue = SQL_IC_LOWER;
		/* SQL_IC_UPPER, SQL_IC_SENSITIVE, SQL_IC_MIXED */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_IDENTIFIER_QUOTE_CHAR:
		sValue = "\"";	/* the " (double quote) */
		break;
	case SQL_INDEX_KEYWORDS:
		nValue = SQL_IK_NONE;
		/* SQL_IK_ASC | SQL_IK_DESC | SQL_IK_ALL */
		break;
	case SQL_INFO_SCHEMA_VIEWS:
		/* SQL_ISV_ASSERTIONS |
		 * SQL_ISV_CHARACTER_SETS |
		 * SQL_ISV_CHECK_CONSTRAINTS |
		 * SQL_ISV_COLLATIONS |
		 * SQL_ISV_COLUMN_DOMAIN_USAGE |
		 * SQL_ISV_COLUMN_PRIVILEGES |
		 * SQL_ISV_COLUMNS |
		 * SQL_ISV_CONSTRAINT_COLUMN_USAGE |
		 * SQL_ISV_CONSTRAINT_TABLE_USAGE |
		 * SQL_ISV_DOMAIN_CONSTRAINTS |
		 * SQL_ISV_DOMAINS |
		 * SQL_ISV_KEY_COLUMN_USAGE |
		 * SQL_ISV_REFERENTIAL_CONSTRAINTS |
		 * SQL_ISV_SCHEMATA |
		 * SQL_ISV_SQL_LANGUAGES |
		 * SQL_ISV_TABLE_CONSTRAINTS |
		 * SQL_ISV_TABLE_PRIVILEGES |
		 * SQL_ISV_TABLES |
		 * SQL_ISV_TRANSLATIONS |
		 * SQL_ISV_USAGE_PRIVILEGES |
		 * SQL_ISV_VIEW_COLUMN_USAGE |
		 * SQL_ISV_VIEWS |
		 * SQL_ISV_VIEW_TABLE_USAGE */
		break;
	case SQL_INSERT_STATEMENT:
		nValue = SQL_IS_INSERT_LITERALS |
			SQL_IS_INSERT_SEARCHED |
			SQL_IS_SELECT_INTO;
		break;
	case SQL_INTEGRITY:
		sValue = "N";	/* "Y" */
		break;
	case SQL_KEYSET_CURSOR_ATTRIBUTES1:
		/* SQL_CA1_ABSOLUTE |
		 * SQL_CA1_BOOKMARK |
		 * SQL_CA1_BULK_ADD |
		 * SQL_CA1_BULK_DELETE_BY_BOOKMARK |
		 * SQL_CA1_BULK_FETCH_BY_BOOKMARK |
		 * SQL_CA1_BULK_UPDATE_BY_BOOKMARK |
		 * SQL_CA1_LOCK_EXCLUSIVE |
		 * SQL_CA1_LOCK_NO_CHANGE |
		 * SQL_CA1_LOCK_UNLOCK |
		 * SQL_CA1_NEXT |
		 * SQL_CA1_POS_DELETE |
		 * SQL_CA1_POSITIONED_DELETE |
		 * SQL_CA1_POSITIONED_UPDATE |
		 * SQL_CA1_POS_POSITION |
		 * SQL_CA1_POS_REFRESH |
		 * SQL_CA1_POS_UPDATE |
		 * SQL_CA1_RELATIVE |
		 * SQL_CA1_SELECT_FOR_UPDATE */
		break;
	case SQL_KEYSET_CURSOR_ATTRIBUTES2:
		/* SQL_CA2_CRC_APPROXIMATE |
		 * SQL_CA2_CRC_EXACT |
		 * SQL_CA2_LOCK_CONCURRENCY |
		 * SQL_CA2_MAX_ROWS_AFFECTS_ALL |
		 * SQL_CA2_MAX_ROWS_CATALOG |
		 * SQL_CA2_MAX_ROWS_DELETE |
		 * SQL_CA2_MAX_ROWS_INSERT |
		 * SQL_CA2_MAX_ROWS_SELECT |
		 * SQL_CA2_MAX_ROWS_UPDATE |
		 * SQL_CA2_OPT_ROWVER_CONCURRENCY |
		 * SQL_CA2_OPT_VALUES_CONCURRENCY |
		 * SQL_CA2_READ_ONLY_CONCURRENCY |
		 * SQL_CA2_SENSITIVITY_ADDITIONS |
		 * SQL_CA2_SENSITIVITY_DELETIONS |
		 * SQL_CA2_SENSITIVITY_UPDATES |
		 * SQL_CA2_SIMULATE_NON_UNIQUE |
		 * SQL_CA2_SIMULATE_TRY_UNIQUE |
		 * SQL_CA2_SIMULATE_UNIQUE */
		break;
	case SQL_KEYWORDS:
		/* Returns the MonetDB keywords which are not listed
		 * as ODBC keyword in the #define SQL_ODBC_KEYWORDS in
		 * sql.h, collated from
		 * sql_scan.c:scanner_init_keywords with values
		 * removed that are in
		 * sql_parser.y:non_reserved_word */
		sValue = "ADMIN,AFTER,AGGREGATE,ALWAYS,ASYMMETRIC,ATOMIC,"
			"AUTO_INCREMENT,BEFORE,BIGINT,BIGSERIAL,BINARY,BLOB,"
			"CALL,CHAIN,CLOB,COMMITTED,COPY,CORR,CUME_DIST,"
			"CURRENT_ROLE,CYCLE,DATABASE,DELIMITERS,DENSE_RANK,"
			"DO,EACH,ELSEIF,ENCRYPTED,EVERY,EXCLUDE,FOLLOWING,"
			"FUNCTION,GENERATED,IF,ILIKE,INCREMENT,LAG,LEAD,"
			"LIMIT,LOCALTIME,LOCALTIMESTAMP,LOCKED,MAXVALUE,"
			"MEDIAN,MEDIUMINT,MERGE,MINVALUE,NEW,NOCYCLE,"
			"NOMAXVALUE,NOMINVALUE,NOW,OFFSET,OLD,OTHERS,OVER,"
			"PARTITION,PERCENT_RANK,PLAN,PRECEDING,PROD,QUANTILE,"
			"RANGE,RANK,RECORDS,REFERENCING,REMOTE,RENAME,"
			"REPEATABLE,REPLICA,RESTART,RETURN,RETURNS,"
			"ROW_NUMBER,ROWS,SAMPLE,SAVEPOINT,SCHEMA,SEQUENCE,"
			"SERIAL,SERIALIZABLE,SIMPLE,START,STATEMENT,STDIN,"
			"STDOUT,STREAM,STRING,SYMMETRIC,TIES,TINYINT,TRIGGER,"
			"UNBOUNDED,UNCOMMITTED,UNENCRYPTED,WHILE,XMLAGG,"
			"XMLATTRIBUTES,XMLCOMMENT,XMLCONCAT,XMLDOCUMENT,"
			"XMLELEMENT,XMLFOREST,XMLNAMESPACES,XMLPARSE,XMLPI,"
			"XMLQUERY,XMLSCHEMA,XMLTEXT,XMLVALIDATE";
		break;
	case SQL_LIKE_ESCAPE_CLAUSE:
		sValue = "Y";	/* "N" */
		break;
	case SQL_MAX_ASYNC_CONCURRENT_STATEMENTS:
		break;
	case SQL_MAX_BINARY_LITERAL_LEN:
		break;
	case SQL_MAX_CATALOG_NAME_LEN:
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_MAX_CHAR_LITERAL_LEN:
		break;
	case SQL_MAX_COLUMN_NAME_LEN:
	case SQL_MAX_COLUMNS_IN_GROUP_BY:
	case SQL_MAX_COLUMNS_IN_INDEX:
	case SQL_MAX_COLUMNS_IN_ORDER_BY:
	case SQL_MAX_COLUMNS_IN_SELECT:
	case SQL_MAX_COLUMNS_IN_TABLE:
	case SQL_MAX_CONCURRENT_ACTIVITIES:
	case SQL_MAX_CURSOR_NAME_LEN:
	case SQL_MAX_DRIVER_CONNECTIONS:
	case SQL_MAX_IDENTIFIER_LEN:
	case SQL_MAX_INDEX_SIZE:
	case SQL_MAX_PROCEDURE_NAME_LEN:
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_MAX_ROW_SIZE:
		break;
	case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
		sValue = "Y";	/* "N" */
		break;
	case SQL_MAX_SCHEMA_NAME_LEN:
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_MAX_STATEMENT_LEN:
		break;
	case SQL_MAX_TABLE_NAME_LEN:
	case SQL_MAX_TABLES_IN_SELECT:
	case SQL_MAX_USER_NAME_LEN:
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_MULT_RESULT_SETS:
		sValue = "Y";	/* "N" */
		break;
	case SQL_MULTIPLE_ACTIVE_TXN:
		sValue = "Y";	/* "N" */
		break;
	case SQL_NEED_LONG_DATA_LEN:
		sValue = "N";	/* "Y" */
		break;
	case SQL_NON_NULLABLE_COLUMNS:
		nValue = SQL_NNC_NON_NULL;
		/* SQL_NNC_NULL */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_NULL_COLLATION:
		nValue = SQL_NC_LOW;
		/* SQL_NC_END, SQL_NC_HIGH, SQL_NC_START */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_NUMERIC_FUNCTIONS:
		nValue = SQL_FN_NUM_ABS |
			SQL_FN_NUM_ACOS |
			SQL_FN_NUM_ASIN |
			SQL_FN_NUM_ATAN |
			SQL_FN_NUM_ATAN2 |
			SQL_FN_NUM_CEILING |
			SQL_FN_NUM_COS |
			SQL_FN_NUM_COT |
			SQL_FN_NUM_DEGREES |
			SQL_FN_NUM_EXP |
			SQL_FN_NUM_FLOOR |
			SQL_FN_NUM_LOG |
			SQL_FN_NUM_LOG10 |
			SQL_FN_NUM_MOD |
			SQL_FN_NUM_PI |
			SQL_FN_NUM_POWER |
			SQL_FN_NUM_RADIANS |
			SQL_FN_NUM_RAND |
			SQL_FN_NUM_ROUND |
			SQL_FN_NUM_SIGN |
			SQL_FN_NUM_SIN |
			SQL_FN_NUM_SQRT |
			SQL_FN_NUM_TAN |
			SQL_FN_NUM_TRUNCATE;
		break;
	case SQL_ODBC_INTERFACE_CONFORMANCE:
		nValue = SQL_OIC_CORE;
		/* SQL_OIC_LEVEL1, SQL_OIC_LEVEL2 */
		break;
	case SQL_OJ_CAPABILITIES:
		nValue = SQL_OJ_LEFT |
			SQL_OJ_RIGHT |
			SQL_OJ_FULL |
			SQL_OJ_NOT_ORDERED |
			SQL_OJ_INNER |
			SQL_OJ_ALL_COMPARISON_OPS;
		/* SQL_OJ_NESTED */
		break;
	case SQL_ORDER_BY_COLUMNS_IN_SELECT:
		sValue = "N";	/* "Y" */
		break;
	case SQL_PARAM_ARRAY_ROW_COUNTS:
		nValue = SQL_PARC_BATCH; /* ? */
		/* SQL_PARC_NO_BATCH */
		break;
	case SQL_PARAM_ARRAY_SELECTS:
		nValue = SQL_PAS_NO_SELECT;
		/* SQL_PAS_BATCH, SQL_PAS_NO_BATCH */
		break;
	case SQL_PROCEDURE_TERM:
		sValue = "procedure";
		break;
	case SQL_PROCEDURES:
		sValue = "Y";	/* "N" */
		break;
	case SQL_QUOTED_IDENTIFIER_CASE:
		nValue = SQL_IC_SENSITIVE;
		/* SQL_IC_LOWER, SQL_IC_MIXED, SQL_IC_UPPER */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_ROW_UPDATES:
		sValue = "N";	/* "Y" */
		break;
	case SQL_SCHEMA_TERM:
		sValue = "schema";
		break;
	case SQL_SCHEMA_USAGE:
		nValue = SQL_SU_DML_STATEMENTS |
			SQL_SU_PROCEDURE_INVOCATION |
			SQL_SU_TABLE_DEFINITION |
			SQL_SU_INDEX_DEFINITION |
			SQL_SU_PRIVILEGE_DEFINITION;
		break;
	case SQL_SCROLL_OPTIONS:
		nValue = SQL_SO_STATIC;
		/* SQL_SO_DYNAMIC,
		 * SQL_SO_FORWARD_ONLY,
		 * SQL_SO_KEYSET_DRIVEN,
		 * SQL_SO_MIXED */
		break;
	case SQL_SEARCH_PATTERN_ESCAPE:
		sValue = "\\";
		break;
	case SQL_SERVER_NAME:
		sValue = MONETDB_SERVER_NAME;
		break;
	case SQL_SPECIAL_CHARACTERS:
		sValue = "!$&'()*+,-./:;<=>?@[]^`{|}~";
		break;
	case SQL_SQL_CONFORMANCE:
		nValue = SQL_SC_SQL92_FULL;
		break;
	case SQL_SQL92_DATETIME_FUNCTIONS:
		nValue = SQL_SDF_CURRENT_DATE |
			SQL_SDF_CURRENT_TIME |
			SQL_SDF_CURRENT_TIMESTAMP;
		break;
	case SQL_SQL92_FOREIGN_KEY_DELETE_RULE: /* ? */
		nValue = SQL_SFKD_CASCADE |
			SQL_SFKD_NO_ACTION |
			SQL_SFKD_SET_DEFAULT |
			SQL_SFKD_SET_NULL;
		break;
	case SQL_SQL92_FOREIGN_KEY_UPDATE_RULE: /* ? */
		nValue = SQL_SFKU_CASCADE |
			SQL_SFKU_NO_ACTION |
			SQL_SFKU_SET_DEFAULT |
			SQL_SFKU_SET_NULL;
		break;
	case SQL_SQL92_GRANT:
		nValue = SQL_SG_DELETE_TABLE |
			SQL_SG_INSERT_COLUMN |
			SQL_SG_INSERT_TABLE |
			SQL_SG_REFERENCES_COLUMN |
			SQL_SG_REFERENCES_TABLE |
			SQL_SG_SELECT_TABLE |
			SQL_SG_UPDATE_COLUMN |
			SQL_SG_UPDATE_TABLE |
			SQL_SG_WITH_GRANT_OPTION;
		/* SQL_SG_USAGE_ON_CHARACTER_SET |
		 * SQL_SG_USAGE_ON_COLLATION |
		 * SQL_SG_USAGE_ON_DOMAIN |
		 * SQL_SG_USAGE_ON_TRANSLATION */
		break;
	case SQL_SQL92_NUMERIC_VALUE_FUNCTIONS:
		nValue = SQL_SNVF_CHAR_LENGTH |
			SQL_SNVF_CHARACTER_LENGTH |
			SQL_SNVF_EXTRACT |
			SQL_SNVF_OCTET_LENGTH |
			SQL_SNVF_POSITION;
		/* SQL_SNVF_BIT_LENGTH */
		break;
	case SQL_SQL92_PREDICATES: /* ? */
		nValue = SQL_SP_BETWEEN |
			SQL_SP_COMPARISON |
			SQL_SP_EXISTS |
			SQL_SP_IN |
			SQL_SP_ISNOTNULL |
			SQL_SP_ISNULL |
			SQL_SP_LIKE |
			SQL_SP_MATCH_FULL |
			SQL_SP_MATCH_PARTIAL|
			SQL_SP_MATCH_UNIQUE_FULL |
			SQL_SP_MATCH_UNIQUE_PARTIAL |
			SQL_SP_OVERLAPS |
			SQL_SP_QUANTIFIED_COMPARISON |
			SQL_SP_UNIQUE;
		break;
	case SQL_SQL92_RELATIONAL_JOIN_OPERATORS:
		nValue = SQL_SRJO_CORRESPONDING_CLAUSE |
			SQL_SRJO_CROSS_JOIN |
			SQL_SRJO_EXCEPT_JOIN |
			SQL_SRJO_FULL_OUTER_JOIN |
			SQL_SRJO_INNER_JOIN |
			SQL_SRJO_INTERSECT_JOIN |
			SQL_SRJO_LEFT_OUTER_JOIN |
			SQL_SRJO_NATURAL_JOIN |
			SQL_SRJO_RIGHT_OUTER_JOIN |
			SQL_SRJO_UNION_JOIN;
		break;
	case SQL_SQL92_REVOKE:
		nValue = SQL_SR_CASCADE |
			SQL_SR_DELETE_TABLE |
			SQL_SR_GRANT_OPTION_FOR |
			SQL_SR_INSERT_COLUMN |
			SQL_SR_INSERT_TABLE |
			SQL_SR_REFERENCES_COLUMN |
			SQL_SR_REFERENCES_TABLE |
			SQL_SR_RESTRICT |
			SQL_SR_SELECT_TABLE |
			SQL_SR_UPDATE_COLUMN |
			SQL_SR_UPDATE_TABLE;
		/* SQL_SR_USAGE_ON_DOMAIN |
		 * SQL_SR_USAGE_ON_CHARACTER_SET |
		 * SQL_SR_USAGE_ON_COLLATION |
		 * SQL_SR_USAGE_ON_TRANSLATION */
		break;
	case SQL_SQL92_ROW_VALUE_CONSTRUCTOR: /* ? */
		nValue = SQL_SRVC_VALUE_EXPRESSION |
			SQL_SRVC_NULL |
			SQL_SRVC_DEFAULT |
			SQL_SRVC_ROW_SUBQUERY;
		break;
	case SQL_SQL92_STRING_FUNCTIONS: /* ? */
		nValue = SQL_SSF_CONVERT |
			SQL_SSF_LOWER |
			SQL_SSF_UPPER |
			SQL_SSF_SUBSTRING |
			SQL_SSF_TRANSLATE |
			SQL_SSF_TRIM_BOTH |
			SQL_SSF_TRIM_LEADING |
			SQL_SSF_TRIM_TRAILING;
		break;
	case SQL_SQL92_VALUE_EXPRESSIONS:
		nValue = SQL_SVE_CASE |
			SQL_SVE_CAST |
			SQL_SVE_COALESCE |
			SQL_SVE_NULLIF;
		break;
	case SQL_STANDARD_CLI_CONFORMANCE: /* ? */
		nValue = SQL_SCC_XOPEN_CLI_VERSION1 | SQL_SCC_ISO92_CLI;
		break;
	case SQL_STATIC_CURSOR_ATTRIBUTES1:
		nValue = SQL_CA1_ABSOLUTE |
			SQL_CA1_NEXT |
			SQL_CA1_RELATIVE;
		/* SQL_CA1_BOOKMARK |
		 * SQL_CA1_BULK_ADD |
		 * SQL_CA1_BULK_DELETE_BY_BOOKMARK |
		 * SQL_CA1_BULK_FETCH_BY_BOOKMARK |
		 * SQL_CA1_BULK_UPDATE_BY_BOOKMARK |
		 * SQL_CA1_LOCK_EXCLUSIVE |
		 * SQL_CA1_LOCK_NO_CHANGE |
		 * SQL_CA1_LOCK_UNLOCK |
		 * SQL_CA1_POS_DELETE |
		 * SQL_CA1_POSITIONED_DELETE |
		 * SQL_CA1_POSITIONED_UPDATE |
		 * SQL_CA1_POS_POSITION |
		 * SQL_CA1_POS_REFRESH |
		 * SQL_CA1_POS_UPDATE |
		 * SQL_CA1_SELECT_FOR_UPDATE */
		break;
	case SQL_STATIC_CURSOR_ATTRIBUTES2:
		/* SQL_CA2_CRC_APPROXIMATE |
		 * SQL_CA2_CRC_EXACT |
		 * SQL_CA2_LOCK_CONCURRENCY |
		 * SQL_CA2_MAX_ROWS_AFFECTS_ALL |
		 * SQL_CA2_MAX_ROWS_CATALOG |
		 * SQL_CA2_MAX_ROWS_DELETE |
		 * SQL_CA2_MAX_ROWS_INSERT |
		 * SQL_CA2_MAX_ROWS_SELECT |
		 * SQL_CA2_MAX_ROWS_UPDATE |
		 * SQL_CA2_OPT_ROWVER_CONCURRENCY |
		 * SQL_CA2_OPT_VALUES_CONCURRENCY |
		 * SQL_CA2_READ_ONLY_CONCURRENCY |
		 * SQL_CA2_SENSITIVITY_ADDITIONS |
		 * SQL_CA2_SENSITIVITY_DELETIONS |
		 * SQL_CA2_SENSITIVITY_UPDATES |
		 * SQL_CA2_SIMULATE_NON_UNIQUE |
		 * SQL_CA2_SIMULATE_TRY_UNIQUE |
		 * SQL_CA2_SIMULATE_UNIQUE */
		break;
	case SQL_STRING_FUNCTIONS:
		nValue = SQL_FN_STR_ASCII |
			SQL_FN_STR_BIT_LENGTH |
			SQL_FN_STR_CHAR |
			SQL_FN_STR_CHARACTER_LENGTH |
			SQL_FN_STR_CHAR_LENGTH |
			SQL_FN_STR_CONCAT |
			SQL_FN_STR_DIFFERENCE |
			SQL_FN_STR_INSERT |
			SQL_FN_STR_LCASE |
			SQL_FN_STR_LEFT |
			SQL_FN_STR_LENGTH |
			SQL_FN_STR_LOCATE |
			SQL_FN_STR_LOCATE_2 |
			SQL_FN_STR_LTRIM |
			SQL_FN_STR_OCTET_LENGTH |
			SQL_FN_STR_POSITION |
			SQL_FN_STR_REPEAT |
			SQL_FN_STR_REPLACE |
			SQL_FN_STR_RIGHT |
			SQL_FN_STR_RTRIM |
			SQL_FN_STR_SOUNDEX |
			SQL_FN_STR_SPACE |
			SQL_FN_STR_SUBSTRING |
			SQL_FN_STR_UCASE;
		break;
	case SQL_SUBQUERIES:
		nValue = SQL_SQ_CORRELATED_SUBQUERIES |
			SQL_SQ_COMPARISON |
			SQL_SQ_EXISTS |
			SQL_SQ_IN |
			SQL_SQ_QUANTIFIED;
		break;
	case SQL_SYSTEM_FUNCTIONS:
		nValue = SQL_FN_SYS_DBNAME |
			SQL_FN_SYS_IFNULL |
			SQL_FN_SYS_USERNAME;
		break;
	case SQL_TABLE_TERM:
		sValue = "table";
		break;
	case SQL_TIMEDATE_ADD_INTERVALS:
	case SQL_TIMEDATE_DIFF_INTERVALS:
		/* SQL_FN_TSI_FRAC_SECOND |
		 * SQL_FN_TSI_SECOND |
		 * SQL_FN_TSI_MINUTE |
		 * SQL_FN_TSI_HOUR |
		 * SQL_FN_TSI_DAY |
		 * SQL_FN_TSI_WEEK |
		 * SQL_FN_TSI_MONTH |
		 * SQL_FN_TSI_QUARTER |
		 * SQL_FN_TSI_YEAR */
		break;
	case SQL_TIMEDATE_FUNCTIONS:
		nValue = SQL_FN_TD_CURRENT_DATE |
			SQL_FN_TD_CURRENT_TIME |
			SQL_FN_TD_CURRENT_TIMESTAMP |
			SQL_FN_TD_CURDATE |
			SQL_FN_TD_CURTIME |
			/* SQL_FN_TD_DAYNAME | */
			SQL_FN_TD_DAYOFMONTH |
			SQL_FN_TD_DAYOFWEEK |
			SQL_FN_TD_DAYOFYEAR |
			SQL_FN_TD_EXTRACT |
			SQL_FN_TD_HOUR |
			SQL_FN_TD_MINUTE |
			SQL_FN_TD_MONTH |
			/* SQL_FN_TD_MONTHNAME | */
			SQL_FN_TD_NOW |
			SQL_FN_TD_QUARTER |
			SQL_FN_TD_SECOND |
			/* SQL_FN_TD_TIMESTAMPADD | */
			/* SQL_FN_TD_TIMESTAMPDIFF | */
			SQL_FN_TD_WEEK |
			SQL_FN_TD_YEAR;
		break;
	case SQL_TXN_CAPABLE:
		nValue = SQL_TC_ALL;
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_TXN_ISOLATION_OPTION:
		nValue = SQL_TXN_SERIALIZABLE;
		break;
	case SQL_UNION:
		nValue = SQL_U_UNION | SQL_U_UNION_ALL;
		break;
	case SQL_USER_NAME:
		sValue = dbc->uid ? dbc->uid : "";
		break;
	case SQL_XOPEN_CLI_YEAR: /* ? */
		sValue = "";
		break;

	/* deprecated info types */
	case SQL_FETCH_DIRECTION:
		nValue = SQL_FD_FETCH_ABSOLUTE |
			SQL_FD_FETCH_FIRST |
			SQL_FD_FETCH_LAST |
			SQL_FD_FETCH_NEXT |
			SQL_FD_FETCH_PRIOR |
			SQL_FD_FETCH_RELATIVE;
		/* SQL_FD_FETCH_BOOKMARK */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_LOCK_TYPES:
		nValue = SQL_LCK_NO_CHANGE;
		/*  SQL_LCK_EXCLUSIVE | SQL_LCK_UNLOCK */
		break;
	case SQL_ODBC_API_CONFORMANCE:
		nValue = SQL_OAC_LEVEL2;
		/* SQL_OAC_CORE, SQL_OAC_LEVEL1 */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_ODBC_SQL_CONFORMANCE:
		nValue = SQL_OSC_CORE;
		/* SQL_OSC_MINIMUM, SQL_OSC_EXTENDED */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_POS_OPERATIONS:
		nValue = SQL_POS_POSITION;
		/* SQL_POS_ADD |
		 * SQL_POS_DELETE |
		 * SQL_POS_REFRESH |
		 * SQL_POS_UPDATE */
		break;
	case SQL_POSITIONED_STATEMENTS:
		nValue = SQL_PS_SELECT_FOR_UPDATE;
		/* SQL_PS_POSITIONED_DELETE |
		 * SQL_PS_POSITIONED_UPDATE |
		 * SQL_PS_SELECT_FOR_UPDATE */
		break;
	case SQL_SCROLL_CONCURRENCY:
		nValue = SQL_SCCO_READ_ONLY;
		/* SQL_SCCO_LOCK |
		 * SQL_SCCO_OPT_ROWVER |
		 * SQL_SCCO_OPT_VALUES */
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_STATIC_SENSITIVITY:
		/* SQL_SS_ADDITIONS |
		 * SQL_SS_DELETIONS |
		 * SQL_SS_UPDATES */
		len = sizeof(SQLINTEGER);
		break;

	case SQL_ODBC_SAG_CLI_CONFORMANCE:
		nValue = SQL_OSCC_COMPLIANT;
		len = sizeof(SQLUSMALLINT);
		break;
	case SQL_OUTER_JOINS:
		sValue = "Y";	/* "N" */
		break;

	default:
		/* Invalid information type */
		addDbcError(dbc, "HY096", NULL, 0);
		return SQL_ERROR;
	}

	/* copy the data to the supplied output parameters */
	if (sValue) {
		copyString(sValue, strlen(sValue), InfoValuePtr, BufferLength, StringLengthPtr, SQLSMALLINT, addDbcError, dbc, return SQL_ERROR);
	} else if (InfoValuePtr) {
Example #11
0
SQLRETURN
MNDBSetConnectAttr(ODBCDbc *dbc,
		   SQLINTEGER Attribute,
		   SQLPOINTER ValuePtr,
		   SQLINTEGER StringLength)
{
	(void) StringLength;	/* Stefan: unused!? */

	switch (Attribute) {
	case SQL_ATTR_AUTOCOMMIT:		/* SQLUINTEGER */
		switch ((SQLUINTEGER) (uintptr_t) ValuePtr) {
		case SQL_AUTOCOMMIT_ON:
		case SQL_AUTOCOMMIT_OFF:
			dbc->sql_attr_autocommit = (SQLUINTEGER) (uintptr_t) ValuePtr;
#ifdef ODBCDEBUG
			ODBCLOG("SQLSetConnectAttr set autocommit %s\n",
				dbc->sql_attr_autocommit == SQL_AUTOCOMMIT_ON ? "on" : "off");
#endif
			if (dbc->mid)
				mapi_setAutocommit(dbc->mid, dbc->sql_attr_autocommit == SQL_AUTOCOMMIT_ON);
			break;
		default:
			/* Invalid attribute value */
			addDbcError(dbc, "HY024", NULL, 0);
			return SQL_ERROR;
		}
		return SQL_SUCCESS;
	case SQL_ATTR_CURRENT_CATALOG:		/* SQLCHAR* */
		fixODBCstring(ValuePtr, StringLength, SQLINTEGER,
			      addDbcError, dbc, return SQL_ERROR);
		if (dbc->Connected) {
			/* Driver does not support this functions */
			addDbcError(dbc, "IM001", NULL, 0);
			return SQL_ERROR;
		}
		if (dbc->dbname)
			free(dbc->dbname);
		dbc->dbname = dupODBCstring(ValuePtr, StringLength);
		if (dbc->dbname == NULL) {
			/* Memory allocation error */
			addDbcError(dbc, "HY001", NULL, 0);
			return SQL_ERROR;
		}
		break;
	case SQL_ATTR_CONNECTION_TIMEOUT:	/* SQLUINTEGER */
		dbc->sql_attr_connection_timeout = (SQLUINTEGER) (uintptr_t) ValuePtr;
		if (dbc->mid)
			mapi_timeout(dbc->mid, dbc->sql_attr_connection_timeout * 1000);
		break;
	case SQL_ATTR_METADATA_ID:		/* SQLUINTEGER */
		switch ((SQLUINTEGER) (uintptr_t) ValuePtr) {
		case SQL_TRUE:
		case SQL_FALSE:
			dbc->sql_attr_metadata_id = (SQLUINTEGER) (uintptr_t) ValuePtr;
#ifdef ODBCDEBUG
			ODBCLOG("SQLSetConnectAttr set metadata_id %s\n",
				dbc->sql_attr_metadata_id == SQL_TRUE ? "true" : "false");
#endif
			break;
		default:
			/* Invalid attribute value */
			addDbcError(dbc, "HY024", NULL, 0);
			return SQL_ERROR;
		}
		return SQL_SUCCESS;
	case SQL_ATTR_TXN_ISOLATION:		/* SQLUINTEGER */
		/* nothing to change, we only do the highest level */
		break;

		/* TODO: implement connection attribute behavior */
	case SQL_ATTR_ACCESS_MODE:		/* SQLUINTEGER */
#ifdef SQL_ATTR_ASYNC_DBC_EVENT
	case SQL_ATTR_ASYNC_DBC_EVENT:		/* SQLPOINTER */
#endif
#ifdef SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE
	case SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE: /* SQLUINTEGER */
#endif
#ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK
	case SQL_ATTR_ASYNC_DBC_PCALLBACK:	/* SQLPOINTER */
#endif
#ifdef SQL_ATTR_ASYNC_DBC_PCONTEXT
	case SQL_ATTR_ASYNC_DBC_PCONTEXT:	/* SQLPOINTER */
#endif
	case SQL_ATTR_ASYNC_ENABLE:		/* SQLULEN */
#ifdef SQL_ATTR_DBC_INFO_TOKEN
	case SQL_ATTR_DBC_INFO_TOKEN:		/* SQLPOINTER */
#endif
	case SQL_ATTR_ENLIST_IN_DTC:		/* SQLPOINTER */
	case SQL_ATTR_LOGIN_TIMEOUT:		/* SQLUINTEGER */
	case SQL_ATTR_ODBC_CURSORS:		/* SQLULEN */
	case SQL_ATTR_PACKET_SIZE:		/* SQLUINTEGER */
	case SQL_ATTR_QUIET_MODE:		/* HWND (SQLPOINTER) */
	case SQL_ATTR_TRACE:			/* SQLUINTEGER */
	case SQL_ATTR_TRACEFILE:		/* SQLCHAR* */
	case SQL_ATTR_TRANSLATE_LIB:		/* SQLCHAR* */
	case SQL_ATTR_TRANSLATE_OPTION:		/* SQLUINTEGER */
		/* Optional feature not implemented */
		addDbcError(dbc, "HYC00", NULL, 0);
		return SQL_ERROR;
	case SQL_ATTR_AUTO_IPD:			/* SQLUINTEGER */
	case SQL_ATTR_CONNECTION_DEAD:		/* SQLUINTEGER */
		/* read-only attribute */
	default:
		/* Invalid attribute/option identifier */
		addDbcError(dbc, "HY092", NULL, 0);
		break;
	}

	return SQL_SUCCESS;
}
Example #12
0
SQLRETURN
MNDBEndTran(SQLSMALLINT HandleType,
	    SQLHANDLE Handle,
	    SQLSMALLINT CompletionType)
{
	ODBCEnv *env = NULL;
	ODBCDbc *dbc = NULL;
	SQLHANDLE StatementHandle;
	RETCODE rc;

	/* check parameters HandleType and Handle for validity */
	switch (HandleType) {
	case SQL_HANDLE_DBC:
		dbc = (ODBCDbc *) Handle;
		if (!isValidDbc(dbc))
			return SQL_INVALID_HANDLE;
		clearDbcErrors(dbc);
		if (!dbc->Connected) {
			/* Connection does not exist */
			addDbcError(dbc, "08003", NULL, 0);
			return SQL_ERROR;
		}
		break;
	case SQL_HANDLE_ENV:
		env = (ODBCEnv *) Handle;
		if (!isValidEnv(env))
			return SQL_INVALID_HANDLE;
		clearEnvErrors(env);
		if (env->sql_attr_odbc_version == 0) {
			/* Function sequence error */
			addEnvError(env, "HY010", NULL, 0);
			return SQL_ERROR;
		}
		break;
	case SQL_HANDLE_STMT:
		if (isValidStmt((ODBCStmt *) Handle)) {
			clearStmtErrors((ODBCStmt *) Handle);
			/* Invalid attribute/option identifier */
			addStmtError((ODBCStmt *) Handle, "HY092", NULL, 0);
			return SQL_ERROR;
		}
		return SQL_INVALID_HANDLE;
	case SQL_HANDLE_DESC:
		if (isValidDesc((ODBCDesc *) Handle)) {
			clearDescErrors((ODBCDesc *) Handle);
			/* Invalid attribute/option identifier */
			addDescError((ODBCDesc *) Handle, "HY092", NULL, 0);
			return SQL_ERROR;
		}
		return SQL_INVALID_HANDLE;
	default:
		return SQL_INVALID_HANDLE;
	}

	/* check parameter CompletionType */
	if (CompletionType != SQL_COMMIT && CompletionType != SQL_ROLLBACK) {
		/* Invalid transaction operation code */
		if (HandleType == SQL_HANDLE_DBC)
			addDbcError(dbc, "HY012", NULL, 0);
		else
			addEnvError(env, "HY012", NULL, 0);
		return SQL_ERROR;
	}

	if (HandleType == SQL_HANDLE_ENV) {
		RETCODE rc1 = SQL_SUCCESS;

		for (dbc = env->FirstDbc; dbc; dbc = dbc->next) {
			assert(isValidDbc(dbc));
			if (!dbc->Connected)
				continue;
			rc = MNDBEndTran(SQL_HANDLE_DBC, dbc, CompletionType);
			if (rc == SQL_ERROR)
				rc1 = SQL_ERROR;
			else if (rc == SQL_SUCCESS_WITH_INFO &&
				 rc1 != SQL_ERROR)
				rc1 = rc;
		}
		return rc1;
	}

	assert(HandleType == SQL_HANDLE_DBC);

	if (dbc->sql_attr_autocommit == SQL_AUTOCOMMIT_ON) {
		/* nothing to do if in autocommit mode */
		return SQL_SUCCESS;
	}

	/* construct a statement object and excute a SQL COMMIT or ROLLBACK */
	rc = MNDBAllocStmt(dbc, &StatementHandle);
	if (SQL_SUCCEEDED(rc)) {
		ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
		rc = MNDBExecDirect(stmt,
				    CompletionType == SQL_COMMIT ? (SQLCHAR *) "commit" : (SQLCHAR *) "rollback",
				    SQL_NTS);

		if (rc == SQL_ERROR || rc == SQL_SUCCESS_WITH_INFO) {
			/* get the error/warning and post in on the
			 * dbc handle */
			SQLCHAR sqlState[SQL_SQLSTATE_SIZE + 1];
			SQLINTEGER nativeErrCode;
			SQLCHAR msgText[SQL_MAX_MESSAGE_LENGTH + 1];

			(void) MNDBGetDiagRec(SQL_HANDLE_STMT, stmt, 1,
					      sqlState, &nativeErrCode,
					      msgText, sizeof(msgText), NULL);

			addDbcError(dbc, (char *) sqlState,
				    (char *) msgText + ODBCErrorMsgPrefixLength,
				    nativeErrCode);
		}
		/* clean up the statement handle */
		ODBCResetStmt(stmt);
		ODBCFreeStmt_(stmt);

		for (stmt = dbc->FirstStmt; stmt; stmt = stmt->next)
			ODBCResetStmt(stmt);
	} else {
		/* could not allocate a statement object */
		/* Memory management error */
		addDbcError(dbc, "HY013", NULL, 0);
		return SQL_ERROR;
	}

	return rc;
}