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;
|
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
|
MAXVALUE
|
||||||
--------
|
--------
|
||||||
|
@ -769,10 +769,10 @@ void setParamsMakeDbkey(DataTypeUtilBase*, const SysFunction*, int argsCount, ds
|
|||||||
args[1]->makeInt64(0);
|
args[1]->makeInt64(0);
|
||||||
|
|
||||||
if (argsCount > 2 && args[2]->isUnknown())
|
if (argsCount > 2 && args[2]->isUnknown())
|
||||||
args[2]->makeLong(0);
|
args[2]->makeInt64(0);
|
||||||
|
|
||||||
if (argsCount > 3 && args[3]->isUnknown())
|
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)
|
int argsCount, const dsc** args)
|
||||||
{
|
{
|
||||||
result->makeText(8, ttype_binary);
|
result->makeText(8, ttype_binary);
|
||||||
|
result->setNullable(true);
|
||||||
bool isNullable;
|
|
||||||
if (initResult(result, argsCount, args, &isNullable))
|
|
||||||
return;
|
|
||||||
|
|
||||||
result->setNullable(isNullable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void makeDoubleResult(DataTypeUtilBase*, const SysFunction*, dsc* result,
|
void makeDoubleResult(DataTypeUtilBase*, const SysFunction*, dsc* result,
|
||||||
int argsCount, const dsc** args)
|
int argsCount, const dsc** args)
|
||||||
{
|
{
|
||||||
@ -4862,7 +4858,7 @@ dsc* evlMakeDbkey(Jrd::thread_db* tdbb, const SysFunction* function, const NestV
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
const SLONG value = MOV_get_long(tdbb, argDsc, 0);
|
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;
|
return NULL;
|
||||||
|
|
||||||
relId = (USHORT) value;
|
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);
|
SINT64 recNo = MOV_get_int64(tdbb, argDsc, 0);
|
||||||
|
|
||||||
ULONG dpNum = MAX_ULONG, ppNum = MAX_ULONG;
|
SINT64 dpNum = 0, ppNum = 0;
|
||||||
|
|
||||||
if (args.getCount() > 2)
|
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)
|
if (request->req_flags & req_null)
|
||||||
return 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)
|
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)
|
if (request->req_flags & req_null)
|
||||||
return 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;
|
RecordNumber temp;
|
||||||
|
|
||||||
if (args.getCount() == 4)
|
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)
|
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);
|
temp.setValue(recNo + 1);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user