mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 18:43:02 +01:00
Some additional checks and documentation for new MAKE_DBKEY function.
This commit is contained in:
parent
92d01afe95
commit
e44446e855
@ -693,6 +693,71 @@ Example:
|
||||
select lpad(x, 10) from y;
|
||||
|
||||
|
||||
----------
|
||||
MAKE_DBKEY
|
||||
----------
|
||||
|
||||
Function:
|
||||
MAKE_DBKEY( relation, recnum [, dpnum [, ppnum]] )
|
||||
Creates DBKEY value using relation name or ID, record number, and, optionally,
|
||||
logical number of data page and pointer page.
|
||||
|
||||
Format:
|
||||
MAKE_DBKEY( <value>, <number> [, <number> [, <number>]] )
|
||||
|
||||
Notes:
|
||||
1) If the first argument (relation) is a string expression or literal, then
|
||||
it's treated as a relation name and the engine searches for the
|
||||
corresponding relation ID. The search is case-sensitive.
|
||||
In the case of string literal, relation ID is evaluated at prepare time.
|
||||
In the case of expression, relation ID is evaluated at execution time.
|
||||
If the relation couldn't be found, then isc_relnotdef error is raised.
|
||||
2) If the first argument (relation) is a numeric expression or literal, then
|
||||
it's treated as a relation ID and used "as is", without verification
|
||||
against existing relations.
|
||||
If the argument value is negative or greater than the maximum allowed
|
||||
relation ID (65535 currently), then NULL is returned.
|
||||
3) Second argument (recnum) represents an absolute record number in relation
|
||||
(if the next arguments -- dpnum and ppnum -- are missing), or a record
|
||||
number relative to the first record, specified by the next arguments.
|
||||
4) Third argument (dpnum) is a logical number of data page in relation (if
|
||||
the next argument -- ppnum -- is missing), or number of data page
|
||||
relative to the first data page addressed by the given ppnum.
|
||||
5) Forth argument (ppnum) is a logical number of pointer page in relation.
|
||||
6) All numbers are zero-based.
|
||||
Maximum allowed value for dpnum and ppnum is 2^32 (4294967296).
|
||||
If dpnum is specified, then recnum could be negative.
|
||||
If dpnum is missing and recnum is negative then NULL is returned.
|
||||
If ppnum is specified, then dpnum could be negative.
|
||||
If ppnum is missing and dpnum is negative then NULL is returned.
|
||||
7) If any of specified arguments has NULL value, the result is also NULL.
|
||||
8) First argument (relation) is described as INTEGER but could be overriden
|
||||
by application as VARCHAR or CHAR.
|
||||
recnum, dpnum and ppnum are described as BIGINT (64-bit signed integer).
|
||||
|
||||
Examples:
|
||||
|
||||
1) Select record using relation name (note, relation name is in uppercase)
|
||||
|
||||
select * from rdb$relations where rdb$db_key = make_dbkey('RDB$RELATIONS', 0)
|
||||
|
||||
2) Select record using relation ID
|
||||
|
||||
select * from rdb$relations where rdb$db_key = make_dbkey(6, 0)
|
||||
|
||||
3) Select all records that physically reside at first data page in relation
|
||||
|
||||
select * from rdb$relations
|
||||
where rdb$db_key >= make_dbkey(6, 0, 0)
|
||||
and rdb$db_key < make_dbkey(6, 0, 1)
|
||||
|
||||
4) Select all records that physically reside at first data page of 6th pointer
|
||||
page at relation
|
||||
|
||||
select * from SOMETABLE
|
||||
where rdb$db_key >= make_dbkey('SOMETABLE', 0, 0, 5)
|
||||
and rdb$db_key < make_dbkey('SOMETABLE', 0, 1, 5)
|
||||
|
||||
--------
|
||||
MAXVALUE
|
||||
--------
|
||||
|
@ -769,10 +769,10 @@ void setParamsMakeDbkey(DataTypeUtilBase*, const SysFunction*, int argsCount, ds
|
||||
args[1]->makeInt64(0);
|
||||
|
||||
if (argsCount > 2 && args[2]->isUnknown())
|
||||
args[2]->makeLong(0);
|
||||
args[2]->makeInt64(0);
|
||||
|
||||
if (argsCount > 3 && args[3]->isUnknown())
|
||||
args[3]->makeLong(0);
|
||||
args[3]->makeInt64(0);
|
||||
}
|
||||
|
||||
|
||||
@ -847,14 +847,10 @@ void makeDbkeyResult(DataTypeUtilBase*, const SysFunction*, dsc* result,
|
||||
int argsCount, const dsc** args)
|
||||
{
|
||||
result->makeText(8, ttype_binary);
|
||||
|
||||
bool isNullable;
|
||||
if (initResult(result, argsCount, args, &isNullable))
|
||||
return;
|
||||
|
||||
result->setNullable(isNullable);
|
||||
result->setNullable(true);
|
||||
}
|
||||
|
||||
|
||||
void makeDoubleResult(DataTypeUtilBase*, const SysFunction*, dsc* result,
|
||||
int argsCount, const dsc** args)
|
||||
{
|
||||
@ -4862,7 +4858,7 @@ dsc* evlMakeDbkey(Jrd::thread_db* tdbb, const SysFunction* function, const NestV
|
||||
else
|
||||
{
|
||||
const SLONG value = MOV_get_long(tdbb, argDsc, 0);
|
||||
if (value > MAX_USHORT) // return NULL if the provided ID is too long
|
||||
if (value < 0 || value > MAX_USHORT) // return NULL if the provided ID is too long
|
||||
return NULL;
|
||||
|
||||
relId = (USHORT) value;
|
||||
@ -4874,7 +4870,7 @@ dsc* evlMakeDbkey(Jrd::thread_db* tdbb, const SysFunction* function, const NestV
|
||||
|
||||
SINT64 recNo = MOV_get_int64(tdbb, argDsc, 0);
|
||||
|
||||
ULONG dpNum = MAX_ULONG, ppNum = MAX_ULONG;
|
||||
SINT64 dpNum = 0, ppNum = 0;
|
||||
|
||||
if (args.getCount() > 2)
|
||||
{
|
||||
@ -4882,7 +4878,9 @@ dsc* evlMakeDbkey(Jrd::thread_db* tdbb, const SysFunction* function, const NestV
|
||||
if (request->req_flags & req_null)
|
||||
return NULL;
|
||||
|
||||
dpNum = MOV_get_long(tdbb, argDsc, 0);
|
||||
dpNum = MOV_get_int64(tdbb, argDsc, 0);
|
||||
if (dpNum > MAX_ULONG)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (args.getCount() > 3)
|
||||
@ -4891,15 +4889,24 @@ dsc* evlMakeDbkey(Jrd::thread_db* tdbb, const SysFunction* function, const NestV
|
||||
if (request->req_flags & req_null)
|
||||
return NULL;
|
||||
|
||||
ppNum = MOV_get_long(tdbb, argDsc, 0);
|
||||
ppNum = MOV_get_int64(tdbb, argDsc, 0);
|
||||
if (ppNum < 0 || ppNum > MAX_ULONG)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RecordNumber temp;
|
||||
|
||||
if (args.getCount() == 4)
|
||||
recNo += ((SINT64) ppNum * dbb->dbb_dp_per_pp + dpNum) * dbb->dbb_max_records;
|
||||
recNo += (ppNum * dbb->dbb_dp_per_pp + dpNum) * dbb->dbb_max_records;
|
||||
else if (args.getCount() == 3)
|
||||
recNo += (SINT64) dpNum * dbb->dbb_max_records;
|
||||
{
|
||||
if (dpNum < 0)
|
||||
return NULL;
|
||||
recNo += dpNum * dbb->dbb_max_records;
|
||||
}
|
||||
|
||||
if (recNo < 0)
|
||||
return NULL;
|
||||
|
||||
temp.setValue(recNo + 1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user