Skip to content

Commit 46960b7

Browse files
committed
fix: invalid sequence of checks lead to attribute not shown
`get_attname` in older systems accepted 2 arguments (today there are 3). Also string extracting function is dumb and does not check for failed vars, so this lead to error message rendered in variables view.
1 parent a76e139 commit 46960b7

File tree

1 file changed

+48
-9
lines changed

1 file changed

+48
-9
lines changed

src/variables.ts

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,14 @@ export class ExecContext {
454454
*/
455455
hasBoolAsChar = false;
456456

457+
/**
458+
* 'get_attname' function accepts 3 arguments.
459+
*
460+
* In PostgreSQL 10 and below 'get_attname' accepted 2 arguments and
461+
* worked same way as current with 'true' passed as 3rd argument.
462+
*/
463+
hasGetAttname3 = true;
464+
457465
constructor(nodeVarRegistry: NodeVarRegistry, specialMemberRegistry: SpecialMemberRegistry,
458466
debug: dbg.IDebuggerFacade, hashTableTypes: HashTableTypes) {
459467
this.nodeVarRegistry = nodeVarRegistry;
@@ -1907,15 +1915,46 @@ class ExprNodeVariable extends NodeVariable {
19071915
const evalResult = await this.evaluate(getAttnameExpr);
19081916
const useGetAttname = this.debug.extractBool({...evalResult, value: evalResult.result});
19091917
if (useGetAttname) {
1910-
/* Call this with `true` last - do not throw error if no such attribute found */
1911-
const r = await this.evaluate(`get_attname(${rtePtr}->relid, ${varattno}, true)`);
1912-
const attname = this.debug.extractString({...r, value: r.result});
1913-
if (attname !== null) {
1914-
return attname;
1915-
}
1916-
1917-
if (this.debug.isFailedVar(r)) {
1918-
this.context.hasGetAttname = false;
1918+
let r;
1919+
let attname;
1920+
if (this.context.hasGetAttname3) {
1921+
/*
1922+
* There are 2 notes:
1923+
*
1924+
* 1. In older versions `get_attname` accepted only 2
1925+
* arguments and behaved in same way as `true` is
1926+
* passed today
1927+
* 2. We first should check for failed var, not extract
1928+
* string and check for null. My current code for
1929+
* extracting strings is dumb and does not check for
1930+
* such situations (so it will return non-null in
1931+
* case of such error)
1932+
*/
1933+
r = await this.evaluate(`get_attname(${rtePtr}->relid, ${varattno}, true)`);
1934+
if (this.debug.isFailedVar(r)) {
1935+
if (r.result.indexOf('no matching function') !== -1) {
1936+
r = await this.evaluate(`get_attname(${rtePtr}->relid, ${varattno})`);
1937+
if (!this.debug.isFailedVar(r) &&
1938+
(attname = this.debug.extractString({...r, value: r.result})) !== null) {
1939+
this.context.hasGetAttname3 = false;
1940+
return attname;
1941+
}
1942+
} else {
1943+
this.context.hasGetAttname = false;
1944+
}
1945+
} else {
1946+
attname = this.debug.extractString({...r, value: r.result});
1947+
if (!this.debug.isFailedVar(r) &&
1948+
(attname = this.debug.extractString({...r, value: r.result})) !== null) {
1949+
return attname;
1950+
}
1951+
}
1952+
} else {
1953+
r = await this.evaluate(`get_attname(${rtePtr}->relid, ${varattno})`);
1954+
if (!this.debug.isFailedVar(r) &&
1955+
(attname = this.debug.extractString({...r, value: r.result})) !== null) {
1956+
return attname;
1957+
}
19191958
}
19201959
}
19211960
}

0 commit comments

Comments
 (0)