mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 21:23:03 +01:00
Style.
This commit is contained in:
parent
3359dc0d43
commit
f7bf07d9be
@ -290,8 +290,10 @@ ULONG IntlUtil::cvtAsciiToUtf16(csconvert* obj, ULONG nSrc, const UCHAR* pSrc,
|
||||
|
||||
const USHORT* const pStart = pDest;
|
||||
const UCHAR* const pStart_src = pSrc;
|
||||
while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) {
|
||||
if (*pSrc > 127) {
|
||||
while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc))
|
||||
{
|
||||
if (*pSrc > 127)
|
||||
{
|
||||
*err_code = CS_BAD_INPUT;
|
||||
break;
|
||||
}
|
||||
@ -336,8 +338,10 @@ ULONG IntlUtil::cvtUtf16ToAscii(csconvert* obj, ULONG nSrc, const UCHAR* ppSrc,
|
||||
|
||||
const UCHAR* const pStart = pDest;
|
||||
const USHORT* const pStart_src = pSrc;
|
||||
while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) {
|
||||
if (*pSrc > 127) {
|
||||
while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc))
|
||||
{
|
||||
if (*pSrc > 127)
|
||||
{
|
||||
*err_code = CS_CONVERT_ERROR;
|
||||
break;
|
||||
}
|
||||
|
@ -95,7 +95,8 @@ bool OPT_computable(CompilerScratch* csb, const jrd_nod* node, SSHORT stream,
|
||||
case nod_procedure:
|
||||
{
|
||||
const jrd_nod* const inputs = node->nod_arg[e_prc_inputs];
|
||||
if (inputs) {
|
||||
if (inputs)
|
||||
{
|
||||
fb_assert(inputs->nod_type == nod_asn_list);
|
||||
const jrd_nod* const* ptr = inputs->nod_arg;
|
||||
for (const jrd_nod* const* const end = ptr + inputs->nod_count; ptr < end; ptr++)
|
||||
@ -140,13 +141,15 @@ bool OPT_computable(CompilerScratch* csb, const jrd_nod* node, SSHORT stream,
|
||||
{
|
||||
case nod_field:
|
||||
n = (USHORT)(IPTR) node->nod_arg[e_fld_stream];
|
||||
if (allowOnlyCurrentStream) {
|
||||
if (allowOnlyCurrentStream)
|
||||
{
|
||||
if (n != stream && !(csb->csb_rpt[n].csb_flags & csb_sub_stream))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
if (n == stream) {
|
||||
return false;
|
||||
}
|
||||
@ -239,8 +242,10 @@ bool OPT_computable(CompilerScratch* csb, const jrd_nod* node, SSHORT stream,
|
||||
const jrd_nod* const* ptr;
|
||||
const jrd_nod* const* end;
|
||||
|
||||
for (ptr = rse->rse_relation, end = ptr + rse->rse_count; ptr < end; ptr++) {
|
||||
if ((*ptr)->nod_type != nod_rse) {
|
||||
for (ptr = rse->rse_relation, end = ptr + rse->rse_count; ptr < end; ptr++)
|
||||
{
|
||||
if ((*ptr)->nod_type != nod_rse)
|
||||
{
|
||||
n = (USHORT)(IPTR) (*ptr)->nod_arg[STREAM_INDEX((*ptr))];
|
||||
csb->csb_rpt[n].csb_flags |= (csb_active | csb_sub_stream);
|
||||
}
|
||||
@ -256,7 +261,8 @@ bool OPT_computable(CompilerScratch* csb, const jrd_nod* node, SSHORT stream,
|
||||
|
||||
for (ptr = rse->rse_relation, end = ptr + rse->rse_count; ptr < end && result; ptr++)
|
||||
{
|
||||
if ((*ptr)->nod_type != nod_rse) {
|
||||
if ((*ptr)->nod_type != nod_rse)
|
||||
{
|
||||
if (!OPT_computable(csb, (*ptr), stream, idx_use, allowOnlyCurrentStream)) {
|
||||
result = false;
|
||||
}
|
||||
@ -617,12 +623,14 @@ double OPT_getRelationCardinality(thread_db* tdbb, jrd_rel* relation, const Form
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
if (relation->isVirtual()) {
|
||||
if (relation->isVirtual())
|
||||
{
|
||||
// Just a dumb estimation
|
||||
return (double) 100;
|
||||
}
|
||||
|
||||
if (relation->rel_file) {
|
||||
if (relation->rel_file)
|
||||
{
|
||||
// Is there really no way to do better?
|
||||
// Don't we know the file-size and record-size?
|
||||
return (double) 10000;
|
||||
@ -711,12 +719,14 @@ VaryingString* OPT_make_alias(thread_db* tdbb, const CompilerScratch* csb,
|
||||
const TEXT* q;
|
||||
if (csb_tail->csb_alias)
|
||||
q = (TEXT *) csb_tail->csb_alias->c_str();
|
||||
else {
|
||||
else
|
||||
{
|
||||
q = (csb_tail->csb_relation && csb_tail->csb_relation->rel_name.length() ?
|
||||
csb_tail->csb_relation->rel_name.c_str() : NULL);
|
||||
}
|
||||
// go to the end of the alias and copy it backwards
|
||||
if (q) {
|
||||
if (q)
|
||||
{
|
||||
for (alias_length = 0; *q; alias_length++)
|
||||
q++;
|
||||
while (alias_length--)
|
||||
@ -845,7 +855,8 @@ IndexScratch::IndexScratch(MemoryPool& p, thread_db* tdbb, index_desc* ix,
|
||||
// Multipling the selectivity with this cardinality gives the estimated
|
||||
// number of index pages that are read for the index retrieval.
|
||||
double factor = 0.5;
|
||||
if (segments.getCount() >= 2) {
|
||||
if (segments.getCount() >= 2)
|
||||
{
|
||||
// Compound indexes are generally less compressed.
|
||||
factor = 0.7;
|
||||
}
|
||||
@ -1046,7 +1057,8 @@ void OptimizerRetrieval::findDependentFromStreams(const jrd_nod* node,
|
||||
if (node->nod_type == nod_procedure)
|
||||
{
|
||||
const jrd_nod* const inputs = node->nod_arg[e_prc_inputs];
|
||||
if (inputs) {
|
||||
if (inputs)
|
||||
{
|
||||
fb_assert(inputs->nod_type == nod_asn_list);
|
||||
const jrd_nod* const* ptr = inputs->nod_arg;
|
||||
for (const jrd_nod* const* const end = ptr + inputs->nod_count; ptr < end; ptr++)
|
||||
@ -1174,7 +1186,8 @@ void OptimizerRetrieval::findDependentFromStreams(const jrd_nod* node,
|
||||
|
||||
const jrd_nod* const* ptr;
|
||||
const jrd_nod* const* end;
|
||||
for (ptr = rse->rse_relation, end = ptr + rse->rse_count; ptr < end; ptr++) {
|
||||
for (ptr = rse->rse_relation, end = ptr + rse->rse_count; ptr < end; ptr++)
|
||||
{
|
||||
if ((*ptr)->nod_type != nod_rse) {
|
||||
findDependentFromStreams(*ptr, streamList);
|
||||
}
|
||||
@ -1199,7 +1212,8 @@ VaryingString* OptimizerRetrieval::getAlias()
|
||||
* Functional description
|
||||
*
|
||||
**************************************/
|
||||
if (!alias) {
|
||||
if (!alias)
|
||||
{
|
||||
const CompilerScratch::csb_repeat* csb_tail = &csb->csb_rpt[this->stream];
|
||||
alias = OPT_make_alias(tdbb, csb, csb_tail);
|
||||
}
|
||||
@ -1234,7 +1248,8 @@ InversionCandidate* OptimizerRetrieval::generateInversion(RecordSource** rsb)
|
||||
if (outerFlag) {
|
||||
tail += optimizer->opt_base_parent_conjuncts;
|
||||
}
|
||||
for (; tail < opt_end; tail++) {
|
||||
for (; tail < opt_end; tail++)
|
||||
{
|
||||
if (tail->opt_conjunct_flags & opt_conjunct_matched) {
|
||||
continue;
|
||||
}
|
||||
@ -1256,7 +1271,8 @@ InversionCandidate* OptimizerRetrieval::generateInversion(RecordSource** rsb)
|
||||
if (outerFlag) {
|
||||
tail += optimizer->opt_base_parent_conjuncts;
|
||||
}
|
||||
for (; tail < opt_end; tail++) {
|
||||
for (; tail < opt_end; tail++)
|
||||
{
|
||||
if (tail->opt_conjunct_flags & opt_conjunct_matched) {
|
||||
continue;
|
||||
}
|
||||
@ -1264,7 +1280,8 @@ InversionCandidate* OptimizerRetrieval::generateInversion(RecordSource** rsb)
|
||||
if (!(tail->opt_conjunct_flags & opt_conjunct_used) && node && (node->nod_type == nod_or))
|
||||
{
|
||||
invCandidate = matchOnIndexes(&indexScratches, node, 1);
|
||||
if (invCandidate) {
|
||||
if (invCandidate)
|
||||
{
|
||||
invCandidate->boolean = node;
|
||||
inversions.add(invCandidate);
|
||||
}
|
||||
@ -1280,12 +1297,14 @@ InversionCandidate* OptimizerRetrieval::generateInversion(RecordSource** rsb)
|
||||
|
||||
if (invCandidate)
|
||||
{
|
||||
if (invCandidate->unique) {
|
||||
if (invCandidate->unique)
|
||||
{
|
||||
// Set up the unique retrieval cost to be fixed and not dependent on
|
||||
// possibly outdated statistics
|
||||
invCandidate->cost = DEFAULT_INDEX_COST * invCandidate->indexes + 1;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// Add the records retrieval cost to the priorly calculated index scan cost
|
||||
invCandidate->cost += csb->csb_rpt[stream].csb_cardinality * invCandidate->selectivity;
|
||||
}
|
||||
@ -1303,8 +1322,10 @@ InversionCandidate* OptimizerRetrieval::generateInversion(RecordSource** rsb)
|
||||
// However SortedArray class should be updated to handle join right!
|
||||
matches.join(invCandidate->matches);
|
||||
tail = optimizer->opt_conjuncts.begin();
|
||||
for (; tail < opt_end; tail++) {
|
||||
if (!(tail->opt_conjunct_flags & opt_conjunct_used)) {
|
||||
for (; tail < opt_end; tail++)
|
||||
{
|
||||
if (!(tail->opt_conjunct_flags & opt_conjunct_used))
|
||||
{
|
||||
if (matches.exist(tail->opt_conjunct_node)) {
|
||||
tail->opt_conjunct_flags |= opt_conjunct_matched;
|
||||
}
|
||||
@ -1346,7 +1367,8 @@ RecordSource* OptimizerRetrieval::generateNavigation()
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
for (; i < indexScratches.getCount(); ++i) {
|
||||
for (; i < indexScratches.getCount(); ++i)
|
||||
{
|
||||
|
||||
index_desc* idx = indexScratches[i].idx;
|
||||
|
||||
@ -1451,7 +1473,8 @@ RecordSource* OptimizerRetrieval::generateNavigation()
|
||||
}
|
||||
}
|
||||
|
||||
if (!usableIndex) {
|
||||
if (!usableIndex)
|
||||
{
|
||||
// We can't use this index, try next one.
|
||||
continue;
|
||||
}
|
||||
@ -1664,7 +1687,8 @@ void OptimizerRetrieval::getInversionCandidates(InversionCandidateList* inversio
|
||||
fb_assert(selectivity <= scratch.selectivity);
|
||||
scratch.selectivity = selectivity;
|
||||
|
||||
if (segment->scanType != segmentScanNone) {
|
||||
if (segment->scanType != segmentScanNone)
|
||||
{
|
||||
matches.join(segment->matches);
|
||||
scratch.nonFullMatchedSegments = scratch.idx->idx_count - j;
|
||||
}
|
||||
@ -1680,7 +1704,8 @@ void OptimizerRetrieval::getInversionCandidates(InversionCandidateList* inversio
|
||||
// For a non-unique one, assume 1/10 of the maximum selectivity, so that
|
||||
// at least some indexes could be chosen by the optimizer.
|
||||
double selectivity = scratch.selectivity;
|
||||
if (selectivity <= 0) {
|
||||
if (selectivity <= 0)
|
||||
{
|
||||
if (unique && cardinality)
|
||||
selectivity = 1 / cardinality;
|
||||
else
|
||||
@ -1703,7 +1728,8 @@ void OptimizerRetrieval::getInversionCandidates(InversionCandidateList* inversio
|
||||
invCandidate->indexes = 1;
|
||||
invCandidate->scratch = &scratch;
|
||||
invCandidate->matches.join(matches);
|
||||
for (size_t k = 0; k < invCandidate->matches.getCount(); k++) {
|
||||
for (size_t k = 0; k < invCandidate->matches.getCount(); k++)
|
||||
{
|
||||
findDependentFromStreams(invCandidate->matches[k],
|
||||
&invCandidate->dependentFromStreams);
|
||||
}
|
||||
@ -1779,7 +1805,8 @@ jrd_nod* OptimizerRetrieval::makeIndexScanNode(IndexScratch* indexScratch) const
|
||||
retrieval->irb_lower_count = indexScratch->lowerCount;
|
||||
retrieval->irb_upper_count = indexScratch->upperCount;
|
||||
|
||||
if (idx->idx_flags & idx_descending) {
|
||||
if (idx->idx_flags & idx_descending)
|
||||
{
|
||||
// switch upper/lower information
|
||||
upper = retrieval->irb_value;
|
||||
lower = retrieval->irb_value + idx->idx_count;
|
||||
@ -1793,13 +1820,15 @@ jrd_nod* OptimizerRetrieval::makeIndexScanNode(IndexScratch* indexScratch) const
|
||||
IndexScratchSegment** segment = indexScratch->segments.begin();
|
||||
for (i = 0; i < MAX(indexScratch->lowerCount, indexScratch->upperCount); i++)
|
||||
{
|
||||
if (segment[i]->scanType == segmentScanMissing) {
|
||||
if (segment[i]->scanType == segmentScanMissing)
|
||||
{
|
||||
jrd_nod* value = PAR_make_node(tdbb, 0);
|
||||
value->nod_type = nod_null;
|
||||
*lower++ = *upper++ = value;
|
||||
ignoreNullsOnScan = false;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
if (i < indexScratch->lowerCount) {
|
||||
*lower++ = segment[i]->lowerValue;
|
||||
}
|
||||
@ -1872,11 +1901,14 @@ jrd_nod* OptimizerRetrieval::makeIndexScanNode(IndexScratch* indexScratch) const
|
||||
}
|
||||
|
||||
// Check to see if this is really an equality retrieval
|
||||
if (retrieval->irb_lower_count == retrieval->irb_upper_count) {
|
||||
if (retrieval->irb_lower_count == retrieval->irb_upper_count)
|
||||
{
|
||||
retrieval->irb_generic |= irb_equality;
|
||||
segment = indexScratch->segments.begin();
|
||||
for (i = 0; i < retrieval->irb_lower_count; i++) {
|
||||
if (segment[i]->lowerValue != segment[i]->upperValue) {
|
||||
for (i = 0; i < retrieval->irb_lower_count; i++)
|
||||
{
|
||||
if (segment[i]->lowerValue != segment[i]->upperValue)
|
||||
{
|
||||
retrieval->irb_generic &= ~irb_equality;
|
||||
break;
|
||||
}
|
||||
@ -1884,12 +1916,14 @@ jrd_nod* OptimizerRetrieval::makeIndexScanNode(IndexScratch* indexScratch) const
|
||||
}
|
||||
|
||||
// If we are matching less than the full index, this is a partial match
|
||||
if (idx->idx_flags & idx_descending) {
|
||||
if (idx->idx_flags & idx_descending)
|
||||
{
|
||||
if (retrieval->irb_lower_count < idx->idx_count) {
|
||||
retrieval->irb_generic |= irb_partial;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
if (retrieval->irb_upper_count < idx->idx_count) {
|
||||
retrieval->irb_generic |= irb_partial;
|
||||
}
|
||||
@ -1960,9 +1994,11 @@ InversionCandidate* OptimizerRetrieval::makeInversion(InversionCandidateList* in
|
||||
size_t i = 0;
|
||||
InversionCandidate* invCandidate = NULL;
|
||||
InversionCandidate** inversion = inversions->begin();
|
||||
for (i = 0; i < inversions->getCount(); i++) {
|
||||
for (i = 0; i < inversions->getCount(); i++)
|
||||
{
|
||||
inversion[i]->used = false;
|
||||
if (inversion[i]->scratch) {
|
||||
if (inversion[i]->scratch)
|
||||
{
|
||||
if (inversion[i]->scratch->idx->idx_runtime_flags & idx_plan_dont_use) {
|
||||
inversion[i]->used = true;
|
||||
}
|
||||
@ -2005,7 +2041,8 @@ InversionCandidate* OptimizerRetrieval::makeInversion(InversionCandidateList* in
|
||||
invCandidate->matchedSegments = currentInv->matchedSegments;
|
||||
invCandidate->dependencies = currentInv->dependencies;
|
||||
matches.clear();
|
||||
for (size_t j = 0; j < currentInv->matches.getCount(); j++) {
|
||||
for (size_t j = 0; j < currentInv->matches.getCount(); j++)
|
||||
{
|
||||
if (!matches.exist(currentInv->matches[j])) {
|
||||
matches.add(currentInv->matches[j]);
|
||||
}
|
||||
@ -2020,18 +2057,22 @@ InversionCandidate* OptimizerRetrieval::makeInversion(InversionCandidateList* in
|
||||
|
||||
// Look if a match is already used by previous matches.
|
||||
bool anyMatchAlreadyUsed = false;
|
||||
for (size_t k = 0; k < currentInv->matches.getCount(); k++) {
|
||||
if (matches.exist(currentInv->matches[k])) {
|
||||
for (size_t k = 0; k < currentInv->matches.getCount(); k++)
|
||||
{
|
||||
if (matches.exist(currentInv->matches[k]))
|
||||
{
|
||||
anyMatchAlreadyUsed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyMatchAlreadyUsed && !acceptAll) {
|
||||
if (anyMatchAlreadyUsed && !acceptAll)
|
||||
{
|
||||
currentInv->used = true;
|
||||
// If a match on this index was already used by another
|
||||
// index, add also the other matches from this index.
|
||||
for (size_t j = 0; j < currentInv->matches.getCount(); j++) {
|
||||
for (size_t j = 0; j < currentInv->matches.getCount(); j++)
|
||||
{
|
||||
if (!matches.exist(currentInv->matches[j])) {
|
||||
matches.add(currentInv->matches[j]);
|
||||
}
|
||||
@ -2041,13 +2082,15 @@ InversionCandidate* OptimizerRetrieval::makeInversion(InversionCandidateList* in
|
||||
break;
|
||||
}
|
||||
|
||||
if (!bestCandidate) {
|
||||
if (!bestCandidate)
|
||||
{
|
||||
// The first candidate
|
||||
bestCandidate = currentInv;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentInv->unique && !bestCandidate->unique) {
|
||||
if (currentInv->unique && !bestCandidate->unique)
|
||||
{
|
||||
// A unique full equal match is better than anything else.
|
||||
bestCandidate = currentInv;
|
||||
}
|
||||
@ -2074,12 +2117,14 @@ InversionCandidate* OptimizerRetrieval::makeInversion(InversionCandidateList* in
|
||||
|
||||
// Do we have very similar costs?
|
||||
double diffCost = currentCandidateCost;
|
||||
if (!diffCost && !bestCandidateCost) {
|
||||
if (!diffCost && !bestCandidateCost)
|
||||
{
|
||||
// Two zero costs should be handled as being the same
|
||||
// (other comparison criterias should be applied, see below).
|
||||
diffCost = 1;
|
||||
}
|
||||
else if (diffCost) {
|
||||
else if (diffCost)
|
||||
{
|
||||
// Calculate the difference.
|
||||
diffCost = bestCandidateCost / diffCost;
|
||||
}
|
||||
@ -2092,12 +2137,14 @@ InversionCandidate* OptimizerRetrieval::makeInversion(InversionCandidateList* in
|
||||
// If the "same" costs then compare with the nr of unmatched segments,
|
||||
// how many indexes and matched segments. First compare number of indexes.
|
||||
int compareSelectivity = (currentInv->indexes - bestCandidate->indexes);
|
||||
if (compareSelectivity == 0) {
|
||||
if (compareSelectivity == 0)
|
||||
{
|
||||
// For the same number of indexes compare number of matched segments.
|
||||
// Note the inverted condition: the more matched segments the better.
|
||||
compareSelectivity =
|
||||
(bestCandidate->matchedSegments - currentInv->matchedSegments);
|
||||
if (compareSelectivity == 0) {
|
||||
if (compareSelectivity == 0)
|
||||
{
|
||||
// For the same number of matched segments
|
||||
// compare ones that aren't full matched
|
||||
compareSelectivity =
|
||||
@ -2108,7 +2155,8 @@ InversionCandidate* OptimizerRetrieval::makeInversion(InversionCandidateList* in
|
||||
bestCandidate = currentInv;
|
||||
}
|
||||
}
|
||||
else if (currentCandidateCost < bestCandidateCost) {
|
||||
else if (currentCandidateCost < bestCandidateCost)
|
||||
{
|
||||
// How lower the cost the better.
|
||||
bestCandidate = currentInv;
|
||||
}
|
||||
@ -2146,7 +2194,8 @@ InversionCandidate* OptimizerRetrieval::makeInversion(InversionCandidateList* in
|
||||
double newTotalSelectivity = 0;
|
||||
double bestSel = bestCandidate->selectivity;
|
||||
double worstSel = totalSelectivity;
|
||||
if (bestCandidate->selectivity > totalSelectivity) {
|
||||
if (bestCandidate->selectivity > totalSelectivity)
|
||||
{
|
||||
worstSel = bestCandidate->selectivity;
|
||||
bestSel = totalSelectivity;
|
||||
}
|
||||
@ -2197,12 +2246,14 @@ InversionCandidate* OptimizerRetrieval::makeInversion(InversionCandidateList* in
|
||||
invCandidate->nonFullMatchedSegments = 0;
|
||||
invCandidate->matchedSegments = bestCandidate->matchedSegments;
|
||||
invCandidate->dependencies = bestCandidate->dependencies;
|
||||
for (size_t j = 0; j < bestCandidate->matches.getCount(); j++) {
|
||||
for (size_t j = 0; j < bestCandidate->matches.getCount(); j++)
|
||||
{
|
||||
if (!matches.exist(bestCandidate->matches[j])) {
|
||||
matches.add(bestCandidate->matches[j]);
|
||||
}
|
||||
}
|
||||
if (bestCandidate->boolean) {
|
||||
if (bestCandidate->boolean)
|
||||
{
|
||||
if (!matches.exist(bestCandidate->boolean)) {
|
||||
matches.add(bestCandidate->boolean);
|
||||
}
|
||||
@ -2210,11 +2261,13 @@ InversionCandidate* OptimizerRetrieval::makeInversion(InversionCandidateList* in
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!bestCandidate->inversion && bestCandidate->scratch) {
|
||||
if (!bestCandidate->inversion && bestCandidate->scratch)
|
||||
{
|
||||
invCandidate->inversion = composeInversion(invCandidate->inversion,
|
||||
makeIndexScanNode(bestCandidate->scratch), nod_bit_and);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
invCandidate->inversion = composeInversion(invCandidate->inversion,
|
||||
bestCandidate->inversion, nod_bit_and);
|
||||
}
|
||||
@ -2226,24 +2279,28 @@ InversionCandidate* OptimizerRetrieval::makeInversion(InversionCandidateList* in
|
||||
invCandidate->matchedSegments =
|
||||
MAX(bestCandidate->matchedSegments, invCandidate->matchedSegments);
|
||||
invCandidate->dependencies += bestCandidate->dependencies;
|
||||
for (size_t j = 0; j < bestCandidate->matches.getCount(); j++) {
|
||||
for (size_t j = 0; j < bestCandidate->matches.getCount(); j++)
|
||||
{
|
||||
if (!matches.exist(bestCandidate->matches[j])) {
|
||||
matches.add(bestCandidate->matches[j]);
|
||||
}
|
||||
}
|
||||
if (bestCandidate->boolean) {
|
||||
if (bestCandidate->boolean)
|
||||
{
|
||||
if (!matches.exist(bestCandidate->boolean)) {
|
||||
matches.add(bestCandidate->boolean);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (invCandidate->unique) {
|
||||
if (invCandidate->unique)
|
||||
{
|
||||
// Single unique full equal match is enough
|
||||
if (!acceptAll)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// We're done
|
||||
break;
|
||||
}
|
||||
@ -2400,7 +2457,8 @@ bool OptimizerRetrieval::matchBoolean(IndexScratch* indexScratch, jrd_nod* boole
|
||||
segment[i]->matches.add(boolean);
|
||||
// AB: If we have already an exact match don't
|
||||
// override it with worser matches.
|
||||
if (!(segment[i]->scanType == segmentScanEqual)) {
|
||||
if (!(segment[i]->scanType == segmentScanEqual))
|
||||
{
|
||||
segment[i]->lowerValue = segment[i]->upperValue = value;
|
||||
segment[i]->scanType = segmentScanEquivalent;
|
||||
segment[i]->excludeLower = false;
|
||||
@ -2519,7 +2577,8 @@ bool OptimizerRetrieval::matchBoolean(IndexScratch* indexScratch, jrd_nod* boole
|
||||
|
||||
++count;
|
||||
|
||||
if (i == 0) {
|
||||
if (i == 0)
|
||||
{
|
||||
// If this is the first segment, then this index is a candidate.
|
||||
indexScratch->candidate = true;
|
||||
}
|
||||
@ -2559,7 +2618,8 @@ InversionCandidate* OptimizerRetrieval::matchOnIndexes(
|
||||
|
||||
// Copy information from caller
|
||||
size_t i = 0;
|
||||
for (; i < inputIndexScratches->getCount(); i++) {
|
||||
for (; i < inputIndexScratches->getCount(); i++)
|
||||
{
|
||||
IndexScratch& scratch = (*inputIndexScratches)[i];
|
||||
indexOrScratches.add(scratch);
|
||||
}
|
||||
@ -2586,7 +2646,8 @@ InversionCandidate* OptimizerRetrieval::matchOnIndexes(
|
||||
indexOrScratches.clear();
|
||||
// Copy information from caller
|
||||
i = 0;
|
||||
for (; i < inputIndexScratches->getCount(); i++) {
|
||||
for (; i < inputIndexScratches->getCount(); i++)
|
||||
{
|
||||
IndexScratch& scratch = (*inputIndexScratches)[i];
|
||||
indexOrScratches.add(scratch);
|
||||
}
|
||||
@ -2658,7 +2719,8 @@ InversionCandidate* OptimizerRetrieval::matchOnIndexes(
|
||||
}
|
||||
|
||||
// Walk through indexes
|
||||
for (size_t i = 0; i < inputIndexScratches->getCount(); i++) {
|
||||
for (size_t i = 0; i < inputIndexScratches->getCount(); i++)
|
||||
{
|
||||
IndexScratch& indexScratch = (*inputIndexScratches)[i];
|
||||
// Try to match the boolean against a index.
|
||||
if (!(indexScratch.idx->idx_runtime_flags & idx_plan_dont_use) ||
|
||||
@ -2695,7 +2757,8 @@ void OptimizerRetrieval::printCandidate(const InversionCandidate* candidate) con
|
||||
if (depFromCount >= 1)
|
||||
{
|
||||
fprintf(opt_debug_file, ", dependent from ");
|
||||
for (int i = 0; i < depFromCount; i++) {
|
||||
for (int i = 0; i < depFromCount; i++)
|
||||
{
|
||||
if (i == 0) {
|
||||
fprintf(opt_debug_file, "%d", candidate->dependentFromStreams[i]);
|
||||
}
|
||||
@ -2724,7 +2787,8 @@ void OptimizerRetrieval::printCandidates(const InversionCandidateList* inversion
|
||||
fprintf(opt_debug_file, " retrieval candidates:\n");
|
||||
fclose(opt_debug_file);
|
||||
const InversionCandidate* const* inversion = inversions->begin();
|
||||
for (int i = 0; i < inversions->getCount(); i++) {
|
||||
for (int i = 0; i < inversions->getCount(); i++)
|
||||
{
|
||||
const InversionCandidate* candidate = inversion[i];
|
||||
printCandidate(candidate);
|
||||
}
|
||||
@ -2742,7 +2806,8 @@ void OptimizerRetrieval::printFinalCandidate(const InversionCandidate* candidate
|
||||
*
|
||||
**************************************/
|
||||
|
||||
if (candidate) {
|
||||
if (candidate)
|
||||
{
|
||||
FILE *opt_debug_file = fopen(OPTIMIZER_DEBUG_FILE, "a");
|
||||
fprintf(opt_debug_file, " final candidate: ");
|
||||
fclose(opt_debug_file);
|
||||
@ -2814,7 +2879,8 @@ bool OptimizerRetrieval::validateStarts(IndexScratch* indexScratch,
|
||||
|
||||
// Every string starts with an empty string so
|
||||
// don't bother using an index in that case.
|
||||
if (value->nod_type == nod_literal) {
|
||||
if (value->nod_type == nod_literal)
|
||||
{
|
||||
const dsc* literal_desc = &((Literal*) value)->lit_desc;
|
||||
if ((literal_desc->dsc_dtype == dtype_text && literal_desc->dsc_length == 0) ||
|
||||
(literal_desc->dsc_dtype == dtype_varying &&
|
||||
@ -2895,8 +2961,7 @@ bool InnerJoinStreamInfo::independent() const
|
||||
* streams.
|
||||
*
|
||||
**************************************/
|
||||
return (indexedRelationships.getCount() == 0) &&
|
||||
(previousExpectedStreams == 0);
|
||||
return (indexedRelationships.getCount() == 0) && (previousExpectedStreams == 0);
|
||||
}
|
||||
|
||||
|
||||
@ -2926,7 +2991,8 @@ OptimizerInnerJoin::OptimizerInnerJoin(MemoryPool& p, OptimizerBlk* opt, const U
|
||||
|
||||
innerStreams.grow(streams[0]);
|
||||
InnerJoinStreamInfo** innerStream = innerStreams.begin();
|
||||
for (size_t i = 0; i < innerStreams.getCount(); i++) {
|
||||
for (size_t i = 0; i < innerStreams.getCount(); i++)
|
||||
{
|
||||
innerStream[i] = FB_NEW(p) InnerJoinStreamInfo(p);
|
||||
innerStream[i]->stream = streams[i + 1];
|
||||
}
|
||||
@ -2947,7 +3013,8 @@ OptimizerInnerJoin::~OptimizerInnerJoin()
|
||||
*
|
||||
**************************************/
|
||||
|
||||
for (size_t i = 0; i < innerStreams.getCount(); i++) {
|
||||
for (size_t i = 0; i < innerStreams.getCount(); i++)
|
||||
{
|
||||
for (size_t j = 0; j < innerStreams[i]->indexedRelationships.getCount(); j++) {
|
||||
delete innerStreams[i]->indexedRelationships[j];
|
||||
}
|
||||
@ -2969,10 +3036,12 @@ void OptimizerInnerJoin::calculateCardinalities()
|
||||
*
|
||||
**************************************/
|
||||
|
||||
for (size_t i = 0; i < innerStreams.getCount(); i++) {
|
||||
for (size_t i = 0; i < innerStreams.getCount(); i++)
|
||||
{
|
||||
CompilerScratch::csb_repeat* csb_tail = &csb->csb_rpt[innerStreams[i]->stream];
|
||||
fb_assert(csb_tail);
|
||||
if (!csb_tail->csb_cardinality) {
|
||||
if (!csb_tail->csb_cardinality)
|
||||
{
|
||||
jrd_rel* relation = csb_tail->csb_relation;
|
||||
fb_assert(relation);
|
||||
const Format* format = CMP_format(tdbb, csb, (USHORT)innerStreams[i]->stream);
|
||||
@ -3022,7 +3091,8 @@ void OptimizerInnerJoin::calculateStreamInfo()
|
||||
|
||||
// Find streams that have a indexed relationship to this
|
||||
// stream and add the information.
|
||||
for (size_t j = 0; j < innerStreams.getCount(); j++) {
|
||||
for (size_t j = 0; j < innerStreams.getCount(); j++)
|
||||
{
|
||||
if (innerStreams[j]->stream != innerStreams[i]->stream) {
|
||||
getIndexedRelationship(innerStreams[i], innerStreams[j]);
|
||||
}
|
||||
@ -3040,7 +3110,8 @@ void OptimizerInnerJoin::calculateStreamInfo()
|
||||
for (i = 0; i < innerStreams.getCount(); i++)
|
||||
{
|
||||
size_t index = 0;
|
||||
for (; index < tempStreams.getCount(); index++) {
|
||||
for (; index < tempStreams.getCount(); index++)
|
||||
{
|
||||
// First those streams which can't be used by other streams
|
||||
// or can't depend on a stream.
|
||||
if (innerStreams[i]->independent() && !tempStreams[index]->independent()) {
|
||||
@ -3052,7 +3123,8 @@ void OptimizerInnerJoin::calculateStreamInfo()
|
||||
if (compare < 0) {
|
||||
break;
|
||||
}
|
||||
if (compare == 0) {
|
||||
if (compare == 0)
|
||||
{
|
||||
// Next those with the cheapest base cost
|
||||
if (innerStreams[i]->baseCost < tempStreams[index]->baseCost) {
|
||||
break;
|
||||
@ -3089,7 +3161,8 @@ bool OptimizerInnerJoin::cheaperRelationship(IndexRelationship* checkRelationshi
|
||||
}
|
||||
|
||||
const double compareValue = checkRelationship->cost / withRelationship->cost;
|
||||
if (compareValue >= 0.98 && compareValue <= 1.02) {
|
||||
if (compareValue >= 0.98 && compareValue <= 1.02)
|
||||
{
|
||||
// cost is nearly the same, now check on cardinality
|
||||
if (checkRelationship->cardinality < withRelationship->cardinality) {
|
||||
return true;
|
||||
@ -3176,9 +3249,11 @@ int OptimizerInnerJoin::findJoinOrder()
|
||||
remainingStreams = 0;
|
||||
for (i = 0; i < innerStreams.getCount(); i++)
|
||||
{
|
||||
if (!innerStreams[i]->used) {
|
||||
if (!innerStreams[i]->used)
|
||||
{
|
||||
remainingStreams++;
|
||||
if (innerStreams[i]->independent()) {
|
||||
if (innerStreams[i]->independent())
|
||||
{
|
||||
if (!optimizer->opt_best_count || innerStreams[i]->baseCost < optimizer->opt_best_cost)
|
||||
{
|
||||
optimizer->opt_streams[0].opt_best_stream = innerStreams[i]->stream;
|
||||
@ -3192,12 +3267,15 @@ int OptimizerInnerJoin::findJoinOrder()
|
||||
if (optimizer->opt_best_count == 0)
|
||||
{
|
||||
IndexedRelationships indexedRelationships(pool);
|
||||
for (i = 0; i < innerStreams.getCount(); i++) {
|
||||
if (!innerStreams[i]->used) {
|
||||
for (i = 0; i < innerStreams.getCount(); i++)
|
||||
{
|
||||
if (!innerStreams[i]->used)
|
||||
{
|
||||
indexedRelationships.clear();
|
||||
findBestOrder(0, innerStreams[i], &indexedRelationships, (double) 0, (double) 1);
|
||||
|
||||
if (plan) {
|
||||
if (plan)
|
||||
{
|
||||
// If a explicit PLAN was specified we should be ready;
|
||||
break;
|
||||
}
|
||||
@ -3210,7 +3288,8 @@ int OptimizerInnerJoin::findJoinOrder()
|
||||
}
|
||||
|
||||
// Mark streams as used
|
||||
for (int stream = 0; stream < optimizer->opt_best_count; stream++) {
|
||||
for (int stream = 0; stream < optimizer->opt_best_count; stream++)
|
||||
{
|
||||
InnerJoinStreamInfo* streamInfo = getStreamInfo(optimizer->opt_streams[stream].opt_best_stream);
|
||||
streamInfo->used = true;
|
||||
}
|
||||
@ -3260,7 +3339,8 @@ void OptimizerInnerJoin::findBestOrder(int position, InnerJoinStreamInfo* stream
|
||||
// Compute delta and total estimate cost to fetch this stream.
|
||||
double position_cost, position_cardinality, new_cost = 0, new_cardinality = 0;
|
||||
|
||||
if (!plan) {
|
||||
if (!plan)
|
||||
{
|
||||
estimateCost(stream->stream, &position_cost, &position_cardinality);
|
||||
new_cost = cost + cardinality * position_cost;
|
||||
new_cardinality = position_cardinality * cardinality;
|
||||
@ -3312,11 +3392,14 @@ void OptimizerInnerJoin::findBestOrder(int position, InnerJoinStreamInfo* stream
|
||||
bool found = false;
|
||||
IndexRelationship** processRelationship = processList->begin();
|
||||
size_t index;
|
||||
for (index = 0; index < processList->getCount(); index++) {
|
||||
if (relationStreamInfo->stream == processRelationship[index]->stream) {
|
||||
for (index = 0; index < processList->getCount(); index++)
|
||||
{
|
||||
if (relationStreamInfo->stream == processRelationship[index]->stream)
|
||||
{
|
||||
// If the cost of this relationship is cheaper then remove the
|
||||
// old relationship and add this one.
|
||||
if (cheaperRelationship(relationship, processRelationship[index])) {
|
||||
if (cheaperRelationship(relationship, processRelationship[index]))
|
||||
{
|
||||
processList->remove(index);
|
||||
break;
|
||||
}
|
||||
@ -3325,10 +3408,12 @@ void OptimizerInnerJoin::findBestOrder(int position, InnerJoinStreamInfo* stream
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (!found)
|
||||
{
|
||||
// Add relationship sorted on cost (cheapest as first)
|
||||
IndexRelationship** relationships = processList->begin();
|
||||
for (index = 0; index < processList->getCount(); index++) {
|
||||
for (index = 0; index < processList->getCount(); index++)
|
||||
{
|
||||
if (cheaperRelationship(relationship, relationships[index])) {
|
||||
break;
|
||||
}
|
||||
@ -3339,22 +3424,27 @@ void OptimizerInnerJoin::findBestOrder(int position, InnerJoinStreamInfo* stream
|
||||
}
|
||||
|
||||
IndexRelationship** nextRelationship = processList->begin();
|
||||
for (size_t j = 0; j < processList->getCount(); j++) {
|
||||
for (size_t j = 0; j < processList->getCount(); j++)
|
||||
{
|
||||
InnerJoinStreamInfo* relationStreamInfo = getStreamInfo(nextRelationship[j]->stream);
|
||||
if (!relationStreamInfo->used) {
|
||||
if (!relationStreamInfo->used)
|
||||
{
|
||||
findBestOrder(position, relationStreamInfo, processList, new_cost, new_cardinality);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plan) {
|
||||
if (plan)
|
||||
{
|
||||
// If a explicit PLAN was specific pick the next relation.
|
||||
// The order in innerStreams is expected to be exactly the order as
|
||||
// specified in the explicit PLAN.
|
||||
for (size_t j = 0; j < innerStreams.getCount(); j++) {
|
||||
for (size_t j = 0; j < innerStreams.getCount(); j++)
|
||||
{
|
||||
InnerJoinStreamInfo* nextStream = innerStreams[j];
|
||||
if (!nextStream->used) {
|
||||
if (!nextStream->used)
|
||||
{
|
||||
findBestOrder(position, nextStream, processList, new_cost, new_cardinality);
|
||||
break;
|
||||
}
|
||||
@ -3408,7 +3498,8 @@ void OptimizerInnerJoin::getIndexedRelationship(InnerJoinStreamInfo* baseStream,
|
||||
// indexRelationship are kept sorted on cost and unique in the indexRelations array.
|
||||
// The unique and cheapest indexed relatioships are on the first position.
|
||||
size_t index = 0;
|
||||
for (; index < baseStream->indexedRelationships.getCount(); index++) {
|
||||
for (; index < baseStream->indexedRelationships.getCount(); index++)
|
||||
{
|
||||
if (cheaperRelationship(indexRelationship, baseStream->indexedRelationships[index])) {
|
||||
break;
|
||||
}
|
||||
@ -3435,7 +3526,8 @@ InnerJoinStreamInfo* OptimizerInnerJoin::getStreamInfo(int stream)
|
||||
*
|
||||
**************************************/
|
||||
|
||||
for (size_t i = 0; i < innerStreams.getCount(); i++) {
|
||||
for (size_t i = 0; i < innerStreams.getCount(); i++)
|
||||
{
|
||||
if (innerStreams[i]->stream == stream) {
|
||||
return innerStreams[i];
|
||||
}
|
||||
@ -3461,7 +3553,8 @@ void OptimizerInnerJoin::printBestOrder() const
|
||||
|
||||
FILE *opt_debug_file = fopen(OPTIMIZER_DEBUG_FILE, "a");
|
||||
fprintf(opt_debug_file, " best order, streams: ");
|
||||
for (int i = 0; i < optimizer->opt_best_count; i++) {
|
||||
for (int i = 0; i < optimizer->opt_best_count; i++)
|
||||
{
|
||||
if (i == 0) {
|
||||
fprintf(opt_debug_file, "%d", optimizer->opt_streams[i].opt_best_stream);
|
||||
}
|
||||
@ -3494,7 +3587,8 @@ void OptimizerInnerJoin::printFoundOrder(int position, double positionCost,
|
||||
fprintf(opt_debug_file, ", streams: ", position);
|
||||
const OptimizerBlk::opt_stream* tail = optimizer->opt_streams.begin();
|
||||
const OptimizerBlk::opt_stream* const order_end = tail + position;
|
||||
for (; tail < order_end; tail++) {
|
||||
for (; tail < order_end; tail++)
|
||||
{
|
||||
if (tail == optimizer->opt_streams.begin()) {
|
||||
fprintf(opt_debug_file, "%d", tail->opt_stream_number);
|
||||
}
|
||||
@ -3544,7 +3638,8 @@ void OptimizerInnerJoin::printStartOrder() const
|
||||
FILE *opt_debug_file = fopen(OPTIMIZER_DEBUG_FILE, "a");
|
||||
fprintf(opt_debug_file, "Start join order: with stream(baseCost)");
|
||||
bool firstStream = true;
|
||||
for (int i = 0; i < innerStreams.getCount(); i++) {
|
||||
for (int i = 0; i < innerStreams.getCount(); i++)
|
||||
{
|
||||
if (!innerStreams[i]->used) {
|
||||
fprintf(opt_debug_file, ", %d (%1.2f)", innerStreams[i]->stream, innerStreams[i]->baseCost);
|
||||
}
|
||||
|
@ -116,6 +116,7 @@ void IDX_check_access(thread_db* tdbb, CompilerScratch* csb, jrd_rel* view, jrd_
|
||||
WIN referenced_window(relPages->rel_pg_space_id, -1);
|
||||
|
||||
while (BTR_next_index(tdbb, relation, 0, &idx, &window))
|
||||
{
|
||||
if (idx.idx_flags & idx_foreign)
|
||||
{
|
||||
/* find the corresponding primary key index */
|
||||
@ -161,6 +162,7 @@ void IDX_check_access(thread_db* tdbb, CompilerScratch* csb, jrd_rel* view, jrd_
|
||||
CCH_RELEASE(tdbb, &referenced_window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool IDX_check_master_types (thread_db* tdbb, index_desc& idx, jrd_rel* partner_relation, int& bad_segment)
|
||||
@ -514,7 +516,8 @@ void IDX_create_index(thread_db* tdbb,
|
||||
|
||||
BTR_create(tdbb, relation, idx, key_length, sort_handle, selectivity);
|
||||
|
||||
if (ifl_data.ifl_duplicates > 0) {
|
||||
if (ifl_data.ifl_duplicates > 0)
|
||||
{
|
||||
// we don't need SORT_fini() here, as it's called inside BTR_create()
|
||||
ERR_post(Arg::Gds(isc_no_dup) << Arg::Str(index_name));
|
||||
}
|
||||
@ -1118,14 +1121,16 @@ static idx_e check_duplicates(thread_db* tdbb,
|
||||
|
||||
if (is_fk)
|
||||
{
|
||||
if (equal_cur && equal_old) {
|
||||
if (equal_cur && equal_old)
|
||||
{
|
||||
result = idx_e_duplicate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (equal_cur || equal_old) {
|
||||
if (equal_cur || equal_old)
|
||||
{
|
||||
result = idx_e_duplicate;
|
||||
break;
|
||||
}
|
||||
@ -1729,7 +1734,8 @@ static void signal_index_deletion(thread_db* tdbb, jrd_rel* relation, USHORT id)
|
||||
|
||||
/* if one didn't exist, create it */
|
||||
|
||||
if (!index_block) {
|
||||
if (!index_block)
|
||||
{
|
||||
index_block = IDX_create_index_block(tdbb, relation, id);
|
||||
lock = index_block->idb_lock;
|
||||
}
|
||||
|
@ -208,7 +208,8 @@ CharSetContainer* CharSetContainer::lookupCharset(thread_db* tdbb, USHORT ttype)
|
||||
cs = dbb->dbb_charsets[id];
|
||||
|
||||
// allocate a new character set object if we couldn't find one.
|
||||
if (!cs) {
|
||||
if (!cs)
|
||||
{
|
||||
SubtypeInfo info;
|
||||
|
||||
if (id == CS_UTF16)
|
||||
@ -536,11 +537,14 @@ int INTL_compare(thread_db* tdbb,
|
||||
USHORT compare_type = MAX(t1, t2); /* YYY */
|
||||
UCHAR buffer[MAX_KEY];
|
||||
|
||||
if (t1 != t2) {
|
||||
if (t1 != t2)
|
||||
{
|
||||
CHARSET_ID cs1 = INTL_charset(tdbb, t1);
|
||||
CHARSET_ID cs2 = INTL_charset(tdbb, t2);
|
||||
if (cs1 != cs2) {
|
||||
if (compare_type != t2) {
|
||||
if (cs1 != cs2)
|
||||
{
|
||||
if (compare_type != t2)
|
||||
{
|
||||
/* convert pText2 to pText1's type, if possible */
|
||||
/* YYY - should failure to convert really return
|
||||
an error here?
|
||||
@ -554,7 +558,8 @@ int INTL_compare(thread_db* tdbb,
|
||||
length2 = INTL_convert_bytes(tdbb, cs1, buffer, sizeof(buffer), cs2, p2, length2, err);
|
||||
p2 = buffer;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/* convert pText1 to pText2's type, if possible */
|
||||
|
||||
length1 = INTL_convert_bytes(tdbb, cs2, buffer, sizeof(buffer), cs1, p1, length1, err);
|
||||
@ -744,7 +749,8 @@ int INTL_convert_string(dsc* to, const dsc* from, ErrorFunction err)
|
||||
from_fill = 0; /* Convert_bytes handles source truncation */
|
||||
p += to_len;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/* binary string can always be converted TO by byte-copy */
|
||||
|
||||
ULONG to_len = MIN(from_len, to_size);
|
||||
@ -775,7 +781,8 @@ int INTL_convert_string(dsc* to, const dsc* from, ErrorFunction err)
|
||||
to->dsc_address[to_len] = 0;
|
||||
from_fill = 0; /* Convert_bytes handles source truncation */
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/* binary string can always be converted TO by byte-copy */
|
||||
|
||||
ULONG to_len = MIN(from_len, to_size);
|
||||
@ -805,7 +812,8 @@ int INTL_convert_string(dsc* to, const dsc* from, ErrorFunction err)
|
||||
((vary*) to->dsc_address)->vary_length = to_len;
|
||||
from_fill = 0; /* Convert_bytes handles source truncation */
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/* binary string can always be converted TO by byte-copy */
|
||||
ULONG to_len = MIN(from_len, to_size);
|
||||
if (!toCharSet->wellFormed(to_len, q))
|
||||
@ -945,7 +953,8 @@ USHORT INTL_key_length(thread_db* tdbb, USHORT idxType, USHORT iLength)
|
||||
USHORT key_length;
|
||||
if (ttype <= ttype_last_internal)
|
||||
key_length = iLength;
|
||||
else {
|
||||
else
|
||||
{
|
||||
TextType* obj = INTL_texttype_lookup(tdbb, ttype);
|
||||
key_length = obj->key_length(iLength);
|
||||
}
|
||||
@ -1216,22 +1225,27 @@ static bool all_spaces(thread_db* tdbb,
|
||||
|
||||
// Single-octet character sets are optimized here
|
||||
|
||||
if (obj->getSpaceLength() == 1) {
|
||||
if (obj->getSpaceLength() == 1)
|
||||
{
|
||||
const BYTE* p = &ptr[offset];
|
||||
const BYTE* const end = &ptr[len];
|
||||
while (p < end) {
|
||||
while (p < end)
|
||||
{
|
||||
if (*p++ != *obj->getSpace())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
const BYTE* p = &ptr[offset];
|
||||
const BYTE* const end = &ptr[len];
|
||||
const unsigned char* space = obj->getSpace();
|
||||
const unsigned char* const end_space = &space[obj->getSpaceLength()];
|
||||
while (p < end) {
|
||||
while (p < end)
|
||||
{
|
||||
space = obj->getSpace();
|
||||
while (p < end && space < end_space) {
|
||||
while (p < end && space < end_space)
|
||||
{
|
||||
if (*p++ != *space++)
|
||||
return false;
|
||||
}
|
||||
@ -1303,16 +1317,19 @@ static void pad_spaces(thread_db* tdbb, CHARSET_ID charset, BYTE* ptr, ULONG len
|
||||
CharSet* obj = INTL_charset_lookup(tdbb, charset);
|
||||
|
||||
/* Single-octet character sets are optimized here */
|
||||
if (obj->getSpaceLength() == 1) {
|
||||
if (obj->getSpaceLength() == 1)
|
||||
{
|
||||
const BYTE* const end = &ptr[len];
|
||||
while (ptr < end)
|
||||
*ptr++ = *obj->getSpace();
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
const BYTE* const end = &ptr[len];
|
||||
const UCHAR* space = obj->getSpace();
|
||||
const UCHAR* const end_space = &space[obj->getSpaceLength()];
|
||||
while (ptr < end) {
|
||||
while (ptr < end)
|
||||
{
|
||||
space = obj->getSpace();
|
||||
while (ptr < end && space < end_space) {
|
||||
*ptr++ = *space++;
|
||||
|
@ -119,9 +119,11 @@ static fss_size_t fss_mbtowc(fss_wchar_t* p, const UCHAR* s, fss_size_t n)
|
||||
return -1;
|
||||
const int c0 = *s & 0xff;
|
||||
SLONG l = c0;
|
||||
for (const Byte_Mask_Table* t = tab; t->cmask; t++) {
|
||||
for (const Byte_Mask_Table* t = tab; t->cmask; t++)
|
||||
{
|
||||
nc++;
|
||||
if ((c0 & t->cmask) == t->cval) {
|
||||
if ((c0 & t->cmask) == t->cval)
|
||||
{
|
||||
l &= t->lmask;
|
||||
if (l < t->lval)
|
||||
return -1;
|
||||
@ -146,12 +148,15 @@ static fss_size_t fss_wctomb(UCHAR * s, fss_wchar_t wc)
|
||||
|
||||
SLONG l = wc;
|
||||
int nc = 0;
|
||||
for (const Byte_Mask_Table* t = tab; t->cmask; t++) {
|
||||
for (const Byte_Mask_Table* t = tab; t->cmask; t++)
|
||||
{
|
||||
nc++;
|
||||
if (l <= t->lmask) {
|
||||
if (l <= t->lmask)
|
||||
{
|
||||
int c = t->shift;
|
||||
*s = t->cval | (l >> c);
|
||||
while (c > 0) {
|
||||
while (c > 0)
|
||||
{
|
||||
c -= 6;
|
||||
s++;
|
||||
*s = 0x80 | ((l >> c) & 0x3F);
|
||||
@ -216,9 +221,11 @@ static ULONG internal_fss_to_unicode(csconvert* obj,
|
||||
|
||||
const UNICODE* const start = dest_ptr;
|
||||
const ULONG src_start = src_len;
|
||||
while ((src_len) && (dest_len >= sizeof(*dest_ptr))) {
|
||||
while ((src_len) && (dest_len >= sizeof(*dest_ptr)))
|
||||
{
|
||||
const fss_size_t res = fss_mbtowc(dest_ptr, src_ptr, src_len);
|
||||
if (res == -1) {
|
||||
if (res == -1)
|
||||
{
|
||||
*err_code = CS_BAD_INPUT;
|
||||
break;
|
||||
}
|
||||
@ -262,15 +269,18 @@ ULONG internal_unicode_to_fss(csconvert* obj,
|
||||
const UNICODE* unicode_str = s;
|
||||
|
||||
const UCHAR* const start = fss_str;
|
||||
while ((fss_len) && (unicode_len >= sizeof(*unicode_str))) {
|
||||
while ((fss_len) && (unicode_len >= sizeof(*unicode_str)))
|
||||
{
|
||||
/* Convert the wide character into temp buffer */
|
||||
fss_size_t res = fss_wctomb(tmp_buffer, *unicode_str);
|
||||
if (res == -1) {
|
||||
if (res == -1)
|
||||
{
|
||||
*err_code = CS_BAD_INPUT;
|
||||
break;
|
||||
}
|
||||
/* will the mb sequence fit into space left? */
|
||||
if (ULONG(res) > fss_len) {
|
||||
if (ULONG(res) > fss_len)
|
||||
{
|
||||
*err_code = CS_TRUNCATION_ERROR;
|
||||
break;
|
||||
}
|
||||
@ -569,7 +579,8 @@ static ULONG internal_str_to_upper(texttype* /*obj*/,
|
||||
*
|
||||
**************************************/
|
||||
const UCHAR* const pStart = dest;
|
||||
while (inLen-- && outLen--) {
|
||||
while (inLen-- && outLen--)
|
||||
{
|
||||
*dest++ = UPPER7(*src);
|
||||
src++;
|
||||
}
|
||||
@ -593,7 +604,8 @@ static ULONG internal_str_to_lower(texttype* /*obj*/,
|
||||
*
|
||||
**************************************/
|
||||
const UCHAR* const pStart = dest;
|
||||
while (inLen-- && outLen--) {
|
||||
while (inLen-- && outLen--)
|
||||
{
|
||||
*dest++ = LOWWER7(*src);
|
||||
src++;
|
||||
}
|
||||
@ -830,8 +842,10 @@ static ULONG wc_to_nc(csconvert* obj, ULONG nSrc, const UCHAR* ppSrc,
|
||||
const UCHAR* const pStart = pDest;
|
||||
const USHORT* const pStart_src = pSrc;
|
||||
|
||||
while (nDest && nSrc >= sizeof(*pSrc)) {
|
||||
if (*pSrc >= 256) {
|
||||
while (nDest && nSrc >= sizeof(*pSrc))
|
||||
{
|
||||
if (*pSrc >= 256)
|
||||
{
|
||||
*err_code = CS_CONVERT_ERROR;
|
||||
break;
|
||||
}
|
||||
@ -877,7 +891,8 @@ static ULONG mb_to_wc(csconvert* obj, ULONG nSrc, const UCHAR* pSrc,
|
||||
|
||||
const USHORT* const pStart = pDest;
|
||||
const UCHAR* const pStart_src = pSrc;
|
||||
while (nDest > 1 && nSrc > 1) {
|
||||
while (nDest > 1 && nSrc > 1)
|
||||
{
|
||||
*pDest++ = *pSrc * 256 + *(pSrc + 1);
|
||||
pSrc += 2;
|
||||
nDest -= 2;
|
||||
@ -921,7 +936,8 @@ static ULONG wc_to_mb(csconvert* obj, ULONG nSrc, const UCHAR* ppSrc,
|
||||
|
||||
const UCHAR* const pStart = pDest;
|
||||
const USHORT* const pStart_src = pSrc;
|
||||
while (nDest > 1 && nSrc > 1) {
|
||||
while (nDest > 1 && nSrc > 1)
|
||||
{
|
||||
*pDest++ = *pSrc / 256;
|
||||
*pDest++ = *pSrc++ % 256;
|
||||
nDest -= 2;
|
||||
@ -1247,8 +1263,10 @@ static ULONG cvt_none_to_unicode(csconvert* obj, ULONG nSrc, const UCHAR* pSrc,
|
||||
|
||||
const USHORT* const pStart = pDest;
|
||||
const UCHAR* const pStart_src = pSrc;
|
||||
while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) {
|
||||
if (*pSrc > 127) {
|
||||
while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc))
|
||||
{
|
||||
if (*pSrc > 127)
|
||||
{
|
||||
*err_code = CS_CONVERT_ERROR;
|
||||
break;
|
||||
}
|
||||
@ -1293,7 +1311,8 @@ static ULONG cvt_unicode_to_unicode(csconvert* obj, ULONG nSrc, const UCHAR* ppS
|
||||
|
||||
const USHORT* const pStart = pDest;
|
||||
const USHORT* const pStart_src = pSrc;
|
||||
while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) {
|
||||
while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc))
|
||||
{
|
||||
*pDest++ = *pSrc++;
|
||||
nDest -= sizeof(*pDest);
|
||||
nSrc -= sizeof(*pSrc);
|
||||
@ -1339,8 +1358,10 @@ static ULONG cvt_utffss_to_ascii(csconvert* obj, ULONG nSrc, const UCHAR* pSrc,
|
||||
|
||||
const UCHAR* const pStart = pDest;
|
||||
const UCHAR* const pStart_src = pSrc;
|
||||
while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) {
|
||||
if (*pSrc > 127) {
|
||||
while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc))
|
||||
{
|
||||
if (*pSrc > 127)
|
||||
{
|
||||
/* In the cvt_ascii_to_utffss case this should be CS_BAD_INPUT */
|
||||
/* but not in cvt_none_to_utffss or cvt_utffss_to_ascii */
|
||||
*err_code = CS_CONVERT_ERROR;
|
||||
|
@ -66,7 +66,7 @@ int CLIB_ROUTINE main( int argc, char** argv)
|
||||
// Let's get the root directory from the instance path of this program.
|
||||
// argv[0] is only _mostly_ guaranteed to give this info,
|
||||
// so we GetModuleFileName()
|
||||
USHORT len = GetModuleFileName(NULL, directory, sizeof(directory));
|
||||
const USHORT len = GetModuleFileName(NULL, directory, sizeof(directory));
|
||||
if (len == 0)
|
||||
return reg_error(GetLastError(), "GetModuleFileName", NULL);
|
||||
|
||||
|
@ -39,9 +39,7 @@ static void cleanup_key(HKEY, const char*);
|
||||
static USHORT remove_subkeys(HKEY, bool, pfnRegError);
|
||||
#endif
|
||||
|
||||
USHORT REGISTRY_install(HKEY hkey_rootnode,
|
||||
const TEXT* directory,
|
||||
pfnRegError err_handler)
|
||||
USHORT REGISTRY_install(HKEY hkey_rootnode, const TEXT* directory, pfnRegError err_handler)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -69,7 +67,8 @@ USHORT REGISTRY_install(HKEY hkey_rootnode,
|
||||
TEXT path_name[MAXPATHLEN];
|
||||
TEXT* p;
|
||||
USHORT len = GetFullPathName(directory, sizeof(path_name), path_name, &p);
|
||||
if (len && path_name[len - 1] != '/' && path_name[len - 1] != '\\') {
|
||||
if (len && path_name[len - 1] != '/' && path_name[len - 1] != '\\')
|
||||
{
|
||||
path_name[len++] = '\\';
|
||||
path_name[len] = 0;
|
||||
}
|
||||
@ -196,7 +195,8 @@ static USHORT remove_subkeys(HKEY hkey,
|
||||
&n_sub_keys,
|
||||
&max_sub_key,
|
||||
&i, &i, &i, &i, &i, &last_write_time);
|
||||
if (status != ERROR_SUCCESS && status != ERROR_MORE_DATA) {
|
||||
if (status != ERROR_SUCCESS && status != ERROR_MORE_DATA)
|
||||
{
|
||||
if (silent_flag)
|
||||
return FB_FAILURE;
|
||||
return (*err_handler) (status, "RegQueryInfoKey", NULL);
|
||||
@ -206,7 +206,8 @@ static USHORT remove_subkeys(HKEY hkey,
|
||||
(TEXT*) malloc((SLONG) max_sub_key) : buffer;
|
||||
|
||||
const TEXT* p = NULL;
|
||||
for (DWORD i = 0; i < n_sub_keys; i++) {
|
||||
for (DWORD i = 0; i < n_sub_keys; i++)
|
||||
{
|
||||
DWORD sub_key_len = max_sub_key;
|
||||
if ((status = RegEnumKeyEx(hkey, i, sub_key, &sub_key_len,
|
||||
NULL, NULL, NULL,
|
||||
@ -229,7 +230,8 @@ static USHORT remove_subkeys(HKEY hkey,
|
||||
RegCloseKey(hkey_sub);
|
||||
if (ret == FB_FAILURE)
|
||||
return FB_FAILURE;
|
||||
if ((status = RegDeleteKey(hkey, sub_key)) != ERROR_SUCCESS) {
|
||||
if ((status = RegDeleteKey(hkey, sub_key)) != ERROR_SUCCESS)
|
||||
{
|
||||
p = "RegDeleteKey";
|
||||
break;
|
||||
}
|
||||
@ -238,7 +240,8 @@ static USHORT remove_subkeys(HKEY hkey,
|
||||
if (buffer != sub_key)
|
||||
free(sub_key);
|
||||
|
||||
if (p) {
|
||||
if (p)
|
||||
{
|
||||
if (silent_flag)
|
||||
return FB_FAILURE;
|
||||
return (*err_handler) (status, p, NULL);
|
||||
|
@ -147,7 +147,8 @@ int main( int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if ((argv < end) && (!strcmp(*argv, "tips"))) {
|
||||
if ((argv < end) && (!strcmp(*argv, "tips")))
|
||||
{
|
||||
argv++;
|
||||
sw_dump_tips = true;
|
||||
}
|
||||
@ -538,7 +539,8 @@ static void dump(FILE* file, rbdb* rbdb, ULONG lower, ULONG upper, UCHAR pg_type
|
||||
{
|
||||
if (tip[sequence] == lower)
|
||||
break;
|
||||
else if (!tip[sequence]) {
|
||||
else if (!tip[sequence])
|
||||
{
|
||||
sequence = 0;
|
||||
break;
|
||||
}
|
||||
@ -786,7 +788,8 @@ static void get_range(TEXT*** argv, const TEXT* const* const end, ULONG* lower,
|
||||
TEXT c = 0;
|
||||
const TEXT* p;
|
||||
for (p = token->swc_string; *p; p++)
|
||||
if (*p < '0' || *p > '9') {
|
||||
if (*p < '0' || *p > '9')
|
||||
{
|
||||
c = *p;
|
||||
*p++ = 0;
|
||||
break;
|
||||
@ -847,7 +850,8 @@ static void get_switch( TEXT** argv, swc* token)
|
||||
**************************************/
|
||||
token->swc_string = *argv;
|
||||
|
||||
if (*token->swc_string == '-') {
|
||||
if (*token->swc_string == '-')
|
||||
{
|
||||
token->swc_switch = true;
|
||||
token->swc_string++;
|
||||
}
|
||||
@ -856,7 +860,8 @@ static void get_switch( TEXT** argv, swc* token)
|
||||
|
||||
const int temp = strlen(token->swc_string) - 1;
|
||||
|
||||
if (token->swc_string[temp] == ',') {
|
||||
if (token->swc_string[temp] == ',')
|
||||
{
|
||||
token->swc_string[temp] = '\0';
|
||||
//token->swc_comma = true;
|
||||
}
|
||||
@ -889,7 +894,8 @@ static header_page* open_database( rbdb* rbdb, ULONG pg_size)
|
||||
|
||||
header_page* header = (header_page*) RBDB_read(rbdb, (SLONG) 0);
|
||||
|
||||
if (header->pag_type != pag_header) {
|
||||
if (header->pag_type != pag_header)
|
||||
{
|
||||
printf("header page has wrong type, expected %d found %d!\n", pag_header, header->pag_type);
|
||||
rbdb->rbdb_valid = false;
|
||||
}
|
||||
@ -904,12 +910,14 @@ static header_page* open_database( rbdb* rbdb, ULONG pg_size)
|
||||
rbdb->rbdb_valid = false;
|
||||
}
|
||||
|
||||
if (pg_size && (pg_size != header->hdr_page_size)) {
|
||||
if (pg_size && (pg_size != header->hdr_page_size))
|
||||
{
|
||||
printf("Using page size %d\n", pg_size);
|
||||
header->hdr_page_size = pg_size;
|
||||
rbdb->rbdb_valid = false;
|
||||
}
|
||||
else if (!header->hdr_page_size) {
|
||||
else if (!header->hdr_page_size)
|
||||
{
|
||||
printf("Using page size 1024\n");
|
||||
header->hdr_page_size = 1024;
|
||||
rbdb->rbdb_valid = false;
|
||||
|
@ -76,10 +76,8 @@ ULONG* RMET_tips(TEXT* db_in)
|
||||
ULONG* tip = tips;
|
||||
|
||||
FOR X IN RDB$PAGES WITH X.RDB$PAGE_TYPE = pag_transactions
|
||||
{
|
||||
*tip = X.RDB$PAGE_NUMBER;
|
||||
tip++;
|
||||
}
|
||||
END_FOR
|
||||
ON_ERROR
|
||||
isc_print_status(gds__status);
|
||||
|
Loading…
Reference in New Issue
Block a user