Repository: mindsdb/mindsdb

Issue:
Make 'predict' argument case insensitive in 'create predictor' query
At this moment user get error if he provide 'predict' target in wrong case:
```
CREATE PREDICTOR predictor
                FROM integration
                (select * FROM test_data.home_rentals) 
                PREDICT RENTAL_PRICE;
```


Discussion:

Resolving patch:
diff --git a/mindsdb/api/mysql/mysql_proxy/mysql_proxy.py b/mindsdb/api/mysql/mysql_proxy/mysql_proxy.py
--- a/mindsdb/api/mysql/mysql_proxy/mysql_proxy.py
+++ b/mindsdb/api/mysql/mysql_proxy/mysql_proxy.py
@@ -406,7 +406,16 @@ def insert_predictor_answer(self, insert):
                     data_store.delete_datasource(ds_name)
                 raise Exception(f"Column '{col}' not exists")
 
-        model_interface.learn(insert['name'], ds, insert['predict'], ds_data['id'], kwargs=kwargs)
+        try:
+            insert['predict'] = self._check_predict_columns(insert['predict'], ds_columns)
+        except Exception:
+            if is_select_data_query:
+                data_store.delete_datasource(ds_name)
+            raise
+
+        model_interface.learn(
+            insert['name'], ds, insert['predict'], ds_data['id'], kwargs=kwargs, delete_ds_on_fail=is_select_data_query
+        )
 
         self.packet(OkPacket).send()
 
@@ -440,6 +449,35 @@ def answer_create_ai_table(self, struct):
 
         self.packet(OkPacket).send()
 
+    def _check_predict_columns(self, predict_column_names, ds_column_names):
+        ''' validate 'predict' column names
+
+            predict_column_names: list of 'predict' columns
+            ds_column_names: list of all datasource columns
+        '''
+        cleaned_predict_column_names = []
+        for predict_column_name in predict_column_names:
+            candidate = None
+            for column_name in ds_column_names:
+                if column_name == predict_column_name:
+                    if candidate is not None:
+                        raise Exception("It is not possible to determine appropriate column name for 'predict' column: {predict_column_name}")
+                    candidate = column_name
+            if candidate is None:
+                for column_name in ds_column_names:
+                    if column_name.lower() == predict_column_name.lower():
+                        if candidate is not None:
+                            raise Exception("It is not possible to determine appropriate column name for 'predict' column: {predict_column_name}")
+                        candidate = column_name
+            if candidate is None:
+                raise Exception("Datasource has not column with name '{predict_column_name}'")
+            cleaned_predict_column_names.append(candidate)
+
+        if len(cleaned_predict_column_names) != len(set(cleaned_predict_column_names)):
+            raise Exception("'predict' column name is duplicated")
+
+        return cleaned_predict_column_names
+
     def answer_retrain_predictor(self, predictor_name):
         model_interface = self.session.model_interface
         models = model_interface.get_models()
@@ -481,6 +519,13 @@ def answer_create_predictor(self, struct):
             else:
                 kwargs['timeseries_settings'].update(timeseries_settings)
 
+        ds_column_names = [x['name'] for x in ds_data['columns']]
+        try:
+            predict = self._check_predict_columns(predict, ds_column_names)
+        except Exception:
+            data_store.delete_datasource(ds_name)
+            raise
+
         model_interface.learn(predictor_name, ds, predict, ds_data['id'], kwargs=kwargs, delete_ds_on_fail=True)
 
         self.packet(OkPacket).send()


Test patch: