@@ -1133,8 +1133,7 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
1133
1133
const static wstr_st https_prefix = WSTR_INIT ("https://" );
1134
1134
wstr_st prefix ;
1135
1135
int cnt , ipv6 ;
1136
- SQLBIGINT secure ;
1137
- long long timeout , max_body_size , max_fetch_size ;
1136
+ SQLBIGINT secure , timeout , max_body_size , max_fetch_size , varchar_limit ;
1138
1137
SQLWCHAR buff_url [ESODBC_MAX_URL_LEN ];
1139
1138
wstr_st url = (wstr_st ) {
1140
1139
buff_url , /*will be init'ed later*/ 0
@@ -1188,7 +1187,7 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
1188
1187
SET_HDIAG (dbc , SQL_STATE_HY000 , "invalid security setting" , 0 );
1189
1188
goto err ;
1190
1189
} else {
1191
- dbc -> secure = (long )secure ;
1190
+ dbc -> secure = (int )secure ;
1192
1191
INFOH (dbc , "connection security level: %ld." , dbc -> secure );
1193
1192
}
1194
1193
@@ -1297,16 +1296,16 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
1297
1296
/*
1298
1297
* request timeout for liburl: negative reset to 0
1299
1298
*/
1300
- if (str2bigint (& attrs -> timeout , /*wide?*/ TRUE,
1301
- ( SQLBIGINT * ) & timeout , /*strict*/ TRUE) < 0 ) {
1299
+ if (str2bigint (& attrs -> timeout , /*wide?*/ TRUE, & timeout ,
1300
+ /*strict*/ TRUE) < 0 ) {
1302
1301
ERRH (dbc , "failed to convert `" LWPDL "` [%zu] to big int." ,
1303
1302
LWSTR (& attrs -> timeout ), attrs -> timeout .cnt );
1304
1303
SET_HDIAG (dbc , SQL_STATE_HY000 , "timeout setting number "
1305
1304
"conversion failure" , 0 );
1306
1305
goto err ;
1307
1306
}
1308
- if (timeout < 0 ) {
1309
- WARNH (dbc , "set timeout is negative (%ld ), normalized to 0." , timeout );
1307
+ if (ULONG_MAX <= timeout || timeout < 0 ) {
1308
+ WARNH (dbc , "invalid timeout value (%lld ), normalized to 0." , timeout );
1310
1309
timeout = 0 ;
1311
1310
}
1312
1311
dbc -> timeout = (SQLUINTEGER )timeout ;
@@ -1315,19 +1314,18 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
1315
1314
/*
1316
1315
* set max body size
1317
1316
*/
1318
- if (str2bigint (& attrs -> max_body_size , /*wide?*/ TRUE,
1319
- ( SQLBIGINT * ) & max_body_size , /*strict*/ TRUE) < 0 ) {
1320
- ERRH (dbc , "failed to convert max body size `" LWPDL "` [%zu] to LL ." ,
1321
- LWSTR ( & attrs -> max_body_size ), attrs -> max_body_size . cnt );
1317
+ if (str2bigint (& attrs -> max_body_size , /*wide?*/ TRUE, & max_body_size ,
1318
+ /*strict*/ TRUE) < 0 ) {
1319
+ ERRH (dbc , "failed to convert max body size [%zu] `" LWPDL "`." ,
1320
+ attrs -> max_body_size . cnt , LWSTR ( & attrs -> max_body_size ) );
1322
1321
SET_HDIAG (dbc , SQL_STATE_HY000 , "max body size setting number "
1323
1322
"conversion failure" , 0 );
1324
1323
goto err ;
1325
1324
}
1326
- if (max_body_size < 0 ) {
1327
- ERRH (dbc , "'%s' setting can't be negative (%ld )." ,
1325
+ if (( SIZE_MAX / ( 1024 * 1024 )) <= max_body_size || max_body_size < 0 ) {
1326
+ ERRH (dbc , "invalid '%s' setting value (%lld )." ,
1328
1327
ESODBC_DSN_MAX_BODY_SIZE_MB , max_body_size );
1329
- SET_HDIAG (dbc , SQL_STATE_HY000 , "invalid max body size setting "
1330
- "(negative)" , 0 );
1328
+ SET_HDIAG (dbc , SQL_STATE_HY000 , "invalid max body size setting" , 0 );
1331
1329
goto err ;
1332
1330
} else {
1333
1331
dbc -> amax = (size_t )max_body_size * 1024 * 1024 ;
@@ -1340,19 +1338,18 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
1340
1338
/*
1341
1339
* set max fetch size
1342
1340
*/
1343
- if (str2bigint (& attrs -> max_fetch_size , /*wide?*/ TRUE,
1344
- ( SQLBIGINT * ) & max_fetch_size , /*strict*/ TRUE) < 0 ) {
1345
- ERRH (dbc , "failed to convert max fetch size `" LWPDL "` [%zu] to LL ." ,
1346
- LWSTR ( & attrs -> max_fetch_size ), attrs -> max_fetch_size . cnt );
1341
+ if (str2bigint (& attrs -> max_fetch_size , /*wide?*/ TRUE, & max_fetch_size ,
1342
+ /*strict*/ TRUE) < 0 ) {
1343
+ ERRH (dbc , "failed to convert max fetch size [%zu] `" LWPDL "`." ,
1344
+ attrs -> max_fetch_size . cnt , LWSTR ( & attrs -> max_fetch_size ) );
1347
1345
SET_HDIAG (dbc , SQL_STATE_HY000 , "max fetch size setting number "
1348
1346
"conversion failure" , 0 );
1349
1347
goto err ;
1350
1348
}
1351
- if (max_fetch_size < 0 ) {
1352
- ERRH (dbc , "'%s' setting can't be negative (%ld )." ,
1349
+ if (SIZE_MAX <= max_fetch_size || max_fetch_size < 0 ) {
1350
+ ERRH (dbc , "invalid '%s' setting value (%lld )." ,
1353
1351
ESODBC_DSN_MAX_FETCH_SIZE , max_fetch_size );
1354
- SET_HDIAG (dbc , SQL_STATE_HY000 , "invalid max fetch size setting "
1355
- "(negative)" , 0 );
1352
+ SET_HDIAG (dbc , SQL_STATE_HY000 , "invalid max fetch size setting" , 0 );
1356
1353
goto err ;
1357
1354
} else {
1358
1355
dbc -> fetch .max = (size_t )max_fetch_size ;
@@ -1370,7 +1367,6 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
1370
1367
}
1371
1368
INFOH (dbc , "fetch_size: %s." , dbc -> fetch .str ? dbc -> fetch .str : "none" );
1372
1369
1373
- // TODO: catalog handling
1374
1370
1375
1371
/*
1376
1372
* set the REST body format: JSON/CBOR
@@ -1433,6 +1429,35 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
1433
1429
/* auto escape pattern value argument */
1434
1430
dbc -> auto_esc_pva = wstr2bool (& attrs -> auto_esc_pva );
1435
1431
INFOH (dbc , "auto escape PVA: %s." , dbc -> auto_esc_pva ? "true" : "false" );
1432
+ /* varchar limit */
1433
+ if (str2bigint (& attrs -> varchar_limit , /*wide?*/ TRUE, & varchar_limit ,
1434
+ /*strict*/ TRUE) < 0 ) {
1435
+ ERRH (dbc , "failed to convert varchar limit [%zu] `" LWPDL "`." ,
1436
+ attrs -> varchar_limit .cnt , LWSTR (& attrs -> varchar_limit ));
1437
+ SET_HDIAG (dbc , SQL_STATE_HY000 , "varchar limit value conversion "
1438
+ "failure" , 0 );
1439
+ goto err ;
1440
+ } else if (ESODBC_MAX_KEYWORD_PRECISION < varchar_limit ||
1441
+ varchar_limit < 0 ) {
1442
+ ERRH (dbc , "varchar limit (`" LWPDL "`) outside the allowed range "
1443
+ "[%d, %d]." , LWSTR (& attrs -> varchar_limit ), 0 ,
1444
+ ESODBC_MAX_KEYWORD_PRECISION );
1445
+ SET_HDIAG (dbc , SQL_STATE_HY000 , "invalid varchar limit setting" , 0 );
1446
+ goto err ;
1447
+ } else {
1448
+ dbc -> varchar_limit = (SQLUINTEGER )varchar_limit ;
1449
+ /* duplicate w-char setting */
1450
+ if (! (dbc -> varchar_limit_str .str = calloc (attrs -> varchar_limit .cnt +
1451
+ /*\0*/ 1 , sizeof (SQLWCHAR )))) {
1452
+ ERRNH (dbc , "OOM: %zu w-chars." , attrs -> varchar_limit .cnt + 1 );
1453
+ SET_HDIAG (dbc , SQL_STATE_HY001 , "Memory allocation error" , 0 );
1454
+ goto err ;
1455
+ }
1456
+ wmemcpy (dbc -> varchar_limit_str .str , attrs -> varchar_limit .str ,
1457
+ attrs -> varchar_limit .cnt );
1458
+ dbc -> varchar_limit_str .cnt = attrs -> varchar_limit .cnt ;
1459
+ INFOH (dbc , "varchar limit: %lu." , dbc -> varchar_limit );
1460
+ }
1436
1461
1437
1462
return SQL_SUCCESS ;
1438
1463
err :
@@ -1524,6 +1549,11 @@ void cleanup_dbc(esodbc_dbc_st *dbc)
1524
1549
} else {
1525
1550
assert (dbc -> catalog .cnt == 0 );
1526
1551
}
1552
+ if (dbc -> varchar_limit_str .str ) {
1553
+ free (dbc -> varchar_limit_str .str );
1554
+ dbc -> varchar_limit_str .str = NULL ;
1555
+ dbc -> varchar_limit_str .cnt = 0 ;
1556
+ }
1527
1557
1528
1558
assert (dbc -> abuff == NULL );
1529
1559
cleanup_curl (dbc );
@@ -2516,7 +2546,7 @@ static void *copy_types_rows(esodbc_dbc_st *dbc, estype_row_st *type_row,
2516
2546
types [i ].maximum_scale , types [i ].minimum_scale );
2517
2547
}
2518
2548
2519
- /* resolve ES type to SQL C type */
2549
+ /* resolve ES type to SQL and SQL C type */
2520
2550
if (! elastic_name2types (& types [i ].type_name , & types [i ].c_concise_type ,
2521
2551
& sql_type )) {
2522
2552
/* ES version newer than driver's? */
@@ -2529,8 +2559,8 @@ static void *copy_types_rows(esodbc_dbc_st *dbc, estype_row_st *type_row,
2529
2559
2530
2560
/* BOOLEAN is used in catalog calls (like SYS TYPES / SQLGetTypeInfo),
2531
2561
* and the data type is piped through to the app (just like with any
2532
- * other statement), which causes issues, since it's a non-SQL type
2533
- * => change it to SQL_BIT */
2562
+ * other statement), which causes issues, since it's not a standard
2563
+ * type => change it to SQL_BIT */
2534
2564
if (types [i ].data_type == ESODBC_SQL_BOOLEAN ) {
2535
2565
types [i ].data_type = ES_BOOLEAN_TO_SQL ;
2536
2566
}
@@ -2555,6 +2585,15 @@ static void *copy_types_rows(esodbc_dbc_st *dbc, estype_row_st *type_row,
2555
2585
concise_to_type_code (types [i ].data_type , & types [i ].sql_data_type ,
2556
2586
& types [i ].sql_datetime_sub );
2557
2587
2588
+ /* if there's a varchar limit, apply it to string types */
2589
+ if (types [i ].sql_data_type == ESODBC_SQL_STRING ) {
2590
+ assert (0 <= types [i ].column_size );
2591
+ if (dbc -> varchar_limit &&
2592
+ dbc -> varchar_limit < (SQLUINTEGER )types [i ].column_size ) {
2593
+ types [i ].column_size = dbc -> varchar_limit ;
2594
+ }
2595
+ }
2596
+
2558
2597
set_display_size (types + i );
2559
2598
2560
2599
/* There's no explicit coverage in the docs on how to communicate the
@@ -2691,10 +2730,10 @@ static BOOL load_es_types(esodbc_dbc_st *dbc)
2691
2730
goto end ;
2692
2731
} else if (col_cnt != ESODBC_TYPES_COLUMNS ) {
2693
2732
ERRH (stmt , "Elasticsearch returned an unexpected number of columns "
2694
- "(%d vs expected %d)." , col_cnt , ESODBC_TYPES_COLUMNS );
2733
+ "(%hd vs expected %d)." , col_cnt , ESODBC_TYPES_COLUMNS );
2695
2734
goto end ;
2696
2735
} else {
2697
- DBGH (stmt , "Elasticsearch types columns count: %d ." , col_cnt );
2736
+ DBGH (stmt , "Elasticsearch types columns count: %hd ." , col_cnt );
2698
2737
}
2699
2738
2700
2739
/* check that we have received proper number of rows (non-0, less than
0 commit comments