Index: funcs/func_realtime.c =================================================================== --- funcs/func_realtime.c (revision 43649) +++ funcs/func_realtime.c (working copy) @@ -74,7 +74,7 @@ if (!args.delim2) args.delim2 = "="; - head = ast_load_realtime(args.family, args.fieldmatch, args.value, NULL); + head = ast_load_realtime_all(args.family, args.fieldmatch, args.value, NULL); if (!head) { ast_module_user_remove(u); Index: include/asterisk/config.h =================================================================== --- include/asterisk/config.h (revision 43649) +++ include/asterisk/config.h (working copy) @@ -128,6 +128,7 @@ * MUST be freed with ast_variables_destroy() as there is no container. */ struct ast_variable *ast_load_realtime(const char *family, ...); +struct ast_variable *ast_load_realtime_all(const char *family, ...); /*! \brief Retrieve realtime configuration * \param family which family/config to lookup Index: main/config.c =================================================================== --- main/config.c (revision 43649) +++ main/config.c (working copy) @@ -1145,7 +1145,7 @@ return result; } -struct ast_variable *ast_load_realtime(const char *family, ...) +struct ast_variable *ast_load_realtime_all(const char *family, ...) { struct ast_config_engine *eng; char db[256]=""; @@ -1162,6 +1162,35 @@ return res; } +struct ast_variable *ast_load_realtime(const char *family, ...) +{ + struct ast_variable *res, *cur, *prev = NULL, *freeme = NULL; + va_list ap; + + va_start(ap, family); + res = ast_load_realtime_all(family, ap); + va_end(ap); + + /* Eliminate blank entries */ + for (cur = res; cur; cur = cur->next) { + if (freeme) { + free(freeme); + freeme = NULL; + } + + if (ast_strlen_zero(cur->value)) { + if (prev) + prev->next = cur->next; + else + res = cur->next; + freeme = cur; + } else { + prev = cur; + } + } + return res; +} + /*! \brief Check if realtime engine is configured for family */ int ast_check_realtime(const char *family) { Index: res/res_config_odbc.c =================================================================== --- res/res_config_odbc.c (revision 43649) +++ res/res_config_odbc.c (working copy) @@ -168,7 +168,12 @@ indicator = 0; res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), &indicator); if (indicator == SQL_NULL_DATA) - continue; + rowdata[0] = '\0'; + else if (ast_strlen_zero(rowdata)) { + /* Because we encode the empty string for a NULL, we will encode + * actual empty strings as a string containing a single whitespace. */ + ast_copy_string(rowdata, " ", sizeof(rowdata)); + } if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); @@ -180,15 +185,12 @@ stringp = rowdata; while(stringp) { chunk = strsep(&stringp, ";"); - if (!ast_strlen_zero(ast_strip(chunk))) { - if (prev) { - prev->next = ast_variable_new(coltitle, chunk); - if (prev->next) - prev = prev->next; - } else - prev = var = ast_variable_new(coltitle, chunk); - - } + if (prev) { + prev->next = ast_variable_new(coltitle, chunk); + if (prev->next) + prev = prev->next; + } else + prev = var = ast_variable_new(coltitle, chunk); } } Index: res/res_realtime.c =================================================================== --- res/res_realtime.c (revision 43649) +++ res/res_realtime.c (working copy) @@ -57,7 +57,7 @@ return RESULT_FAILURE; } - var = ast_load_realtime(argv[2], argv[3], argv[4], NULL); + var = ast_load_realtime_all(argv[2], argv[3], argv[4], NULL); if(var) { ast_cli(fd, header_format, "Column Name", "Column Value");