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

📄 abssqlprocessor.pas

📁 Absolute Database 是来替代BDE[Borland数据库引擎]的用于Delphi 和 C++ Builder 开发用的数据库引擎. 它小巧, 高速, 健壮, 易于使用. 它能直接编译进
💻 PAS
📖 第 1 页 / 共 5 页
字号:

  // if expressions, then AOTable -> AOTableExpr?
  if (bGroupBy) or (Result is TABSAOTable) then
   begin
    bAnyExpressions := False;
    for i := 0 to SelectListCount-1 do
     if (SelectList[i].ValueExpr <> nil) then
      // 5.01 fix to support "select f1,f1 from table1"
      if (not TABSExpression(SelectList[i].ValueExpr).IsField) or SelectList[i].IsDuplicatedField then
        if (not TABSExpression(SelectList[i].ValueExpr).IsAggregated) then
         begin
          bAnyExpressions := True;
          break;
         end;
    // create table wrapper with expression-fields?
    if (bAnyExpressions) then
      begin
        if (bGroupBy) then
          begin
            bAnyExpressions := False;
            // check if group by expression, not only by fields
            for i := 0 to SelectListCount-1 do
             if (SelectList[i].ValueExpr <> nil) then
              if (not TABSExpression(SelectList[i].ValueExpr).IsField) then
                if (not TABSExpression(SelectList[i].ValueExpr).IsAggregated) then
                  begin
                    for j := 0 to GroupByFields.ItemCount-1 do
                      if (AnsiUpperCase(GroupByFields.Items[j].FieldName) =
                          AnsiUpperCase(SelectList[i].Pseudonym)) then
                        begin
                          bAnyExpressions := True;
                          break;
                        end;
                  end;
            if (bAnyExpressions) then
              begin
                Result := TABSAOTableExpr.Create(Result);
                Result.SetResultFields(SelectList,False);
              end;
          end
        else
          Result := TABSAOTableExpr.Create(Result);
      end;
   end;

  // apply parts of WHERE clause if possible
  if (SearchCondition <> nil) then
     SearchCondition.ApplyFilterParts(Result, ParentQueryAO, ParentCursor);

  // create GroupByAO, apply having condition
  if (bGroupBy) then
   begin
    try
     Result := TABSAOGroupBy.Create(Result, GroupByFields, SelectList);
     GroupByAO := Result;
    except
     // to avoid duplicated destroying
     Result := nil;
     for i := 0 to SelectListCount-1 do
      if (SelectList[i].ValueExpr <> nil) then
       begin
        SelectList[i].ValueExpr.Free;
        SelectList[i].ValueExpr := nil;
       end;
     raise;
    end;
   end;

  // prepare for setting projection
  if (Result.FHasSetResultFields) then
    Result := TABSAOTableExpr.Create(Result);

  bAddTempTableAO := (not RequestLive) and (Result is TABSAOTable) and (TopRowCount < 0);
  // sets projection
  Result.SetResultFields(SelectList,Distinct and (not bAddTempTableAO));

  if (bGroupBy) then
    begin
      // apply having
      if (HavingCondition <> nil) then
        begin
          // apply having with pseudonames
          HavingCondition.ApplyFilterParts(Result, ParentQueryAO, ParentCursor, false, true);
          // apply having w/o pseudonames
          HavingCondition.ApplyFilterParts(GroupByAO, ParentQueryAO, ParentCursor, true, true);
          if (not AllowNotAppliedConditions) then
            if (not HavingCondition.IsEmpty) then
               raise EABSException.Create(20244, ErorrANotApplicableHavingCondition);
        end;
    end;

  // sort - order by
  ApplyOrderBy(Result);

  // apply pseudonames parts of WHERE clause if possible
  if (SearchCondition <> nil) then
   begin
     SearchCondition.ApplyFilterParts(Result, ParentQueryAO, ParentCursor);
     if (not AllowNotAppliedConditions) then
       if (not SearchCondition.IsEmpty) then
         raise EABSException.Create(30144, ErorrGNotApplicableCondition);
   end;

  // TOP n?
  if (TopRowCount > -1) then
   begin
    Result := TABSAOSQLTopRowCount.Create(Result);
    Result.SetTopRowCount(FirstRowNo, TopRowCount);
   end;

  // if not request live => always use temp table
  if (bAddTempTableAO) then
    begin
      Result := TABSAOTableExpr.Create(Result);
      Result.SetResultFields(SelectList,Distinct and bAddTempTableAO);
    end;

 except
  if (Assigned(Result)) then
   Result.Free;
  raise;
 end;
end;//BuildAOTree


//------------------------------------------------------------------------------
// SELECT
//------------------------------------------------------------------------------
function TABSSQLSelect.ParseSelectToken: Boolean;
begin
  Result := IsReservedWord(Token, rwSELECT);
  if (not Result) then
   // unsupported SQL or unexpected token
   raise EABSException.Create(30156, ErrorGSQLCommandExpected,
         [Token.Text, Token.LineNum, Token.ColumnNum]);
  GetNextToken;
end;//ParseSelectToken


//------------------------------------------------------------------------------
// DISTINCT | ALL ?
//------------------------------------------------------------------------------
function TABSSQLSelect.ParseSetQuantifier: Boolean;
begin
 if (IsReservedWord(Token)) then
  begin
    if (IsReservedWord(Token, rwALL)) then
     begin
      Distinct := False;
      Result := True;
     end
    else
    if (IsReservedWord(Token, rwDISTINCT)) then
     begin
      Distinct := True;
      Result := True;
     end
    else // unrecognized reserved word - give up to handle
     begin
      Distinct := False; // default value
      Result := False; // handle this token by another handler
     end;
  end
 else // not reserved-word token give up handling
  begin
    Distinct := False; // default value
    Result := False; // handle this word by another handler
  end;

 // get next token
 if (Result) then
  GetNextToken;
end;// ParseSetQuantifier


//------------------------------------------------------------------------------
// TOP n ?
//------------------------------------------------------------------------------
function TABSSQLSelect.ParseTopOperator: Boolean;
begin
  if (IsReservedWord(Token, rwTOP)) then
   begin
    // suppose 'TOP n'
    GetNextToken;
    // integer?
    if (not (Token.TokenType in [tktInt,tktParameter]) ) then
     raise EABSException.Create(30158, ErrorGIntegerExpected,
                             [Token.Text, Token.LineNum, Token.ColumnNum]);
    if (Token.TokenType = tktInt) then
      TopRowCount := StrToInt(Token.Text)
    else
      TopRowCount := Token.ParamValue.AsInteger;
    // get next token
    GetNextToken;
    // default value
    FirstRowNo := -1;
    // ','? => TOP n, first_row
    if (Token.Text = ',') then
     begin
       // get next token
       GetNextToken;
       // integer?
       if (not (Token.TokenType in [tktInt,tktParameter]) ) then
         raise EABSException.Create(30159, ErrorGIntegerExpected,
                             [Token.Text, Token.LineNum, Token.ColumnNum]);
       if (Token.TokenType = tktInt) then
         FirstRowNo := StrToInt(Token.Text)
       else
         FirstRowNo := Token.ParamValue.AsInteger;
       // get next token
       GetNextToken;
     end;
    Result := True;
   end
  else // unrecognized reserved word - give up to handle
   begin
    TopRowCount := -1; // default value
    FirstRowNo := -1;
    Result := False; // handle this token by another handler
   end;
end;// ParseTopOperator


//------------------------------------------------------------------------------
// DuplicatedFieldExists
//------------------------------------------------------------------------------
function TABSSQLSelect.DuplicatedFieldExists(const TableName, FieldName: String): Boolean;
var
  i: Integer;
begin
  Result := False;
  for i:=0 to SelectListCount-1 do
    if (not SelectList[i].IsExpression) then
      if (AnsiUpperCase(SelectList[i].TableName) = AnsiUpperCase(TableName)) and
          (AnsiUpperCase(SelectList[i].FieldName) = AnsiUpperCase(FieldName)) then
        begin
          Result := True;
          break;
        end;
end;// DuplicatedFieldExists


//------------------------------------------------------------------------------
// FieldExists
//------------------------------------------------------------------------------
function TABSSQLSelect.FieldExists(const TableName, FieldName: String): Boolean;
var
  i: Integer;
begin
  Result := False;
  for i:=0 to SelectListCount-1 do
      if (AnsiUpperCase(SelectList[i].TableName) = AnsiUpperCase(TableName)) and
         ((AnsiUpperCase(SelectList[i].FieldName) = AnsiUpperCase(FieldName)) or
          (AnsiUpperCase(SelectList[i].Pseudonym) = AnsiUpperCase(FieldName)))then
        begin
          Result := True;
          break;
        end;
end;// FieldExists


//------------------------------------------------------------------------------
// GetFieldNameForDuplicatedField
//------------------------------------------------------------------------------
function TABSSQLSelect.GetFieldNameForDuplicatedField(const TableName, FieldName: String): String;
var
  i: Integer;
begin
  i := 0;
  repeat
    Inc(i);
    Result := Format('%s_%d',[FieldName,i]);
  until (not FieldExists(TableName, Result));
end;// GetFieldNameForDuplicatedField


//------------------------------------------------------------------------------
// <derived column>  | <qualifier> <period> <asterisk>
//------------------------------------------------------------------------------
function TABSSQLSelect.ParseSelectSubList: Boolean;
var
  FieldName, TableName, Pseudonym: string;
  AllFields: Boolean;
begin
 // handle field1 | table1.field1 | expr
  begin
   Result := True;

   // add new select list item
   inc(SelectListCount);
   SetLength(SelectList, SelectListCount);

   // parse field name | expr
   SelectList[SelectListCount-1].ValueExpr := TABSExpression.Create;

   TABSExpression(SelectList[SelectListCount-1].ValueExpr).InMemory :=
                                                     TABSQuery(LQuery).InMemory;

   TABSExpression(SelectList[SelectListCount-1].ValueExpr).ParseForValueExpression(
                                LQuery, LLex);

   if (TABSExpression(SelectList[SelectListCount-1].ValueExpr).IsEmpty) then
    begin
     SelectList[SelectListCount-1].ValueExpr.Free;
     SelectList[SelectListCount-1].ValueExpr := nil;
     raise EABSException.Create(30160, ErrorGExpressionExpected,
                             [Token.Text, Token.LineNum, Token.ColumnNum]);
    end;
   GetCurrentToken;

   // pseudonym is not specified yet
   Pseudonym := '';
   AllFields := False;
   // check pseudonym
   if (not AllFields) then
    // (Field1 AS F1) ?
          if (IsReservedWord(Token, rwAS)) then
           begin
             // get next token (F1?)
             GetNextToken([tktString, tktQuotedString, tktBracketedString],
                          30162, ErrorGFieldPseudonymExpected);
             // got pseudonym
             Pseudonym := Token.Text;
             // get next token
             GetNextToken;
            end
          else
          // (Field1 F1) ?
          if (Token.TokenType in
               [tktString, tktQuotedString, tktBracketedString]) then
            begin
             // got pseudonym
             Pseudonym := Token.Text;
             // look at next token
             GetNextToken;
            end;

   // expr or field?
   SelectList[SelectListCount-1].IsExpression :=
          not TABSExpression(SelectList[SelectListCount-1].ValueExpr).IsField;

   // field?
   if (not SelectList[SelectListCount-1].IsExpression) then
    begin
     // get field name, table name
     TABSExpression(SelectList[SelectListCount-1].ValueExpr).GetFieldInfo(TableName, FieldName);
     // treat duplicated field as expression
     if (FieldName = '*') or (not DuplicatedFieldExists(TableName, FieldName)) then
       begin
         // store TableName
         SelectList[SelectListCount-1].TableName := TableName;
         // store ValueExpr (FieldName)
         SelectList[SelectListCount-1].FieldName := FieldName;
         if (FieldName = '*') then
          AllFields := True;
         SelectList[SelectListCount-1].IsDuplicatedField := False;
       end
     else
       begin
         SelectList[SelectListCount-1].IsExpression :=True;
         SelectList[SelectListCount-1].IsDuplicatedField := True;
         if (Pseudonym = '') then
           Pseudonym := GetFieldNameForDuplicatedField(TableName, FieldName);
       end;
    end;

   // free non-expr objects (expr objects are freed by AO)
   if (not SelectList[SelectListCount-1].IsExpression) then
    begin
     TABSExpression(SelectList[SelectListCount-1].ValueExpr).Free;
     TABSExpression(SelectList[SelectListCount-1].ValueExpr) := nil;
    end;

   // store AllFields ('table1.*'?)
   SelectList[SelectListCount-1].AllFields := AllFields;
   // pseudonym
   SelectList[SelectListCount-1].Pseudonym := Pseudonym;
  end;
end;// ParseSelectSubList


//------------------------------------------------------------------------------
// * | <select sublist>
//------------------------------------------------------------------------------
function TABSSQLSelect.ParseSelectList: Boolean;
begin
  if (Token.Text =

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -