Re: Parsing text-based queries to SQL queries
by Joost (Canon) on Sep 29, 2005 at 11:30 UTC
|
You might be able to paste the given statement in the WHERE part, and then use SQL::Parser to examine / modify it.
Hope this helps.
| [reply] |
|
|
| [reply] |
Re: Parsing text-based queries to SQL queries
by dragonchild (Archbishop) on Sep 29, 2005 at 12:15 UTC
|
Create a mini-language. You will want to put a UI around this anyways, because you don't want to force the user to understand the table layout. (If they understand that, then why aren't they using SQL?) Plus, you don't want to restrict them to just one table, do you? If you're going to provide this kind of solution, then do it right.
They should also be using business names, not the column names. Otherwise, you're going to get the user who keeps asking "Where's my foo column?!?" (This also aids in security by giving the attacker less information.)
If the UI was HTML, I'd create a form that had dropdowns. The first set of dropdowns is the information they want to see. (SELECT * is a security hole.) They'd be able to pick a bunch, including the COUNT(*), SUM(colname), etc. Then, I'd have the restrictions, and this would be three dropdowns. One for the column name, one for the value, and one for the operator. Then, between the triplets, I'd have another dropdown with "AND" and "OR" in it. Parentheses would be added giving the user the ability to group together statements, maybe with another dropdown next to the AND/OR dropdown. At the end, provide the ability to order based on the items they chose to see. If the user chose any grouped SELECT statements, I'd automatically group the rest of the statements for them. No HAVING would be allowed (initially).
That's not that hard, really.
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] |
Re: Parsing text-based queries to SQL queries
by McDarren (Abbot) on Sep 29, 2005 at 11:41 UTC
|
Just a general observation:
..that doesn't allow error checking or using placeholders..
I think I would be much more worried about security. Imagine a mischevious user that gave:
A>6 AND B<3 OR (C>5 AND B=3); DELETE FROM table;
or even...
A>6 AND B<3 OR (C>5 AND B=3); DROP DATABASE foo;
I'm sure there are lots of ways you could allow the level of flexibility you are looking for, but you'd want to make damned sure you do some serious data validation.
--Darren | [reply] [d/l] [select] |
|
|
Since the purpose of this is to allow users to query a table then the DB handler should use a DB user that has only query rights. No fancy parsing needed.
| [reply] |
|
|
| [reply] |
|
|
Actually, they're only one part of it. The bigger part is the execution of only one statement at a time. Some DBD's will allow you to restrict yourself to one SQL statement per $sth, which is the big win.
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] |
|
|
I think I would be much more worried about security.
That depends. The OP only talks about "the user", he doesn't talk about the environment. If the OP writes a program that's run with the permissions of the user (that is, asking the user for a database user name and password), you don't need to worry about SQL attacks - the program can't do anything the user couldn't do already. If the user has permission to drop the database, he doesn't need your program to drop it. If he doesn't have permission, the program wouldn't give it to him.
Not every program is a web program. And even then, if I were to create a web program where I wanted to let users type in queries, I'd create a database user with only permissions to query - and only query the tables the webusers are allowed to see, and use that user to log in from my web program. That way, you are protecting the data at its source, and you only have to do it once, not for every possible program.
| [reply] |
Re: Parsing text-based queries to SQL queries
by jZed (Prior) on Sep 29, 2005 at 15:21 UTC
|
While I appreciate the pointer to SQL::Parser (I am its author), I have to say that it is not the module you want in this case - it is for de-constructing SQL into perl structures, not for constructing SQL from perl structures. I would recommend you look at modules like SQL::Abstract, SQL::Interpolate, and SQL::String which are for *building* SQL rather than parsing it. All of these modules support use of placeholders and will automtatically create the placeholders and bind-value lists from the perl structures. | [reply] |
Re: Parsing text-based queries to SQL queries
by jhourcle (Prior) on Sep 29, 2005 at 12:10 UTC
|
In theory, you'd know the names of all of the fields in your expressions, and what are valid operators, so you could just try to assume that runs of items between them are values that require placeholders.
If you're just dealing with numbers, as in the example, it should be easy.
Text is more difficult, as someone may search for something with the word 'like' or 'and' in it, throwing you off.
Now -- I said 'in theory'. I've never tried implementing something like this (although I may in the near future), so there may be some subtle problems that I haven't thought of.
| [reply] |