Exemple #1
0
SQLRETURN SQL_API
SQLFetch(SQLHSTMT StatementHandle)
{
	ODBCStmt *stmt = (ODBCStmt *) StatementHandle;

#ifdef ODBCDEBUG
	ODBCLOG("SQLFetch " PTRFMT "\n", PTRFMTCAST StatementHandle);
#endif

	if (!isValidStmt(stmt))
		 return SQL_INVALID_HANDLE;

	clearStmtErrors(stmt);

	assert(stmt->hdl);

	/* check statement cursor state, query should be executed */
	if (stmt->State < EXECUTED0 || stmt->State == EXTENDEDFETCHED) {
		/* Function sequence error */
		addStmtError(stmt, "HY010", NULL, 0);
		return SQL_ERROR;
	}
	if (stmt->State == EXECUTED0) {
		/* Invalid cursor state */
		addStmtError(stmt, "24000", NULL, 0);
		return SQL_ERROR;
	}

	stmt->startRow += stmt->rowSetSize;

	return MNDBFetch(stmt, stmt->ImplRowDescr->sql_desc_array_status_ptr);
}
Exemple #2
0
SQLRETURN
MNDBFetchScroll(ODBCStmt *stmt,
		SQLSMALLINT FetchOrientation,
		SQLLEN FetchOffset,
		SQLUSMALLINT *RowStatusArray)
{
	assert(stmt->hdl);

	if ((stmt->cursorType == SQL_CURSOR_FORWARD_ONLY ||
	     stmt->cursorScrollable == SQL_NONSCROLLABLE) &&
	    FetchOrientation != SQL_FETCH_NEXT) {
		/* Fetch type out of range */
		addStmtError(stmt, "HY106", NULL, 0);
		return SQL_ERROR;
	}
#define RowSetSize	(stmt->ApplRowDescr->sql_desc_array_size)

	assert(stmt->startRow >= 0);
	switch (FetchOrientation) {
	case SQL_FETCH_NEXT:
		stmt->startRow += stmt->rowSetSize;
		break;
	case SQL_FETCH_FIRST:
		stmt->startRow = 0;
		break;
	case SQL_FETCH_LAST:
		if (stmt->rowcount < RowSetSize)
			stmt->startRow = 0;
		else
			stmt->startRow = stmt->rowcount - RowSetSize;
		break;
	case SQL_FETCH_PRIOR:
		if (stmt->startRow == 0) {
			/* before start */
			stmt->startRow = 0;
			stmt->rowSetSize = 0;
			stmt->State = FETCHED;
			return SQL_NO_DATA;
		}
		if (stmt->startRow < (SQLLEN) RowSetSize) {
			/* Attempt to fetch before the result set
			 * returned the first rowset */
			addStmtError(stmt, "01S06", NULL, 0);
			stmt->startRow = 0;
		} else
			stmt->startRow = stmt->startRow - RowSetSize;
		break;
	case SQL_FETCH_RELATIVE:
		if ((stmt->startRow > 0 || stmt->rowSetSize > 0 ||
		     FetchOffset <= 0) &&
		    ((SQLULEN) stmt->startRow < stmt->rowcount ||
		     FetchOffset >= 0)) {
			if ((stmt->startRow == 0 && stmt->rowSetSize == 0 &&
			     FetchOffset <= 0) ||
			    (stmt->startRow == 0 && stmt->rowSetSize > 0 &&
			     FetchOffset < 0) ||
			    (stmt->startRow > 0 &&
			     stmt->startRow + FetchOffset < 1 &&
			     (FetchOffset > (SQLLEN) RowSetSize ||
			      -FetchOffset > (SQLLEN) RowSetSize))) {
				/* before start */
				stmt->startRow = 0;
				stmt->rowSetSize = 0;
				stmt->State = FETCHED;
				return SQL_NO_DATA;
			}
			if (stmt->startRow > 0 &&
			    stmt->startRow + FetchOffset < 1 &&
			    FetchOffset <= (SQLLEN) RowSetSize &&
			    -FetchOffset <= (SQLLEN) RowSetSize) {
				/* Attempt to fetch before the result
				 * set returned the first rowset */
				addStmtError(stmt, "01S06", NULL, 0);
				stmt->startRow = 0;
				break;
			}
			if (stmt->startRow + FetchOffset >= 0 &&
			    stmt->startRow + FetchOffset < (SQLLEN) stmt->rowcount) {
				stmt->startRow += FetchOffset;
				break;
			}
			if (stmt->startRow + FetchOffset >= (SQLLEN) stmt->rowcount ||
			    (stmt->startRow >= (SQLLEN) stmt->rowcount &&
			     FetchOffset >= 0)) {
				/* after end */
				stmt->startRow = stmt->rowcount;
				stmt->rowSetSize = 0;
				stmt->State = FETCHED;
				return SQL_NO_DATA;
			}
			/* all bases should have been covered above */
			assert(0);
		}
		/* fall through */
	case SQL_FETCH_ABSOLUTE:
		if (FetchOffset < 0) {
			if ((unsigned int) -FetchOffset <= stmt->rowcount) {
				stmt->startRow = stmt->rowcount + FetchOffset;
				break;
			}
			stmt->startRow = 0;
			if ((unsigned int) -FetchOffset > RowSetSize) {
				/* before start */
				stmt->State = FETCHED;
				stmt->rowSetSize = 0;
				return SQL_NO_DATA;
			}
			/* Attempt to fetch before the result set
			   returned the first rowset */
			addStmtError(stmt, "01S06", NULL, 0);
			break;
		}
		if (FetchOffset == 0) {
			/* before start */
			stmt->startRow = 0;
			stmt->rowSetSize = 0;
			stmt->State = FETCHED;
			return SQL_NO_DATA;
		}
		if ((SQLULEN) FetchOffset > stmt->rowcount) {
			/* after end */
			stmt->startRow = stmt->rowcount;
			stmt->rowSetSize = 0;
			stmt->State = FETCHED;
			return SQL_NO_DATA;
		}
		stmt->startRow = FetchOffset - 1;
		break;
	case SQL_FETCH_BOOKMARK:
		/* Optional feature not implemented */
		addStmtError(stmt, "HYC00", NULL, 0);
		return SQL_ERROR;
	default:
		/* Fetch type out of range */
		addStmtError(stmt, "HY106", NULL, 0);
		return SQL_ERROR;
	}

	return MNDBFetch(stmt, RowStatusArray);
}