You've already forked lazarus-ccr
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5438 8e941d3f-bd1b-0410-a28a-d453659cc2b4
3579 lines
98 KiB
ObjectPascal
3579 lines
98 KiB
ObjectPascal
{$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 }.
|