How do you edit an SQL query in Apache Superset? - mysql

I have set up Superset on my Jupiter notebook and it is working i.e. the sample dashboards etc, work. When I try to create a simple table view to just do a SELECT * from Table to view the whole table (it is a small table), Superset keeps generating the SQL:
SELECT
FROM*
(SELECT Country,
Region,
Users,
Emails
FROM `UserStats`
LIMIT 50000) *AS expr_qry
LIMIT 50000
The first SELECT FROM and the AS expr_qry LIMIT 50000 are automatically generated and I cannot get rid of them (i.e. in the Slice view it shows this as the query, but won't let me edit it). Why does it generate its own SQL and where do you change this?
I tried to find workarounds for this but I feel I am missing something fundamental here.

there is a configuration for 'ROW_LIMIT' in superset/config.py,(default is 50000). if you need remove 'limit cause', try superset/viz.py, query_obj function.

Related

How to give table an alternative name in MySQL?

I want to use a table that would be accessible under two names (something like e-mail address alias) i.e. I want queries:
select * from my_table_name
and
select * from my_alt_table_name
return records from the same table.
I know I can use a view and then run query on view, but wouldn't it be less efficient?
I know I can use a view and then run query on view, but wouldn't it be less efficient?
If the view is strictly SELECT * FROM table, without any additions (WHERE and so on), then there is no difference does you use the table or the view as an alias.
See small DEMO.
See SHOW WARNING outputs - they claims that the server is smart enough for to understand that it may/must use the table itself.
See EXPLAIN outputs - they claims that the server is smart enough for to understand that it may/must use the index which is present in the table structure.
expanded DEMO fiddle - analyse it by itself.
Also study CREATE VIEW Statement, ALGORITHM clause, and View Processing Algorithms. Try to add ALGORITHM = TEMPTABLE to DEMO and investigate the changes.
You can't have a table with multiple names, so yeah, just use views. There will be no impact on performance during the runtime, however during the compilation of the query, there will be just a small delay time for the compilation of the view to be transformed into a table in memory which is absolutely negligible
CREATE VIEW table_name_alias AS SELECT * FROM table_name;
SELECT * FROM table_name_alias;
Creating a view would look like this
CREATE VIEW my_alt_table_name AS SELECT * FROM my_table_name;
and next time you can use it like this
SELECT * FROM my_alt_table_name ;

Storing SQL queries in table and run them on-the-fly when selecting - Possible? Good practice?

I'm currently thinking about a database schema in MySQL where I store SELECT queries into a certain table column, just to execute them on-the-fly when getting selected, and having the result passed instead of the actual query.
Would this be possible somehow? Or may this be bad practice? Is it even technically possible to have a result table passed to a single field, at least so I could run the query through PDO to get back a nested result array? Are there any alternatives?
I've read that this may be achieved through stored procedures, and although I grip the concept of those I can't think of how I could use those to achieve that.
You could do this, but what purpose do you have for doing it?
I would suggest using views:
The syntax should be valid when the view is created, unlike storing
the SQL in a field which may have invalid syntax.
It's easier to debug and modify.
For example, let's say one of the queries you want to store is:
SELECT product_category, COUNT(*) AS category_count
FROM product
GROUP BY product_category;
You can create a new "view" object that defines this query:
CREATE VIEW prod_cat_count AS
SELECT product_category, COUNT(*) AS category_count
FROM product
GROUP BY product_category;
Now, the object called "prod_cat_count" is stored in the database. Internally, the database just knows that "prod_cat_count" is equal to the SELECT query we mentioned. When the view is created, the database validates the syntax (checks that all columns exist, checks you haven't forgotten the GROUP BY, for example)
Then, whenever you want to get this data/run this query, you can run this statement (in SQL or in application code, for example):
SELECT product_category, category_count
FROM prod_cat_count;
If you then decide you want to change the way the product categories are counted, you can adjust the view:
SELECT product_category, COUNT(*) AS category_count
FROM product
GROUP BY product_category
ORDER BY product_category;
Hope that helps!

(Routed) SQL injection on shared parameter

I am in charge of the security of several websites. Recently we bought the Acunetix WVS and performed several tests that gave positive on SQL injection. Not only am I trying to replicate these tests but I also trying to find out if it is possible to extract relevant information, given that we have a WAF/IPS deployed that mitigates the more critical SQL injections.
I am obviously not allowed to disclose the website I am currently testing on, for that I will refer to it as http://example.com.
I was able to find out that on the page http://example.com/show_results.php?group=1&query=members there are 2 queries being used to display the results. So maybe, this is related to Routed SQL Injection. I have applied several SQL injection techniques, and through the error messages I have identified that they take the form of:
SELECT 1 FROM ... WHERE group='1' LIMIT 0,1
SELECT 1,2,3,4 FROM ... WHERE group='1' AND `user_type` NOT LIKE 'colaborators' ORDER BY 'name'
Both queries are displayed on individual <div>. user_type represents the members on the URL. The first query is obviously very easy to inject. I can get the database name by simply changing the URL to:
http://example.com/show_results.php?group=1' union select database() -- - &query=
The obvious question here is: How to get the table names for instance. Something like:
GROUP_CONCAT(table_name) FROM information_schema.tables WHERE TABLE_SCHEMA=database()
This is tricky because both queries use the same group parameter, so it is not entirely Routed SQL Injection in its simplest form. Something like this:
http://example.com/show_results.php?group=1' union select database() -- -&query=members
Note the difference brom above on the query parameter. This shows me the error of The used SELECT statements have a different number of columns (obviously because both queries have a different number of columns).

Switch values in MySQL table

I have a table in MySQL with a field "Ordering" These are just auto incremented numbers. Now I wonder if there is a query to change the values from the last to the first...
So the entry with ordering 205 should become 1, 204 -> 2 and so on...
It's actually not an auto-increment. The problem is I started adding projects from the current website. From page 1 to page 20, but the first item on page 1 is the latest. The way I added the new projects, the newest is on the last page..
If the ordering field is switched, the new items added will be correctly numbered again and added to the front page. It's just a wrong way I started adding old projects...
Structure
Examples of the content
I can't comment due to limitations, but i really agree with #Abhik Chakraborty.
You don't want to do this. Just use the order by as he suggested.
Example:
SELECT * FROM tableName
ORDER BY columnName DESC;
Just in case you would like to know more about it: http://www.w3schools.com/sql/sql_orderby.asp
Try this as one statement call:
SET #MaxSort := (SELECT MAX(Ordering) FROM MyTable);
UPDATE MyTable t set t.Ordering = (#MaxSort + 1 - t.Ordering);
This will work if field doesn't have unique constraint.
But this field, should not be an auto_increment field at first place. Auto increment is increasing NOT decreasing counter. Except if you just try to fix existing data and the new records will be increasing.
Additional explanation
Thanks for pointing it out. Multiple query inside single query statement doesn't work with php_mysqli and it is not used because of potential MySQL injection attack if servers allows it. Maybe you can setup PHPMyAdmin to use PHP PDO.
I can use multiple queries, but I'm using PHP PDO or DBeaver database manager.
I can only suggest to supply MaxSort manually (since this is one time job anyway):
UPDATE
MyTable t
set
t.Ordering = 254 - t.Ordering + 1;

Mysql "magic" catch all column for select statement

Is there a way that I can do a select as such
select * from attributes where product_id = 500
would return
id name description
1 wheel round and black
2 horn makes loud noise
3 window solid object you can see through
and the query
select * from attributes where product_id = 234
would return the same results as would any query to this table.
Now obviously I could just remove the where clause and go about my day. But this involves editing code that I don't really want to modify so i'm trying to fix this at the database level.
So is there a "magical" way to ignore what is in the where clause and return whatever I want using a view or something ?
Even if it was possible, I doubt it would work. Both of those WHERE clauses expect one thing to be returned, therefore the code would probably just use the first row returned, not all of them.
It would also give the database a behaviour that would make future developers pull their hair out trying to understand.
Do it properly and fix the code.
or you could pass "product_id" instead of an integer, if there's no code checking for that...so the query would become:
select * from attributes where product_id = product_id;
this would give you every row in the table.
If you can't edit the query, maybe you can append to it? You could stick
OR 1=1
on the end.
You may be able to use result set metadata to get what you want, but a result set won't have descriptions of fields. The specific API to get result set metadata from a prepared query varies by programming language, and you haven't said what language you're using.
You can query the INFORMATION_SCHEMA for the products table.
SELECT ordinal_position, column_name, column_comment
FROM INFORMATION_SCHEMA.columns
WHERE table_name = 'products' AND schema_name = 'mydatabase';
You can restructure the database into an Entity-Attribute-Value design, but that's a much more ambitious change than fixing your code.
Or you can abandon SQL databases altogether, and use a semantic data store like RDF, which allows you to query metadata of an entity in the same way you query data.
As far out as this idea seems I'm always interested in crazy ways to do things.
I think the best solution I could come up with is to use a view that uses the products table to get all the products then the attributes table to get the attributes, so every possible product is accounted for and all will get the same result