Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : /*
14 : * This code was created by Peter Harvey (mostly during Christmas 98/99).
15 : * This code is LGPL. Please ensure that this message remains in future
16 : * distributions and uses of this code (that's about all I get out of it).
17 : * - Peter Harvey pharvey@codebydesign.com
18 : *
19 : * This file has been modified for the MonetDB project. See the file
20 : * Copyright in this directory for more information.
21 : */
22 :
23 : /**********************************************************************
24 : * SQLFetch()
25 : * CLI Compliance: ISO 92
26 : *
27 : * Author: Martin van Dinther, Sjoerd Mullender
28 : * Date : 30 aug 2002
29 : *
30 : **********************************************************************/
31 :
32 : #include "ODBCGlobal.h"
33 : #include "ODBCStmt.h"
34 : #include "ODBCUtil.h"
35 :
36 : SQLRETURN
37 2659 : MNDBFetch(ODBCStmt *stmt, SQLUSMALLINT *RowStatusArray)
38 : {
39 2659 : ODBCDesc *ard, *ird;
40 2659 : ODBCDescRec *rec;
41 2659 : int i;
42 2659 : SQLULEN row;
43 2659 : SQLLEN offset;
44 2659 : long timeout;
45 :
46 : /* stmt->startRow is the (0 based) index of the first row we
47 : * stmt->need to fetch */
48 :
49 2659 : ard = stmt->ApplRowDescr;
50 2659 : ird = stmt->ImplRowDescr;
51 :
52 2659 : stmt->retrieved = 0;
53 2659 : stmt->currentCol = 0;
54 :
55 2659 : stmt->rowSetSize = 0;
56 2659 : stmt->currentRow = stmt->startRow + 1;
57 2659 : if (mapi_seek_row(stmt->hdl, stmt->startRow, MAPI_SEEK_SET) != MOK) {
58 : /* Row value out of range */
59 0 : addStmtError(stmt, "HY107", mapi_error_str(stmt->Dbc->mid), 0);
60 0 : return SQL_ERROR;
61 : }
62 :
63 2659 : stmt->State = FETCHED;
64 :
65 2659 : if (stmt->retrieveData == SQL_RD_OFF) {
66 : /* don't really retrieve the data, just do as if,
67 : updating the SQL_DESC_ARRAY_STATUS_PTR */
68 0 : stmt->rowSetSize = ard->sql_desc_array_size;
69 :
70 0 : if (stmt->startRow + stmt->rowSetSize > (SQLLEN) stmt->rowcount)
71 0 : stmt->rowSetSize = stmt->rowcount - stmt->startRow;
72 :
73 0 : if (stmt->rowSetSize <= 0) {
74 0 : stmt->rowSetSize = 0;
75 0 : return SQL_NO_DATA;
76 : }
77 0 : if (RowStatusArray) {
78 0 : for (row = 0; (SQLLEN) row < stmt->rowSetSize; row++) {
79 0 : WriteValue(RowStatusArray, SQL_ROW_SUCCESS);
80 0 : RowStatusArray++;
81 : }
82 0 : for (; row < ard->sql_desc_array_size; row++) {
83 0 : WriteValue(RowStatusArray, SQL_ROW_NOROW);
84 0 : RowStatusArray++;
85 : }
86 : }
87 0 : return SQL_SUCCESS;
88 : }
89 :
90 2659 : if (ard->sql_desc_bind_offset_ptr)
91 0 : offset = *ard->sql_desc_bind_offset_ptr;
92 : else
93 : offset = 0;
94 5228 : for (row = 0; row < ard->sql_desc_array_size; row++) {
95 2659 : if (mapi_fetch_row(stmt->hdl) == 0) {
96 90 : switch (mapi_error(stmt->Dbc->mid)) {
97 90 : case MOK:
98 90 : if (row == 0)
99 : return SQL_NO_DATA;
100 : break;
101 0 : case MTIMEOUT:
102 0 : if (RowStatusArray)
103 0 : WriteValue(RowStatusArray, SQL_ROW_ERROR);
104 : /* Connection timeout expired / Communication link failure */
105 0 : timeout = msetting_long(stmt->Dbc->settings, MP_REPLY_TIMEOUT);
106 0 : addStmtError(stmt, timeout > 0 ? "HYT01" : "08S01", mapi_error_str(stmt->Dbc->mid), 0);
107 0 : return SQL_ERROR;
108 0 : default:
109 0 : if (RowStatusArray)
110 0 : WriteValue(RowStatusArray, SQL_ROW_ERROR);
111 : /* General error */
112 0 : addStmtError(stmt, "HY000", mapi_error_str(stmt->Dbc->mid), 0);
113 0 : return SQL_ERROR;
114 : }
115 : break;
116 : }
117 2569 : if (RowStatusArray)
118 0 : WriteValue(RowStatusArray, SQL_ROW_SUCCESS);
119 :
120 2569 : stmt->rowSetSize++;
121 :
122 19162 : for (i = 1; i <= ird->sql_desc_count; i++)
123 16593 : ird->descRec[i].already_returned = -1;
124 :
125 12654 : for (i = 1; i <= ard->sql_desc_count; i++) {
126 10085 : rec = &ard->descRec[i];
127 10085 : if (rec->sql_desc_data_ptr == NULL)
128 75 : continue;
129 10010 : stmt->retrieved = 0;
130 10010 : if (ODBCFetch(stmt, i,
131 10010 : rec->sql_desc_concise_type,
132 : rec->sql_desc_data_ptr,
133 : rec->sql_desc_octet_length,
134 : rec->sql_desc_octet_length_ptr,
135 : rec->sql_desc_indicator_ptr,
136 10010 : rec->sql_desc_precision,
137 10010 : rec->sql_desc_scale,
138 : rec->sql_desc_datetime_interval_precision,
139 : offset, row) == SQL_ERROR) {
140 0 : if (RowStatusArray)
141 10085 : WriteValue(RowStatusArray, SQL_ROW_SUCCESS_WITH_INFO);
142 : }
143 : }
144 2569 : if (RowStatusArray)
145 0 : RowStatusArray++;
146 : }
147 2569 : if (ird->sql_desc_rows_processed_ptr)
148 0 : *ird->sql_desc_rows_processed_ptr = (SQLULEN) stmt->rowSetSize;
149 :
150 2569 : if (RowStatusArray)
151 0 : while (row++ < ard->sql_desc_array_size) {
152 0 : WriteValue(RowStatusArray, SQL_ROW_NOROW);
153 0 : RowStatusArray++;
154 : }
155 :
156 2569 : return stmt->Error ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
157 : }
158 :
159 : SQLRETURN SQL_API
160 : SQLFetch(SQLHSTMT StatementHandle)
161 : {
162 1658 : ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
163 :
164 : #ifdef ODBCDEBUG
165 1658 : ODBCLOG("SQLFetch %p\n", StatementHandle);
166 : #endif
167 :
168 1658 : if (!isValidStmt(stmt))
169 : return SQL_INVALID_HANDLE;
170 :
171 1658 : clearStmtErrors(stmt);
172 :
173 1658 : assert(stmt->hdl);
174 :
175 : /* check statement cursor state, query should be executed */
176 1658 : if (stmt->State < EXECUTED0 || stmt->State == EXTENDEDFETCHED) {
177 : /* Function sequence error */
178 0 : addStmtError(stmt, "HY010", NULL, 0);
179 0 : return SQL_ERROR;
180 : }
181 1658 : if (stmt->State == EXECUTED0) {
182 : /* Invalid cursor state */
183 0 : addStmtError(stmt, "24000", NULL, 0);
184 0 : return SQL_ERROR;
185 : }
186 :
187 1658 : stmt->startRow += stmt->rowSetSize;
188 :
189 1658 : return MNDBFetch(stmt, stmt->ImplRowDescr->sql_desc_array_status_ptr);
190 : }
|