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

📄 absexpressions.pas

📁 Absolute Database 是来替代BDE[Borland数据库引擎]的用于Delphi 和 C++ Builder 开发用的数据库引擎. 它小巧, 高速, 健壮, 易于使用. 它能直接编译进
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    // return Size of Data (for strings and arrays)
    function GetPrecision: Integer;
    // is expression contains no nodes
    function IsEmpty: Boolean;
    // is expression a Field (for join)
    function IsField: Boolean;
    // is expression a fields combination
    function IsFieldsExpression: Boolean;
    // Move AndNodes To RootNode
    procedure MoveAndNodesToRoot;
    // Field Name, Table Name
    procedure GetFieldInfo(var TableName: String; var FieldName: String);
    // makes filter string from related parts and sets it to AO
    procedure ApplyFilterParts(AO: TABSAO; ParentQueryAO: TABSAO;
                ParentCursor: TABSCursor;
                AllowRecurse: Boolean = True; ForHavingClause: Boolean = False);
    // replace pseudonyms to original names (f1 -> table1.field1)
    procedure ReplacePseudonyms(SelectList: array of TABSSelectListItem);
    // makes join field lists
    function ExtractJoinConditions(
                                    AO1, AO2: TABSAO;
                                    FieldList1, FieldList2: TABSFields
                                  ): Integer;
    // create conditions for index scan
    procedure TryCreateIndexScanConditionsFromNode(
                             Node:           TABSExprNode;
                             IndexDefs:      TABSIndexDefs;
                             ScanConditions: TABSScanSearchConditionArray;
                             SessionID: TABSSessionID);
    // remove extracted nodes (they included in list, but list contains more)
    procedure RemoveExtractedNodes(ScanConditions: TABSScanSearchConditionArray;
                                   ScanConditionNo, ScanEndConditionNo: Integer);
    // create conditions for index scan
    procedure CreateIndexScanConditions(
                             IndexDefs:               TABSIndexDefs;
                             ScanConditions:          TABSScanSearchConditionArray;
                             SessionID:               TABSSessionID);
    // try to add conditions on another index fields
    function ExtendMultiFieldIndexConditionFromNode(Node: TABSExprNode;
       ScanCondition: TABSScanSearchCondition; IndexDef: TABSIndexDef): Boolean;
    // try to add conditions on another index fields
    function ExtendMultiFieldIndexCondition(ScanCondition: TABSScanSearchCondition;
                                            IndexDef: TABSIndexDef): Boolean;
    // add extracted node
    procedure AddNode(Node: TABSExprNode);
    // add and move nodes from another expression: self => (self AND Expr2)
    procedure AddAndMoveNodesFromExpression(Expr: TABSExpression);
    // check if agregate expr, const or only grouped fields are used
    function CanBeUsedInGroupBy(GroupByFields: String): Boolean;
   public
    property InMemory: Boolean read FInMemory write FInMemory;
  end;




  TABSExprNode = class(TObject)
   private
    Children: TList;                  // Children nodes
    Operator: TABSDataOperator;      // '<',  '>', AND, NOT, ...
    Value:  TABSVariant;
    FCaseInsensitive: boolean;
    FPartialKey: boolean;
   private
    // converts some WideStrings to Strings
    procedure PatchWideStrings; virtual;
   public
    // constructors
    constructor Create(
                       CaseInsensitive: boolean = true;
                       PartialKey: boolean = false
                      ); overload;
    constructor Create(
                       Op: TABSDataOperator;
                       CaseInsensitive: boolean = true;
                       PartialKey: boolean = false
                      ); overload;
    constructor Create(
                       Op: TABSDataOperator;
                       Node: TABSExprNode;
                       CaseInsensitive: boolean = true;
                       PartialKey: boolean = false
                      ); overload;
    constructor Create(
                       Op: TABSDataOperator;
                       Node1, Node2: TABSExprNode;
                       CaseInsensitive: boolean = true;
                       PartialKey: boolean = false
                       ); overload;
    constructor Create(
                       Op: TABSDataOperator;
                       Node1, Node2, Node3: TABSExprNode;
                       CaseInsensitive: boolean = true;
                       PartialKey: boolean = false
                       ); overload;
    // destroys
    destructor Destroy; override;
    // return Value
    function GetDataValue: TABSVariant;  virtual; abstract;
    // calc subquery field values again
    procedure ResetSubqueryFieldValues; virtual;
    // Return subquery field value
    function GetSubqueryFieldValue(FieldNo: Integer): TABSVariant; virtual;
    // is expression contains aggregated function
    function IsAggregated: Boolean; virtual;
    function IsAggregatedCountAll: Boolean; virtual;
    // Init for group function
    procedure Init; virtual;
    // Accumulate for group functions
    procedure Accumulate; virtual;
    procedure SetCountAll(RecordCount: Integer); virtual;

    // process assign AO
    procedure AssignAO(AO, ParentQueryAO: TABSAO; ParentCursor: TABSCursor); virtual;
    // process assign Cursor
    procedure AssignCursor(Cursor: TABSCursor; ParentQueryAO: TABSAO; ParentCursor: TABSCursor); virtual;
    // process assign New Cursor Buffer
    procedure AssignCursorBuffer(Buffer: TABSRecordBuffer; ApplyToParentQueryFields: Boolean); virtual;

    // return Type of Data
    function GetDataType: TABSAdvancedFieldType; virtual;
    // return Size of Data (for strings and arrays)
    function GetDataSize: Integer; virtual;
    // return Data Precision
    function GetPrecision: Integer; virtual;

    // can be used by the AO?
    function CanBeAssigned(AO, ParentQueryAO: TABSAO; ParentCursor: TABSCursor; ForHavingClause: Boolean = False): Boolean; virtual;

    // node is field?
    function CanUseNodeAsField(Node: TABSExprNode): Boolean;
    // node is const or correlated field fomr parent query?
    function CanUseNodeAsConst(Node: TABSExprNode): Boolean;
    // can use index for comparison?
    function CanUseIndex(IndexColumnNo: Integer; ConditionSearchOperator: TABSSearchCondition; IndexDef: TABSIndexDef; SessionID: TABSSessionID = INVALID_SESSION_ID): Boolean; virtual;
  private
    // fill scan condition props
    procedure FillScanCondition(Value:         TABSVariant;
                                Cursor:        TABSCursor;
                                IndexColumnNo: Integer;
                                FieldNo:       Integer;
                                IndexDef:      TABSIndexDef;
                                Expression:    TABSExpression;
                                ScanCondition: TABSScanSearchCondition);

  public
    // add index scan condition
    procedure AddAsIndexScanCondition(
                   ScanConditions: TABSScanSearchConditionArray;
                   IndexDef:       TABSIndexDef;
                   Expression:  TABSExpression); virtual;
    // add checks to multi-field index scan condition
    procedure ExtendIndexScanCondition(
                   ScanCondition: TABSScanSearchCondition;
                   IndexDef:      TABSIndexDef;
                   Expression:    TABSExpression); virtual;

    // is node a join condition?
    function IsJoinCondition(AO1, AO2: TABSAO): Boolean; virtual;

    // replace pseudonyms to original names (f1 -> table1.field1)
    procedure ReplacePseudonyms(SelectList: array of TABSSelectListItem); virtual;

    // check if agregate expr, const or only grouped fields are used
    function CanBeUsedInGroupBy(GroupByFields: String): Boolean; virtual;
  end;

  TABSExprNodeConst = class(TABSExprNode)
   public
    // return Value
    function GetDataValue: TABSVariant; override;
    // return Type of Data
    function GetDataType: TABSAdvancedFieldType; override;
    // return Size of Data (for strings and arrays)
    function GetDataSize: Integer; override;

    function IsLikePatternEqualToPartialComparePattern: Boolean;
    procedure TruncateForPartialCompare;

    // can be used by the AO?
    function CanBeAssigned(AO, ParentQueryAO: TABSAO; ParentCursor: TABSCursor; ForHavingClause: Boolean = False): Boolean; override;
    function IsUpperCase: Boolean;
    function IsLowerCase: Boolean;
  end;


  TABSExprNodeField = class(TABSExprNode)
   private
    LCursor:              TABSCursor; // Cursor
    LAO:                  TABSAO;
    LRecordBuffer:        PChar;
    FTableName:           string;  // table name - Table1 (Table1.Field1)
    FFieldName:           string;  // field name - Field1
    FFieldNameInAO:       string;  // field name - could be like Field1_1
    FFieldNo:             Integer;
    FFieldOffsetInBuffer: Integer;
    FFieldType:           TABSAdvancedFieldType;
    FBaseFieldType:       TABSBaseFieldType;
    FFieldSize:           Integer;
    FFieldPrecision:      Integer;
    FGetFromParent:       Boolean;
    FScanOnlyVisibleFieldsInAO: Boolean;
   public
    constructor Create(Cursor: TABSCursor; FieldName: String; TableName: string = ''); overload;
    // Return Data Value
    function GetDataValue: TABSVariant;  override;
    // try to assign AO
    function TryAssignAO(AOToAssign: TABSAO): Boolean;
    // process assign AO
    procedure AssignAO(AO, ParentQueryAO: TABSAO; ParentCursor: TABSCursor); override;
    // find field No in cursor
    function FindFieldInCursor(Cursor: TABSCursor; var FieldNo: Integer): Boolean;
    // process assign Cursor and its buffer
    procedure AssignCursor(Cursor: TABSCursor; ParentQueryAO: TABSAO; ParentCursor: TABSCursor); override;
    // process assign New Cursor Buffer
    procedure AssignCursorBuffer(Buffer: TABSRecordBuffer; ApplyToParentQueryFields: Boolean); override;
    // return Type of Data
    function GetDataType: TABSAdvancedFieldType; override;
    // return Data Size
    function GetDataSize: Integer;  override;

    // can be used by the AO?
    function CanBeAssigned(AO, ParentQueryAO: TABSAO;
                           ParentCursor: TABSCursor; ForHavingClause: Boolean = False): Boolean; override;
    // fills Field Item
    procedure FillItem(var Item: TABSSelectListItem);
    // replace pseudonyms to original names (f1 -> table1.field1)
    procedure ReplacePseudonyms(SelectList: array of TABSSelectListItem); override;
    // check if agregate expr, const or only grouped fields are used
    function CanBeUsedInGroupBy(GroupByFields: String): Boolean; override;

   public
    property TableName: String read FTableName;
    property FieldName: String read FFieldName;
    property FieldNo: Integer read FFieldNo;
    property FieldSize: Integer read FFieldSize;
    property BaseFieldType: TABSBaseFieldType read FBaseFieldType;
  end;

  TABSExprNodeComparison = class(TABSExprNode)
   private
    F3ValueLogic: Boolean; // 3 Value Logic (TRUE, FALSE, NULL)
    FQuantifier: TABSQuantifier;
   private
    procedure PatchWideStrings; override;
    // x > y
    function GetDataValueByCompare: TABSVariant;
    // x > all (select ...)
    function GetDataValueByQuantifiedCompare: TABSVariant;
   public
    // Constructor
    constructor Create(
                       Op: TABSDataOperator;
                       Node1, Node2: TABSExprNode;
                       TrueFalseNullLogic: boolean = true;
                       CaseInsensitive: boolean = true;
                       PartialKey: boolean = false
                       ); overload;
    // Constructor
    constructor Create(
                       Op: TABSDataOperator;
                       Quantifier: TABSQuantifier;
                       Node1, Node2: TABSExprNode;
                       TrueFalseNullLogic: boolean = true;
                       CaseInsensitive: boolean = true;
                       PartialKey: boolean = false
                       ); overload;
    // Return Data Value
    function GetDataValue: TABSVariant;  override;
    procedure GetFieldAndConstNodes(var FieldNode: TABSExprNodeField; var ConstNode: TABSExprNodeConst);
    // can use index for comparison?
    function CanUseIndex(IndexColumnNo: Integer; ConditionSearchOperator: TABSSearchCondition; IndexDef: TABSIndexDef; SessionID: TABSSessionID = INVALID_SESSION_ID): Boolean; override;
    // add index scan condition
    procedure AddAsIndexScanCondition(
                   ScanConditions: TABSScanSearchConditionArray;
                   IndexDef:       TABSIndexDef;
                   Expression:  TABSExpression); override;
    // add checks to multi-field index scan condition
    procedure ExtendIndexScanCondition(
                   ScanCondition: TABSScanSearchCondition;
                   IndexDef:      TABSIndexDef;
                   Expression:    TABSExpression); override;
    // is node a join condition?
    function IsJoinCondition(AO1, AO2: TABSAO): Boolean; override;
  end;


  TABSExprNodeBoolean = class(TABSExprNode)
   private
    TempVal: TABSVariant;
    EscapeStr: String;
   private
    // process a Like b
    procedure Like;
    // process IN (SELECT ...)
    procedure bInSubquery;
    // process IN (...)
    procedure bIn;
    // process A BETWEEN B AND C
    procedure Between;
    // process EXISTS
    procedure Exists;
   public
    constructor Create(
                       CaseInsensitive: boolean = true;
                       PartialKey: boolean = false
                      ); overload;
    constructor Create(
                       Op: TABSDataOperator;
                       CaseInsensitive: boolean = true;
                       PartialKey: boolean = false;
                       aEscapeStr: String=''
                      ); overload;
    constructor Create(
                       Op: TABSDataOperator;
                       Node: TABSExprNode;
                       CaseInsensitive: boolean = true;
                       PartialKey: boolean = false
                      ); overload;
    constructor Create(
                       Op: TABSDataOperator;
                       Node1, Node2: TABSExprNode;
                       CaseInsensitive: boolean = true;
                       PartialKey: boolean = false
                       ); overload;
    constructor Create(
                       Op: TABSDataOperator;
                       Node1, Node2, Node3: TABSExprNode;
                       CaseInsensitive: boolean = true;
                       PartialKey: boolean = false
                       ); overload;
    destructor Destroy; override;
    // Return Data Value
    function GetDataValue: TABSVariant;  override;
    // can use index for comparison?
    function CanUseIndex(ColumnNo: Integer; ConditionSearchOperator: TABSSearchCondition;
     IndexDef: TABSIndexDef; SessionID: TABSSessionID = INVALID_SESSION_ID): Boolean; override;
    // add index scan condition
    procedure AddAsIndexScanCondition(
                   ScanConditions: TABSScanSearchConditionArray;
                   IndexDef:       TABSIndexDef;
                   Expression:  TABSExpression); override;
    // add checks to multi-field index scan condition
    procedure ExtendIndexScanCondition(
                   ScanCondition: TABSScanSearchCondition;
                   IndexDef:      TABSIndexDef;
                   Expression:    TABSExpression); override;
  end;


  TABSExprNodeArithmetic = class(TABSExprNode)
   protected

⌨️ 快捷键说明

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