* fcl-db: sql parser:

- support reading (and ignoring) SET AUTODDL statements generated by isql.
  This allows the parser to read isql-generated metadata extraction scripts from Firebird databases
- tests

git-svn-id: trunk@27921 -
This commit is contained in:
reiniero 2014-06-10 08:47:56 +00:00
parent 041b4681e9
commit 0782f4f853
5 changed files with 104 additions and 48 deletions

View File

@ -2,6 +2,8 @@ SQL scanner/parser/Abstract Syntax Tree units
This can parse the complete Firebird dialect 3 SQL syntax (which should come pretty close to SQL-92) and builds a syntax tree from it. The Abstract Syntax Tree can re-create the SQL with limited formatting support. This can parse the complete Firebird dialect 3 SQL syntax (which should come pretty close to SQL-92) and builds a syntax tree from it. The Abstract Syntax Tree can re-create the SQL with limited formatting support.
Additionally, the parser has limited support for SET commands used by the Firebird isql tool, enough to read DDL dumps from databases generated by isql.
It comes with extensive test suite (over 830 test cases; see the fcl-db\tests directory). It has been tested on almost 400,000 SQL statements. Nevertheless bugs may remain, so any test results you may produce are welcome. Especially the GRANT/REVOKE statements are tested only theoretically. It comes with extensive test suite (over 830 test cases; see the fcl-db\tests directory). It has been tested on almost 400,000 SQL statements. Nevertheless bugs may remain, so any test results you may produce are welcome. Especially the GRANT/REVOKE statements are tested only theoretically.
The scanner/parser have been designed so they should be able to cope with other SQL dialects (using a set of flags) such as MySQL, but this support is currently not implemented. The scanner/parser have been designed so they should be able to cope with other SQL dialects (using a set of flags) such as MySQL, but this support is currently not implemented.

View File

@ -3412,8 +3412,22 @@ begin
// On Entry, we're on the SET statement // On Entry, we're on the SET statement
Consume(tsqlSet); Consume(tsqlSet);
Case CurrentToken of Case CurrentToken of
tsqlGenerator : Result:=ParseSetGeneratorStatement(AParent); tsqlGenerator : Result:=ParseSetGeneratorStatement(AParent); //SET GENERATOR
tsqlTerm : Result:=ParseSetTermStatement(AParent); tsqlTerm : Result:=ParseSetTermStatement(AParent); //SET TERM
tsqlAutoDDL : //SET AUTODDL: ignore these isql commands for now
begin
// SET AUTODDL ON, SET AUTODDL OFF; optional arguments
if (PeekNextToken in [tsqlOn, tsqlOff]) then
begin
GetNextToken;
Consume([tsqlOn,tsqlOff]);
end
else
begin
Consume(tsqlAutoDDL);
end;
Result:=nil; //ignore
end;
else else
// For the time being // For the time being
UnexpectedToken; UnexpectedToken;

View File

@ -50,7 +50,7 @@ type
tsqlEQ,tsqlGE,tsqlLE,tsqlNE, tsqlEQ,tsqlGE,tsqlLE,tsqlNE,
{ Reserved words/keywords start here. They must be last } { Reserved words/keywords start here. They must be last }
{ Note: if adding before tsqlALL or after tsqlWHEN please update FirstKeyword/LastKeyword } { 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,tsqlAfter,tsqlAdmin, 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,
tsqlBETWEEN, tsqlBinary, tsqlBY, tsqlBLOB, tsqlBegin, tsqlBefore, tsqlBETWEEN, tsqlBinary, tsqlBY, tsqlBLOB, tsqlBegin, tsqlBefore,
tsqlCOLLATE, tsqlCONTAINING, tsqlCOUNT, tsqlCREATE, tsqlCOLUMN, tsqlCONSTRAINT, tsqlChar,tsqlCHARACTER, tsqlCHECK, tsqlComputed,tsqlCASCADE, tsqlCast, tsqlCommit,tsqlConnect,tsqlCache,tsqlConditional,tsqlCString, 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, tsqlDESC, tsqlDESCENDING, tsqlDISTINCT, tsqlDEFAULT, tsqlDELETE, tsqlDO, tsqlDouble, tsqlDECLARE, tsqlDROP, tsqlDomain, tsqlDecimal, tsqlDate,tsqlDatabase,
@ -64,11 +64,11 @@ type
tsqlLEFT, tsqlLIKE, tsqlLength, tsqlLEFT, tsqlLIKE, tsqlLength,
tsqlMAX, tsqlMIN, tsqlMERGE, tsqlManual, tsqlModuleName, tsqlMAX, tsqlMIN, tsqlMERGE, tsqlManual, tsqlModuleName,
tsqlNOT, tsqlNULL, tsqlNUMERIC , tsqlNChar, tsqlNATIONAL,tsqlNO, tsqlNatural, tsqlNOT, tsqlNULL, tsqlNUMERIC , tsqlNChar, tsqlNATIONAL,tsqlNO, tsqlNatural,
tsqlON, tsqlOR, tsqlORDER, tsqlOUTER, tsqlOption, tsqlOFF {not an FB reserved word; used in isql scripts}, tsqlON, tsqlOR, tsqlORDER, tsqlOUTER, tsqlOption,
tsqlPrecision, tsqlPRIMARY, tsqlProcedure, tsqlPosition, tsqlPlan, tsqlPassword, tsqlPage,tsqlPages,tsqlPageSize,tsqlPostEvent,tsqlPrivileges,tsqlPublic, tsqlPrecision, tsqlPRIMARY, tsqlProcedure, tsqlPosition, tsqlPlan, tsqlPassword, tsqlPage,tsqlPages,tsqlPageSize,tsqlPostEvent,tsqlPrivileges,tsqlPublic,
tsqlRIGHT, tsqlROLE, tsqlReferences, tsqlRollBack, tsqlRelease, tsqlretain, tsqlReturningValues,tsqlReturns, tsqlrevoke, 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, tsqlSELECT, tsqlSET, tsqlSINGULAR, tsqlSOME, tsqlSTARTING, tsqlSUM, tsqlSKIP,tsqlSUBTYPE,tsqlSize,tsqlSegment, tsqlSORT, tsqlSnapShot,tsqlSchema,tsqlShadow,tsqlSuspend,tsqlSQLCode,tsqlSmallint,
tSQLTABLE, tsqlText, tsqlTerm, tsqlTrigger, tsqlTime, tsqlTimeStamp, tsqlType, tsqlTo, tsqlTransaction, tsqlThen, tSQLTABLE, tsqlText, tsqlTerm {not an FB reserved word, used in isql scripts}, tsqlTrigger, tsqlTime, tsqlTimeStamp, tsqlType, tsqlTo, tsqlTransaction, tsqlThen,
tsqlUNION, tsqlUPDATE, tsqlUPPER, tsqlUNIQUE, tsqlUSER, tsqlUNION, tsqlUPDATE, tsqlUPPER, tsqlUNIQUE, tsqlUSER,
tsqlValue, tsqlVALUES, tsqlVARIABLE, tsqlVIEW, tsqlVARCHAR,TSQLVARYING, tsqlValue, tsqlVALUES, tsqlVARIABLE, tsqlVIEW, tsqlVARCHAR,TSQLVARYING,
tsqlWHERE, tsqlWITH, tsqlWHILE, tsqlWork, tsqlWhen tsqlWHERE, tsqlWITH, tsqlWHILE, tsqlWork, tsqlWhen
@ -96,7 +96,7 @@ const
'+','-','*','/','||', '+','-','*','/','||',
'=','>=','<=','<>', '=','>=','<=','<>',
// Identifiers last: // Identifiers last:
'ALL', 'AND', 'ANY', 'ASC', 'ASCENDING', 'AVG', 'ALTER', 'ADD','ACTIVE','ACTION', 'AS', 'AT', 'AUTO', 'AFTER', 'ADMIN', 'ALL', 'AND', 'ANY', 'ASC', 'ASCENDING', 'AVG', 'ALTER', 'ADD','ACTIVE','ACTION', 'AS', 'AT', 'AUTO', 'AUTODDL', 'AFTER', 'ADMIN',
'BETWEEN', 'BINARY', 'BY', 'BLOB','BEGIN', 'BEFORE', 'BETWEEN', 'BINARY', 'BY', 'BLOB','BEGIN', 'BEFORE',
'COLLATE', 'CONTAINING', 'COUNT', 'CREATE', 'COLUMN', 'CONSTRAINT', 'CHAR','CHARACTER','CHECK', 'COMPUTED','CASCADE','CAST', 'COMMIT', 'CONNECT', 'CACHE','CONDITIONAL', 'CSTRING', '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', 'DESC', 'DESCENDING', 'DISTINCT', 'DEFAULT', 'DELETE', 'DO', 'DOUBLE', 'DECLARE', 'DROP', 'DOMAIN', 'DECIMAL', 'DATE','DATABASE',
@ -110,7 +110,7 @@ const
'LEFT', 'LIKE', 'LENGTH', 'LEFT', 'LIKE', 'LENGTH',
'MAX', 'MIN', 'MERGE', 'MANUAL', 'MODULE_NAME', 'MAX', 'MIN', 'MERGE', 'MANUAL', 'MODULE_NAME',
'NOT', 'NULL', 'NUMERIC','NCHAR','NATIONAL', 'NO', 'NATURAL', 'NOT', 'NULL', 'NUMERIC','NCHAR','NATIONAL', 'NO', 'NATURAL',
'ON', 'OR', 'ORDER', 'OUTER', 'OPTION', 'OFF', 'ON', 'OR', 'ORDER', 'OUTER', 'OPTION',
'PRECISION', 'PRIMARY', 'PROCEDURE','POSITION','PLAN', 'PASSWORD','PAGE','PAGES','PAGE_SIZE','POST_EVENT','PRIVILEGES','PUBLIC', 'PRECISION', 'PRIMARY', 'PROCEDURE','POSITION','PLAN', 'PASSWORD','PAGE','PAGES','PAGE_SIZE','POST_EVENT','PRIVILEGES','PUBLIC',
'RIGHT', 'ROLE', 'REFERENCES', 'ROLLBACK','RELEASE', 'RETAIN', 'RETURNING_VALUES', 'RETURNS','REVOKE', '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', 'SELECT', 'SET', 'SINGULAR', 'SOME', 'STARTING', 'SUM', 'SKIP','SUB_TYPE', 'SIZE', 'SEGMENT', 'SORT', 'SNAPSHOT','SCHEMA','SHADOW','SUSPEND','SQLCODE','SMALLINT',

View File

@ -2014,14 +2014,14 @@ begin
AssertSQL(S,'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]); AssertSQL(S,'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]);
P:=TSQLProcedureParamDef.Create(Nil); P:=TSQLProcedureParamDef.Create(Nil);
P.ParamName:=CreateIdentifier('A'); P.ParamName:=CreateIdentifier('A');
P.ParamType:=CreatetypeDefinition(sdtInteger,0); P.ParamType:=CreateTypeDefinition(sdtInteger,0);
FToFree:=S; FToFree:=S;
S.LocalVariables.Add(P); S.LocalVariables.Add(P);
AssertSQL(S,'DECLARE VARIABLE A INT;'+sLineBreak+'BEGIN'+sLineBreak+'EXIT;'+sLineBreak+'END'); AssertSQL(S,'DECLARE VARIABLE A INT;'+sLineBreak+'BEGIN'+sLineBreak+'EXIT;'+sLineBreak+'END');
AssertSQL(S,'DECLARE VARIABLE A INT;'+sLineBreak+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]); AssertSQL(S,'DECLARE VARIABLE A INT;'+sLineBreak+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]);
P:=TSQLProcedureParamDef.Create(Nil); P:=TSQLProcedureParamDef.Create(Nil);
P.ParamName:=CreateIdentifier('B'); P.ParamName:=CreateIdentifier('B');
P.ParamType:=CreatetypeDefinition(sdtChar,5); P.ParamType:=CreateTypeDefinition(sdtChar,5);
FToFree:=S; FToFree:=S;
S.LocalVariables.Add(P); S.LocalVariables.Add(P);
AssertSQL(S,'DECLARE VARIABLE A INT;'+sLineBreak+'DECLARE VARIABLE B CHAR(5);'+sLineBreak+'BEGIN'+sLineBreak+'EXIT;'+sLineBreak+'END'); AssertSQL(S,'DECLARE VARIABLE A INT;'+sLineBreak+'DECLARE VARIABLE B CHAR(5);'+sLineBreak+'BEGIN'+sLineBreak+'EXIT;'+sLineBreak+'END');
@ -2046,7 +2046,7 @@ begin
AssertSQL(S,H+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]); AssertSQL(S,H+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]);
P:=TSQLProcedureParamDef.Create(Nil); P:=TSQLProcedureParamDef.Create(Nil);
P.ParamName:=CreateIdentifier('I'); P.ParamName:=CreateIdentifier('I');
P.ParamType:=CreatetypeDefinition(sdtInteger,0); P.ParamType:=CreateTypeDefinition(sdtInteger,0);
FToFree:=S; FToFree:=S;
S.InputVariables.Add(P); S.InputVariables.Add(P);
H:=PHEAD+' (I INT)'+sLineBreak+'AS'+sLineBreak; H:=PHEAD+' (I INT)'+sLineBreak+'AS'+sLineBreak;
@ -2054,7 +2054,7 @@ begin
AssertSQL(S,H+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]); AssertSQL(S,H+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]);
P:=TSQLProcedureParamDef.Create(Nil); P:=TSQLProcedureParamDef.Create(Nil);
P.ParamName:=CreateIdentifier('J'); P.ParamName:=CreateIdentifier('J');
P.ParamType:=CreatetypeDefinition(sdtChar,5); P.ParamType:=CreateTypeDefinition(sdtChar,5);
FToFree:=S; FToFree:=S;
S.InputVariables.Add(P); S.InputVariables.Add(P);
H:=PHEAD+' (I INT , J CHAR(5))'+sLineBreak+'AS'+sLineBreak; H:=PHEAD+' (I INT , J CHAR(5))'+sLineBreak+'AS'+sLineBreak;
@ -2062,7 +2062,7 @@ begin
AssertSQL(S,H+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]); AssertSQL(S,H+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]);
P:=TSQLProcedureParamDef.Create(Nil); P:=TSQLProcedureParamDef.Create(Nil);
P.ParamName:=CreateIdentifier('R'); P.ParamName:=CreateIdentifier('R');
P.ParamType:=CreatetypeDefinition(sdtInteger,0); P.ParamType:=CreateTypeDefinition(sdtInteger,0);
FToFree:=S; FToFree:=S;
S.OutputVariables.Add(P); S.OutputVariables.Add(P);
H:=PHEAD+' (I INT , J CHAR(5))'+sLineBreak+'RETURNS (R INT)'+sLineBreak+'AS'+sLineBreak; H:=PHEAD+' (I INT , J CHAR(5))'+sLineBreak+'RETURNS (R INT)'+sLineBreak+'AS'+sLineBreak;
@ -2070,7 +2070,7 @@ begin
AssertSQL(S,H+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]); AssertSQL(S,H+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]);
P:=TSQLProcedureParamDef.Create(Nil); P:=TSQLProcedureParamDef.Create(Nil);
P.ParamName:=CreateIdentifier('S'); P.ParamName:=CreateIdentifier('S');
P.ParamType:=CreatetypeDefinition(sdtChar,5); P.ParamType:=CreateTypeDefinition(sdtChar,5);
FToFree:=S; FToFree:=S;
S.OutputVariables.Add(P); S.OutputVariables.Add(P);
H:=PHEAD+' (I INT , J CHAR(5))'+sLineBreak+'RETURNS (R INT , S CHAR(5))'+sLineBreak+'AS'+sLineBreak; H:=PHEAD+' (I INT , J CHAR(5))'+sLineBreak+'RETURNS (R INT , S CHAR(5))'+sLineBreak+'AS'+sLineBreak;
@ -2078,14 +2078,14 @@ begin
AssertSQL(S,H+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]); AssertSQL(S,H+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]);
P:=TSQLProcedureParamDef.Create(Nil); P:=TSQLProcedureParamDef.Create(Nil);
P.ParamName:=CreateIdentifier('A'); P.ParamName:=CreateIdentifier('A');
P.ParamType:=CreatetypeDefinition(sdtInteger,0); P.ParamType:=CreateTypeDefinition(sdtInteger,0);
FToFree:=S; FToFree:=S;
S.LocalVariables.Add(P); S.LocalVariables.Add(P);
AssertSQL(S,H+'DECLARE VARIABLE A INT;'+sLineBreak+'BEGIN'+sLineBreak+'EXIT;'+sLineBreak+'END'); AssertSQL(S,H+'DECLARE VARIABLE A INT;'+sLineBreak+'BEGIN'+sLineBreak+'EXIT;'+sLineBreak+'END');
AssertSQL(S,H+'DECLARE VARIABLE A INT;'+sLineBreak+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]); AssertSQL(S,H+'DECLARE VARIABLE A INT;'+sLineBreak+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]);
P:=TSQLProcedureParamDef.Create(Nil); P:=TSQLProcedureParamDef.Create(Nil);
P.ParamName:=CreateIdentifier('B'); P.ParamName:=CreateIdentifier('B');
P.ParamType:=CreatetypeDefinition(sdtChar,5); P.ParamType:=CreateTypeDefinition(sdtChar,5);
FToFree:=S; FToFree:=S;
S.LocalVariables.Add(P); S.LocalVariables.Add(P);
AssertSQL(S,H+'DECLARE VARIABLE A INT;'+sLineBreak+'DECLARE VARIABLE B CHAR(5);'+sLineBreak+'BEGIN'+sLineBreak+'EXIT;'+sLineBreak+'END'); AssertSQL(S,H+'DECLARE VARIABLE A INT;'+sLineBreak+'DECLARE VARIABLE B CHAR(5);'+sLineBreak+'BEGIN'+sLineBreak+'EXIT;'+sLineBreak+'END');
@ -2141,14 +2141,14 @@ begin
AssertSQL(S,H+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]); AssertSQL(S,H+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]);
P:=TSQLProcedureParamDef.Create(Nil); P:=TSQLProcedureParamDef.Create(Nil);
P.ParamName:=CreateIdentifier('A'); P.ParamName:=CreateIdentifier('A');
P.ParamType:=CreatetypeDefinition(sdtInteger,0); P.ParamType:=CreateTypeDefinition(sdtInteger,0);
FToFree:=S; FToFree:=S;
S.LocalVariables.Add(P); S.LocalVariables.Add(P);
AssertSQL(S,H+'DECLARE VARIABLE A INT;'+sLineBreak+'BEGIN'+sLineBreak+'EXIT;'+sLineBreak+'END'); AssertSQL(S,H+'DECLARE VARIABLE A INT;'+sLineBreak+'BEGIN'+sLineBreak+'EXIT;'+sLineBreak+'END');
AssertSQL(S,H+'DECLARE VARIABLE A INT;'+sLineBreak+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]); AssertSQL(S,H+'DECLARE VARIABLE A INT;'+sLineBreak+'BEGIN'+sLineBreak+' EXIT;'+sLineBreak+'END',[sfoIndentProcedureBlock]);
P:=TSQLProcedureParamDef.Create(Nil); P:=TSQLProcedureParamDef.Create(Nil);
P.ParamName:=CreateIdentifier('B'); P.ParamName:=CreateIdentifier('B');
P.ParamType:=CreatetypeDefinition(sdtChar,5); P.ParamType:=CreateTypeDefinition(sdtChar,5);
FToFree:=S; FToFree:=S;
S.LocalVariables.Add(P); S.LocalVariables.Add(P);
AssertSQL(S,H+'DECLARE VARIABLE A INT;'+sLineBreak+'DECLARE VARIABLE B CHAR(5);'+sLineBreak+'BEGIN'+sLineBreak+'EXIT;'+sLineBreak+'END'); AssertSQL(S,H+'DECLARE VARIABLE A INT;'+sLineBreak+'DECLARE VARIABLE B CHAR(5);'+sLineBreak+'BEGIN'+sLineBreak+'EXIT;'+sLineBreak+'END');

View File

@ -844,10 +844,14 @@ type
procedure Test2RolesToUser; procedure Test2RolesToUser;
end; end;
{ TTestTermParser } { TTestSetParser }
TTestTermParser = Class(TTestSQLParser) TTestSetParser = Class(TTestSQLParser)
published published
procedure TestSetAutoDDL;
procedure TestSetAutoDDLOn;
procedure TestSetAutoDDLOff;
procedure TestSetAutoDDLCreateProcedure;
procedure TestSetTerm; procedure TestSetTerm;
procedure TestSetTermSemicolon; procedure TestSetTermSemicolon;
procedure TestSetTermCreateProcedure; procedure TestSetTermCreateProcedure;
@ -865,9 +869,43 @@ implementation
uses typinfo; uses typinfo;
{ TTestTermParser } { TTestSetParser }
procedure TTestTermParser.TestSetTerm; procedure TTestSetParser.TestSetAutoDDL;
begin
CreateParser('SET AUTODDL;');
AssertNull('SET AUTODDL should be ignored and give nil result',Parser.Parse);
end;
procedure TTestSetParser.TestSetAutoDDLOn;
begin
CreateParser('SET AUTODDL ON;');
AssertNull('SET AUTODDL should be ignored and give nil result',Parser.Parse);
end;
procedure TTestSetParser.TestSetAutoDDLOff;
begin
CreateParser('SET AUTODDL OFF;');
AssertNull('SET AUTODDL should be ignored and give nil result',Parser.Parse);
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 Var
S : TSQLSetTermStatement; S : TSQLSetTermStatement;
@ -881,7 +919,7 @@ begin
AssertEquals('End of stream reached',tsqlEOF,Parser.CurrentToken); AssertEquals('End of stream reached',tsqlEOF,Parser.CurrentToken);
end; end;
procedure TTestTermParser.TestSetTermSemicolon; procedure TTestSetParser.TestSetTermSemicolon;
Var Var
S : TSQLSetTermStatement; S : TSQLSetTermStatement;
@ -898,48 +936,50 @@ begin
AssertEquals('End of stream reached',tsqlEOF,Parser.CurrentToken); AssertEquals('End of stream reached',tsqlEOF,Parser.CurrentToken);
end; end;
procedure TTestTermParser.TestSetTermCreateProcedure; procedure TTestSetParser.TestSetTermCreateProcedure;
Const Const
SQL = SQL =
'SET TERM ^ ;'+#13+#10+ 'SET TERM ^ ;'+LineEnding+
''+#13+#10+ ''+LineEnding+
'CREATE PROCEDURE PROCNAME'+#13+#10+ 'CREATE PROCEDURE PROCNAME'+LineEnding+
'AS'+#13+#10+ 'AS'+LineEnding+
'BEGIN'+#13+#10+ 'BEGIN'+LineEnding+
' /* Empty procedure */'+#13+#10+ ' /* Empty procedure */'+LineEnding+
'END^'+#13+#10+ 'END^'+LineEnding+
''+#13+#10+ ''+LineEnding+
'SET TERM ; ^'; 'SET TERM ; ^';
begin begin
CreateParser(SQL); CreateParser(SQL);
Parser.ParseScript; Parser.ParseScript;
//todo: test name etc of procedure
end; end;
procedure TTestTermParser.TestSetTermCreateProcedureVar; procedure TTestSetParser.TestSetTermCreateProcedureVar;
// Procedure with variable // Procedure with variable
Const Const
SQL = SQL =
'SET TERM ^ ;'+#13+#10+ 'SET TERM ^ ;'+LineEnding+
'CREATE PROCEDURE PROCWITHVAR'+#13+#10+ 'CREATE PROCEDURE PROCWITHVAR'+LineEnding+
'RETURNS (LANGUAGES VARCHAR(15) CHARACTER SET NONE)'+#13+#10+ 'RETURNS (LANGUAGES VARCHAR(15) CHARACTER SET NONE)'+LineEnding+
'AS'+#13+#10+ 'AS'+LineEnding+
'DECLARE VARIABLE i INTEGER;'+#13+#10+ 'DECLARE VARIABLE i INTEGER;'+LineEnding+
'BEGIN'+#13+#10+ 'BEGIN'+LineEnding+
' i = 1;'+#13+#10+ ' i = 1;'+LineEnding+
' WHILE (i <= 5) DO'+#13+#10+ ' WHILE (i <= 5) DO'+LineEnding+
' BEGIN'+#13+#10+ ' BEGIN'+LineEnding+
' SELECT language_req[:i] FROM job'+#13+#10+ ' SELECT language_req[:i] FROM job'+LineEnding+
' INTO :languages;'+#13+#10+ ' INTO :languages;'+LineEnding+
' i = i +1;'+#13+#10+ ' i = i +1;'+LineEnding+
' SUSPEND;'+#13+#10+ ' SUSPEND;'+LineEnding+
' END'+#13+#10+ ' END'+LineEnding+
'END ^'+#13+#10+ 'END ^'+LineEnding+
'SET TERM ; ^'; 'SET TERM ; ^';
begin begin
CreateParser(SQL); CreateParser(SQL);
Parser.ParseScript; Parser.ParseScript;
//todo: test name etc of procedure
end; end;
@ -8259,7 +8299,7 @@ initialization
TTestDeclareExternalFunctionParser, TTestDeclareExternalFunctionParser,
TTestGrantParser, TTestGrantParser,
TTestRevokeParser, TTestRevokeParser,
TTestTermParser, TTestSetParser,
TTestGlobalParser]); TTestGlobalParser]);
end. end.