@@ -4,7 +4,7 @@ import * as constants from './constants';
44import * as dbg from './debugger' ;
55import { EvaluationError , DebuggerNotAvailableError } from './debugger' ;
66import { Log as logger } from './logger' ;
7- import { PghhError ,
7+ import { ArgumentInvalidError , PghhError ,
88 unnullify } from './error' ;
99import { Configuration ,
1010 getWorkspaceFolder ,
@@ -1601,6 +1601,46 @@ export abstract class Variable {
16011601 return await this . legacyOidOutputFunctionCall ( funcOid , datum ) ;
16021602 }
16031603
1604+ /**
1605+ * Invoke SearchSysCache1 with fallback to legacy implementation
1606+ *
1607+ * Unlike other implementations this accepts only 1 key, because for now
1608+ * we do not need other count.
1609+ */
1610+ async searchSysCache1 ( cacheId : string , key : number ) {
1611+ await this . checkCanUseSysCache ( ) ;
1612+
1613+ if ( ! oidIsValid ( key ) ) {
1614+ throw new ArgumentInvalidError ( key , 'valid Oid is a positive integer' ) ;
1615+ }
1616+
1617+ const typeoid = this . debug . formatEnumValue ( 'SysCacheIdentifier' , cacheId ) ;
1618+
1619+ if ( this . context . hasSearchSysCacheFunction ) {
1620+ try {
1621+ const expr = `SearchSysCache1(${ typeoid } , (Datum)${ key } )` ;
1622+ const result = await this . evaluateSysCache ( expr ) ;
1623+ if ( this . debug . isNull ( result ) ) {
1624+ return ;
1625+ }
1626+ return result . memoryReference ;
1627+ } catch ( err ) {
1628+ if ( ! isEvaluationError ( err ) ) {
1629+ throw err ;
1630+ }
1631+ }
1632+
1633+ this . context . hasSearchSysCacheFunction = false ;
1634+ }
1635+
1636+ const expr = `SearchSysCache(${ typeoid } , (Datum)${ key } , 0, 0, 0)` ;
1637+ const result = await this . evaluateSysCache ( expr ) ;
1638+ if ( this . debug . isNull ( result ) ) {
1639+ return ;
1640+ }
1641+ return result . memoryReference ;
1642+ }
1643+
16041644 private haveSysCatCacheBreakpoint ( ) {
16051645 return ! ! vscode . debug . breakpoints . find ( b => {
16061646 if ( ! b . enabled ) {
@@ -1623,14 +1663,19 @@ export abstract class Variable {
16231663 ??= ! this . haveSysCatCacheBreakpoint ( ) ;
16241664 }
16251665
1626- /*
1627- * Call evaluate with safety checks for sys/cat cache usage.
1628- */
1629- async evaluateSysCache ( expr : string ) {
1666+ private async checkCanUseSysCache ( ) {
16301667 if ( ! this . isSafeToUseSysCache ( ) ) {
16311668 throw new EvaluationError ( 'Not safe to use SysCache' ) ;
16321669 }
16331670
1671+ await this . checkCanAlloc ( ) ;
1672+ }
1673+
1674+ /*
1675+ * Call evaluate with safety checks for sys/cat cache usage.
1676+ */
1677+ async evaluateSysCache ( expr : string ) {
1678+ await this . checkCanUseSysCache ( ) ;
16341679 return await this . evaluate ( expr ) ;
16351680 }
16361681
@@ -2167,7 +2212,17 @@ export class RealVariable extends Variable {
21672212 * years (and I do not think will be changed in near future).
21682213 */
21692214const InvalidOid = 0 ;
2170- const oidIsValid = ( oid : number ) => Number . isInteger ( oid ) && oid !== InvalidOid ;
2215+
2216+ /*
2217+ * This check is not the same as in vanilla code. Specifically there is check
2218+ * that given number is Integer (JS type) and check that Oid is positive.
2219+ *
2220+ * The last check was not in original OidIsValid macro, but Oid defined as unsigned,
2221+ * so any negative number will be invalid and even if some debugger will perform
2222+ * casting for us (and in the end complete successfully) we should treat it as
2223+ * an error in OUR code.
2224+ */
2225+ const oidIsValid = ( oid : number ) => Number . isInteger ( oid ) && oid > InvalidOid ;
21712226
21722227const InvalidAttrNumber = 0 ;
21732228
@@ -5769,34 +5824,6 @@ class TupleTableSlotAttributesVariable extends Variable {
57695824 const form = await this . evaluate ( expr ) ;
57705825 return form . memoryReference ;
57715826 }
5772-
5773- async searchSysCache1 ( cacheId : string , key : number ) {
5774- const typeoid = this . debug . formatEnumValue ( 'SysCacheIdentifier' , cacheId ) ;
5775-
5776- if ( this . context . hasSearchSysCacheFunction ) {
5777- try {
5778- const expr = `SearchSysCache1(${ typeoid } , (Datum)${ key } )` ;
5779- const result = await this . evaluateSysCache ( expr ) ;
5780- if ( this . debug . isNull ( result ) ) {
5781- return ;
5782- }
5783- return result . memoryReference ;
5784- } catch ( err ) {
5785- if ( ! isEvaluationError ( err ) ) {
5786- throw err ;
5787- }
5788- }
5789-
5790- this . context . hasSearchSysCacheFunction = false ;
5791- }
5792-
5793- const expr = `SearchSysCache(${ typeoid } , (Datum)${ key } , 0, 0, 0)` ;
5794- const result = await this . evaluateSysCache ( expr ) ;
5795- if ( this . debug . isNull ( result ) ) {
5796- return ;
5797- }
5798- return result . memoryReference ;
5799- }
58005827
58015828 /*
58025829 * Search output function information for given type.
0 commit comments