Skip to content

Commit e357948

Browse files
authored
Merge branch 'codefori:main' into feature/record_locks
2 parents 88fc4a2 + 22525e4 commit e357948

File tree

13 files changed

+249
-70
lines changed

13 files changed

+249
-70
lines changed

package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,11 @@
429429
"category": "Db2 for i",
430430
"icon": "$(search)"
431431
},
432+
{
433+
"command": "vscode-db2i.viewPermissions",
434+
"title": "View permissions",
435+
"category": "Db2 for i"
436+
},
432437
{
433438
"command": "vscode-db2i.runEditorStatement",
434439
"title": "Run statement",
@@ -1027,6 +1032,11 @@
10271032
"when": "viewItem == table || viewItem == view || viewItem == index",
10281033
"group": "db2data@4"
10291034
},
1035+
{
1036+
"command": "vscode-db2i.viewPermissions",
1037+
"when": "viewItem == table || viewItem == view || viewItem == alias || viewItem == function || viewItem == variable || viewItem == index || viewItem == procedure || viewItem == sequence || viewItem == package || viewItem == trigger || viewItem == type",
1038+
"group": "db2data@5"
1039+
},
10301040
{
10311041
"command": "vscode-db2i.advisedIndexes",
10321042
"when": "viewItem == table || viewItem == schema",

src/connection/sqlJob.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export class OldSQLJob extends SQLJob {
106106
getStatus(): JobStatus {
107107
const currentListenerCount = this.responseEmitter.eventNames().length;
108108

109-
return this.channel && currentListenerCount > 0 ? JobStatus.BUSY : this.status;
109+
return this.channel && currentListenerCount > 0 ? JobStatus.BUSY : this.status as JobStatus;
110110
}
111111

112112
async connect(): Promise<ConnectionResult> {

src/database/schemas.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -356,18 +356,12 @@ export default class Schemas {
356356

357357
let query: string;
358358

359-
if (selects.length > 1) {
360-
if (details.sort) {
361-
query = `with results as (${selects.join(
362-
" UNION ALL "
363-
)}) select * from results Order by QSYS2.DELIMIT_NAME(NAME) asc`;
364-
} else {
365-
query = selects.join(` UNION ALL `);
366-
}
367-
359+
if (details.sort) {
360+
query = `with results as (${selects.join(
361+
" UNION ALL "
362+
)}) select * from results Order by QSYS2.DELIMIT_NAME(NAME) asc`;
368363
} else {
369-
// TODO: sort single
370-
query = selects[0];
364+
query = selects.join(` UNION ALL `);
371365
}
372366

373367
const objects: any[] = await JobManager.runSQL(

src/database/table.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ export default class Table {
7070
}
7171

7272
static async isPartitioned(schema: string, name: string): Promise<boolean> {
73-
const sql = `select table_name, partitioned_table from qsys2.sysfiles where table_schema = ? and table_name = ? and partitioned_table is not null and partitioned_table = 'YES'`;
74-
const parameters = [schema, name];
73+
const sql = `select table_name, partitioned_table from qsys2.sysfiles where ((table_schema = ? and table_name = ?) or (system_table_schema = ? and system_table_name = ?)) and partitioned_table is not null and partitioned_table = 'YES'`;
74+
const parameters = [schema, name, schema, name];
7575

7676
const result = await JobManager.runSQL(sql, {parameters});
7777
return result.length > 0;

src/language/providers/hoverProvider.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import Statement from "../../database/statement";
66
import { getParmAttributes, prepareParamType } from "./logic/completion";
77
import { StatementType } from "../sql/types";
88
import { remoteAssistIsEnabled } from "./logic/available";
9-
import { getPositionData } from "./logic/callable";
109
import { CallableSignature } from "../../database/callable";
10+
import { getPositionData } from "../sql/document";
1111

1212
// =================================
1313
// We need to open provider to exist so symbols can be cached for hover support when opening files
@@ -87,16 +87,29 @@ export const hoverProvider = languages.registerHoverProvider({ language: `sql` }
8787

8888
if (result) {
8989
if ('routine' in result) {
90-
const routineOffset = ref.tokens[ref.tokens.length-1].range.end+1;
91-
const callableRef = statementAt.getCallableDetail(routineOffset, false);
92-
if (callableRef) {
93-
const { currentCount } = getPositionData(callableRef, routineOffset);
94-
const signatures = await DbCache.getCachedSignatures(callableRef.parentRef.object.schema, callableRef.parentRef.object.name);
95-
const possibleSignatures = signatures.filter((s) => s.parms.length >= currentCount).sort((a, b) => a.parms.length - b.parms.length);
96-
const signature = possibleSignatures.find((signature) => currentCount <= signature.parms.length);
97-
if (signature) {
98-
addRoutineMd(md, signature, result);
99-
}
90+
let signatures: CallableSignature[];
91+
let signature: CallableSignature | undefined;
92+
93+
const lastToken = ref.tokens[ref.tokens.length-1];
94+
95+
if (lastToken.type === `closebracket`) {
96+
let routineOffset: number = lastToken.range.start-1;
97+
const callableRef = statementAt.getCallableDetail(routineOffset, false);
98+
if (callableRef) {
99+
const { currentCount } = getPositionData(callableRef, routineOffset);
100+
signatures = await DbCache.getCachedSignatures(callableRef.parentRef.object.schema, callableRef.parentRef.object.name);
101+
const possibleSignatures = signatures.filter((s) => s.parms.length >= currentCount).sort((a, b) => a.parms.length - b.parms.length);
102+
signature = possibleSignatures.find((signature) => currentCount <= signature.parms.length);
103+
}
104+
}
105+
106+
if (!signature) {
107+
signatures = await DbCache.getCachedSignatures(result.routine.schema, result.routine.name);
108+
signature = signatures[0];
109+
}
110+
111+
if (signature) {
112+
addRoutineMd(md, signature, result);
100113
}
101114
} else {
102115
addSymbol(md, result);

src/language/providers/logic/callable.ts

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Statement from "../../../database/statement";
55
import { createCompletionItem, getParmAttributes } from "./completion";
66
import { DbCache } from "./cache";
77
import { SQLParm } from "../../../types";
8+
import { getPositionData } from "../../sql/document";
89

910
/**
1011
* Checks if the ref exists as a procedure or function. Then,
@@ -117,27 +118,4 @@ export function getCallableParameters(ref: CallableReference, offset: number): C
117118
});
118119
}
119120
return [];
120-
}
121-
122-
export function getPositionData(ref: CallableReference, offset: number) {
123-
const paramCommas = ref.tokens.filter(token => token.type === `comma`);
124-
125-
let currentParm = paramCommas.findIndex(t => offset < t.range.end);
126-
127-
if (currentParm === -1) {
128-
currentParm = paramCommas.length;
129-
}
130-
131-
const firstNamedPipe = ref.tokens.find((token, i) => token.type === `rightpipe`);
132-
let firstNamedParameter = firstNamedPipe ? paramCommas.findIndex((token, i) => token.range.start > firstNamedPipe.range.start) : undefined;
133-
134-
if (firstNamedParameter === -1) {
135-
firstNamedParameter = undefined;
136-
}
137-
138-
return {
139-
currentParm,
140-
currentCount: paramCommas.length + 1,
141-
firstNamedParameter
142-
};
143121
}

src/language/providers/parameterProvider.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { MarkdownString, ParameterInformation, Position, Range, SignatureHelp, SignatureInformation, TextEdit, languages } from "vscode";
22
import Statement from "../../database/statement";
3-
import Document from "../sql/document";
4-
import { getCallableParameters, getPositionData, isCallableType } from "./logic/callable";
5-
import { getParmAttributes, prepareParamType } from "./logic/completion";
3+
import Document, { getPositionData } from "../sql/document";
4+
import { isCallableType } from "./logic/callable";
5+
import { prepareParamType } from "./logic/completion";
66
import { CallableType } from "../../database/callable";
77
import { StatementType } from "../sql/types";
88
import { remoteAssistIsEnabled } from "./logic/available";
@@ -22,7 +22,7 @@ export const signatureProvider = languages.registerSignatureHelpProvider({ langu
2222
const currentStatement = sqlDoc.getStatementByOffset(offset);
2323

2424
if (currentStatement) {
25-
const routineType: CallableType = currentStatement.type === StatementType.Call ? `PROCEDURE` : `FUNCTION`;
25+
const routineType: CallableType = currentStatement. type === StatementType.Call ? `PROCEDURE` : `FUNCTION`;
2626
const callableRef = currentStatement.getCallableDetail(offset, true);
2727
// TODO: check the function actually exists before returning
2828
if (callableRef) {

src/language/sql/document.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Statement from "./statement";
22
import SQLTokeniser from "./tokens";
3-
import { Definition, IRange, ParsedEmbeddedStatement, StatementGroup, StatementType, StatementTypeWord, Token } from "./types";
3+
import { CallableReference, Definition, IRange, ParsedEmbeddedStatement, StatementGroup, StatementType, StatementTypeWord, Token } from "./types";
44

55
export default class Document {
66
content: string;
@@ -261,6 +261,30 @@ export default class Document {
261261
}
262262
}
263263

264+
265+
export function getPositionData(ref: CallableReference, offset: number) {
266+
const paramCommas = ref.tokens.filter(token => token.type === `comma`);
267+
268+
let currentParm = paramCommas.findIndex(t => offset < t.range.start);
269+
270+
if (currentParm === -1) {
271+
currentParm = paramCommas.length;
272+
}
273+
274+
const firstNamedPipe = ref.tokens.find((token, i) => token.type === `rightpipe`);
275+
let firstNamedParameter = firstNamedPipe ? paramCommas.findIndex((token, i) => token.range.start > firstNamedPipe.range.start) : undefined;
276+
277+
if (firstNamedParameter === -1) {
278+
firstNamedParameter = undefined;
279+
}
280+
281+
return {
282+
currentParm,
283+
currentCount: paramCommas.length + 1,
284+
firstNamedParameter
285+
};
286+
}
287+
264288
function getSymbolsForStatements(statements: Statement[]) {
265289
let defintions: Definition[] = [];
266290

src/language/sql/statement.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,16 @@ export default class Statement {
117117
if (tokenInOffset) {
118118
if (tokenInOffset.type === `block`) {
119119
if (tokenInOffset.block!.length > 0) {
120-
return blockContainsOffset(cOffset, tokenInOffset.block!);
120+
let blockRange = blockContainsOffset(cOffset, tokenInOffset.block!);
121+
if (!blockRange) {
122+
blockRange = {
123+
start: this.tokens.findIndex(token => token.range.start === tokenInOffset.range.start) + 1,
124+
end: this.tokens.findIndex(token => token.range.end === tokenInOffset.range.end)
125+
}
126+
}
127+
128+
return blockRange;
129+
121130
} else {
122131
const rawEnd = this.tokens.findIndex(token => token.range.end === tokenInOffset.range.end);
123132
return {
@@ -378,7 +387,7 @@ export default class Statement {
378387
switch (this.type) {
379388
case StatementType.Call:
380389
// CALL X()
381-
doAdd(this.getRefAtToken(1));
390+
doAdd(this.getRefAtToken(1, {includeParameters: true}));
382391
break;
383392

384393
case StatementType.Alter:
@@ -550,7 +559,7 @@ export default class Statement {
550559

551560
let endIndex = i;
552561

553-
const isSubSelect = tokenIs(nextToken, `function`, `TABLE`) || tokenIs(nextToken, `function`, `LATERAL`) || (options.includeParameters && tokenIs(nextToken, `function`));
562+
const isSubSelect = (tokenIs(nextToken, `function`, `TABLE`) || tokenIs(nextToken, `function`, `LATERAL`) || (options.includeParameters && tokenIs(nextToken, `function`)) && this.type !== StatementType.Call);
554563

555564
if (isSubSelect) {
556565
sqlObj = this.getRefAtToken(i+2);
@@ -598,7 +607,6 @@ export default class Statement {
598607
}
599608

600609
if (sqlObj) {
601-
602610
if (options.withSystemName !== true) {
603611
// If the next token is not a clause.. we might have the alias
604612
if (nextToken && this.tokens[nextIndex+1]) {
@@ -615,6 +623,18 @@ export default class Statement {
615623

616624
if (!isSubSelect && !sqlObj.isUDTF) {
617625
sqlObj.tokens = this.tokens.slice(i, endIndex+1);
626+
627+
if (options.includeParameters && tokenIs(this.tokens[endIndex+1], `openbracket`)) {
628+
const blockTokens = this.getBlockAt(this.tokens[endIndex+1].range.end+1);
629+
630+
if (blockTokens.length > 0) {
631+
sqlObj.tokens = sqlObj.tokens.concat([
632+
{type: `openbracket`, value: `(`, range: {start: this.tokens[endIndex+1].range.start, end: this.tokens[endIndex+1].range.end}},
633+
...blockTokens,
634+
{type: `closebracket`, value: `)`, range: {start: blockTokens[blockTokens.length-1].range.end, end: blockTokens[blockTokens.length-1].range.end}}
635+
]);
636+
}
637+
}
618638
}
619639

620640
if (options.withSystemName) {

0 commit comments

Comments
 (0)