1f193fffdSBram Moolenaar" Vim OMNI completion script for SQL 2e2f98b95SBram Moolenaar" Language: SQL 35c73622aSBram Moolenaar" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com> 4*f9d5ca1dSBram Moolenaar" Version: 10.0 5*f9d5ca1dSBram Moolenaar" Last Change: 2010 Jun 11 6f193fffdSBram Moolenaar" Usage: For detailed help 7f193fffdSBram Moolenaar" ":help sql.txt" 8f193fffdSBram Moolenaar" or ":help ft-sql-omni" 9f193fffdSBram Moolenaar" or read $VIMRUNTIME/doc/sql.txt 10e2f98b95SBram Moolenaar 115c73622aSBram Moolenaar" History 12*f9d5ca1dSBram Moolenaar" Version 10.0 13*f9d5ca1dSBram Moolenaar" Updated PreCacheSyntax() 14*f9d5ca1dSBram Moolenaar" - Now returns a List of the syntax items it finds. 15*f9d5ca1dSBram Moolenaar" This allows other plugins / scripts to use this list for their own 16*f9d5ca1dSBram Moolenaar" purposes. In this case XPTemplate can use them for a Choose list. 17*f9d5ca1dSBram Moolenaar" - Verifies the parameters are the correct type and displays a 18*f9d5ca1dSBram Moolenaar" warning if not. 19*f9d5ca1dSBram Moolenaar" - Verifies the parameters are the correct type and displays a 20*f9d5ca1dSBram Moolenaar" warning if not. 21*f9d5ca1dSBram Moolenaar" Updated SQLCWarningMsg() 22*f9d5ca1dSBram Moolenaar" - Prepends warning message with SQLComplete so you know who issued 23*f9d5ca1dSBram Moolenaar" the warning. 24*f9d5ca1dSBram Moolenaar" Updated SQLCErrorMsg() 25*f9d5ca1dSBram Moolenaar" - Prepends error message with SQLComplete so you know who issued 26*f9d5ca1dSBram Moolenaar" the error. 27*f9d5ca1dSBram Moolenaar" 2800a927d6SBram Moolenaar" Version 9.0 2900a927d6SBram Moolenaar" This change removes some of the support for tables with spaces in their 3000a927d6SBram Moolenaar" names in order to simplify the regexes used to pull out query table 3100a927d6SBram Moolenaar" aliases for more robust table name and column name code completion. 3200a927d6SBram Moolenaar" Full support for "table names with spaces" can be added in again 3300a927d6SBram Moolenaar" after 7.3. 34*f9d5ca1dSBram Moolenaar" 3500a927d6SBram Moolenaar" Version 8.0 3600a927d6SBram Moolenaar" Incorrectly re-executed the g:ftplugin_sql_omni_key_right and g:ftplugin_sql_omni_key_left 3700a927d6SBram Moolenaar" when drilling in and out of a column list for a table. 38*f9d5ca1dSBram Moolenaar" 395c73622aSBram Moolenaar" Version 7.0 405c73622aSBram Moolenaar" Better handling of object names 41*f9d5ca1dSBram Moolenaar" 425c73622aSBram Moolenaar" Version 6.0 435c73622aSBram Moolenaar" Supports object names with spaces "my table name" 445c73622aSBram Moolenaar" 45e2f98b95SBram Moolenaar" Set completion with CTRL-X CTRL-O to autoloaded function. 46e2f98b95SBram Moolenaar" This check is in place in case this script is 47e2f98b95SBram Moolenaar" sourced directly instead of using the autoload feature. 48e2f98b95SBram Moolenaarif exists('&omnifunc') 49e2f98b95SBram Moolenaar " Do not set the option if already set since this 50e2f98b95SBram Moolenaar " results in an E117 warning. 51e2f98b95SBram Moolenaar if &omnifunc == "" 52e2f98b95SBram Moolenaar setlocal omnifunc=sqlcomplete#Complete 53e2f98b95SBram Moolenaar endif 54e2f98b95SBram Moolenaarendif 55e2f98b95SBram Moolenaar 56e2f98b95SBram Moolenaarif exists('g:loaded_sql_completion') 57e2f98b95SBram Moolenaar finish 58e2f98b95SBram Moolenaarendif 59*f9d5ca1dSBram Moolenaarlet g:loaded_sql_completion = 100 60e2f98b95SBram Moolenaar 61e2f98b95SBram Moolenaar" Maintains filename of dictionary 62e2f98b95SBram Moolenaarlet s:sql_file_table = "" 63e2f98b95SBram Moolenaarlet s:sql_file_procedure = "" 64e2f98b95SBram Moolenaarlet s:sql_file_view = "" 65e2f98b95SBram Moolenaar 66e2f98b95SBram Moolenaar" Define various arrays to be used for caching 67e2f98b95SBram Moolenaarlet s:tbl_name = [] 68e2f98b95SBram Moolenaarlet s:tbl_alias = [] 69e2f98b95SBram Moolenaarlet s:tbl_cols = [] 70e2f98b95SBram Moolenaarlet s:syn_list = [] 71e2f98b95SBram Moolenaarlet s:syn_value = [] 72e2f98b95SBram Moolenaar 73e2f98b95SBram Moolenaar" Used in conjunction with the syntaxcomplete plugin 74e2f98b95SBram Moolenaarlet s:save_inc = "" 75e2f98b95SBram Moolenaarlet s:save_exc = "" 76e2f98b95SBram Moolenaarif exists('g:omni_syntax_group_include_sql') 77e2f98b95SBram Moolenaar let s:save_inc = g:omni_syntax_group_include_sql 78e2f98b95SBram Moolenaarendif 79e2f98b95SBram Moolenaarif exists('g:omni_syntax_group_exclude_sql') 80e2f98b95SBram Moolenaar let s:save_exc = g:omni_syntax_group_exclude_sql 81e2f98b95SBram Moolenaarendif 82e2f98b95SBram Moolenaar 83e2f98b95SBram Moolenaar" Used with the column list 84e2f98b95SBram Moolenaarlet s:save_prev_table = "" 85e2f98b95SBram Moolenaar 86e2f98b95SBram Moolenaar" Default the option to verify table alias 87e2f98b95SBram Moolenaarif !exists('g:omni_sql_use_tbl_alias') 88e2f98b95SBram Moolenaar let g:omni_sql_use_tbl_alias = 'a' 89e2f98b95SBram Moolenaarendif 90910f66f9SBram Moolenaar" Default syntax items to precache 91910f66f9SBram Moolenaarif !exists('g:omni_sql_precache_syntax_groups') 92910f66f9SBram Moolenaar let g:omni_sql_precache_syntax_groups = [ 93910f66f9SBram Moolenaar \ 'syntax', 94910f66f9SBram Moolenaar \ 'sqlKeyword', 95910f66f9SBram Moolenaar \ 'sqlFunction', 96910f66f9SBram Moolenaar \ 'sqlOption', 97910f66f9SBram Moolenaar \ 'sqlType', 98910f66f9SBram Moolenaar \ 'sqlStatement' 99910f66f9SBram Moolenaar \ ] 100910f66f9SBram Moolenaarendif 101eb3593b3SBram Moolenaar" Set ignorecase to the ftplugin standard 102eb3593b3SBram Moolenaarif !exists('g:omni_sql_ignorecase') 103eb3593b3SBram Moolenaar let g:omni_sql_ignorecase = &ignorecase 104eb3593b3SBram Moolenaarendif 105eb3593b3SBram Moolenaar" During table completion, should the table list also 106eb3593b3SBram Moolenaar" include the owner name 107eb3593b3SBram Moolenaarif !exists('g:omni_sql_include_owner') 108eb3593b3SBram Moolenaar let g:omni_sql_include_owner = 0 109eb3593b3SBram Moolenaar if exists('g:loaded_dbext') 110eb3593b3SBram Moolenaar if g:loaded_dbext >= 300 111eb3593b3SBram Moolenaar " New to dbext 3.00, by default the table lists include the owner 112eb3593b3SBram Moolenaar " name of the table. This is used when determining how much of 113eb3593b3SBram Moolenaar " whatever has been typed should be replaced as part of the 114eb3593b3SBram Moolenaar " code replacement. 115eb3593b3SBram Moolenaar let g:omni_sql_include_owner = 1 116eb3593b3SBram Moolenaar endif 117eb3593b3SBram Moolenaar endif 118eb3593b3SBram Moolenaarendif 119e2f98b95SBram Moolenaar 120e2f98b95SBram Moolenaar" This function is used for the 'omnifunc' option. 121e2f98b95SBram Moolenaarfunction! sqlcomplete#Complete(findstart, base) 122e2f98b95SBram Moolenaar 123e2f98b95SBram Moolenaar " Default to table name completion 124e2f98b95SBram Moolenaar let compl_type = 'table' 125e2f98b95SBram Moolenaar " Allow maps to specify what type of object completion they want 126e2f98b95SBram Moolenaar if exists('b:sql_compl_type') 127e2f98b95SBram Moolenaar let compl_type = b:sql_compl_type 128e2f98b95SBram Moolenaar endif 129e2f98b95SBram Moolenaar 130910f66f9SBram Moolenaar " First pass through this function determines how much of the line should 131910f66f9SBram Moolenaar " be replaced by whatever is chosen from the completion list 132e2f98b95SBram Moolenaar if a:findstart 133e2f98b95SBram Moolenaar " Locate the start of the item, including "." 134e2f98b95SBram Moolenaar let line = getline('.') 135e2f98b95SBram Moolenaar let start = col('.') - 1 136e2f98b95SBram Moolenaar let lastword = -1 137f193fffdSBram Moolenaar let begindot = 0 138f193fffdSBram Moolenaar " Check if the first character is a ".", for column completion 139f193fffdSBram Moolenaar if line[start - 1] == '.' 140f193fffdSBram Moolenaar let begindot = 1 141f193fffdSBram Moolenaar endif 142e2f98b95SBram Moolenaar while start > 0 1435c73622aSBram Moolenaar " Additional code was required to handle objects which 1445c73622aSBram Moolenaar " can contain spaces like "my table name". 1455c73622aSBram Moolenaar if line[start - 1] !~ '\(\w\|\.\)' 1465c73622aSBram Moolenaar " If the previous character is not a period or word character 1475c73622aSBram Moolenaar break 1485c73622aSBram Moolenaar " elseif line[start - 1] =~ '\(\w\|\s\+\)' 1495c73622aSBram Moolenaar " let start -= 1 1505c73622aSBram Moolenaar elseif line[start - 1] =~ '\w' 1515c73622aSBram Moolenaar " If the previous character is word character continue back 152e2f98b95SBram Moolenaar let start -= 1 153eb3593b3SBram Moolenaar elseif line[start - 1] =~ '\.' && 154eb3593b3SBram Moolenaar \ compl_type =~ 'column\|table\|view\|procedure' 1555c73622aSBram Moolenaar " If the previous character is a period and we are completing 1565c73622aSBram Moolenaar " an object which can be specified with a period like this: 1575c73622aSBram Moolenaar " table_name.column_name 1585c73622aSBram Moolenaar " owner_name.table_name 1595c73622aSBram Moolenaar 160eb3593b3SBram Moolenaar " If lastword has already been set for column completion 161eb3593b3SBram Moolenaar " break from the loop, since we do not also want to pickup 162eb3593b3SBram Moolenaar " a table name if it was also supplied. 163f193fffdSBram Moolenaar if lastword != -1 && compl_type == 'column' 164eb3593b3SBram Moolenaar break 165eb3593b3SBram Moolenaar endif 166f193fffdSBram Moolenaar " If column completion was specified stop at the "." if 167f193fffdSBram Moolenaar " a . was specified, otherwise, replace all the way up 168f193fffdSBram Moolenaar " to the owner name (if included). 169f193fffdSBram Moolenaar if lastword == -1 && compl_type == 'column' && begindot == 1 170e2f98b95SBram Moolenaar let lastword = start 171e2f98b95SBram Moolenaar endif 172eb3593b3SBram Moolenaar " If omni_sql_include_owner = 0, do not include the table 173eb3593b3SBram Moolenaar " name as part of the substitution, so break here 174eb3593b3SBram Moolenaar if lastword == -1 && 175f193fffdSBram Moolenaar \ compl_type =~ 'table\|view\|procedure\column_csv' && 176eb3593b3SBram Moolenaar \ g:omni_sql_include_owner == 0 177eb3593b3SBram Moolenaar let lastword = start 178eb3593b3SBram Moolenaar break 179eb3593b3SBram Moolenaar endif 180e2f98b95SBram Moolenaar let start -= 1 181e2f98b95SBram Moolenaar else 182e2f98b95SBram Moolenaar break 183e2f98b95SBram Moolenaar endif 184e2f98b95SBram Moolenaar endwhile 185e2f98b95SBram Moolenaar 186e2f98b95SBram Moolenaar " Return the column of the last word, which is going to be changed. 187e2f98b95SBram Moolenaar " Remember the text that comes before it in s:prepended. 188e2f98b95SBram Moolenaar if lastword == -1 189e2f98b95SBram Moolenaar let s:prepended = '' 190e2f98b95SBram Moolenaar return start 191e2f98b95SBram Moolenaar endif 192e2f98b95SBram Moolenaar let s:prepended = strpart(line, start, lastword - start) 193e2f98b95SBram Moolenaar return lastword 194e2f98b95SBram Moolenaar endif 195e2f98b95SBram Moolenaar 196910f66f9SBram Moolenaar " Second pass through this function will determine what data to put inside 197910f66f9SBram Moolenaar " of the completion list 198910f66f9SBram Moolenaar " s:prepended is set by the first pass 199e2f98b95SBram Moolenaar let base = s:prepended . a:base 200e2f98b95SBram Moolenaar 201910f66f9SBram Moolenaar " Default the completion list to an empty list 202e2f98b95SBram Moolenaar let compl_list = [] 203e2f98b95SBram Moolenaar 204e2f98b95SBram Moolenaar " Default to table name completion 205e2f98b95SBram Moolenaar let compl_type = 'table' 206e2f98b95SBram Moolenaar " Allow maps to specify what type of object completion they want 207e2f98b95SBram Moolenaar if exists('b:sql_compl_type') 208e2f98b95SBram Moolenaar let compl_type = b:sql_compl_type 209e2f98b95SBram Moolenaar unlet b:sql_compl_type 210e2f98b95SBram Moolenaar endif 211e2f98b95SBram Moolenaar 212e2f98b95SBram Moolenaar if compl_type == 'tableReset' 213e2f98b95SBram Moolenaar let compl_type = 'table' 214e2f98b95SBram Moolenaar let base = '' 215e2f98b95SBram Moolenaar endif 216e2f98b95SBram Moolenaar 217e2f98b95SBram Moolenaar if compl_type == 'table' || 218e2f98b95SBram Moolenaar \ compl_type == 'procedure' || 219e2f98b95SBram Moolenaar \ compl_type == 'view' 220e2f98b95SBram Moolenaar 221e2f98b95SBram Moolenaar " This type of completion relies upon the dbext.vim plugin 222e2f98b95SBram Moolenaar if s:SQLCCheck4dbext() == -1 223e2f98b95SBram Moolenaar return [] 224e2f98b95SBram Moolenaar endif 225e2f98b95SBram Moolenaar 22683e138c6SBram Moolenaar " Allow the user to override the dbext plugin to specify whether 22783e138c6SBram Moolenaar " the owner/creator should be included in the list 2288c8de839SBram Moolenaar if g:loaded_dbext >= 300 2298c8de839SBram Moolenaar let saveSetting = DB_listOption('dict_show_owner') 2308c8de839SBram Moolenaar exec 'DBSetOption dict_show_owner='.(g:omni_sql_include_owner==1?'1':'0') 231e2f98b95SBram Moolenaar endif 23283e138c6SBram Moolenaar 23383e138c6SBram Moolenaar let compl_type_uc = substitute(compl_type, '\w\+', '\u&', '') 2345c73622aSBram Moolenaar " Same call below, no need to do it twice 2355c73622aSBram Moolenaar " if s:sql_file_{compl_type} == "" 2365c73622aSBram Moolenaar " let s:sql_file_{compl_type} = DB_getDictionaryName(compl_type_uc) 2375c73622aSBram Moolenaar " endif 23883e138c6SBram Moolenaar let s:sql_file_{compl_type} = DB_getDictionaryName(compl_type_uc) 239e2f98b95SBram Moolenaar if s:sql_file_{compl_type} != "" 240e2f98b95SBram Moolenaar if filereadable(s:sql_file_{compl_type}) 241e2f98b95SBram Moolenaar let compl_list = readfile(s:sql_file_{compl_type}) 242e2f98b95SBram Moolenaar endif 243e2f98b95SBram Moolenaar endif 24483e138c6SBram Moolenaar 2458c8de839SBram Moolenaar if g:loaded_dbext > 300 2468c8de839SBram Moolenaar exec 'DBSetOption dict_show_owner='.saveSetting 2478c8de839SBram Moolenaar endif 24883e138c6SBram Moolenaar elseif compl_type =~? 'column' 249e2f98b95SBram Moolenaar 250e2f98b95SBram Moolenaar " This type of completion relies upon the dbext.vim plugin 251e2f98b95SBram Moolenaar if s:SQLCCheck4dbext() == -1 252e2f98b95SBram Moolenaar return [] 253e2f98b95SBram Moolenaar endif 254e2f98b95SBram Moolenaar 255e2f98b95SBram Moolenaar if base == "" 256e2f98b95SBram Moolenaar " The last time we displayed a column list we stored 257e2f98b95SBram Moolenaar " the table name. If the user selects a column list 258e2f98b95SBram Moolenaar " without a table name of alias present, assume they want 259e2f98b95SBram Moolenaar " the previous column list displayed. 260e2f98b95SBram Moolenaar let base = s:save_prev_table 261e2f98b95SBram Moolenaar endif 262e2f98b95SBram Moolenaar 26383e138c6SBram Moolenaar let owner = '' 26483e138c6SBram Moolenaar let column = '' 26583e138c6SBram Moolenaar 26683e138c6SBram Moolenaar if base =~ '\.' 26783e138c6SBram Moolenaar " Check if the owner/creator has been specified 26883e138c6SBram Moolenaar let owner = matchstr( base, '^\zs.*\ze\..*\..*' ) 26983e138c6SBram Moolenaar let table = matchstr( base, '^\(.*\.\)\?\zs.*\ze\..*' ) 27083e138c6SBram Moolenaar let column = matchstr( base, '.*\.\zs.*' ) 27183e138c6SBram Moolenaar 27283e138c6SBram Moolenaar " It is pretty well impossible to determine if the user 27383e138c6SBram Moolenaar " has entered: 27483e138c6SBram Moolenaar " owner.table 27583e138c6SBram Moolenaar " table.column_prefix 27683e138c6SBram Moolenaar " So there are a couple of things we can do to mitigate 27783e138c6SBram Moolenaar " this issue. 27883e138c6SBram Moolenaar " 1. Check if the dbext plugin has the option turned 27983e138c6SBram Moolenaar " on to even allow owners 28083e138c6SBram Moolenaar " 2. Based on 1, if the user is showing a table list 28100a927d6SBram Moolenaar " and the DrillIntoTable (using <Right>) then 28283e138c6SBram Moolenaar " this will be owner.table. In this case, we can 28383e138c6SBram Moolenaar " check to see the table.column exists in the 28483e138c6SBram Moolenaar " cached table list. If it does, then we have 28583e138c6SBram Moolenaar " determined the user has actually chosen 28683e138c6SBram Moolenaar " owner.table, not table.column_prefix. 28783e138c6SBram Moolenaar let found = -1 28883e138c6SBram Moolenaar if g:omni_sql_include_owner == 1 && owner == '' 28983e138c6SBram Moolenaar if filereadable(s:sql_file_table) 29083e138c6SBram Moolenaar let tbl_list = readfile(s:sql_file_table) 29183e138c6SBram Moolenaar let found = index( tbl_list, ((table != '')?(table.'.'):'').column) 29283e138c6SBram Moolenaar endif 29383e138c6SBram Moolenaar endif 29483e138c6SBram Moolenaar " If the table.column was found in the table list, we can safely assume 29583e138c6SBram Moolenaar " the owner was not provided and shift the items appropriately. 29683e138c6SBram Moolenaar " OR 29783e138c6SBram Moolenaar " If the user has indicated not to use table owners at all and 29883e138c6SBram Moolenaar " the base ends in a '.' we know they are not providing a column 29983e138c6SBram Moolenaar " name, so we can shift the items appropriately. 30083e138c6SBram Moolenaar if found != -1 || (g:omni_sql_include_owner == 0 && base !~ '\.$') 30183e138c6SBram Moolenaar let owner = table 30283e138c6SBram Moolenaar let table = column 30383e138c6SBram Moolenaar let column = '' 30483e138c6SBram Moolenaar endif 30583e138c6SBram Moolenaar else 30683e138c6SBram Moolenaar let table = base 30783e138c6SBram Moolenaar endif 30883e138c6SBram Moolenaar 30983e138c6SBram Moolenaar " Get anything after the . and consider this the table name 31083e138c6SBram Moolenaar " If an owner has been specified, then we must consider the 31183e138c6SBram Moolenaar " base to be a partial column name 31283e138c6SBram Moolenaar " let base = matchstr( base, '^\(.*\.\)\?\zs.*' ) 31383e138c6SBram Moolenaar 31483e138c6SBram Moolenaar if table != "" 315e2f98b95SBram Moolenaar let s:save_prev_table = base 31683e138c6SBram Moolenaar let list_type = '' 31783e138c6SBram Moolenaar 31883e138c6SBram Moolenaar if compl_type == 'column_csv' 31983e138c6SBram Moolenaar " Return one array element, with a comma separated 32083e138c6SBram Moolenaar " list of values instead of multiple array entries 32183e138c6SBram Moolenaar " for each column in the table. 32283e138c6SBram Moolenaar let list_type = 'csv' 32383e138c6SBram Moolenaar endif 32483e138c6SBram Moolenaar 32583e138c6SBram Moolenaar let compl_list = s:SQLCGetColumns(table, list_type) 32683e138c6SBram Moolenaar if column != '' 32783e138c6SBram Moolenaar " If no column prefix has been provided and the table 32883e138c6SBram Moolenaar " name was provided, append it to each of the items 32983e138c6SBram Moolenaar " returned. 33083e138c6SBram Moolenaar let compl_list = map(compl_list, "table.'.'.v:val") 33183e138c6SBram Moolenaar if owner != '' 33283e138c6SBram Moolenaar " If an owner has been provided append it to each of the 33383e138c6SBram Moolenaar " items returned. 33483e138c6SBram Moolenaar let compl_list = map(compl_list, "owner.'.'.v:val") 33583e138c6SBram Moolenaar endif 33683e138c6SBram Moolenaar else 337e2f98b95SBram Moolenaar let base = '' 338e2f98b95SBram Moolenaar endif 339e2f98b95SBram Moolenaar 34083e138c6SBram Moolenaar if compl_type == 'column_csv' 341e2f98b95SBram Moolenaar " Join the column array into 1 single element array 342e2f98b95SBram Moolenaar " but make the columns column separated 343e2f98b95SBram Moolenaar let compl_list = [join(compl_list, ', ')] 34483e138c6SBram Moolenaar endif 345e2f98b95SBram Moolenaar endif 346e2f98b95SBram Moolenaar elseif compl_type == 'resetCache' 347e2f98b95SBram Moolenaar " Reset all cached items 348e2f98b95SBram Moolenaar let s:tbl_name = [] 349e2f98b95SBram Moolenaar let s:tbl_alias = [] 350e2f98b95SBram Moolenaar let s:tbl_cols = [] 351e2f98b95SBram Moolenaar let s:syn_list = [] 352e2f98b95SBram Moolenaar let s:syn_value = [] 353f193fffdSBram Moolenaar 354f193fffdSBram Moolenaar let msg = "All SQL cached items have been removed." 355f193fffdSBram Moolenaar call s:SQLCWarningMsg(msg) 356f193fffdSBram Moolenaar " Leave time for the user to read the error message 357f193fffdSBram Moolenaar :sleep 2 358e2f98b95SBram Moolenaar else 359910f66f9SBram Moolenaar let compl_list = s:SQLCGetSyntaxList(compl_type) 360e2f98b95SBram Moolenaar endif 361e2f98b95SBram Moolenaar 362e2f98b95SBram Moolenaar if base != '' 3635c73622aSBram Moolenaar " Filter the list based on the first few characters the user entered. 3645c73622aSBram Moolenaar " Check if the text matches at the beginning 3655c73622aSBram Moolenaar " or 3665c73622aSBram Moolenaar " Match to a owner.table or alias.column type match 3675c73622aSBram Moolenaar " or 3685c73622aSBram Moolenaar " Handle names with spaces "my table name" 3695c73622aSBram Moolenaar let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|^\\(\\w\\+\\.\\)\\?'.base.'\\)"' 3705c73622aSBram Moolenaar " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\)"' 3715c73622aSBram Moolenaar " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|\\(\\.\\)\\?'.base.'\\)"' 3725c73622aSBram Moolenaar " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|\\([^.]*\\)\\?'.base.'\\)"' 373eb3593b3SBram Moolenaar let compl_list = filter(deepcopy(compl_list), expr) 374e2f98b95SBram Moolenaar endif 375e2f98b95SBram Moolenaar 376910f66f9SBram Moolenaar if exists('b:sql_compl_savefunc') && b:sql_compl_savefunc != "" 377910f66f9SBram Moolenaar let &omnifunc = b:sql_compl_savefunc 378910f66f9SBram Moolenaar endif 379910f66f9SBram Moolenaar 380e2f98b95SBram Moolenaar return compl_list 381e2f98b95SBram Moolenaarendfunc 382e2f98b95SBram Moolenaar 383910f66f9SBram Moolenaarfunction! sqlcomplete#PreCacheSyntax(...) 384910f66f9SBram Moolenaar let syn_group_arr = [] 385*f9d5ca1dSBram Moolenaar let syn_items = [] 386*f9d5ca1dSBram Moolenaar 387910f66f9SBram Moolenaar if a:0 > 0 388*f9d5ca1dSBram Moolenaar if type(a:1) != 3 389*f9d5ca1dSBram Moolenaar call s:SQLCWarningMsg("Parameter is not a list. Example:['syntaxGroup1', 'syntaxGroup2']") 390*f9d5ca1dSBram Moolenaar return '' 391*f9d5ca1dSBram Moolenaar endif 392910f66f9SBram Moolenaar let syn_group_arr = a:1 393910f66f9SBram Moolenaar else 394910f66f9SBram Moolenaar let syn_group_arr = g:omni_sql_precache_syntax_groups 395910f66f9SBram Moolenaar endif 39683e138c6SBram Moolenaar " For each group specified in the list, precache all 39783e138c6SBram Moolenaar " the sytnax items. 398910f66f9SBram Moolenaar if !empty(syn_group_arr) 399910f66f9SBram Moolenaar for group_name in syn_group_arr 400*f9d5ca1dSBram Moolenaar let syn_items = extend( syn_items, s:SQLCGetSyntaxList(group_name) ) 401*f9d5ca1dSBram Moolenaar endfor 402*f9d5ca1dSBram Moolenaar endif 403*f9d5ca1dSBram Moolenaar 404*f9d5ca1dSBram Moolenaar return syn_items 405*f9d5ca1dSBram Moolenaarendfunction 406*f9d5ca1dSBram Moolenaar 407*f9d5ca1dSBram Moolenaarfunction! sqlcomplete#ResetCacheSyntax(...) 408*f9d5ca1dSBram Moolenaar let syn_group_arr = [] 409*f9d5ca1dSBram Moolenaar 410*f9d5ca1dSBram Moolenaar if a:0 > 0 411*f9d5ca1dSBram Moolenaar if type(a:1) != 3 412*f9d5ca1dSBram Moolenaar call s:SQLCWarningMsg("Parameter is not a list. Example:['syntaxGroup1', 'syntaxGroup2']") 413*f9d5ca1dSBram Moolenaar return '' 414*f9d5ca1dSBram Moolenaar endif 415*f9d5ca1dSBram Moolenaar let syn_group_arr = a:1 416*f9d5ca1dSBram Moolenaar else 417*f9d5ca1dSBram Moolenaar let syn_group_arr = g:omni_sql_precache_syntax_groups 418*f9d5ca1dSBram Moolenaar endif 419*f9d5ca1dSBram Moolenaar " For each group specified in the list, precache all 420*f9d5ca1dSBram Moolenaar " the sytnax items. 421*f9d5ca1dSBram Moolenaar if !empty(syn_group_arr) 422*f9d5ca1dSBram Moolenaar for group_name in syn_group_arr 423*f9d5ca1dSBram Moolenaar let list_idx = index(s:syn_list, group_name, 0, &ignorecase) 424*f9d5ca1dSBram Moolenaar if list_idx > -1 425*f9d5ca1dSBram Moolenaar " Remove from list of groups 426*f9d5ca1dSBram Moolenaar call remove( s:syn_list, list_idx ) 427*f9d5ca1dSBram Moolenaar " Remove from list of keywords 428*f9d5ca1dSBram Moolenaar call remove( s:syn_value, list_idx ) 429*f9d5ca1dSBram Moolenaar endif 430910f66f9SBram Moolenaar endfor 431910f66f9SBram Moolenaar endif 432910f66f9SBram Moolenaarendfunction 433910f66f9SBram Moolenaar 434910f66f9SBram Moolenaarfunction! sqlcomplete#Map(type) 435910f66f9SBram Moolenaar " Tell the SQL plugin what you want to complete 436910f66f9SBram Moolenaar let b:sql_compl_type=a:type 437910f66f9SBram Moolenaar " Record previous omnifunc, if the SQL completion 438910f66f9SBram Moolenaar " is being used in conjunction with other filetype 439910f66f9SBram Moolenaar " completion plugins 440910f66f9SBram Moolenaar if &omnifunc != "" && &omnifunc != 'sqlcomplete#Complete' 441910f66f9SBram Moolenaar " Record the previous omnifunc, the plugin 442910f66f9SBram Moolenaar " will automatically set this back so that it 443910f66f9SBram Moolenaar " does not interfere with other ftplugins settings 444910f66f9SBram Moolenaar let b:sql_compl_savefunc=&omnifunc 445910f66f9SBram Moolenaar endif 446910f66f9SBram Moolenaar " Set the OMNI func for the SQL completion plugin 447910f66f9SBram Moolenaar let &omnifunc='sqlcomplete#Complete' 448910f66f9SBram Moolenaarendfunction 449910f66f9SBram Moolenaar 450f193fffdSBram Moolenaarfunction! sqlcomplete#DrillIntoTable() 451f193fffdSBram Moolenaar " If the omni popup window is visible 452f193fffdSBram Moolenaar if pumvisible() 453f193fffdSBram Moolenaar call sqlcomplete#Map('column') 454f193fffdSBram Moolenaar " C-Y, makes the currently highlighted entry active 455f193fffdSBram Moolenaar " and trigger the omni popup to be redisplayed 45600a927d6SBram Moolenaar call feedkeys("\<C-Y>\<C-X>\<C-O>", 'n') 457f193fffdSBram Moolenaar else 458f193fffdSBram Moolenaar " If the popup is not visible, simple perform the normal 45900a927d6SBram Moolenaar " key behaviour. 46000a927d6SBram Moolenaar " Must use exec since they key must be preceeded by "\" 46100a927d6SBram Moolenaar " or feedkeys will simply push each character of the string 46200a927d6SBram Moolenaar " rather than the "key press". 46300a927d6SBram Moolenaar exec 'call feedkeys("\'.g:ftplugin_sql_omni_key_right.'", "n")' 464f193fffdSBram Moolenaar endif 465f193fffdSBram Moolenaar return "" 466f193fffdSBram Moolenaarendfunction 467f193fffdSBram Moolenaar 468f193fffdSBram Moolenaarfunction! sqlcomplete#DrillOutOfColumns() 469f193fffdSBram Moolenaar " If the omni popup window is visible 470f193fffdSBram Moolenaar if pumvisible() 471f193fffdSBram Moolenaar call sqlcomplete#Map('tableReset') 472f193fffdSBram Moolenaar " Trigger the omni popup to be redisplayed 473f193fffdSBram Moolenaar call feedkeys("\<C-X>\<C-O>") 474f193fffdSBram Moolenaar else 475f193fffdSBram Moolenaar " If the popup is not visible, simple perform the normal 47600a927d6SBram Moolenaar " key behaviour. 47700a927d6SBram Moolenaar " Must use exec since they key must be preceeded by "\" 47800a927d6SBram Moolenaar " or feedkeys will simply push each character of the string 47900a927d6SBram Moolenaar " rather than the "key press". 48000a927d6SBram Moolenaar exec 'call feedkeys("\'.g:ftplugin_sql_omni_key_left.'", "n")' 481f193fffdSBram Moolenaar endif 482f193fffdSBram Moolenaar return "" 483f193fffdSBram Moolenaarendfunction 484f193fffdSBram Moolenaar 485f193fffdSBram Moolenaarfunction! s:SQLCWarningMsg(msg) 486f193fffdSBram Moolenaar echohl WarningMsg 487*f9d5ca1dSBram Moolenaar echomsg 'SQLComplete:'.a:msg 488f193fffdSBram Moolenaar echohl None 489f193fffdSBram Moolenaarendfunction 490f193fffdSBram Moolenaar 491f193fffdSBram Moolenaarfunction! s:SQLCErrorMsg(msg) 492f193fffdSBram Moolenaar echohl ErrorMsg 493*f9d5ca1dSBram Moolenaar echomsg 'SQLComplete:'.a:msg 494f193fffdSBram Moolenaar echohl None 495f193fffdSBram Moolenaarendfunction 496f193fffdSBram Moolenaar 497910f66f9SBram Moolenaarfunction! s:SQLCGetSyntaxList(syn_group) 498910f66f9SBram Moolenaar let syn_group = a:syn_group 499910f66f9SBram Moolenaar let compl_list = [] 500910f66f9SBram Moolenaar 501910f66f9SBram Moolenaar " Check if we have already cached the syntax list 502910f66f9SBram Moolenaar let list_idx = index(s:syn_list, syn_group, 0, &ignorecase) 503910f66f9SBram Moolenaar if list_idx > -1 504910f66f9SBram Moolenaar " Return previously cached value 505910f66f9SBram Moolenaar let compl_list = s:syn_value[list_idx] 506910f66f9SBram Moolenaar else 507910f66f9SBram Moolenaar " Request the syntax list items from the 508910f66f9SBram Moolenaar " syntax completion plugin 509910f66f9SBram Moolenaar if syn_group == 'syntax' 510910f66f9SBram Moolenaar " Handle this special case. This allows the user 511910f66f9SBram Moolenaar " to indicate they want all the syntax items available, 512910f66f9SBram Moolenaar " so do not specify a specific include list. 513910f66f9SBram Moolenaar let g:omni_syntax_group_include_sql = '' 514910f66f9SBram Moolenaar else 515910f66f9SBram Moolenaar " The user has specified a specific syntax group 516910f66f9SBram Moolenaar let g:omni_syntax_group_include_sql = syn_group 517910f66f9SBram Moolenaar endif 518910f66f9SBram Moolenaar let g:omni_syntax_group_exclude_sql = '' 519*f9d5ca1dSBram Moolenaar let syn_value = syntaxcomplete#OmniSyntaxList() 520910f66f9SBram Moolenaar let g:omni_syntax_group_include_sql = s:save_inc 521910f66f9SBram Moolenaar let g:omni_syntax_group_exclude_sql = s:save_exc 522910f66f9SBram Moolenaar " Cache these values for later use 523910f66f9SBram Moolenaar let s:syn_list = add( s:syn_list, syn_group ) 524910f66f9SBram Moolenaar let s:syn_value = add( s:syn_value, syn_value ) 525910f66f9SBram Moolenaar let compl_list = syn_value 526910f66f9SBram Moolenaar endif 527910f66f9SBram Moolenaar 528910f66f9SBram Moolenaar return compl_list 529910f66f9SBram Moolenaarendfunction 530910f66f9SBram Moolenaar 531e2f98b95SBram Moolenaarfunction! s:SQLCCheck4dbext() 532e2f98b95SBram Moolenaar if !exists('g:loaded_dbext') 533e2f98b95SBram Moolenaar let msg = "The dbext plugin must be loaded for dynamic SQL completion" 534e2f98b95SBram Moolenaar call s:SQLCErrorMsg(msg) 535e2f98b95SBram Moolenaar " Leave time for the user to read the error message 536e2f98b95SBram Moolenaar :sleep 2 537e2f98b95SBram Moolenaar return -1 5388c8de839SBram Moolenaar elseif g:loaded_dbext < 600 5398c8de839SBram Moolenaar let msg = "The dbext plugin must be at least version 5.30 " . 540e2f98b95SBram Moolenaar \ " for dynamic SQL completion" 541e2f98b95SBram Moolenaar call s:SQLCErrorMsg(msg) 542e2f98b95SBram Moolenaar " Leave time for the user to read the error message 543e2f98b95SBram Moolenaar :sleep 2 544e2f98b95SBram Moolenaar return -1 545e2f98b95SBram Moolenaar endif 546e2f98b95SBram Moolenaar return 1 547e2f98b95SBram Moolenaarendfunction 548e2f98b95SBram Moolenaar 549e2f98b95SBram Moolenaarfunction! s:SQLCAddAlias(table_name, table_alias, cols) 550f193fffdSBram Moolenaar " Strip off the owner if included 551f193fffdSBram Moolenaar let table_name = matchstr(a:table_name, '\%(.\{-}\.\)\?\zs\(.*\)' ) 552e2f98b95SBram Moolenaar let table_alias = a:table_alias 553e2f98b95SBram Moolenaar let cols = a:cols 554e2f98b95SBram Moolenaar 555e2f98b95SBram Moolenaar if g:omni_sql_use_tbl_alias != 'n' 556e2f98b95SBram Moolenaar if table_alias == '' 557e2f98b95SBram Moolenaar if 'da' =~? g:omni_sql_use_tbl_alias 558e2f98b95SBram Moolenaar if table_name =~ '_' 559e2f98b95SBram Moolenaar " Treat _ as separators since people often use these 560e2f98b95SBram Moolenaar " for word separators 561e2f98b95SBram Moolenaar let save_keyword = &iskeyword 562e2f98b95SBram Moolenaar setlocal iskeyword-=_ 563e2f98b95SBram Moolenaar 564e2f98b95SBram Moolenaar " Get the first letter of each word 565e2f98b95SBram Moolenaar " [[:alpha:]] is used instead of \w 566e2f98b95SBram Moolenaar " to catch extended accented characters 567e2f98b95SBram Moolenaar " 568e2f98b95SBram Moolenaar let table_alias = substitute( 569e2f98b95SBram Moolenaar \ table_name, 570e2f98b95SBram Moolenaar \ '\<[[:alpha:]]\+\>_\?', 571e2f98b95SBram Moolenaar \ '\=strpart(submatch(0), 0, 1)', 572e2f98b95SBram Moolenaar \ 'g' 573e2f98b95SBram Moolenaar \ ) 574e2f98b95SBram Moolenaar " Restore original value 575e2f98b95SBram Moolenaar let &iskeyword = save_keyword 576e2f98b95SBram Moolenaar elseif table_name =~ '\u\U' 577f193fffdSBram Moolenaar let table_alias = substitute( 578e2f98b95SBram Moolenaar \ table_name, '\(\u\)\U*', '\1', 'g') 579e2f98b95SBram Moolenaar else 580e2f98b95SBram Moolenaar let table_alias = strpart(table_name, 0, 1) 581e2f98b95SBram Moolenaar endif 582e2f98b95SBram Moolenaar endif 583e2f98b95SBram Moolenaar endif 584e2f98b95SBram Moolenaar if table_alias != '' 585e2f98b95SBram Moolenaar " Following a word character, make sure there is a . and no spaces 586e2f98b95SBram Moolenaar let table_alias = substitute(table_alias, '\w\zs\.\?\s*$', '.', '') 587e2f98b95SBram Moolenaar if 'a' =~? g:omni_sql_use_tbl_alias && a:table_alias == '' 588e2f98b95SBram Moolenaar let table_alias = inputdialog("Enter table alias:", table_alias) 589e2f98b95SBram Moolenaar endif 590e2f98b95SBram Moolenaar endif 591e2f98b95SBram Moolenaar if table_alias != '' 592e2f98b95SBram Moolenaar let cols = substitute(cols, '\<\w', table_alias.'&', 'g') 593e2f98b95SBram Moolenaar endif 594e2f98b95SBram Moolenaar endif 595e2f98b95SBram Moolenaar 596e2f98b95SBram Moolenaar return cols 597e2f98b95SBram Moolenaarendfunction 598e2f98b95SBram Moolenaar 59983e138c6SBram Moolenaarfunction! s:SQLCGetObjectOwner(object) 60083e138c6SBram Moolenaar " The owner regex matches a word at the start of the string which is 60183e138c6SBram Moolenaar " followed by a dot, but doesn't include the dot in the result. 60283e138c6SBram Moolenaar " ^ - from beginning of line 6038c8de839SBram Moolenaar " \("\|\[\)\? - ignore any quotes 60483e138c6SBram Moolenaar " \zs - start the match now 6058c8de839SBram Moolenaar " .\{-} - get owner name 60683e138c6SBram Moolenaar " \ze - end the match 6078c8de839SBram Moolenaar " \("\|\[\)\? - ignore any quotes 60883e138c6SBram Moolenaar " \. - must by followed by a . 6098c8de839SBram Moolenaar " let owner = matchstr( a:object, '^\s*\zs.*\ze\.' ) 6108c8de839SBram Moolenaar let owner = matchstr( a:object, '^\("\|\[\)\?\zs\.\{-}\ze\("\|\]\)\?\.' ) 61183e138c6SBram Moolenaar return owner 61283e138c6SBram Moolenaarendfunction 61383e138c6SBram Moolenaar 614e2f98b95SBram Moolenaarfunction! s:SQLCGetColumns(table_name, list_type) 61583e138c6SBram Moolenaar " Check if the table name was provided as part of the column name 6168c8de839SBram Moolenaar let table_name = matchstr(a:table_name, '^["\[\]a-zA-Z0-9_ ]\+\ze\.\?') 617e2f98b95SBram Moolenaar let table_cols = [] 618e2f98b95SBram Moolenaar let table_alias = '' 619e2f98b95SBram Moolenaar let move_to_top = 1 620e2f98b95SBram Moolenaar 6218c8de839SBram Moolenaar let table_name = substitute(table_name, '\s*\(.\{-}\)\s*$', '\1', 'g') 6228c8de839SBram Moolenaar 6238c8de839SBram Moolenaar " If the table name was given as: 6248c8de839SBram Moolenaar " where c. 6258c8de839SBram Moolenaar let table_name = substitute(table_name, '^\c\(WHERE\|AND\|OR\)\s\+', '', '') 626eb3593b3SBram Moolenaar if g:loaded_dbext >= 300 627e2f98b95SBram Moolenaar let saveSettingAlias = DB_listOption('use_tbl_alias') 628e2f98b95SBram Moolenaar exec 'DBSetOption use_tbl_alias=n' 629e2f98b95SBram Moolenaar endif 630e2f98b95SBram Moolenaar 6318c8de839SBram Moolenaar let table_name_stripped = substitute(table_name, '["\[\]]*', '', 'g') 6328c8de839SBram Moolenaar 633e2f98b95SBram Moolenaar " Check if we have already cached the column list for this table 634e2f98b95SBram Moolenaar " by its name 6358c8de839SBram Moolenaar let list_idx = index(s:tbl_name, table_name_stripped, 0, &ignorecase) 636e2f98b95SBram Moolenaar if list_idx > -1 6378c8de839SBram Moolenaar let table_cols = split(s:tbl_cols[list_idx], '\n') 638e2f98b95SBram Moolenaar else 639e2f98b95SBram Moolenaar " Check if we have already cached the column list for this table 640e2f98b95SBram Moolenaar " by its alias, assuming the table_name provided was actually 641e2f98b95SBram Moolenaar " the alias for the table instead 642e2f98b95SBram Moolenaar " select * 643e2f98b95SBram Moolenaar " from area a 644e2f98b95SBram Moolenaar " where a. 6458c8de839SBram Moolenaar let list_idx = index(s:tbl_alias, table_name_stripped, 0, &ignorecase) 646e2f98b95SBram Moolenaar if list_idx > -1 6478c8de839SBram Moolenaar let table_alias = table_name_stripped 648e2f98b95SBram Moolenaar let table_name = s:tbl_name[list_idx] 6498c8de839SBram Moolenaar let table_cols = split(s:tbl_cols[list_idx], '\n') 650e2f98b95SBram Moolenaar endif 651e2f98b95SBram Moolenaar endif 652e2f98b95SBram Moolenaar 653e2f98b95SBram Moolenaar " If we have not found a cached copy of the table 654e2f98b95SBram Moolenaar " And the table ends in a "." or we are looking for a column list 655e2f98b95SBram Moolenaar " if list_idx == -1 && (a:table_name =~ '\.' || b:sql_compl_type =~ 'column') 656e2f98b95SBram Moolenaar " if list_idx == -1 && (a:table_name =~ '\.' || a:list_type =~ 'csv') 657e2f98b95SBram Moolenaar if list_idx == -1 658e2f98b95SBram Moolenaar let saveY = @y 659e2f98b95SBram Moolenaar let saveSearch = @/ 660e2f98b95SBram Moolenaar let saveWScan = &wrapscan 661e2f98b95SBram Moolenaar let curline = line(".") 662e2f98b95SBram Moolenaar let curcol = col(".") 663e2f98b95SBram Moolenaar 664e2f98b95SBram Moolenaar " Do not let searchs wrap 665e2f98b95SBram Moolenaar setlocal nowrapscan 666e2f98b95SBram Moolenaar " If . was entered, look at the word just before the . 667e2f98b95SBram Moolenaar " We are looking for something like this: 668e2f98b95SBram Moolenaar " select * 669e2f98b95SBram Moolenaar " from customer c 670e2f98b95SBram Moolenaar " where c. 671e2f98b95SBram Moolenaar " So when . is pressed, we need to find 'c' 672e2f98b95SBram Moolenaar " 673e2f98b95SBram Moolenaar 674e2f98b95SBram Moolenaar " Search backwards to the beginning of the statement 675e2f98b95SBram Moolenaar " and do NOT wrap 676e2f98b95SBram Moolenaar " exec 'silent! normal! v?\<\(select\|update\|delete\|;\)\>'."\n".'"yy' 67700a927d6SBram Moolenaar exec 'silent! normal! ?\<\c\(select\|update\|delete\|;\)\>'."\n" 678e2f98b95SBram Moolenaar 679e2f98b95SBram Moolenaar " Start characterwise visual mode 680e2f98b95SBram Moolenaar " Advance right one character 681e2f98b95SBram Moolenaar " Search foward until one of the following: 682e2f98b95SBram Moolenaar " 1. Another select/update/delete statement 683e2f98b95SBram Moolenaar " 2. A ; at the end of a line (the delimiter) 684e2f98b95SBram Moolenaar " 3. The end of the file (incase no delimiter) 685e2f98b95SBram Moolenaar " Yank the visually selected text into the "y register. 68600a927d6SBram Moolenaar exec 'silent! normal! vl/\c\(\<select\>\|\<update\>\|\<delete\>\|;\s*$\|\%$\)'."\n".'"yy' 687e2f98b95SBram Moolenaar 688e2f98b95SBram Moolenaar let query = @y 689e2f98b95SBram Moolenaar let query = substitute(query, "\n", ' ', 'g') 690e2f98b95SBram Moolenaar let found = 0 691e2f98b95SBram Moolenaar 69200a927d6SBram Moolenaar " if query =~? '^\c\(select\)' 69300a927d6SBram Moolenaar if query =~? '^\(select\|update\|delete\)' 694e2f98b95SBram Moolenaar let found = 1 695e2f98b95SBram Moolenaar " \(\(\<\w\+\>\)\.\)\? - 69600a927d6SBram Moolenaar " '\c\(from\|join\|,\).\{-}' - Starting at the from clause (case insensitive) 697e2f98b95SBram Moolenaar " '\zs\(\(\<\w\+\>\)\.\)\?' - Get the owner name (optional) 698e2f98b95SBram Moolenaar " '\<\w\+\>\ze' - Get the table name 699e2f98b95SBram Moolenaar " '\s\+\<'.table_name.'\>' - Followed by the alias 700e2f98b95SBram Moolenaar " '\s*\.\@!.*' - Cannot be followed by a . 701e2f98b95SBram Moolenaar " '\(\<where\>\|$\)' - Must be followed by a WHERE clause 702e2f98b95SBram Moolenaar " '.*' - Exclude the rest of the line in the match 70300a927d6SBram Moolenaar " let table_name_new = matchstr(@y, 70400a927d6SBram Moolenaar " \ '\c\(from\|join\|,\).\{-}'. 70500a927d6SBram Moolenaar " \ '\zs\(\("\|\[\)\?.\{-}\("\|\]\)\.\)\?'. 70600a927d6SBram Moolenaar " \ '\("\|\[\)\?.\{-}\("\|\]\)\?\ze'. 70700a927d6SBram Moolenaar " \ '\s\+\%(as\s\+\)\?\<'. 70800a927d6SBram Moolenaar " \ matchstr(table_name, '.\{-}\ze\.\?$'). 70900a927d6SBram Moolenaar " \ '\>'. 71000a927d6SBram Moolenaar " \ '\s*\.\@!.*'. 71100a927d6SBram Moolenaar " \ '\(\<where\>\|$\)'. 71200a927d6SBram Moolenaar " \ '.*' 71300a927d6SBram Moolenaar " \ ) 714e2f98b95SBram Moolenaar let table_name_new = matchstr(@y, 71500a927d6SBram Moolenaar \ '\c\(\<from\>\|\<join\>\|,\)\s*'. 71600a927d6SBram Moolenaar \ '\zs\(\("\|\[\)\?\w\+\("\|\]\)\?\.\)\?'. 71700a927d6SBram Moolenaar \ '\("\|\[\)\?\w\+\("\|\]\)\?\ze'. 718f193fffdSBram Moolenaar \ '\s\+\%(as\s\+\)\?\<'. 719f193fffdSBram Moolenaar \ matchstr(table_name, '.\{-}\ze\.\?$'). 720f193fffdSBram Moolenaar \ '\>'. 721e2f98b95SBram Moolenaar \ '\s*\.\@!.*'. 722e2f98b95SBram Moolenaar \ '\(\<where\>\|$\)'. 723e2f98b95SBram Moolenaar \ '.*' 724e2f98b95SBram Moolenaar \ ) 7258c8de839SBram Moolenaar 726e2f98b95SBram Moolenaar if table_name_new != '' 727e2f98b95SBram Moolenaar let table_alias = table_name 72800a927d6SBram Moolenaar let table_name = matchstr( table_name_new, '^\(.*\.\)\?\zs.*\ze' ) 729e2f98b95SBram Moolenaar 730e2f98b95SBram Moolenaar let list_idx = index(s:tbl_name, table_name, 0, &ignorecase) 731e2f98b95SBram Moolenaar if list_idx > -1 732e2f98b95SBram Moolenaar let table_cols = split(s:tbl_cols[list_idx]) 733e2f98b95SBram Moolenaar let s:tbl_name[list_idx] = table_name 734e2f98b95SBram Moolenaar let s:tbl_alias[list_idx] = table_alias 735e2f98b95SBram Moolenaar else 736e2f98b95SBram Moolenaar let list_idx = index(s:tbl_alias, table_name, 0, &ignorecase) 737e2f98b95SBram Moolenaar if list_idx > -1 738e2f98b95SBram Moolenaar let table_cols = split(s:tbl_cols[list_idx]) 739e2f98b95SBram Moolenaar let s:tbl_name[list_idx] = table_name 740e2f98b95SBram Moolenaar let s:tbl_alias[list_idx] = table_alias 741e2f98b95SBram Moolenaar endif 742e2f98b95SBram Moolenaar endif 743e2f98b95SBram Moolenaar 744e2f98b95SBram Moolenaar endif 745e2f98b95SBram Moolenaar else 746e2f98b95SBram Moolenaar " Simply assume it is a table name provided with a . on the end 747e2f98b95SBram Moolenaar let found = 1 748e2f98b95SBram Moolenaar endif 749e2f98b95SBram Moolenaar 750e2f98b95SBram Moolenaar let @y = saveY 751e2f98b95SBram Moolenaar let @/ = saveSearch 752e2f98b95SBram Moolenaar let &wrapscan = saveWScan 753e2f98b95SBram Moolenaar 754e2f98b95SBram Moolenaar " Return to previous location 755e2f98b95SBram Moolenaar call cursor(curline, curcol) 756e2f98b95SBram Moolenaar 757e2f98b95SBram Moolenaar if found == 0 758eb3593b3SBram Moolenaar if g:loaded_dbext > 300 759e2f98b95SBram Moolenaar exec 'DBSetOption use_tbl_alias='.saveSettingAlias 760e2f98b95SBram Moolenaar endif 761e2f98b95SBram Moolenaar 762e2f98b95SBram Moolenaar " Not a SQL statement, do not display a list 763e2f98b95SBram Moolenaar return [] 764e2f98b95SBram Moolenaar endif 765e2f98b95SBram Moolenaar endif 766e2f98b95SBram Moolenaar 767e2f98b95SBram Moolenaar if empty(table_cols) 768e2f98b95SBram Moolenaar " Specify silent mode, no messages to the user (tbl, 1) 769e2f98b95SBram Moolenaar " Specify do not comma separate (tbl, 1, 1) 770e2f98b95SBram Moolenaar let table_cols_str = DB_getListColumn(table_name, 1, 1) 771e2f98b95SBram Moolenaar 772e2f98b95SBram Moolenaar if table_cols_str != "" 773e2f98b95SBram Moolenaar let s:tbl_name = add( s:tbl_name, table_name ) 774e2f98b95SBram Moolenaar let s:tbl_alias = add( s:tbl_alias, table_alias ) 775e2f98b95SBram Moolenaar let s:tbl_cols = add( s:tbl_cols, table_cols_str ) 7768c8de839SBram Moolenaar let table_cols = split(table_cols_str, '\n') 777e2f98b95SBram Moolenaar endif 778e2f98b95SBram Moolenaar 779e2f98b95SBram Moolenaar endif 780e2f98b95SBram Moolenaar 781eb3593b3SBram Moolenaar if g:loaded_dbext > 300 782e2f98b95SBram Moolenaar exec 'DBSetOption use_tbl_alias='.saveSettingAlias 783e2f98b95SBram Moolenaar endif 784e2f98b95SBram Moolenaar 785f193fffdSBram Moolenaar " If the user has asked for a comma separate list of column 786f193fffdSBram Moolenaar " values, ask the user if they want to prepend each column 787f193fffdSBram Moolenaar " with a tablename alias. 788e2f98b95SBram Moolenaar if a:list_type == 'csv' && !empty(table_cols) 789e2f98b95SBram Moolenaar let cols = join(table_cols, ', ') 790e2f98b95SBram Moolenaar let cols = s:SQLCAddAlias(table_name, table_alias, cols) 791e2f98b95SBram Moolenaar let table_cols = [cols] 792e2f98b95SBram Moolenaar endif 793e2f98b95SBram Moolenaar 794e2f98b95SBram Moolenaar return table_cols 795e2f98b95SBram Moolenaarendfunction 796