mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-15 14:19:28 +02:00
* 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:
parent
a99919a4bc
commit
c63b31c839
@ -511,6 +511,7 @@ procedure TSQLParser.ParseOrderBy(AParent: TSQLSelectStatement;
|
||||
Var
|
||||
O : TSQLOrderByElement;
|
||||
F : TSQLElement;
|
||||
BuildToken : string;
|
||||
|
||||
begin
|
||||
// On entry we're on the ORDER token.
|
||||
@ -518,10 +519,21 @@ begin
|
||||
Expect(tsqlBy);
|
||||
Repeat
|
||||
GetNextToken;
|
||||
// Deal with table.column notation:
|
||||
Case CurrentToken of
|
||||
tsqlIdentifier :
|
||||
F:=CreateIdentifier(AParent,CurrentTokenString);
|
||||
tsqlIntegerNumber :
|
||||
begin
|
||||
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
|
||||
F:=TSQLIntegerLiteral(CreateElement(TSQLIntegerLiteral,AParent));
|
||||
TSQLIntegerLiteral(F).Value:=StrToInt(CurrentTokenString);
|
||||
@ -2077,7 +2089,7 @@ begin
|
||||
tsqlNull :
|
||||
Result:=TSQLLiteral(CreateElement(TSQLNullLiteral,AParent));
|
||||
tsqlValue :
|
||||
Result:=TSQLLiteral(CreateElement(TSQLValueLiteral,AParent));
|
||||
Result:=TSQLLiteral(CreateElement(TSQLValueLiteral,AParent));
|
||||
tsqlUSER :
|
||||
Result:=TSQLLiteral(CreateElement(TSQLUserLiteral,AParent));
|
||||
else
|
||||
@ -2219,7 +2231,7 @@ begin
|
||||
if (CurrentToken=tsqlNot) then
|
||||
begin
|
||||
GetNextToken;
|
||||
if not (tt=tsqlis) then
|
||||
if not (tt=tsqlIS) then
|
||||
UnexpectedToken;
|
||||
Inverted:=true;
|
||||
end;
|
||||
|
@ -40,7 +40,7 @@ type
|
||||
tsqlEOF,tsqlWhiteSpace,
|
||||
tsqlString {string literal},
|
||||
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,
|
||||
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,
|
||||
|
@ -150,6 +150,7 @@ Type
|
||||
Property Value : TSQLStringType Read FValue Write FValue;
|
||||
end;
|
||||
|
||||
|
||||
{ TSQLIdentifierElement }
|
||||
|
||||
TSQLIdentifierName = Class(TSQLElement)
|
||||
@ -585,13 +586,13 @@ Type
|
||||
|
||||
TSQLSelectField = Class(TSQLSelectElement)
|
||||
private
|
||||
FAliasName: TSQLIDentifierName;
|
||||
FAliasName: TSQLIdentifierName;
|
||||
FExpression: TSQLExpression;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override;
|
||||
Property Expression : TSQLExpression Read FExpression Write FExpression;
|
||||
Property AliasName : TSQLIDentifierName Read FAliasName Write FAliasName;
|
||||
Property AliasName : TSQLIdentifierName Read FAliasName Write FAliasName;
|
||||
end;
|
||||
|
||||
{ TSQLTableReference }
|
||||
@ -602,7 +603,7 @@ Type
|
||||
|
||||
TSQLSimpleTableReference = Class(TSQLTableReference)
|
||||
private
|
||||
FAliasName: TSQLIDentifierName;
|
||||
FAliasName: TSQLIdentifierName;
|
||||
FObjectName: TSQLIdentifierName;
|
||||
FParams: TSQLElementList;
|
||||
Public
|
||||
@ -610,7 +611,7 @@ Type
|
||||
Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override;
|
||||
Property ObjectName : TSQLIdentifierName Read FObjectName Write FObjectName;
|
||||
Property Params : TSQLElementList Read FParams Write FParams;
|
||||
Property AliasName : TSQLIDentifierName Read FAliasName Write FAliasName;
|
||||
Property AliasName : TSQLIdentifierName Read FAliasName Write FAliasName;
|
||||
end;
|
||||
|
||||
{ TSQLJoinTableReference }
|
||||
@ -722,7 +723,7 @@ Type
|
||||
FPlan: TSQLSelectPlan;
|
||||
FStartAt: TSQLExpression;
|
||||
FTables: TSQLElementList;
|
||||
FTN: TSQLidentifierName;
|
||||
FTN: TSQLIdentifierName;
|
||||
FUnion: TSQLSelectStatement;
|
||||
FUnionAll: Boolean;
|
||||
FWhere: TSQLExpression;
|
||||
@ -730,7 +731,7 @@ Type
|
||||
Constructor Create(AParent : TSQLElement); override;
|
||||
Destructor Destroy; 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 Fields : TSQLElementList Read FFields;
|
||||
Property Where : TSQLExpression read FWhere write FWhere;
|
||||
@ -779,12 +780,12 @@ Type
|
||||
|
||||
TSQLUpdatePair = Class(TSQLElement)
|
||||
private
|
||||
FFieldName: TSQLidentifierName;
|
||||
FFieldName: TSQLIdentifierName;
|
||||
FValue: TSQLExpression;
|
||||
Public
|
||||
Destructor Destroy; 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;
|
||||
end;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
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
|
||||
|
||||
@ -31,11 +31,11 @@ type
|
||||
Private
|
||||
FToFree:TSQLElement;
|
||||
protected
|
||||
procedure SetUp; override;
|
||||
procedure TearDown; override;
|
||||
procedure DoTestDropStatement(AClass: TSQLDropStatementClass; const AObjectName: String);
|
||||
procedure DoTestAlterCreateProcedure(S: TSQLAlterCreateProcedureStatement; PHEAD: String);
|
||||
procedure DoTestAlterCreateTrigger(S: TSQLAlterCreateTriggerStatement; PHEAD: String);
|
||||
Procedure SetUp; override;
|
||||
Procedure TearDown; override;
|
||||
Procedure DoTestDropStatement(AClass: TSQLDropStatementClass; const AObjectName: String);
|
||||
Procedure DoTestAlterCreateProcedure(S: TSQLAlterCreateProcedureStatement; PHEAD: String);
|
||||
Procedure DoTestAlterCreateTrigger(S: TSQLAlterCreateTriggerStatement; PHEAD: String);
|
||||
Function CreateIdentifier(Const AName : TSQLStringType) : TSQLIdentifierName;
|
||||
Function CreateGrantee(Const AName : TSQLStringType; AClass : TSQLGranteeClass = Nil) : TSQLGrantee;
|
||||
Function CreateLiteral(Const AValue : Integer) : TSQLIntegerLiteral;
|
||||
|
@ -378,6 +378,7 @@ type
|
||||
procedure TestSelectTwoFieldsOneTable;
|
||||
procedure TestSelectOneFieldAliasOneTable;
|
||||
procedure TestSelectTwoFieldAliasesOneTable;
|
||||
procedure TestSelectOneTableFieldOneTable;
|
||||
procedure TestSelectOneDistinctFieldOneTable;
|
||||
procedure TestSelectOneAllFieldOneTable;
|
||||
procedure TestSelectAsteriskOneTable;
|
||||
@ -427,6 +428,7 @@ type
|
||||
procedure TestOrderByOneDescField;
|
||||
procedure TestOrderByTwoDescFields;
|
||||
procedure TestOrderByThreeDescFields;
|
||||
procedure TestOrderByOneTableField;
|
||||
procedure TestOrderByOneColumn;
|
||||
procedure TestOrderByTwoColumns;
|
||||
procedure TestOrderByTwoColumnsDesc;
|
||||
@ -3755,6 +3757,16 @@ begin
|
||||
AssertTable(Select.Tables[0],'A');
|
||||
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;
|
||||
begin
|
||||
TestSelect('SELECT DISTINCT B FROM A');
|
||||
@ -4274,6 +4286,7 @@ begin
|
||||
AssertOrderBy(Select.OrderBy[1],'D',0,obAscending);
|
||||
AssertOrderBy(Select.OrderBy[2],'E',0,obAscending);
|
||||
end;
|
||||
|
||||
procedure TTestSelectParser.TestOrderByOneDescField;
|
||||
|
||||
begin
|
||||
@ -4312,6 +4325,19 @@ begin
|
||||
AssertOrderBy(Select.OrderBy[2],'E',0,obDescending);
|
||||
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;
|
||||
begin
|
||||
TestSelect('SELECT B FROM A ORDER BY 1');
|
||||
|
Loading…
Reference in New Issue
Block a user