pg_query icon indicating copy to clipboard operation
pg_query copied to clipboard

"user" table_name is not considered by the library

Open skpravien opened this issue 3 years ago • 3 comments

Hi, In our sql query, the table_name is "user". But this is not been considered when I parsed and try to get the table_names. `irb(main):010:0> query = "select * from user" => "select * from user"

irb(main):011:0> @parsed_query = PgQuery.parse(query) => #<PgQuery:0x00000009d56638 @query="select * from user", @tree=[{"SelectStmt"=>{"targetList"=>[{"ResTarget"=>{"val"=>{"ColumnRef"=>{"fields"=>[{"A_Star"=>{}}], "location"=>7}}, "location"=>7}}], "fromClause"=>[{"RangeFunction"=>{"functions"=>[[{"FuncCall"=>{"funcname"=>[{"String"=>{"str"=>"pg_catalog"}}, {"String"=>{"str"=>"current_user"}}], "location"=>14}}, nil]]}}], "op"=>0}}], @warnings=[]>

irb(main):012:0> @parsed_query.tables => []`

Let me know if we would need to do any change to accommodate this?

TIA

skpravien avatar Sep 17 '22 16:09 skpravien

The parse tree seems to indicate that your query is actually interpreted as "SELECT * FROM current_user()".

I think this is an escaping issue in your input - if you put the user in double quotes, it works as expected:

irb(main):006:0> query = "select * from \"user\""
=> "select * from \"user\""
irb(main):007:0> @parsed_query = PgQuery.parse(query)
=> #<PgQuery::ParserResult:0x00007f8290828768 @query="select * from \"user\"", @tree=<PgQuery::ParseResult: version: 130003, stmts: [<PgQuery::RawStmt: stmt: <PgQuery::Node: select_stmt: <PgQuery::SelectStmt: distinct_clause: [], target_list: [<PgQuery::Node: res_target: <PgQuery::ResTarget: name: "", indirection: [], val: <PgQuery::Node: column_ref: <PgQuery::ColumnRef: fields: [<PgQuery::Node: a_star: <PgQuery::A_Star: >>], location: 7>>, location: 7>>], from_clause: [<PgQuery::Node: range_var: <PgQuery::RangeVar: catalogname: "", schemaname: "", relname: "user", inh: true, relpersistence: "p", location: 14>>], group_clause: [], window_clause: [], values_lists: [], sort_clause: [], limit_option: :LIMIT_OPTION_DEFAULT, locking_clause: [], op: :SETOP_NONE, all: false>>, stmt_location: 0, stmt_len: 0>]>, @warnings=[], @tables=nil, @aliases=nil, @cte_names=nil, @functions=nil>
irb(main):008:0> @parsed_query.tables
=> ["user"]

lfittl avatar Sep 17 '22 18:09 lfittl

Thanks for pointing it out. But is there any other approach for this? Instead of having an additional quotes around the table_name? For other table_names, this works fine without the quotes around it. We can't specify that for "user" table, wrap it around a quote. @lfittl please advice

skpravien avatar Nov 30 '22 09:11 skpravien

Thanks for pointing it out. But is there any other approach for this? Instead of having an additional quotes around the table_name? For other table_names, this works fine without the quotes around it. We can't specify that for "user" table, wrap it around a quote. @lfittl please advice

I'm not sure I'm following - your query has a different intent when there are no quotes, as you are not referencing that "user" table, you are referencing the current_user function through the user alias for that function.

Where are you getting your query texts from? I'm surprised why you don't have correct escaping on the input queries you are working with.

lfittl avatar Nov 30 '22 21:11 lfittl