8000 implemented get min and max for <, <=, > and >= selections · mpws2013n1/postgres@ed8380f · GitHub
[go: up one dir, main page]

Skip to content

Commit ed8380f

Browse files
committed
implemented get min and max for <, <=, > and >= selections
1 parent 90d1dbf commit ed8380f

File tree

1 file changed

+118
-22
lines changed

1 file changed

+118
-22
lines changed

src/backend/executor/execProcnode.c

Lines changed: 118 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ void addToTwoColumnCombinationHashSet(int from, char* valueToConcat, int to, cha
132132
void LookForFilterWithEquality(PlanState* result, Oid tableOid, List* qual);
133133
void InvalidateStatisticsForTables(List* oldTableOids);
134134
void InvalidateStatisticsForTable(int tableOid);
135+
void SetStatisticValuesForEqual(int* equationValue, int columnStatisticId, be_PGAttDesc *columnData);
136+
void SetStatisticValuesForUnequal(bool greaterThan, bool orEquals,int* equationValue, int columnStatisticId, be_PGAttDesc *columnData);
137+
135138
/* ------------------------------------------------------------------------
136139
* ExecInitNode
137140
*
@@ -448,6 +451,73 @@ InvalidateStatisticsForTable(int tableOid)
448451
}
449452
}
450453

454+
void
455+
SetStatisticValuesForEqual(int* equationValue, int columnStatisticId, be_PGAttDesc *columnData) {
456+
// only write values, if the selected field is part of the result table
457+
if (columnStatisticId < piggyback->numberOfAttributes){
458+
piggyback->resultStatistics->columnStatistics[columnStatisticId].columnDescriptor = columnData;
459+
piggyback->resultStatistics->columnStatistics[columnStatisticId].isNumeric = 1;
460+
piggyback->resultStatistics->columnStatistics[columnStatisticId].maxValue = equationValue;
461+
piggyback->resultStatistics->columnStatistics[columnStatisticId].minValue = equationValue;
462+
piggyback->resultStatistics->columnStatistics[columnStatisticId].mostFrequentValue = equationValue;
463+
piggyback->resultStatistics->columnStatistics[columnStatisticId].n_distinct = 1;
464+
465+
// the meta data for this column is complete and should not be calculated again
466+
piggyback->resultStatistics->columnStatistics[columnStatisticId].n_distinctIsFinal = 1;
467+
piggyback->resultStatistics->columnStatistics[columnStatisticId].minValueIsFinal = 1;
468+
piggyback->resultStatistics->columnStatistics[columnStatisticId].maxValueIsFinal = 1;
469+
piggyback->resultStatistics->columnStatistics[columnStatisticId].mostFrequentValueIsFinal = 1;
470+
}
471+
else {
472+
printf("there are statistics results from a selection with = that are not part of the result table\n");
473+
}
474+
}
475+
476+
// meaning of the first and second parameter:
477+
// >= == greaterThan true, orEquals true
478+
// > == greaterThan true, orEquals false
479+
// <= == greaterThan false, orEquals true
480+
// < == greaterThan false, orEquals false
481+
void
482+
SetStatisticValuesForUnequal(bool greaterThan, bool orEquals, int* equationValue, int columnStatisticId, be_PGAttDesc *columnData) {
483+
// only write values, if the selected field is part of the result table
484+
int *value = (int*) malloc(sizeof(int));
485+
if (!orEquals)
486+
{
487+
if (greaterThan) // for instance x > 3 means x has at least the value 4
488+
{
489+
*value = *equationValue + 1;
490+
}
491+
else // for instance x < 3 means x has at maximum the value 2
492+
{
493+
*value = *equationValue - 1;
494+
}
495+
}
496+
else
497+
{
498+
*value = *equationValue;
499+
}
500+
501+
if (columnStatisticId < piggyback->numberOfAttributes)
502+
{
503+
piggyback->resultStatistics->columnStatistics[columnStatisticId].columnDescriptor = columnData;
504+
if(greaterThan)
505+
piggyback->resultStatistics->columnStatistics[columnStatisticId].minValue = value;
506+
else
507+
piggyback->resultStatistics->columnStatistics[columnStatisticId].maxValue = value;
508+
509+
// the meta data for this column is complete and should not be calculated again
510+
if(greaterThan)
511+
piggyback->resultStatistics->columnStatistics[columnStatisticId].minValueIsFinal = 1;
512+
else
513+
piggyback->resultStatistics->columnStatistics[columnStatisticId].maxValueIsFinal = 1;
514+
}
515+
else
516+
{
517+
printf("there are statistics results from a selection with > or < with a constant that are not part of the result table\n");
518+
}
519+
}
520+
451521
void
452522
LookForFilterWithEquality(PlanState* result, Oid tableOid, List* qual)
453523
{
@@ -466,6 +536,8 @@ LookForFilterWithEquality(PlanState* result, Oid tableOid, List* qual)
466536
break;
467537
}
468538

539+
// the magic numbers are operator identifiers from posgres/src/include/catalog/pg_operator.h
540+
// equals
469541
if(opno == 94 || opno == 96 || opno == 410 || opno == 416 || opno == 1862 || opno == 1868 || opno == 15 || opno == 532 || opno == 533) { // it is a equality like number_of_tracks = 3
470542
int numberOfAttributes = result->plan->targetlist->length;
471543

@@ -475,29 +547,54 @@ LookForFilterWithEquality(PlanState* result, Oid tableOid, List* qual)
475547
// we always set the type to 8byte-integer because we don't need a detailed differentiation
476548
columnData->typid = 20;
477549

478-
// only write values, if the selected field is part of the result table
479-
if (i < piggyback->numberOfAttributes)
480-
{
481-
piggyback->resultStatistics->columnStatistics[i].columnDescriptor = columnData;
482-
piggyback->resultStatistics->columnStatistics[i].isNumeric = 1;
483-
piggyback->resultStatistics->columnStatistics[i].maxValue = minAndMaxAndAvg;
484-
piggyback->resultStatistics->columnStatistics[i].minValue = minAndMaxAndAvg;
485-
piggyback->resultStatistics->columnStatistics[i].mostFrequentValue = minAndMaxAndAvg;
486-
piggyback->resultStatistics->columnStatistics[i].n_distinct = 1;
487-
488-
// the meta data for this column is complete and should not be calculated again
489-
piggyback->resultStatistics->columnStatistics[i].n_distinctIsFinal = 1;
490-
piggyback->resultStatistics->columnStatistics[i].minValueIsFinal = 1;
491-
piggyback->resultStatistics->columnStatistics[i].maxValueIsFinal = 1;
492-
piggyback->resultStatistics->columnStatistics[i].mostFrequentValueIsFinal = 1;
493-
}
494-
else
495-
{
496-
printf("there are statistics results from the selection that are not part of the result table\n");
497-
}
550+
SetStatisticValuesForEqual(minAndMaxAndAvg, i, columnData);
551+
}
552+
// <
553+
else if(opno == 37 || opno == 95 || opno == 97 || opno == 412 || opno == 418 || opno == 534 || opno == 535 || opno == 1864 || opno == 1870) {
554+
555+
int *min = (int*) malloc(sizeof(int));
556+
min = &(((Const*) ((OpExpr*) ((ExprState*) linitial(qual))->expr)->args->tail->data.ptr_value)->constvalue);
557+
558+
// we always set the type to 8byte-integer because we don't need a detailed differentiation
559+
columnData->typid = 20;
560+
561+
SetStatisticValuesForUnequal(false, false, min, i, columnData);
562+
}
563+
// <=
564+
else if(opno == 80 || opno == 414 || opno == 420 || opno == 522 || opno == 523 || opno == 540 || opno == 541 || opno == 1866 || opno == 1872) {
565+
566+
int *min = (int*) malloc(sizeof(int));
567+
min = &(((Const*) ((OpExpr*) ((ExprState*) linitial(qual))->expr)->args->tail->data.ptr_value)->constvalue);
568+
569+
// we always set the type to 8byte-integer because we don't need a detailed differentiation
570+
columnData->typid = 20;
571+
572+
SetStatisticValuesForUnequal(false, true, min, i, columnData);
573+
}
574+
// >
575+
else if(opno == 76 || opno == 413 || opno == 419 || opno == 520 || opno == 521 || opno == 536 || opno == 1865 || opno == 1871) {
576+
577+
int *max = (int*) malloc(sizeof(int));
578+
max = &(((Const*) ((OpExpr*) ((ExprState*) linitial(qual))->expr)->args->tail->data.ptr_value)->constvalue);
579+
580+
// we always set the type to 8byte-integer because we don't need a detailed differentiation
581+
columnData->typid = 20;
582+
583+
SetStatisticValuesForUnequal(true, false, max, i, columnData);
584+
}
585+
// >=
586+
else if(opno == 82 || opno == 415 || opno == 430 || opno == 524 || opno == 525 || opno == 537 || opno == 542 || opno == 543 || opno == 1867 || opno == 1873) {
587+
588+
int *max = (int*) malloc(sizeof(int));
589+
max = &(((Const*) ((OpExpr*) ((ExprState*) linitial(qual))->expr)->args->tail->data.ptr_value)->constvalue);
590+
591+
// we always set the type to 8byte-integer because we don't need a detailed differentiation
592+
columnData->typid = 20;
593+
594+
SetStatisticValuesForUnequal(true, true, max, i, columnData);
498595
}
499596
else {
500-
printf("this opno is no equality: %d (for column id %d)\n", opno, columnId);
597+
printf("this opno is no =, <, >, <= or >=: %d (for column id %d)\n", opno, columnId);
501598
// found a selection, therefore we cannot use old statistics
502599
InvalidateStatisticsForTable(tableOid);
503600
}
@@ -679,7 +776,6 @@ ExecProcNode(PlanState *node) {
679776

680777
int i;
681778
for (i = 0; i < piggyback->numberOfAttributes; i++) {
682-
683779
if(!(piggyback->resultStatistics->columnStatistics[i].minValueIsFinal
684780
&& piggyback->resultStatistics->columnStatistics[i].maxValueIsFinal &&
685781
piggyback->resultStatistics->columnStatistics[i].n_distinctIsFinal)) { //TODO add mostFrequentValueIsFinal if ever implemented

0 commit comments

Comments
 (0)
0