LCOV - code coverage report
Current view: top level - clients/odbc/driver - SQLFetchScroll.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 17 103 16.5 %
Date: 2021-10-13 02:24:04 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : /*
      10             :  * This code was created by Peter Harvey (mostly during Christmas 98/99).
      11             :  * This code is LGPL. Please ensure that this message remains in future
      12             :  * distributions and uses of this code (thats about all I get out of it).
      13             :  * - Peter Harvey pharvey@codebydesign.com
      14             :  *
      15             :  * This file has been modified for the MonetDB project.  See the file
      16             :  * Copyright in this directory for more information.
      17             :  */
      18             : 
      19             : /*****************************************************************************
      20             :  * SQLFetchScroll()
      21             :  * CLI Compliance: ISO 92
      22             :  *
      23             :  * Author: Martin van Dinther, Sjoerd Mullender
      24             :  * Date  : 30 aug 2002
      25             :  *
      26             :  *****************************************************************************/
      27             : 
      28             : #include "ODBCGlobal.h"
      29             : #include "ODBCStmt.h"
      30             : 
      31             : 
      32             : SQLRETURN
      33        1001 : MNDBFetchScroll(ODBCStmt *stmt,
      34             :                 SQLSMALLINT FetchOrientation,
      35             :                 SQLLEN FetchOffset,
      36             :                 SQLUSMALLINT *RowStatusArray)
      37             : {
      38        1001 :         assert(stmt->hdl);
      39             : 
      40        1001 :         if ((stmt->cursorType == SQL_CURSOR_FORWARD_ONLY ||
      41        1001 :              stmt->cursorScrollable == SQL_NONSCROLLABLE) &&
      42             :             FetchOrientation != SQL_FETCH_NEXT) {
      43             :                 /* Fetch type out of range */
      44           0 :                 addStmtError(stmt, "HY106", NULL, 0);
      45           0 :                 return SQL_ERROR;
      46             :         }
      47             : #define RowSetSize      (stmt->ApplRowDescr->sql_desc_array_size)
      48             : 
      49        1001 :         assert(stmt->startRow >= 0);
      50        1001 :         switch (FetchOrientation) {
      51        1001 :         case SQL_FETCH_NEXT:
      52        1001 :                 stmt->startRow += stmt->rowSetSize;
      53        1001 :                 break;
      54           0 :         case SQL_FETCH_FIRST:
      55           0 :                 stmt->startRow = 0;
      56           0 :                 break;
      57           0 :         case SQL_FETCH_LAST:
      58           0 :                 if (stmt->rowcount < RowSetSize)
      59           0 :                         stmt->startRow = 0;
      60             :                 else
      61           0 :                         stmt->startRow = stmt->rowcount - RowSetSize;
      62             :                 break;
      63           0 :         case SQL_FETCH_PRIOR:
      64           0 :                 if (stmt->startRow == 0) {
      65             :                         /* before start */
      66           0 :                         stmt->startRow = 0;
      67           0 :                         stmt->rowSetSize = 0;
      68           0 :                         stmt->State = FETCHED;
      69           0 :                         return SQL_NO_DATA;
      70             :                 }
      71           0 :                 if (stmt->startRow < (SQLLEN) RowSetSize) {
      72             :                         /* Attempt to fetch before the result set
      73             :                          * returned the first rowset */
      74           0 :                         addStmtError(stmt, "01S06", NULL, 0);
      75           0 :                         stmt->startRow = 0;
      76             :                 } else
      77           0 :                         stmt->startRow = stmt->startRow - RowSetSize;
      78             :                 break;
      79           0 :         case SQL_FETCH_RELATIVE:
      80           0 :                 if ((stmt->startRow > 0 || stmt->rowSetSize > 0 ||
      81           0 :                      FetchOffset <= 0) &&
      82           0 :                     ((SQLULEN) stmt->startRow < stmt->rowcount ||
      83             :                      FetchOffset >= 0)) {
      84           0 :                         if ((stmt->startRow == 0 && stmt->rowSetSize == 0 &&
      85           0 :                              FetchOffset <= 0) ||
      86           0 :                             (stmt->startRow == 0 && stmt->rowSetSize > 0 &&
      87           0 :                              FetchOffset < 0) ||
      88           0 :                             (stmt->startRow > 0 &&
      89           0 :                              stmt->startRow + FetchOffset < 1 &&
      90           0 :                              (FetchOffset > (SQLLEN) RowSetSize ||
      91           0 :                               -FetchOffset > (SQLLEN) RowSetSize))) {
      92             :                                 /* before start */
      93           0 :                                 stmt->startRow = 0;
      94           0 :                                 stmt->rowSetSize = 0;
      95           0 :                                 stmt->State = FETCHED;
      96           0 :                                 return SQL_NO_DATA;
      97             :                         }
      98           0 :                         if (stmt->startRow > 0 &&
      99           0 :                             stmt->startRow + FetchOffset < 1 &&
     100           0 :                             FetchOffset <= (SQLLEN) RowSetSize &&
     101           0 :                             -FetchOffset <= (SQLLEN) RowSetSize) {
     102             :                                 /* Attempt to fetch before the result
     103             :                                  * set returned the first rowset */
     104           0 :                                 addStmtError(stmt, "01S06", NULL, 0);
     105           0 :                                 stmt->startRow = 0;
     106           0 :                                 break;
     107             :                         }
     108           0 :                         if (stmt->startRow + FetchOffset >= 0 &&
     109           0 :                             stmt->startRow + FetchOffset < (SQLLEN) stmt->rowcount) {
     110           0 :                                 stmt->startRow += FetchOffset;
     111           0 :                                 break;
     112             :                         }
     113           0 :                         if (stmt->startRow + FetchOffset >= (SQLLEN) stmt->rowcount ||
     114           0 :                             (stmt->startRow >= (SQLLEN) stmt->rowcount &&
     115             :                              FetchOffset >= 0)) {
     116             :                                 /* after end */
     117           0 :                                 stmt->startRow = stmt->rowcount;
     118           0 :                                 stmt->rowSetSize = 0;
     119           0 :                                 stmt->State = FETCHED;
     120           0 :                                 return SQL_NO_DATA;
     121             :                         }
     122             :                         /* all bases should have been covered above */
     123           0 :                         assert(0);
     124             :                 }
     125             :                 /* fall through */
     126             :         case SQL_FETCH_ABSOLUTE:
     127           0 :                 if (FetchOffset < 0) {
     128           0 :                         if ((unsigned int) -FetchOffset <= stmt->rowcount) {
     129           0 :                                 stmt->startRow = stmt->rowcount + FetchOffset;
     130           0 :                                 break;
     131             :                         }
     132           0 :                         stmt->startRow = 0;
     133           0 :                         if ((unsigned int) -FetchOffset > RowSetSize) {
     134             :                                 /* before start */
     135           0 :                                 stmt->State = FETCHED;
     136           0 :                                 stmt->rowSetSize = 0;
     137           0 :                                 return SQL_NO_DATA;
     138             :                         }
     139             :                         /* Attempt to fetch before the result set
     140             :                            returned the first rowset */
     141           0 :                         addStmtError(stmt, "01S06", NULL, 0);
     142           0 :                         break;
     143             :                 }
     144           0 :                 if (FetchOffset == 0) {
     145             :                         /* before start */
     146           0 :                         stmt->startRow = 0;
     147           0 :                         stmt->rowSetSize = 0;
     148           0 :                         stmt->State = FETCHED;
     149           0 :                         return SQL_NO_DATA;
     150             :                 }
     151           0 :                 if ((SQLULEN) FetchOffset > stmt->rowcount) {
     152             :                         /* after end */
     153           0 :                         stmt->startRow = stmt->rowcount;
     154           0 :                         stmt->rowSetSize = 0;
     155           0 :                         stmt->State = FETCHED;
     156           0 :                         return SQL_NO_DATA;
     157             :                 }
     158           0 :                 stmt->startRow = FetchOffset - 1;
     159           0 :                 break;
     160           0 :         case SQL_FETCH_BOOKMARK:
     161             :                 /* Optional feature not implemented */
     162           0 :                 addStmtError(stmt, "HYC00", NULL, 0);
     163           0 :                 return SQL_ERROR;
     164           0 :         default:
     165             :                 /* Fetch type out of range */
     166           0 :                 addStmtError(stmt, "HY106", NULL, 0);
     167           0 :                 return SQL_ERROR;
     168             :         }
     169             : 
     170        1001 :         return MNDBFetch(stmt, RowStatusArray);
     171             : }
     172             : 
     173             : SQLRETURN SQL_API
     174             : SQLFetchScroll(SQLHSTMT StatementHandle,
     175             :                SQLSMALLINT FetchOrientation,
     176             :                SQLLEN FetchOffset)
     177             : {
     178             :         ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
     179             : 
     180             : #ifdef ODBCDEBUG
     181        1001 :         ODBCLOG("SQLFetchScroll %p %s " LENFMT "\n",
     182             :                 StatementHandle,
     183             :                 translateFetchOrientation(FetchOrientation),
     184             :                 LENCAST FetchOffset);
     185             : #endif
     186             : 
     187        1001 :         if (!isValidStmt(stmt))
     188             :                  return SQL_INVALID_HANDLE;
     189             : 
     190        1001 :         clearStmtErrors(stmt);
     191             : 
     192             :         /* check statement cursor state, query should be executed */
     193        1001 :         if (stmt->State < EXECUTED0 || stmt->State == EXTENDEDFETCHED) {
     194             :                 /* Function sequence error */
     195           0 :                 addStmtError(stmt, "HY010", NULL, 0);
     196           0 :                 return SQL_ERROR;
     197             :         }
     198        1001 :         if (stmt->State == EXECUTED0) {
     199             :                 /* Invalid cursor state */
     200           0 :                 addStmtError(stmt, "24000", NULL, 0);
     201           0 :                 return SQL_ERROR;
     202             :         }
     203             : 
     204        1001 :         return MNDBFetchScroll(stmt, FetchOrientation, FetchOffset,
     205        1001 :                                stmt->ImplRowDescr->sql_desc_array_status_ptr);
     206             : }

Generated by: LCOV version 1.14