From 951d1280420d905fc47fae53cbf6dd43092b6fe3 Mon Sep 17 00:00:00 2001 From: reiniero Date: Sun, 15 Jun 2014 09:10:24 +0000 Subject: [PATCH] - fcl-db: sql parser - remove support for SET TERM/SET AUTODDL as it does not fall within Firebird SQL git-svn-id: trunk@27961 - --- packages/fcl-db/src/sql/fpsqlparser.pas | 92 +-------------- packages/fcl-db/src/sql/fpsqlscanner.pp | 20 +--- packages/fcl-db/src/sql/fpsqltree.pp | 24 ---- packages/fcl-db/tests/tcparser.pas | 149 +----------------------- 4 files changed, 8 insertions(+), 277 deletions(-) diff --git a/packages/fcl-db/src/sql/fpsqlparser.pas b/packages/fcl-db/src/sql/fpsqlparser.pas index d8bd59b8ba..431d0f737a 100644 --- a/packages/fcl-db/src/sql/fpsqlparser.pas +++ b/packages/fcl-db/src/sql/fpsqlparser.pas @@ -101,8 +101,6 @@ Type function ParseCreateViewStatement(AParent: TSQLElement; IsAlter: Boolean): TSQLCreateOrAlterStatement; function ParseCreateTriggerStatement(AParent: TSQLElement; IsAlter: Boolean): TSQLCreateOrAlterStatement; function ParseSetGeneratorStatement(AParent: TSQLElement) : TSQLSetGeneratorStatement; - function ParseSetISQLStatement(AParent: TSQLElement) : TSQLSetISQLStatement; - function ParseSetTermStatement(AParent: TSQLElement) : TSQLSetTermStatement; function ParseCreateDatabaseStatement(AParent: TSQLElement; IsAlter: Boolean ): TSQLCreateDatabaseStatement; function ParseCreateShadowStatement(AParent: TSQLElement; IsAlter: Boolean ): TSQLCreateShadowStatement; function ParseAlterDatabaseStatement(AParent: TSQLElement; IsAlter: Boolean ): TSQLAlterDatabaseStatement; @@ -163,12 +161,6 @@ Type Function Parse : TSQLElement; // Parse script containing 1 or more elements Function ParseScript(AllowPartial : Boolean = False) : TSQLElementList; - // Gets statement terminator (as e.g. used in SET TERM) so statements like - // EXECUTE BLOCK or CREATE PROCEDURE that contain semicolons can be parsed - function GetStatementTerminator: string; - // Sets statement terminator (as e.g. used in SET TERM) so statements like - // EXECUTE BLOCK or CREATE PROCEDURE that contain semicolons can be parsed - procedure SetStatementTerminator(AValue: string); // Auxiliary stuff Function CurrentToken : TSQLToken; Function CurrentTokenString : String; @@ -1522,7 +1514,7 @@ begin S:=ParseProcedureStatement(AParent); Statements.Add(S); if not (PreviousToken=tsqlEnd) then - Consume([tsqlSemicolon,tsqlStatementTerminator]); + Consume([tsqlSemicolon]); end; Consume(tsqlEnd); end; @@ -2981,74 +2973,6 @@ begin end; end; -function TSQLParser.ParseSetISQLStatement(AParent: TSQLElement - ): TSQLSetISQLStatement; -begin - // On entry, we're on the first argument e.g. AUTODDL in SET AUTODDL - // for now, only support AutoDDL - //SET AUTODDL: ignore these isql commands for now - case CurrentToken of - tsqlAutoDDL: - begin - Result:=TSQLSetISQLStatement(CreateElement(TSQLSetISQLStatement,AParent)); - // SET AUTODDL ON, SET AUTODDL OFF; optional arguments - if (PeekNextToken in [tsqlOn, tsqlOff]) then - begin - GetNextToken; - if CurrentToken=tsqlOFF then - Result.Arguments:='AUTODDL OFF' - else - Result.Arguments:='AUTODDL ON'; - Consume([tsqlOn,tsqlOff]); - end - else - begin - Result.Arguments:='AUTODDL ON'; - Consume(tsqlAutoDDL); - end; - end - else - UnexpectedToken; - end; -end; - -function TSQLParser.ParseSetTermStatement(AParent: TSQLElement - ): TSQLSetTermStatement; -var - ExistingStatTerm: string; -begin - // On entry, we're on the 'TERM' token - Consume(tsqlTerm) ; - try - Result:=TSQLSetTermStatement(CreateElement(TSQLSetTermStatement,AParent)); - Expect([tsqlSemiColon,tsqlStatementTerminator,tsqlSymbolString,tsqlString]); - // Already set the expression's new value to the new terminator, but do not - // change tSQLStatementTerminator as GetNextToken etc need the old one to - // detect the closing terminator - case CurrentToken of - tsqlSemiColon, tsqlStatementTerminator: Result.NewTerminator:=TokenInfos[CurrentToken]; - tsqlSymbolString, tsqlString: Result.NewTerminator:=CurrentTokenString; - end; - // Expect the old terminator... - GetNextToken; - // Parser will give tsqlSemicolon rather than tsqlStatementTerminator: - if TokenInfos[tsqlStatementTerminator]=TokenInfos[tsqlSEMICOLON] then - begin - Expect(tsqlSEMICOLON); - Result.OldTerminator:=TokenInfos[tsqlSEMICOLON]; - end - else - begin - Expect(tsqlStatementTerminator); - Result.OldTerminator:=TokenInfos[tsqlStatementTerminator]; - end; - //... and now set the new terminator: - TokenInfos[tsqlStatementTerminator]:=Result.NewTerminator; //process new terminator value - except - FreeAndNil(Result); - Raise; - end; -end; function TSQLParser.ParseSecondaryFile(AParent: TSQLElement) : TSQLDatabaseFileInfo; @@ -3453,8 +3377,6 @@ begin Consume(tsqlSet); Case CurrentToken of tsqlGenerator : Result:=ParseSetGeneratorStatement(AParent); //SET GENERATOR - tsqlTerm : Result:=ParseSetTermStatement(AParent); //SET TERM - tsqlAutoDDL : Result:=ParseSetISQLStatement(AParent); //SET AUTODDL else // For the time being UnexpectedToken; @@ -3971,7 +3893,7 @@ begin else UnexpectedToken; end; - if Not (CurrentToken in [tsqlEOF,tsqlSemicolon,tsqlStatementTerminator]) then + if Not (CurrentToken in [tsqlEOF,tsqlSemicolon]) then begin FreeAndNil(Result); if (CurrentToken=tsqlBraceClose) then @@ -4003,16 +3925,6 @@ begin end; end; -function TSQLParser.GetStatementTerminator: string; -begin - result:=TokenInfos[tsqlStatementTerminator]; -end; - -procedure TSQLParser.SetStatementTerminator(AValue: string); -begin - TokenInfos[tsqlStatementTerminator]:=AValue;; -end; - function TSQLParser.CurrentToken: TSQLToken; begin Result:=FCurrent; diff --git a/packages/fcl-db/src/sql/fpsqlscanner.pp b/packages/fcl-db/src/sql/fpsqlscanner.pp index 91f2578833..2f4aa76b9a 100644 --- a/packages/fcl-db/src/sql/fpsqlscanner.pp +++ b/packages/fcl-db/src/sql/fpsqlscanner.pp @@ -42,8 +42,6 @@ type tsqlIdentifier {a table etc name}, tsqlSymbolString {a string containing symbols/punctuation marks; only rarely used - e.g. in SET TERM ^ ;}, tsqlIntegerNumber,tsqlFloatNumber,tsqlComment, - tsqlStatementTerminator {statement separator, usually semicolon but may be changed by code. For now, limited to semicolon and symbol literals not already defined like tsqlCOMMA.} - {todo: move this out of fpsqlscanner into fpsqlparser with an option to disable}, tsqlBraceOpen,tsqlBraceClose,tsqlSquareBraceOpen,tsqlSquareBraceClose, tsqlPlaceHolder {question mark}, tsqlCOMMA,tsqlCOLON,tsqlDOT,tsqlSEMICOLON, @@ -51,7 +49,7 @@ type tsqlEQ,tsqlGE,tsqlLE,tsqlNE, { Reserved words/keywords start here. They must be last } { Note: if adding before tsqlALL or after tsqlWHEN please update FirstKeyword/LastKeyword } - tsqlALL, tsqlAND, tsqlANY, tsqlASC, tsqlASCENDING, tsqlAVG, tsqlALTER, tsqlAdd, tsqlActive, tsqlAction, tsqlAs,tsqlAt, tsqlAuto, tsqlAutoDDL {not an FB reserved word but used in isql scripts}, tsqlAfter,tsqlAdmin, + tsqlALL, tsqlAND, tsqlANY, tsqlASC, tsqlASCENDING, tsqlAVG, tsqlALTER, tsqlAdd, tsqlActive, tsqlAction, tsqlAs,tsqlAt, tsqlAuto, tsqlAfter,tsqlAdmin, tsqlBETWEEN, tsqlBinary, tsqlBY, tsqlBLOB, tsqlBegin, tsqlBefore, tsqlCOLLATE, tsqlCONTAINING, tsqlCOUNT, tsqlCREATE, tsqlCOLUMN, tsqlCONSTRAINT, tsqlChar,tsqlCHARACTER, tsqlCHECK, tsqlComputed,tsqlCASCADE, tsqlCast, tsqlCommit,tsqlConnect,tsqlCache,tsqlConditional,tsqlCString, tsqlDESC, tsqlDESCENDING, tsqlDISTINCT, tsqlDEFAULT, tsqlDELETE, tsqlDO, tsqlDouble, tsqlDECLARE, tsqlDROP, tsqlDomain, tsqlDecimal, tsqlDate,tsqlDatabase, @@ -69,7 +67,7 @@ type tsqlPrecision, tsqlPRIMARY, tsqlProcedure, tsqlPosition, tsqlPlan, tsqlPassword, tsqlPage,tsqlPages,tsqlPageSize,tsqlPostEvent,tsqlPrivileges,tsqlPublic, tsqlRIGHT, tsqlROLE, tsqlReferences, tsqlRollBack, tsqlRelease, tsqlretain, tsqlReturningValues,tsqlReturns, tsqlrevoke, tsqlSELECT, tsqlSET, tsqlSINGULAR, tsqlSOME, tsqlSTARTING, tsqlSUM, tsqlSKIP,tsqlSUBTYPE,tsqlSize,tsqlSegment, tsqlSORT, tsqlSnapShot,tsqlSchema,tsqlShadow,tsqlSuspend,tsqlSQLCode,tsqlSmallint, - tSQLTABLE, tsqlText, tsqlTerm {not an FB reserved word, used in isql scripts}, tsqlTrigger, tsqlTime, tsqlTimeStamp, tsqlType, tsqlTo, tsqlTransaction, tsqlThen, + tSQLTABLE, tsqlText, tsqlTrigger, tsqlTime, tsqlTimeStamp, tsqlType, tsqlTo, tsqlTransaction, tsqlThen, tsqlUNION, tsqlUPDATE, tsqlUPPER, tsqlUNIQUE, tsqlUSER, tsqlValue, tsqlVALUES, tsqlVARIABLE, tsqlVIEW, tsqlVARCHAR,TSQLVARYING, tsqlWHERE, tsqlWITH, tsqlWHILE, tsqlWork, tsqlWhen @@ -89,15 +87,14 @@ const 'EOF','whitespace', 'String', 'identifier', - 'symbol literal', + 'symbol string', 'integer number','float number', 'comment', - ';' {value may be changed at run time to any symbol or set of symbols}, '(',')', '[',']', '?',',',':','.',';','>','<', '+','-','*','/','||', '=','>=','<=','<>', // Identifiers last: - 'ALL', 'AND', 'ANY', 'ASC', 'ASCENDING', 'AVG', 'ALTER', 'ADD','ACTIVE','ACTION', 'AS', 'AT', 'AUTO', 'AUTODDL', 'AFTER', 'ADMIN', + 'ALL', 'AND', 'ANY', 'ASC', 'ASCENDING', 'AVG', 'ALTER', 'ADD','ACTIVE','ACTION', 'AS', 'AT', 'AUTO', 'AFTER', 'ADMIN', 'BETWEEN', 'BINARY', 'BY', 'BLOB','BEGIN', 'BEFORE', 'COLLATE', 'CONTAINING', 'COUNT', 'CREATE', 'COLUMN', 'CONSTRAINT', 'CHAR','CHARACTER','CHECK', 'COMPUTED','CASCADE','CAST', 'COMMIT', 'CONNECT', 'CACHE','CONDITIONAL', 'CSTRING', 'DESC', 'DESCENDING', 'DISTINCT', 'DEFAULT', 'DELETE', 'DO', 'DOUBLE', 'DECLARE', 'DROP', 'DOMAIN', 'DECIMAL', 'DATE','DATABASE', @@ -115,7 +112,7 @@ const 'PRECISION', 'PRIMARY', 'PROCEDURE','POSITION','PLAN', 'PASSWORD','PAGE','PAGES','PAGE_SIZE','POST_EVENT','PRIVILEGES','PUBLIC', 'RIGHT', 'ROLE', 'REFERENCES', 'ROLLBACK','RELEASE', 'RETAIN', 'RETURNING_VALUES', 'RETURNS','REVOKE', 'SELECT', 'SET', 'SINGULAR', 'SOME', 'STARTING', 'SUM', 'SKIP','SUB_TYPE', 'SIZE', 'SEGMENT', 'SORT', 'SNAPSHOT','SCHEMA','SHADOW','SUSPEND','SQLCODE','SMALLINT', - 'TABLE', 'TEXT', 'TERM', 'TRIGGER', 'TIME', 'TIMESTAMP', 'TYPE', 'TO', 'TRANSACTION', 'THEN', + 'TABLE', 'TEXT', 'TRIGGER', 'TIME', 'TIMESTAMP', 'TYPE', 'TO', 'TRANSACTION', 'THEN', 'UNION', 'UPDATE', 'UPPER', 'UNIQUE', 'USER', 'VALUE','VALUES','VARIABLE', 'VIEW','VARCHAR','VARYING', 'WHERE', 'WITH', 'WHILE','WORK','WHEN' @@ -187,7 +184,6 @@ Type // Used to parse out an identifier/name and store it in the list of identifiers function DoIdentifier : TSQLToken; // Used to parse out a string containing symbols - // Also looks for tsqlStatementTerminator function DoSymbolString : TSQLToken; function DoMultiLineComment: TSQLToken; function DoNumericLiteral: TSQLToken; @@ -692,12 +688,6 @@ begin SetLength(FCurTokenString,Len); Move(TokenStart^,FCurTokenString[1],Len); - // Check if it is the statement terminator - if FCurTokenString=TokenInfos[tsqlStatementTerminator] then - begin - exit(tsqlStatementTerminator); - end; - // Check if this is a keyword or identifier/literal // Probably not (due to naming rules) but it doesn't hurt If FKeyWords.Count=0 then diff --git a/packages/fcl-db/src/sql/fpsqltree.pp b/packages/fcl-db/src/sql/fpsqltree.pp index 750ab9d52c..c2f0781f12 100644 --- a/packages/fcl-db/src/sql/fpsqltree.pp +++ b/packages/fcl-db/src/sql/fpsqltree.pp @@ -912,20 +912,6 @@ Type Property Arguments : string Read FArgument Write FArgument; end; - { TSQLSetTermStatement } - - TSQLSetTermStatement = Class(TSQLStatement) - private - FNewValue: string; - FOldValue: string; - Public - Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override; - // The first, new terminator in the SET TERM statement - Property NewTerminator : string Read FNewValue Write FNewValue; - // The second, old terminator in the SET TERM statement - Property OldTerminator : string Read FOldValue Write FOldValue; - end; - { TSQLCreateRoleStatement } TSQLCreateRoleStatement = Class(TSQLCreateOrAlterStatement) @@ -1890,16 +1876,6 @@ begin Result:='-- SET '+Arguments; end; -{ TSQLSetTermStatement } - -function TSQLSetTermStatement.GetAsSQL(Options: TSQLFormatOptions; - AIndent: Integer): TSQLStringType; -begin - // Note: we generate this as a comment as this is ISQL-specific and will generate - // errors when passed as SQL to servers - Result:='-- SET TERM '+NewTerminator+' '+OldTerminator; -end; - function TSQLElementList.GetE(AIndex : Integer): TSQLElement; begin Result:=TSQLElement(Items[AIndex]); diff --git a/packages/fcl-db/tests/tcparser.pas b/packages/fcl-db/tests/tcparser.pas index d4649cceb9..5552f63837 100644 --- a/packages/fcl-db/tests/tcparser.pas +++ b/packages/fcl-db/tests/tcparser.pas @@ -844,20 +844,6 @@ type procedure Test2RolesToUser; end; - { TTestSetParser } - - TTestSetParser = Class(TTestSQLParser) - published - procedure TestSetAutoDDL; - procedure TestSetAutoDDLOn; - procedure TestSetAutoDDLOff; - procedure TestSetAutoDDLCreateProcedure; - procedure TestSetTerm; - procedure TestSetTermSemicolon; - procedure TestSetTermCreateProcedure; - procedure TestSetTermCreateProcedureVar; - end; - { TTestGlobalParser } TTestGlobalParser = Class(TTestSQLParser) @@ -869,138 +855,6 @@ implementation uses typinfo; -{ TTestSetParser } - -procedure TTestSetParser.TestSetAutoDDL; -Const - Desired='-- SET AUTODDL ON'; -Var - I: TSQLSetISQLStatement; -begin - CreateParser('SET AUTODDL;'); - FToFree:=Parser.Parse; - I:=TSQLSetISQLStatement(CheckClass(FToFree,TSQLSetISQLStatement)); - AssertEquals('GetAsSQL',I.GetAsSQL([]),Desired); -end; - -procedure TTestSetParser.TestSetAutoDDLOn; -Const - Desired='-- SET AUTODDL ON'; -Var - I: TSQLSetISQLStatement; -begin - CreateParser('SET AUTODDL ON;'); - FToFree:=Parser.Parse; - I:=TSQLSetISQLStatement(CheckClass(FToFree,TSQLSetISQLStatement)); - AssertEquals('GetAsSQL',I.GetAsSQL([]),Desired); -end; - -procedure TTestSetParser.TestSetAutoDDLOff; -Const - Desired='-- SET AUTODDL OFF'; -Var - I: TSQLSetISQLStatement; -begin - CreateParser('SET AUTODDL OFF;'); - FToFree:=Parser.Parse; - I:=TSQLSetISQLStatement(CheckClass(FToFree,TSQLSetISQLStatement)); - AssertEquals('GetAsSQL',I.GetAsSQL([]),Desired); -end; - -procedure TTestSetParser.TestSetAutoDDLCreateProcedure; -Const - SQL = - 'SET AUTODDL ;'+LineEnding+ - ''+LineEnding+ - 'CREATE PROCEDURE PROCNAME'+LineEnding+ - 'AS'+LineEnding+ - 'BEGIN'+LineEnding+ - ' /* Empty procedure */'+LineEnding+ - 'END;'; -begin - CreateParser(SQL); - Parser.ParseScript; - //todo: test name etc of procedure -end; - -procedure TTestSetParser.TestSetTerm; -Var - S : TSQLSetTermStatement; - -begin - CreateParser('SET TERM ^ ;'); - FToFree:=Parser.Parse; - S:=TSQLSetTermStatement(CheckClass(FToFree,TSQLSetTermStatement)); - AssertEquals('New terminator','^',S.NewTerminator); - AssertEquals('Closing semicolon',tsqlSEMICOLON,Parser.CurrentToken); - Parser.GetNextToken; - AssertEquals('End of stream reached',tsqlEOF,Parser.CurrentToken); -end; - -procedure TTestSetParser.TestSetTermSemicolon; -Var - S : TSQLSetTermStatement; - -begin - CreateParser('SET TERM ; ^'); - FParser.SetStatementTerminator('^'); // emulate a previous SET TERM ^ ; - AssertEquals('Closing statement terminator should match ^','^',Parser.GetStatementTerminator); - FToFree:=Parser.Parse; - S:=TSQLSetTermStatement(CheckClass(FToFree,TSQLSetTermStatement)); - AssertEquals('New terminator',';',S.NewTerminator); - AssertEquals('Closing terminator',tsqlStatementTerminator,Parser.CurrentToken); - AssertEquals('Closing ^','^',Parser.CurrentTokenString); - Parser.GetNextToken; - AssertEquals('End of stream reached',tsqlEOF,Parser.CurrentToken); -end; - -procedure TTestSetParser.TestSetTermCreateProcedure; -Const - SQL = - 'SET TERM ^ ;'+LineEnding+ - ''+LineEnding+ - 'CREATE PROCEDURE PROCNAME'+LineEnding+ - 'AS'+LineEnding+ - 'BEGIN'+LineEnding+ - ' /* Empty procedure */'+LineEnding+ - 'END^'+LineEnding+ - ''+LineEnding+ - 'SET TERM ; ^'; - -begin - CreateParser(SQL); - Parser.ParseScript; - //todo: test name etc of procedure -end; - -procedure TTestSetParser.TestSetTermCreateProcedureVar; -// Procedure with variable -Const - SQL = - 'SET TERM ^ ;'+LineEnding+ - 'CREATE PROCEDURE PROCWITHVAR'+LineEnding+ - 'RETURNS (LANGUAGES VARCHAR(15) CHARACTER SET NONE)'+LineEnding+ - 'AS'+LineEnding+ - 'DECLARE VARIABLE i INTEGER;'+LineEnding+ - 'BEGIN'+LineEnding+ - ' i = 1;'+LineEnding+ - ' WHILE (i <= 5) DO'+LineEnding+ - ' BEGIN'+LineEnding+ - ' SELECT language_req[:i] FROM job'+LineEnding+ - ' INTO :languages;'+LineEnding+ - ' i = i +1;'+LineEnding+ - ' SUSPEND;'+LineEnding+ - ' END'+LineEnding+ - 'END ^'+LineEnding+ - 'SET TERM ; ^'; - -begin - CreateParser(SQL); - Parser.ParseScript; - //todo: test name etc of procedure -end; - - { TTestGlobalParser } procedure TTestGlobalParser.TestEmpty; @@ -1040,7 +894,7 @@ end; procedure TTestSQLParser.SetUp; begin - FParser.SetStatementTerminator(';'); + // nothing yet end; procedure TTestSQLParser.TearDown; @@ -8317,7 +8171,6 @@ initialization TTestDeclareExternalFunctionParser, TTestGrantParser, TTestRevokeParser, - TTestSetParser, TTestGlobalParser]); end.