@@ -132,6 +132,9 @@ void addToTwoColumnCombinationHashSet(int from, char* valueToConcat, int to, cha
132
132
void LookForFilterWithEquality (PlanState * result , Oid tableOid , List * qual );
133
133
void InvalidateStatisticsForTables (List * oldTableOids );
134
134
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
+
135
138
/* ------------------------------------------------------------------------
136
139
* ExecInitNode
137
140
*
@@ -448,6 +451,73 @@ InvalidateStatisticsForTable(int tableOid)
448
451
}
449
452
}
450
453
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
+
451
521
void
452
522
LookForFilterWithEquality (PlanState * result , Oid tableOid , List * qual )
453
523
{
@@ -466,6 +536,8 @@ LookForFilterWithEquality(PlanState* result, Oid tableOid, List* qual)
466
536
break ;
467
537
}
468
538
539
+ // the magic numbers are operator identifiers from posgres/src/include/catalog/pg_operator.h
540
+ // equals
469
541
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
470
542
int numberOfAttributes = result -> plan -> targetlist -> length ;
471
543
@@ -475,29 +547,54 @@ LookForFilterWithEquality(PlanState* result, Oid tableOid, List* qual)
475
547
// we always set the type to 8byte-integer because we don't need a detailed differentiation
476
548
columnData -> typid = 20 ;
477
549
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 );
498
595
}
499
596
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 );
501
598
// found a selection, therefore we cannot use old statistics
502
599
InvalidateStatisticsForTable (tableOid );
503
600
}
@@ -679,7 +776,6 @@ ExecProcNode(PlanState *node) {
679
776
680
777
int i ;
681
778
for (i = 0 ; i < piggyback -> numberOfAttributes ; i ++ ) {
682
-
683
779
if (!(piggyback -> resultStatistics -> columnStatistics [i ].minValueIsFinal
684
780
&& piggyback -> resultStatistics -> columnStatistics [i ].maxValueIsFinal &&
685
781
piggyback -> resultStatistics -> columnStatistics [i ].n_distinctIsFinal )) { //TODO add mostFrequentValueIsFinal if ever implemented
0 commit comments