@@ -132,6 +132,53 @@ SQLSMALLINT copy_current_catalog(esodbc_dbc_st *dbc, SQLWCHAR *dest,
132
132
return used ;
133
133
}
134
134
135
+ /*
136
+ * Quote the tokens in a string: "a, b,,c" -> "'a','b',,'c'".
137
+ * No string sanity done (garbage in, garbage out).
138
+ */
139
+ size_t quote_tokens (SQLWCHAR * src , size_t len , SQLWCHAR * dest )
140
+ {
141
+ size_t i ;
142
+ BOOL copying ;
143
+ SQLWCHAR * pos ;
144
+
145
+ DBG ("len=%d." , len );
146
+ copying = FALSE;
147
+ pos = dest ;
148
+ for (i = 0 ; i < len ; i ++ ) {
149
+ DBG ("src[%d]=%C, dest:`" LWPD "`." , i , src [i ], dest );
150
+ switch (src [i ]) {
151
+ /* ignore white space */
152
+ case L' ' :
153
+ case L'\t' :
154
+ TRACE ;
155
+ if (copying ) {
156
+ * pos ++ = L'\'' ; /* end current token */
157
+ copying = FALSE;
158
+ }
159
+ continue ; /* don't copy WS */
160
+
161
+ case L',' :
162
+ TRACE ;
163
+ if (copying ) {
164
+ * pos ++ = L'\'' ; /* end current token */
165
+ copying = FALSE;
166
+ } /* else continue; -- to remove extra `,` */
167
+ break ;
168
+
169
+ default :
170
+ TRACE ;
171
+ if (! copying ) {
172
+ * pos ++ = L'\'' ; /* start a new token */
173
+ }
174
+ copying = TRUE;
175
+ }
176
+ * pos ++ = src [i ];
177
+ }
178
+ /* should not overrun */
179
+ assert (i < 2 /*see typ_buf below*/ * ESODBC_MAX_IDENTIFIER_LEN );
180
+ return pos - dest ;
181
+ }
135
182
136
183
SQLRETURN EsSQLTablesW (
137
184
SQLHSTMT StatementHandle ,
@@ -146,29 +193,47 @@ SQLRETURN EsSQLTablesW(
146
193
{
147
194
esodbc_stmt_st * stmt = STMH (StatementHandle );
148
195
SQLRETURN ret ;
149
- SQLWCHAR wbuf [sizeof (SQL_TABLES ) + 2 * ESODBC_MAX_IDENTIFIER_LEN ];
150
- SQLWCHAR * table , * schema , * catalog ;
151
- size_t cnt_tab , cnt_sch , cnt_cat , pos ;
196
+ /* b/c declaring an array with a const doesn't work with MSVC's compiler */
197
+ enum wbuf_len { wbuf_len = sizeof (SQL_TABLES )
198
+ + sizeof (SQL_TABLES_CAT )
199
+ + sizeof (SQL_TABLES_TAB )
200
+ + sizeof (SQL_TABLES_TYP )
201
+ + 3 * ESODBC_MAX_IDENTIFIER_LEN /* it has 4x 0-term space */
202
+ };
203
+ SQLWCHAR wbuf [wbuf_len ];
204
+ SQLWCHAR * table , * schema , * catalog , * type ;
205
+ size_t cnt_tab , cnt_sch , cnt_cat , cnt_typ , pos ;
206
+ /* 2x: "a,b,c" -> "'a','b','c'" : each "x," => "'x'," */
207
+ SQLWCHAR typ_buf [2 * ESODBC_MAX_IDENTIFIER_LEN ];
152
208
153
209
if (stmt -> metadata_id == SQL_TRUE )
154
210
FIXME ; // FIXME
155
211
212
+ pos = sizeof (SQL_TABLES ) - 1 ;
213
+ wmemcpy (wbuf , MK_WPTR (SQL_TABLES ), pos );
214
+
156
215
if (CatalogName ) {
157
216
catalog = CatalogName ;
158
217
if (NameLength1 == SQL_NTS ) {
159
218
cnt_cat = wcslen (catalog );
160
219
if (ESODBC_MAX_IDENTIFIER_LEN < cnt_cat ) {
161
220
ERRH (stmt , "catalog identifier name '" LTPDL "' too long "
162
- "(%d . max=%d)." , cnt_cat , catalog , cnt_cat ,
221
+ "(%zd . max=%d)." , ( int ) cnt_cat , catalog , cnt_cat ,
163
222
ESODBC_MAX_IDENTIFIER_LEN );
164
223
RET_HDIAG (stmt , SQL_STATE_HY090 , "catalog name too long" , 0 );
165
224
}
166
225
} else {
167
226
cnt_cat = NameLength1 ;
168
227
}
169
- } else {
170
- catalog = MK_WPTR (SQL_ALL_CATALOGS );
171
- cnt_cat = sizeof (SQL_ALL_CATALOGS ) - /*0-term*/ 1 ;
228
+
229
+ cnt_cat = swprintf (wbuf + pos , wbuf_len - pos , SQL_TABLES_CAT ,
230
+ (int )cnt_cat , catalog );
231
+ if (cnt_cat <= 0 ) {
232
+ ERRH (stmt , "failed to print 'catalog' for tables catalog SQL." );
233
+ RET_HDIAGS (stmt , SQL_STATE_HY000 );
234
+ } else {
235
+ pos += cnt_cat ;
236
+ }
172
237
}
173
238
174
239
if (SchemaName ) {
@@ -177,23 +242,20 @@ SQLRETURN EsSQLTablesW(
177
242
cnt_sch = wcslen (schema );
178
243
if (ESODBC_MAX_IDENTIFIER_LEN < cnt_sch ) {
179
244
ERRH (stmt , "schema identifier name '" LTPDL "' too long "
180
- "(%d . max=%d)." , cnt_sch , schema , cnt_sch ,
245
+ "(%zd . max=%d)." , ( int ) cnt_sch , schema , cnt_sch ,
181
246
ESODBC_MAX_IDENTIFIER_LEN );
182
247
RET_HDIAG (stmt , SQL_STATE_HY090 , "schema name too long" , 0 );
183
248
}
184
249
} else {
185
250
cnt_sch = NameLength2 ;
186
251
}
187
- } else {
188
- schema = MK_WPTR (SQL_ALL_SCHEMAS );
189
- cnt_sch = sizeof (SQL_ALL_SCHEMAS ) - /*0-term*/ 1 ;
190
- }
191
252
192
- /* TODO: server support needed for sch. name filtering */
193
- if (cnt_sch && wszmemcmp (schema , MK_WPTR (SQL_ALL_SCHEMAS ),
194
- (long )cnt_sch )) {
195
- ERRH (stmt , "filtering by schemas is not supported." );
196
- RET_HDIAG (stmt , SQL_STATE_IM001 , "schema filtering not supported" , 0 );
253
+ /* TODO: server support needed for sch. name filtering */
254
+ if (wszmemcmp (schema , MK_WPTR (SQL_ALL_SCHEMAS ), (long )cnt_sch )) {
255
+ ERRH (stmt , "filtering by schemas is not supported." );
256
+ RET_HDIAG (stmt , SQL_STATE_IM001 , "schema filtering not supported" ,
257
+ 0 );
258
+ }
197
259
}
198
260
199
261
// FIXME: string needs escaping of % \\ _
@@ -203,31 +265,58 @@ SQLRETURN EsSQLTablesW(
203
265
cnt_tab = wcslen (table );
204
266
if (ESODBC_MAX_IDENTIFIER_LEN < cnt_tab ) {
205
267
ERRH (stmt , "table identifier name '" LTPDL "' too long "
206
- "(%d . max=%d)." , cnt_tab , table , cnt_tab ,
268
+ "(%zd . max=%d)." , ( int ) cnt_tab , table , cnt_tab ,
207
269
ESODBC_MAX_IDENTIFIER_LEN );
208
270
RET_HDIAG (stmt , SQL_STATE_HY090 , "table name too long" , 0 );
209
271
}
210
272
} else {
211
273
cnt_tab = NameLength3 ;
212
274
}
213
- } else {
214
- table = MK_WPTR (ESODBC_ALL_TABLES );
215
- cnt_tab = sizeof (ESODBC_ALL_TABLES ) - /*0-term*/ 1 ;
216
- }
217
- #if 1 // TODO: GH#4334
218
- if (cnt_tab == 0 ) {
219
- table = MK_WPTR (ESODBC_ALL_TABLES );
220
- cnt_tab = sizeof (ESODBC_ALL_TABLES ) - /*0-term*/ 1 ;
275
+
276
+ cnt_tab = swprintf (wbuf + pos , wbuf_len - pos , SQL_TABLES_TAB ,
277
+ (int )cnt_tab , table );
278
+ if (cnt_tab <= 0 ) {
279
+ ERRH (stmt , "failed to print 'table' for tables catalog SQL." );
280
+ RET_HDIAGS (stmt , SQL_STATE_HY000 );
281
+ } else {
282
+ pos += cnt_tab ;
283
+ }
221
284
}
222
- #endif // 1
223
285
224
- /* print SQL to send to server */
225
- pos = swprintf (wbuf , sizeof (wbuf )/sizeof (wbuf [0 ]), SQL_TABLES ,
226
- (int )cnt_cat , catalog , (int )cnt_tab , table );
227
- if (pos <= 0 ) {
228
- ERRH (stmt , "failed to print 'tables' catalog SQL." );
229
- RET_HDIAGS (stmt , SQL_STATE_HY000 );
286
+ #if 1 // GH#30398
287
+ if (TableType ) {
288
+ type = TableType ;
289
+ if (NameLength4 == SQL_NTS ) {
290
+ cnt_typ = wcslen (type );
291
+ if (ESODBC_MAX_IDENTIFIER_LEN < cnt_typ ) {
292
+ ERRH (stmt , "type identifier name '" LTPDL "' too long "
293
+ "(%zd. max=%d)." , (int )cnt_typ , type , cnt_typ ,
294
+ ESODBC_MAX_IDENTIFIER_LEN );
295
+ RET_HDIAG (stmt , SQL_STATE_HY090 , "type name too long" , 0 );
296
+ }
297
+ } else {
298
+ cnt_typ = NameLength4 ;
299
+ }
300
+
301
+ /* In this argument, "each value can be enclosed in single quotation
302
+ * marks (') or unquoted" => quote if not quoted (see GH#30398). */
303
+ if (! wcsnstr (type , cnt_typ , L'\'' )) {
304
+ cnt_typ = quote_tokens (type , cnt_typ , typ_buf );
305
+ type = typ_buf ;
306
+ }
307
+
308
+ cnt_typ = swprintf (wbuf + pos , wbuf_len - pos , SQL_TABLES_TYP ,
309
+ (int )cnt_typ , type );
310
+ if (cnt_typ <= 0 ) {
311
+ ERRH (stmt , "failed to print 'type' for tables catalog SQL." );
312
+ RET_HDIAGS (stmt , SQL_STATE_HY000 );
313
+ } else {
314
+ pos += cnt_typ ;
315
+ }
230
316
}
317
+ #endif // 0
318
+
319
+ DBGH (stmt , "tables catalog SQL [%d]:`" LWPDL "`." , pos , pos , wbuf );
231
320
232
321
ret = EsSQLFreeStmt (stmt , ESODBC_SQL_CLOSE );
233
322
assert (SQL_SUCCEEDED (ret )); /* can't return error */
0 commit comments