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*00a927d6SBram Moolenaar" Version:     9.0
5*00a927d6SBram Moolenaar" Last Change: 2010 Apr 20
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*00a927d6SBram Moolenaar" Version 9.0
13*00a927d6SBram Moolenaar"     This change removes some of the support for tables with spaces in their
14*00a927d6SBram Moolenaar"     names in order to simplify the regexes used to pull out query table
15*00a927d6SBram Moolenaar"     aliases for more robust table name and column name code completion.
16*00a927d6SBram Moolenaar"     Full support for "table names with spaces" can be added in again
17*00a927d6SBram Moolenaar"     after 7.3.
18*00a927d6SBram Moolenaar" Version 8.0
19*00a927d6SBram Moolenaar"     Incorrectly re-executed the g:ftplugin_sql_omni_key_right and g:ftplugin_sql_omni_key_left
20*00a927d6SBram Moolenaar"     when drilling in and out of a column list for a table.
215c73622aSBram Moolenaar" Version 7.0
225c73622aSBram Moolenaar"     Better handling of object names
235c73622aSBram Moolenaar" Version 6.0
245c73622aSBram Moolenaar"     Supports object names with spaces "my table name"
255c73622aSBram Moolenaar"
26e2f98b95SBram Moolenaar" Set completion with CTRL-X CTRL-O to autoloaded function.
27e2f98b95SBram Moolenaar" This check is in place in case this script is
28e2f98b95SBram Moolenaar" sourced directly instead of using the autoload feature.
29e2f98b95SBram Moolenaarif exists('&omnifunc')
30e2f98b95SBram Moolenaar    " Do not set the option if already set since this
31e2f98b95SBram Moolenaar    " results in an E117 warning.
32e2f98b95SBram Moolenaar    if &omnifunc == ""
33e2f98b95SBram Moolenaar        setlocal omnifunc=sqlcomplete#Complete
34e2f98b95SBram Moolenaar    endif
35e2f98b95SBram Moolenaarendif
36e2f98b95SBram Moolenaar
37e2f98b95SBram Moolenaarif exists('g:loaded_sql_completion')
38e2f98b95SBram Moolenaar    finish
39e2f98b95SBram Moolenaarendif
405c73622aSBram Moolenaarlet g:loaded_sql_completion = 70
41e2f98b95SBram Moolenaar
42e2f98b95SBram Moolenaar" Maintains filename of dictionary
43e2f98b95SBram Moolenaarlet s:sql_file_table        = ""
44e2f98b95SBram Moolenaarlet s:sql_file_procedure    = ""
45e2f98b95SBram Moolenaarlet s:sql_file_view         = ""
46e2f98b95SBram Moolenaar
47e2f98b95SBram Moolenaar" Define various arrays to be used for caching
48e2f98b95SBram Moolenaarlet s:tbl_name              = []
49e2f98b95SBram Moolenaarlet s:tbl_alias             = []
50e2f98b95SBram Moolenaarlet s:tbl_cols              = []
51e2f98b95SBram Moolenaarlet s:syn_list              = []
52e2f98b95SBram Moolenaarlet s:syn_value             = []
53e2f98b95SBram Moolenaar
54e2f98b95SBram Moolenaar" Used in conjunction with the syntaxcomplete plugin
55e2f98b95SBram Moolenaarlet s:save_inc              = ""
56e2f98b95SBram Moolenaarlet s:save_exc              = ""
57e2f98b95SBram Moolenaarif exists('g:omni_syntax_group_include_sql')
58e2f98b95SBram Moolenaar    let s:save_inc = g:omni_syntax_group_include_sql
59e2f98b95SBram Moolenaarendif
60e2f98b95SBram Moolenaarif exists('g:omni_syntax_group_exclude_sql')
61e2f98b95SBram Moolenaar    let s:save_exc = g:omni_syntax_group_exclude_sql
62e2f98b95SBram Moolenaarendif
63e2f98b95SBram Moolenaar
64e2f98b95SBram Moolenaar" Used with the column list
65e2f98b95SBram Moolenaarlet s:save_prev_table       = ""
66e2f98b95SBram Moolenaar
67e2f98b95SBram Moolenaar" Default the option to verify table alias
68e2f98b95SBram Moolenaarif !exists('g:omni_sql_use_tbl_alias')
69e2f98b95SBram Moolenaar    let g:omni_sql_use_tbl_alias = 'a'
70e2f98b95SBram Moolenaarendif
71910f66f9SBram Moolenaar" Default syntax items to precache
72910f66f9SBram Moolenaarif !exists('g:omni_sql_precache_syntax_groups')
73910f66f9SBram Moolenaar    let g:omni_sql_precache_syntax_groups = [
74910f66f9SBram Moolenaar                \ 'syntax',
75910f66f9SBram Moolenaar                \ 'sqlKeyword',
76910f66f9SBram Moolenaar                \ 'sqlFunction',
77910f66f9SBram Moolenaar                \ 'sqlOption',
78910f66f9SBram Moolenaar                \ 'sqlType',
79910f66f9SBram Moolenaar                \ 'sqlStatement'
80910f66f9SBram Moolenaar                \ ]
81910f66f9SBram Moolenaarendif
82eb3593b3SBram Moolenaar" Set ignorecase to the ftplugin standard
83eb3593b3SBram Moolenaarif !exists('g:omni_sql_ignorecase')
84eb3593b3SBram Moolenaar    let g:omni_sql_ignorecase = &ignorecase
85eb3593b3SBram Moolenaarendif
86eb3593b3SBram Moolenaar" During table completion, should the table list also
87eb3593b3SBram Moolenaar" include the owner name
88eb3593b3SBram Moolenaarif !exists('g:omni_sql_include_owner')
89eb3593b3SBram Moolenaar    let g:omni_sql_include_owner = 0
90eb3593b3SBram Moolenaar    if exists('g:loaded_dbext')
91eb3593b3SBram Moolenaar        if g:loaded_dbext >= 300
92eb3593b3SBram Moolenaar            " New to dbext 3.00, by default the table lists include the owner
93eb3593b3SBram Moolenaar            " name of the table.  This is used when determining how much of
94eb3593b3SBram Moolenaar            " whatever has been typed should be replaced as part of the
95eb3593b3SBram Moolenaar            " code replacement.
96eb3593b3SBram Moolenaar            let g:omni_sql_include_owner = 1
97eb3593b3SBram Moolenaar        endif
98eb3593b3SBram Moolenaar    endif
99eb3593b3SBram Moolenaarendif
100e2f98b95SBram Moolenaar
101e2f98b95SBram Moolenaar" This function is used for the 'omnifunc' option.
102e2f98b95SBram Moolenaarfunction! sqlcomplete#Complete(findstart, base)
103e2f98b95SBram Moolenaar
104e2f98b95SBram Moolenaar    " Default to table name completion
105e2f98b95SBram Moolenaar    let compl_type = 'table'
106e2f98b95SBram Moolenaar    " Allow maps to specify what type of object completion they want
107e2f98b95SBram Moolenaar    if exists('b:sql_compl_type')
108e2f98b95SBram Moolenaar        let compl_type = b:sql_compl_type
109e2f98b95SBram Moolenaar    endif
110e2f98b95SBram Moolenaar
111910f66f9SBram Moolenaar    " First pass through this function determines how much of the line should
112910f66f9SBram Moolenaar    " be replaced by whatever is chosen from the completion list
113e2f98b95SBram Moolenaar    if a:findstart
114e2f98b95SBram Moolenaar        " Locate the start of the item, including "."
115e2f98b95SBram Moolenaar        let line     = getline('.')
116e2f98b95SBram Moolenaar        let start    = col('.') - 1
117e2f98b95SBram Moolenaar        let lastword = -1
118f193fffdSBram Moolenaar        let begindot = 0
119f193fffdSBram Moolenaar        " Check if the first character is a ".", for column completion
120f193fffdSBram Moolenaar        if line[start - 1] == '.'
121f193fffdSBram Moolenaar            let begindot = 1
122f193fffdSBram Moolenaar        endif
123e2f98b95SBram Moolenaar        while start > 0
1245c73622aSBram Moolenaar            " Additional code was required to handle objects which
1255c73622aSBram Moolenaar            " can contain spaces like "my table name".
1265c73622aSBram Moolenaar            if line[start - 1] !~ '\(\w\|\.\)'
1275c73622aSBram Moolenaar                " If the previous character is not a period or word character
1285c73622aSBram Moolenaar                break
1295c73622aSBram Moolenaar            " elseif line[start - 1] =~ '\(\w\|\s\+\)'
1305c73622aSBram Moolenaar            "     let start -= 1
1315c73622aSBram Moolenaar            elseif line[start - 1] =~ '\w'
1325c73622aSBram Moolenaar                " If the previous character is word character continue back
133e2f98b95SBram Moolenaar                let start -= 1
134eb3593b3SBram Moolenaar            elseif line[start - 1] =~ '\.' &&
135eb3593b3SBram Moolenaar                        \ compl_type =~ 'column\|table\|view\|procedure'
1365c73622aSBram Moolenaar                " If the previous character is a period and we are completing
1375c73622aSBram Moolenaar                " an object which can be specified with a period like this:
1385c73622aSBram Moolenaar                "     table_name.column_name
1395c73622aSBram Moolenaar                "     owner_name.table_name
1405c73622aSBram Moolenaar
141eb3593b3SBram Moolenaar                " If lastword has already been set for column completion
142eb3593b3SBram Moolenaar                " break from the loop, since we do not also want to pickup
143eb3593b3SBram Moolenaar                " a table name if it was also supplied.
144f193fffdSBram Moolenaar                if lastword != -1 && compl_type == 'column'
145eb3593b3SBram Moolenaar                    break
146eb3593b3SBram Moolenaar                endif
147f193fffdSBram Moolenaar                " If column completion was specified stop at the "." if
148f193fffdSBram Moolenaar                " a . was specified, otherwise, replace all the way up
149f193fffdSBram Moolenaar                " to the owner name (if included).
150f193fffdSBram Moolenaar                if lastword == -1 && compl_type == 'column' && begindot == 1
151e2f98b95SBram Moolenaar                    let lastword = start
152e2f98b95SBram Moolenaar                endif
153eb3593b3SBram Moolenaar                " If omni_sql_include_owner = 0, do not include the table
154eb3593b3SBram Moolenaar                " name as part of the substitution, so break here
155eb3593b3SBram Moolenaar                if lastword == -1 &&
156f193fffdSBram Moolenaar                            \ compl_type =~ 'table\|view\|procedure\column_csv' &&
157eb3593b3SBram Moolenaar                            \ g:omni_sql_include_owner == 0
158eb3593b3SBram Moolenaar                    let lastword = start
159eb3593b3SBram Moolenaar                    break
160eb3593b3SBram Moolenaar                endif
161e2f98b95SBram Moolenaar                let start -= 1
162e2f98b95SBram Moolenaar            else
163e2f98b95SBram Moolenaar                break
164e2f98b95SBram Moolenaar            endif
165e2f98b95SBram Moolenaar        endwhile
166e2f98b95SBram Moolenaar
167e2f98b95SBram Moolenaar        " Return the column of the last word, which is going to be changed.
168e2f98b95SBram Moolenaar        " Remember the text that comes before it in s:prepended.
169e2f98b95SBram Moolenaar        if lastword == -1
170e2f98b95SBram Moolenaar            let s:prepended = ''
171e2f98b95SBram Moolenaar            return start
172e2f98b95SBram Moolenaar        endif
173e2f98b95SBram Moolenaar        let s:prepended = strpart(line, start, lastword - start)
174e2f98b95SBram Moolenaar        return lastword
175e2f98b95SBram Moolenaar    endif
176e2f98b95SBram Moolenaar
177910f66f9SBram Moolenaar    " Second pass through this function will determine what data to put inside
178910f66f9SBram Moolenaar    " of the completion list
179910f66f9SBram Moolenaar    " s:prepended is set by the first pass
180e2f98b95SBram Moolenaar    let base = s:prepended . a:base
181e2f98b95SBram Moolenaar
182910f66f9SBram Moolenaar    " Default the completion list to an empty list
183e2f98b95SBram Moolenaar    let compl_list = []
184e2f98b95SBram Moolenaar
185e2f98b95SBram Moolenaar    " Default to table name completion
186e2f98b95SBram Moolenaar    let compl_type = 'table'
187e2f98b95SBram Moolenaar    " Allow maps to specify what type of object completion they want
188e2f98b95SBram Moolenaar    if exists('b:sql_compl_type')
189e2f98b95SBram Moolenaar        let compl_type = b:sql_compl_type
190e2f98b95SBram Moolenaar        unlet b:sql_compl_type
191e2f98b95SBram Moolenaar    endif
192e2f98b95SBram Moolenaar
193e2f98b95SBram Moolenaar    if compl_type == 'tableReset'
194e2f98b95SBram Moolenaar        let compl_type = 'table'
195e2f98b95SBram Moolenaar        let base = ''
196e2f98b95SBram Moolenaar    endif
197e2f98b95SBram Moolenaar
198e2f98b95SBram Moolenaar    if compl_type == 'table' ||
199e2f98b95SBram Moolenaar                \ compl_type == 'procedure' ||
200e2f98b95SBram Moolenaar                \ compl_type == 'view'
201e2f98b95SBram Moolenaar
202e2f98b95SBram Moolenaar        " This type of completion relies upon the dbext.vim plugin
203e2f98b95SBram Moolenaar        if s:SQLCCheck4dbext() == -1
204e2f98b95SBram Moolenaar            return []
205e2f98b95SBram Moolenaar        endif
206e2f98b95SBram Moolenaar
20783e138c6SBram Moolenaar        " Allow the user to override the dbext plugin to specify whether
20883e138c6SBram Moolenaar        " the owner/creator should be included in the list
2098c8de839SBram Moolenaar        if g:loaded_dbext >= 300
2108c8de839SBram Moolenaar            let saveSetting = DB_listOption('dict_show_owner')
2118c8de839SBram Moolenaar            exec 'DBSetOption dict_show_owner='.(g:omni_sql_include_owner==1?'1':'0')
212e2f98b95SBram Moolenaar        endif
21383e138c6SBram Moolenaar
21483e138c6SBram Moolenaar        let compl_type_uc = substitute(compl_type, '\w\+', '\u&', '')
2155c73622aSBram Moolenaar        " Same call below, no need to do it twice
2165c73622aSBram Moolenaar        " if s:sql_file_{compl_type} == ""
2175c73622aSBram Moolenaar        "     let s:sql_file_{compl_type} = DB_getDictionaryName(compl_type_uc)
2185c73622aSBram Moolenaar        " endif
21983e138c6SBram Moolenaar        let s:sql_file_{compl_type} = DB_getDictionaryName(compl_type_uc)
220e2f98b95SBram Moolenaar        if s:sql_file_{compl_type} != ""
221e2f98b95SBram Moolenaar            if filereadable(s:sql_file_{compl_type})
222e2f98b95SBram Moolenaar                let compl_list = readfile(s:sql_file_{compl_type})
223e2f98b95SBram Moolenaar            endif
224e2f98b95SBram Moolenaar        endif
22583e138c6SBram Moolenaar
2268c8de839SBram Moolenaar        if g:loaded_dbext > 300
2278c8de839SBram Moolenaar            exec 'DBSetOption dict_show_owner='.saveSetting
2288c8de839SBram Moolenaar        endif
22983e138c6SBram Moolenaar    elseif compl_type =~? 'column'
230e2f98b95SBram Moolenaar
231e2f98b95SBram Moolenaar        " This type of completion relies upon the dbext.vim plugin
232e2f98b95SBram Moolenaar        if s:SQLCCheck4dbext() == -1
233e2f98b95SBram Moolenaar            return []
234e2f98b95SBram Moolenaar        endif
235e2f98b95SBram Moolenaar
236e2f98b95SBram Moolenaar        if base == ""
237e2f98b95SBram Moolenaar            " The last time we displayed a column list we stored
238e2f98b95SBram Moolenaar            " the table name.  If the user selects a column list
239e2f98b95SBram Moolenaar            " without a table name of alias present, assume they want
240e2f98b95SBram Moolenaar            " the previous column list displayed.
241e2f98b95SBram Moolenaar            let base = s:save_prev_table
242e2f98b95SBram Moolenaar        endif
243e2f98b95SBram Moolenaar
24483e138c6SBram Moolenaar        let owner  = ''
24583e138c6SBram Moolenaar        let column = ''
24683e138c6SBram Moolenaar
24783e138c6SBram Moolenaar        if base =~ '\.'
24883e138c6SBram Moolenaar            " Check if the owner/creator has been specified
24983e138c6SBram Moolenaar            let owner  = matchstr( base, '^\zs.*\ze\..*\..*' )
25083e138c6SBram Moolenaar            let table  = matchstr( base, '^\(.*\.\)\?\zs.*\ze\..*' )
25183e138c6SBram Moolenaar            let column = matchstr( base, '.*\.\zs.*' )
25283e138c6SBram Moolenaar
25383e138c6SBram Moolenaar            " It is pretty well impossible to determine if the user
25483e138c6SBram Moolenaar            " has entered:
25583e138c6SBram Moolenaar            "    owner.table
25683e138c6SBram Moolenaar            "    table.column_prefix
25783e138c6SBram Moolenaar            " So there are a couple of things we can do to mitigate
25883e138c6SBram Moolenaar            " this issue.
25983e138c6SBram Moolenaar            "    1.  Check if the dbext plugin has the option turned
26083e138c6SBram Moolenaar            "        on to even allow owners
26183e138c6SBram Moolenaar            "    2.  Based on 1, if the user is showing a table list
262*00a927d6SBram Moolenaar            "        and the DrillIntoTable (using <Right>) then
26383e138c6SBram Moolenaar            "        this will be owner.table.  In this case, we can
26483e138c6SBram Moolenaar            "        check to see the table.column exists in the
26583e138c6SBram Moolenaar            "        cached table list.  If it does, then we have
26683e138c6SBram Moolenaar            "        determined the user has actually chosen
26783e138c6SBram Moolenaar            "        owner.table, not table.column_prefix.
26883e138c6SBram Moolenaar            let found = -1
26983e138c6SBram Moolenaar            if g:omni_sql_include_owner == 1 && owner == ''
27083e138c6SBram Moolenaar                if filereadable(s:sql_file_table)
27183e138c6SBram Moolenaar                    let tbl_list = readfile(s:sql_file_table)
27283e138c6SBram Moolenaar                    let found    = index( tbl_list, ((table != '')?(table.'.'):'').column)
27383e138c6SBram Moolenaar                endif
27483e138c6SBram Moolenaar            endif
27583e138c6SBram Moolenaar            " If the table.column was found in the table list, we can safely assume
27683e138c6SBram Moolenaar            " the owner was not provided and shift the items appropriately.
27783e138c6SBram Moolenaar            " OR
27883e138c6SBram Moolenaar            " If the user has indicated not to use table owners at all and
27983e138c6SBram Moolenaar            " the base ends in a '.' we know they are not providing a column
28083e138c6SBram Moolenaar            " name, so we can shift the items appropriately.
28183e138c6SBram Moolenaar            if found != -1 || (g:omni_sql_include_owner == 0 && base !~ '\.$')
28283e138c6SBram Moolenaar                let owner  = table
28383e138c6SBram Moolenaar                let table  = column
28483e138c6SBram Moolenaar                let column = ''
28583e138c6SBram Moolenaar            endif
28683e138c6SBram Moolenaar        else
28783e138c6SBram Moolenaar            let table  = base
28883e138c6SBram Moolenaar        endif
28983e138c6SBram Moolenaar
29083e138c6SBram Moolenaar        " Get anything after the . and consider this the table name
29183e138c6SBram Moolenaar        " If an owner has been specified, then we must consider the
29283e138c6SBram Moolenaar        " base to be a partial column name
29383e138c6SBram Moolenaar        " let base  = matchstr( base, '^\(.*\.\)\?\zs.*' )
29483e138c6SBram Moolenaar
29583e138c6SBram Moolenaar        if table != ""
296e2f98b95SBram Moolenaar            let s:save_prev_table = base
29783e138c6SBram Moolenaar            let list_type         = ''
29883e138c6SBram Moolenaar
29983e138c6SBram Moolenaar            if compl_type == 'column_csv'
30083e138c6SBram Moolenaar                " Return one array element, with a comma separated
30183e138c6SBram Moolenaar                " list of values instead of multiple array entries
30283e138c6SBram Moolenaar                " for each column in the table.
30383e138c6SBram Moolenaar                let list_type     = 'csv'
30483e138c6SBram Moolenaar            endif
30583e138c6SBram Moolenaar
30683e138c6SBram Moolenaar            let compl_list  = s:SQLCGetColumns(table, list_type)
30783e138c6SBram Moolenaar            if column != ''
30883e138c6SBram Moolenaar                " If no column prefix has been provided and the table
30983e138c6SBram Moolenaar                " name was provided, append it to each of the items
31083e138c6SBram Moolenaar                " returned.
31183e138c6SBram Moolenaar                let compl_list = map(compl_list, "table.'.'.v:val")
31283e138c6SBram Moolenaar                if owner != ''
31383e138c6SBram Moolenaar                    " If an owner has been provided append it to each of the
31483e138c6SBram Moolenaar                    " items returned.
31583e138c6SBram Moolenaar                    let compl_list = map(compl_list, "owner.'.'.v:val")
31683e138c6SBram Moolenaar                endif
31783e138c6SBram Moolenaar            else
318e2f98b95SBram Moolenaar                let base = ''
319e2f98b95SBram Moolenaar            endif
320e2f98b95SBram Moolenaar
32183e138c6SBram Moolenaar            if compl_type == 'column_csv'
322e2f98b95SBram Moolenaar                " Join the column array into 1 single element array
323e2f98b95SBram Moolenaar                " but make the columns column separated
324e2f98b95SBram Moolenaar                let compl_list        = [join(compl_list, ', ')]
32583e138c6SBram Moolenaar            endif
326e2f98b95SBram Moolenaar        endif
327e2f98b95SBram Moolenaar    elseif compl_type == 'resetCache'
328e2f98b95SBram Moolenaar        " Reset all cached items
329e2f98b95SBram Moolenaar        let s:tbl_name  = []
330e2f98b95SBram Moolenaar        let s:tbl_alias = []
331e2f98b95SBram Moolenaar        let s:tbl_cols  = []
332e2f98b95SBram Moolenaar        let s:syn_list  = []
333e2f98b95SBram Moolenaar        let s:syn_value = []
334f193fffdSBram Moolenaar
335f193fffdSBram Moolenaar        let msg = "All SQL cached items have been removed."
336f193fffdSBram Moolenaar        call s:SQLCWarningMsg(msg)
337f193fffdSBram Moolenaar        " Leave time for the user to read the error message
338f193fffdSBram Moolenaar        :sleep 2
339e2f98b95SBram Moolenaar    else
340910f66f9SBram Moolenaar        let compl_list = s:SQLCGetSyntaxList(compl_type)
341e2f98b95SBram Moolenaar    endif
342e2f98b95SBram Moolenaar
343e2f98b95SBram Moolenaar    if base != ''
3445c73622aSBram Moolenaar        " Filter the list based on the first few characters the user entered.
3455c73622aSBram Moolenaar        " Check if the text matches at the beginning
3465c73622aSBram Moolenaar        " or
3475c73622aSBram Moolenaar        " Match to a owner.table or alias.column type match
3485c73622aSBram Moolenaar        " or
3495c73622aSBram Moolenaar        " Handle names with spaces "my table name"
3505c73622aSBram Moolenaar        let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|^\\(\\w\\+\\.\\)\\?'.base.'\\)"'
3515c73622aSBram Moolenaar        " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\)"'
3525c73622aSBram Moolenaar        " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|\\(\\.\\)\\?'.base.'\\)"'
3535c73622aSBram Moolenaar        " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|\\([^.]*\\)\\?'.base.'\\)"'
354eb3593b3SBram Moolenaar        let compl_list = filter(deepcopy(compl_list), expr)
355e2f98b95SBram Moolenaar    endif
356e2f98b95SBram Moolenaar
357910f66f9SBram Moolenaar    if exists('b:sql_compl_savefunc') && b:sql_compl_savefunc != ""
358910f66f9SBram Moolenaar        let &omnifunc = b:sql_compl_savefunc
359910f66f9SBram Moolenaar    endif
360910f66f9SBram Moolenaar
361e2f98b95SBram Moolenaar    return compl_list
362e2f98b95SBram Moolenaarendfunc
363e2f98b95SBram Moolenaar
364910f66f9SBram Moolenaarfunction! sqlcomplete#PreCacheSyntax(...)
365910f66f9SBram Moolenaar    let syn_group_arr = []
366910f66f9SBram Moolenaar    if a:0 > 0
367910f66f9SBram Moolenaar        let syn_group_arr = a:1
368910f66f9SBram Moolenaar    else
369910f66f9SBram Moolenaar        let syn_group_arr = g:omni_sql_precache_syntax_groups
370910f66f9SBram Moolenaar    endif
37183e138c6SBram Moolenaar    " For each group specified in the list, precache all
37283e138c6SBram Moolenaar    " the sytnax items.
373910f66f9SBram Moolenaar    if !empty(syn_group_arr)
374910f66f9SBram Moolenaar        for group_name in syn_group_arr
375910f66f9SBram Moolenaar            call s:SQLCGetSyntaxList(group_name)
376910f66f9SBram Moolenaar        endfor
377910f66f9SBram Moolenaar    endif
378910f66f9SBram Moolenaarendfunction
379910f66f9SBram Moolenaar
380910f66f9SBram Moolenaarfunction! sqlcomplete#Map(type)
381910f66f9SBram Moolenaar    " Tell the SQL plugin what you want to complete
382910f66f9SBram Moolenaar    let b:sql_compl_type=a:type
383910f66f9SBram Moolenaar    " Record previous omnifunc, if the SQL completion
384910f66f9SBram Moolenaar    " is being used in conjunction with other filetype
385910f66f9SBram Moolenaar    " completion plugins
386910f66f9SBram Moolenaar    if &omnifunc != "" && &omnifunc != 'sqlcomplete#Complete'
387910f66f9SBram Moolenaar        " Record the previous omnifunc, the plugin
388910f66f9SBram Moolenaar        " will automatically set this back so that it
389910f66f9SBram Moolenaar        " does not interfere with other ftplugins settings
390910f66f9SBram Moolenaar        let b:sql_compl_savefunc=&omnifunc
391910f66f9SBram Moolenaar    endif
392910f66f9SBram Moolenaar    " Set the OMNI func for the SQL completion plugin
393910f66f9SBram Moolenaar    let &omnifunc='sqlcomplete#Complete'
394910f66f9SBram Moolenaarendfunction
395910f66f9SBram Moolenaar
396f193fffdSBram Moolenaarfunction! sqlcomplete#DrillIntoTable()
397f193fffdSBram Moolenaar    " If the omni popup window is visible
398f193fffdSBram Moolenaar    if pumvisible()
399f193fffdSBram Moolenaar        call sqlcomplete#Map('column')
400f193fffdSBram Moolenaar        " C-Y, makes the currently highlighted entry active
401f193fffdSBram Moolenaar        " and trigger the omni popup to be redisplayed
402*00a927d6SBram Moolenaar        call feedkeys("\<C-Y>\<C-X>\<C-O>", 'n')
403f193fffdSBram Moolenaar    else
404f193fffdSBram Moolenaar	" If the popup is not visible, simple perform the normal
405*00a927d6SBram Moolenaar	" key behaviour.
406*00a927d6SBram Moolenaar	" Must use exec since they key must be preceeded by "\"
407*00a927d6SBram Moolenaar	" or feedkeys will simply push each character of the string
408*00a927d6SBram Moolenaar	" rather than the "key press".
409*00a927d6SBram Moolenaar        exec 'call feedkeys("\'.g:ftplugin_sql_omni_key_right.'", "n")'
410f193fffdSBram Moolenaar    endif
411f193fffdSBram Moolenaar    return ""
412f193fffdSBram Moolenaarendfunction
413f193fffdSBram Moolenaar
414f193fffdSBram Moolenaarfunction! sqlcomplete#DrillOutOfColumns()
415f193fffdSBram Moolenaar    " If the omni popup window is visible
416f193fffdSBram Moolenaar    if pumvisible()
417f193fffdSBram Moolenaar        call sqlcomplete#Map('tableReset')
418f193fffdSBram Moolenaar        " Trigger the omni popup to be redisplayed
419f193fffdSBram Moolenaar        call feedkeys("\<C-X>\<C-O>")
420f193fffdSBram Moolenaar    else
421f193fffdSBram Moolenaar	" If the popup is not visible, simple perform the normal
422*00a927d6SBram Moolenaar	" key behaviour.
423*00a927d6SBram Moolenaar	" Must use exec since they key must be preceeded by "\"
424*00a927d6SBram Moolenaar	" or feedkeys will simply push each character of the string
425*00a927d6SBram Moolenaar	" rather than the "key press".
426*00a927d6SBram Moolenaar        exec 'call feedkeys("\'.g:ftplugin_sql_omni_key_left.'", "n")'
427f193fffdSBram Moolenaar    endif
428f193fffdSBram Moolenaar    return ""
429f193fffdSBram Moolenaarendfunction
430f193fffdSBram Moolenaar
431f193fffdSBram Moolenaarfunction! s:SQLCWarningMsg(msg)
432f193fffdSBram Moolenaar    echohl WarningMsg
433f193fffdSBram Moolenaar    echomsg a:msg
434f193fffdSBram Moolenaar    echohl None
435f193fffdSBram Moolenaarendfunction
436f193fffdSBram Moolenaar
437f193fffdSBram Moolenaarfunction! s:SQLCErrorMsg(msg)
438f193fffdSBram Moolenaar    echohl ErrorMsg
439f193fffdSBram Moolenaar    echomsg a:msg
440f193fffdSBram Moolenaar    echohl None
441f193fffdSBram Moolenaarendfunction
442f193fffdSBram Moolenaar
443910f66f9SBram Moolenaarfunction! s:SQLCGetSyntaxList(syn_group)
444910f66f9SBram Moolenaar    let syn_group  = a:syn_group
445910f66f9SBram Moolenaar    let compl_list = []
446910f66f9SBram Moolenaar
447910f66f9SBram Moolenaar    " Check if we have already cached the syntax list
448910f66f9SBram Moolenaar    let list_idx = index(s:syn_list, syn_group, 0, &ignorecase)
449910f66f9SBram Moolenaar    if list_idx > -1
450910f66f9SBram Moolenaar        " Return previously cached value
451910f66f9SBram Moolenaar        let compl_list = s:syn_value[list_idx]
452910f66f9SBram Moolenaar    else
453910f66f9SBram Moolenaar        " Request the syntax list items from the
454910f66f9SBram Moolenaar        " syntax completion plugin
455910f66f9SBram Moolenaar        if syn_group == 'syntax'
456910f66f9SBram Moolenaar            " Handle this special case.  This allows the user
457910f66f9SBram Moolenaar            " to indicate they want all the syntax items available,
458910f66f9SBram Moolenaar            " so do not specify a specific include list.
459910f66f9SBram Moolenaar            let g:omni_syntax_group_include_sql = ''
460910f66f9SBram Moolenaar        else
461910f66f9SBram Moolenaar            " The user has specified a specific syntax group
462910f66f9SBram Moolenaar            let g:omni_syntax_group_include_sql = syn_group
463910f66f9SBram Moolenaar        endif
464910f66f9SBram Moolenaar        let g:omni_syntax_group_exclude_sql = ''
465910f66f9SBram Moolenaar        let syn_value                       = OmniSyntaxList()
466910f66f9SBram Moolenaar        let g:omni_syntax_group_include_sql = s:save_inc
467910f66f9SBram Moolenaar        let g:omni_syntax_group_exclude_sql = s:save_exc
468910f66f9SBram Moolenaar        " Cache these values for later use
469910f66f9SBram Moolenaar        let s:syn_list  = add( s:syn_list,  syn_group )
470910f66f9SBram Moolenaar        let s:syn_value = add( s:syn_value, syn_value )
471910f66f9SBram Moolenaar        let compl_list  = syn_value
472910f66f9SBram Moolenaar    endif
473910f66f9SBram Moolenaar
474910f66f9SBram Moolenaar    return compl_list
475910f66f9SBram Moolenaarendfunction
476910f66f9SBram Moolenaar
477e2f98b95SBram Moolenaarfunction! s:SQLCCheck4dbext()
478e2f98b95SBram Moolenaar    if !exists('g:loaded_dbext')
479e2f98b95SBram Moolenaar        let msg = "The dbext plugin must be loaded for dynamic SQL completion"
480e2f98b95SBram Moolenaar        call s:SQLCErrorMsg(msg)
481e2f98b95SBram Moolenaar        " Leave time for the user to read the error message
482e2f98b95SBram Moolenaar        :sleep 2
483e2f98b95SBram Moolenaar        return -1
4848c8de839SBram Moolenaar    elseif g:loaded_dbext < 600
4858c8de839SBram Moolenaar        let msg = "The dbext plugin must be at least version 5.30 " .
486e2f98b95SBram Moolenaar                    \ " for dynamic SQL completion"
487e2f98b95SBram Moolenaar        call s:SQLCErrorMsg(msg)
488e2f98b95SBram Moolenaar        " Leave time for the user to read the error message
489e2f98b95SBram Moolenaar        :sleep 2
490e2f98b95SBram Moolenaar        return -1
491e2f98b95SBram Moolenaar    endif
492e2f98b95SBram Moolenaar    return 1
493e2f98b95SBram Moolenaarendfunction
494e2f98b95SBram Moolenaar
495e2f98b95SBram Moolenaarfunction! s:SQLCAddAlias(table_name, table_alias, cols)
496f193fffdSBram Moolenaar    " Strip off the owner if included
497f193fffdSBram Moolenaar    let table_name  = matchstr(a:table_name, '\%(.\{-}\.\)\?\zs\(.*\)' )
498e2f98b95SBram Moolenaar    let table_alias = a:table_alias
499e2f98b95SBram Moolenaar    let cols        = a:cols
500e2f98b95SBram Moolenaar
501e2f98b95SBram Moolenaar    if g:omni_sql_use_tbl_alias != 'n'
502e2f98b95SBram Moolenaar        if table_alias == ''
503e2f98b95SBram Moolenaar            if 'da' =~? g:omni_sql_use_tbl_alias
504e2f98b95SBram Moolenaar                if table_name =~ '_'
505e2f98b95SBram Moolenaar                    " Treat _ as separators since people often use these
506e2f98b95SBram Moolenaar                    " for word separators
507e2f98b95SBram Moolenaar                    let save_keyword = &iskeyword
508e2f98b95SBram Moolenaar                    setlocal iskeyword-=_
509e2f98b95SBram Moolenaar
510e2f98b95SBram Moolenaar                    " Get the first letter of each word
511e2f98b95SBram Moolenaar                    " [[:alpha:]] is used instead of \w
512e2f98b95SBram Moolenaar                    " to catch extended accented characters
513e2f98b95SBram Moolenaar                    "
514e2f98b95SBram Moolenaar                    let table_alias = substitute(
515e2f98b95SBram Moolenaar                                \ table_name,
516e2f98b95SBram Moolenaar                                \ '\<[[:alpha:]]\+\>_\?',
517e2f98b95SBram Moolenaar                                \ '\=strpart(submatch(0), 0, 1)',
518e2f98b95SBram Moolenaar                                \ 'g'
519e2f98b95SBram Moolenaar                                \ )
520e2f98b95SBram Moolenaar                    " Restore original value
521e2f98b95SBram Moolenaar                    let &iskeyword = save_keyword
522e2f98b95SBram Moolenaar                elseif table_name =~ '\u\U'
523f193fffdSBram Moolenaar                    let table_alias = substitute(
524e2f98b95SBram Moolenaar                                \ table_name, '\(\u\)\U*', '\1', 'g')
525e2f98b95SBram Moolenaar                else
526e2f98b95SBram Moolenaar                    let table_alias = strpart(table_name, 0, 1)
527e2f98b95SBram Moolenaar                endif
528e2f98b95SBram Moolenaar            endif
529e2f98b95SBram Moolenaar        endif
530e2f98b95SBram Moolenaar        if table_alias != ''
531e2f98b95SBram Moolenaar            " Following a word character, make sure there is a . and no spaces
532e2f98b95SBram Moolenaar            let table_alias = substitute(table_alias, '\w\zs\.\?\s*$', '.', '')
533e2f98b95SBram Moolenaar            if 'a' =~? g:omni_sql_use_tbl_alias && a:table_alias == ''
534e2f98b95SBram Moolenaar                let table_alias = inputdialog("Enter table alias:", table_alias)
535e2f98b95SBram Moolenaar            endif
536e2f98b95SBram Moolenaar        endif
537e2f98b95SBram Moolenaar        if table_alias != ''
538e2f98b95SBram Moolenaar            let cols = substitute(cols, '\<\w', table_alias.'&', 'g')
539e2f98b95SBram Moolenaar        endif
540e2f98b95SBram Moolenaar    endif
541e2f98b95SBram Moolenaar
542e2f98b95SBram Moolenaar    return cols
543e2f98b95SBram Moolenaarendfunction
544e2f98b95SBram Moolenaar
54583e138c6SBram Moolenaarfunction! s:SQLCGetObjectOwner(object)
54683e138c6SBram Moolenaar    " The owner regex matches a word at the start of the string which is
54783e138c6SBram Moolenaar    " followed by a dot, but doesn't include the dot in the result.
54883e138c6SBram Moolenaar    " ^           - from beginning of line
5498c8de839SBram Moolenaar    " \("\|\[\)\? - ignore any quotes
55083e138c6SBram Moolenaar    " \zs         - start the match now
5518c8de839SBram Moolenaar    " .\{-}       - get owner name
55283e138c6SBram Moolenaar    " \ze         - end the match
5538c8de839SBram Moolenaar    " \("\|\[\)\? - ignore any quotes
55483e138c6SBram Moolenaar    " \.          - must by followed by a .
5558c8de839SBram Moolenaar    " let owner = matchstr( a:object, '^\s*\zs.*\ze\.' )
5568c8de839SBram Moolenaar    let owner = matchstr( a:object, '^\("\|\[\)\?\zs\.\{-}\ze\("\|\]\)\?\.' )
55783e138c6SBram Moolenaar    return owner
55883e138c6SBram Moolenaarendfunction
55983e138c6SBram Moolenaar
560e2f98b95SBram Moolenaarfunction! s:SQLCGetColumns(table_name, list_type)
56183e138c6SBram Moolenaar    " Check if the table name was provided as part of the column name
5628c8de839SBram Moolenaar    let table_name   = matchstr(a:table_name, '^["\[\]a-zA-Z0-9_ ]\+\ze\.\?')
563e2f98b95SBram Moolenaar    let table_cols   = []
564e2f98b95SBram Moolenaar    let table_alias  = ''
565e2f98b95SBram Moolenaar    let move_to_top  = 1
566e2f98b95SBram Moolenaar
5678c8de839SBram Moolenaar    let table_name   = substitute(table_name, '\s*\(.\{-}\)\s*$', '\1', 'g')
5688c8de839SBram Moolenaar
5698c8de839SBram Moolenaar    " If the table name was given as:
5708c8de839SBram Moolenaar    "     where c.
5718c8de839SBram Moolenaar    let table_name   = substitute(table_name, '^\c\(WHERE\|AND\|OR\)\s\+', '', '')
572eb3593b3SBram Moolenaar    if g:loaded_dbext >= 300
573e2f98b95SBram Moolenaar        let saveSettingAlias = DB_listOption('use_tbl_alias')
574e2f98b95SBram Moolenaar        exec 'DBSetOption use_tbl_alias=n'
575e2f98b95SBram Moolenaar    endif
576e2f98b95SBram Moolenaar
5778c8de839SBram Moolenaar    let table_name_stripped = substitute(table_name, '["\[\]]*', '', 'g')
5788c8de839SBram Moolenaar
579e2f98b95SBram Moolenaar    " Check if we have already cached the column list for this table
580e2f98b95SBram Moolenaar    " by its name
5818c8de839SBram Moolenaar    let list_idx = index(s:tbl_name, table_name_stripped, 0, &ignorecase)
582e2f98b95SBram Moolenaar    if list_idx > -1
5838c8de839SBram Moolenaar        let table_cols = split(s:tbl_cols[list_idx], '\n')
584e2f98b95SBram Moolenaar    else
585e2f98b95SBram Moolenaar        " Check if we have already cached the column list for this table
586e2f98b95SBram Moolenaar        " by its alias, assuming the table_name provided was actually
587e2f98b95SBram Moolenaar        " the alias for the table instead
588e2f98b95SBram Moolenaar        "     select *
589e2f98b95SBram Moolenaar        "       from area a
590e2f98b95SBram Moolenaar        "      where a.
5918c8de839SBram Moolenaar        let list_idx = index(s:tbl_alias, table_name_stripped, 0, &ignorecase)
592e2f98b95SBram Moolenaar        if list_idx > -1
5938c8de839SBram Moolenaar            let table_alias = table_name_stripped
594e2f98b95SBram Moolenaar            let table_name  = s:tbl_name[list_idx]
5958c8de839SBram Moolenaar            let table_cols  = split(s:tbl_cols[list_idx], '\n')
596e2f98b95SBram Moolenaar        endif
597e2f98b95SBram Moolenaar    endif
598e2f98b95SBram Moolenaar
599e2f98b95SBram Moolenaar    " If we have not found a cached copy of the table
600e2f98b95SBram Moolenaar    " And the table ends in a "." or we are looking for a column list
601e2f98b95SBram Moolenaar    " if list_idx == -1 && (a:table_name =~ '\.' || b:sql_compl_type =~ 'column')
602e2f98b95SBram Moolenaar    " if list_idx == -1 && (a:table_name =~ '\.' || a:list_type =~ 'csv')
603e2f98b95SBram Moolenaar    if list_idx == -1
604e2f98b95SBram Moolenaar         let saveY      = @y
605e2f98b95SBram Moolenaar         let saveSearch = @/
606e2f98b95SBram Moolenaar         let saveWScan  = &wrapscan
607e2f98b95SBram Moolenaar         let curline    = line(".")
608e2f98b95SBram Moolenaar         let curcol     = col(".")
609e2f98b95SBram Moolenaar
610e2f98b95SBram Moolenaar         " Do not let searchs wrap
611e2f98b95SBram Moolenaar         setlocal nowrapscan
612e2f98b95SBram Moolenaar         " If . was entered, look at the word just before the .
613e2f98b95SBram Moolenaar         " We are looking for something like this:
614e2f98b95SBram Moolenaar         "    select *
615e2f98b95SBram Moolenaar         "      from customer c
616e2f98b95SBram Moolenaar         "     where c.
617e2f98b95SBram Moolenaar         " So when . is pressed, we need to find 'c'
618e2f98b95SBram Moolenaar         "
619e2f98b95SBram Moolenaar
620e2f98b95SBram Moolenaar         " Search backwards to the beginning of the statement
621e2f98b95SBram Moolenaar         " and do NOT wrap
622e2f98b95SBram Moolenaar         " exec 'silent! normal! v?\<\(select\|update\|delete\|;\)\>'."\n".'"yy'
623*00a927d6SBram Moolenaar         exec 'silent! normal! ?\<\c\(select\|update\|delete\|;\)\>'."\n"
624e2f98b95SBram Moolenaar
625e2f98b95SBram Moolenaar         " Start characterwise visual mode
626e2f98b95SBram Moolenaar         " Advance right one character
627e2f98b95SBram Moolenaar         " Search foward until one of the following:
628e2f98b95SBram Moolenaar         "     1.  Another select/update/delete statement
629e2f98b95SBram Moolenaar         "     2.  A ; at the end of a line (the delimiter)
630e2f98b95SBram Moolenaar         "     3.  The end of the file (incase no delimiter)
631e2f98b95SBram Moolenaar         " Yank the visually selected text into the "y register.
632*00a927d6SBram Moolenaar         exec 'silent! normal! vl/\c\(\<select\>\|\<update\>\|\<delete\>\|;\s*$\|\%$\)'."\n".'"yy'
633e2f98b95SBram Moolenaar
634e2f98b95SBram Moolenaar         let query = @y
635e2f98b95SBram Moolenaar         let query = substitute(query, "\n", ' ', 'g')
636e2f98b95SBram Moolenaar         let found = 0
637e2f98b95SBram Moolenaar
638*00a927d6SBram Moolenaar         " if query =~? '^\c\(select\)'
639*00a927d6SBram Moolenaar         if query =~? '^\(select\|update\|delete\)'
640e2f98b95SBram Moolenaar             let found = 1
641e2f98b95SBram Moolenaar             "  \(\(\<\w\+\>\)\.\)\?   -
642*00a927d6SBram Moolenaar             " '\c\(from\|join\|,\).\{-}'  - Starting at the from clause (case insensitive)
643e2f98b95SBram Moolenaar             " '\zs\(\(\<\w\+\>\)\.\)\?' - Get the owner name (optional)
644e2f98b95SBram Moolenaar             " '\<\w\+\>\ze' - Get the table name
645e2f98b95SBram Moolenaar             " '\s\+\<'.table_name.'\>' - Followed by the alias
646e2f98b95SBram Moolenaar             " '\s*\.\@!.*'  - Cannot be followed by a .
647e2f98b95SBram Moolenaar             " '\(\<where\>\|$\)' - Must be followed by a WHERE clause
648e2f98b95SBram Moolenaar             " '.*'  - Exclude the rest of the line in the match
649*00a927d6SBram Moolenaar             " let table_name_new = matchstr(@y,
650*00a927d6SBram Moolenaar             "             \ '\c\(from\|join\|,\).\{-}'.
651*00a927d6SBram Moolenaar             "             \ '\zs\(\("\|\[\)\?.\{-}\("\|\]\)\.\)\?'.
652*00a927d6SBram Moolenaar             "             \ '\("\|\[\)\?.\{-}\("\|\]\)\?\ze'.
653*00a927d6SBram Moolenaar             "             \ '\s\+\%(as\s\+\)\?\<'.
654*00a927d6SBram Moolenaar             "             \ matchstr(table_name, '.\{-}\ze\.\?$').
655*00a927d6SBram Moolenaar             "             \ '\>'.
656*00a927d6SBram Moolenaar             "             \ '\s*\.\@!.*'.
657*00a927d6SBram Moolenaar             "             \ '\(\<where\>\|$\)'.
658*00a927d6SBram Moolenaar             "             \ '.*'
659*00a927d6SBram Moolenaar             "             \ )
660e2f98b95SBram Moolenaar             let table_name_new = matchstr(@y,
661*00a927d6SBram Moolenaar                         \ '\c\(\<from\>\|\<join\>\|,\)\s*'.
662*00a927d6SBram Moolenaar                         \ '\zs\(\("\|\[\)\?\w\+\("\|\]\)\?\.\)\?'.
663*00a927d6SBram Moolenaar                         \ '\("\|\[\)\?\w\+\("\|\]\)\?\ze'.
664f193fffdSBram Moolenaar                         \ '\s\+\%(as\s\+\)\?\<'.
665f193fffdSBram Moolenaar                         \ matchstr(table_name, '.\{-}\ze\.\?$').
666f193fffdSBram Moolenaar                         \ '\>'.
667e2f98b95SBram Moolenaar                         \ '\s*\.\@!.*'.
668e2f98b95SBram Moolenaar                         \ '\(\<where\>\|$\)'.
669e2f98b95SBram Moolenaar                         \ '.*'
670e2f98b95SBram Moolenaar                         \ )
6718c8de839SBram Moolenaar
672e2f98b95SBram Moolenaar             if table_name_new != ''
673e2f98b95SBram Moolenaar                 let table_alias = table_name
674*00a927d6SBram Moolenaar                 let table_name  = matchstr( table_name_new, '^\(.*\.\)\?\zs.*\ze' )
675e2f98b95SBram Moolenaar
676e2f98b95SBram Moolenaar                 let list_idx = index(s:tbl_name, table_name, 0, &ignorecase)
677e2f98b95SBram Moolenaar                 if list_idx > -1
678e2f98b95SBram Moolenaar                     let table_cols  = split(s:tbl_cols[list_idx])
679e2f98b95SBram Moolenaar                     let s:tbl_name[list_idx]  = table_name
680e2f98b95SBram Moolenaar                     let s:tbl_alias[list_idx] = table_alias
681e2f98b95SBram Moolenaar                 else
682e2f98b95SBram Moolenaar                     let list_idx = index(s:tbl_alias, table_name, 0, &ignorecase)
683e2f98b95SBram Moolenaar                     if list_idx > -1
684e2f98b95SBram Moolenaar                         let table_cols = split(s:tbl_cols[list_idx])
685e2f98b95SBram Moolenaar                         let s:tbl_name[list_idx]  = table_name
686e2f98b95SBram Moolenaar                         let s:tbl_alias[list_idx] = table_alias
687e2f98b95SBram Moolenaar                     endif
688e2f98b95SBram Moolenaar                 endif
689e2f98b95SBram Moolenaar
690e2f98b95SBram Moolenaar             endif
691e2f98b95SBram Moolenaar         else
692e2f98b95SBram Moolenaar             " Simply assume it is a table name provided with a . on the end
693e2f98b95SBram Moolenaar             let found = 1
694e2f98b95SBram Moolenaar         endif
695e2f98b95SBram Moolenaar
696e2f98b95SBram Moolenaar         let @y        = saveY
697e2f98b95SBram Moolenaar         let @/        = saveSearch
698e2f98b95SBram Moolenaar         let &wrapscan = saveWScan
699e2f98b95SBram Moolenaar
700e2f98b95SBram Moolenaar         " Return to previous location
701e2f98b95SBram Moolenaar         call cursor(curline, curcol)
702e2f98b95SBram Moolenaar
703e2f98b95SBram Moolenaar         if found == 0
704eb3593b3SBram Moolenaar             if g:loaded_dbext > 300
705e2f98b95SBram Moolenaar                 exec 'DBSetOption use_tbl_alias='.saveSettingAlias
706e2f98b95SBram Moolenaar             endif
707e2f98b95SBram Moolenaar
708e2f98b95SBram Moolenaar             " Not a SQL statement, do not display a list
709e2f98b95SBram Moolenaar             return []
710e2f98b95SBram Moolenaar         endif
711e2f98b95SBram Moolenaar    endif
712e2f98b95SBram Moolenaar
713e2f98b95SBram Moolenaar    if empty(table_cols)
714e2f98b95SBram Moolenaar        " Specify silent mode, no messages to the user (tbl, 1)
715e2f98b95SBram Moolenaar        " Specify do not comma separate (tbl, 1, 1)
716e2f98b95SBram Moolenaar        let table_cols_str = DB_getListColumn(table_name, 1, 1)
717e2f98b95SBram Moolenaar
718e2f98b95SBram Moolenaar        if table_cols_str != ""
719e2f98b95SBram Moolenaar            let s:tbl_name  = add( s:tbl_name,  table_name )
720e2f98b95SBram Moolenaar            let s:tbl_alias = add( s:tbl_alias, table_alias )
721e2f98b95SBram Moolenaar            let s:tbl_cols  = add( s:tbl_cols,  table_cols_str )
7228c8de839SBram Moolenaar            let table_cols  = split(table_cols_str, '\n')
723e2f98b95SBram Moolenaar        endif
724e2f98b95SBram Moolenaar
725e2f98b95SBram Moolenaar    endif
726e2f98b95SBram Moolenaar
727eb3593b3SBram Moolenaar    if g:loaded_dbext > 300
728e2f98b95SBram Moolenaar        exec 'DBSetOption use_tbl_alias='.saveSettingAlias
729e2f98b95SBram Moolenaar    endif
730e2f98b95SBram Moolenaar
731f193fffdSBram Moolenaar    " If the user has asked for a comma separate list of column
732f193fffdSBram Moolenaar    " values, ask the user if they want to prepend each column
733f193fffdSBram Moolenaar    " with a tablename alias.
734e2f98b95SBram Moolenaar    if a:list_type == 'csv' && !empty(table_cols)
735e2f98b95SBram Moolenaar        let cols       = join(table_cols, ', ')
736e2f98b95SBram Moolenaar        let cols       = s:SQLCAddAlias(table_name, table_alias, cols)
737e2f98b95SBram Moolenaar        let table_cols = [cols]
738e2f98b95SBram Moolenaar    endif
739e2f98b95SBram Moolenaar
740e2f98b95SBram Moolenaar    return table_cols
741e2f98b95SBram Moolenaarendfunction
742