📄 xqyacc.pas
字号:
// gis product
FTempJoinOnItem.GraphicJoin := False;
End;
End;
procedure TxqParser.AddJoinCandidate(const LeftExpr, RightExpr: String);
begin
CurrentAnalizer.LJoinCandidateList.Add( LeftExpr );
CurrentAnalizer.RJoinCandidateList.Add( RightExpr );
end;
procedure TxqParser.AddHavingColumn( const ColText : String );
var
Column: TColumnItem;
begin
Column := CurrentAnalizer.ColumnList.Add;
with Column do
begin
ColumnExpr := ColText;
if Assigned(Self.fAggregateList) then
begin
AggregateList.Free; { free previous aggregate list}
AggregateList := Self.fAggregateList; { assign the current list}
Self.fAggregateList:= nil; { define as nil the current }
end;
{ mark also as a temporary column that will be deleted after result set is
generated }
IsTemporaryCol := True;
end;
end;
procedure TxqParser.AddUpdateColumn(const ColumnName, ColumnExpr: String);
var
UpdateItem: TUpdateItem;
begin
UpdateItem := CurrentAnalizer.UpdateColumnList.Add;
with UpdateItem do
begin
ColName := ColumnName;
ColExpr := ColumnExpr;
end;
end;
procedure TxqParser.AddWhereOptimize( const AFieldName, ARangeStart,
ARangeEnd: String; ARelOperator: TRelationalOperator );
var
WhereOptimize : TWhereOptimizeItem;
N : Integer;
function DeleteStringDelim(const s: String): String;
begin
Result := s;
if Length(Result) > 1 then
begin
if (Result[1] in xqbase.SQuote) and (Result[Length(Result)] in xqbase.SQuote) then
Result:= Copy(Result, 2, Length(Result) - 2);
end;
end;
begin
if Not (yyLexer as TxqLexer).IsWhereActive then Exit;
N := CurrentAnalizer.WhereOptimizeList.Count - 1;
if ((ARelOperator in [ropLE, ropLT]) or (ARelOperator in [ropGE, ropGT]) ) and (N > 0) then
begin
{ I will check if the previous command was something like (CustNo >= 1000)
and if so, and this is something like (CustNo <= 3000) then
I will add to the previous optimize and will generate a ropBETWEEN range }
WhereOptimize:= CurrentAnalizer.WhereOptimizeList[N - 1];
if ( ((ARelOperator in [ropLE, ropLT]) and (WhereOptimize.RelOperator in [ropGE, ropGT])) or
((ARelOperator in [ropGE, ropGT]) and (WhereOptimize.RelOperator in [ropLE, ropLT])) ) and
(AnsiCompareText(WhereOptimize.FieldNames, AFieldName) = 0) then
begin
WhereOptimize.RangeEnd := DeleteStringDelim( ARangeEnd );
WhereOptimize.RelOperator := ropBETWEEN;
Exit;
end;
end;
WhereOptimize := CurrentAnalizer.WhereOptimizeList.Add;
with WhereOptimize do
begin
FieldNames := AFieldName;
RangeStart := DeleteStringDelim(ARangeStart);
RangeEnd := DeleteStringDelim(ARangeEnd);
RelOperator := ARelOperator;
CanOptimize := False;
end;
end;
{ ALTER TABLE }
function TxqParser.CurrentAlterTable: TCreateTableItem;
begin
if FNumTables > CurrentAnalizer.AlterTableList.Count - 1 then
Result := CurrentAnalizer.AlterTableList.Add
else
Result:= CurrentAnalizer.AlterTableList[ FNumTables ];
end;
{ CREATE TABLE }
function TxqParser.CurrentCreateTable: TCreateTableItem;
begin
if FNumTables > CurrentAnalizer.CreateTableList.Count - 1 then
Result := CurrentAnalizer.CreateTableList.Add
else
Result:= CurrentAnalizer.CreateTableList[ FNumTables ];
end;
procedure TxqParser.SetTableName(const TableName: String);
begin
CurrentCreateTable.TableName := TableName;
end;
procedure TxqParser.SetAlterTableName(const TableName: String);
begin
CurrentAlterTable.TableName := TableName;
end;
procedure TxqParser.SetFieldParams(AFieldType, AScale, APrecision, ASize, ABlobType: Integer);
begin
FFieldType := AFieldType;
FScale := AScale;
FPrecision := APrecision;
FSize := ASize;
FBlobType := ABlobType;
end;
procedure TxqParser.AddAlterField(const FieldName: String; DropField: Boolean);
var
I: Integer;
begin
{ check if field exists }
with CurrentAlterTable do
for I := 0 to FieldCount - 1 do
if (AnsiCompareText(Fields[I].FieldName, FieldName) = 0)
and (Fields[I].MustDrop=DropField) then
begin
yyerror(SDuplicateFieldName);
yyabort;
Exit;
end;
if (FFieldType = RW_BLOB) and not (FBlobType in [1..5]) then
begin
yyerror(SBlobFieldWrongType);
yyabort;
end;
CurrentAlterTable.Fields.AddField(FieldName, FFieldType, FScale, FPrecision,
FSize, FBlobType, DropField);
end;
procedure TxqParser.AddCreateField(const FieldName: String);
var
I: Integer;
begin
{ check if field exists }
with CurrentCreateTable do
for I := 0 to FieldCount - 1 do
if AnsiCompareText(Fields[I].FieldName, FieldName) = 0 then
begin
yyerror(SDuplicateFieldName);
yyabort;
Exit;
end;
if (FFieldType = RW_BLOB) and not (FBlobType in [1..5]) then
begin
yyerror(SBlobFieldWrongType);
yyabort;
end;
CurrentCreateTable.Fields.AddField(FieldName,FFieldType, FScale, FPrecision,
FSize, FBlobType, False);
end;
procedure TxqParser.AddPrimaryKeyField(const FieldName: String);
var
I : Integer;
Found : Boolean;
begin
{ check that the field exists in the list of field names }
Found := False;
with CurrentCreateTable do
for I := 0 to FieldCount - 1 do
if AnsiCompareText(Fields[I].FieldName, FieldName) = 0 then
begin
Found:= True;
Break;
end;
if Not Found then
begin
yyerror(SFieldNameNotFound);
yyabort;
end;
CurrentCreateTable.PrimaryKey.Add( FieldName );
end;
function TxqParser.CurrentInsertItem: TInsertItem;
begin
if fNumInserts >= CurrentAnalizer.InsertList.Count then
Result := CurrentAnalizer.InsertList.Add
else
Result := CurrentAnalizer.InsertList[fNumInserts];
end;
function TxqParser.CreateInListExpression( const Expr : String ) : String;
var
I : Integer;
begin
{ This subroutine helps to change the syntax:
custno IN (1000, 2000, 3000)
to this :
(custno = 1000) OR (custno = 2000) OR (custno = 3000) }
Result := '';
for i := 0 to fInPredicateList.Count - 1 do
begin
Result := Result + Format('(%s = %s)', [Expr, fInPredicateList[i]]);
if i < fInPredicateList.Count - 1 then
Result := Result + ' OR ';
end;
if fIsNotInList then
Result := 'NOT ( ' + Result + ' )'
else
Result := '( ' + Result + ' )';
fInPredicateList.Clear;
end;
// function yylex : Integer; forward; // addition 1
function TXQParser.yyparse : Integer; // addition 2
var yystate, yysp, yyn : SmallInt;
yys : array [1..yymaxdepth] of SmallInt;
yyv : array [1..yymaxdepth] of YYSType;
yyval : YYSType;
procedure yyaction ( yyruleno : Integer );
(* local definitions: *)
begin
(* actions: *)
case yyruleno of
1 : begin
fAnalizer.Statement := ssSelect;
end;
2 : begin
fAnalizer.Statement := ssSelect;
end;
3 : begin
fAnalizer.Statement := ssUnion;
end;
4 : begin
fAnalizer.Statement := ssUpdate;
end;
5 : begin
fAnalizer.Statement := ssDelete;
end;
6 : begin
fAnalizer.Statement := ssInsert;
end;
7 : begin
fAnalizer.Statement := ssCreateTable;
end;
8 : begin
fAnalizer.Statement := ssAlterTable;
end;
9 : begin
fAnalizer.Statement := ssCreateIndex;
end;
10 : begin
fAnalizer.Statement := ssDropTable;
end;
11 : begin
fAnalizer.Statement := ssDropIndex;
end;
12 : begin
fAnalizer.Statement := ssPacktable;
end;
13 : begin
fAnalizer.Statement := ssZapTable;
end;
14 : begin
fAnalizer.Statement := ssReindexTable;
end;
15 : begin
yyval := yyv[yysp-7];
end;
16 : begin
yyval := yyv[yysp-3];
end;
17 : begin
end;
18 : begin
CurrentAnalizer.IntoTable:= yyv[yysp-2].yystring;
end;
19 : begin
CurrentAnalizer.DoSelectAll := True;
CurrentAnalizer.AddFieldIfNot('*');
end;
20 : begin
yyval := yyv[yysp-1];
end;
21 : begin
yyval := yyv[yysp-2];
end;
22 : begin
CurrentAnalizer.IsDistinct:= True;
end;
23 : begin
end;
24 : begin
CurrentAnalizer.TopNInSelect:= StrToInt( yyv[yysp-0].yystring ) ;
end;
25 : begin
end;
26 : begin
CurrentAnalizer.TopNInGroupBy:= StrToInt( yyv[yysp-0].yystring ) ;
end;
27 : begin
yyval := yyv[yysp-0];
end;
28 : begin
yyval := yyv[yysp-2];
end;
29 : begin
addColumn( yyv[yysp-1].yystring, false );
end;
30 : begin
CurrentAnalizer.TableAllFields.Add( yyv[yysp-2].yystring );
CurrentAnalizer.AddFieldIfNot( yyv[yysp-2].yystring + '.*' );
end;
31 : begin
AddColumn( yyv[yysp-4].yystring, False );
end;
32 : begin
end;
33 : begin
fAsAlias:= yyv[yysp-0].yystring;
end;
34 : begin
end;
35 : begin
yyval := yyv[yysp-0];
end;
36 : begin
yyval := yyv[yysp-0];
end;
37 : begin
yyval := yyv[yysp-0];
end;
38 : begin
yyval := yyv[yysp-0];
end;
39 : begin
yyval := yyv[yysp-0];
end;
40 : begin
yyval := yyv[yysp-0];
end;
41 : begin
yyval := yyv[yysp-0];
end;
42 : begin
yyval := yyv[yysp-0];
end;
43 : begin
yyval.yystring := AddSubQueryInSelect;
end;
44 : begin
yyval.yystring := yyv[yysp-2].yystring + ' + ' + yyv[yysp-0].yystring;
end;
45 : begin
yyval.yystring := yyv[yysp-2].yystring + ' - ' + yyv[yysp-0].yystring;
end;
46 : begin
yyval.yystring := yyv[yysp-2].yystring + ' * ' + yyv[yysp-0].yystring;
end;
47 : begin
yyval.yystring := yyv[yysp-2].yystring + ' / ' + yyv[yysp-0].yystring;
end;
48 : begin
yyval.yystring := yyv[yysp-2].yystring + ' ^ ' + yyv[yysp-0].yystring;
end;
49 : begin
yyval.yystring := yyv[yysp-2].yystring + ' MOD ' + yyv[yysp-0].yystring;
end;
50 : begin
yyval.yystring := yyv[yysp-2].yystring + ' DIV ' + yyv[yysp-0].yystring;
end;
51 : begin
yyval.yystring := yyv[yysp-2].yystring + ' SHL ' + yyv[yysp-0].yystring;
end;
52 : begin
yyval.yystring := yyv[yysp-2].yystring + ' SHR ' + yyv[yysp-0].yystring;
end;
53 : begin
yyval.yystring := yyv[yysp-2].yystring + ' > ' + yyv[yysp-0].yystring;
end;
54 : begin
yyval.yystring := yyv[yysp-2].yystring + ' < ' + yyv[yysp-0].yystring;
end;
55 : begin
yyval.yystring := yyv[yysp-2].yystring + ' <> ' + yyv[yysp-0].yystring;
end;
56 : begin
yyval.yystring := yyv[yysp-2].yystring + ' >= ' + yyv[yysp-0].yystring;
end;
57 : begin
yyval.yystring := yyv[yysp-2].yystring + ' <= ' + yyv[yysp-0].yystring;
end;
58 : begin
yyval.yystring := yyv[yysp-2].yystring + ' = ' + yyv[yysp-0].yystring;
end;
59 : begin
yyval.yystring := yyv[yysp-2].yystring + ' AND ' + yyv[yysp-0].yystring;
end;
60 : begin
yyval.yystring := yyv[yysp-2].yystring + ' AND ' + yyv[yysp-0].yystring;
end;
61 : begin
yyval.yystring := yyv[yysp-1].yystring + yyv[yysp-0].yystring;
end;
62 : begin
yyval.yystring := yyv[yysp-1].yystring + yyv[yysp-0].yystring;
end;
63 : begin
yyval.yystring := yyv[yysp-2].yystring + yyv[yysp-1].yystring + yyv[yysp-0].yystring;
end;
64 : begin
yyval.yystring := AddAggregate(akSUM, yyv[yysp-1].yystring);
end;
65 : begin
yyval.yystring := AddAggregate(akMIN, yyv[yysp-1].yystring);
end;
66 : begin
yyval.yystring := AddAggregate(akMAX, yyv[yysp-1].yystring);
end;
67 : begin
yyval.yystring := AddAggregate(akAVG, yyv[yysp-1].yystring);
end;
68 : begin
yyval.yystring := AddAggregate(akSTDEV, yyv[yysp-1].yystring);
end;
69 : begin
yyval.yystring := AddAggregate(akCOUNT, '0');
end;
70 : begin
yyval.yystring := AddAggregate(akCOUNT, yyv[yysp-1].yystring);
end;
71 : begin
end;
72 : begin
Self.fIsDistinctAggr:= True;
end;
73 : begin
yyval.yystring := yyv[yysp-2].yystring + '()';
end;
74 : begin
yyval.yystring := yyv[yysp-3].yystring + yyv[yysp-2].yystring + yyv[yysp-1].yystring + yyv[yysp-0].yystring;
end;
75 : begin
yyval := yyv[yysp-0];
end;
76 : begin
yyval := yyv[yysp-0];
end;
77 : begin
yyval := yyv[yysp-0];
end;
78 : begin
yyval.yystring:= yyv[yysp-2].yystring + ', ' + yyv[yysp-0].yystring;
end;
79 : begin
yyval.yystring := Format('SQLTRIM(%s, %s, %d)',[yyv[yysp-3].yystring, yyv[yysp-1].yystring, fTrimPosition]);
end;
80 : begin
fTrimPosition := 0;
end;
81 : begin
fTrimPosition := 1;
end;
82 : begin
fTrimPosition := 2;
end;
83 : begin
case fExtractField of
0: yyval.yystring := Format('YEAR(%s)', [yyv[yysp-1].yystring]);
1: yyval.yystring := Format('MONTH(%s)', [yyv[yysp-1].yystring]);
2: yyval.yystring := Format('DAY(%s)', [yyv[yysp-1].yystring]);
3: yyval.yystring := Format('HOUR(%s)', [yyv[yysp-1].yystring]);
4: yyval.yystring := Format('MIN(%s)', [yyv[yysp-1].yystring]);
5: yyval.yystring := Format('SEC(%s)', [yyv[yysp-1].yystring]);
end;
end;
84 : begin
fExtractField:= 0;
end;
85 : begin
fExtractField:= 1;
end;
86 : begin
fExtractField:= 2;
end;
87 : begin
fExtractField:= 3;
end;
88 : begin
fExtractField:= 4;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -