mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-11 20:49:14 +02:00
* Patch from Laco to implement filtering on null values
This commit is contained in:
parent
0f5bd26cba
commit
f1043ef099
@ -65,10 +65,12 @@ type
|
|||||||
private
|
private
|
||||||
FField: TField;
|
FField: TField;
|
||||||
FFieldName: string;
|
FFieldName: string;
|
||||||
|
FFieldIsNull: boolean;
|
||||||
FExprWord: TExprWord;
|
FExprWord: TExprWord;
|
||||||
protected
|
protected
|
||||||
function GetFieldVal: Pointer; virtual; abstract;
|
function GetFieldVal: Pointer; virtual; abstract;
|
||||||
function GetFieldType: TExpressionType; virtual; abstract;
|
function GetFieldType: TExpressionType; virtual; abstract;
|
||||||
|
function GetFieldIsNull: PBoolean;
|
||||||
public
|
public
|
||||||
constructor Create(UseField: TField);
|
constructor Create(UseField: TField);
|
||||||
|
|
||||||
@ -78,6 +80,7 @@ type
|
|||||||
property FieldDef: TField read FField;
|
property FieldDef: TField read FField;
|
||||||
property FieldType: TExpressionType read GetFieldType;
|
property FieldType: TExpressionType read GetFieldType;
|
||||||
property FieldName: string read FFieldName;
|
property FieldName: string read FFieldName;
|
||||||
|
property FieldIsNull: PBoolean read GetFieldIsNull;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TStringFieldVar = class(TFieldVar)
|
TStringFieldVar = class(TFieldVar)
|
||||||
@ -148,7 +151,6 @@ type
|
|||||||
procedure Refresh(Buffer: TRecordBuffer); override;
|
procedure Refresh(Buffer: TRecordBuffer); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
//--TFieldVar----------------------------------------------------------------
|
//--TFieldVar----------------------------------------------------------------
|
||||||
constructor TFieldVar.Create(UseField: TField);
|
constructor TFieldVar.Create(UseField: TField);
|
||||||
begin
|
begin
|
||||||
@ -160,6 +162,11 @@ begin
|
|||||||
FFieldName := UseField.FieldName;
|
FFieldName := UseField.FieldName;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFieldVar.GetFieldIsNull: PBoolean;
|
||||||
|
begin
|
||||||
|
Result := @FFieldIsNull;
|
||||||
|
end;
|
||||||
|
|
||||||
//--TStringFieldVar-------------------------------------------------------------
|
//--TStringFieldVar-------------------------------------------------------------
|
||||||
function TStringFieldVar.GetFieldVal: Pointer;
|
function TStringFieldVar.GetFieldVal: Pointer;
|
||||||
begin
|
begin
|
||||||
@ -188,7 +195,8 @@ end;
|
|||||||
procedure TStringFieldVar.Refresh(Buffer: TRecordBuffer);
|
procedure TStringFieldVar.Refresh(Buffer: TRecordBuffer);
|
||||||
var Fieldbuf : TStringFieldBuffer;
|
var Fieldbuf : TStringFieldBuffer;
|
||||||
begin
|
begin
|
||||||
if not FField.DataSet.GetFieldData(FField,@Fieldbuf) then
|
FFieldIsNull := not FField.DataSet.GetFieldData(FField,@Fieldbuf);
|
||||||
|
if FFieldIsNull then
|
||||||
FFieldVal^:=#0
|
FFieldVal^:=#0
|
||||||
else
|
else
|
||||||
strcopy(FFieldVal,@Fieldbuf[0]);
|
strcopy(FFieldVal,@Fieldbuf[0]);
|
||||||
@ -207,7 +215,8 @@ end;
|
|||||||
|
|
||||||
procedure TFloatFieldVar.Refresh(Buffer: TRecordBuffer);
|
procedure TFloatFieldVar.Refresh(Buffer: TRecordBuffer);
|
||||||
begin
|
begin
|
||||||
if not FField.DataSet.GetFieldData(FField,@FFieldVal) then
|
FFieldIsNull := not FField.DataSet.GetFieldData(FField,@FFieldVal);
|
||||||
|
if FFieldIsNull then
|
||||||
FFieldVal := 0;
|
FFieldVal := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -224,7 +233,8 @@ end;
|
|||||||
|
|
||||||
procedure TIntegerFieldVar.Refresh(Buffer: TRecordBuffer);
|
procedure TIntegerFieldVar.Refresh(Buffer: TRecordBuffer);
|
||||||
begin
|
begin
|
||||||
if not FField.DataSet.GetFieldData(FField,@FFieldVal) then
|
FFieldIsNull := not FField.DataSet.GetFieldData(FField,@FFieldVal);
|
||||||
|
if FFieldIsNull then
|
||||||
FFieldVal := 0;
|
FFieldVal := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -241,7 +251,8 @@ end;
|
|||||||
|
|
||||||
procedure TLargeIntFieldVar.Refresh(Buffer: TRecordBuffer);
|
procedure TLargeIntFieldVar.Refresh(Buffer: TRecordBuffer);
|
||||||
begin
|
begin
|
||||||
if not FField.DataSet.GetFieldData(FField,@FFieldVal) then
|
FFieldIsNull := not FField.DataSet.GetFieldData(FField,@FFieldVal);
|
||||||
|
if FFieldIsNull then
|
||||||
FFieldVal := 0;
|
FFieldVal := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -258,7 +269,8 @@ end;
|
|||||||
|
|
||||||
procedure TDateTimeFieldVar.Refresh(Buffer:TRecordBuffer );
|
procedure TDateTimeFieldVar.Refresh(Buffer:TRecordBuffer );
|
||||||
begin
|
begin
|
||||||
if not FField.DataSet.GetFieldData(FField,@FFieldVal) then
|
FFieldIsNull := not FField.DataSet.GetFieldData(FField,@FFieldVal);
|
||||||
|
if FFieldIsNull then
|
||||||
FFieldVal := 0;
|
FFieldVal := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -275,17 +287,19 @@ end;
|
|||||||
|
|
||||||
procedure TBooleanFieldVar.Refresh(Buffer: TRecordBuffer);
|
procedure TBooleanFieldVar.Refresh(Buffer: TRecordBuffer);
|
||||||
begin
|
begin
|
||||||
if not FField.DataSet.GetFieldData(FField,@FFieldVal) then
|
FFieldIsNull := not FField.DataSet.GetFieldData(FField,@FFieldVal);
|
||||||
|
if FFieldIsNull then
|
||||||
FFieldVal := False;
|
FFieldVal := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TBCDFieldVar.Refresh(Buffer: TRecordBuffer);
|
procedure TBCDFieldVar.Refresh(Buffer: TRecordBuffer);
|
||||||
var c: currency;
|
var c: currency;
|
||||||
begin
|
begin
|
||||||
if FField.DataSet.GetFieldData(FField,@c) then
|
FFieldIsNull := not FField.DataSet.GetFieldData(FField,@c);
|
||||||
FFieldVal := c
|
if FFieldIsNull then
|
||||||
|
FFieldVal := 0
|
||||||
else
|
else
|
||||||
FFieldVal := 0;
|
FFieldVal := c;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -390,7 +404,7 @@ begin
|
|||||||
ftString, ftFixedChar:
|
ftString, ftFixedChar:
|
||||||
begin
|
begin
|
||||||
TempFieldVar := TStringFieldVar.Create(FieldInfo);
|
TempFieldVar := TStringFieldVar.Create(FieldInfo);
|
||||||
TempFieldVar.FExprWord := DefineStringVariable(VarName, TempFieldVar.FieldVal);
|
TempFieldVar.FExprWord := DefineStringVariable(VarName, TempFieldVar.FieldVal, TempFieldVar.FieldIsNull);
|
||||||
TempFieldVar.FExprWord.fixedlen := Fieldinfo.Size;
|
TempFieldVar.FExprWord.fixedlen := Fieldinfo.Size;
|
||||||
end;
|
end;
|
||||||
ftBoolean:
|
ftBoolean:
|
||||||
@ -406,7 +420,7 @@ begin
|
|||||||
ftAutoInc, ftInteger, ftSmallInt, ftWord:
|
ftAutoInc, ftInteger, ftSmallInt, ftWord:
|
||||||
begin
|
begin
|
||||||
TempFieldVar := TIntegerFieldVar.Create(FieldInfo);
|
TempFieldVar := TIntegerFieldVar.Create(FieldInfo);
|
||||||
TempFieldVar.FExprWord := DefineIntegerVariable(VarName, TempFieldVar.FieldVal);
|
TempFieldVar.FExprWord := DefineIntegerVariable(VarName, TempFieldVar.FieldVal, TempFieldVar.FieldIsNull);
|
||||||
end;
|
end;
|
||||||
ftLargeInt:
|
ftLargeInt:
|
||||||
begin
|
begin
|
||||||
|
@ -85,14 +85,14 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
function DefineFloatVariable(AVarName: string; AValue: PDouble): TExprWord;
|
function DefineFloatVariable(AVarName: string; AValue: PDouble): TExprWord;
|
||||||
function DefineIntegerVariable(AVarName: string; AValue: PInteger): TExprWord;
|
function DefineIntegerVariable(AVarName: string; AValue: PInteger; AIsNull: PBoolean = nil): TExprWord;
|
||||||
// procedure DefineSmallIntVariable(AVarName: string; AValue: PSmallInt);
|
// procedure DefineSmallIntVariable(AVarName: string; AValue: PSmallInt);
|
||||||
{$ifdef SUPPORT_INT64}
|
{$ifdef SUPPORT_INT64}
|
||||||
function DefineLargeIntVariable(AVarName: string; AValue: PLargeInt): TExprWord;
|
function DefineLargeIntVariable(AVarName: string; AValue: PLargeInt): TExprWord;
|
||||||
{$endif}
|
{$endif}
|
||||||
function DefineDateTimeVariable(AVarName: string; AValue: PDateTimeRec): TExprWord;
|
function DefineDateTimeVariable(AVarName: string; AValue: PDateTimeRec): TExprWord;
|
||||||
function DefineBooleanVariable(AVarName: string; AValue: PBoolean): TExprWord;
|
function DefineBooleanVariable(AVarName: string; AValue: PBoolean): TExprWord;
|
||||||
function DefineStringVariable(AVarName: string; AValue: PPChar): TExprWord;
|
function DefineStringVariable(AVarName: string; AValue: PPChar; AIsNull: PBoolean = nil): TExprWord;
|
||||||
function DefineFunction(AFunctName, AShortName, ADescription, ATypeSpec: string;
|
function DefineFunction(AFunctName, AShortName, ADescription, ATypeSpec: string;
|
||||||
AMinFunctionArg: Integer; AResultType: TExpressionType; AFuncAddress: TExprFunc): TExprWord;
|
AMinFunctionArg: Integer; AResultType: TExpressionType; AFuncAddress: TExprFunc): TExprWord;
|
||||||
procedure Evaluate(AnExpression: string);
|
procedure Evaluate(AnExpression: string);
|
||||||
@ -265,6 +265,8 @@ begin
|
|||||||
Args[0] := ExprWord.AsPointer;
|
Args[0] := ExprWord.AsPointer;
|
||||||
// store length as second parameter
|
// store length as second parameter
|
||||||
Args[1] := PChar(ExprWord.LenAsPointer);
|
Args[1] := PChar(ExprWord.LenAsPointer);
|
||||||
|
// and NULL indicator as third parameter
|
||||||
|
Args[2] := PChar(ExprWord.IsNullAsPointer);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -501,6 +503,7 @@ begin
|
|||||||
etLargeInt:ExprWord := TLargeIntConstant.Create(PInt64(FExpResult)^);
|
etLargeInt:ExprWord := TLargeIntConstant.Create(PInt64(FExpResult)^);
|
||||||
{$endif}
|
{$endif}
|
||||||
etString: ExprWord := TStringConstant.Create(FExpResult);
|
etString: ExprWord := TStringConstant.Create(FExpResult);
|
||||||
|
etUnknown: ExprWord := TNullConstant.Create;
|
||||||
else raise EParserException.CreateFmt('No support for resulttype %d. Please fix the TDBF code.',[ResultType]);
|
else raise EParserException.CreateFmt('No support for resulttype %d. Please fix the TDBF code.',[ResultType]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -778,6 +781,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomExpressionParser.ParseString(AnExpression: string; DestCollection: TExprCollection);
|
procedure TCustomExpressionParser.ParseString(AnExpression: string; DestCollection: TExprCollection);
|
||||||
|
const
|
||||||
|
NullWord='NULL';
|
||||||
var
|
var
|
||||||
isConstant: Boolean;
|
isConstant: Boolean;
|
||||||
I, I1, I2, Len, DecSep: Integer;
|
I, I1, I2, Len, DecSep: Integer;
|
||||||
@ -971,6 +976,13 @@ begin
|
|||||||
DestCollection.Add(TempWord);
|
DestCollection.Add(TempWord);
|
||||||
FConstantsList.Add(TempWord);
|
FConstantsList.Add(TempWord);
|
||||||
end
|
end
|
||||||
|
else if UpCase(W) = NullWord then
|
||||||
|
begin
|
||||||
|
// NULL
|
||||||
|
TempWord := TNullConstant.Create;
|
||||||
|
DestCollection.Add(TempWord);
|
||||||
|
FConstantsList.Add(TempWord);
|
||||||
|
end
|
||||||
else if Length(W) > 0 then
|
else if Length(W) > 0 then
|
||||||
if FWordsList.Search(PChar(W), I) then
|
if FWordsList.Search(PChar(W), I) then
|
||||||
begin
|
begin
|
||||||
@ -1132,9 +1144,9 @@ begin
|
|||||||
FWordsList.Add(Result);
|
FWordsList.Add(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomExpressionParser.DefineIntegerVariable(AVarName: string; AValue: PInteger): TExprWord;
|
function TCustomExpressionParser.DefineIntegerVariable(AVarName: string; AValue: PInteger; AIsNull: PBoolean): TExprWord;
|
||||||
begin
|
begin
|
||||||
Result := TIntegerVariable.Create(AVarName, AValue);
|
Result := TIntegerVariable.Create(AVarName, AValue, AIsNull);
|
||||||
FWordsList.Add(Result);
|
FWordsList.Add(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1166,9 +1178,9 @@ begin
|
|||||||
FWordsList.Add(Result);
|
FWordsList.Add(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomExpressionParser.DefineStringVariable(AVarName: string; AValue: PPChar): TExprWord;
|
function TCustomExpressionParser.DefineStringVariable(AVarName: string; AValue: PPChar; AIsNull: PBoolean): TExprWord;
|
||||||
begin
|
begin
|
||||||
Result := TStringVariable.Create(AVarName, AValue);
|
Result := TStringVariable.Create(AVarName, AValue, AIsNull);
|
||||||
FWordsList.Add(Result);
|
FWordsList.Add(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1864,6 +1876,12 @@ begin
|
|||||||
Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) >= 0);
|
Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) >= 0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure Func_SU_EQ(Param: PExpressionRec);
|
||||||
|
begin
|
||||||
|
with Param^ do
|
||||||
|
Res.MemoryPos^^ := Char(PBoolean(Args[0]+StrLen(Args[0])+1)^);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure Func_FF_EQ(Param: PExpressionRec);
|
procedure Func_FF_EQ(Param: PExpressionRec);
|
||||||
begin
|
begin
|
||||||
with Param^ do
|
with Param^ do
|
||||||
@ -1941,6 +1959,11 @@ begin
|
|||||||
with Param^ do
|
with Param^ do
|
||||||
Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInteger(Args[1])^);
|
Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInteger(Args[1])^);
|
||||||
end;
|
end;
|
||||||
|
procedure Func_IU_EQ(Param: PExpressionRec);
|
||||||
|
begin
|
||||||
|
with Param^ do
|
||||||
|
Res.MemoryPos^^ := Char(PBoolean(Args[0]+8)^);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure Func_II_NEQ(Param: PExpressionRec);
|
procedure Func_II_NEQ(Param: PExpressionRec);
|
||||||
begin
|
begin
|
||||||
@ -2294,6 +2317,7 @@ initialization
|
|||||||
Add(TFunction.CreateOper('>=','FI', etBoolean, Func_FI_GTE, 80));
|
Add(TFunction.CreateOper('>=','FI', etBoolean, Func_FI_GTE, 80));
|
||||||
Add(TFunction.CreateOper('<>','FI', etBoolean, Func_FI_NEQ, 80));
|
Add(TFunction.CreateOper('<>','FI', etBoolean, Func_FI_NEQ, 80));
|
||||||
Add(TFunction.CreateOper('=', 'II', etBoolean, Func_II_EQ , 80));
|
Add(TFunction.CreateOper('=', 'II', etBoolean, Func_II_EQ , 80));
|
||||||
|
Add(TFunction.CreateOper('=', 'IU', etBoolean, Func_IU_EQ , 80));
|
||||||
Add(TFunction.CreateOper('<', 'II', etBoolean, Func_II_LT , 80));
|
Add(TFunction.CreateOper('<', 'II', etBoolean, Func_II_LT , 80));
|
||||||
Add(TFunction.CreateOper('>', 'II', etBoolean, Func_II_GT , 80));
|
Add(TFunction.CreateOper('>', 'II', etBoolean, Func_II_GT , 80));
|
||||||
Add(TFunction.CreateOper('<=','II', etBoolean, Func_II_LTE, 80));
|
Add(TFunction.CreateOper('<=','II', etBoolean, Func_II_LTE, 80));
|
||||||
@ -2337,6 +2361,7 @@ initialization
|
|||||||
Add(TFunction.CreateOper('>=','IL', etBoolean, Func_IL_GTE, 80));
|
Add(TFunction.CreateOper('>=','IL', etBoolean, Func_IL_GTE, 80));
|
||||||
Add(TFunction.CreateOper('<>','IL', etBoolean, Func_IL_NEQ, 80));
|
Add(TFunction.CreateOper('<>','IL', etBoolean, Func_IL_NEQ, 80));
|
||||||
{$endif}
|
{$endif}
|
||||||
|
Add(TFunction.CreateOper('=', 'SU', etBoolean, Func_SU_EQ , 80));
|
||||||
|
|
||||||
Add(TFunction.CreateOper('NOT', 'B', etBoolean, Func_NOT, 85));
|
Add(TFunction.CreateOper('NOT', 'B', etBoolean, Func_NOT, 85));
|
||||||
Add(TFunction.CreateOper('AND', 'BB', etBoolean, Func_AND, 90));
|
Add(TFunction.CreateOper('AND', 'BB', etBoolean, Func_AND, 90));
|
||||||
|
@ -90,6 +90,8 @@ type
|
|||||||
ExprFunc: TExprFunc;
|
ExprFunc: TExprFunc;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TExprWord }
|
||||||
|
|
||||||
TExprWord = class(TObject)
|
TExprWord = class(TObject)
|
||||||
private
|
private
|
||||||
FName: string;
|
FName: string;
|
||||||
@ -112,8 +114,9 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create(AName: string; AExprFunc: TExprFunc);
|
constructor Create(AName: string; AExprFunc: TExprFunc);
|
||||||
|
|
||||||
function LenAsPointer: PInteger; virtual;
|
|
||||||
function AsPointer: PChar; virtual;
|
function AsPointer: PChar; virtual;
|
||||||
|
function LenAsPointer: PInteger; virtual;
|
||||||
|
function IsNullAsPointer: PBoolean; virtual;
|
||||||
function IsFunction: Boolean; virtual;
|
function IsFunction: Boolean; virtual;
|
||||||
|
|
||||||
property ExprFunc: TExprFunc read FExprFunc;
|
property ExprFunc: TExprFunc read FExprFunc;
|
||||||
@ -225,14 +228,26 @@ type
|
|||||||
property Value: Boolean read FValue write FValue;
|
property Value: Boolean read FValue write FValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TNullConstant }
|
||||||
|
|
||||||
|
TNullConstant = class(TConstant)
|
||||||
|
private
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TVariable }
|
||||||
|
|
||||||
TVariable = class(TExprWord)
|
TVariable = class(TExprWord)
|
||||||
private
|
private
|
||||||
FResultType: TExpressionType;
|
FResultType: TExpressionType;
|
||||||
|
FIsNull: PBoolean;
|
||||||
protected
|
protected
|
||||||
function GetCanVary: Boolean; override;
|
function GetCanVary: Boolean; override;
|
||||||
function GetResultType: TExpressionType; override;
|
function GetResultType: TExpressionType; override;
|
||||||
public
|
public
|
||||||
constructor Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc);
|
constructor Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc);
|
||||||
|
function IsNullAsPointer: PBoolean; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TFloatVariable = class(TVariable)
|
TFloatVariable = class(TVariable)
|
||||||
@ -252,7 +267,7 @@ type
|
|||||||
function GetFixedLen: Integer; override;
|
function GetFixedLen: Integer; override;
|
||||||
procedure SetFixedLen(NewLen: integer); override;
|
procedure SetFixedLen(NewLen: integer); override;
|
||||||
public
|
public
|
||||||
constructor Create(AName: string; AValue: PPChar);
|
constructor Create(AName: string; AValue: PPChar; AIsNull: PBoolean);
|
||||||
|
|
||||||
function LenAsPointer: PInteger; override;
|
function LenAsPointer: PInteger; override;
|
||||||
function AsPointer: PChar; override;
|
function AsPointer: PChar; override;
|
||||||
@ -273,7 +288,7 @@ type
|
|||||||
private
|
private
|
||||||
FValue: PInteger;
|
FValue: PInteger;
|
||||||
public
|
public
|
||||||
constructor Create(AName: string; AValue: PInteger);
|
constructor Create(AName: string; AValue: PInteger; AIsNull: PBoolean);
|
||||||
|
|
||||||
function AsPointer: PChar; override;
|
function AsPointer: PChar; override;
|
||||||
end;
|
end;
|
||||||
@ -372,6 +387,7 @@ begin
|
|||||||
'F': Result := etFloat;
|
'F': Result := etFloat;
|
||||||
'D': Result := etDateTime;
|
'D': Result := etDateTime;
|
||||||
'S': Result := etString;
|
'S': Result := etString;
|
||||||
|
'U': Result := etUnknown;
|
||||||
else
|
else
|
||||||
Result := etUnknown;
|
Result := etUnknown;
|
||||||
end;
|
end;
|
||||||
@ -405,6 +421,10 @@ begin
|
|||||||
if length = -1 then
|
if length = -1 then
|
||||||
length := StrLen(PPChar(Args[0])^);
|
length := StrLen(PPChar(Args[0])^);
|
||||||
Res.Append(PPChar(Args[0])^, length);
|
Res.Append(PPChar(Args[0])^, length);
|
||||||
|
// NULL indicator (placed after NULL terminated string)
|
||||||
|
length := StrLen(PPChar(Args[0])^)+1;
|
||||||
|
Res.AssureSpace(length+1);
|
||||||
|
PBoolean(Res.Memory^+length)^ := Assigned(Args[2]) and PBoolean(Args[2])^;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -416,8 +436,10 @@ end;
|
|||||||
|
|
||||||
procedure _IntegerVariable(Param: PExpressionRec);
|
procedure _IntegerVariable(Param: PExpressionRec);
|
||||||
begin
|
begin
|
||||||
with Param^ do
|
with Param^ do begin
|
||||||
PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^;
|
PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^;
|
||||||
|
PBoolean(Res.MemoryPos^+8)^ := Assigned(Args[2]) and PBoolean(Args[2])^; // NULL indicator
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -429,15 +451,18 @@ end;
|
|||||||
}
|
}
|
||||||
|
|
||||||
{$ifdef SUPPORT_INT64}
|
{$ifdef SUPPORT_INT64}
|
||||||
|
|
||||||
procedure _LargeIntVariable(Param: PExpressionRec);
|
procedure _LargeIntVariable(Param: PExpressionRec);
|
||||||
begin
|
begin
|
||||||
with Param^ do
|
with Param^ do
|
||||||
PLargeInt(Res.MemoryPos^)^ := PLargeInt(Args[0])^;
|
PLargeInt(Res.MemoryPos^)^ := PLargeInt(Args[0])^;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
procedure _NullConstant(Param: PExpressionRec);
|
||||||
|
begin
|
||||||
|
// NOP
|
||||||
|
end;
|
||||||
|
|
||||||
{ TExpressionWord }
|
{ TExpressionWord }
|
||||||
|
|
||||||
constructor TExprWord.Create(AName: string; AExprFunc: TExprFunc);
|
constructor TExprWord.Create(AName: string; AExprFunc: TExprFunc);
|
||||||
@ -536,6 +561,11 @@ begin
|
|||||||
Result := nil;
|
Result := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TExprWord.IsNullAsPointer: PBoolean;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
function TExprWord.IsFunction: Boolean;
|
function TExprWord.IsFunction: Boolean;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
@ -665,6 +695,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
{ TNullConstant }
|
||||||
|
|
||||||
|
constructor TNullConstant.Create;
|
||||||
|
begin
|
||||||
|
inherited Create('NULL', etUnknown, _NullConstant);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TVariable }
|
{ TVariable }
|
||||||
|
|
||||||
constructor TVariable.Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc);
|
constructor TVariable.Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc);
|
||||||
@ -684,6 +721,11 @@ begin
|
|||||||
Result := FResultType;
|
Result := FResultType;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TVariable.IsNullAsPointer: PBoolean;
|
||||||
|
begin
|
||||||
|
Result := FIsNull;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TFloatVariable }
|
{ TFloatVariable }
|
||||||
|
|
||||||
constructor TFloatVariable.Create(AName: string; AValue: PDouble);
|
constructor TFloatVariable.Create(AName: string; AValue: PDouble);
|
||||||
@ -699,7 +741,7 @@ end;
|
|||||||
|
|
||||||
{ TStringVariable }
|
{ TStringVariable }
|
||||||
|
|
||||||
constructor TStringVariable.Create(AName: string; AValue: PPChar);
|
constructor TStringVariable.Create(AName: string; AValue: PPChar; AIsNull: PBoolean);
|
||||||
begin
|
begin
|
||||||
// variable or fixed length?
|
// variable or fixed length?
|
||||||
inherited Create(AName, etString, _StringVariable);
|
inherited Create(AName, etString, _StringVariable);
|
||||||
@ -707,6 +749,7 @@ begin
|
|||||||
// store pointer to string
|
// store pointer to string
|
||||||
FValue := AValue;
|
FValue := AValue;
|
||||||
FFixedLen := -1;
|
FFixedLen := -1;
|
||||||
|
FIsNull := AIsNull;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TStringVariable.AsPointer: PChar;
|
function TStringVariable.AsPointer: PChar;
|
||||||
@ -744,10 +787,11 @@ end;
|
|||||||
|
|
||||||
{ TIntegerVariable }
|
{ TIntegerVariable }
|
||||||
|
|
||||||
constructor TIntegerVariable.Create(AName: string; AValue: PInteger);
|
constructor TIntegerVariable.Create(AName: string; AValue: PInteger; AIsNull: PBoolean);
|
||||||
begin
|
begin
|
||||||
inherited Create(AName, etInteger, _IntegerVariable);
|
inherited Create(AName, etInteger, _IntegerVariable);
|
||||||
FValue := AValue;
|
FValue := AValue;
|
||||||
|
FIsNull := AIsNull;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TIntegerVariable.AsPointer: PChar;
|
function TIntegerVariable.AsPointer: PChar;
|
||||||
@ -1070,6 +1114,7 @@ begin
|
|||||||
Inc(FMemoryPos^, Length);
|
Inc(FMemoryPos^, Length);
|
||||||
// null-terminate
|
// null-terminate
|
||||||
FMemoryPos^^ := #0;
|
FMemoryPos^^ := #0;
|
||||||
|
Inc(FMemoryPos^);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDynamicType.AppendInteger(Source: Integer);
|
procedure TDynamicType.AppendInteger(Source: Integer);
|
||||||
@ -1078,6 +1123,7 @@ begin
|
|||||||
AssureSpace(12);
|
AssureSpace(12);
|
||||||
Inc(FMemoryPos^, GetStrFromInt(Source, FMemoryPos^));
|
Inc(FMemoryPos^, GetStrFromInt(Source, FMemoryPos^));
|
||||||
FMemoryPos^^ := #0;
|
FMemoryPos^^ := #0;
|
||||||
|
Inc(FMemoryPos^);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user