⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xqyacc.pas

📁 TxQuery is an SQL engine implemented in a TDataSet descendant component, that can parse SQL syntax,
💻 PAS
📖 第 1 页 / 共 4 页
字号:
     // 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 + -