Mercurial > vim
annotate runtime/autoload/sqlcomplete.vim @ 33776:9503dc55b5ed v9.0.2108
patch 9.0.2108: [security]: overflow with count for :s command
Commit: https://github.com/vim/vim/commit/ac63787734fda2e294e477af52b3bd601517fa78
Author: Christian Brabandt <cb@256bit.org>
Date: Tue Nov 14 20:45:48 2023 +0100
patch 9.0.2108: [security]: overflow with count for :s command
Problem: [security]: overflow with count for :s command
Solution: Abort the :s command if the count is too large
If the count after the :s command is larger than what fits into a
(signed) long variable, abort with e_value_too_large.
Adds a test with INT_MAX as count and verify it correctly fails.
It seems the return value on Windows using mingw compiler wraps around,
so the initial test using :s/./b/9999999999999999999999999990 doesn't
fail there, since the count is wrapping around several times and finally
is no longer larger than 2147483647. So let's just use 2147483647 in the
test, which hopefully will always cause a failure
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 16 Nov 2023 22:15:10 +0100 |
parents | 11b656e74444 |
children |
rev | line source |
---|---|
844 | 1 " Vim OMNI completion script for SQL |
818 | 2 " Language: SQL |
2034 | 3 " Maintainer: David Fishburn <dfishburn dot vim at gmail dot com> |
7876
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
4 " Version: 16.0 |
12756
3b26420fc639
Long overdue runtime update.
Christian Brabandt <cb@256bit.org>
parents:
7876
diff
changeset
|
5 " Last Change: 2017 Oct 15 |
3996 | 6 " Homepage: http://www.vim.org/scripts/script.php?script_id=1572 |
844 | 7 " Usage: For detailed help |
3371 | 8 " ":help sql.txt" |
9 " or ":help ft-sql-omni" | |
844 | 10 " or read $VIMRUNTIME/doc/sql.txt |
818 | 11 |
2034 | 12 " History |
3996 | 13 " |
4437 | 14 " TODO |
15 " - Jonas Enberg - if no table is found when using column completion | |
16 " look backwards to a FROM clause and find the first table | |
17 " and complete it. | |
18 " | |
7876
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
19 " Version 16.0 (Dec 2015) |
25773 | 20 " - NF: If resetting the cache and table, procedure or view completion |
7876
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
21 " had been used via dbext, have dbext delete or recreate the |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
22 " dictionary so that new objects are picked up for the |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
23 " next completion. |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
24 " |
4437 | 25 " Version 15.0 (May 2013) |
26 " - NF: Changed the SQL precached syntax items, omni_sql_precache_syntax_groups, | |
27 " to use regular expressions to pick up extended syntax group names. | |
28 " This requires an updated SyntaxComplete plugin version 13.0. | |
29 " If the required versions have not been installed, previous | |
30 " behaviour will not be impacted. | |
31 " | |
3996 | 32 " Version 14.0 (Dec 2012) |
33 " - BF: Added check for cpo | |
34 " | |
35 " Version 13.0 (Dec 2012) | |
36 " - NF: When completing column lists or drilling into a table | |
37 " and g:omni_sql_include_owner is enabled, the | |
38 " only the table name would be replaced with the column | |
39 " list instead of the table name and owner (if specified). | |
40 " - NF: When completing column lists using table aliases | |
41 " and g:omni_sql_include_owner is enabled, account | |
42 " for the owner name when looking up the table | |
43 " list instead of the table name and owner (if specified). | |
44 " - BF: When completing column lists or drilling into a table | |
45 " and g:omni_sql_include_owner is enabled, the | |
46 " column list could often not be found for the table. | |
47 " - BF: When OMNI popped up, possibly the wrong word | |
48 " would be replaced for column and column list options. | |
49 " | |
50 " Version 12.0 (Feb 2012) | |
3371 | 51 " - Partial column name completion did not work when a table |
52 " name or table alias was provided (Jonas Enberg). | |
53 " - Improved the handling of column completion. First we match any | |
54 " columns from a previous completion. If not matches are found, we | |
3996 | 55 " consider the partial name to be a table or table alias for the |
3371 | 56 " query and attempt to match on it. |
57 " | |
3996 | 58 " Version 11.0 (Jan 2012) |
3371 | 59 " Added g:omni_sql_default_compl_type variable |
60 " - You can specify which type of completion to default to | |
61 " when pressing <C-X><C-O>. The entire list of available | |
62 " choices can be found in the calls to sqlcomplete#Map in: | |
63 " ftplugin/sql.vim | |
64 " | |
2458 | 65 " Version 10.0 |
3371 | 66 " Updated PreCacheSyntax() |
2458 | 67 " - Now returns a List of the syntax items it finds. |
68 " This allows other plugins / scripts to use this list for their own | |
69 " purposes. In this case XPTemplate can use them for a Choose list. | |
70 " - Verifies the parameters are the correct type and displays a | |
71 " warning if not. | |
72 " - Verifies the parameters are the correct type and displays a | |
73 " warning if not. | |
3371 | 74 " Updated SQLCWarningMsg() |
2458 | 75 " - Prepends warning message with SQLComplete so you know who issued |
76 " the warning. | |
3371 | 77 " Updated SQLCErrorMsg() |
2458 | 78 " - Prepends error message with SQLComplete so you know who issued |
79 " the error. | |
3371 | 80 " |
3996 | 81 " Version 9.0 (May 2010) |
2152 | 82 " This change removes some of the support for tables with spaces in their |
3371 | 83 " names in order to simplify the regexes used to pull out query table |
2152 | 84 " aliases for more robust table name and column name code completion. |
85 " Full support for "table names with spaces" can be added in again | |
86 " after 7.3. | |
2458 | 87 " |
2152 | 88 " Version 8.0 |
3371 | 89 " Incorrectly re-executed the g:ftplugin_sql_omni_key_right and g:ftplugin_sql_omni_key_left |
2152 | 90 " when drilling in and out of a column list for a table. |
2458 | 91 " |
3996 | 92 " Version 7.0 (Jan 2010) |
2034 | 93 " Better handling of object names |
2458 | 94 " |
3996 | 95 " Version 6.0 (Apr 2008) |
2034 | 96 " Supports object names with spaces "my table name" |
97 " | |
818 | 98 " Set completion with CTRL-X CTRL-O to autoloaded function. |
99 " This check is in place in case this script is | |
3371 | 100 " sourced directly instead of using the autoload feature. |
818 | 101 if exists('&omnifunc') |
102 " Do not set the option if already set since this | |
103 " results in an E117 warning. | |
104 if &omnifunc == "" | |
105 setlocal omnifunc=sqlcomplete#Complete | |
106 endif | |
107 endif | |
108 | |
109 if exists('g:loaded_sql_completion') | |
3371 | 110 finish |
818 | 111 endif |
7876
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
112 let g:loaded_sql_completion = 160 |
3996 | 113 let s:keepcpo= &cpo |
114 set cpo&vim | |
818 | 115 |
116 " Maintains filename of dictionary | |
819 | 117 let s:sql_file_table = "" |
118 let s:sql_file_procedure = "" | |
119 let s:sql_file_view = "" | |
818 | 120 |
121 " Define various arrays to be used for caching | |
819 | 122 let s:tbl_name = [] |
123 let s:tbl_alias = [] | |
124 let s:tbl_cols = [] | |
125 let s:syn_list = [] | |
126 let s:syn_value = [] | |
3371 | 127 |
818 | 128 " Used in conjunction with the syntaxcomplete plugin |
819 | 129 let s:save_inc = "" |
130 let s:save_exc = "" | |
4437 | 131 if !exists('g:omni_syntax_group_include_sql') |
132 let g:omni_syntax_group_include_sql = '' | |
818 | 133 endif |
4437 | 134 if !exists('g:omni_syntax_group_exclude_sql') |
135 let g:omni_syntax_group_exclude_sql = '' | |
818 | 136 endif |
4437 | 137 let s:save_inc = g:omni_syntax_group_include_sql |
138 let s:save_exc = g:omni_syntax_group_exclude_sql | |
3371 | 139 |
818 | 140 " Used with the column list |
819 | 141 let s:save_prev_table = "" |
818 | 142 |
143 " Default the option to verify table alias | |
144 if !exists('g:omni_sql_use_tbl_alias') | |
145 let g:omni_sql_use_tbl_alias = 'a' | |
146 endif | |
819 | 147 " Default syntax items to precache |
148 if !exists('g:omni_sql_precache_syntax_groups') | |
149 let g:omni_sql_precache_syntax_groups = [ | |
4437 | 150 \ 'syntax\w*', |
151 \ 'sqlKeyword\w*', | |
152 \ 'sqlFunction\w*', | |
153 \ 'sqlOption\w*', | |
154 \ 'sqlType\w*', | |
155 \ 'sqlStatement\w*' | |
819 | 156 \ ] |
157 endif | |
840 | 158 " Set ignorecase to the ftplugin standard |
159 if !exists('g:omni_sql_ignorecase') | |
160 let g:omni_sql_ignorecase = &ignorecase | |
161 endif | |
162 " During table completion, should the table list also | |
163 " include the owner name | |
164 if !exists('g:omni_sql_include_owner') | |
165 let g:omni_sql_include_owner = 0 | |
166 if exists('g:loaded_dbext') | |
167 if g:loaded_dbext >= 300 | |
168 " New to dbext 3.00, by default the table lists include the owner | |
169 " name of the table. This is used when determining how much of | |
3371 | 170 " whatever has been typed should be replaced as part of the |
840 | 171 " code replacement. |
172 let g:omni_sql_include_owner = 1 | |
173 endif | |
174 endif | |
175 endif | |
3371 | 176 " Default type of completion used when <C-X><C-O> is pressed |
177 if !exists('g:omni_sql_default_compl_type') | |
178 let g:omni_sql_default_compl_type = 'table' | |
179 endif | |
818 | 180 |
181 " This function is used for the 'omnifunc' option. | |
3996 | 182 " It is called twice by omni and it is responsible |
183 " for returning the completion list of items. | |
184 " But it must also determine context of what to complete | |
185 " and what to "replace" with the completion. | |
186 " The a:base, is replaced directly with what the user | |
187 " chooses from the choices. | |
188 " The s:prepend provides context for the completion. | |
818 | 189 function! sqlcomplete#Complete(findstart, base) |
190 | |
191 " Default to table name completion | |
192 let compl_type = 'table' | |
193 " Allow maps to specify what type of object completion they want | |
194 if exists('b:sql_compl_type') | |
195 let compl_type = b:sql_compl_type | |
196 endif | |
3996 | 197 let begindot = 0 |
818 | 198 |
819 | 199 " First pass through this function determines how much of the line should |
200 " be replaced by whatever is chosen from the completion list | |
818 | 201 if a:findstart |
202 " Locate the start of the item, including "." | |
844 | 203 let line = getline('.') |
204 let start = col('.') - 1 | |
818 | 205 let lastword = -1 |
844 | 206 " Check if the first character is a ".", for column completion |
207 if line[start - 1] == '.' | |
208 let begindot = 1 | |
209 endif | |
818 | 210 while start > 0 |
3371 | 211 " Additional code was required to handle objects which |
2034 | 212 " can contain spaces like "my table name". |
213 if line[start - 1] !~ '\(\w\|\.\)' | |
214 " If the previous character is not a period or word character | |
215 break | |
216 " elseif line[start - 1] =~ '\(\w\|\s\+\)' | |
217 " let start -= 1 | |
218 elseif line[start - 1] =~ '\w' | |
219 " If the previous character is word character continue back | |
818 | 220 let start -= 1 |
3371 | 221 elseif line[start - 1] =~ '\.' && |
840 | 222 \ compl_type =~ 'column\|table\|view\|procedure' |
2034 | 223 " If the previous character is a period and we are completing |
224 " an object which can be specified with a period like this: | |
225 " table_name.column_name | |
226 " owner_name.table_name | |
227 | |
840 | 228 " If lastword has already been set for column completion |
229 " break from the loop, since we do not also want to pickup | |
230 " a table name if it was also supplied. | |
3996 | 231 " Unless g:omni_sql_include_owner == 1, then we can |
232 " include the ownername. | |
3371 | 233 if lastword != -1 && compl_type == 'column' |
3996 | 234 \ && g:omni_sql_include_owner == 0 |
840 | 235 break |
236 endif | |
844 | 237 " If column completion was specified stop at the "." if |
238 " a . was specified, otherwise, replace all the way up | |
239 " to the owner name (if included). | |
240 if lastword == -1 && compl_type == 'column' && begindot == 1 | |
818 | 241 let lastword = start |
242 endif | |
840 | 243 " If omni_sql_include_owner = 0, do not include the table |
244 " name as part of the substitution, so break here | |
3371 | 245 if lastword == -1 && |
3996 | 246 \ compl_type =~ '\<\(table\|view\|procedure\|column\|column_csv\)\>' && |
840 | 247 \ g:omni_sql_include_owner == 0 |
248 let lastword = start | |
249 break | |
250 endif | |
818 | 251 let start -= 1 |
252 else | |
253 break | |
254 endif | |
255 endwhile | |
256 | |
257 " Return the column of the last word, which is going to be changed. | |
258 " Remember the text that comes before it in s:prepended. | |
259 if lastword == -1 | |
260 let s:prepended = '' | |
261 return start | |
262 endif | |
263 let s:prepended = strpart(line, start, lastword - start) | |
264 return lastword | |
265 endif | |
266 | |
819 | 267 " Second pass through this function will determine what data to put inside |
268 " of the completion list | |
269 " s:prepended is set by the first pass | |
818 | 270 let base = s:prepended . a:base |
271 | |
819 | 272 " Default the completion list to an empty list |
818 | 273 let compl_list = [] |
274 | |
275 " Default to table name completion | |
3371 | 276 let compl_type = g:omni_sql_default_compl_type |
818 | 277 " Allow maps to specify what type of object completion they want |
278 if exists('b:sql_compl_type') | |
279 let compl_type = b:sql_compl_type | |
280 unlet b:sql_compl_type | |
281 endif | |
282 | |
283 if compl_type == 'tableReset' | |
284 let compl_type = 'table' | |
285 let base = '' | |
286 endif | |
287 | |
288 if compl_type == 'table' || | |
289 \ compl_type == 'procedure' || | |
3371 | 290 \ compl_type == 'view' |
818 | 291 |
292 " This type of completion relies upon the dbext.vim plugin | |
293 if s:SQLCCheck4dbext() == -1 | |
294 return [] | |
295 endif | |
296 | |
1126 | 297 " Allow the user to override the dbext plugin to specify whether |
298 " the owner/creator should be included in the list | |
1624 | 299 if g:loaded_dbext >= 300 |
300 let saveSetting = DB_listOption('dict_show_owner') | |
301 exec 'DBSetOption dict_show_owner='.(g:omni_sql_include_owner==1?'1':'0') | |
1126 | 302 endif |
303 | |
304 let compl_type_uc = substitute(compl_type, '\w\+', '\u&', '') | |
2034 | 305 " Same call below, no need to do it twice |
306 " if s:sql_file_{compl_type} == "" | |
307 " let s:sql_file_{compl_type} = DB_getDictionaryName(compl_type_uc) | |
308 " endif | |
1126 | 309 let s:sql_file_{compl_type} = DB_getDictionaryName(compl_type_uc) |
818 | 310 if s:sql_file_{compl_type} != "" |
311 if filereadable(s:sql_file_{compl_type}) | |
312 let compl_list = readfile(s:sql_file_{compl_type}) | |
313 endif | |
314 endif | |
1126 | 315 |
1624 | 316 if g:loaded_dbext > 300 |
317 exec 'DBSetOption dict_show_owner='.saveSetting | |
318 endif | |
1126 | 319 elseif compl_type =~? 'column' |
818 | 320 |
321 " This type of completion relies upon the dbext.vim plugin | |
322 if s:SQLCCheck4dbext() == -1 | |
323 return [] | |
324 endif | |
325 | |
326 if base == "" | |
327 " The last time we displayed a column list we stored | |
3371 | 328 " the table name. If the user selects a column list |
818 | 329 " without a table name of alias present, assume they want |
330 " the previous column list displayed. | |
331 let base = s:save_prev_table | |
332 endif | |
333 | |
1126 | 334 let owner = '' |
335 let column = '' | |
336 | |
337 if base =~ '\.' | |
338 " Check if the owner/creator has been specified | |
339 let owner = matchstr( base, '^\zs.*\ze\..*\..*' ) | |
340 let table = matchstr( base, '^\(.*\.\)\?\zs.*\ze\..*' ) | |
341 let column = matchstr( base, '.*\.\zs.*' ) | |
818 | 342 |
3996 | 343 if g:omni_sql_include_owner == 1 && owner == '' && table != '' && column != '' |
344 let owner = table | |
345 let table = column | |
346 let column = '' | |
347 endif | |
348 | |
1126 | 349 " It is pretty well impossible to determine if the user |
350 " has entered: | |
351 " owner.table | |
352 " table.column_prefix | |
3371 | 353 " So there are a couple of things we can do to mitigate |
1126 | 354 " this issue. |
355 " 1. Check if the dbext plugin has the option turned | |
356 " on to even allow owners | |
357 " 2. Based on 1, if the user is showing a table list | |
3371 | 358 " and the DrillIntoTable (using <Right>) then |
1126 | 359 " this will be owner.table. In this case, we can |
3371 | 360 " check to see the table.column exists in the |
1126 | 361 " cached table list. If it does, then we have |
3371 | 362 " determined the user has actually chosen |
1126 | 363 " owner.table, not table.column_prefix. |
364 let found = -1 | |
365 if g:omni_sql_include_owner == 1 && owner == '' | |
366 if filereadable(s:sql_file_table) | |
367 let tbl_list = readfile(s:sql_file_table) | |
368 let found = index( tbl_list, ((table != '')?(table.'.'):'').column) | |
369 endif | |
370 endif | |
371 " If the table.column was found in the table list, we can safely assume | |
372 " the owner was not provided and shift the items appropriately. | |
373 " OR | |
374 " If the user has indicated not to use table owners at all and | |
375 " the base ends in a '.' we know they are not providing a column | |
376 " name, so we can shift the items appropriately. | |
3371 | 377 " if found != -1 || (g:omni_sql_include_owner == 0 && base !~ '\.$') |
378 " let owner = table | |
379 " let table = column | |
380 " let column = '' | |
381 " endif | |
382 else | |
383 " If no "." was provided and the user asked for | |
384 " column level completion, first attempt the match | |
385 " on any previous column lists. If the user asked | |
386 " for a list of columns comma separated, continue as usual. | |
387 if compl_type == 'column' && s:save_prev_table != '' | |
388 " The last time we displayed a column list we stored | |
389 " the table name. If the user selects a column list | |
390 " without a table name of alias present, assume they want | |
391 " the previous column list displayed. | |
392 let table = s:save_prev_table | |
393 let list_type = '' | |
394 | |
395 let compl_list = s:SQLCGetColumns(table, list_type) | |
396 if ! empty(compl_list) | |
397 " If no column prefix has been provided and the table | |
398 " name was provided, append it to each of the items | |
399 " returned. | |
400 let compl_list = filter(deepcopy(compl_list), 'v:val=~"^'.base.'"' ) | |
401 | |
402 " If not empty, we have a match on columns | |
403 " return the list | |
404 if ! empty(compl_list) | |
405 return compl_list | |
406 endif | |
407 endif | |
1126 | 408 endif |
3371 | 409 " Since no columns were found to match the base supplied |
410 " assume the user is trying to complete the column list | |
411 " for a table (and or an alias to a table). | |
1126 | 412 let table = base |
818 | 413 endif |
414 | |
1126 | 415 " Get anything after the . and consider this the table name |
3371 | 416 " If an owner has been specified, then we must consider the |
1126 | 417 " base to be a partial column name |
418 " let base = matchstr( base, '^\(.*\.\)\?\zs.*' ) | |
419 | |
420 if table != "" | |
421 let s:save_prev_table = base | |
422 let list_type = '' | |
423 | |
424 if compl_type == 'column_csv' | |
425 " Return one array element, with a comma separated | |
426 " list of values instead of multiple array entries | |
427 " for each column in the table. | |
428 let list_type = 'csv' | |
429 endif | |
818 | 430 |
3996 | 431 " If we are including the OWNER for the objects, then for |
432 " table completion, if we have it, it should be included | |
433 " as there can be the same table names in a database yet | |
434 " with different owner names. | |
435 if g:omni_sql_include_owner == 1 && owner != '' && table != '' | |
436 let compl_list = s:SQLCGetColumns(owner.'.'.table, list_type) | |
437 else | |
438 let compl_list = s:SQLCGetColumns(table, list_type) | |
439 endif | |
440 | |
1126 | 441 if column != '' |
442 " If no column prefix has been provided and the table | |
443 " name was provided, append it to each of the items | |
444 " returned. | |
3371 | 445 let compl_list = map(compl_list, 'table.".".v:val') |
1126 | 446 if owner != '' |
447 " If an owner has been provided append it to each of the | |
448 " items returned. | |
3371 | 449 let compl_list = map(compl_list, 'owner.".".v:val') |
1126 | 450 endif |
451 else | |
452 let base = '' | |
453 endif | |
454 | |
455 if compl_type == 'column_csv' | |
456 " Join the column array into 1 single element array | |
457 " but make the columns column separated | |
458 let compl_list = [join(compl_list, ', ')] | |
459 endif | |
818 | 460 endif |
461 elseif compl_type == 'resetCache' | |
462 " Reset all cached items | |
3996 | 463 let s:tbl_name = [] |
464 let s:tbl_alias = [] | |
465 let s:tbl_cols = [] | |
466 let s:syn_list = [] | |
467 let s:syn_value = [] | |
7876
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
468 |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
469 if s:sql_file_table != "" |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
470 if g:loaded_dbext >= 2300 |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
471 call DB_DictionaryDelete("table") |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
472 else |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
473 DBCompleteTables! |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
474 endif |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
475 endif |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
476 if s:sql_file_procedure != "" |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
477 if g:loaded_dbext >= 2300 |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
478 call DB_DictionaryDelete("procedure") |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
479 else |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
480 DBCompleteProcedures! |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
481 endif |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
482 endif |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
483 if s:sql_file_view != "" |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
484 if g:loaded_dbext >= 2300 |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
485 call DB_DictionaryDelete("view") |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
486 else |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
487 DBCompleteViews! |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
488 endif |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
489 endif |
93f747af7b58
commit https://github.com/vim/vim/commit/5e9b2fa9bb0e6061cf18457c173cd141a5dc9c92
Christian Brabandt <cb@256bit.org>
parents:
4437
diff
changeset
|
490 |
3996 | 491 let s:sql_file_table = "" |
492 let s:sql_file_procedure = "" | |
493 let s:sql_file_view = "" | |
844 | 494 |
495 let msg = "All SQL cached items have been removed." | |
496 call s:SQLCWarningMsg(msg) | |
497 " Leave time for the user to read the error message | |
498 :sleep 2 | |
818 | 499 else |
819 | 500 let compl_list = s:SQLCGetSyntaxList(compl_type) |
818 | 501 endif |
502 | |
503 if base != '' | |
2034 | 504 " Filter the list based on the first few characters the user entered. |
3371 | 505 " Check if the text matches at the beginning |
506 " \\(^.base.'\\) | |
507 " or | |
2034 | 508 " Match to a owner.table or alias.column type match |
3371 | 509 " ^\\(\\w\\+\\.\\)\\?'.base.'\\) |
2034 | 510 " or |
511 " Handle names with spaces "my table name" | |
3371 | 512 " "\\(^'.base.'\\|^\\(\\w\\+\\.\\)\\?'.base.'\\)"' |
513 " | |
2034 | 514 let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|^\\(\\w\\+\\.\\)\\?'.base.'\\)"' |
515 " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\)"' | |
516 " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|\\(\\.\\)\\?'.base.'\\)"' | |
517 " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|\\([^.]*\\)\\?'.base.'\\)"' | |
840 | 518 let compl_list = filter(deepcopy(compl_list), expr) |
3996 | 519 |
520 if empty(compl_list) && compl_type == 'table' && base =~ '\.$' | |
521 " It is possible we could be looking for column name completion | |
522 " and the user simply hit C-X C-O to lets try it as well | |
523 " since we had no hits with the tables. | |
524 " If the base ends with a . it is hard to know if we are | |
525 " completing table names or column names. | |
526 let list_type = '' | |
527 | |
528 let compl_list = s:SQLCGetColumns(base, list_type) | |
529 endif | |
818 | 530 endif |
531 | |
819 | 532 if exists('b:sql_compl_savefunc') && b:sql_compl_savefunc != "" |
533 let &omnifunc = b:sql_compl_savefunc | |
534 endif | |
535 | |
3996 | 536 if empty(compl_list) |
537 call s:SQLCWarningMsg( 'Could not find type['.compl_type.'] using prepend[.'.s:prepended.'] base['.a:base.']' ) | |
538 endif | |
539 | |
818 | 540 return compl_list |
541 endfunc | |
542 | |
819 | 543 function! sqlcomplete#PreCacheSyntax(...) |
544 let syn_group_arr = [] | |
2458 | 545 let syn_items = [] |
546 | |
3371 | 547 if a:0 > 0 |
2458 | 548 if type(a:1) != 3 |
549 call s:SQLCWarningMsg("Parameter is not a list. Example:['syntaxGroup1', 'syntaxGroup2']") | |
550 return '' | |
551 endif | |
819 | 552 let syn_group_arr = a:1 |
553 else | |
554 let syn_group_arr = g:omni_sql_precache_syntax_groups | |
555 endif | |
1126 | 556 " For each group specified in the list, precache all |
25773 | 557 " the syntax items. |
819 | 558 if !empty(syn_group_arr) |
559 for group_name in syn_group_arr | |
2458 | 560 let syn_items = extend( syn_items, s:SQLCGetSyntaxList(group_name) ) |
561 endfor | |
562 endif | |
563 | |
564 return syn_items | |
565 endfunction | |
566 | |
567 function! sqlcomplete#ResetCacheSyntax(...) | |
568 let syn_group_arr = [] | |
569 | |
3371 | 570 if a:0 > 0 |
2458 | 571 if type(a:1) != 3 |
572 call s:SQLCWarningMsg("Parameter is not a list. Example:['syntaxGroup1', 'syntaxGroup2']") | |
573 return '' | |
574 endif | |
575 let syn_group_arr = a:1 | |
576 else | |
577 let syn_group_arr = g:omni_sql_precache_syntax_groups | |
578 endif | |
579 " For each group specified in the list, precache all | |
25773 | 580 " the syntax items. |
2458 | 581 if !empty(syn_group_arr) |
582 for group_name in syn_group_arr | |
583 let list_idx = index(s:syn_list, group_name, 0, &ignorecase) | |
584 if list_idx > -1 | |
585 " Remove from list of groups | |
586 call remove( s:syn_list, list_idx ) | |
587 " Remove from list of keywords | |
588 call remove( s:syn_value, list_idx ) | |
589 endif | |
819 | 590 endfor |
591 endif | |
592 endfunction | |
593 | |
594 function! sqlcomplete#Map(type) | |
595 " Tell the SQL plugin what you want to complete | |
596 let b:sql_compl_type=a:type | |
597 " Record previous omnifunc, if the SQL completion | |
598 " is being used in conjunction with other filetype | |
599 " completion plugins | |
600 if &omnifunc != "" && &omnifunc != 'sqlcomplete#Complete' | |
601 " Record the previous omnifunc, the plugin | |
602 " will automatically set this back so that it | |
603 " does not interfere with other ftplugins settings | |
604 let b:sql_compl_savefunc=&omnifunc | |
605 endif | |
606 " Set the OMNI func for the SQL completion plugin | |
607 let &omnifunc='sqlcomplete#Complete' | |
608 endfunction | |
609 | |
844 | 610 function! sqlcomplete#DrillIntoTable() |
611 " If the omni popup window is visible | |
612 if pumvisible() | |
613 call sqlcomplete#Map('column') | |
614 " C-Y, makes the currently highlighted entry active | |
615 " and trigger the omni popup to be redisplayed | |
2152 | 616 call feedkeys("\<C-Y>\<C-X>\<C-O>", 'n') |
844 | 617 else |
2152 | 618 " If the popup is not visible, simple perform the normal |
619 " key behaviour. | |
25773 | 620 " Must use exec since the key must be preceded by "\" |
3371 | 621 " or feedkeys will simply push each character of the string |
2152 | 622 " rather than the "key press". |
623 exec 'call feedkeys("\'.g:ftplugin_sql_omni_key_right.'", "n")' | |
844 | 624 endif |
625 return "" | |
626 endfunction | |
627 | |
628 function! sqlcomplete#DrillOutOfColumns() | |
629 " If the omni popup window is visible | |
630 if pumvisible() | |
631 call sqlcomplete#Map('tableReset') | |
632 " Trigger the omni popup to be redisplayed | |
633 call feedkeys("\<C-X>\<C-O>") | |
634 else | |
2152 | 635 " If the popup is not visible, simple perform the normal |
636 " key behaviour. | |
25773 | 637 " Must use exec since the key must be preceded by "\" |
3371 | 638 " or feedkeys will simply push each character of the string |
2152 | 639 " rather than the "key press". |
640 exec 'call feedkeys("\'.g:ftplugin_sql_omni_key_left.'", "n")' | |
844 | 641 endif |
642 return "" | |
643 endfunction | |
644 | |
645 function! s:SQLCWarningMsg(msg) | |
646 echohl WarningMsg | |
3371 | 647 echomsg 'SQLComplete:'.a:msg |
844 | 648 echohl None |
649 endfunction | |
3371 | 650 |
844 | 651 function! s:SQLCErrorMsg(msg) |
652 echohl ErrorMsg | |
3371 | 653 echomsg 'SQLComplete:'.a:msg |
844 | 654 echohl None |
655 endfunction | |
3371 | 656 |
819 | 657 function! s:SQLCGetSyntaxList(syn_group) |
658 let syn_group = a:syn_group | |
659 let compl_list = [] | |
660 | |
661 " Check if we have already cached the syntax list | |
662 let list_idx = index(s:syn_list, syn_group, 0, &ignorecase) | |
663 if list_idx > -1 | |
664 " Return previously cached value | |
665 let compl_list = s:syn_value[list_idx] | |
666 else | |
4437 | 667 let s:save_inc = g:omni_syntax_group_include_sql |
668 let s:save_exc = g:omni_syntax_group_exclude_sql | |
669 let g:omni_syntax_group_include_sql = '' | |
670 let g:omni_syntax_group_exclude_sql = '' | |
671 | |
3371 | 672 " Request the syntax list items from the |
819 | 673 " syntax completion plugin |
674 if syn_group == 'syntax' | |
675 " Handle this special case. This allows the user | |
676 " to indicate they want all the syntax items available, | |
677 " so do not specify a specific include list. | |
4437 | 678 let syn_value = syntaxcomplete#OmniSyntaxList() |
819 | 679 else |
680 " The user has specified a specific syntax group | |
681 let g:omni_syntax_group_include_sql = syn_group | |
4437 | 682 let syn_value = syntaxcomplete#OmniSyntaxList(syn_group) |
819 | 683 endif |
684 let g:omni_syntax_group_include_sql = s:save_inc | |
685 let g:omni_syntax_group_exclude_sql = s:save_exc | |
686 " Cache these values for later use | |
687 let s:syn_list = add( s:syn_list, syn_group ) | |
688 let s:syn_value = add( s:syn_value, syn_value ) | |
689 let compl_list = syn_value | |
690 endif | |
691 | |
692 return compl_list | |
693 endfunction | |
694 | |
818 | 695 function! s:SQLCCheck4dbext() |
696 if !exists('g:loaded_dbext') | |
697 let msg = "The dbext plugin must be loaded for dynamic SQL completion" | |
698 call s:SQLCErrorMsg(msg) | |
699 " Leave time for the user to read the error message | |
700 :sleep 2 | |
701 return -1 | |
1624 | 702 elseif g:loaded_dbext < 600 |
703 let msg = "The dbext plugin must be at least version 5.30 " . | |
818 | 704 \ " for dynamic SQL completion" |
705 call s:SQLCErrorMsg(msg) | |
706 " Leave time for the user to read the error message | |
707 :sleep 2 | |
708 return -1 | |
709 endif | |
710 return 1 | |
711 endfunction | |
712 | |
713 function! s:SQLCAddAlias(table_name, table_alias, cols) | |
844 | 714 " Strip off the owner if included |
715 let table_name = matchstr(a:table_name, '\%(.\{-}\.\)\?\zs\(.*\)' ) | |
818 | 716 let table_alias = a:table_alias |
717 let cols = a:cols | |
718 | |
3371 | 719 if g:omni_sql_use_tbl_alias != 'n' |
818 | 720 if table_alias == '' |
721 if 'da' =~? g:omni_sql_use_tbl_alias | |
722 if table_name =~ '_' | |
723 " Treat _ as separators since people often use these | |
724 " for word separators | |
725 let save_keyword = &iskeyword | |
726 setlocal iskeyword-=_ | |
727 | |
728 " Get the first letter of each word | |
3371 | 729 " [[:alpha:]] is used instead of \w |
818 | 730 " to catch extended accented characters |
731 " | |
3371 | 732 let table_alias = substitute( |
733 \ table_name, | |
734 \ '\<[[:alpha:]]\+\>_\?', | |
735 \ '\=strpart(submatch(0), 0, 1)', | |
818 | 736 \ 'g' |
737 \ ) | |
738 " Restore original value | |
739 let &iskeyword = save_keyword | |
740 elseif table_name =~ '\u\U' | |
844 | 741 let table_alias = substitute( |
818 | 742 \ table_name, '\(\u\)\U*', '\1', 'g') |
743 else | |
744 let table_alias = strpart(table_name, 0, 1) | |
745 endif | |
746 endif | |
747 endif | |
748 if table_alias != '' | |
749 " Following a word character, make sure there is a . and no spaces | |
750 let table_alias = substitute(table_alias, '\w\zs\.\?\s*$', '.', '') | |
751 if 'a' =~? g:omni_sql_use_tbl_alias && a:table_alias == '' | |
752 let table_alias = inputdialog("Enter table alias:", table_alias) | |
753 endif | |
754 endif | |
755 if table_alias != '' | |
756 let cols = substitute(cols, '\<\w', table_alias.'&', 'g') | |
757 endif | |
758 endif | |
759 | |
760 return cols | |
761 endfunction | |
762 | |
3371 | 763 function! s:SQLCGetObjectOwner(object) |
1126 | 764 " The owner regex matches a word at the start of the string which is |
765 " followed by a dot, but doesn't include the dot in the result. | |
1624 | 766 " ^ - from beginning of line |
767 " \("\|\[\)\? - ignore any quotes | |
768 " \zs - start the match now | |
769 " .\{-} - get owner name | |
770 " \ze - end the match | |
771 " \("\|\[\)\? - ignore any quotes | |
772 " \. - must by followed by a . | |
773 " let owner = matchstr( a:object, '^\s*\zs.*\ze\.' ) | |
774 let owner = matchstr( a:object, '^\("\|\[\)\?\zs\.\{-}\ze\("\|\]\)\?\.' ) | |
1126 | 775 return owner |
3371 | 776 endfunction |
1126 | 777 |
818 | 778 function! s:SQLCGetColumns(table_name, list_type) |
3996 | 779 if a:table_name =~ '\.' |
780 " Check if the owner/creator has been specified | |
781 let owner = matchstr( a:table_name, '^\zs.*\ze\..*\..*' ) | |
782 let table = matchstr( a:table_name, '^\(.*\.\)\?\zs.*\ze\..*' ) | |
783 let column = matchstr( a:table_name, '.*\.\zs.*' ) | |
784 | |
785 if g:omni_sql_include_owner == 1 && owner == '' && table != '' && column != '' | |
786 let owner = table | |
787 let table = column | |
788 let column = '' | |
789 endif | |
790 else | |
791 let owner = '' | |
792 let table = matchstr(a:table_name, '^["\[\]a-zA-Z0-9_ ]\+\ze\.\?') | |
793 let column = '' | |
794 endif | |
795 | |
1126 | 796 " Check if the table name was provided as part of the column name |
3996 | 797 " let table_name = matchstr(a:table_name, '^["\[\]a-zA-Z0-9_ ]\+\ze\.\?') |
798 let table_name = table | |
818 | 799 let table_cols = [] |
800 let table_alias = '' | |
801 let move_to_top = 1 | |
802 | |
1624 | 803 let table_name = substitute(table_name, '\s*\(.\{-}\)\s*$', '\1', 'g') |
804 | |
805 " If the table name was given as: | |
806 " where c. | |
807 let table_name = substitute(table_name, '^\c\(WHERE\|AND\|OR\)\s\+', '', '') | |
840 | 808 if g:loaded_dbext >= 300 |
818 | 809 let saveSettingAlias = DB_listOption('use_tbl_alias') |
810 exec 'DBSetOption use_tbl_alias=n' | |
811 endif | |
812 | |
1624 | 813 let table_name_stripped = substitute(table_name, '["\[\]]*', '', 'g') |
814 | |
818 | 815 " Check if we have already cached the column list for this table |
816 " by its name | |
1624 | 817 let list_idx = index(s:tbl_name, table_name_stripped, 0, &ignorecase) |
818 | 818 if list_idx > -1 |
1624 | 819 let table_cols = split(s:tbl_cols[list_idx], '\n') |
818 | 820 else |
3371 | 821 " Check if we have already cached the column list for this table |
818 | 822 " by its alias, assuming the table_name provided was actually |
823 " the alias for the table instead | |
824 " select * | |
825 " from area a | |
826 " where a. | |
1624 | 827 let list_idx = index(s:tbl_alias, table_name_stripped, 0, &ignorecase) |
818 | 828 if list_idx > -1 |
1624 | 829 let table_alias = table_name_stripped |
818 | 830 let table_name = s:tbl_name[list_idx] |
1624 | 831 let table_cols = split(s:tbl_cols[list_idx], '\n') |
818 | 832 endif |
833 endif | |
834 | |
835 " If we have not found a cached copy of the table | |
836 " And the table ends in a "." or we are looking for a column list | |
837 " if list_idx == -1 && (a:table_name =~ '\.' || b:sql_compl_type =~ 'column') | |
838 " if list_idx == -1 && (a:table_name =~ '\.' || a:list_type =~ 'csv') | |
3371 | 839 if list_idx == -1 |
818 | 840 let saveY = @y |
841 let saveSearch = @/ | |
842 let saveWScan = &wrapscan | |
843 let curline = line(".") | |
844 let curcol = col(".") | |
845 | |
25773 | 846 " Do not let searches wrap |
818 | 847 setlocal nowrapscan |
848 " If . was entered, look at the word just before the . | |
849 " We are looking for something like this: | |
3371 | 850 " select * |
818 | 851 " from customer c |
852 " where c. | |
853 " So when . is pressed, we need to find 'c' | |
854 " | |
855 | |
856 " Search backwards to the beginning of the statement | |
857 " and do NOT wrap | |
858 " exec 'silent! normal! v?\<\(select\|update\|delete\|;\)\>'."\n".'"yy' | |
2152 | 859 exec 'silent! normal! ?\<\c\(select\|update\|delete\|;\)\>'."\n" |
818 | 860 |
861 " Start characterwise visual mode | |
862 " Advance right one character | |
12756
3b26420fc639
Long overdue runtime update.
Christian Brabandt <cb@256bit.org>
parents:
7876
diff
changeset
|
863 " Search forward until one of the following: |
818 | 864 " 1. Another select/update/delete statement |
865 " 2. A ; at the end of a line (the delimiter) | |
25773 | 866 " 3. The end of the file (in case no delimiter) |
818 | 867 " Yank the visually selected text into the "y register. |
2152 | 868 exec 'silent! normal! vl/\c\(\<select\>\|\<update\>\|\<delete\>\|;\s*$\|\%$\)'."\n".'"yy' |
818 | 869 |
870 let query = @y | |
871 let query = substitute(query, "\n", ' ', 'g') | |
872 let found = 0 | |
873 | |
2152 | 874 " if query =~? '^\c\(select\)' |
875 if query =~? '^\(select\|update\|delete\)' | |
818 | 876 let found = 1 |
3371 | 877 " \(\(\<\w\+\>\)\.\)\? - |
2152 | 878 " '\c\(from\|join\|,\).\{-}' - Starting at the from clause (case insensitive) |
818 | 879 " '\zs\(\(\<\w\+\>\)\.\)\?' - Get the owner name (optional) |
3371 | 880 " '\<\w\+\>\ze' - Get the table name |
818 | 881 " '\s\+\<'.table_name.'\>' - Followed by the alias |
882 " '\s*\.\@!.*' - Cannot be followed by a . | |
883 " '\(\<where\>\|$\)' - Must be followed by a WHERE clause | |
884 " '.*' - Exclude the rest of the line in the match | |
3371 | 885 " let table_name_new = matchstr(@y, |
2152 | 886 " \ '\c\(from\|join\|,\).\{-}'. |
887 " \ '\zs\(\("\|\[\)\?.\{-}\("\|\]\)\.\)\?'. | |
888 " \ '\("\|\[\)\?.\{-}\("\|\]\)\?\ze'. | |
889 " \ '\s\+\%(as\s\+\)\?\<'. | |
890 " \ matchstr(table_name, '.\{-}\ze\.\?$'). | |
891 " \ '\>'. | |
892 " \ '\s*\.\@!.*'. | |
893 " \ '\(\<where\>\|$\)'. | |
894 " \ '.*' | |
895 " \ ) | |
3371 | 896 " |
897 " | |
898 " ''\c\(\<from\>\|\<join\>\|,\)\s*' - Starting at the from clause (case insensitive) | |
899 " '\zs\(\("\|\[\)\?\w\+\("\|\]\)\?\.\)\?' - Get the owner name (optional) | |
900 " '\("\|\[\)\?\w\+\("\|\]\)\?\ze' - Get the table name | |
901 " '\s\+\%(as\s\+\)\?\<'.matchstr(table_name, '.\{-}\ze\.\?$').'\>' - Followed by the alias | |
902 " '\s*\.\@!.*' - Cannot be followed by a . | |
903 " '\(\<where\>\|$\)' - Must be followed by a WHERE clause | |
904 " '.*' - Exclude the rest of the line in the match | |
905 let table_name_new = matchstr(@y, | |
2152 | 906 \ '\c\(\<from\>\|\<join\>\|,\)\s*'. |
907 \ '\zs\(\("\|\[\)\?\w\+\("\|\]\)\?\.\)\?'. | |
908 \ '\("\|\[\)\?\w\+\("\|\]\)\?\ze'. | |
844 | 909 \ '\s\+\%(as\s\+\)\?\<'. |
910 \ matchstr(table_name, '.\{-}\ze\.\?$'). | |
911 \ '\>'. | |
818 | 912 \ '\s*\.\@!.*'. |
913 \ '\(\<where\>\|$\)'. | |
914 \ '.*' | |
915 \ ) | |
1624 | 916 |
818 | 917 if table_name_new != '' |
918 let table_alias = table_name | |
3996 | 919 if g:omni_sql_include_owner == 1 |
920 let table_name = matchstr( table_name_new, '^\zs\(.\{-}\.\)\?\(.\{-}\.\)\?.*\ze' ) | |
921 else | |
922 " let table_name = matchstr( table_name_new, '^\(.*\.\)\?\zs.*\ze' ) | |
923 let table_name = matchstr( table_name_new, '^\(.\{-}\.\)\?\zs\(.\{-}\.\)\?.*\ze' ) | |
924 endif | |
818 | 925 |
926 let list_idx = index(s:tbl_name, table_name, 0, &ignorecase) | |
927 if list_idx > -1 | |
928 let table_cols = split(s:tbl_cols[list_idx]) | |
929 let s:tbl_name[list_idx] = table_name | |
930 let s:tbl_alias[list_idx] = table_alias | |
931 else | |
932 let list_idx = index(s:tbl_alias, table_name, 0, &ignorecase) | |
933 if list_idx > -1 | |
934 let table_cols = split(s:tbl_cols[list_idx]) | |
935 let s:tbl_name[list_idx] = table_name | |
936 let s:tbl_alias[list_idx] = table_alias | |
937 endif | |
938 endif | |
939 | |
940 endif | |
941 else | |
942 " Simply assume it is a table name provided with a . on the end | |
943 let found = 1 | |
944 endif | |
945 | |
946 let @y = saveY | |
947 let @/ = saveSearch | |
948 let &wrapscan = saveWScan | |
949 | |
950 " Return to previous location | |
951 call cursor(curline, curcol) | |
3371 | 952 |
818 | 953 if found == 0 |
840 | 954 if g:loaded_dbext > 300 |
818 | 955 exec 'DBSetOption use_tbl_alias='.saveSettingAlias |
956 endif | |
957 | |
958 " Not a SQL statement, do not display a list | |
959 return [] | |
960 endif | |
3371 | 961 endif |
818 | 962 |
963 if empty(table_cols) | |
964 " Specify silent mode, no messages to the user (tbl, 1) | |
965 " Specify do not comma separate (tbl, 1, 1) | |
3996 | 966 " let table_cols_str = DB_getListColumn(table_name, 1, 1) |
967 let table_cols_str = DB_getListColumn((owner!=''?owner.'.':'').table_name, 1, 1) | |
818 | 968 |
969 if table_cols_str != "" | |
970 let s:tbl_name = add( s:tbl_name, table_name ) | |
971 let s:tbl_alias = add( s:tbl_alias, table_alias ) | |
972 let s:tbl_cols = add( s:tbl_cols, table_cols_str ) | |
1624 | 973 let table_cols = split(table_cols_str, '\n') |
818 | 974 endif |
975 | |
976 endif | |
977 | |
840 | 978 if g:loaded_dbext > 300 |
818 | 979 exec 'DBSetOption use_tbl_alias='.saveSettingAlias |
980 endif | |
981 | |
844 | 982 " If the user has asked for a comma separate list of column |
983 " values, ask the user if they want to prepend each column | |
984 " with a tablename alias. | |
818 | 985 if a:list_type == 'csv' && !empty(table_cols) |
844 | 986 let cols = join(table_cols, ', ') |
987 let cols = s:SQLCAddAlias(table_name, table_alias, cols) | |
818 | 988 let table_cols = [cols] |
989 endif | |
990 | |
991 return table_cols | |
992 endfunction | |
3996 | 993 " Restore: |
994 let &cpo= s:keepcpo | |
995 unlet s:keepcpo | |
996 " vim: ts=4 fdm=marker |