{$I ffdefine.inc} //<-- soner added unit FFSQL; {============================================================================== FFSQL 0.0.0.102 Date of Generation: 11/19/2002 2:45 PM Comment: Author: Copyright: This unit was generated by Coco/R for Delphi (www.tetzel.com) Any code in this file that you edit manually will be over-written when the file is regenerated. ==============================================================================} interface uses SysUtils,Classes,CocoBase,FFSQLDef,FFSQLDB,Dialogs; const maxT = 125; type SymbolSet = array[0..maxT div setsize] of TBitSet; EFFSQL = class(Exception); TFFSQL = class; TFFSQLScanner = class(TCocoRScanner) private FOwner : TFFSQL; function CharInIgnoreSet(const Ch : char) : boolean; procedure CheckLiteral(var Sym : integer); function Equal(s : string) : boolean; function Comment : boolean; protected procedure NextCh; override; public constructor Create; procedure Get(var sym : integer); override; // Gets next symbol from source file property CurrentSymbol; property NextSymbol; property OnStatusUpdate; property Owner : TFFSQL read fOwner write fOwner; property ScannerError; property SrcStream; end; { TFFSQLScanner } TFFSQL = class(TCocoRGrammar) private { strictly internal variables } symSet : array[0..7] of SymbolSet; // symSet[0] = allSyncSyms function GetBuildDate : TDateTime; function GetVersion : string; function GetVersionStr : string; procedure SetVersion(const Value : string); function GetVersionInfo : string; function _In(var s : SymbolSet; x : integer) : boolean; procedure InitSymSet; {Production methods} procedure _SimpleAlias (var TableRef: TffSqlTableRef); procedure _BooleanLiteral (Parent: TFFSqlNode; var BooleanLiteral: TFFSqlBooleanLiteral); procedure _IntervalLiteral (Parent: TFFSqlNode; var IntervalLiteral: TFFSqlIntervalLiteral); procedure _TimestampLiteral (Parent: TFFSqlNode; var TimestampLiteral: TFFSqlTimestampLiteral); procedure _TimeLiteral (Parent: TFFSqlNode; var TimeLiteral: TFFSqlTimeLiteral); procedure _DateLiteral (Parent: TFFSqlNode; var DateLiteral: TFFSqlDateLiteral); procedure _StringLiteral (Parent: TFFSqlNode; var StringLiteral: TFFSqlStringLiteral); procedure _IntegerLiteral (Parent: TFFSqlNode; var IntegerLiteral: TFFSqlIntegerLiteral); procedure _FloatLiteral (Parent: TFFSqlNode; var FloatLiteral: TFFSqlFloatLiteral); procedure _WhenClause (Parent : TFFSqlNode; var WhenClause : TFFSqlWhenClause); procedure _WhenClauseList (Parent: TFFSqlNode; var WhenClauseList : TFFSqlWhenClauseList); procedure _CoalesceExpression (Parent: TFFSqlNode; var CoalesceExp: TFFSqlCoalesceExpression); procedure _CaseExpression (Parent: TFFSqlNode; var CaseExp: TFFSqlCaseExpression); procedure _ScalarFunction (Parent: TFFSqlNode; var Func: TFFSqlScalarFunc); procedure _Param (Parent: TFFSqlNode; var Param: TFFSqlParam); procedure _Literal (Parent: TFFSqlNode; var Literal: TFFSqlLiteral); procedure _Factor (Parent: TFFSqlNode; var Factor : TFFSqlFactor; MulOp: TFFSqlMulOp); procedure _Term (Parent: TFFSqlNode; var Term : TFFSqlTerm; AddOp : TFFSqlAddOp); procedure _SimpleExpressionList (Parent: TFFSqlNode; var SimpleExpressionList: TFFSqlSimpleExpressionList); procedure _IsTest (Parent: TFFSqlNode; var IsTest: TFFSqlIsTest); procedure _MatchClause (Parent: TFFSqlNode; var MatchClause: TFFSqlMatchClause); procedure _InClause (Parent: TFFSqlNode; var InClause: TFFSqlInClause; Negated: Boolean); procedure _LikeClause (Parent: TFFSqlNode; var LikeClause: TFFSqlLikeClause; Negated: Boolean); procedure _BetweenClause (Parent: TFFSqlNode; var BetweenClause: TFFSqlBetweenClause; Negated: Boolean); procedure _AllOrAnyClause (Parent: TFFSqlNode; var AllOrAny: TFFSqlAllOrAnyClause); procedure _UniqueClause (Parent: TFFSqlNode; var Unique: TFFSqlUniqueClause); procedure _ExistsClause (Parent: TFFSqlNode; var Exists: TFFSqlExistsClause); procedure _CondPrimary (Parent: TFFSqlNode; var CondPrimary : TFFSqlCondPrimary); procedure _CondFactor (Parent: TFFSqlNode; var CondFactor: TFFSqlCondFactor); procedure _CondTerm (Parent: TFFSqlNode; var CondTerm : TFFSqlCondTerm); procedure _GroupColumn (Parent: TFFSqlNode; var Col : TFFSqlGroupColumn); procedure _FieldRef (Parent: TFFSqlNode; var FieldRef: TFFSqlFieldRef); procedure _Aggregate (Parent: TFFSqlNode; var Aggregate : TFFSqlAggregate); procedure _Column (Parent: TFFSqlNode; var Col : TFFSqlColumn); procedure _ColumnAlias (var Selection : TFFSqlSelection); procedure _Selection (SelectionList: TFFSqlSelectionList); procedure _OrderColumn (Parent: TFFSqlNode; var Col : TFFSqlOrderColumn); procedure _OrderItem (Parent: TFFSqlNode; var OrderItem : TFFSqlOrderItem); procedure _UpdateItem (Parent: TFFSqlNode; var UpdateItem : TFFSqlUpdateItem); procedure _UpdateList (Parent: TFFSqlNode; var UpdateList : TFFSqlUpdateList); procedure _SimpleTableRef (Parent: TFFSqlNode; var TableRef: TffSqlTableRef); procedure _SimpleExpression (Parent: TFFSqlNode; var SimpleExpression : TFFSqlSimpleExpression); procedure _ValueItem (Parent: TFFSqlNode; var ValueItem : TFFSqlValueItem); procedure _InsertItem (Parent: TFFSqlNode; var InsertItem : TFFSqlInsertItem); procedure _ValueList (Parent: TFFSqlNode; var ValueList : TFFSqlValueList); procedure _TableConstructor (Parent: TFFSqlNode; var ValueList: TffSqlValueList); procedure _NonJoinTablePrimary (Parent: TffSqlNode; var NonJoinTablePrimary: TffSqlNonJoinTablePrimary); procedure _NonJoinTableTerm (Parent:TffSqlNode; var NonJoinTableTerm: TffSqlNonJoinTableTerm); procedure _UsingItem (Parent: TFFSqlNode; var UsingItem : TFFSqlUsingItem); procedure _UsingList (Parent: TFFSqlNode; var UsingList : TFFSqlUsingList); procedure _TableRef (Parent: TFFSqlNode; var TableRef: TffSqlTableRef); procedure _NonJoinTableExp (Parent:TffSqlNode; var NonJoinTableExp: TffSqlNonJoinTableExp); procedure _JoinTableExp (Parent:TffSqlNode; const JoinTableExp: TffSqlJoinTableExp); procedure _SimpleTableRefOrParenTableExp (Parent: TFFSqlNode; var TableRef: TffSqlTableRef); procedure _InsertColumnList (Parent: TFFSqlNode; var InsertColumnList : TFFSqlInsertColumnList); procedure _SQLName (var aName : string); procedure _OrderList (Parent: TFFSqlNode; var OrderList : TFFSqlOrderList); procedure _GroupColumnList (Parent: TFFSqlNode; var ColumnList : TFFSqlGroupColumnList); procedure _CondExp (Parent: TFFSqlNode; var CondExp: TFFSqlCondExp); procedure _TableRefList (Parent: TFFSqlNode; var TableRefList: TFFSqlTableRefList); procedure _SelectionList (Parent: TFFSqlSELECT; var SelectionList: TFFSqlSelectionList); procedure _SelectStatement (Parent: TFFSqlNode; var Select : TFFSqlSELECT); procedure _DeleteStatement (Parent: TFFSqlNode; var DeleteSt : TFFSqlDELETE); procedure _UpdateStatement (Parent: TFFSqlNode; var UpdateSt : TFFSqlUPDATE); procedure _InsertStatement (Parent: TFFSqlNode; var InsertSt : TFFSqlINSERT); procedure _TableExp (Parent:TffSqlNode; var TableExp: TffSqlTableExp); procedure _FFSQL; private FRootNode : TFFSQLStatement; FReservedWordList : TStringList; FAllowReservedWordNames : boolean; procedure Init; procedure Final; procedure InitReservedWordList; function CheckSQLName(const SQLNameString : string) : string; function IsColumnList : Boolean; function Matches(n : integer) : Boolean; function IsSymbol(n: integer): boolean; {mwr} function IsParenNonJoinTableExp : Boolean; function IsParenJoinTableExp: Boolean; function IsParenTableExp: Boolean; function IsNonJoinTableExp : Boolean; function IsJoinTableExp: Boolean; function IsTableExp: Boolean; function IsTableRef: Boolean; protected { Protected Declarations } procedure Get; override; public { Public Declarations } constructor Create(AOwner : TComponent); override; destructor Destroy; override; function ErrorStr(const ErrorCode : integer; const Data : string) : string; override; procedure Execute; function GetScanner : TFFSQLScanner; procedure Parse; property ErrorList; property ListStream; property SourceStream; property Successful; property BuildDate : TDateTime read GetBuildDate; property VersionStr : string read GetVersionStr; property VersionInfo : string read GetVersionInfo; public property RootNode : TFFSqlStatement read FRootNode write FRootNode; property AllowReservedWordNames : boolean read FAllowReservedWordNames write FAllowReservedWordNames; published { Published Declarations } property AfterGet; property AfterParse; property AfterGenList; property BeforeGenList; property BeforeParse; property ClearSourceStream; property GenListWhen; property SourceFileName; property Version : string read GetVersion write SetVersion; property OnCustomError; property OnError; property OnFailure; property OnStatusUpdate; property OnSuccess; end; { TFFSQL } implementation const EOFSYMB = 0; identSym = 1; integer_Sym = 2; floatSym = 3; SQLStringSym = 4; SQLNameStringSym = 5; NOINDEXSym = 6; NOREDUCESym = 7; _semicolonSym = 8; SELECTSym = 9; ALLSym = 10; DISTINCTSym = 11; FROMSym = 12; WHERESym = 13; GROUPSym = 14; BYSym = 15; HAVINGSym = 16; ORDERSym = 17; INSERTSym = 18; INTOSym = 19; DEFAULTSym = 20; VALUESSym = 21; _lparenSym = 22; _rparenSym = 23; CROSSSym = 24; JOINSym = 25; NATURALSym = 26; INNERSym = 27; LEFTSym = 28; OUTERSym = 29; RIGHTSym = 30; FULLSym = 31; UNIONSym = 32; ONSym = 33; USINGSym = 34; _commaSym = 35; TABLESym = 36; NULLSym = 37; DELETESym = 38; UPDATESym = 39; SETSym = 40; _equalSym = 41; ASCSym = 42; DESCSym = 43; _pointSym = 44; _starSym = 45; ASSym = 46; COUNTSym = 47; MINSym = 48; MAXSym = 49; SUMSym = 50; AVGSym = 51; ORSym = 52; ANDSym = 53; NOTSym = 54; _less_equalSym = 55; _lessSym = 56; _greaterSym = 57; _greater_equalSym = 58; _less_greaterSym = 59; ANYSym = 60; SOMESym = 61; EXISTSSym = 62; UNIQUESym = 63; ISSym = 64; TRUESym = 65; FALSESym = 66; UNKNOWNSym = 67; BETWEENSym = 68; LIKESym = 69; ESCAPESym = 70; IGNORESym = 71; CASESym = 72; INSym = 73; MATCHSym = 74; PARTIALSym = 75; _plusSym = 76; _minusSym = 77; _bar_barSym = 78; _slashSym = 79; CHARACTER_underscoreLENGTHSym = 80; CHAR_underscoreLENGTHSym = 81; COALESCESym = 82; CURRENT_underscoreDATESym = 83; CURRENT_underscoreTIMESym = 84; CURRENT_underscoreTIMESTAMPSym = 85; CURRENT_underscoreUSERSym = 86; USERSym = 87; LOWERSym = 88; UPPERSym = 89; POSITIONSym = 90; SESSION_underscoreUSERSym = 91; SUBSTRINGSym = 92; FORSym = 93; SYSTEM_underscoreUSERSym = 94; TRIMSym = 95; LEADINGSym = 96; TRAILINGSym = 97; BOTHSym = 98; EXTRACTSym = 99; YEARSym = 100; MONTHSym = 101; DAYSym = 102; HOURSym = 103; MINUTESym = 104; SECONDSym = 105; NULLIFSym = 106; ABSSym = 107; CEILINGSym = 108; FLOORSym = 109; EXPSym = 110; LOGSym = 111; POWERSym = 112; RANDSym = 113; ROUNDSym = 114; ELSESym = 115; ENDSym = 116; WHENSym = 117; THENSym = 118; _querySym = 119; DATESym = 120; TIMESym = 121; TIMESTAMPSym = 122; INTERVALSym = 123; TOSym = 124; NOSYMB = 125; _noSym = NOSYMB; {error token code} { --------------------------------------------------------------------------- } { Arbitrary Code from ATG file } procedure TFFSQL.InitReservedWordList; begin FReservedWordList.Add('ABS'); {!!.11} FReservedWordList.Add('ALL'); FReservedWordList.Add('AND'); FReservedWordList.Add('ANY'); FReservedWordList.Add('AS'); FReservedWordList.Add('ASC'); FReservedWordList.Add('AVG'); FReservedWordList.Add('BETWEEN'); FReservedWordList.Add('BOTH'); FReservedWordList.Add('BY'); FReservedWordList.Add('CASE'); FReservedWordList.Add('CEILING'); {!!.11} FReservedWordList.Add('CHARACTER_LENGTH'); FReservedWordList.Add('CHAR_LENGTH'); FReservedWordList.Add('COALESCE'); FReservedWordList.Add('COUNT'); FReservedWordList.Add('CROSS'); FReservedWordList.Add('CURRENT_DATE'); FReservedWordList.Add('CURRENT_TIME'); FReservedWordList.Add('CURRENT_TIMESTAMP'); FReservedWordList.Add('CURRENT_USER'); FReservedWordList.Add('DATE'); FReservedWordList.Add('DAY'); FReservedWordList.Add('DEFAULT'); FReservedWordList.Add('DELETE'); FReservedWordList.Add('DESC'); FReservedWordList.Add('DISTINCT'); FReservedWordList.Add('ELSE'); FReservedWordList.Add('END'); FReservedWordList.Add('EXP'); {!!.11} FReservedWordList.Add('ESCAPE'); FReservedWordList.Add('EXISTS'); FReservedWordList.Add('EXTRACT'); FReservedWordList.Add('FALSE'); FReservedWordList.Add('FLOOR'); {!!.11} FReservedWordList.Add('FOR'); FReservedWordList.Add('FROM'); FReservedWordList.Add('FULL'); FReservedWordList.Add('GROUP'); FReservedWordList.Add('HAVING'); FReservedWordList.Add('HOUR'); FReservedWordList.Add('IN'); FReservedWordList.Add('INNER'); FReservedWordList.Add('INSERT'); FReservedWordList.Add('INTERVAL'); FReservedWordList.Add('IS'); FReservedWordList.Add('JOIN'); FReservedWordList.Add('LEADING'); FReservedWordList.Add('LEFT'); FReservedWordList.Add('LIKE'); FReservedWordList.Add('LOG'); {!!.11} FReservedWordList.Add('LOWER'); FReservedWordList.Add('MATCH'); FReservedWordList.Add('MAX'); FReservedWordList.Add('MIN'); FReservedWordList.Add('MINUTE'); FReservedWordList.Add('MONTH'); FReservedWordList.Add('NOINDEX'); FReservedWordList.Add('NOREDUCE'); FReservedWordList.Add('NOT'); FReservedWordList.Add('NULL'); FReservedWordList.Add('NULLIF'); FReservedWordList.Add('OR'); FReservedWordList.Add('ORDER'); FReservedWordList.Add('OUTER'); FReservedWordList.Add('PARTIAL'); FReservedWordList.Add('POSITION'); FReservedWordList.Add('POWER'); {!!.11} FReservedWordList.Add('RAND'); {!!.11} FReservedWordList.Add('RIGHT'); FReservedWordList.Add('ROUND'); {!!.11} FReservedWordList.Add('SECOND'); FReservedWordList.Add('SELECT'); FReservedWordList.Add('SESSION_USER'); FReservedWordList.Add('SET'); FReservedWordList.Add('SOME'); FReservedWordList.Add('SUBSTRING'); FReservedWordList.Add('SUM'); FReservedWordList.Add('SYSTEM_USER'); FReservedWordList.Add('TABLE'); FReservedWordList.Add('THEN'); FReservedWordList.Add('TIME'); FReservedWordList.Add('TIMESTAMP'); FReservedWordList.Add('TO'); FReservedWordList.Add('TRAILING'); FReservedWordList.Add('TRIM'); FReservedWordList.Add('TRUE'); FReservedWordList.Add('UNIQUE'); FReservedWordList.Add('UNKNOWN'); FReservedWordList.Add('UPDATE'); FReservedWordList.Add('UPPER'); FReservedWordList.Add('USER'); FReservedWordList.Add('USING'); FReservedWordList.Add('VALUES'); FReservedWordList.Add('WHEN'); FReservedWordList.Add('WHERE'); FReservedWordList.Add('YEAR'); FReservedWordList.Sorted := TRUE; end; procedure TFFSQL.Init; begin fRootNode := TFFSqlStatement.Create; fRootNode.UseIndex := True; fRootNode.Reduce := True; InitReservedWordList; end; procedure TFFSQL.Final; begin if successful and fRootNode.Reduce then fRootNode.ReduceStrength; end; function TFFSQL.CheckSQLName(const SQLNameString : string) : string; var Idx : integer; begin Result := copy(SQLNameString,2,length(SQLNameString) - 2); if NOT fAllowReservedWordNames AND fReservedWordList.Find(UpperCase(Result), Idx) then SemError(203, Result); end; function TFFSQL.IsSymbol(n : integer) : boolean; begin if CurrentInputSymbol = n then Result := True else Result := False; end; function TFFSQL.Matches(n: integer): boolean; begin Result := IsSymbol(n); if Result then Get; end; {Expect} function TFFSQL.IsColumnList : boolean; var BS: string; begin Result := False; BS := Bookmark; try if not Matches(_lparenSym) then exit; if not Matches(identSym) and not Matches(SQLNameStringSym) then exit; while (fCurrentInputSymbol = _commaSym) do begin Get; if not Matches(identSym) and not Matches(SQLNameStringSym) then exit; end; if not Matches(_rparenSym) then exit; Result := True; finally GotoBookmark(BS); end; end; function TFFSQL.IsParenNonJoinTableExp : boolean; var BS: string; begin Result := False; BS := Bookmark; try if not Matches(_lparenSym) then exit; if not IsParenNonJoinTableExp and not (fCurrentInputSymbol in [SELECTsym, TABLEsym, VALUESsym]) then exit; Result := True; finally GotoBookmark(BS); end; end; function TFFSQL.IsNonJoinTableExp : boolean; var BS: string; begin Result := False; BS := Bookmark; try if not IsParenNonJoinTableExp and not (fCurrentInputSymbol in [SELECTsym, TABLEsym, VALUESsym]) then exit; Result := True; finally GotoBookmark(BS); end; end; function TFFSQL.IsTableRef : boolean; begin Result := False; if (fCurrentInputSymbol = identSym) OR (fCurrentInputSymbol = SQLNameStringSym) then begin Get; if (fCurrentInputSymbol = _pointSym) then begin Get; Get; end; Result := True; end; end; function TFFSQL.IsParenJoinTableExp : boolean; var BS: string; begin Result := False; BS := Bookmark; try if not Matches(_lparenSym) then exit; if not IsTableRef then exit; if not (fCurrentInputSymbol in [CROSSSym, NATURALSym, INNERSym, LEFTSym, RIGHTSym, FULLSym, UNIONSym, JOINSym]) then exit; Result := True; finally GotoBookmark(BS); end; end; function TFFSQL.IsJoinTableExp : boolean; var BS: string; begin Result := False; BS := Bookmark; try if not IsTableRef then exit; if IsSymbol(ASSym) then Get; if IsSymbol(identSym) then Get; if not (fCurrentInputSymbol in [CROSSSym, NATURALSym, INNERSym, LEFTSym, RIGHTSym, FULLSym, UNIONSym, JOINSym]) then exit; Result := True; finally GotoBookmark(BS); end; end; function TFFSQL.IsParenTableExp : boolean; begin Result := IsParenNonJoinTableExp or IsParenJoinTableExp; end; function TFFSQL.IsTableExp : boolean; begin Result := IsNonJoinTableExp or IsJoinTableExp or IsParenTableExp; end; (* End of Arbitrary Code *) { --------------------------------------------------------------------------- } { ---- implementation for TFFSQLScanner ---- } procedure TFFSQLScanner.NextCh; { Return global variable ch } begin LastInputCh := CurrInputCh; BufferPosition := BufferPosition + 1; SrcStream.Seek(BufferPosition,soFromBeginning); CurrInputCh := CurrentCh(BufferPosition); if (CurrInputCh = _EL) OR ((CurrInputCh = _LF) AND (LastInputCh <> _EL)) then begin CurrLine := CurrLine + 1; if Assigned(OnStatusUpdate) then OnStatusUpdate(Owner, cstLineNum, '', CurrLine); StartOfLine := BufferPosition; end end; {NextCh} function TFFSQLScanner.Comment : boolean; var level : integer; startLine : integer; oldLineStart : longint; CommentStr : string; begin level := 1; startLine := CurrLine; oldLineStart := StartOfLine; CommentStr := CharAt(BufferPosition); //Result := false; if (CurrInputCh = '/') then begin NextCh; CommentStr := CommentStr + CharAt(BufferPosition); if (CurrInputCh = '/') then begin NextCh; CommentStr := CommentStr + CharAt(BufferPosition); while true do begin if (CurrInputCh = CHR(13)) then begin level := level - 1; NumEOLInComment := CurrLine - startLine; NextCh; CommentStr := CommentStr + CharAt(BufferPosition); if level = 0 then begin Result := true; Exit; end; end else if CurrInputCh = _EF then begin Result := false; Exit; end else begin NextCh; CommentStr := CommentStr + CharAt(BufferPosition); end; end; { WHILE TRUE } end else begin if (CurrInputCh = _CR) OR (CurrInputCh = _LF) then begin CurrLine := CurrLine - 1; StartOfLine := oldLineStart end; BufferPosition := BufferPosition - 1; CurrInputCh := LastInputCh; //Result := false; end; end; //Result := false; if (CurrInputCh = '-') then begin NextCh; CommentStr := CommentStr + CharAt(BufferPosition); if (CurrInputCh = '-') then begin NextCh; CommentStr := CommentStr + CharAt(BufferPosition); while true do begin if (CurrInputCh = CHR(13)) then begin level := level - 1; NumEOLInComment := CurrLine - startLine; NextCh; CommentStr := CommentStr + CharAt(BufferPosition); if level = 0 then begin Result := true; Exit; end; end else if CurrInputCh = _EF then begin Result := false; Exit; end else begin NextCh; CommentStr := CommentStr + CharAt(BufferPosition); end; end; { WHILE TRUE } end else begin if (CurrInputCh = _CR) OR (CurrInputCh = _LF) then begin CurrLine := CurrLine - 1; StartOfLine := oldLineStart end; BufferPosition := BufferPosition - 1; CurrInputCh := LastInputCh; //Result := false; end; end; Result := false; if (CurrInputCh = '/') then begin NextCh; CommentStr := CommentStr + CharAt(BufferPosition); if (CurrInputCh = '*') then begin NextCh; CommentStr := CommentStr + CharAt(BufferPosition); while true do begin if (CurrInputCh = '*') then begin NextCh; CommentStr := CommentStr + CharAt(BufferPosition); if (CurrInputCh = '/') then begin level := level - 1; NextCh; CommentStr := CommentStr + CharAt(BufferPosition); if level = 0 then begin Result := true; Exit; end end end else if (CurrInputCh = '/') then begin NextCh; CommentStr := CommentStr + CharAt(BufferPosition); if (CurrInputCh = '*') then begin level := level + 1; NextCh; CommentStr := CommentStr + CharAt(BufferPosition); end end else if CurrInputCh = _EF then begin Result := false; Exit; end else begin NextCh; CommentStr := CommentStr + CharAt(BufferPosition); end; end; { WHILE TRUE } end else begin if (CurrInputCh = _CR) OR (CurrInputCh = _LF) then begin CurrLine := CurrLine - 1; StartOfLine := oldLineStart end; BufferPosition := BufferPosition - 1; CurrInputCh := LastInputCh; Result := false; end; end; end; { Comment } function TFFSQLScanner.CharInIgnoreSet(const Ch : char) : boolean; begin Result := (Ch = ' ') OR ((CurrInputCh >= CHR(1)) AND (CurrInputCh <= ' ')); end; {CharInIgnoreSet} function TFFSQLScanner.Equal(s : string) : boolean; var i : integer; q : longint; begin if NextSymbol.Len <> Length(s) then begin Result := false; EXIT end; i := 1; q := bpCurrToken; while i <= NextSymbol.Len do begin if CurrentCh(q) <> s[i] then begin Result := false; EXIT; end; inc(i); inc(q); end; Result := true end; {Equal} procedure TFFSQLScanner.CheckLiteral(var Sym : integer); begin case CurrentCh(bpCurrToken) of 'A': if Equal('ABS') then begin sym := ABSSym; end else if Equal('ALL') then begin sym := ALLSym; end else if Equal('AND') then begin sym := ANDSym; end else if Equal('ANY') then begin sym := ANYSym; end else if Equal('AS') then begin sym := ASSym; end else if Equal('ASC') then begin sym := ASCSym; end else if Equal('AVG') then begin sym := AVGSym; end; 'B': if Equal('BETWEEN') then begin sym := BETWEENSym; end else if Equal('BOTH') then begin sym := BOTHSym; end else if Equal('BY') then begin sym := BYSym; end; 'C': if Equal('CASE') then begin sym := CASESym; end else if Equal('CEILING') then begin sym := CEILINGSym; end else if Equal('CHARACTER_LENGTH') then begin sym := CHARACTER_underscoreLENGTHSym; end else if Equal('CHAR_LENGTH') then begin sym := CHAR_underscoreLENGTHSym; end else if Equal('COALESCE') then begin sym := COALESCESym; end else if Equal('COUNT') then begin sym := COUNTSym; end else if Equal('CROSS') then begin sym := CROSSSym; end else if Equal('CURRENT_DATE') then begin sym := CURRENT_underscoreDATESym; end else if Equal('CURRENT_TIME') then begin sym := CURRENT_underscoreTIMESym; end else if Equal('CURRENT_TIMESTAMP') then begin sym := CURRENT_underscoreTIMESTAMPSym; end else if Equal('CURRENT_USER') then begin sym := CURRENT_underscoreUSERSym; end; 'D': if Equal('DATE') then begin sym := DATESym; end else if Equal('DAY') then begin sym := DAYSym; end else if Equal('DEFAULT') then begin sym := DEFAULTSym; end else if Equal('DELETE') then begin sym := DELETESym; end else if Equal('DESC') then begin sym := DESCSym; end else if Equal('DISTINCT') then begin sym := DISTINCTSym; end; 'E': if Equal('ELSE') then begin sym := ELSESym; end else if Equal('END') then begin sym := ENDSym; end else if Equal('ESCAPE') then begin sym := ESCAPESym; end else if Equal('EXISTS') then begin sym := EXISTSSym; end else if Equal('EXP') then begin sym := EXPSym; end else if Equal('EXTRACT') then begin sym := EXTRACTSym; end; 'F': if Equal('FALSE') then begin sym := FALSESym; end else if Equal('FLOOR') then begin sym := FLOORSym; end else if Equal('FOR') then begin sym := FORSym; end else if Equal('FROM') then begin sym := FROMSym; end else if Equal('FULL') then begin sym := FULLSym; end; 'G': if Equal('GROUP') then begin sym := GROUPSym; end; 'H': if Equal('HAVING') then begin sym := HAVINGSym; end else if Equal('HOUR') then begin sym := HOURSym; end; 'I': if Equal('IGNORE') then begin sym := IGNORESym; end else if Equal('IN') then begin sym := INSym; end else if Equal('INNER') then begin sym := INNERSym; end else if Equal('INSERT') then begin sym := INSERTSym; end else if Equal('INTERVAL') then begin sym := INTERVALSym; end else if Equal('INTO') then begin sym := INTOSym; end else if Equal('IS') then begin sym := ISSym; end; 'J': if Equal('JOIN') then begin sym := JOINSym; end; 'L': if Equal('LEADING') then begin sym := LEADINGSym; end else if Equal('LEFT') then begin sym := LEFTSym; end else if Equal('LIKE') then begin sym := LIKESym; end else if Equal('LOG') then begin sym := LOGSym; end else if Equal('LOWER') then begin sym := LOWERSym; end; 'M': if Equal('MATCH') then begin sym := MATCHSym; end else if Equal('MAX') then begin sym := MAXSym; end else if Equal('MIN') then begin sym := MINSym; end else if Equal('MINUTE') then begin sym := MINUTESym; end else if Equal('MONTH') then begin sym := MONTHSym; end; 'N': if Equal('NATURAL') then begin sym := NATURALSym; end else if Equal('NOINDEX') then begin sym := NOINDEXSym; end else if Equal('NOREDUCE') then begin sym := NOREDUCESym; end else if Equal('NOT') then begin sym := NOTSym; end else if Equal('NULL') then begin sym := NULLSym; end else if Equal('NULLIF') then begin sym := NULLIFSym; end; 'O': if Equal('ON') then begin sym := ONSym; end else if Equal('OR') then begin sym := ORSym; end else if Equal('ORDER') then begin sym := ORDERSym; end else if Equal('OUTER') then begin sym := OUTERSym; end; 'P': if Equal('PARTIAL') then begin sym := PARTIALSym; end else if Equal('POSITION') then begin sym := POSITIONSym; end else if Equal('POWER') then begin sym := POWERSym; end; 'R': if Equal('RAND') then begin sym := RANDSym; end else if Equal('RIGHT') then begin sym := RIGHTSym; end else if Equal('ROUND') then begin sym := ROUNDSym; end; 'S': if Equal('SECOND') then begin sym := SECONDSym; end else if Equal('SELECT') then begin sym := SELECTSym; end else if Equal('SESSION_USER') then begin sym := SESSION_underscoreUSERSym; end else if Equal('SET') then begin sym := SETSym; end else if Equal('SOME') then begin sym := SOMESym; end else if Equal('SUBSTRING') then begin sym := SUBSTRINGSym; end else if Equal('SUM') then begin sym := SUMSym; end else if Equal('SYSTEM_USER') then begin sym := SYSTEM_underscoreUSERSym; end; 'T': if Equal('TABLE') then begin sym := TABLESym; end else if Equal('THEN') then begin sym := THENSym; end else if Equal('TIME') then begin sym := TIMESym; end else if Equal('TIMESTAMP') then begin sym := TIMESTAMPSym; end else if Equal('TO') then begin sym := TOSym; end else if Equal('TRAILING') then begin sym := TRAILINGSym; end else if Equal('TRIM') then begin sym := TRIMSym; end else if Equal('TRUE') then begin sym := TRUESym; end; 'U': if Equal('UNION') then begin sym := UNIONSym; end else if Equal('UNIQUE') then begin sym := UNIQUESym; end else if Equal('UNKNOWN') then begin sym := UNKNOWNSym; end else if Equal('UPDATE') then begin sym := UPDATESym; end else if Equal('UPPER') then begin sym := UPPERSym; end else if Equal('USER') then begin sym := USERSym; end else if Equal('USING') then begin sym := USINGSym; end; 'V': if Equal('VALUES') then begin sym := VALUESSym; end; 'W': if Equal('WHEN') then begin sym := WHENSym; end else if Equal('WHERE') then begin sym := WHERESym; end; 'Y': if Equal('YEAR') then begin sym := YEARSym; end; else begin end end end; {CheckLiteral} procedure TFFSQLScanner.Get(var sym : integer); var state : integer; begin {Get} while CharInIgnoreSet(CurrInputCh) do NextCh; if ((CurrInputCh = '/') OR (CurrInputCh = '-') OR (CurrInputCh = '/')) AND Comment then begin Get(sym); exit; end; CurrentSymbol.Assign(NextSymbol); NextSymbol.Pos := BufferPosition; NextSymbol.Col := BufferPosition - StartOfLine; NextSymbol.Line := CurrLine; NextSymbol.Len := 0; ContextLen := 0; state := StartState[ORD(CurrInputCh)]; bpCurrToken := BufferPosition; while true do begin NextCh; NextSymbol.Len := NextSymbol.Len + 1; if BufferPosition > SrcStream.Size then begin sym := EOFSYMB; CurrInputCh := _EF; BufferPosition := BufferPosition - 1; exit end; case state of 1: if ((CurrInputCh = '!') OR (CurrInputCh >= '#') AND (CurrInputCh <= '$') OR (CurrInputCh >= '0') AND (CurrInputCh <= '9') OR (CurrInputCh >= '@') AND (CurrInputCh <= 'Z') OR (CurrInputCh = '\') OR (CurrInputCh >= '^') AND (CurrInputCh <= '{') OR (CurrInputCh >= '}')) then begin end else begin sym := identSym; CheckLiteral(sym); exit; end; 2: if ((CurrInputCh >= '0') AND (CurrInputCh <= '9')) then begin state := 3; end else begin sym := _pointSym; exit; end; 3: if ((CurrInputCh >= '0') AND (CurrInputCh <= '9')) then begin end else begin sym := floatSym; exit; end; 4: if ((CurrInputCh <= CHR(12)) OR (CurrInputCh >= CHR(14)) AND (CurrInputCh <= '&') OR (CurrInputCh >= '(')) then begin end else if (CurrInputCh = CHR(39)) then begin state := 8; end else begin sym := _noSym; exit; end; 5: if ((CurrInputCh <= CHR(12)) OR (CurrInputCh >= CHR(14)) AND (CurrInputCh <= '!') OR (CurrInputCh >= '#')) then begin end else if (CurrInputCh = '"') then begin state := 6; end else begin sym := _noSym; exit; end; 6: begin sym := SQLNameStringSym; exit; end; 7: if ((CurrInputCh >= '0') AND (CurrInputCh <= '9')) then begin end else if (CurrInputCh = '.') then begin state := 2; end else begin sym := integer_Sym; exit; end; 8: if (CurrInputCh = CHR(39)) then begin state := 4; end else begin sym := SQLStringSym; exit; end; 9: begin sym := _semicolonSym; exit; end; 10: begin sym := _lparenSym; exit; end; 11: begin sym := _rparenSym; exit; end; 12: begin sym := _commaSym; exit; end; 13: begin sym := _equalSym; exit; end; 14: begin sym := _starSym; exit; end; 15: if (CurrInputCh = '=') then begin state := 16; end else if (CurrInputCh = '>') then begin state := 19; end else begin sym := _lessSym; exit; end; 16: begin sym := _less_equalSym; exit; end; 17: if (CurrInputCh = '=') then begin state := 18; end else begin sym := _greaterSym; exit; end; 18: begin sym := _greater_equalSym; exit; end; 19: begin sym := _less_greaterSym; exit; end; 20: begin sym := _plusSym; exit; end; 21: begin sym := _minusSym; exit; end; 22: if (CurrInputCh = '|') then begin state := 23; end else begin sym := _noSym; exit; end; 23: begin sym := _bar_barSym; exit; end; 24: begin sym := _slashSym; exit; end; 25: begin sym := _querySym; exit; end; 26: begin sym := EOFSYMB; CurrInputCh := #0; BufferPosition := BufferPosition - 1; exit end; else begin sym := _noSym; EXIT; // NextCh already done end; end; end; end; {Get} constructor TFFSQLScanner.Create; begin inherited; CurrentCh := CapChAt; fStartState[ 0] := 26; fStartState[ 1] := 27; fStartState[ 2] := 27; fStartState[ 3] := 27; fStartState[ 4] := 27; fStartState[ 5] := 27; fStartState[ 6] := 27; fStartState[ 7] := 27; fStartState[ 8] := 27; fStartState[ 9] := 27; fStartState[ 10] := 27; fStartState[ 11] := 27; fStartState[ 12] := 27; fStartState[ 13] := 27; fStartState[ 14] := 27; fStartState[ 15] := 27; fStartState[ 16] := 27; fStartState[ 17] := 27; fStartState[ 18] := 27; fStartState[ 19] := 27; fStartState[ 20] := 27; fStartState[ 21] := 27; fStartState[ 22] := 27; fStartState[ 23] := 27; fStartState[ 24] := 27; fStartState[ 25] := 27; fStartState[ 26] := 27; fStartState[ 27] := 27; fStartState[ 28] := 27; fStartState[ 29] := 27; fStartState[ 30] := 27; fStartState[ 31] := 27; fStartState[ 32] := 27; fStartState[ 33] := 1; fStartState[ 34] := 5; fStartState[ 35] := 1; fStartState[ 36] := 1; fStartState[ 37] := 27; fStartState[ 38] := 27; fStartState[ 39] := 4; fStartState[ 40] := 10; fStartState[ 41] := 11; fStartState[ 42] := 14; fStartState[ 43] := 20; fStartState[ 44] := 12; fStartState[ 45] := 21; fStartState[ 46] := 2; fStartState[ 47] := 24; fStartState[ 48] := 7; fStartState[ 49] := 7; fStartState[ 50] := 7; fStartState[ 51] := 7; fStartState[ 52] := 7; fStartState[ 53] := 7; fStartState[ 54] := 7; fStartState[ 55] := 7; fStartState[ 56] := 7; fStartState[ 57] := 7; fStartState[ 58] := 27; fStartState[ 59] := 9; fStartState[ 60] := 15; fStartState[ 61] := 13; fStartState[ 62] := 17; fStartState[ 63] := 25; fStartState[ 64] := 1; fStartState[ 65] := 1; fStartState[ 66] := 1; fStartState[ 67] := 1; fStartState[ 68] := 1; fStartState[ 69] := 1; fStartState[ 70] := 1; fStartState[ 71] := 1; fStartState[ 72] := 1; fStartState[ 73] := 1; fStartState[ 74] := 1; fStartState[ 75] := 1; fStartState[ 76] := 1; fStartState[ 77] := 1; fStartState[ 78] := 1; fStartState[ 79] := 1; fStartState[ 80] := 1; fStartState[ 81] := 1; fStartState[ 82] := 1; fStartState[ 83] := 1; fStartState[ 84] := 1; fStartState[ 85] := 1; fStartState[ 86] := 1; fStartState[ 87] := 1; fStartState[ 88] := 1; fStartState[ 89] := 1; fStartState[ 90] := 1; fStartState[ 91] := 27; fStartState[ 92] := 1; fStartState[ 93] := 27; fStartState[ 94] := 1; fStartState[ 95] := 1; fStartState[ 96] := 1; fStartState[ 97] := 1; fStartState[ 98] := 1; fStartState[ 99] := 1; fStartState[100] := 1; fStartState[101] := 1; fStartState[102] := 1; fStartState[103] := 1; fStartState[104] := 1; fStartState[105] := 1; fStartState[106] := 1; fStartState[107] := 1; fStartState[108] := 1; fStartState[109] := 1; fStartState[110] := 1; fStartState[111] := 1; fStartState[112] := 1; fStartState[113] := 1; fStartState[114] := 1; fStartState[115] := 1; fStartState[116] := 1; fStartState[117] := 1; fStartState[118] := 1; fStartState[119] := 1; fStartState[120] := 1; fStartState[121] := 1; fStartState[122] := 1; fStartState[123] := 1; fStartState[124] := 22; fStartState[125] := 1; fStartState[126] := 1; fStartState[127] := 1; fStartState[128] := 1; fStartState[129] := 1; fStartState[130] := 1; fStartState[131] := 1; fStartState[132] := 1; fStartState[133] := 1; fStartState[134] := 1; fStartState[135] := 1; fStartState[136] := 1; fStartState[137] := 1; fStartState[138] := 1; fStartState[139] := 1; fStartState[140] := 1; fStartState[141] := 1; fStartState[142] := 1; fStartState[143] := 1; fStartState[144] := 1; fStartState[145] := 1; fStartState[146] := 1; fStartState[147] := 1; fStartState[148] := 1; fStartState[149] := 1; fStartState[150] := 1; fStartState[151] := 1; fStartState[152] := 1; fStartState[153] := 1; fStartState[154] := 1; fStartState[155] := 1; fStartState[156] := 1; fStartState[157] := 1; fStartState[158] := 1; fStartState[159] := 1; fStartState[160] := 1; fStartState[161] := 1; fStartState[162] := 1; fStartState[163] := 1; fStartState[164] := 1; fStartState[165] := 1; fStartState[166] := 1; fStartState[167] := 1; fStartState[168] := 1; fStartState[169] := 1; fStartState[170] := 1; fStartState[171] := 1; fStartState[172] := 1; fStartState[173] := 1; fStartState[174] := 1; fStartState[175] := 1; fStartState[176] := 1; fStartState[177] := 1; fStartState[178] := 1; fStartState[179] := 1; fStartState[180] := 1; fStartState[181] := 1; fStartState[182] := 1; fStartState[183] := 1; fStartState[184] := 1; fStartState[185] := 1; fStartState[186] := 1; fStartState[187] := 1; fStartState[188] := 1; fStartState[189] := 1; fStartState[190] := 1; fStartState[191] := 1; fStartState[192] := 1; fStartState[193] := 1; fStartState[194] := 1; fStartState[195] := 1; fStartState[196] := 1; fStartState[197] := 1; fStartState[198] := 1; fStartState[199] := 1; fStartState[200] := 1; fStartState[201] := 1; fStartState[202] := 1; fStartState[203] := 1; fStartState[204] := 1; fStartState[205] := 1; fStartState[206] := 1; fStartState[207] := 1; fStartState[208] := 1; fStartState[209] := 1; fStartState[210] := 1; fStartState[211] := 1; fStartState[212] := 1; fStartState[213] := 1; fStartState[214] := 1; fStartState[215] := 1; fStartState[216] := 1; fStartState[217] := 1; fStartState[218] := 1; fStartState[219] := 1; fStartState[220] := 1; fStartState[221] := 1; fStartState[222] := 1; fStartState[223] := 1; fStartState[224] := 1; fStartState[225] := 1; fStartState[226] := 1; fStartState[227] := 1; fStartState[228] := 1; fStartState[229] := 1; fStartState[230] := 1; fStartState[231] := 1; fStartState[232] := 1; fStartState[233] := 1; fStartState[234] := 1; fStartState[235] := 1; fStartState[236] := 1; fStartState[237] := 1; fStartState[238] := 1; fStartState[239] := 1; fStartState[240] := 1; fStartState[241] := 1; fStartState[242] := 1; fStartState[243] := 1; fStartState[244] := 1; fStartState[245] := 1; fStartState[246] := 1; fStartState[247] := 1; fStartState[248] := 1; fStartState[249] := 1; fStartState[250] := 1; fStartState[251] := 1; fStartState[252] := 1; fStartState[253] := 1; fStartState[254] := 1; fStartState[255] := 1; end; {Create} { --------------------------------------------------------------------------- } { ---- implementation for TFFSQL ---- } constructor TFFSQL.Create(AOwner : TComponent); begin inherited; Scanner := TFFSQLScanner.Create; GetScanner.Owner := self; FRootNode := nil; FReservedWordList := TStringList.Create; FAllowReservedWordNames := True; InitSymSet; end; {Create} destructor TFFSQL.Destroy; begin Scanner.Free; FReservedWordList.Free; FReservedWordList := NIL; inherited; end; {Destroy} function TFFSQL.ErrorStr(const ErrorCode : integer; const Data : string) : string; begin case ErrorCode of 0 : Result := 'EOF expected'; 1 : Result := 'ident expected'; 2 : Result := 'integer_ expected'; 3 : Result := 'float expected'; 4 : Result := 'SQLString expected'; 5 : Result := 'SQLNameString expected'; 6 : Result := '"NOINDEX" expected'; 7 : Result := '"NOREDUCE" expected'; 8 : Result := '";" expected'; 9 : Result := '"SELECT" expected'; 10 : Result := '"ALL" expected'; 11 : Result := '"DISTINCT" expected'; 12 : Result := '"FROM" expected'; 13 : Result := '"WHERE" expected'; 14 : Result := '"GROUP" expected'; 15 : Result := '"BY" expected'; 16 : Result := '"HAVING" expected'; 17 : Result := '"ORDER" expected'; 18 : Result := '"INSERT" expected'; 19 : Result := '"INTO" expected'; 20 : Result := '"DEFAULT" expected'; 21 : Result := '"VALUES" expected'; 22 : Result := '"(" expected'; 23 : Result := '")" expected'; 24 : Result := '"CROSS" expected'; 25 : Result := '"JOIN" expected'; 26 : Result := '"NATURAL" expected'; 27 : Result := '"INNER" expected'; 28 : Result := '"LEFT" expected'; 29 : Result := '"OUTER" expected'; 30 : Result := '"RIGHT" expected'; 31 : Result := '"FULL" expected'; 32 : Result := '"UNION" expected'; 33 : Result := '"ON" expected'; 34 : Result := '"USING" expected'; 35 : Result := '"," expected'; 36 : Result := '"TABLE" expected'; 37 : Result := '"NULL" expected'; 38 : Result := '"DELETE" expected'; 39 : Result := '"UPDATE" expected'; 40 : Result := '"SET" expected'; 41 : Result := '"=" expected'; 42 : Result := '"ASC" expected'; 43 : Result := '"DESC" expected'; 44 : Result := '"." expected'; 45 : Result := '"*" expected'; 46 : Result := '"AS" expected'; 47 : Result := '"COUNT" expected'; 48 : Result := '"MIN" expected'; 49 : Result := '"MAX" expected'; 50 : Result := '"SUM" expected'; 51 : Result := '"AVG" expected'; 52 : Result := '"OR" expected'; 53 : Result := '"AND" expected'; 54 : Result := '"NOT" expected'; 55 : Result := '"<=" expected'; 56 : Result := '"<" expected'; 57 : Result := '">" expected'; 58 : Result := '">=" expected'; 59 : Result := '"<>" expected'; 60 : Result := '"ANY" expected'; 61 : Result := '"SOME" expected'; 62 : Result := '"EXISTS" expected'; 63 : Result := '"UNIQUE" expected'; 64 : Result := '"IS" expected'; 65 : Result := '"TRUE" expected'; 66 : Result := '"FALSE" expected'; 67 : Result := '"UNKNOWN" expected'; 68 : Result := '"BETWEEN" expected'; 69 : Result := '"LIKE" expected'; 70 : Result := '"ESCAPE" expected'; 71 : Result := '"IGNORE" expected'; 72 : Result := '"CASE" expected'; 73 : Result := '"IN" expected'; 74 : Result := '"MATCH" expected'; 75 : Result := '"PARTIAL" expected'; 76 : Result := '"+" expected'; 77 : Result := '"-" expected'; 78 : Result := '"||" expected'; 79 : Result := '"/" expected'; 80 : Result := '"CHARACTER_LENGTH" expected'; 81 : Result := '"CHAR_LENGTH" expected'; 82 : Result := '"COALESCE" expected'; 83 : Result := '"CURRENT_DATE" expected'; 84 : Result := '"CURRENT_TIME" expected'; 85 : Result := '"CURRENT_TIMESTAMP" expected'; 86 : Result := '"CURRENT_USER" expected'; 87 : Result := '"USER" expected'; 88 : Result := '"LOWER" expected'; 89 : Result := '"UPPER" expected'; 90 : Result := '"POSITION" expected'; 91 : Result := '"SESSION_USER" expected'; 92 : Result := '"SUBSTRING" expected'; 93 : Result := '"FOR" expected'; 94 : Result := '"SYSTEM_USER" expected'; 95 : Result := '"TRIM" expected'; 96 : Result := '"LEADING" expected'; 97 : Result := '"TRAILING" expected'; 98 : Result := '"BOTH" expected'; 99 : Result := '"EXTRACT" expected'; 100 : Result := '"YEAR" expected'; 101 : Result := '"MONTH" expected'; 102 : Result := '"DAY" expected'; 103 : Result := '"HOUR" expected'; 104 : Result := '"MINUTE" expected'; 105 : Result := '"SECOND" expected'; 106 : Result := '"NULLIF" expected'; 107 : Result := '"ABS" expected'; 108 : Result := '"CEILING" expected'; 109 : Result := '"FLOOR" expected'; 110 : Result := '"EXP" expected'; 111 : Result := '"LOG" expected'; 112 : Result := '"POWER" expected'; 113 : Result := '"RAND" expected'; 114 : Result := '"ROUND" expected'; 115 : Result := '"ELSE" expected'; 116 : Result := '"END" expected'; 117 : Result := '"WHEN" expected'; 118 : Result := '"THEN" expected'; 119 : Result := '"?" expected'; 120 : Result := '"DATE" expected'; 121 : Result := '"TIME" expected'; 122 : Result := '"TIMESTAMP" expected'; 123 : Result := '"INTERVAL" expected'; 124 : Result := '"TO" expected'; 125 : Result := 'not expected'; 126 : Result := 'invalid BooleanLiteral'; 127 : Result := 'invalid IntervalLiteral'; 128 : Result := 'invalid IntervalLiteral'; 129 : Result := 'invalid WhenClause'; 130 : Result := 'invalid CaseExpression'; 131 : Result := 'invalid ScalarFunction'; 132 : Result := 'invalid ScalarFunction'; 133 : Result := 'invalid ScalarFunction'; 134 : Result := 'invalid Literal'; 135 : Result := 'invalid Factor'; 136 : Result := 'invalid Factor'; 137 : Result := 'invalid IsTest'; 138 : Result := 'invalid InClause'; 139 : Result := 'invalid AllOrAnyClause'; 140 : Result := 'invalid CondPrimary'; 141 : Result := 'invalid CondPrimary'; 142 : Result := 'invalid CondPrimary'; 143 : Result := 'invalid CondPrimary'; 144 : Result := 'invalid CondPrimary'; 145 : Result := 'invalid FieldRef'; 146 : Result := 'invalid Aggregate'; 147 : Result := 'invalid Aggregate'; 148 : Result := 'invalid Selection'; 149 : Result := 'invalid OrderItem'; 150 : Result := 'invalid UpdateItem'; 151 : Result := 'invalid ValueItem'; 152 : Result := 'invalid NonJoinTablePrimary'; 153 : Result := 'invalid JoinTableExp'; 154 : Result := 'invalid SimpleTableRefOrParenTableExp'; 155 : Result := 'invalid SQLName'; 156 : Result := 'invalid InsertStatement'; 157 : Result := 'invalid TableExp'; 158 : Result := 'invalid FFSQL'; 200 : Result := 'Text after end of valid sql statement'; 201 : Result := 'Nested aggregates are not allowed'; 202 : Result := 'Aggregates may not appear in a WHERE clause'; 203 : Result := 'Reserved word (' + data + ') not allowed'; else if Assigned(OnCustomError) then Result := OnCustomError(Self, ErrorCode, Data) else begin Result := 'Error: ' + IntToStr(ErrorCode); if Trim(Data) > '' then Result := Result + ' (' + Data + ')'; end; end; {case nr} end; {ErrorStr} procedure TFFSQL.Execute; begin ClearErrors; ListStream.Clear; Extra := 1; { if there is a file name then load the file } if Trim(SourceFileName) <> '' then begin GetScanner.SrcStream.Clear; GetScanner.SrcStream.LoadFromFile(SourceFileName); end; { install error reporting procedure } GetScanner.ScannerError := StoreError; { instigate the compilation } DoBeforeParse; Parse; DoAfterParse; { generate the source listing to the ListStream } if (GenListWhen = glAlways) OR ((GenListWhen = glOnError) AND (ErrorList.Count > 0)) then GenerateListing; if ClearSourceStream then GetScanner.SrcStream.Clear; ListStream.Position := 0; // goto the beginning of the stream if Successful AND Assigned(OnSuccess) then OnSuccess(Self); if (NOT Successful) AND Assigned(OnFailure) then OnFailure(Self, ErrorList.Count); end; {Execute} procedure TFFSQL.Get; begin repeat GetScanner.Get(fCurrentInputSymbol); if fCurrentInputSymbol <= maxT then errDist := errDist + 1 else begin end; until fCurrentInputSymbol <= maxT; if Assigned(AfterGet) then AfterGet(Self, fCurrentInputSymbol); end; {Get} function TFFSQL.GetScanner : TFFSQLScanner; begin Result := Scanner AS TFFSQLScanner; end; {GetScanner} function TFFSQL._In(var s : SymbolSet; x : integer) : boolean; begin _In := x mod setsize in s[x div setsize]; end; {_In} procedure TFFSQL._SimpleAlias (var TableRef: TffSqlTableRef);var aSQLName: string; begin if (fCurrentInputSymbol = ASSym) then begin Get; end; _SQLName(aSQLName); TableRef.Alias := aSQLName; end; procedure TFFSQL._BooleanLiteral (Parent: TFFSqlNode; var BooleanLiteral: TFFSqlBooleanLiteral);begin BooleanLiteral := TFFSqlBooleanLiteral.Create(Parent); if (fCurrentInputSymbol = TRUESym) then begin Get; BooleanLiteral.Value := True; end else if (fCurrentInputSymbol = FALSESym) then begin Get; end else begin SynError(126); end; end; procedure TFFSQL._IntervalLiteral (Parent: TFFSqlNode; var IntervalLiteral: TFFSqlIntervalLiteral);begin IntervalLiteral := TFFSqlIntervalLiteral.Create(Parent); Expect(INTERVALSym); IntervalLiteral.StartDef := iUnspec; Expect(SQLStringSym); IntervalLiteral.Value := LexString; case fCurrentInputSymbol of YEARSym : begin Get; IntervalLiteral.StartDef := iYear; end; MONTHSym : begin Get; IntervalLiteral.StartDef := iMonth; end; DAYSym : begin Get; IntervalLiteral.StartDef := iDay; end; HOURSym : begin Get; IntervalLiteral.StartDef := iHour; end; MINUTESym : begin Get; IntervalLiteral.StartDef := iMinute; end; SECONDSym : begin Get; IntervalLiteral.StartDef := iSecond; end; else begin SynError(127); end; end; IntervalLiteral.EndDef := iUnspec; if (fCurrentInputSymbol = TOSym) then begin Get; case fCurrentInputSymbol of YEARSym : begin Get; IntervalLiteral.EndDef := iYear; end; MONTHSym : begin Get; IntervalLiteral.EndDef := iMonth; end; DAYSym : begin Get; IntervalLiteral.EndDef := iDay; end; HOURSym : begin Get; IntervalLiteral.EndDef := iHour; end; MINUTESym : begin Get; IntervalLiteral.EndDef := iMinute; end; SECONDSym : begin Get; IntervalLiteral.EndDef := iSecond; end; else begin SynError(128); end; end; end; end; procedure TFFSQL._TimestampLiteral (Parent: TFFSqlNode; var TimestampLiteral: TFFSqlTimestampLiteral);begin TimestampLiteral := TFFSqlTimestampLiteral.Create(Parent); Expect(TIMESTAMPSym); Expect(SQLStringSym); TimestampLiteral.Value := LexString; end; procedure TFFSQL._TimeLiteral (Parent: TFFSqlNode; var TimeLiteral: TFFSqlTimeLiteral);begin TimeLiteral := TFFSqlTimeLiteral.Create(Parent); Expect(TIMESym); Expect(SQLStringSym); TimeLiteral.Value := LexString; end; procedure TFFSQL._DateLiteral (Parent: TFFSqlNode; var DateLiteral: TFFSqlDateLiteral);begin DateLiteral := TFFSqlDateLiteral.Create(Parent); Expect(DATESym); Expect(SQLStringSym); DateLiteral.Value := LexString; end; procedure TFFSQL._StringLiteral (Parent: TFFSqlNode; var StringLiteral: TFFSqlStringLiteral);begin StringLiteral := TFFSqlStringLiteral.Create(Parent); Expect(SQLStringSym); StringLiteral.Value := LexString; end; procedure TFFSQL._IntegerLiteral (Parent: TFFSqlNode; var IntegerLiteral: TFFSqlIntegerLiteral);begin IntegerLiteral := TFFSqlIntegerLiteral.Create(Parent); Expect(integer_Sym); IntegerLiteral.Value := LexString; end; procedure TFFSQL._FloatLiteral (Parent: TFFSqlNode; var FloatLiteral: TFFSqlFloatLiteral);begin FloatLiteral := TFFSqlFloatLiteral.Create(Parent); Expect(floatSym); FloatLiteral.Value := LexString; end; procedure TFFSQL._WhenClause (Parent : TFFSqlNode; var WhenClause : TFFSqlWhenClause);var CondExp : TFFSqlCondExp; Exp : TFFSqlSimpleExpression; begin WhenClause := TFFSqlWhenClause.Create(Parent); Expect(WHENSym); _CondExp(WhenClause, CondExp); WhenClause.WhenExp := CondExp; Expect(THENSym); if (fCurrentInputSymbol = NULLSym) then begin Get; end else if _In(symSet[1], fCurrentInputSymbol) then begin _SimpleExpression(WhenClause, Exp); WhenClause.ThenExp := Exp; end else begin SynError(129); end; end; procedure TFFSQL._WhenClauseList (Parent: TFFSqlNode; var WhenClauseList : TFFSqlWhenClauseList);var WhenClause : TFFSqlWhenClause; begin WhenClauseList := TFFSqlWhenClauseList.Create(Parent); _WhenClause(WhenClauseList, WhenClause); WhenClauseList.AddWhenClause(WhenClause); while (fCurrentInputSymbol = WHENSym) do begin _WhenClause(WhenClauseList, WhenClause); WhenClauseList.AddWhenClause(WhenClause); end; end; procedure TFFSQL._CoalesceExpression (Parent: TFFSqlNode; var CoalesceExp: TFFSqlCoalesceExpression);var Exp : TFFSqlSimpleExpression; begin CoalesceExp := TFFSqlCoalesceExpression.Create(Parent); Expect(_lparenSym); _SimpleExpression(CoalesceExp, Exp); CoalesceExp.AddArg(Exp); while (fCurrentInputSymbol = _commaSym) do begin Get; _SimpleExpression(CoalesceExp, Exp); CoalesceExp.AddArg(Exp); end; Expect(_rparenSym); end; procedure TFFSQL._CaseExpression (Parent: TFFSqlNode; var CaseExp: TFFSqlCaseExpression);var WhenClauseList : TFFSqlWhenClauseList; var Exp : TFFSqlSimpleExpression; begin CaseExp := TFFSqlCaseExpression.Create(Parent); _WhenClauseList(CaseExp, WhenClauseList); CaseExp.WhenClauseList := WhenClauseList; if (fCurrentInputSymbol = ELSESym) then begin Get; if (fCurrentInputSymbol = NULLSym) then begin Get; end else if _In(symSet[1], fCurrentInputSymbol) then begin _SimpleExpression(CaseExp, Exp); CaseExp.ElseExp := Exp; end else begin SynError(130); end; end; Expect(ENDSym); end; procedure TFFSQL._ScalarFunction (Parent: TFFSqlNode; var Func: TFFSqlScalarFunc);var Exp : TFFSqlSimpleExpression; var CaseExp : TFFSqlCaseExpression; var CoalesceExp : TFFSqlCoalesceExpression; begin Func := TFFSqlScalarFunc.Create(Parent); case fCurrentInputSymbol of CASESym : begin Get; _CaseExpression(Func, CaseExp); Func.CaseExp := CaseExp; Func.SQLFunction := sfCase; end; CHARACTER_underscoreLENGTHSym, CHAR_underscoreLENGTHSym : begin if (fCurrentInputSymbol = CHARACTER_underscoreLENGTHSym) then begin Get; end else begin Get; end; Expect(_lparenSym); _SimpleExpression(Func, Exp); Expect(_rparenSym); Func.SQLFunction := sfCharLen; Func.Arg1 := Exp; end; COALESCESym : begin Get; _CoalesceExpression(Func, CoalesceExp); Func.CoalesceExp := CoalesceExp; Func.SQLFunction := sfCoalesce; end; CURRENT_underscoreDATESym : begin Get; Func.SQLFunction := sfCurrentDate; end; CURRENT_underscoreTIMESym : begin Get; Func.SQLFunction := sfCurrentTime; end; CURRENT_underscoreTIMESTAMPSym : begin Get; Func.SQLFunction := sfCurrentTimestamp; end; CURRENT_underscoreUSERSym, USERSym : begin if (fCurrentInputSymbol = CURRENT_underscoreUSERSym) then begin Get; end else begin Get; end; Func.SQLFunction := sfCurrentUser; end; LOWERSym : begin Get; Expect(_lparenSym); _SimpleExpression(Func, Exp); Expect(_rparenSym); Func.SQLFunction := sfLower; Func.Arg1 := Exp end; UPPERSym : begin Get; Expect(_lparenSym); _SimpleExpression(Func, Exp); Expect(_rparenSym); Func.SQLFunction := sfUpper; Func.Arg1 := Exp; end; POSITIONSym : begin Get; Expect(_lparenSym); _SimpleExpression(Func, Exp); Func.SQLFunction := sfPosition; Func.Arg1 := Exp; if (fCurrentInputSymbol = _commaSym) then begin Get; end else if (fCurrentInputSymbol = INSym) then begin Get; end else begin SynError(131); end; _SimpleExpression(Func, Exp); Func.Arg2 := Exp; Expect(_rparenSym); end; SESSION_underscoreUSERSym : begin Get; Func.SQLFunction := sfSessionUser; end; SUBSTRINGSym : begin Get; Expect(_lparenSym); _SimpleExpression(Func, Exp); Func.SQLFunction := sfSubstring; Func.Arg1 := Exp; Expect(FROMSym); _SimpleExpression(Func, Exp); Func.Arg2 := Exp; if (fCurrentInputSymbol = FORSym) then begin Get; _SimpleExpression(Func, Exp); Func.Arg3 := Exp; end; Expect(_rparenSym); end; SYSTEM_underscoreUSERSym : begin Get; Func.SQLFunction := sfSystemUser; end; TRIMSym : begin Get; Expect(_lparenSym); Func.SQLFunction := sfTrim; Func.LTB := ltbBoth; if (fCurrentInputSymbol = LEADINGSym) OR (fCurrentInputSymbol = TRAILINGSym) OR (fCurrentInputSymbol = BOTHSym) then begin if (fCurrentInputSymbol = LEADINGSym) then begin Get; Func.LTB := ltbLeading; end else if (fCurrentInputSymbol = TRAILINGSym) then begin Get; Func.LTB := ltbTrailing; end else begin Get; end; end; if _In(symSet[1], fCurrentInputSymbol) then begin _SimpleExpression(Func, Exp); Func.Arg1 := Exp; end; if (fCurrentInputSymbol = FROMSym) then begin Get; _SimpleExpression(Func, Exp); Func.Arg2 := Exp end; Expect(_rparenSym); end; EXTRACTSym : begin Get; Expect(_lparenSym); Func.SQLFunction := sfExtract; case fCurrentInputSymbol of YEARSym : begin Get; Func.xDef := iYear; end; MONTHSym : begin Get; Func.xDef := iMonth; end; DAYSym : begin Get; Func.xDef := iDay; end; HOURSym : begin Get; Func.xDef := iHour; end; MINUTESym : begin Get; Func.xDef := iMinute; end; SECONDSym : begin Get; Func.xDef := iSecond; end; else begin SynError(132); end; end; Expect(FROMSym); _SimpleExpression(Func, Exp); Func.Arg1 := Exp; Expect(_rparenSym); end; NULLIFSym : begin Get; Expect(_lparenSym); Func.SQLFunction := sfNullIf; _SimpleExpression(Func, Exp); Func.Arg1 := Exp; Expect(_commaSym); _SimpleExpression(Func, Exp); Func.Arg2 := Exp; Expect(_rparenSym); end; ABSSym : begin Get; Expect(_lparenSym); Func.SQLFunction := sfAbs; _SimpleExpression(Func, Exp); Func.Arg1 := Exp; Expect(_rparenSym); end; CEILINGSym : begin Get; Expect(_lparenSym); Func.SQLFunction := sfCeil; _SimpleExpression(Func, Exp); Func.Arg1 := Exp; Expect(_rparenSym); end; FLOORSym : begin Get; Expect(_lparenSym); Func.SQLFunction := sfFloor; _SimpleExpression(Func, Exp); Func.Arg1 := Exp; Expect(_rparenSym); end; EXPSym : begin Get; Expect(_lparenSym); Func.SQLFunction := sfExp; _SimpleExpression(Func, Exp); Func.Arg1 := Exp; Expect(_rparenSym); end; LOGSym : begin Get; Expect(_lparenSym); Func.SQLFunction := sfLog; _SimpleExpression(Func, Exp); Func.Arg1 := Exp; Expect(_rparenSym); end; POWERSym : begin Get; Expect(_lparenSym); Func.SQLFunction := sfPower; _SimpleExpression(Func, Exp); Func.Arg1 := Exp; Expect(_commaSym); _SimpleExpression(Func, Exp); Func.Arg2 := Exp; Expect(_rparenSym); end; RANDSym : begin Get; Func.SQLFunction := sfRand; end; ROUNDSym : begin Get; Expect(_lparenSym); Func.SQLFunction := sfRound; _SimpleExpression(Func, Exp); Func.Arg1 := Exp; Expect(_rparenSym); end; else begin SynError(133); end; end; end; procedure TFFSQL._Param (Parent: TFFSqlNode; var Param: TFFSqlParam);begin Param := TFFSqlParam.Create(Parent); Expect(_querySym); end; procedure TFFSQL._Literal (Parent: TFFSqlNode; var Literal: TFFSqlLiteral);var FloatLiteral : TFFSqlFloatLiteral; var IntegerLiteral : TFFSqlIntegerLiteral; var StringLiteral : TFFSqlStringLiteral; var DateLiteral : TFFSqlDateLiteral; var TimeLiteral : TFFSqlTimeLiteral; var TimestampLiteral : TFFSqlTimestampLiteral; var IntervalLiteral : TFFSqlIntervalLiteral; var BooleanLiteral : TFFSqlBooleanLiteral; begin Literal := TFFSqlLiteral.Create(Parent); case fCurrentInputSymbol of floatSym : begin _FloatLiteral(Literal, FloatLiteral); Literal.FloatLiteral := FloatLiteral; end; integer_Sym : begin _IntegerLiteral(Literal, IntegerLiteral); Literal.IntegerLiteral := IntegerLiteral; end; SQLStringSym : begin _StringLiteral(Literal, StringLiteral); Literal.StringLiteral := StringLiteral; end; DATESym : begin _DateLiteral(Literal, DateLiteral); Literal.DateLiteral := DateLiteral; end; TIMESym : begin _TimeLiteral(Literal, TimeLiteral); Literal.TimeLiteral := TimeLiteral; end; TIMESTAMPSym : begin _TimestampLiteral(Literal, TimestampLiteral); Literal.TimestampLiteral := TimestampLiteral; end; INTERVALSym : begin _IntervalLiteral(Literal, IntervalLiteral); Literal.IntervalLiteral := IntervalLiteral; end; TRUESym, FALSESym : begin _BooleanLiteral(Literal, BooleanLiteral); Literal.BooleanLiteral := BooleanLiteral; end; else begin SynError(134); end; end; end; procedure TFFSQL._Factor (Parent: TFFSqlNode; var Factor : TFFSqlFactor; MulOp: TFFSqlMulOp);var FieldRef : TFFSqlFieldRef; var CondExp : TFFSqlCondExp; var Literal : TFFSqlLiteral; var Param : TFFSqlParam; var Select : TFFSqlSELECT; var Agg : TFFSqlAggregate; var Func : TFFSqlScalarFunc; begin Factor := TFFSqlFactor.Create(Parent); Factor.MulOp := MulOp; if (fCurrentInputSymbol = _minusSym) then begin Get; Factor.UnaryMinus := True; end; case fCurrentInputSymbol of _lparenSym : begin Get; if _In(symSet[2], fCurrentInputSymbol) then begin _CondExp(Factor, CondExp); Factor.CondExp := CondExp; end else if (fCurrentInputSymbol = SELECTSym) then begin _SelectStatement(Factor, Select); Factor.SubQuery := Select; end else begin SynError(135); end; Expect(_rparenSym); end; identSym, SQLNameStringSym : begin _FieldRef(Factor, FieldRef); Factor.FieldRef := FieldRef; end; integer_Sym, floatSym, SQLStringSym, TRUESym, FALSESym, DATESym, TIMESym, TIMESTAMPSym, INTERVALSym : begin _Literal(Factor, Literal); Factor.Literal := Literal; end; _querySym : begin _Param(Factor, Param); Factor.Param := Param; end; COUNTSym, MINSym, MAXSym, SUMSym, AVGSym : begin _Aggregate(Factor, Agg); Factor.Aggregate := Agg; end; CASESym, CHARACTER_underscoreLENGTHSym, CHAR_underscoreLENGTHSym, COALESCESym, CURRENT_underscoreDATESym, CURRENT_underscoreTIMESym, CURRENT_underscoreTIMESTAMPSym, CURRENT_underscoreUSERSym, USERSym, LOWERSym, UPPERSym, POSITIONSym, SESSION_underscoreUSERSym, SUBSTRINGSym, SYSTEM_underscoreUSERSym, TRIMSym, EXTRACTSym, NULLIFSym, ABSSym, CEILINGSym, FLOORSym, EXPSym, LOGSym, POWERSym, RANDSym, ROUNDSym : begin _ScalarFunction(Factor, Func); Factor.ScalarFunc := Func; end; else begin SynError(136); end; end; end; procedure TFFSQL._Term (Parent: TFFSqlNode; var Term : TFFSqlTerm; AddOp : TFFSqlAddOp);var Factor : TFFSqlFactor; var MO : TFFSqlMulOp; begin Term := TFFSqlTerm.Create(Parent); Term.AddOp := AddOp; _Factor(Term, Factor, moMul); Term.AddFactor(Factor); while (fCurrentInputSymbol = _starSym) OR (fCurrentInputSymbol = _slashSym) do begin if (fCurrentInputSymbol = _starSym) then begin Get; MO := moMul; end else begin Get; MO := moDiv; end; _Factor(Term, Factor, MO); Term.AddFactor(Factor); end; end; procedure TFFSQL._SimpleExpressionList (Parent: TFFSqlNode; var SimpleExpressionList: TFFSqlSimpleExpressionList);var SimpleExpression : TFFSqlSimpleExpression; begin SimpleExpressionList := TFFSqlSimpleExpressionList.Create(Parent); _SimpleExpression(SimpleExpressionList, SimpleExpression); SimpleExpressionList.AddExpression(SimpleExpression); while (fCurrentInputSymbol = _commaSym) do begin Get; _SimpleExpression(SimpleExpressionList, SimpleExpression); SimpleExpressionList.AddExpression(SimpleExpression); end; end; procedure TFFSQL._IsTest (Parent: TFFSqlNode; var IsTest: TFFSqlIsTest);begin Expect(ISSym); IsTest := TFFSqlIsTest.Create(Parent); if (fCurrentInputSymbol = NOTSym) then begin Get; IsTest.UnaryNot := True; end; if (fCurrentInputSymbol = NULLSym) then begin Get; IsTest.IsOp := ioNull; end else if (fCurrentInputSymbol = TRUESym) then begin Get; IsTest.IsOp := ioTrue; end else if (fCurrentInputSymbol = FALSESym) then begin Get; IsTest.IsOp := ioFalse; end else if (fCurrentInputSymbol = UNKNOWNSym) then begin Get; IsTest.IsOp := ioUnknown; end else begin SynError(137); end; end; procedure TFFSQL._MatchClause (Parent: TFFSqlNode; var MatchClause: TFFSqlMatchClause);var Select : TFFSqlSelect; begin MatchClause := TFFSqlMatchClause.Create(Parent); Expect(MATCHSym); if (fCurrentInputSymbol = UNIQUESym) then begin Get; MatchClause.Unique := True; end; MatchClause.Option := moUnspec; if (fCurrentInputSymbol = FULLSym) OR (fCurrentInputSymbol = PARTIALSym) then begin if (fCurrentInputSymbol = PARTIALSym) then begin Get; MatchClause.Option := moPartial; end else begin Get; MatchClause.Option := moFull; end; end; Expect(_lparenSym); _SelectStatement(MatchClause, Select); MatchClause.SubQuery := Select; Expect(_rparenSym); end; procedure TFFSQL._InClause (Parent: TFFSqlNode; var InClause: TFFSqlInClause; Negated: Boolean);var SimpleExpressionList : TFFSqlSimpleExpressionList; var Select : TFFSqlSelect; begin InClause := TFFSqlInClause.Create(Parent); InClause.Negated := Negated; Expect(INSym); Expect(_lparenSym); if (fCurrentInputSymbol = SELECTSym) then begin _SelectStatement(InClause, Select); InClause.SubQuery := Select; end else if _In(symSet[1], fCurrentInputSymbol) then begin _SimpleExpressionList(InClause, SimpleExpressionList); Inclause.SimpleExpList := SimpleExpressionList; end else begin SynError(138); end; Expect(_rparenSym); end; procedure TFFSQL._LikeClause (Parent: TFFSqlNode; var LikeClause: TFFSqlLikeClause; Negated: Boolean);var SimpleExpression : TFFSqlSimpleExpression; begin LikeClause := TFFSqlLikeClause.Create(Parent); LikeClause.Negated := Negated; Expect(LIKESym); _SimpleExpression(LikeClause, SimpleExpression); LikeClause.SimpleExp := SimpleExpression; if (fCurrentInputSymbol = ESCAPESym) then begin Get; _SimpleExpression(LikeClause, SimpleExpression); LikeClause.EscapeExp := SimpleExpression; end; if (fCurrentInputSymbol = IGNORESym) then begin Get; Expect(CASESym); LikeClause.IgnoreCase := True; end; end; procedure TFFSQL._BetweenClause (Parent: TFFSqlNode; var BetweenClause: TFFSqlBetweenClause; Negated: Boolean);var SimpleExpression : TFFSqlSimpleExpression; begin BetweenClause := TFFSqlBetweenClause.Create(Parent); BetweenClause.Negated := Negated; Expect(BETWEENSym); _SimpleExpression(BetweenClause, SimpleExpression); BetweenClause.SimpleLow := SimpleExpression; Expect(ANDSym); _SimpleExpression(BetweenClause, SimpleExpression); BetweenClause.SimpleHigh := SimpleExpression; end; procedure TFFSQL._AllOrAnyClause (Parent: TFFSqlNode; var AllOrAny: TFFSqlAllOrAnyClause);var Select : TFFSqlSelect; begin AllOrAny := TFFSqlAllOrAnyClause.Create(Parent); if (fCurrentInputSymbol = ALLSym) then begin Get; AllOrAny.All := True; end else if (fCurrentInputSymbol = ANYSym) then begin Get; end else if (fCurrentInputSymbol = SOMESym) then begin Get; end else begin SynError(139); end; Expect(_lparenSym); _SelectStatement(AllOrAny, Select); AllOrAny.SubQuery := Select; Expect(_rparenSym); end; procedure TFFSQL._UniqueClause (Parent: TFFSqlNode; var Unique: TFFSqlUniqueClause);var TableExp : TFFSqlTableExp; begin Unique := TFFSqlUniqueClause.Create(Parent); Expect(UNIQUESym); Expect(_lparenSym); _TableExp(Unique, TableExp); Unique.SubQuery := TableExp; Expect(_rparenSym); end; procedure TFFSQL._ExistsClause (Parent: TFFSqlNode; var Exists: TFFSqlExistsClause);var Select : TFFSqlSelect; begin Exists := TFFSqlExistsClause.Create(Parent); Expect(EXISTSSym); Expect(_lparenSym); _SelectStatement(Exists, Select); Exists.SubQuery := Select; Expect(_rparenSym); end; procedure TFFSQL._CondPrimary (Parent: TFFSqlNode; var CondPrimary : TFFSqlCondPrimary);var SimpleExpression : TFFSqlSimpleExpression; var RelOp : TFFSqlRelop; var BetweenClause : TFFSqlBetweenClause; var LikeClause : TFFSqlLikeClause; var InClause : TFFSqlInClause; var IsTest: TFFSqlIsTest; var AllOrAny : TFFSqlAllOrAnyClause; var ExistsClause : TFFSqlExistsClause; var UniqueClause : TFFSqlUniqueClause; var MatchClause : TFFSqlMatchClause; begin CondPrimary := TFFSqlCondPrimary.Create(Parent); RelOp := roNone; if (fCurrentInputSymbol = EXISTSSym) then begin _ExistsClause(CondPrimary, ExistsClause); CondPrimary.ExistsClause := ExistsClause; end else if (fCurrentInputSymbol = UNIQUESym) then begin _UniqueClause(CondPrimary, UniqueClause); CondPrimary.UniqueClause := UniqueClause; end else if _In(symSet[1], fCurrentInputSymbol) then begin _SimpleExpression(CondPrimary, SimpleExpression); CondPrimary.SimpleExp1 := SimpleExpression; if _In(symSet[3], fCurrentInputSymbol) then begin if _In(symSet[4], fCurrentInputSymbol) then begin case fCurrentInputSymbol of _equalSym, _less_equalSym, _lessSym, _greaterSym, _greater_equalSym, _less_greaterSym : begin case fCurrentInputSymbol of _equalSym : begin Get; RelOp := roEQ; end; _less_equalSym : begin Get; RelOp := roLE; end; _lessSym : begin Get; RelOp := roL; end; _greaterSym : begin Get; RelOp := roG; end; _greater_equalSym : begin Get; RelOp := roGE; end; _less_greaterSym : begin Get; RelOp := roNE; end; else begin SynError(140); end; end; CondPrimary.RelOp := RelOp; if (fCurrentInputSymbol = ALLSym) OR (fCurrentInputSymbol = ANYSym) OR (fCurrentInputSymbol = SOMESym) then begin _AllOrAnyClause(CondPrimary, AllOrAny); CondPrimary.AllOrAnyClause := AllOrAny; end else if _In(symSet[1], fCurrentInputSymbol) then begin _SimpleExpression(CondPrimary, SimpleExpression); CondPrimary.SimpleExp2 := SimpleExpression; end else begin SynError(141); end; end; BETWEENSym : begin _BetweenClause(CondPrimary, BetweenClause, False); CondPrimary.BetweenClause := BetweenClause; end; LIKESym : begin _LikeClause(CondPrimary, LikeClause, False); CondPrimary.LikeClause := LikeClause; end; INSym : begin _InClause(CondPrimary, InClause, False); CondPrimary.InClause := InClause; end; MATCHSym : begin _MatchClause(CondPrimary, MatchClause); CondPrimary.MatchClause := MatchClause; end; NOTSym : begin Get; if (fCurrentInputSymbol = BETWEENSym) then begin _BetweenClause(CondPrimary, BetweenClause, True); CondPrimary.BetweenClause := BetweenClause; end else if (fCurrentInputSymbol = LIKESym) then begin _LikeClause(CondPrimary, LikeClause, True); CondPrimary.LikeClause := LikeClause; end else if (fCurrentInputSymbol = INSym) then begin _InClause(CondPrimary, InClause, True); CondPrimary.InClause := InClause; end else begin SynError(142); end; end; else begin SynError(143); end; end; end else begin _IsTest(CondPrimary, IsTest); CondPrimary.IsTest := IsTest; CondPrimary.RelOp := RoNone; end; end; end else begin SynError(144); end; end; procedure TFFSQL._CondFactor (Parent: TFFSqlNode; var CondFactor: TFFSqlCondFactor);var CondPrimary : TFFSqlCondPrimary; begin CondFactor := TFFSqlCondFactor.Create(Parent); if (fCurrentInputSymbol = NOTSym) then begin Get; CondFactor.UnaryNot := True; end; _CondPrimary(CondFactor, CondPrimary); CondFactor.CondPrimary := CondPrimary; end; procedure TFFSQL._CondTerm (Parent: TFFSqlNode; var CondTerm : TFFSqlCondTerm);var CondFactor : TFFSqlCondFactor; begin CondTerm := TFFSqlCondTerm.Create(Parent); _CondFactor(CondTerm, CondFactor); CondTerm.AddCondFactor(CondFactor); while (fCurrentInputSymbol = ANDSym) do begin Get; _CondFactor(CondTerm, CondFactor); CondTerm.AddCondFactor(CondFactor); end; end; procedure TFFSQL._GroupColumn (Parent: TFFSqlNode; var Col : TFFSqlGroupColumn);var aSQLName : string; begin Col := TFFSqlGroupColumn.Create(Parent); aSQLName := ''; _SQLName(aSQLName); if (fCurrentInputSymbol = _pointSym) then begin Get; Col.TableName := aSQLName; _SQLName(aSQLName); end; Col.FieldName := aSQLName; end; procedure TFFSQL._FieldRef (Parent: TFFSqlNode; var FieldRef: TFFSqlFieldRef);var aSQLName : string; begin FieldRef := TFFSqlFieldRef.Create(Parent); aSQLName := ''; _SQLName(aSQLName); if (fCurrentInputSymbol = _pointSym) then begin Get; FieldRef.TableName := aSQLName; if (fCurrentInputSymbol = identSym) OR (fCurrentInputSymbol = SQLNameStringSym) then begin _SQLName(aSQLName); end else if (fCurrentInputSymbol = _starSym) then begin Get; aSQLName := ''; end else begin SynError(145); end; end; FieldRef.FieldName := aSQLName; end; procedure TFFSQL._Aggregate (Parent: TFFSqlNode; var Aggregate : TFFSqlAggregate);var SimpleExpression : TFFSqlSimpleExpression; begin if Parent.OwnerSelect.InWhere then SynError(202); Aggregate := TFFSqlAggregate.Create(Parent); if (fCurrentInputSymbol = COUNTSym) then begin Get; Aggregate.AgFunction := agCount; Expect(_lparenSym); if (fCurrentInputSymbol = _starSym) then begin Get; end else if _In(symSet[5], fCurrentInputSymbol) then begin if (fCurrentInputSymbol = ALLSym) OR (fCurrentInputSymbol = DISTINCTSym) then begin if (fCurrentInputSymbol = ALLSym) then begin Get; end else begin Get; Aggregate.Distinct := True; end; end; _SimpleExpression(Aggregate, SimpleExpression); Aggregate.SimpleExpression := SimpleExpression; end else begin SynError(146); end; Expect(_rparenSym); end else if (fCurrentInputSymbol = MINSym) OR (fCurrentInputSymbol = MAXSym) OR (fCurrentInputSymbol = SUMSym) OR (fCurrentInputSymbol = AVGSym) then begin if (fCurrentInputSymbol = MINSym) then begin Get; Aggregate.AgFunction := agMin; end else if (fCurrentInputSymbol = MAXSym) then begin Get; Aggregate.AgFunction := agMax; end else if (fCurrentInputSymbol = SUMSym) then begin Get; Aggregate.AgFunction := agSum; end else begin Get; Aggregate.AgFunction := agAvg; end; Expect(_lparenSym); if (fCurrentInputSymbol = ALLSym) OR (fCurrentInputSymbol = DISTINCTSym) then begin if (fCurrentInputSymbol = ALLSym) then begin Get; end else begin Get; Aggregate.Distinct := True; end; end; _SimpleExpression(Aggregate, SimpleExpression); Aggregate.SimpleExpression := SimpleExpression; if Aggregate.SimpleExpression.IsAggregateExpression then SynError(201); Expect(_rparenSym); end else begin SynError(147); end; end; procedure TFFSQL._Column (Parent: TFFSqlNode; var Col : TFFSqlColumn);var ColumnName : string; begin Col := TFFSqlColumn.Create(Parent); _SQLName(ColumnName); Col.ColumnName := ColumnName; end; procedure TFFSQL._ColumnAlias (var Selection : TFFSqlSelection);var Col : TFFSqlColumn; begin if (fCurrentInputSymbol = ASSym) then begin Get; end; _Column(Selection, Col); Selection.Column := Col; end; procedure TFFSQL._Selection (SelectionList: TFFSqlSelectionList);var Selection : TFFSqlSelection; var Exp : TFFSqlSimpleExpression; var Term: TFFSqlTerm; var Factor: TFFSqlFactor; var FieldRef: TFFSqlFieldRef; begin Selection := TFFSqlSelection.Create(SelectionList); if (fCurrentInputSymbol = _starSym) then begin Get; Exp := TFFSqlSimpleExpression.Create(Selection); Term := TFFSqlTerm.Create(Exp); Factor := TFFSqlFactor.Create(Term); FieldRef := TFFSqlFieldRef.Create(Factor); Factor.FieldRef := FieldRef; Term.AddFactor(Factor); Exp.AddTerm(Term); Selection.SimpleExpression := Exp; end else if _In(symSet[1], fCurrentInputSymbol) then begin _SimpleExpression(Selection, Exp); Selection.SimpleExpression := Exp; if (fCurrentInputSymbol = identSym) OR (fCurrentInputSymbol = SQLNameStringSym) OR (fCurrentInputSymbol = ASSym) then begin _ColumnAlias(Selection); end; end else begin SynError(148); end; SelectionList.AddSelection(Selection); end; procedure TFFSQL._OrderColumn (Parent: TFFSqlNode; var Col : TFFSqlOrderColumn);var aSQLName : string; begin Col := TFFSqlOrderColumn.Create(Parent); aSQLName := ''; _SQLName(aSQLName); if (fCurrentInputSymbol = _pointSym) then begin Get; Col.TableName := aSQLName; aSQLName := ''; _SQLName(aSQLName); end; Col.FieldName := aSQLName; end; procedure TFFSQL._OrderItem (Parent: TFFSqlNode; var OrderItem : TFFSqlOrderItem);var OrderColumn : TFFSqlOrderColumn; begin OrderItem := TFFSqlOrderItem.Create(Parent); if (fCurrentInputSymbol = identSym) OR (fCurrentInputSymbol = SQLNameStringSym) then begin _OrderColumn(OrderItem, OrderColumn); OrderItem.Column := OrderColumn; end else if (fCurrentInputSymbol = integer_Sym) then begin Get; OrderItem.Index := LexString; end else begin SynError(149); end; if (fCurrentInputSymbol = ASCSym) OR (fCurrentInputSymbol = DESCSym) then begin if (fCurrentInputSymbol = ASCSym) then begin Get; end else begin Get; OrderItem.Descending := True; end; end; end; procedure TFFSQL._UpdateItem (Parent: TFFSqlNode; var UpdateItem : TFFSqlUpdateItem);var Simplex : TFFSqlSimpleExpression; var aSQLName : string; begin UpdateItem := TFFSqlUpdateItem.Create(Parent); _SQLName(aSQLName); UpdateItem.ColumnName := aSQLName; Expect(_equalSym); if (fCurrentInputSymbol = DEFAULTSym) then begin Get; UpdateItem.Default := True; end else if (fCurrentInputSymbol = NULLSym) then begin Get; end else if _In(symSet[1], fCurrentInputSymbol) then begin _SimpleExpression(UpdateItem, Simplex); UpdateItem.Simplex := Simplex; end else begin SynError(150); end; end; procedure TFFSQL._UpdateList (Parent: TFFSqlNode; var UpdateList : TFFSqlUpdateList);var UpdateItem : TFFSqlUpdateItem; begin UpdateList := TFFSqlUpdateList.Create(Parent); _UpdateItem(UpdateList, UpdateItem); UpdateList.AddItem(UpdateItem); while (fCurrentInputSymbol = _commaSym) do begin Get; _UpdateItem(UpdateList, UpdateItem); UpdateList.AddItem(UpdateItem); end; end; procedure TFFSQL._SimpleTableRef (Parent: TFFSqlNode; var TableRef: TffSqlTableRef);var aSQLName : string; begin TableRef := TFFSqlTableRef.Create(Parent); _SQLName(aSQLName); TableRef.TableName := aSQLName; if (fCurrentInputSymbol = _pointSym) then begin Get; _SQLName(aSQLName); TableRef.DatabaseName := TableRef.TableName; TableRef.TableName := aSQLName; end; if (fCurrentInputSymbol = identSym) OR (fCurrentInputSymbol = SQLNameStringSym) OR (fCurrentInputSymbol = ASSym) then begin _SimpleAlias(TableRef); end; end; procedure TFFSQL._SimpleExpression (Parent: TFFSqlNode; var SimpleExpression : TFFSqlSimpleExpression);var Term : TFFSqlTerm; var AO : TFFSqlAddOp; begin SimpleExpression := TFFSqlSimpleExpression.Create(Parent); _Term(SimpleExpression, Term, aoPlus); SimpleExpression.AddTerm(Term); while (fCurrentInputSymbol = _plusSym) OR (fCurrentInputSymbol = _minusSym) OR (fCurrentInputSymbol = _bar_barSym) do begin if (fCurrentInputSymbol = _plusSym) then begin Get; AO := aoPlus; end else if (fCurrentInputSymbol = _minusSym) then begin Get; AO := aoMinus; end else begin Get; AO := aoConcat; end; _Term(SimpleExpression, Term, AO); SimpleExpression.AddTerm(Term); end; end; procedure TFFSQL._ValueItem (Parent: TFFSqlNode; var ValueItem : TFFSqlValueItem); var Simplex : TFFSqlSimpleExpression; begin ValueItem := TFFSqlValueItem.Create(Parent); if (fCurrentInputSymbol = DEFAULTSym) then begin Get; ValueItem.Default := True; end else if (fCurrentInputSymbol = NULLSym) then begin Get; end else if _In(symSet[1], fCurrentInputSymbol) then begin _SimpleExpression(ValueItem, Simplex); ValueItem.Simplex := Simplex; end else begin SynError(151); end; end; procedure TFFSQL._InsertItem (Parent: TFFSqlNode; var InsertItem : TFFSqlInsertItem);var aSQLName: string; begin InsertItem := TFFSqlInsertItem.Create(Parent); _SQLName(aSQLName); InsertItem.ColumnName := aSQLName; end; procedure TFFSQL._ValueList (Parent: TFFSqlNode; var ValueList : TFFSqlValueList);var ValueItem : TFFSqlValueItem; begin ValueList := TFFSqlValueList.Create(Parent); _ValueItem(ValueList, ValueItem); ValueList.AddItem(ValueItem); while (fCurrentInputSymbol = _commaSym) do begin Get; _ValueItem(ValueList, ValueItem); ValueList.AddItem(ValueItem); end; end; procedure TFFSQL._TableConstructor (Parent: TFFSqlNode; var ValueList: TffSqlValueList);begin Expect(VALUESSym); Expect(_lparenSym); _ValueList(Parent, ValueList); Expect(_rparenSym); end; procedure TFFSQL._NonJoinTablePrimary (Parent: TffSqlNode; var NonJoinTablePrimary: TffSqlNonJoinTablePrimary);var ValueList: TffSqlValueList; var NonJoinTableExp: TffSqlNonJoinTableExp; var TableRef: TffSqlTableRef; var SelectSt: TFFSqlSELECT; begin NonJoinTablePrimary := TffSqlNonJoinTablePrimary.Create(Parent); if IsParenNonJoinTableExp then begin Expect(_lparenSym); _NonJoinTableExp(NonJoinTablePrimary, NonJoinTableExp); NonJoinTablePrimary.NonJoinTableExp := NonJoinTableExp; Expect(_rparenSym); end else if (fCurrentInputSymbol = SELECTSym) then begin _SelectStatement(NonJoinTablePrimary, SelectSt); NonJoinTablePrimary.SelectSt := SelectSt; end else if (fCurrentInputSymbol = TABLESym) then begin Get; _TableRef(NonJoinTablePrimary, TableRef); NonJoinTablePrimary.TableRef := TableRef; end else if (fCurrentInputSymbol = VALUESSym) then begin _TableConstructor(NonJoinTablePrimary, ValueList); NonJoinTablePrimary.ValueList := ValueList; end else begin SynError(152); end; end; procedure TFFSQL._NonJoinTableTerm (Parent:TffSqlNode; var NonJoinTableTerm: TffSqlNonJoinTableTerm);var NonJoinTablePrimary: TffSqlNonJoinTablePrimary; begin NonJoinTableTerm := TffSqlNonJoinTableTerm.Create(Parent); _NonJoinTablePrimary(NonJoinTableTerm, NonJoinTablePrimary); NonJoinTableTerm.NonJoinTablePrimary := NonJoinTablePrimary; end; procedure TFFSQL._UsingItem (Parent: TFFSqlNode; var UsingItem : TFFSqlUsingItem);var aSQLName: string; begin UsingItem := TFFSqlUsingItem.Create(Parent); _SQLName(aSQLName); UsingItem.ColumnName := aSQLName; end; procedure TFFSQL._UsingList (Parent: TFFSqlNode; var UsingList : TFFSqlUsingList);var UsingItem : TFFSqlUsingItem; begin UsingList := TFFSqlUsingList.Create(Parent); _UsingItem(UsingList, UsingItem); UsingList.AddItem(UsingItem); while (fCurrentInputSymbol = _commaSym) do begin Get; _UsingItem(UsingList, UsingItem); UsingList.AddItem(UsingItem); end; end; procedure TFFSQL._TableRef (Parent: TFFSqlNode; var TableRef: TffSqlTableRef);var aSQLName : string; var TableExp: TffSqlTableExp; var ColumnList : TFFSqlInsertColumnList; begin TableRef := TFFSqlTableRef.Create(Parent); if IsTableExp then begin _TableExp(TableRef, TableExp); TableRef.TableExp := TableExp; if (fCurrentInputSymbol = identSym) OR (fCurrentInputSymbol = SQLNameStringSym) OR (fCurrentInputSymbol = ASSym) then begin _SimpleAlias(TableRef); end; if (fCurrentInputSymbol = _lparenSym) then begin Get; _InsertColumnList(TableRef, ColumnList); Expect(_rparenSym); TableRef.ColumnList := ColumnList; end; end else begin _SQLName(aSQLName); TableRef.TableName := aSQLName; if (fCurrentInputSymbol = _pointSym) then begin Get; _SQLName(aSQLName); TableRef.DatabaseName := TableRef.TableName; TableRef.TableName := aSQLName; end; if (fCurrentInputSymbol = identSym) OR (fCurrentInputSymbol = SQLNameStringSym) OR (fCurrentInputSymbol = ASSym) then begin _SimpleAlias(TableRef); end; end; end; procedure TFFSQL._NonJoinTableExp (Parent:TffSqlNode; var NonJoinTableExp: TffSqlNonJoinTableExp);var NonJoinTableTerm: TffSqlNonJoinTableTerm; begin NonJoinTableExp := TffSqlNonJoinTableExp.Create(Parent); _NonJoinTableTerm(NonJoinTableExp, NonJoinTableTerm); NonJoinTableExp.NonJoinTableTerm := NonJoinTableTerm; end; procedure TFFSQL._JoinTableExp (Parent:TffSqlNode; const JoinTableExp: TffSqlJoinTableExp); var TableRef: TffSqlTableRef; var CondExp: TFFSqlCondExp; var UsingList : TFFSqlUsingList; begin if (fCurrentInputSymbol = CROSSSym) then begin Get; Expect(JOINSym); _TableRef(JoinTableExp, TableRef); JoinTableExp.JoinType := jtCross; JoinTableExp.TableRef2 := TableRef; end else if _In(symSet[6], fCurrentInputSymbol) then begin if (fCurrentInputSymbol = NATURALSym) then begin Get; JoinTableExp.Natural := True; end; JoinTableExp.JoinType := jtInner; if (fCurrentInputSymbol = INNERSym) OR (fCurrentInputSymbol = LEFTSym) OR (fCurrentInputSymbol = RIGHTSym) OR (fCurrentInputSymbol = FULLSym) OR (fCurrentInputSymbol = UNIONSym) then begin if (fCurrentInputSymbol = INNERSym) then begin Get; end else if (fCurrentInputSymbol = LEFTSym) then begin Get; if (fCurrentInputSymbol = OUTERSym) then begin Get; end; JoinTableExp.JoinType := jtLeftOuter; end else if (fCurrentInputSymbol = RIGHTSym) then begin Get; if (fCurrentInputSymbol = OUTERSym) then begin Get; end; JoinTableExp.JoinType := jtRightOuter; end else if (fCurrentInputSymbol = FULLSym) then begin Get; if (fCurrentInputSymbol = OUTERSym) then begin Get; end; JoinTableExp.JoinType := jtFullOuter; end else begin Get; JoinTableExp.JoinType := jtUnion; end; end; Expect(JOINSym); _SimpleTableRefOrParenTableExp(JoinTableExp, TableRef); JoinTableExp.TableRef2 := TableRef; if (fCurrentInputSymbol = ONSym) OR (fCurrentInputSymbol = USINGSym) then begin if (fCurrentInputSymbol = ONSym) then begin Get; _CondExp(JoinTableExp, CondExp); JoinTableExp.CondExp := CondExp; end else begin Get; Expect(_lparenSym); _UsingList(JoinTableExp, UsingList); Expect(_rparenSym); JoinTableExp.UsingList := UsingList; end; end; end else begin SynError(153); end; end; procedure TFFSQL._SimpleTableRefOrParenTableExp (Parent: TFFSqlNode; var TableRef: TffSqlTableRef);var TableExp: TffSqlTableExp; var aSQLName : string; begin TableRef := TFFSqlTableRef.Create(Parent); if (fCurrentInputSymbol = identSym) OR (fCurrentInputSymbol = SQLNameStringSym) then begin _SQLName(aSQLName); TableRef.TableName := aSQLName; if (fCurrentInputSymbol = _pointSym) then begin Get; _SQLName(aSQLName); TableRef.DatabaseName := TableRef.TableName; TableRef.TableName := aSQLName; end; if (fCurrentInputSymbol = identSym) OR (fCurrentInputSymbol = SQLNameStringSym) OR (fCurrentInputSymbol = ASSym) then begin _SimpleAlias(TableRef); end; end else if (fCurrentInputSymbol = _lparenSym) then begin Get; _TableExp(TableRef, TableExp); TableRef.TableExp := TableExp; Expect(_rparenSym); if (fCurrentInputSymbol = identSym) OR (fCurrentInputSymbol = SQLNameStringSym) OR (fCurrentInputSymbol = ASSym) then begin _SimpleAlias(TableRef); end; end else begin SynError(154); end; end; procedure TFFSQL._InsertColumnList (Parent: TFFSqlNode; var InsertColumnList : TFFSqlInsertColumnList);var InsertItem : TFFSqlInsertItem; begin InsertColumnList := TFFSqlInsertColumnList.Create(Parent); _InsertItem(InsertColumnList, InsertItem); InsertColumnList.AddItem(InsertItem); while (fCurrentInputSymbol = _commaSym) do begin Get; _InsertItem(InsertColumnList, InsertItem); InsertColumnList.AddItem(InsertItem); end; end; procedure TFFSQL._SQLName (var aName : string);begin if (fCurrentInputSymbol = identSym) then begin Get; aName := LexString; end else if (fCurrentInputSymbol = SQLNameStringSym) then begin Get; aName := CheckSQLName(LexString); end else begin SynError(155); end; end; procedure TFFSQL._OrderList (Parent: TFFSqlNode; var OrderList : TFFSqlOrderList);var OrderItem : TFFSqlOrderItem; begin OrderList := TFFSqlOrderList.Create(Parent); _OrderItem(OrderList, OrderItem); OrderList.AddOrderItem(OrderItem); while (fCurrentInputSymbol = _commaSym) do begin Get; _OrderItem(OrderList, OrderItem); OrderList.AddOrderItem(OrderItem); end; end; procedure TFFSQL._GroupColumnList (Parent: TFFSqlNode; var ColumnList : TFFSqlGroupColumnList);var Col : TFFSqlGroupColumn; begin ColumnList := TFFSqlGroupColumnList.Create(Parent); _GroupColumn(Parent, Col); ColumnList.AddColumn(Col); while (fCurrentInputSymbol = _commaSym) do begin Get; _GroupColumn(Parent, Col); ColumnList.AddColumn(Col); end; end; procedure TFFSQL._CondExp (Parent: TFFSqlNode; var CondExp: TFFSqlCondExp);var CondTerm : TFFSqlCondTerm; begin CondExp := TFFSqlCondExp.Create(Parent); _CondTerm(CondExp, CondTerm); CondExp.AddCondTerm(CondTerm); while (fCurrentInputSymbol = ORSym) do begin Get; _CondTerm(CondExp, CondTerm); CondExp.AddCondTerm(CondTerm); end; end; procedure TFFSQL._TableRefList (Parent: TFFSqlNode; var TableRefList: TFFSqlTableRefList);var TableRef: TffSqlTableRef; begin TableRefList := TFFSqlTableRefList.Create(Parent); _TableRef(TableRefList, TableRef); TableRefList.AddTableRef(TableRef); while (fCurrentInputSymbol = _commaSym) do begin Get; _TableRef(TableRefList, TableRef); TableRefList.AddTableRef(TableRef); end; end; procedure TFFSQL._SelectionList (Parent: TFFSqlSELECT; var SelectionList: TFFSqlSelectionList);begin SelectionList := TFFSqlSelectionList.Create(Parent); _Selection(SelectionList); while (fCurrentInputSymbol = _commaSym) do begin Get; _Selection(SelectionList); end; end; procedure TFFSQL._SelectStatement (Parent: TFFSqlNode; var Select : TFFSqlSELECT);var SelectionList : TFFSqlSelectionList; var CondExp : TFFSqlCondExp; var GroupColumnList : TFFSqlGroupColumnList; var TableRefList : TFFSqlTableRefList; var OrderList : TFFSqlOrderList; begin Expect(SELECTSym); Select := TFFSqlSELECT.Create(Parent); if (fCurrentInputSymbol = ALLSym) OR (fCurrentInputSymbol = DISTINCTSym) then begin if (fCurrentInputSymbol = ALLSym) then begin Get; end else begin Get; Select.Distinct := True; end; end; _SelectionList(Select, SelectionList); Select.SelectionList := SelectionList; Expect(FROMSym); _TableRefList(Select, TableRefList); Select.TableRefList := TableRefList; if (fCurrentInputSymbol = WHERESym) then begin Get; Select.InWhere := True; _CondExp(Select, CondExp); Select.CondExpWhere := CondExp; Select.InWhere := False; end; if (fCurrentInputSymbol = GROUPSym) then begin Get; Expect(BYSym); _GroupColumnList(Select, GroupColumnList); Select.GroupColumnList := GroupColumnList; end; if (fCurrentInputSymbol = HAVINGSym) then begin Get; _CondExp(Select, CondExp); Select.CondExpHaving := CondExp; end; if (fCurrentInputSymbol = ORDERSym) then begin Get; Expect(BYSym); _OrderList(Select, OrderList); Select.OrderList := OrderList; end; end; procedure TFFSQL._DeleteStatement (Parent: TFFSqlNode; var DeleteSt : TFFSqlDELETE);var TableRef: TffSqlTableRef; var CondExp: TFFSqlCondExp; begin Expect(DELETESym); Expect(FROMSym); DeleteSt := TFFSqlDELETE.Create(Parent); _SimpleTableRef(DeleteSt, TableRef); DeleteSt.TableRef := TableRef; if (fCurrentInputSymbol = WHERESym) then begin Get; _CondExp(DeleteSt, CondExp); DeleteSt.CondExpWhere := CondExp; end; end; procedure TFFSQL._UpdateStatement (Parent: TFFSqlNode; var UpdateSt : TFFSqlUPDATE);var TableRef: TffSqlTableRef; var CondExp: TFFSqlCondExp; var UpdateList: TFFSqlUpdateList; begin Expect(UPDATESym); UpdateSt := TFFSqlUPDATE.Create(Parent); _SimpleTableRef(UpdateSt, TableRef); UpdateSt.TableRef := TableRef; Expect(SETSym); _UpdateList(UpdateSt, UpdateList); UpdateSt.UpdateList := UpdateList; if (fCurrentInputSymbol = WHERESym) then begin Get; _CondExp(UpdateSt, CondExp); UpdateSt.CondExpWhere := CondExp; end; end; procedure TFFSQL._InsertStatement (Parent: TFFSqlNode; var InsertSt : TFFSqlINSERT);var aSQLName: string; var InsertColumnList: TffSqlInsertColumnList; var TableExp: TffSqlTableExp; begin Expect(INSERTSym); Expect(INTOSym); InsertSt := TFFSqlINSERT.Create(Parent); _SQLName(aSQLName); InsertSt.TableName := aSQLName; if (fCurrentInputSymbol = DEFAULTSym) then begin Get; Expect(VALUESSym); InsertSt.DefaultValues := True; end else if IsColumnList then begin Expect(_lparenSym); _InsertColumnList(InsertSt, InsertColumnList); InsertSt.InsertColumnList := InsertColumnList; Expect(_rparenSym); _TableExp(InsertSt, TableExp); InsertSt.TableExp := TableExp; end else if (fCurrentInputSymbol = SELECTSym) OR (fCurrentInputSymbol = VALUESSym) OR (fCurrentInputSymbol = _lparenSym) OR (fCurrentInputSymbol = TABLESym) then begin _TableExp(InsertSt, TableExp); InsertSt.TableExp := TableExp; end else begin SynError(156); end; end; procedure TFFSQL._TableExp (Parent:TffSqlNode; var TableExp: TffSqlTableExp);var NestedTableExp: TffSqlTableExp; var JoinTableExp: TffSqlJoinTableExp; var TmpJoinTableExp: TffSqlJoinTableExp; var TmpTableExp: TffSqlTableExp; var TableRef, TmpTableRef: TffSqlTableRef; var NonJoinTableExp: TffSqlNonJoinTableExp; begin TableExp := TffSqlTableExp.Create(Parent); if IsJoinTableExp then begin JoinTableExp := TffSqlJoinTableExp.Create(TableExp); TableExp.JoinTableExp := JoinTableExp; _SimpleTableRefOrParenTableExp(JoinTableExp, TableRef); JoinTableExp.TableRef1 := TableRef; _JoinTableExp(TableExp, JoinTableExp); while _In(symSet[7], fCurrentInputSymbol) do begin TmpJoinTableExp := JoinTableExp; JoinTableExp := TffSqlJoinTableExp.Create(TableExp); TableExp.JoinTableExp := JoinTableExp; TmpTableRef := TffSqlTableRef.Create(JoinTableExp); TmpTableExp := TffSqlTableExp.Create(TmpTableRef); TmpJoinTableExp.Parent := TmpTableExp; TmpTableExp.JoinTableExp := TmpJoinTableExp; TmpTableRef.TableExp := TmpTableExp; JoinTableExp.TableRef1 := TmpTableRef; _JoinTableExp(TableExp, JoinTableExp); end; end else if (fCurrentInputSymbol = SELECTSym) OR (fCurrentInputSymbol = VALUESSym) OR (fCurrentInputSymbol = TABLESym) then begin _NonJoinTableExp(TableExp, NonJoinTableExp); TableExp.NonJoinTableExp := NonJoinTableExp; end else if (fCurrentInputSymbol = _lparenSym) then begin Get; _TableExp(TableExp, NestedTableExp); TableExp.NestedTableExp := NestedTableExp; Expect(_rparenSym); end else begin SynError(157); end; end; procedure TFFSQL._FFSQL; var TableExp: TffSqlTableExp; var InsertSt: TffSqlINSERT; var UpdateSt: TffSqlUPDATE; var DeleteSt: TffSqlDELETE; begin Init; if (fCurrentInputSymbol = NOINDEXSym) then begin Get; fRootNode.UseIndex := False end; if (fCurrentInputSymbol = NOREDUCESym) then begin Get; fRootNode.Reduce := False end; if IsTableExp then begin _TableExp(fRootNode, TableExp); fRootNode.TableExp := TableExp; end else if (fCurrentInputSymbol = INSERTSym) then begin _InsertStatement(fRootNode, InsertSt); fRootNode.Insert := InsertSt; end else if (fCurrentInputSymbol = UPDATESym) then begin _UpdateStatement(fRootNode, UpdateSt); fRootNode.Update := UpdateSt; end else if (fCurrentInputSymbol = DELETESym) then begin _DeleteStatement(fRootNode, DeleteSt); fRootNode.Delete := DeleteSt; end else begin SynError(158); end; if (fCurrentInputSymbol = _semicolonSym) then begin Get; end; if fCurrentInputSymbol <> EOFSYMB then SynError(200); Final; end; function TFFSQL.GetBuildDate : TDateTime; const BDate = 37579; Hour = 14; Min = 45; begin Result := BDate + EncodeTime(Hour, Min, 0 ,0); end; function TFFSQL.GetVersion : string; begin Result := '0.0.0.102'; end; function TFFSQL.GetVersionStr : string; begin Result := '0.0.0.102'; end; function TFFSQL.GetVersionInfo : string; begin Result := 'Comment: ' + #13#10 + 'Author: ' + #13#10 + 'Copyright: '; end; procedure TFFSQL.SetVersion(const Value : string); begin // This is a read only property. However, we want the value // to appear in the Object Inspector during design time. end; procedure TFFSQL.Parse; begin errDist := minErrDist; GetScanner._Reset; Get; _FFSQL; end; {Parse} procedure TFFSQL.InitSymSet; begin symSet[ 0, 0] := [EOFSYMB]; symSet[ 0, 1] := []; symSet[ 0, 2] := []; symSet[ 0, 3] := []; symSet[ 0, 4] := []; symSet[ 0, 5] := []; symSet[ 0, 6] := []; symSet[ 0, 7] := []; symSet[ 1, 0] := [identSym, integer_Sym, floatSym, SQLStringSym, SQLNameStringSym]; symSet[ 1, 1] := [_lparenSym-16]; symSet[ 1, 2] := [COUNTSym-32]; symSet[ 1, 3] := [MINSym-48, MAXSym-48, SUMSym-48, AVGSym-48]; symSet[ 1, 4] := [TRUESym-64, FALSESym-64, CASESym-64, _minusSym-64]; symSet[ 1, 5] := [CHARACTER_underscoreLENGTHSym-80, CHAR_underscoreLENGTHSym-80, COALESCESym-80, CURRENT_underscoreDATESym-80, CURRENT_underscoreTIMESym-80, CURRENT_underscoreTIMESTAMPSym-80, CURRENT_underscoreUSERSym-80, USERSym-80, LOWERSym-80, UPPERSym-80, POSITIONSym-80, SESSION_underscoreUSERSym-80, SUBSTRINGSym-80, SYSTEM_underscoreUSERSym-80, TRIMSym-80]; symSet[ 1, 6] := [EXTRACTSym-96, NULLIFSym-96, ABSSym-96, CEILINGSym-96, FLOORSym-96, EXPSym-96, LOGSym-96]; symSet[ 1, 7] := [POWERSym-112, RANDSym-112, ROUNDSym-112, _querySym-112, DATESym-112, TIMESym-112, TIMESTAMPSym-112, INTERVALSym-112]; symSet[ 2, 0] := [identSym, integer_Sym, floatSym, SQLStringSym, SQLNameStringSym]; symSet[ 2, 1] := [_lparenSym-16]; symSet[ 2, 2] := [COUNTSym-32]; symSet[ 2, 3] := [MINSym-48, MAXSym-48, SUMSym-48, AVGSym-48, NOTSym-48, EXISTSSym-48, UNIQUESym-48]; symSet[ 2, 4] := [TRUESym-64, FALSESym-64, CASESym-64, _minusSym-64]; symSet[ 2, 5] := [CHARACTER_underscoreLENGTHSym-80, CHAR_underscoreLENGTHSym-80, COALESCESym-80, CURRENT_underscoreDATESym-80, CURRENT_underscoreTIMESym-80, CURRENT_underscoreTIMESTAMPSym-80, CURRENT_underscoreUSERSym-80, USERSym-80, LOWERSym-80, UPPERSym-80, POSITIONSym-80, SESSION_underscoreUSERSym-80, SUBSTRINGSym-80, SYSTEM_underscoreUSERSym-80, TRIMSym-80]; symSet[ 2, 6] := [EXTRACTSym-96, NULLIFSym-96, ABSSym-96, CEILINGSym-96, FLOORSym-96, EXPSym-96, LOGSym-96]; symSet[ 2, 7] := [POWERSym-112, RANDSym-112, ROUNDSym-112, _querySym-112, DATESym-112, TIMESym-112, TIMESTAMPSym-112, INTERVALSym-112]; symSet[ 3, 0] := []; symSet[ 3, 1] := []; symSet[ 3, 2] := [_equalSym-32]; symSet[ 3, 3] := [NOTSym-48, _less_equalSym-48, _lessSym-48, _greaterSym-48, _greater_equalSym-48, _less_greaterSym-48]; symSet[ 3, 4] := [ISSym-64, BETWEENSym-64, LIKESym-64, INSym-64, MATCHSym-64]; symSet[ 3, 5] := []; symSet[ 3, 6] := []; symSet[ 3, 7] := []; symSet[ 4, 0] := []; symSet[ 4, 1] := []; symSet[ 4, 2] := [_equalSym-32]; symSet[ 4, 3] := [NOTSym-48, _less_equalSym-48, _lessSym-48, _greaterSym-48, _greater_equalSym-48, _less_greaterSym-48]; symSet[ 4, 4] := [BETWEENSym-64, LIKESym-64, INSym-64, MATCHSym-64]; symSet[ 4, 5] := []; symSet[ 4, 6] := []; symSet[ 4, 7] := []; symSet[ 5, 0] := [identSym, integer_Sym, floatSym, SQLStringSym, SQLNameStringSym, ALLSym, DISTINCTSym]; symSet[ 5, 1] := [_lparenSym-16]; symSet[ 5, 2] := [COUNTSym-32]; symSet[ 5, 3] := [MINSym-48, MAXSym-48, SUMSym-48, AVGSym-48]; symSet[ 5, 4] := [TRUESym-64, FALSESym-64, CASESym-64, _minusSym-64]; symSet[ 5, 5] := [CHARACTER_underscoreLENGTHSym-80, CHAR_underscoreLENGTHSym-80, COALESCESym-80, CURRENT_underscoreDATESym-80, CURRENT_underscoreTIMESym-80, CURRENT_underscoreTIMESTAMPSym-80, CURRENT_underscoreUSERSym-80, USERSym-80, LOWERSym-80, UPPERSym-80, POSITIONSym-80, SESSION_underscoreUSERSym-80, SUBSTRINGSym-80, SYSTEM_underscoreUSERSym-80, TRIMSym-80]; symSet[ 5, 6] := [EXTRACTSym-96, NULLIFSym-96, ABSSym-96, CEILINGSym-96, FLOORSym-96, EXPSym-96, LOGSym-96]; symSet[ 5, 7] := [POWERSym-112, RANDSym-112, ROUNDSym-112, _querySym-112, DATESym-112, TIMESym-112, TIMESTAMPSym-112, INTERVALSym-112]; symSet[ 6, 0] := []; symSet[ 6, 1] := [JOINSym-16, NATURALSym-16, INNERSym-16, LEFTSym-16, RIGHTSym-16, FULLSym-16]; symSet[ 6, 2] := [UNIONSym-32]; symSet[ 6, 3] := []; symSet[ 6, 4] := []; symSet[ 6, 5] := []; symSet[ 6, 6] := []; symSet[ 6, 7] := []; symSet[ 7, 0] := []; symSet[ 7, 1] := [CROSSSym-16, JOINSym-16, NATURALSym-16, INNERSym-16, LEFTSym-16, RIGHTSym-16, FULLSym-16]; symSet[ 7, 2] := [UNIONSym-32]; symSet[ 7, 3] := []; symSet[ 7, 4] := []; symSet[ 7, 5] := []; symSet[ 7, 6] := []; symSet[ 7, 7] := []; end; {InitSymSet} end { FFSQL }.