Technical Article

SQLStackEngine - simulate a character stack

,

SQLStackEngine - simulate a character stack using a string.  This script was developed specifically to support the operator stack in SQLCalcEngine(also on this site).  However, the implementation is complete enough to stand on its own.

There are several functions in the package that correspond to the common stack functions of Push, Pop, Peek, and so on.

In addition, unit test code is embedded in-line within the package as commented out lines.

--
-- SQLStackEngine
--
IF EXISTS(SELECT name FROM sysobjects
      WHERE name = 'FN_StringStackDepth' AND type = 'FN')
DROP FUNCTION FN_StringStackDepth
GO

CREATE FUNCTION FN_StringStackDepth (
   @InStack VARCHAR(500))
   RETURNS  NUMERIC
AS
BEGIN
   RETURN (CASE
           WHEN (@InStack IS NULL) THEN 0
           WHEN (LEN(RTRIM(@InStack)) < 1) THEN 0
           ELSE LEN(RTRIM(@InStack))
           END)
END
GO
-- test and debug       DECLARE @MyStack VARCHAR(500)
-- test and debug       SET @MyStack = '*'
-- test and debug       SELECT @MyStack, dbo.FN_StringStackDepth (@MyStack)
-- test and debug       SET @MyStack = ''
-- test and debug       SELECT @MyStack, dbo.FN_StringStackDepth (@MyStack)
-- test and debug       SET @MyStack = NULL
-- test and debug       SELECT @MyStack, dbo.FN_StringStackDepth (@MyStack)
-- test and debug       SET @MyStack = '*+-/'
-- test and debug       SELECT @MyStack, dbo.FN_StringStackDepth (@MyStack)

IF EXISTS(SELECT name FROM sysobjects
      WHERE name = 'FN_StringStackIsEmpty' AND type = 'FN')
DROP FUNCTION FN_StringStackIsEmpty
GO

CREATE FUNCTION FN_StringStackIsEmpty (
   @InStack VARCHAR(500))
   RETURNS  CHAR
AS
BEGIN
   RETURN (CASE
           WHEN (@InStack IS NULL) THEN 'T'
           WHEN (LEN(RTRIM(@InStack)) < 1) THEN 'T'
           ELSE 'F'
           END)
END
GO
-- test and debug       DECLARE @MyStack VARCHAR(500)
-- test and debug       SET @MyStack = '*'
-- test and debug       SELECT @MyStack, dbo.FN_StringStackIsEmpty (@MyStack)
-- test and debug       SET @MyStack = ''
-- test and debug       SELECT @MyStack, dbo.FN_StringStackIsEmpty (@MyStack)
-- test and debug       SET @MyStack = NULL
-- test and debug       SELECT @MyStack, dbo.FN_StringStackIsEmpty (@MyStack)

IF EXISTS(SELECT name FROM sysobjects
      WHERE name = 'FN_StringStackPush' AND type = 'FN')
DROP FUNCTION FN_StringStackPush
GO

CREATE FUNCTION FN_StringStackPush (
   @InStack VARCHAR(500),
   @InChar  CHAR)
   RETURNS  VARCHAR(500)
AS
BEGIN
   RETURN (CASE
           WHEN (@InStack IS NULL) THEN @InChar
           ELSE (RTRIM(@InStack) + @InChar)
           END)

END
GO
-- test and debug       DECLARE @MyStack VARCHAR(500), @MyChar CHAR
-- test and debug       SELECT '1', @MyStack
-- test and debug       SET @MyChar = 'A'
-- test and debug       SET @MyStack = dbo.FN_StringStackPush (@MyStack, @MyChar)
-- test and debug       SELECT '2', @MyStack
-- test and debug       SET @MyChar = 'B'
-- test and debug       SET @MyStack = dbo.FN_StringStackPush (@MyStack, @MyChar)
-- test and debug       SELECT '3', @MyStack
-- test and debug       SET @MyChar = 'C'
-- test and debug       SET @MyStack = dbo.FN_StringStackPush (@MyStack, @MyChar)
-- test and debug       SELECT '4', @MyStack

IF EXISTS(SELECT name FROM sysobjects
      WHERE name = 'FN_StringStackPeek' AND type = 'FN')
DROP FUNCTION FN_StringStackPeek
GO

CREATE FUNCTION FN_StringStackPeek (
   @InStack VARCHAR(500),
   @InPos   INT)
   RETURNS  CHAR
AS
BEGIN
   RETURN (CASE
           WHEN (@InPos < 1) THEN NULL
           WHEN (@InStack IS NULL) THEN NULL
           WHEN (LEN(RTRIM(@InStack)) < @InPos) THEN NULL
           ELSE SUBSTRING(RTRIM(@InStack), @InPos, 1)
           END)

END
GO
-- test and debug       DECLARE @MyStack VARCHAR(500)
-- test and debug       SELECT '1', @MyStack,dbo.FN_StringStackPeek (@MyStack, 0)
-- test and debug       SELECT '2', @MyStack,dbo.FN_StringStackPeek (@MyStack, 1)
-- test and debug       SELECT '3', @MyStack,dbo.FN_StringStackPeek (@MyStack, 2)
-- test and debug       SET @MyStack = 'A'
-- test and debug       SELECT '4', @MyStack,dbo.FN_StringStackPeek (@MyStack, 0)
-- test and debug       SELECT '5', @MyStack,dbo.FN_StringStackPeek (@MyStack, 1)
-- test and debug       SELECT '6', @MyStack,dbo.FN_StringStackPeek (@MyStack, 2)
-- test and debug       SET @MyStack = 'ABCDE'
-- test and debug       SELECT '7', @MyStack,dbo.FN_StringStackPeek (@MyStack, 0)
-- test and debug       SELECT '8', @MyStack,dbo.FN_StringStackPeek (@MyStack, 1)
-- test and debug       SELECT '9', @MyStack,dbo.FN_StringStackPeek (@MyStack, 2)
-- test and debug       SET @MyStack = ''
-- test and debug       SELECT '10', @MyStack,dbo.FN_StringStackPeek (@MyStack, 0)
-- test and debug       SELECT '11', @MyStack,dbo.FN_StringStackPeek (@MyStack, 1)
-- test and debug       SELECT '12', @MyStack,dbo.FN_StringStackPeek (@MyStack, 2)

IF EXISTS(SELECT name FROM sysobjects
      WHERE name = 'FN_StringStackTop' AND type = 'FN')
DROP FUNCTION FN_StringStackTop
GO

CREATE FUNCTION FN_StringStackTop (
   @InStack VARCHAR(500))
   RETURNS  CHAR
AS
BEGIN
   RETURN (CASE
           WHEN (@InStack IS NULL) THEN NULL
           WHEN (LEN(RTRIM(@InStack)) < 1) THEN NULL
           ELSE RIGHT (RTRIM(@InStack), 1)
           END)

END
GO
-- test and debug       DECLARE @MyStack VARCHAR(500)
-- test and debug       SELECT '1', @MyStack,dbo.FN_StringStackTop (@MyStack)
-- test and debug       SET @MyStack = 'A'
-- test and debug       SELECT '2', @MyStack,dbo.FN_StringStackTop (@MyStack)
-- test and debug       SET @MyStack = 'ABCDE'
-- test and debug       SELECT '3', @MyStack,dbo.FN_StringStackTop (@MyStack)
-- test and debug       SET @MyStack = ''
-- test and debug       SELECT '4', @MyStack,dbo.FN_StringStackTop (@MyStack)

IF EXISTS(SELECT name FROM sysobjects
      WHERE name = 'FN_StringStackPop' AND type = 'FN')
DROP FUNCTION FN_StringStackPop
GO

CREATE FUNCTION FN_StringStackPop (
   @InStack VARCHAR(500))
   RETURNS  VARCHAR(500)
AS
BEGIN
   RETURN (CASE
           WHEN (@InStack IS NULL) THEN NULL
           WHEN (LEN(RTRIM(@InStack)) <= 1) THEN NULL
           ELSE LEFT (RTRIM(@InStack), LEN(RTRIM(@InStack)) - 1)
           END)

END
GO
-- test and debug       DECLARE @MyStack VARCHAR(500)
-- test and debug       SELECT '1', @MyStack, dbo.FN_StringStackPop (@MyStack)
-- test and debug       SET @MyStack = 'A'
-- test and debug       SELECT '2', @MyStack, dbo.FN_StringStackPop (@MyStack)
-- test and debug       SET @MyStack = 'AB'
-- test and debug       SELECT '3', @MyStack, dbo.FN_StringStackPop (@MyStack)
-- test and debug       SET @MyStack = 'ABCDE'
-- test and debug       SELECT '4', @MyStack, dbo.FN_StringStackPop (@MyStack)
-- test and debug       SET @MyStack = ''
-- test and debug       SELECT '5', @MyStack, dbo.FN_StringStackPop (@MyStack)

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating