@@ -1133,8 +1133,7 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
11331133 const static wstr_st https_prefix = WSTR_INIT ("https://" );
11341134 wstr_st prefix ;
11351135 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 ;
11381137 SQLWCHAR buff_url [ESODBC_MAX_URL_LEN ];
11391138 wstr_st url = (wstr_st ) {
11401139 buff_url , /*will be init'ed later*/ 0
@@ -1188,7 +1187,7 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
11881187 SET_HDIAG (dbc , SQL_STATE_HY000 , "invalid security setting" , 0 );
11891188 goto err ;
11901189 } else {
1191- dbc -> secure = (long )secure ;
1190+ dbc -> secure = (int )secure ;
11921191 INFOH (dbc , "connection security level: %ld." , dbc -> secure );
11931192 }
11941193
@@ -1297,16 +1296,16 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
12971296 /*
12981297 * request timeout for liburl: negative reset to 0
12991298 */
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 ) {
13021301 ERRH (dbc , "failed to convert `" LWPDL "` [%zu] to big int." ,
13031302 LWSTR (& attrs -> timeout ), attrs -> timeout .cnt );
13041303 SET_HDIAG (dbc , SQL_STATE_HY000 , "timeout setting number "
13051304 "conversion failure" , 0 );
13061305 goto err ;
13071306 }
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 );
13101309 timeout = 0 ;
13111310 }
13121311 dbc -> timeout = (SQLUINTEGER )timeout ;
@@ -1315,19 +1314,18 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
13151314 /*
13161315 * set max body size
13171316 */
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 ) );
13221321 SET_HDIAG (dbc , SQL_STATE_HY000 , "max body size setting number "
13231322 "conversion failure" , 0 );
13241323 goto err ;
13251324 }
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 )." ,
13281327 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 );
13311329 goto err ;
13321330 } else {
13331331 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)
13401338 /*
13411339 * set max fetch size
13421340 */
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 ) );
13471345 SET_HDIAG (dbc , SQL_STATE_HY000 , "max fetch size setting number "
13481346 "conversion failure" , 0 );
13491347 goto err ;
13501348 }
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 )." ,
13531351 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 );
13561353 goto err ;
13571354 } else {
13581355 dbc -> fetch .max = (size_t )max_fetch_size ;
@@ -1370,7 +1367,6 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
13701367 }
13711368 INFOH (dbc , "fetch_size: %s." , dbc -> fetch .str ? dbc -> fetch .str : "none" );
13721369
1373- // TODO: catalog handling
13741370
13751371 /*
13761372 * set the REST body format: JSON/CBOR
@@ -1433,6 +1429,35 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
14331429 /* auto escape pattern value argument */
14341430 dbc -> auto_esc_pva = wstr2bool (& attrs -> auto_esc_pva );
14351431 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+ }
14361461
14371462 return SQL_SUCCESS ;
14381463err :
@@ -1524,6 +1549,11 @@ void cleanup_dbc(esodbc_dbc_st *dbc)
15241549 } else {
15251550 assert (dbc -> catalog .cnt == 0 );
15261551 }
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+ }
15271557
15281558 assert (dbc -> abuff == NULL );
15291559 cleanup_curl (dbc );
@@ -2516,7 +2546,7 @@ static void *copy_types_rows(esodbc_dbc_st *dbc, estype_row_st *type_row,
25162546 types [i ].maximum_scale , types [i ].minimum_scale );
25172547 }
25182548
2519- /* resolve ES type to SQL C type */
2549+ /* resolve ES type to SQL and SQL C type */
25202550 if (! elastic_name2types (& types [i ].type_name , & types [i ].c_concise_type ,
25212551 & sql_type )) {
25222552 /* ES version newer than driver's? */
@@ -2529,8 +2559,8 @@ static void *copy_types_rows(esodbc_dbc_st *dbc, estype_row_st *type_row,
25292559
25302560 /* BOOLEAN is used in catalog calls (like SYS TYPES / SQLGetTypeInfo),
25312561 * 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 */
25342564 if (types [i ].data_type == ESODBC_SQL_BOOLEAN ) {
25352565 types [i ].data_type = ES_BOOLEAN_TO_SQL ;
25362566 }
@@ -2555,6 +2585,15 @@ static void *copy_types_rows(esodbc_dbc_st *dbc, estype_row_st *type_row,
25552585 concise_to_type_code (types [i ].data_type , & types [i ].sql_data_type ,
25562586 & types [i ].sql_datetime_sub );
25572587
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+
25582597 set_display_size (types + i );
25592598
25602599 /* 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)
26912730 goto end ;
26922731 } else if (col_cnt != ESODBC_TYPES_COLUMNS ) {
26932732 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 );
26952734 goto end ;
26962735 } else {
2697- DBGH (stmt , "Elasticsearch types columns count: %d ." , col_cnt );
2736+ DBGH (stmt , "Elasticsearch types columns count: %hd ." , col_cnt );
26982737 }
26992738
27002739 /* check that we have received proper number of rows (non-0, less than
0 commit comments