mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-11 11:29:29 +02:00
- fcl-db: sql parser
- remove support for SET TERM/SET AUTODDL as it does not fall within Firebird SQL git-svn-id: trunk@27961 -
This commit is contained in:
parent
d7f9265eba
commit
951d128042
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
|
@ -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.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user