]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
extconfig: Allow explicit DB result set ordering to be disabled.
authorSean Bright <sean@seanbright.com>
Wed, 12 Jul 2023 16:03:59 +0000 (12:03 -0400)
committerAsterisk Development Team <asteriskteam@digium.com>
Wed, 6 Sep 2023 18:21:30 +0000 (18:21 +0000)
Added a new boolean configuration flag -
`order_multi_row_results_by_initial_column` - to both res_pgsql.conf
and res_config_odbc.conf that allows the administrator to disable the
explicit `ORDER BY` that was previously being added to all generated
SQL statements that returned multiple rows.

Fixes: #179
(cherry picked from commit 1171beb7e45eff06d473915eaeef840fce842408)

configs/samples/res_config_odbc.conf.sample [new file with mode: 0644]
configs/samples/res_pgsql.conf.sample
res/res_config_odbc.c
res/res_config_pgsql.c

diff --git a/configs/samples/res_config_odbc.conf.sample b/configs/samples/res_config_odbc.conf.sample
new file mode 100644 (file)
index 0000000..1e4767c
--- /dev/null
@@ -0,0 +1,14 @@
+;
+; Sample configuration for res_config_odbc
+;
+; Most configuration occurs in the system ODBC configuration files,
+; res_odbc.conf, and extconfig.conf. You only need this file in the
+; event that you want to influence default sorting behavior.
+;
+
+[general]
+; When multiple rows are requested by realtime, res_config_odbc will add an
+; explicit ORDER BY clause to the generated SELECT statement. To prevent
+; that from occuring, set order_multi_row_results_by_initial_column to 'no'.
+;
+;order_multi_row_results_by_initial_column=no
index 015d68c13c2dc337c86bdc87883e9d498ce4c316..717821c8e1745ee3c2a54429598c7c502501c3e0 100644 (file)
@@ -28,3 +28,9 @@ dbpass=password
 ; createchar  - Create char columns only
 ;
 requirements=warn
+
+; When multiple rows are requested by realtime, res_config_pgsql will add an
+; explicit ORDER BY clause to the generated SELECT statement. To prevent
+; that from occuring, set order_multi_row_results_by_initial_column to 'no'.
+;
+;order_multi_row_results_by_initial_column=no
index b6a878a8537148b4d53d101620c1016fe1735d11..cecbd1792f80d818a02a46ac6bb6af26ddda392b 100644 (file)
@@ -49,6 +49,9 @@
 /*! Initial SQL query buffer size to allocate. */
 #define SQL_BUF_SIZE   1024
 
+static const char *res_config_odbc_conf = "res_config_odbc.conf";
+static int order_multi_row_results_by_initial_column = 1;
+
 AST_THREADSTORAGE(sql_buf);
 AST_THREADSTORAGE(rowdata_buf);
 
@@ -388,7 +391,10 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char *
                ast_str_append(&sql, 0, " AND %s%s ?%s", field->name, op,
                        strcasestr(field->name, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\\\'" : "");
        }
-       ast_str_append(&sql, 0, " ORDER BY %s", initfield);
+
+       if (order_multi_row_results_by_initial_column) {
+               ast_str_append(&sql, 0, " ORDER BY %s", initfield);
+       }
 
        cps.sql = ast_str_buffer(sql);
 
@@ -954,7 +960,7 @@ static struct ast_config *config_odbc(const char *database, const char *table, c
 
        memset(&q, 0, sizeof(q));
 
-       if (!file || !strcmp (file, "res_config_odbc.conf") || !sql) {
+       if (!file || !strcmp (file, res_config_odbc_conf) || !sql) {
                return NULL;            /* cant configure myself with myself ! */
        }
 
@@ -1248,22 +1254,46 @@ static struct ast_config_engine odbc_engine = {
        .unload_func = unload_odbc,
 };
 
-static int unload_module (void)
+static void load_config(const char *filename)
 {
-       ast_config_engine_deregister(&odbc_engine);
+       struct ast_config *config;
+       struct ast_flags config_flags = { 0 };
+       const char *s;
+
+       config = ast_config_load(filename, config_flags);
+       if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
+               if (config == CONFIG_STATUS_FILEINVALID) {
+                       ast_log(LOG_WARNING, "Unable to load config '%s'. Using defaults.\n", filename);
+               }
+               order_multi_row_results_by_initial_column = 1;
+               return;
+       }
 
-       return 0;
+       /* Result set ordering is enabled by default */
+       s = ast_variable_retrieve(config, "general", "order_multi_row_results_by_initial_column");
+       order_multi_row_results_by_initial_column = !s || ast_true(s);
+
+       ast_config_destroy(config);
 }
 
-static int load_module (void)
+static int load_module(void)
 {
+       /* We'll either successfully load the configuration or fail with reasonable
+        * defaults */
+       load_config(res_config_odbc_conf);
        ast_config_engine_register(&odbc_engine);
-
        return 0;
 }
 
 static int reload_module(void)
 {
+       load_config(res_config_odbc_conf);
+       return 0;
+}
+
+static int unload_module(void)
+{
+       ast_config_engine_deregister(&odbc_engine);
        return 0;
 }
 
index 62a3565e024ef4902b66833044678aa5e17ec390..2bdffea2c3e4bbbaf93754fb6033a3b30c0a3d63 100644 (file)
@@ -82,6 +82,7 @@ static char dbappname[MAX_DB_OPTION_SIZE] = "";
 static char dbsock[MAX_DB_OPTION_SIZE] = "";
 static int dbport = 5432;
 static time_t connect_time = 0;
+static int order_multi_row_results_by_initial_column = 1;
 
 static int parse_config(int reload);
 static int pgsql_reconnect(const char *database);
@@ -624,7 +625,7 @@ static struct ast_config *realtime_multi_pgsql(const char *database, const char
                ast_str_append(&sql, 0, " AND %s%s '%s'%s", field->name, op, ast_str_buffer(escapebuf), escape);
        }
 
-       if (initfield) {
+       if (initfield && order_multi_row_results_by_initial_column) {
                ast_str_append(&sql, 0, " ORDER BY %s", initfield);
        }
 
@@ -1524,6 +1525,10 @@ static int parse_config(int is_reload)
                requirements = RQ_CREATECHAR;
        }
 
+       /* Result set ordering is enabled by default */
+       s = ast_variable_retrieve(config, "general", "order_multi_row_results_by_initial_column");
+       order_multi_row_results_by_initial_column = !s || ast_true(s);
+
        ast_config_destroy(config);
 
        if (DEBUG_ATLEAST(1)) {