1*e2f98b95SBram Moolenaar" Vim completion script 2*e2f98b95SBram Moolenaar" Language: SQL 3*e2f98b95SBram Moolenaar" Maintainer: David Fishburn <[email protected]> 4*e2f98b95SBram Moolenaar" Version: 1.0 5*e2f98b95SBram Moolenaar" Last Change: Tue Mar 28 2006 4:39:49 PM 6*e2f98b95SBram Moolenaar 7*e2f98b95SBram Moolenaar" Set completion with CTRL-X CTRL-O to autoloaded function. 8*e2f98b95SBram Moolenaar" This check is in place in case this script is 9*e2f98b95SBram Moolenaar" sourced directly instead of using the autoload feature. 10*e2f98b95SBram Moolenaarif exists('&omnifunc') 11*e2f98b95SBram Moolenaar " Do not set the option if already set since this 12*e2f98b95SBram Moolenaar " results in an E117 warning. 13*e2f98b95SBram Moolenaar if &omnifunc == "" 14*e2f98b95SBram Moolenaar setlocal omnifunc=sqlcomplete#Complete 15*e2f98b95SBram Moolenaar endif 16*e2f98b95SBram Moolenaarendif 17*e2f98b95SBram Moolenaar 18*e2f98b95SBram Moolenaarif exists('g:loaded_sql_completion') 19*e2f98b95SBram Moolenaar finish 20*e2f98b95SBram Moolenaarendif 21*e2f98b95SBram Moolenaarlet g:loaded_sql_completion = 1 22*e2f98b95SBram Moolenaar 23*e2f98b95SBram Moolenaar" Maintains filename of dictionary 24*e2f98b95SBram Moolenaarlet s:sql_file_table = "" 25*e2f98b95SBram Moolenaarlet s:sql_file_procedure = "" 26*e2f98b95SBram Moolenaarlet s:sql_file_view = "" 27*e2f98b95SBram Moolenaar 28*e2f98b95SBram Moolenaar" Define various arrays to be used for caching 29*e2f98b95SBram Moolenaarlet s:tbl_name = [] 30*e2f98b95SBram Moolenaarlet s:tbl_alias = [] 31*e2f98b95SBram Moolenaarlet s:tbl_cols = [] 32*e2f98b95SBram Moolenaarlet s:syn_list = [] 33*e2f98b95SBram Moolenaarlet s:syn_value = [] 34*e2f98b95SBram Moolenaar 35*e2f98b95SBram Moolenaar" Used in conjunction with the syntaxcomplete plugin 36*e2f98b95SBram Moolenaarlet s:save_inc = "" 37*e2f98b95SBram Moolenaarlet s:save_exc = "" 38*e2f98b95SBram Moolenaarif exists('g:omni_syntax_group_include_sql') 39*e2f98b95SBram Moolenaar let s:save_inc = g:omni_syntax_group_include_sql 40*e2f98b95SBram Moolenaarendif 41*e2f98b95SBram Moolenaarif exists('g:omni_syntax_group_exclude_sql') 42*e2f98b95SBram Moolenaar let s:save_exc = g:omni_syntax_group_exclude_sql 43*e2f98b95SBram Moolenaarendif 44*e2f98b95SBram Moolenaar 45*e2f98b95SBram Moolenaar" Used with the column list 46*e2f98b95SBram Moolenaarlet s:save_prev_table = "" 47*e2f98b95SBram Moolenaar 48*e2f98b95SBram Moolenaar" Default the option to verify table alias 49*e2f98b95SBram Moolenaarif !exists('g:omni_sql_use_tbl_alias') 50*e2f98b95SBram Moolenaar let g:omni_sql_use_tbl_alias = 'a' 51*e2f98b95SBram Moolenaarendif 52*e2f98b95SBram Moolenaar 53*e2f98b95SBram Moolenaar" This function is used for the 'omnifunc' option. 54*e2f98b95SBram Moolenaarfunction! sqlcomplete#Complete(findstart, base) 55*e2f98b95SBram Moolenaar 56*e2f98b95SBram Moolenaar " Default to table name completion 57*e2f98b95SBram Moolenaar let compl_type = 'table' 58*e2f98b95SBram Moolenaar " Allow maps to specify what type of object completion they want 59*e2f98b95SBram Moolenaar if exists('b:sql_compl_type') 60*e2f98b95SBram Moolenaar let compl_type = b:sql_compl_type 61*e2f98b95SBram Moolenaar endif 62*e2f98b95SBram Moolenaar 63*e2f98b95SBram Moolenaar if a:findstart 64*e2f98b95SBram Moolenaar " Locate the start of the item, including "." 65*e2f98b95SBram Moolenaar let line = getline('.') 66*e2f98b95SBram Moolenaar let start = col('.') - 1 67*e2f98b95SBram Moolenaar let lastword = -1 68*e2f98b95SBram Moolenaar while start > 0 69*e2f98b95SBram Moolenaar if line[start - 1] =~ '\w' 70*e2f98b95SBram Moolenaar let start -= 1 71*e2f98b95SBram Moolenaar elseif line[start - 1] =~ '\.' && compl_type =~ 'column\|table' 72*e2f98b95SBram Moolenaar " If the completion type is table or column 73*e2f98b95SBram Moolenaar " Then assume we are looking for column completion 74*e2f98b95SBram Moolenaar " column_type can be either 'column' or 'column_csv' 75*e2f98b95SBram Moolenaar if lastword == -1 76*e2f98b95SBram Moolenaar let lastword = start 77*e2f98b95SBram Moolenaar endif 78*e2f98b95SBram Moolenaar let start -= 1 79*e2f98b95SBram Moolenaar let b:sql_compl_type = 'column' 80*e2f98b95SBram Moolenaar else 81*e2f98b95SBram Moolenaar break 82*e2f98b95SBram Moolenaar endif 83*e2f98b95SBram Moolenaar endwhile 84*e2f98b95SBram Moolenaar 85*e2f98b95SBram Moolenaar " Return the column of the last word, which is going to be changed. 86*e2f98b95SBram Moolenaar " Remember the text that comes before it in s:prepended. 87*e2f98b95SBram Moolenaar if lastword == -1 88*e2f98b95SBram Moolenaar let s:prepended = '' 89*e2f98b95SBram Moolenaar return start 90*e2f98b95SBram Moolenaar endif 91*e2f98b95SBram Moolenaar let s:prepended = strpart(line, start, lastword - start) 92*e2f98b95SBram Moolenaar return lastword 93*e2f98b95SBram Moolenaar endif 94*e2f98b95SBram Moolenaar 95*e2f98b95SBram Moolenaar let base = s:prepended . a:base 96*e2f98b95SBram Moolenaar 97*e2f98b95SBram Moolenaar let compl_list = [] 98*e2f98b95SBram Moolenaar 99*e2f98b95SBram Moolenaar " Default to table name completion 100*e2f98b95SBram Moolenaar let compl_type = 'table' 101*e2f98b95SBram Moolenaar " Allow maps to specify what type of object completion they want 102*e2f98b95SBram Moolenaar if exists('b:sql_compl_type') 103*e2f98b95SBram Moolenaar let compl_type = b:sql_compl_type 104*e2f98b95SBram Moolenaar unlet b:sql_compl_type 105*e2f98b95SBram Moolenaar endif 106*e2f98b95SBram Moolenaar 107*e2f98b95SBram Moolenaar if compl_type == 'tableReset' 108*e2f98b95SBram Moolenaar let compl_type = 'table' 109*e2f98b95SBram Moolenaar let base = '' 110*e2f98b95SBram Moolenaar endif 111*e2f98b95SBram Moolenaar 112*e2f98b95SBram Moolenaar if compl_type == 'table' || 113*e2f98b95SBram Moolenaar \ compl_type == 'procedure' || 114*e2f98b95SBram Moolenaar \ compl_type == 'view' 115*e2f98b95SBram Moolenaar 116*e2f98b95SBram Moolenaar " This type of completion relies upon the dbext.vim plugin 117*e2f98b95SBram Moolenaar if s:SQLCCheck4dbext() == -1 118*e2f98b95SBram Moolenaar return [] 119*e2f98b95SBram Moolenaar endif 120*e2f98b95SBram Moolenaar 121*e2f98b95SBram Moolenaar if s:sql_file_{compl_type} == "" 122*e2f98b95SBram Moolenaar let compl_type = substitute(compl_type, '\w\+', '\u&', '') 123*e2f98b95SBram Moolenaar let s:sql_file_{compl_type} = DB_getDictionaryName(compl_type) 124*e2f98b95SBram Moolenaar endif 125*e2f98b95SBram Moolenaar let s:sql_file_{compl_type} = DB_getDictionaryName(compl_type) 126*e2f98b95SBram Moolenaar if s:sql_file_{compl_type} != "" 127*e2f98b95SBram Moolenaar if filereadable(s:sql_file_{compl_type}) 128*e2f98b95SBram Moolenaar let compl_list = readfile(s:sql_file_{compl_type}) 129*e2f98b95SBram Moolenaar endif 130*e2f98b95SBram Moolenaar endif 131*e2f98b95SBram Moolenaar elseif compl_type == 'column' 132*e2f98b95SBram Moolenaar 133*e2f98b95SBram Moolenaar " This type of completion relies upon the dbext.vim plugin 134*e2f98b95SBram Moolenaar if s:SQLCCheck4dbext() == -1 135*e2f98b95SBram Moolenaar return [] 136*e2f98b95SBram Moolenaar endif 137*e2f98b95SBram Moolenaar 138*e2f98b95SBram Moolenaar if base == "" 139*e2f98b95SBram Moolenaar " The last time we displayed a column list we stored 140*e2f98b95SBram Moolenaar " the table name. If the user selects a column list 141*e2f98b95SBram Moolenaar " without a table name of alias present, assume they want 142*e2f98b95SBram Moolenaar " the previous column list displayed. 143*e2f98b95SBram Moolenaar let base = s:save_prev_table 144*e2f98b95SBram Moolenaar endif 145*e2f98b95SBram Moolenaar 146*e2f98b95SBram Moolenaar if base != "" 147*e2f98b95SBram Moolenaar let compl_list = s:SQLCGetColumns(base, '') 148*e2f98b95SBram Moolenaar let s:save_prev_table = base 149*e2f98b95SBram Moolenaar let base = '' 150*e2f98b95SBram Moolenaar endif 151*e2f98b95SBram Moolenaar elseif compl_type == 'column_csv' 152*e2f98b95SBram Moolenaar 153*e2f98b95SBram Moolenaar " This type of completion relies upon the dbext.vim plugin 154*e2f98b95SBram Moolenaar if s:SQLCCheck4dbext() == -1 155*e2f98b95SBram Moolenaar return [] 156*e2f98b95SBram Moolenaar endif 157*e2f98b95SBram Moolenaar 158*e2f98b95SBram Moolenaar if base == "" 159*e2f98b95SBram Moolenaar " The last time we displayed a column list we stored 160*e2f98b95SBram Moolenaar " the table name. If the user selects a column list 161*e2f98b95SBram Moolenaar " without a table name of alias present, assume they want 162*e2f98b95SBram Moolenaar " the previous column list displayed. 163*e2f98b95SBram Moolenaar let base = s:save_prev_table 164*e2f98b95SBram Moolenaar endif 165*e2f98b95SBram Moolenaar 166*e2f98b95SBram Moolenaar if base != "" 167*e2f98b95SBram Moolenaar let compl_list = s:SQLCGetColumns(base, 'csv') 168*e2f98b95SBram Moolenaar let s:save_prev_table = base 169*e2f98b95SBram Moolenaar " Join the column array into 1 single element array 170*e2f98b95SBram Moolenaar " but make the columns column separated 171*e2f98b95SBram Moolenaar let compl_list = [join(compl_list, ', ')] 172*e2f98b95SBram Moolenaar let base = '' 173*e2f98b95SBram Moolenaar endif 174*e2f98b95SBram Moolenaar elseif compl_type == 'resetCache' 175*e2f98b95SBram Moolenaar " Reset all cached items 176*e2f98b95SBram Moolenaar let s:tbl_name = [] 177*e2f98b95SBram Moolenaar let s:tbl_alias = [] 178*e2f98b95SBram Moolenaar let s:tbl_cols = [] 179*e2f98b95SBram Moolenaar let s:syn_list = [] 180*e2f98b95SBram Moolenaar let s:syn_value = [] 181*e2f98b95SBram Moolenaar return [] 182*e2f98b95SBram Moolenaar else 183*e2f98b95SBram Moolenaar " Default to empty or not found 184*e2f98b95SBram Moolenaar let compl_list = [] 185*e2f98b95SBram Moolenaar " Check if we have already cached the syntax list 186*e2f98b95SBram Moolenaar let list_idx = index(s:syn_list, compl_type, 0, &ignorecase) 187*e2f98b95SBram Moolenaar if list_idx > -1 188*e2f98b95SBram Moolenaar " Return previously cached value 189*e2f98b95SBram Moolenaar let compl_list = s:syn_value[list_idx] 190*e2f98b95SBram Moolenaar else 191*e2f98b95SBram Moolenaar " Request the syntax list items from the 192*e2f98b95SBram Moolenaar " syntax completion plugin 193*e2f98b95SBram Moolenaar if compl_type == 'syntax' 194*e2f98b95SBram Moolenaar " Handle this special case. This allows the user 195*e2f98b95SBram Moolenaar " to indicate they want all the syntax items available, 196*e2f98b95SBram Moolenaar " so do not specify a specific include list. 197*e2f98b95SBram Moolenaar let g:omni_syntax_group_include_sql = '' 198*e2f98b95SBram Moolenaar else 199*e2f98b95SBram Moolenaar " The user has specified a specific syntax group 200*e2f98b95SBram Moolenaar let g:omni_syntax_group_include_sql = compl_type 201*e2f98b95SBram Moolenaar endif 202*e2f98b95SBram Moolenaar let g:omni_syntax_group_exclude_sql = '' 203*e2f98b95SBram Moolenaar let syn_value = OmniSyntaxList() 204*e2f98b95SBram Moolenaar let g:omni_syntax_group_include_sql = s:save_inc 205*e2f98b95SBram Moolenaar let g:omni_syntax_group_exclude_sql = s:save_exc 206*e2f98b95SBram Moolenaar " Cache these values for later use 207*e2f98b95SBram Moolenaar let s:syn_list = add( s:syn_list, compl_type ) 208*e2f98b95SBram Moolenaar let s:syn_value = add( s:syn_value, syn_value ) 209*e2f98b95SBram Moolenaar let compl_list = syn_value 210*e2f98b95SBram Moolenaar endif 211*e2f98b95SBram Moolenaar endif 212*e2f98b95SBram Moolenaar 213*e2f98b95SBram Moolenaar if base != '' 214*e2f98b95SBram Moolenaar " Filter the list based on the first few characters the user 215*e2f98b95SBram Moolenaar " entered 216*e2f98b95SBram Moolenaar let expr = 'v:val =~ "^'.base.'"' 217*e2f98b95SBram Moolenaar let compl_list = filter(copy(compl_list), expr) 218*e2f98b95SBram Moolenaar endif 219*e2f98b95SBram Moolenaar 220*e2f98b95SBram Moolenaar return compl_list 221*e2f98b95SBram Moolenaarendfunc 222*e2f98b95SBram Moolenaar 223*e2f98b95SBram Moolenaarfunction! s:SQLCWarningMsg(msg) 224*e2f98b95SBram Moolenaar echohl WarningMsg 225*e2f98b95SBram Moolenaar echomsg a:msg 226*e2f98b95SBram Moolenaar echohl None 227*e2f98b95SBram Moolenaarendfunction 228*e2f98b95SBram Moolenaar 229*e2f98b95SBram Moolenaarfunction! s:SQLCErrorMsg(msg) 230*e2f98b95SBram Moolenaar echohl ErrorMsg 231*e2f98b95SBram Moolenaar echomsg a:msg 232*e2f98b95SBram Moolenaar echohl None 233*e2f98b95SBram Moolenaarendfunction 234*e2f98b95SBram Moolenaar 235*e2f98b95SBram Moolenaarfunction! s:SQLCCheck4dbext() 236*e2f98b95SBram Moolenaar if !exists('g:loaded_dbext') 237*e2f98b95SBram Moolenaar let msg = "The dbext plugin must be loaded for dynamic SQL completion" 238*e2f98b95SBram Moolenaar call s:SQLCErrorMsg(msg) 239*e2f98b95SBram Moolenaar " Leave time for the user to read the error message 240*e2f98b95SBram Moolenaar :sleep 2 241*e2f98b95SBram Moolenaar return -1 242*e2f98b95SBram Moolenaar elseif g:loaded_dbext < 210 243*e2f98b95SBram Moolenaar let msg = "The dbext plugin must be at least version 2.10 " . 244*e2f98b95SBram Moolenaar \ " for dynamic SQL completion" 245*e2f98b95SBram Moolenaar call s:SQLCErrorMsg(msg) 246*e2f98b95SBram Moolenaar " Leave time for the user to read the error message 247*e2f98b95SBram Moolenaar :sleep 2 248*e2f98b95SBram Moolenaar return -1 249*e2f98b95SBram Moolenaar endif 250*e2f98b95SBram Moolenaar return 1 251*e2f98b95SBram Moolenaarendfunction 252*e2f98b95SBram Moolenaar 253*e2f98b95SBram Moolenaarfunction! s:SQLCAddAlias(table_name, table_alias, cols) 254*e2f98b95SBram Moolenaar let table_name = a:table_name 255*e2f98b95SBram Moolenaar let table_alias = a:table_alias 256*e2f98b95SBram Moolenaar let cols = a:cols 257*e2f98b95SBram Moolenaar 258*e2f98b95SBram Moolenaar if g:omni_sql_use_tbl_alias != 'n' 259*e2f98b95SBram Moolenaar if table_alias == '' 260*e2f98b95SBram Moolenaar if 'da' =~? g:omni_sql_use_tbl_alias 261*e2f98b95SBram Moolenaar if table_name =~ '_' 262*e2f98b95SBram Moolenaar " Treat _ as separators since people often use these 263*e2f98b95SBram Moolenaar " for word separators 264*e2f98b95SBram Moolenaar let save_keyword = &iskeyword 265*e2f98b95SBram Moolenaar setlocal iskeyword-=_ 266*e2f98b95SBram Moolenaar 267*e2f98b95SBram Moolenaar " Get the first letter of each word 268*e2f98b95SBram Moolenaar " [[:alpha:]] is used instead of \w 269*e2f98b95SBram Moolenaar " to catch extended accented characters 270*e2f98b95SBram Moolenaar " 271*e2f98b95SBram Moolenaar let table_alias = substitute( 272*e2f98b95SBram Moolenaar \ table_name, 273*e2f98b95SBram Moolenaar \ '\<[[:alpha:]]\+\>_\?', 274*e2f98b95SBram Moolenaar \ '\=strpart(submatch(0), 0, 1)', 275*e2f98b95SBram Moolenaar \ 'g' 276*e2f98b95SBram Moolenaar \ ) 277*e2f98b95SBram Moolenaar " Restore original value 278*e2f98b95SBram Moolenaar let &iskeyword = save_keyword 279*e2f98b95SBram Moolenaar elseif table_name =~ '\u\U' 280*e2f98b95SBram Moolenaar let initials = substitute( 281*e2f98b95SBram Moolenaar \ table_name, '\(\u\)\U*', '\1', 'g') 282*e2f98b95SBram Moolenaar else 283*e2f98b95SBram Moolenaar let table_alias = strpart(table_name, 0, 1) 284*e2f98b95SBram Moolenaar endif 285*e2f98b95SBram Moolenaar endif 286*e2f98b95SBram Moolenaar endif 287*e2f98b95SBram Moolenaar if table_alias != '' 288*e2f98b95SBram Moolenaar " Following a word character, make sure there is a . and no spaces 289*e2f98b95SBram Moolenaar let table_alias = substitute(table_alias, '\w\zs\.\?\s*$', '.', '') 290*e2f98b95SBram Moolenaar if 'a' =~? g:omni_sql_use_tbl_alias && a:table_alias == '' 291*e2f98b95SBram Moolenaar let table_alias = inputdialog("Enter table alias:", table_alias) 292*e2f98b95SBram Moolenaar endif 293*e2f98b95SBram Moolenaar endif 294*e2f98b95SBram Moolenaar if table_alias != '' 295*e2f98b95SBram Moolenaar let cols = substitute(cols, '\<\w', table_alias.'&', 'g') 296*e2f98b95SBram Moolenaar endif 297*e2f98b95SBram Moolenaar endif 298*e2f98b95SBram Moolenaar 299*e2f98b95SBram Moolenaar return cols 300*e2f98b95SBram Moolenaarendfunction 301*e2f98b95SBram Moolenaar 302*e2f98b95SBram Moolenaarfunction! s:SQLCGetColumns(table_name, list_type) 303*e2f98b95SBram Moolenaar let table_name = matchstr(a:table_name, '^\w\+') 304*e2f98b95SBram Moolenaar let table_cols = [] 305*e2f98b95SBram Moolenaar let table_alias = '' 306*e2f98b95SBram Moolenaar let move_to_top = 1 307*e2f98b95SBram Moolenaar 308*e2f98b95SBram Moolenaar if g:loaded_dbext >= 210 309*e2f98b95SBram Moolenaar let saveSettingAlias = DB_listOption('use_tbl_alias') 310*e2f98b95SBram Moolenaar exec 'DBSetOption use_tbl_alias=n' 311*e2f98b95SBram Moolenaar endif 312*e2f98b95SBram Moolenaar 313*e2f98b95SBram Moolenaar " Check if we have already cached the column list for this table 314*e2f98b95SBram Moolenaar " by its name 315*e2f98b95SBram Moolenaar let list_idx = index(s:tbl_name, table_name, 0, &ignorecase) 316*e2f98b95SBram Moolenaar if list_idx > -1 317*e2f98b95SBram Moolenaar let table_cols = split(s:tbl_cols[list_idx]) 318*e2f98b95SBram Moolenaar else 319*e2f98b95SBram Moolenaar " Check if we have already cached the column list for this table 320*e2f98b95SBram Moolenaar " by its alias, assuming the table_name provided was actually 321*e2f98b95SBram Moolenaar " the alias for the table instead 322*e2f98b95SBram Moolenaar " select * 323*e2f98b95SBram Moolenaar " from area a 324*e2f98b95SBram Moolenaar " where a. 325*e2f98b95SBram Moolenaar let list_idx = index(s:tbl_alias, table_name, 0, &ignorecase) 326*e2f98b95SBram Moolenaar if list_idx > -1 327*e2f98b95SBram Moolenaar let table_alias = table_name 328*e2f98b95SBram Moolenaar let table_name = s:tbl_name[list_idx] 329*e2f98b95SBram Moolenaar let table_cols = split(s:tbl_cols[list_idx]) 330*e2f98b95SBram Moolenaar endif 331*e2f98b95SBram Moolenaar endif 332*e2f98b95SBram Moolenaar 333*e2f98b95SBram Moolenaar " If we have not found a cached copy of the table 334*e2f98b95SBram Moolenaar " And the table ends in a "." or we are looking for a column list 335*e2f98b95SBram Moolenaar " if list_idx == -1 && (a:table_name =~ '\.' || b:sql_compl_type =~ 'column') 336*e2f98b95SBram Moolenaar " if list_idx == -1 && (a:table_name =~ '\.' || a:list_type =~ 'csv') 337*e2f98b95SBram Moolenaar if list_idx == -1 338*e2f98b95SBram Moolenaar let saveY = @y 339*e2f98b95SBram Moolenaar let saveSearch = @/ 340*e2f98b95SBram Moolenaar let saveWScan = &wrapscan 341*e2f98b95SBram Moolenaar let curline = line(".") 342*e2f98b95SBram Moolenaar let curcol = col(".") 343*e2f98b95SBram Moolenaar 344*e2f98b95SBram Moolenaar " Do not let searchs wrap 345*e2f98b95SBram Moolenaar setlocal nowrapscan 346*e2f98b95SBram Moolenaar " If . was entered, look at the word just before the . 347*e2f98b95SBram Moolenaar " We are looking for something like this: 348*e2f98b95SBram Moolenaar " select * 349*e2f98b95SBram Moolenaar " from customer c 350*e2f98b95SBram Moolenaar " where c. 351*e2f98b95SBram Moolenaar " So when . is pressed, we need to find 'c' 352*e2f98b95SBram Moolenaar " 353*e2f98b95SBram Moolenaar 354*e2f98b95SBram Moolenaar " Search backwards to the beginning of the statement 355*e2f98b95SBram Moolenaar " and do NOT wrap 356*e2f98b95SBram Moolenaar " exec 'silent! normal! v?\<\(select\|update\|delete\|;\)\>'."\n".'"yy' 357*e2f98b95SBram Moolenaar exec 'silent! normal! ?\<\(select\|update\|delete\|;\)\>'."\n" 358*e2f98b95SBram Moolenaar 359*e2f98b95SBram Moolenaar " Start characterwise visual mode 360*e2f98b95SBram Moolenaar " Advance right one character 361*e2f98b95SBram Moolenaar " Search foward until one of the following: 362*e2f98b95SBram Moolenaar " 1. Another select/update/delete statement 363*e2f98b95SBram Moolenaar " 2. A ; at the end of a line (the delimiter) 364*e2f98b95SBram Moolenaar " 3. The end of the file (incase no delimiter) 365*e2f98b95SBram Moolenaar " Yank the visually selected text into the "y register. 366*e2f98b95SBram Moolenaar exec 'silent! normal! vl/\(\<select\>\|\<update\>\|\<delete\>\|;\s*$\|\%$\)'."\n".'"yy' 367*e2f98b95SBram Moolenaar 368*e2f98b95SBram Moolenaar let query = @y 369*e2f98b95SBram Moolenaar let query = substitute(query, "\n", ' ', 'g') 370*e2f98b95SBram Moolenaar let found = 0 371*e2f98b95SBram Moolenaar 372*e2f98b95SBram Moolenaar " if query =~? '^\(select\|update\|delete\)' 373*e2f98b95SBram Moolenaar if query =~? '^\(select\)' 374*e2f98b95SBram Moolenaar let found = 1 375*e2f98b95SBram Moolenaar " \(\(\<\w\+\>\)\.\)\? - 376*e2f98b95SBram Moolenaar " 'from.\{-}' - Starting at the from clause 377*e2f98b95SBram Moolenaar " '\zs\(\(\<\w\+\>\)\.\)\?' - Get the owner name (optional) 378*e2f98b95SBram Moolenaar " '\<\w\+\>\ze' - Get the table name 379*e2f98b95SBram Moolenaar " '\s\+\<'.table_name.'\>' - Followed by the alias 380*e2f98b95SBram Moolenaar " '\s*\.\@!.*' - Cannot be followed by a . 381*e2f98b95SBram Moolenaar " '\(\<where\>\|$\)' - Must be followed by a WHERE clause 382*e2f98b95SBram Moolenaar " '.*' - Exclude the rest of the line in the match 383*e2f98b95SBram Moolenaar let table_name_new = matchstr(@y, 384*e2f98b95SBram Moolenaar \ 'from.\{-}'. 385*e2f98b95SBram Moolenaar \ '\zs\(\(\<\w\+\>\)\.\)\?'. 386*e2f98b95SBram Moolenaar \ '\<\w\+\>\ze'. 387*e2f98b95SBram Moolenaar \ '\s\+\%(as\s\+\)\?\<'.table_name.'\>'. 388*e2f98b95SBram Moolenaar \ '\s*\.\@!.*'. 389*e2f98b95SBram Moolenaar \ '\(\<where\>\|$\)'. 390*e2f98b95SBram Moolenaar \ '.*' 391*e2f98b95SBram Moolenaar \ ) 392*e2f98b95SBram Moolenaar if table_name_new != '' 393*e2f98b95SBram Moolenaar let table_alias = table_name 394*e2f98b95SBram Moolenaar let table_name = table_name_new 395*e2f98b95SBram Moolenaar 396*e2f98b95SBram Moolenaar let list_idx = index(s:tbl_name, table_name, 0, &ignorecase) 397*e2f98b95SBram Moolenaar if list_idx > -1 398*e2f98b95SBram Moolenaar let table_cols = split(s:tbl_cols[list_idx]) 399*e2f98b95SBram Moolenaar let s:tbl_name[list_idx] = table_name 400*e2f98b95SBram Moolenaar let s:tbl_alias[list_idx] = table_alias 401*e2f98b95SBram Moolenaar else 402*e2f98b95SBram Moolenaar let list_idx = index(s:tbl_alias, table_name, 0, &ignorecase) 403*e2f98b95SBram Moolenaar if list_idx > -1 404*e2f98b95SBram Moolenaar let table_cols = split(s:tbl_cols[list_idx]) 405*e2f98b95SBram Moolenaar let s:tbl_name[list_idx] = table_name 406*e2f98b95SBram Moolenaar let s:tbl_alias[list_idx] = table_alias 407*e2f98b95SBram Moolenaar endif 408*e2f98b95SBram Moolenaar endif 409*e2f98b95SBram Moolenaar 410*e2f98b95SBram Moolenaar endif 411*e2f98b95SBram Moolenaar else 412*e2f98b95SBram Moolenaar " Simply assume it is a table name provided with a . on the end 413*e2f98b95SBram Moolenaar let found = 1 414*e2f98b95SBram Moolenaar endif 415*e2f98b95SBram Moolenaar 416*e2f98b95SBram Moolenaar let @y = saveY 417*e2f98b95SBram Moolenaar let @/ = saveSearch 418*e2f98b95SBram Moolenaar let &wrapscan = saveWScan 419*e2f98b95SBram Moolenaar 420*e2f98b95SBram Moolenaar " Return to previous location 421*e2f98b95SBram Moolenaar call cursor(curline, curcol) 422*e2f98b95SBram Moolenaar 423*e2f98b95SBram Moolenaar if found == 0 424*e2f98b95SBram Moolenaar if g:loaded_dbext > 201 425*e2f98b95SBram Moolenaar exec 'DBSetOption use_tbl_alias='.saveSettingAlias 426*e2f98b95SBram Moolenaar endif 427*e2f98b95SBram Moolenaar 428*e2f98b95SBram Moolenaar " Not a SQL statement, do not display a list 429*e2f98b95SBram Moolenaar return [] 430*e2f98b95SBram Moolenaar endif 431*e2f98b95SBram Moolenaar endif 432*e2f98b95SBram Moolenaar 433*e2f98b95SBram Moolenaar if empty(table_cols) 434*e2f98b95SBram Moolenaar " Specify silent mode, no messages to the user (tbl, 1) 435*e2f98b95SBram Moolenaar " Specify do not comma separate (tbl, 1, 1) 436*e2f98b95SBram Moolenaar let table_cols_str = DB_getListColumn(table_name, 1, 1) 437*e2f98b95SBram Moolenaar 438*e2f98b95SBram Moolenaar if table_cols_str != "" 439*e2f98b95SBram Moolenaar let s:tbl_name = add( s:tbl_name, table_name ) 440*e2f98b95SBram Moolenaar let s:tbl_alias = add( s:tbl_alias, table_alias ) 441*e2f98b95SBram Moolenaar let s:tbl_cols = add( s:tbl_cols, table_cols_str ) 442*e2f98b95SBram Moolenaar let table_cols = split(table_cols_str) 443*e2f98b95SBram Moolenaar endif 444*e2f98b95SBram Moolenaar 445*e2f98b95SBram Moolenaar endif 446*e2f98b95SBram Moolenaar 447*e2f98b95SBram Moolenaar if g:loaded_dbext > 201 448*e2f98b95SBram Moolenaar exec 'DBSetOption use_tbl_alias='.saveSettingAlias 449*e2f98b95SBram Moolenaar endif 450*e2f98b95SBram Moolenaar 451*e2f98b95SBram Moolenaar if a:list_type == 'csv' && !empty(table_cols) 452*e2f98b95SBram Moolenaar let cols = join(table_cols, ', ') 453*e2f98b95SBram Moolenaar let cols = s:SQLCAddAlias(table_name, table_alias, cols) 454*e2f98b95SBram Moolenaar let table_cols = [cols] 455*e2f98b95SBram Moolenaar endif 456*e2f98b95SBram Moolenaar 457*e2f98b95SBram Moolenaar return table_cols 458*e2f98b95SBram Moolenaarendfunction 459*e2f98b95SBram Moolenaar 460