diff --git a/src/tokenizer.ts b/src/tokenizer.ts index 1214b72..fce2841 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -140,6 +140,14 @@ function unread(state: State): void { state.position--; } +function peekBack(state: State): Char { + if (state.position == 0) { + return null; + } + + return state.input[state.position - 1]; +} + function peek(state: State): Char { if (state.position >= state.input.length - 1) { return null; @@ -469,6 +477,13 @@ function isParameter(ch: Char, state: State, paramTypes: ParamTypes): boolean { return false; } const nextChar = peek(state); + const prevChar = peekBack(state); + + // HACK (@day): This is a fix for casts and identifiers that use the `::` syntax + if (ch === ':' && (prevChar === ':' || nextChar === ':')) { + return false; + } + if (paramTypes.positional && ch === '?') return true; if (paramTypes.numbered?.length && paramTypes.numbered.some((type) => ch === type)) { diff --git a/test/index.spec.ts b/test/index.spec.ts index aaa04b1..bf8be98 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -127,3 +127,35 @@ describe('getExecutionType', () => { expect(getExecutionType('FAKE_TYPE')).to.equal('UNKNOWN'); }); }); + +describe('Regression tests', () => { + // Regression test: https://github.com/beekeeper-studio/beekeeper-studio/issues/2560 + it('Double colon should not be recognized as a param for mssql', () => { + const result = identify( + ` + DECLARE @g geometry; + DECLARE @h geometry; + SET @g = geometry::STGeomFromText('POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))', 0); + set @h = geometry::STGeomFromText('POLYGON((1 1, 3 1, 3 3, 1 3, 1 1))', 0); + SELECT @g.STWithin(@h); + `, + { strict: false, dialect: 'mssql' as Dialect }, + ); + result.forEach((res) => { + expect(res.parameters.length).to.equal(0); + }); + }); + + // Regression test: https://github.com/beekeeper-studio/beekeeper-studio/issues/2560 + it('Double colon should not be recognized as a param for psql', () => { + const result = identify( + ` + SELECT '123'::INTEGER; + `, + { strict: false, dialect: 'psql' as Dialect }, + ); + result.forEach((res) => { + expect(res.parameters.length).to.equal(0); + }); + }); +});