示例#1
0
SQLRETURN
SQLFreeStmt_(ODBCStmt *stmt,
	     SQLUSMALLINT Option)
{
	switch (Option) {
	case SQL_CLOSE:
		/* Note: this option is also called from SQLCancel()
		 * and SQLCloseCursor(), so be careful when changing
		 * the code */
		/* close cursor, discard result set, set to prepared */
		setODBCDescRecCount(stmt->ImplRowDescr, 0);
		stmt->currentRow = 0;
		stmt->startRow = 0;
		stmt->rowSetSize = 0;

		if (stmt->State == EXECUTED0)
			stmt->State = stmt->queryid >= 0 ? PREPARED0 : INITED;
		else if (stmt->State >= EXECUTED1)
			stmt->State = stmt->queryid >= 0 ? PREPARED1 : INITED;

		/* Important: do not destroy the bind parameters and columns! */
		return SQL_SUCCESS;
	case SQL_DROP:
		return ODBCFreeStmt_(stmt);
	case SQL_UNBIND:
		setODBCDescRecCount(stmt->ApplRowDescr, 0);
		return SQL_SUCCESS;
	case SQL_RESET_PARAMS:
		setODBCDescRecCount(stmt->ApplParamDescr, 0);
		setODBCDescRecCount(stmt->ImplParamDescr, 0);
		mapi_clear_params(stmt->hdl);
		return SQL_SUCCESS;
	default:
		/* Invalid attribute/option identifier */
		addStmtError(stmt, "HY092", NULL, 0);
		return SQL_ERROR;
	}

	/* not reached */
}
示例#2
0
SQLRETURN SQL_API
SQLBindCol(SQLHSTMT StatementHandle,
	   SQLUSMALLINT ColumnNumber,
	   SQLSMALLINT TargetType,
	   SQLPOINTER TargetValuePtr,
	   SQLLEN BufferLength,
	   SQLLEN *StrLen_or_Ind)
{
	ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
	ODBCDesc *desc;		/* Application Row Descriptor */

#ifdef ODBCDEBUG
	ODBCLOG("SQLBindCol " PTRFMT " %u %s " LENFMT "\n",
		PTRFMTCAST StatementHandle, (unsigned int) ColumnNumber,
		translateCType(TargetType), LENCAST BufferLength);
#endif

	if (!isValidStmt(stmt))
		 return SQL_INVALID_HANDLE;

	assert(stmt->Dbc);

	clearStmtErrors(stmt);

	/* check input parameters */
	/* column number 0 (Bookmark column) is not supported */
	if (ColumnNumber == 0) {
		if (TargetType == SQL_C_BOOKMARK || TargetType == SQL_C_VARBOOKMARK) {
			/* Optional feature not implemented */
			addStmtError(stmt, "HYC00", NULL, 0);
		} else {
			/* Restricted data type attribute violation */
			addStmtError(stmt, "07006", NULL, 0);
		}
		return SQL_ERROR;
	}
	if (stmt->State >= EXECUTED1 && ColumnNumber > stmt->ImplRowDescr->sql_desc_count) {
		/* Invalid descriptor index */
		addStmtError(stmt, "07009", NULL, 0);
		return SQL_ERROR;
	}

	/* For safety: limit the maximum number of columns to bind */
	if (ColumnNumber > MONETDB_MAX_BIND_COLS) {
		/* General error */
		addStmtError(stmt, "HY000", "Maximum number of bind columns (8192) exceeded", 0);
		return SQL_ERROR;
	}

	/* can't let SQLSetDescField below do this check since it
	   returns the wrong error code if the type is incorrect */
	switch (TargetType) {
	case SQL_C_CHAR:
	case SQL_C_WCHAR:
	case SQL_C_BINARY:
	case SQL_C_BIT:
	case SQL_C_STINYINT:
	case SQL_C_UTINYINT:
	case SQL_C_TINYINT:
	case SQL_C_SSHORT:
	case SQL_C_USHORT:
	case SQL_C_SHORT:
	case SQL_C_SLONG:
	case SQL_C_ULONG:
	case SQL_C_LONG:
	case SQL_C_SBIGINT:
	case SQL_C_UBIGINT:
	case SQL_C_NUMERIC:
	case SQL_C_FLOAT:
	case SQL_C_DOUBLE:
	case SQL_C_TYPE_DATE:
	case SQL_C_TYPE_TIME:
	case SQL_C_TYPE_TIMESTAMP:
	case SQL_C_INTERVAL_YEAR:
	case SQL_C_INTERVAL_MONTH:
	case SQL_C_INTERVAL_YEAR_TO_MONTH:
	case SQL_C_INTERVAL_DAY:
	case SQL_C_INTERVAL_HOUR:
	case SQL_C_INTERVAL_MINUTE:
	case SQL_C_INTERVAL_SECOND:
	case SQL_C_INTERVAL_DAY_TO_HOUR:
	case SQL_C_INTERVAL_DAY_TO_MINUTE:
	case SQL_C_INTERVAL_DAY_TO_SECOND:
	case SQL_C_INTERVAL_HOUR_TO_MINUTE:
	case SQL_C_INTERVAL_HOUR_TO_SECOND:
	case SQL_C_INTERVAL_MINUTE_TO_SECOND:
	case SQL_C_GUID:
	case SQL_C_DEFAULT:
		break;
	default:
		/* Invalid application buffer type */
		addStmtError(stmt, "HY003", NULL, 0);
		return SQL_ERROR;
	}

	if (BufferLength < 0) {
		/* Invalid string or buffer length */
		addStmtError(stmt, "HY090", NULL, 0);
		return SQL_ERROR;
	}

	desc = stmt->ApplRowDescr;

	if (TargetValuePtr == NULL && ColumnNumber == desc->sql_desc_count) {
		int i = desc->sql_desc_count - 1;

		while (i > 0 && desc->descRec[i].sql_desc_data_ptr == NULL)
			i--;
		setODBCDescRecCount(desc, i);
	} else {
		ODBCDescRec *rec;
		SQLRETURN rc;

		if (ColumnNumber > desc->sql_desc_count)
			setODBCDescRecCount(desc, ColumnNumber);
		rc = SQLSetDescField_(desc, ColumnNumber, SQL_DESC_CONCISE_TYPE, (SQLPOINTER) (ssize_t) TargetType, 0);
		if (!SQL_SUCCEEDED(rc))
			return rc;
		rec = &desc->descRec[ColumnNumber];
		rec->sql_desc_octet_length = BufferLength;
		rec->sql_desc_data_ptr = TargetValuePtr;
		rec->sql_desc_indicator_ptr = StrLen_or_Ind;
		rec->sql_desc_octet_length_ptr = StrLen_or_Ind;
	}

	return SQL_SUCCESS;
}
示例#3
0
SQLRETURN
MNDBSetDescField(ODBCDesc *desc,
		 SQLSMALLINT RecNumber,
		 SQLSMALLINT FieldIdentifier,
		 SQLPOINTER ValuePtr,
		 SQLINTEGER BufferLength)
{
	ODBCDescRec *rec;
	struct sql_types *tp;

	if (isAD(desc))
		tp = ODBC_c_types;
	else
		tp = ODBC_sql_types;

	switch (FieldIdentifier) {
	case SQL_DESC_ALLOC_TYPE:		/* SQLSMALLINT */
		/* Invalid descriptor field identifier */
		addDescError(desc, "HY091", NULL, 0);
		return SQL_ERROR;
	case SQL_DESC_ARRAY_SIZE:		/* SQLULEN */
		if ((SQLULEN) (uintptr_t) ValuePtr == 0) {
			/* Invalid attribute/option identifier */
			addDescError(desc, "HY092", NULL, 0);
			return SQL_ERROR;
		}
		if (isAD(desc)) {
			/* limit size to protect against bugs */
			if ((SQLULEN) (uintptr_t) ValuePtr > 10000) {
				/* Driver does not support this function */
				addDescError(desc, "IM001", NULL, 0);
				return SQL_ERROR;
			}
			desc->sql_desc_array_size = (SQLULEN) (uintptr_t) ValuePtr;
		}
		return SQL_SUCCESS;
	case SQL_DESC_ARRAY_STATUS_PTR:		/* SQLUSMALLINT * */
		desc->sql_desc_array_status_ptr = (SQLUSMALLINT *) ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_BIND_OFFSET_PTR:		/* SQLLEN * */
		if (isAD(desc))
			desc->sql_desc_bind_offset_ptr = (SQLLEN *) ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_BIND_TYPE:		/* SQLINTEGER */
		if (isAD(desc))
			desc->sql_desc_bind_type = (SQLINTEGER) (intptr_t) ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_COUNT:			/* SQLSMALLINT */
		if (isIRD(desc)) {
			/* Invalid descriptor field identifier */
			addDescError(desc, "HY091", NULL, 0);
			return SQL_ERROR;
		}
		setODBCDescRecCount(desc, (int) (SQLSMALLINT) (intptr_t) ValuePtr);
		return SQL_SUCCESS;
	case SQL_DESC_ROWS_PROCESSED_PTR:	/* SQLULEN * */
		if (desc->Stmt)
			desc->sql_desc_rows_processed_ptr = (SQLULEN *) ValuePtr;
		return SQL_SUCCESS;
	}

	if (RecNumber <= 0) {
		/* Invalid descriptor index */
		addDescError(desc, "07009", NULL, 0);
		return SQL_ERROR;
	}
	if (RecNumber > desc->sql_desc_count)
		return SQL_NO_DATA;

	if (isIRD(desc)) {
		/* the Implementation Row Descriptor is read-only */
		/* Invalid descriptor field identifier */
		addDescError(desc, "HY091", NULL, 0);
		return SQL_ERROR;
	}

	rec = &desc->descRec[RecNumber];

	/* break for read-only fields since the error is the same as
	   unknown FieldIdentifier */
	switch (FieldIdentifier) {
	case SQL_DESC_AUTO_UNIQUE_VALUE:	/* SQLINTEGER */
	case SQL_DESC_BASE_COLUMN_NAME:		/* SQLCHAR * */
	case SQL_DESC_BASE_TABLE_NAME:		/* SQLCHAR * */
	case SQL_DESC_CASE_SENSITIVE:		/* SQLINTEGER */
	case SQL_DESC_CATALOG_NAME:		/* SQLCHAR * */
	case SQL_DESC_DISPLAY_SIZE:		/* SQLLEN */
	case SQL_DESC_FIXED_PREC_SCALE:		/* SQLSMALLINT */
	case SQL_DESC_LABEL:			/* SQLCHAR * */
	case SQL_DESC_LITERAL_PREFIX:		/* SQLCHAR * */
	case SQL_DESC_LITERAL_SUFFIX:		/* SQLCHAR * */
	case SQL_DESC_LOCAL_TYPE_NAME:		/* SQLCHAR * */
	case SQL_DESC_NULLABLE:			/* SQLSMALLINT */
	case SQL_DESC_ROWVER:			/* SQLSMALLINT */
	case SQL_DESC_SCHEMA_NAME:		/* SQLCHAR * */
	case SQL_DESC_SEARCHABLE:		/* SQLSMALLINT */
	case SQL_DESC_TABLE_NAME:		/* SQLCHAR * */
	case SQL_DESC_TYPE_NAME:		/* SQLCHAR * */
	case SQL_DESC_UNSIGNED:			/* SQLSMALLINT */
	case SQL_DESC_UPDATABLE:		/* SQLSMALLINT */
		break;		/* read-only or unused */
	case SQL_DESC_CONCISE_TYPE:		/* SQLSMALLINT */
		while (tp->concise_type != 0) {
			if ((intptr_t) tp->concise_type == (intptr_t) ValuePtr) {
				rec->sql_desc_concise_type = tp->concise_type;
				rec->sql_desc_type = tp->type;
				rec->sql_desc_datetime_interval_code = tp->code;
				if (tp->precision != UNAFFECTED)
					rec->sql_desc_precision = tp->precision;
				if (tp->datetime_interval_precision != UNAFFECTED)
					rec->sql_desc_datetime_interval_precision = tp->datetime_interval_precision;
				if (tp->length != UNAFFECTED)
					rec->sql_desc_length = tp->length;
				if (tp->scale != UNAFFECTED)
					rec->sql_desc_scale = tp->scale;
				rec->sql_desc_fixed_prec_scale = tp->fixed;
				rec->sql_desc_num_prec_radix = tp->radix;
				return SQL_SUCCESS;
			}
			tp++;
		}
		/* Invalid attribute/option identifier */
		addDescError(desc, "HY092", NULL, 0);
		return SQL_ERROR;
	case SQL_DESC_DATA_PTR:			/* SQLPOINTER */
		/* TODO: consistency check */
		rec->sql_desc_data_ptr = ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_DATETIME_INTERVAL_CODE:	/* SQLSMALLINT */
		while (tp->concise_type != 0) {
			if ((intptr_t) tp->code == (intptr_t) ValuePtr &&
			    tp->type == rec->sql_desc_type) {
				rec->sql_desc_concise_type = tp->concise_type;
				rec->sql_desc_type = tp->type;
				rec->sql_desc_datetime_interval_code = tp->code;
				if (tp->precision != UNAFFECTED)
					rec->sql_desc_precision = tp->precision;
				if (tp->datetime_interval_precision != UNAFFECTED)
					rec->sql_desc_datetime_interval_precision = tp->datetime_interval_precision;
				if (tp->length != UNAFFECTED)
					rec->sql_desc_length = tp->length;
				if (tp->scale != UNAFFECTED)
					rec->sql_desc_scale = tp->scale;
				rec->sql_desc_fixed_prec_scale = tp->fixed;
				rec->sql_desc_num_prec_radix = tp->radix;
				return SQL_SUCCESS;
			}
			tp++;
		}
		/* Inconsistent descriptor information */
		addDescError(desc, "HY021", NULL, 0);
		return SQL_ERROR;
	case SQL_DESC_DATETIME_INTERVAL_PRECISION: /* SQLINTEGER */
		rec->sql_desc_datetime_interval_precision = (SQLINTEGER) (intptr_t) ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_INDICATOR_PTR:		/* SQLLEN * */
		if (isAD(desc))
			rec->sql_desc_indicator_ptr = (SQLLEN *) ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_LENGTH:			/* SQLULEN */
		rec->sql_desc_length = (SQLULEN) (uintptr_t) ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_NAME:			/* SQLCHAR * */
		if (isID(desc)) {
			fixODBCstring(ValuePtr, BufferLength, SQLINTEGER,
				      addDescError, desc, return SQL_ERROR);
			if (rec->sql_desc_name != NULL)
				free(rec->sql_desc_name);
			rec->sql_desc_name = (SQLCHAR *) dupODBCstring((SQLCHAR *) ValuePtr, (size_t) BufferLength);
			if (rec->sql_desc_name == NULL) {
				/* Memory allocation error */
				addDescError(desc, "HY001", NULL, 0);
				return SQL_ERROR;
			}
			rec->sql_desc_unnamed = *rec->sql_desc_name ? SQL_NAMED : SQL_UNNAMED;
		}
		return SQL_SUCCESS;
	case SQL_DESC_NUM_PREC_RADIX:
		rec->sql_desc_num_prec_radix = (SQLINTEGER) (intptr_t) ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_OCTET_LENGTH:		/* SQLLEN */
		rec->sql_desc_octet_length = (SQLLEN) (intptr_t) ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_OCTET_LENGTH_PTR:		/* SQLLEN * */
		if (isAD(desc))
			rec->sql_desc_octet_length_ptr = (SQLLEN *) ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_PARAMETER_TYPE:		/* SQLSMALLINT */
		switch ((SQLSMALLINT) (intptr_t) ValuePtr) {
		case SQL_PARAM_INPUT:
			break;
		case SQL_PARAM_INPUT_OUTPUT:
		case SQL_PARAM_OUTPUT:
			/* Driver does not support this function */
			addDescError(desc, "IM001", NULL, 0);
			return SQL_ERROR;
		default:
			/* Invalid attribute/option identifier */
			addDescError(desc, "HY092", NULL, 0);
			return SQL_ERROR;
		}
		if (isIPD(desc))
			rec->sql_desc_parameter_type = (SQLSMALLINT) (intptr_t) ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_PRECISION:		/* SQLSMALLINT */
		rec->sql_desc_precision = (SQLSMALLINT) (intptr_t) ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_SCALE:			/* SQLSMALLINT */
		rec->sql_desc_scale = (SQLSMALLINT) (intptr_t) ValuePtr;
		return SQL_SUCCESS;
	case SQL_DESC_TYPE:			/* SQLSMALLINT */
		while (tp->concise_type != 0) {
			if ((SQLSMALLINT) (intptr_t) ValuePtr == tp->type &&
			    (((SQLSMALLINT) (intptr_t) ValuePtr != SQL_DATETIME &&
			      (SQLSMALLINT) (intptr_t) ValuePtr != SQL_INTERVAL) ||
			     tp->code == rec->sql_desc_datetime_interval_code)) {
				rec->sql_desc_concise_type = tp->concise_type;
				rec->sql_desc_type = tp->type;
				rec->sql_desc_datetime_interval_code = tp->code;
				if (tp->precision != UNAFFECTED)
					rec->sql_desc_precision = tp->precision;
				if (tp->datetime_interval_precision != UNAFFECTED)
					rec->sql_desc_datetime_interval_precision = tp->datetime_interval_precision;
				if (tp->length != UNAFFECTED)
					rec->sql_desc_length = tp->length;
				if (tp->scale != UNAFFECTED)
					rec->sql_desc_scale = tp->scale;
				rec->sql_desc_fixed_prec_scale = tp->fixed;
				rec->sql_desc_num_prec_radix = tp->radix;
				return SQL_SUCCESS;
			}
			tp++;
		}
		/* Inconsistent descriptor information */
		addDescError(desc, "HY021", NULL, 0);
		return SQL_ERROR;
	case SQL_DESC_UNNAMED:			/* SQLSMALLINT */
		if ((SQLSMALLINT) (intptr_t) ValuePtr == SQL_NAMED) {
			/* Invalid descriptor field identifier */
			addDescError(desc, "HY091", NULL, 0);
			return SQL_ERROR;
		} else if ((SQLSMALLINT) (intptr_t) ValuePtr == SQL_UNNAMED && isIPD(desc)) {
			rec->sql_desc_unnamed = SQL_UNNAMED;
			if (rec->sql_desc_name)
				free(rec->sql_desc_name);
			rec->sql_desc_name = NULL;
			return SQL_SUCCESS;
		}
		/* Inconsistent descriptor information */
		addDescError(desc, "HY021", NULL, 0);
		return SQL_ERROR;
	}

	/* Invalid descriptor field identifier */
	addDescError(desc, "HY091", NULL, 0);
	return SQL_ERROR;
}