* fcl-db: sql parser: support table.column notation for fields like

- SELECT A.B FROM A
- SELECT B FROM A ORDER BY C.D
- tests
Note: failing test due to needed implementation of parsing table.field into table and field references

git-svn-id: trunk@27912 -
This commit is contained in:
reiniero 2014-06-09 12:34:52 +00:00
parent a99919a4bc
commit c63b31c839
5 changed files with 58 additions and 19 deletions

View File

@ -511,6 +511,7 @@ procedure TSQLParser.ParseOrderBy(AParent: TSQLSelectStatement;
Var Var
O : TSQLOrderByElement; O : TSQLOrderByElement;
F : TSQLElement; F : TSQLElement;
BuildToken : string;
begin begin
// On entry we're on the ORDER token. // On entry we're on the ORDER token.
@ -518,10 +519,21 @@ begin
Expect(tsqlBy); Expect(tsqlBy);
Repeat Repeat
GetNextToken; GetNextToken;
// Deal with table.column notation:
Case CurrentToken of Case CurrentToken of
tsqlIdentifier : tsqlIdentifier :
F:=CreateIdentifier(AParent,CurrentTokenString); begin
tsqlIntegerNumber : BuildToken:=CurrentTokenString;
If (PeekNextToken=tsqlDot) then
begin
GetNextToken; //past tsqlDot
GetNextToken;
Expect(tsqlIdentifier);
BuildToken:=BuildToken+'.'+CurrentTokenString;
end;
F:=CreateIdentifier(AParent,BuildToken);
end;
tsqlIntegerNumber : //e.g. ORDER BY 1
begin begin
F:=TSQLIntegerLiteral(CreateElement(TSQLIntegerLiteral,AParent)); F:=TSQLIntegerLiteral(CreateElement(TSQLIntegerLiteral,AParent));
TSQLIntegerLiteral(F).Value:=StrToInt(CurrentTokenString); TSQLIntegerLiteral(F).Value:=StrToInt(CurrentTokenString);
@ -2077,7 +2089,7 @@ begin
tsqlNull : tsqlNull :
Result:=TSQLLiteral(CreateElement(TSQLNullLiteral,AParent)); Result:=TSQLLiteral(CreateElement(TSQLNullLiteral,AParent));
tsqlValue : tsqlValue :
Result:=TSQLLiteral(CreateElement(TSQLValueLiteral,AParent)); Result:=TSQLLiteral(CreateElement(TSQLValueLiteral,AParent));
tsqlUSER : tsqlUSER :
Result:=TSQLLiteral(CreateElement(TSQLUserLiteral,AParent)); Result:=TSQLLiteral(CreateElement(TSQLUserLiteral,AParent));
else else
@ -2219,7 +2231,7 @@ begin
if (CurrentToken=tsqlNot) then if (CurrentToken=tsqlNot) then
begin begin
GetNextToken; GetNextToken;
if not (tt=tsqlis) then if not (tt=tsqlIS) then
UnexpectedToken; UnexpectedToken;
Inverted:=true; Inverted:=true;
end; end;

View File

@ -40,7 +40,7 @@ type
tsqlEOF,tsqlWhiteSpace, tsqlEOF,tsqlWhiteSpace,
tsqlString {string literal}, tsqlString {string literal},
tsqlIdentifier {a table etc name}, tsqlIdentifier {a table etc name},
tsqlSymbolLiteral {a literal containing symbols/punctuation marks}, tsqlSymbolLiteral {a literal containing symbols/punctuation marks; only rarely used - e.g. in SET TERM ^ ;},
tsqlIntegerNumber,tsqlFloatNumber,tsqlComment, tsqlIntegerNumber,tsqlFloatNumber,tsqlComment,
tsqlStatementTerminator {statement separator, usually semicolon but may be changed by code. For now, limited to semicolon and symbol literals not already defined like tsqlCOMMA}, tsqlStatementTerminator {statement separator, usually semicolon but may be changed by code. For now, limited to semicolon and symbol literals not already defined like tsqlCOMMA},
tsqlBraceOpen,tsqlBraceClose,tsqlSquareBraceOpen,tsqlSquareBraceClose, tsqlBraceOpen,tsqlBraceClose,tsqlSquareBraceOpen,tsqlSquareBraceClose,

View File

@ -150,6 +150,7 @@ Type
Property Value : TSQLStringType Read FValue Write FValue; Property Value : TSQLStringType Read FValue Write FValue;
end; end;
{ TSQLIdentifierElement } { TSQLIdentifierElement }
TSQLIdentifierName = Class(TSQLElement) TSQLIdentifierName = Class(TSQLElement)
@ -585,13 +586,13 @@ Type
TSQLSelectField = Class(TSQLSelectElement) TSQLSelectField = Class(TSQLSelectElement)
private private
FAliasName: TSQLIDentifierName; FAliasName: TSQLIdentifierName;
FExpression: TSQLExpression; FExpression: TSQLExpression;
Public Public
Destructor Destroy; override; Destructor Destroy; override;
Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override; Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override;
Property Expression : TSQLExpression Read FExpression Write FExpression; Property Expression : TSQLExpression Read FExpression Write FExpression;
Property AliasName : TSQLIDentifierName Read FAliasName Write FAliasName; Property AliasName : TSQLIdentifierName Read FAliasName Write FAliasName;
end; end;
{ TSQLTableReference } { TSQLTableReference }
@ -602,7 +603,7 @@ Type
TSQLSimpleTableReference = Class(TSQLTableReference) TSQLSimpleTableReference = Class(TSQLTableReference)
private private
FAliasName: TSQLIDentifierName; FAliasName: TSQLIdentifierName;
FObjectName: TSQLIdentifierName; FObjectName: TSQLIdentifierName;
FParams: TSQLElementList; FParams: TSQLElementList;
Public Public
@ -610,7 +611,7 @@ Type
Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override; Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override;
Property ObjectName : TSQLIdentifierName Read FObjectName Write FObjectName; Property ObjectName : TSQLIdentifierName Read FObjectName Write FObjectName;
Property Params : TSQLElementList Read FParams Write FParams; Property Params : TSQLElementList Read FParams Write FParams;
Property AliasName : TSQLIDentifierName Read FAliasName Write FAliasName; Property AliasName : TSQLIdentifierName Read FAliasName Write FAliasName;
end; end;
{ TSQLJoinTableReference } { TSQLJoinTableReference }
@ -722,7 +723,7 @@ Type
FPlan: TSQLSelectPlan; FPlan: TSQLSelectPlan;
FStartAt: TSQLExpression; FStartAt: TSQLExpression;
FTables: TSQLElementList; FTables: TSQLElementList;
FTN: TSQLidentifierName; FTN: TSQLIdentifierName;
FUnion: TSQLSelectStatement; FUnion: TSQLSelectStatement;
FUnionAll: Boolean; FUnionAll: Boolean;
FWhere: TSQLExpression; FWhere: TSQLExpression;
@ -730,7 +731,7 @@ Type
Constructor Create(AParent : TSQLElement); override; Constructor Create(AParent : TSQLElement); override;
Destructor Destroy; override; Destructor Destroy; override;
Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override; Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override;
Property TransactionName : TSQLidentifierName Read FTN Write FTN; Property TransactionName : TSQLIdentifierName Read FTN Write FTN;
Property Tables : TSQLElementList Read FTables; Property Tables : TSQLElementList Read FTables;
Property Fields : TSQLElementList Read FFields; Property Fields : TSQLElementList Read FFields;
Property Where : TSQLExpression read FWhere write FWhere; Property Where : TSQLExpression read FWhere write FWhere;
@ -779,12 +780,12 @@ Type
TSQLUpdatePair = Class(TSQLElement) TSQLUpdatePair = Class(TSQLElement)
private private
FFieldName: TSQLidentifierName; FFieldName: TSQLIdentifierName;
FValue: TSQLExpression; FValue: TSQLExpression;
Public Public
Destructor Destroy; override; Destructor Destroy; override;
Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override; Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override;
Property FieldName : TSQLidentifierName Read FFieldName Write FFieldName; Property FieldName : TSQLIdentifierName Read FFieldName Write FFieldName;
Property Value : TSQLExpression Read FValue Write FValue; Property Value : TSQLExpression Read FValue Write FValue;
end; end;

View File

@ -1,6 +1,6 @@
{ {
This file is part of the Free Component Library This file is part of the Free Component Library
Copyright (c) 2010 by the Free Pascal development team Copyright (c) 2010-2014 by the Free Pascal development team
SQL Syntax Tree SQL generation tests SQL Syntax Tree SQL generation tests
@ -31,11 +31,11 @@ type
Private Private
FToFree:TSQLElement; FToFree:TSQLElement;
protected protected
procedure SetUp; override; Procedure SetUp; override;
procedure TearDown; override; Procedure TearDown; override;
procedure DoTestDropStatement(AClass: TSQLDropStatementClass; const AObjectName: String); Procedure DoTestDropStatement(AClass: TSQLDropStatementClass; const AObjectName: String);
procedure DoTestAlterCreateProcedure(S: TSQLAlterCreateProcedureStatement; PHEAD: String); Procedure DoTestAlterCreateProcedure(S: TSQLAlterCreateProcedureStatement; PHEAD: String);
procedure DoTestAlterCreateTrigger(S: TSQLAlterCreateTriggerStatement; PHEAD: String); Procedure DoTestAlterCreateTrigger(S: TSQLAlterCreateTriggerStatement; PHEAD: String);
Function CreateIdentifier(Const AName : TSQLStringType) : TSQLIdentifierName; Function CreateIdentifier(Const AName : TSQLStringType) : TSQLIdentifierName;
Function CreateGrantee(Const AName : TSQLStringType; AClass : TSQLGranteeClass = Nil) : TSQLGrantee; Function CreateGrantee(Const AName : TSQLStringType; AClass : TSQLGranteeClass = Nil) : TSQLGrantee;
Function CreateLiteral(Const AValue : Integer) : TSQLIntegerLiteral; Function CreateLiteral(Const AValue : Integer) : TSQLIntegerLiteral;

View File

@ -378,6 +378,7 @@ type
procedure TestSelectTwoFieldsOneTable; procedure TestSelectTwoFieldsOneTable;
procedure TestSelectOneFieldAliasOneTable; procedure TestSelectOneFieldAliasOneTable;
procedure TestSelectTwoFieldAliasesOneTable; procedure TestSelectTwoFieldAliasesOneTable;
procedure TestSelectOneTableFieldOneTable;
procedure TestSelectOneDistinctFieldOneTable; procedure TestSelectOneDistinctFieldOneTable;
procedure TestSelectOneAllFieldOneTable; procedure TestSelectOneAllFieldOneTable;
procedure TestSelectAsteriskOneTable; procedure TestSelectAsteriskOneTable;
@ -427,6 +428,7 @@ type
procedure TestOrderByOneDescField; procedure TestOrderByOneDescField;
procedure TestOrderByTwoDescFields; procedure TestOrderByTwoDescFields;
procedure TestOrderByThreeDescFields; procedure TestOrderByThreeDescFields;
procedure TestOrderByOneTableField;
procedure TestOrderByOneColumn; procedure TestOrderByOneColumn;
procedure TestOrderByTwoColumns; procedure TestOrderByTwoColumns;
procedure TestOrderByTwoColumnsDesc; procedure TestOrderByTwoColumnsDesc;
@ -3755,6 +3757,16 @@ begin
AssertTable(Select.Tables[0],'A'); AssertTable(Select.Tables[0],'A');
end; end;
procedure TTestSelectParser.TestSelectOneTableFieldOneTable;
begin
TestSelect('SELECT A.B FROM A');
AssertEquals('One field',1,Select.Fields.Count);
AssertField(Select.Fields[0],'B');
AssertEquals('One table',1,Select.Tables.Count);
AssertTable(Select.Tables[0],'A');
end;
procedure TTestSelectParser.TestSelectOneDistinctFieldOneTable; procedure TTestSelectParser.TestSelectOneDistinctFieldOneTable;
begin begin
TestSelect('SELECT DISTINCT B FROM A'); TestSelect('SELECT DISTINCT B FROM A');
@ -4274,6 +4286,7 @@ begin
AssertOrderBy(Select.OrderBy[1],'D',0,obAscending); AssertOrderBy(Select.OrderBy[1],'D',0,obAscending);
AssertOrderBy(Select.OrderBy[2],'E',0,obAscending); AssertOrderBy(Select.OrderBy[2],'E',0,obAscending);
end; end;
procedure TTestSelectParser.TestOrderByOneDescField; procedure TTestSelectParser.TestOrderByOneDescField;
begin begin
@ -4312,6 +4325,19 @@ begin
AssertOrderBy(Select.OrderBy[2],'E',0,obDescending); AssertOrderBy(Select.OrderBy[2],'E',0,obDescending);
end; end;
procedure TTestSelectParser.TestOrderByOneTableField;
begin
TestSelect('SELECT B FROM A ORDER BY C.D');
AssertEquals('One field',1,Select.Fields.Count);
AssertEquals('One table',1,Select.Tables.Count);
AssertField(Select.Fields[0],'B');
AssertTable(Select.Tables[0],'A');
AssertEquals('One order by field',1,Select.Orderby.Count);
AssertOrderBy(Select.OrderBy[0],'C',0,obAscending);
end;
procedure TTestSelectParser.TestOrderByOneColumn; procedure TTestSelectParser.TestOrderByOneColumn;
begin begin
TestSelect('SELECT B FROM A ORDER BY 1'); TestSelect('SELECT B FROM A ORDER BY 1');