From 867e01d9fe77c2b808e772d8328237928f350bf3 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Tue, 20 Dec 2005 15:34:58 +0100
Subject: [PATCH] Store the each column from a multi column result set into a
 separate variable.

client/mysqltest.c:
  Update var_query_set to store every column from a query into a separate variable.
  The whole result will still be stored as tab separated string in the var that let points at.
mysql-test/r/mysqltest.result:
  Add test results
mysql-test/t/mysqltest.test:
  Add tests for "one variable for each column" from let.
---
 client/mysqltest.c            | 68 +++++++++++++++++++++++++++--------
 mysql-test/r/mysqltest.result | 19 ++++++++++
 mysql-test/t/mysqltest.test   | 36 +++++++++++++++++++
 3 files changed, 109 insertions(+), 14 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 7ba8dc31405..e709dc64ef4 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -1137,26 +1137,50 @@ static void do_exec(struct st_query *query)
   DBUG_VOID_RETURN;
 }
 
+/*
+  Set variable from the result of a query
+
+  SYNOPSIS
+    var_query_set()
+    var	        variable to set from query
+    query       start of query string to execute
+    query_end   end of the query string to execute
 
-int var_query_set(VAR* v, const char *p, const char** p_end)
+
+  DESCRIPTION
+    let @<var_name> = `<query>`
+
+    Execute the query and assign the first row of result to var as
+    a tab separated strings
+
+    Also assign each column of the result set to
+    variable "$<var_name>_<column_name>"
+    Thus the tab separated output can be read from $<var_name> and
+    and each individual column can be read as $<var_name>_<col_name>
+
+*/
+
+int var_query_set(VAR* var, const char *query, const char** query_end)
 {
-  char* end = (char*)((p_end && *p_end) ? *p_end : p + strlen(p));
+  char* end = (char*)((query_end && *query_end) ?
+		      *query_end : query + strlen(query));
   MYSQL_RES *res;
   MYSQL_ROW row;
   MYSQL* mysql = &cur_con->mysql;
   LINT_INIT(res);
 
-  while (end > p && *end != '`')
+  while (end > query && *end != '`')
     --end;
-  if (p == end)
+  if (query == end)
     die("Syntax error in query, missing '`'");
-  ++p;
+  ++query;
 
-  if (mysql_real_query(mysql, p, (int)(end - p)) ||
+  if (mysql_real_query(mysql, query, (int)(end - query)) ||
       !(res = mysql_store_result(mysql)))
   {
     *end = 0;
-    die("Error running query '%s': %s", p, mysql_error(mysql));
+    die("Error running query '%s': %d: %s", query,
+	mysql_errno(mysql) ,mysql_error(mysql));
   }
 
   if ((row = mysql_fetch_row(res)) && row[0])
@@ -1169,21 +1193,39 @@ int var_query_set(VAR* v, const char *p, const char** p_end)
     uint i;
     ulong *lengths;
     char *end;
+    MYSQL_FIELD *fields= mysql_fetch_fields(res);
 
     init_dynamic_string(&result, "", 16384, 65536);
     lengths= mysql_fetch_lengths(res);
     for (i=0; i < mysql_num_fields(res); i++)
     {
       if (row[0])
+      {
+	/* Add to <var_name>_<col_name> */
+	uint j;
+	char var_col_name[MAX_VAR_NAME];
+	uint length= snprintf(var_col_name, MAX_VAR_NAME,
+			      "$%s_%s", var->name, fields[i].name);
+	/* Convert characters not allowed in variable names to '_' */
+	for (j= 1; j < length; j++)
+	{
+	  if (!my_isvar(charset_info,var_col_name[j]))
+	     var_col_name[j]= '_';
+        }
+	var_set(var_col_name,  var_col_name + length,
+		row[i], row[i] + lengths[i]);
+
+        /* Add column to tab separated string */
 	dynstr_append_mem(&result, row[i], lengths[i]);
+      }
       dynstr_append_mem(&result, "\t", 1);
     }
     end= result.str + result.length-1;
-    eval_expr(v, result.str, (const char**) &end);
+    eval_expr(var, result.str, (const char**) &end);
     dynstr_free(&result);
   }
   else
-    eval_expr(v, "", 0);
+    eval_expr(var, "", 0);
 
   mysql_free_result(res);
   return 0;
@@ -4129,12 +4171,10 @@ static VAR *var_init(VAR *v, const char *name, int name_len, const char *val,
   if (!(tmp_var->str_val = my_malloc(val_alloc_len+1, MYF(MY_WME))))
     die("Out of memory");
 
-  memcpy(tmp_var->name, name, name_len);
+  if (name)
+    strmake(tmp_var->name, name, name_len);
   if (val)
-  {
-    memcpy(tmp_var->str_val, val, val_len);
-    tmp_var->str_val[val_len]=0;
-  }
+    strmake(tmp_var->str_val, val, val_len);
   tmp_var->name_len = name_len;
   tmp_var->str_val_len = val_len;
   tmp_var->alloced_len = val_alloc_len;
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 0109436fac9..bf3821555cc 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -222,6 +222,25 @@ mysqltest: At line 1: Missing arguments to let
 mysqltest: At line 1: Missing variable name in let
 mysqltest: At line 1: Variable name in =hi does not start with '$'
 mysqltest: At line 1: Missing assignment operator in let
+var1
+hi	1	hi there
+hi
+1
+hi there
+var2
+2
+
+
+var2 again
+2
+
+2
+
+var3 two columns with same name
+1	2	3
+2
+2
+3
 mysqltest: At line 1: Missing file name in source
 mysqltest: At line 1: Could not open file ./non_existingFile
 mysqltest: In included file "./var/tmp/recursive.sql": At line 1: Source directives are nesting too deep
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index 3d851605823..ae28a66c685 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -539,6 +539,42 @@ echo $novar1;
 --error 1
 --exec echo "let hi;" | $MYSQL_TEST  2>&1
 
+# ----------------------------------------------------------------------------
+# Test to assign let from query
+# let $<var_name>=`<query>`;
+# ----------------------------------------------------------------------------
+
+echo var1;
+let $var1= `select "hi" as "Col", 1 as "Column1", "hi there" as Col3`;
+echo $var1;
+echo $var1_Col;
+echo $var1_Column1;
+echo $var1_Col3;
+
+echo var2;
+let $var2= `select 2 as "Column num 2"`;
+echo $var2;
+echo $var2_Column num 2;
+echo $var2_Column;
+
+echo var2 again;
+let $var2= `select 2 as "Column num 2"`;
+echo $var2;
+echo $var2_Column num 2;
+echo $var2_Column_num_2;
+echo $var2_Column;
+
+echo var3 two columns with same name;
+let $var3= `select 1 as "Col", 2 as "Col", 3 as "var3"`;
+echo $var3;
+echo $var3_Col;
+echo $var3_Col;
+echo $var3_var3;
+
+#echo failing query in let;
+#--error 1
+#--exec echo "let $var2= `failing query;`" | $MYSQL_TEST 2>&1
+
 # ----------------------------------------------------------------------------
 # Test source command
 # ----------------------------------------------------------------------------
-- 
2.30.9