#! /bin/ruby require ('fiddle') #antlr = Fiddle.dlopen('mylib.so') #input_string = "(sql_script (unit_statement (data_manipulation_language_statements (insert_statement INSERT (single_table_insert (insert_into_clause INTO (general_table_ref (dml_table_expression_clause (tableview_name (identifier (id_expression (regular_id suppliers)))))) (paren_column_list ( (column_list (column_name (identifier (id_expression (regular_id supplier_id)))) , (column_name (identifier (id_expression (regular_id supplier_name))))) ))) (values_clause VALUES ( (expressions (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (numeric 5000))))))))))) , (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (quoted_string 'Apple')))))))))))) )))))) ; )" #input_string = "(sql_script (unit_statement (data_manipulation_language_statements (insert_statement INSERT (single_table_insert (insert_into_clause INTO (general_table_ref (dml_table_expression_clause (tableview_name (identifier (id_expression (regular_id suppliers)))))) (paren_column_list ( (column_list (column_name (identifier (id_expression (regular_id supplier_id)))) , (column_name (identifier (id_expression (regular_id supplier_name))))) ))) (select_statement (subquery (subquery_basic_elements (query_block SELECT (selected_element (select_list_elements (expressions (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id account_no))))))))))))) , (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id (non_reserved_keywords_pre12c name))))))))))))))))) (from_clause FROM (table_ref_list (table_ref (table_ref_aux (table_ref_aux_internal (dml_table_expression_clause (tableview_name (identifier (id_expression (regular_id customers)))))))))) (where_clause WHERE (expression (logical_expression (multiset_expression (relational_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id customer_id)))))))))) (relational_operator >) (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (numeric 5000))))))))))))))))))))) ; )" #input_string = "(sql_script (unit_statement (data_manipulation_language_statements (update_statement UPDATE (general_table_ref (dml_table_expression_clause (tableview_name (identifier (id_expression (regular_id customers)))))) (update_set_clause SET (column_based_update_set_clause (column_name (identifier (id_expression (regular_id last_name)))) = (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (quoted_string 'Anderson'))))))))))))) (where_clause WHERE (expression (logical_expression (multiset_expression (relational_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id customer_id)))))))))) (relational_operator =) (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (numeric 5000)))))))))))))))) ; )" #input_string = "(sql_script (unit_statement (data_manipulation_language_statements (insert_statement INSERT (single_table_insert (insert_into_clause INTO (general_table_ref (dml_table_expression_clause (tableview_name (identifier (id_expression (regular_id suppliers)))))) (paren_column_list ( (column_list (column_name (identifier (id_expression (regular_id supplier_id)))) , (column_name (identifier (id_expression (regular_id supplier_name))))) ))) (select_statement (subquery (subquery_basic_elements (query_block SELECT (selected_element (select_list_elements (expressions (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id account_no))))))))))))) , (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id (non_reserved_keywords_pre12c name))))))))))))))))) (from_clause FROM (table_ref_list (table_ref (table_ref_aux (table_ref_aux_internal (dml_table_expression_clause (tableview_name (identifier (id_expression (regular_id customers)))))))))) (where_clause WHERE (expression (logical_expression (logical_expression (multiset_expression (relational_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id customer_id)))))))))) (relational_operator >) (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (numeric 5000))))))))))) and (logical_expression (multiset_expression (relational_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id customer_name)))))))))) (relational_operator <>) (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (quoted_string 'john')))))))))))))))))))))) ; )" #input_string = "[@0,0:5='INSERT',<663>,1:0]\n[@1,7:10='INTO',<685>,1:7]\n[@2,12:20='suppliers',<2242>,1:12]\n[@3,22:22='(',<2213>,2:0]\n[@4,23:33='supplier_id',<2242>,2:1]\n[@5,34:34=',',<2219>,2:12]\n[@6,36:48='supplier_name',<2242>,2:14]\n[@7,49:49=')',<2214>,2:27]\n[@8,51:56='VALUES',<2064>,3:0]\n[@9,58:58='(',<2213>,4:0]\n[@10,59:62='5000',<2207>,4:1]\n[@11,63:63=',',<2219>,4:5]\n[@12,65:71=''Apple'',<2209>,4:7]\n[@13,72:72=')',<2214>,4:14]\n[@14,73:73=';',<2231>,4:15]\n[@15,75:74='',<-1>,5:0]" #input_string = "[@0,0:5='INSERT',<663>,1:0]\n[@1,7:10='INTO',<685>,1:7]\n[@2,12:20='suppliers',<2242>,1:12]\n[@3,22:22='(',<2213>,2:0]\n[@4,23:33='supplier_id',<2242>,2:1]\n[@5,34:34=',',<2219>,2:12]\n[@6,36:48='supplier_name',<2242>,2:14]\n[@7,49:49=')',<2214>,2:27]\n[@8,51:56='SELECT',<1482>,3:0]\n[@9,58:67='account_no',<2242>,3:7]\n[@10,68:68=',',<2219>,3:17]\n[@11,70:73='name',<873>,3:19]\n[@12,75:78='FROM',<548>,4:0]\n[@13,80:88='customers',<2242>,4:5]\n[@14,90:94='WHERE',<2105>,5:0]\n[@15,96:106='customer_id',<2242>,5:6]\n[@16,108:108='>',<2228>,5:18]\n[@17,110:113='5000',<2207>,5:20]\n[@18,114:114=';',<2231>,5:24]\n[@19,116:115='',<-1>,6:0]" #input_string = "[@0,0:5='INSERT',<663>,1:0]\n[@1,7:10='INTO',<685>,1:7]\n[@2,12:20='suppliers',<2242>,1:12]\n[@3,22:22='(',<2213>,2:0]\n[@4,23:33='supplier_id',<2242>,2:1]\n[@5,34:34=',',<2219>,2:12]\n[@6,36:48='supplier_name',<2242>,2:14]\n[@7,49:49=')',<2214>,2:27]\n[@8,51:56='SELECT',<1482>,3:0]\n[@9,58:58='(',<2213>,3:7]\n[@10,59:68='account_no',<2242>,3:8]\n[@11,69:69=',',<2219>,3:18]\n[@12,71:74='name',<873>,3:20]\n[@13,75:75=')',<2214>,3:24]\n[@14,77:80='FROM',<548>,4:0]\n[@15,82:90='customers',<2242>,4:5]\n[@16,92:96='WHERE',<2105>,5:0]\n[@17,98:108='customer_id',<2242>,5:6]\n[@18,110:110='>',<2228>,5:18]\n[@19,112:115='5000',<2207>,5:20]\n[@20,116:116=';',<2231>,5:24]\n[@21,118:117='',<-1>,6:0]" #input_string = "[@0,0:5='INSERT',<663>,1:0]\n[@1,7:10='INTO',<685>,1:7]\n[@2,12:20='suppliers',<2242>,1:12]\n[@3,22:22='(',<2213>,2:0]\n[@4,23:33='supplier_id',<2242>,2:1]\n[@5,34:34=',',<2219>,2:12]\n[@6,36:48='supplier_name',<2242>,2:14]\n[@7,49:49=')',<2214>,2:27]\n[@8,51:56='SELECT',<1482>,3:0]\n[@9,58:58='(',<2213>,3:7]\n[@10,59:68='account_no',<2242>,3:8]\n[@11,69:69=',',<2219>,3:18]\n[@12,71:74='name',<873>,3:20]\n[@13,75:75=')',<2214>,3:24]\n[@14,77:80='FROM',<548>,4:0]\n[@15,82:90='customers',<2242>,4:5]\n[@16,92:96='WHERE',<2105>,5:0]\n[@17,98:98='(',<2213>,5:6]\n[@18,99:109='customer_id',<2242>,5:7]\n[@19,111:111='>',<2228>,5:19]\n[@20,113:116='5000',<2207>,5:21]\n[@21,117:117=')',<2214>,5:25]\n[@22,118:118=';',<2231>,5:26]\n[@23,120:119='',<-1>,6:0]" #Problematic input, mixing SELECT statement input_string = "[@0,0:5='INSERT',<663>,1:0]\n[@1,7:10='INTO',<685>,1:7]\n[@2,12:18='clients',<2242>,1:12]\n[@3,20:20='(',<2213>,2:0]\n[@4,21:29='client_id',<2242>,2:1]\n[@5,30:30=',',<2219>,2:10]\n[@6,32:42='client_name',<2242>,2:12]\n[@7,43:43=',',<2219>,2:23]\n[@8,45:55='client_type',<2242>,2:25]\n[@9,56:56=')',<2214>,2:36]\n[@10,58:63='SELECT',<1482>,3:0]\n[@11,65:69='10345',<2207>,3:7]\n[@12,70:70=',',<2219>,3:12]\n[@13,72:76=''IBM'',<2209>,3:14]\n[@14,77:77=',',<2219>,3:19]\n[@15,79:91=''advertising'',<2209>,3:21]\n[@16,93:96='FROM',<548>,4:0]\n[@17,98:101='dual',<2242>,4:5]\n[@18,103:107='WHERE',<2105>,5:0]\n[@19,109:111='NOT',<1067>,5:6]\n[@20,113:118='EXISTS',<472>,5:10]\n[@21,120:120='(',<2213>,5:17]\n[@22,121:126='SELECT',<1482>,5:18]\n[@23,128:128='*',<2216>,5:25]\n[@24,148:151='FROM',<548>,6:18]\n[@25,153:159='clients',<2242>,6:23]\n[@26,179:183='WHERE',<2105>,7:18]\n[@27,185:191='clients',<2242>,7:24]\n[@28,192:192='.',<2206>,7:31]\n[@29,193:201='client_id',<2242>,7:32]\n[@30,203:203='=',<2233>,7:42]\n[@31,205:209='10345',<2207>,7:44]\n[@32,210:210=')',<2214>,7:49]\n[@33,211:211=';',<2231>,7:50]\n[@34,213:212='',<-1>,8:0]" def get_quoted_value (line) first_quote = line.index('\'') last_quote = line.rindex('\'') if first_quote and last_quote then return line[first_quote+1..last_quote-1] else return '' end end input_array = input_string.split("\n") #Constants COMMAND_LINE = 0 #Command is in first line INSERT_MODE = 0 UPDATE_MODE = 1 output = Hash.new command_mode = nil output['command'] = get_quoted_value(input_array[COMMAND_LINE]) case output['command'].downcase when 'insert' command_mode = INSERT_MODE when 'update' command_mode = UPDATE_MODE end i=0 input_array.each do |line| if line.downcase.index('into') then output['table_name'] = get_quoted_value(input_array[i+1]) #table for INSERT is line after INTO statement #column_names are after table name and '(' output['column_names'] = [] k=i+3 loop do column_name = get_quoted_value(input_array[k]) break if column_name == ')' if column_name != ',' then output['column_names'].push(column_name) end k+=1 end end if line.downcase.index('values') then output['column_values'] = [] k=i+2 loop do column_value = get_quoted_value(input_array[k]) break if column_value == ')' if column_value != ',' then output['column_values'].push(column_value) end k+=1 end end if line.downcase.index('select') then output['select_columns'] = [] finish_loop_on_char = 'from' k=i+1 if get_quoted_value(input_array[i+1]) == '(' then finish_loop_on_char = ')' k+=1 end loop do column_value = get_quoted_value(input_array[k]) break if column_value.downcase == finish_loop_on_char if column_value != ',' then output['select_columns'].push(column_value) end k+=1 end end if line.downcase.index('where') then output['where_conditions'] = '' finish_loop_on_char = ';' k=i+1 if get_quoted_value(input_array[i+1]) == '(' then finish_loop_on_char = ')' k+=1 end loop do column_value = get_quoted_value(input_array[k]) break if column_value.downcase == finish_loop_on_char output['where_conditions'] += column_value k+=1 end end if line.downcase.index('from') then output['from_table'] = get_quoted_value(input_array[i+1]) #table for FROM query is line after FROM statement end i+=1 end puts output return #Old try end_of_input = input_string.index(';') - 1 input_string = input_string[0..end_of_input] + ')' tag_list = [] tag_levels = [] tag_level = 0 input_string.split('(').each do |tag| level_down = tag.count(')') clean_tag = tag.gsub ')', '' #puts clean_tag + "[" + tag_level.to_s + "]" if clean_tag.length > 1 then tag_list.push(clean_tag) tag_levels.push(tag_level) #result[tag_level] = clean_tag + ';' + result[tag_level].to_s tag_level += 1 tag_level -= level_down end end #Command : INSERT / UPDATE / DELETE / CREATE / ALTER is on level 3 #On level 3, there is statement like "insert_statement INSERT" #CONSTANTS : COMMAND_LEVEL = 3 output = Hash.new output['command'] = tag_list[COMMAND_LEVEL].split(' ')[1] #command is after space output['values'] = Hash.new output['where'] = nil output['from'] = nil values_array = [] i=0 value_counter = 0 k=0 first_block = true tag_list.each do |tag| puts "[" + tag_levels[i].to_s + "] : " + tag if tag.index('from_clause') then output['from'] = tag_list[i+8].to_s.split(' ')[1] end if tag.index('where_clause') then end if i < tag_list.length-1 if tag_levels[i+1] < tag_levels[i] then k = tag_levels[i] - tag_levels[i+1] parent = tag_list[i-k].rstrip.lstrip clean_tag = tag.split(' ')[1] if parent == "general_table_ref" then output['table_name'] = clean_tag elsif parent == "column_name" then output['values'][clean_tag] = nil values_array.push(clean_tag) elsif parent == "expression" then output['values'][values_array[value_counter]] = clean_tag value_counter+=1 i+=1 end else end else #Last tag in array, locate parent if first_block then first_block = false else parent = tag_list[i-k-1].rstrip.lstrip clean_tag = tag.split(' ')[1] if parent == "expression" then output['values'][values_array[value_counter]] = clean_tag end end end i+=1 end puts output return #Old try #2 def parse(input) puts "New input : " + input open_count = input.count('(') close_count = input.count(')') first_bracket = input.index('(') last_bracket = input.rindex(')') if (first_bracket == -1) or (last_bracket == -1) then return '' end #return everything between brackets tmp_token = '' result = [] level = 0 new_input = input[first_bracket+1..last_bracket-1] # new_input.split('').each do |character| # if character == '(' then level += 1 end # if character == ')' then level -= 1 end # if level == 0 then # puts "ok" # if tmp_token.length > 0 then # result.push(tmp_token) # tmp_token='' # end # else # tmp_token += character # end # end # puts "===" # return result end