@@ -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,76 @@ 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
+ piggyback -> resultStatistics -> columnStatistics [columnStatisticId ].n_distinctIsFinal = 0 ;
516
+ piggyback -> resultStatistics -> columnStatistics [columnStatisticId ].mostFrequentValueIsFinal = 0 ;
517
+ }
518
+ else
519
+ {
520
+ printf ("there are statistics results from a selection with > or < with a constant that are not part of the result table\n" );
521
+ }
522
+ }
523
+
451
524
void
452
525
LookForFilterWithEquality (PlanState * result , Oid tableOid , List * qual )
453
526
{
@@ -466,6 +539,8 @@ LookForFilterWithEquality(PlanState* result, Oid tableOid, List* qual)
466
539
break ;
467
540
}
468
541
542
+ // the magic numbers are operator identifiers from posgres/src/include/catalog/pg_operator.h
543
+ // equals
469
544
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
545
int numberOfAttributes = result -> plan -> targetlist -> length ;
471
546
@@ -475,29 +550,54 @@ LookForFilterWithEquality(PlanState* result, Oid tableOid, List* qual)
475
550
// we always set the type to 8byte-integer because we don't need a detailed differentiation
476
551
columnData -> typid = 20 ;
477
552
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
- }
553
+ SetStatisticValuesForEqual (minAndMaxAndAvg , i , columnData );
554
+ }
555
+ // <
556
+ else if (opno == 37 || opno == 95 || opno == 97 || opno == 412 || opno == 418 || opno == 534 || opno == 535 || opno == 1864 || opno == 1870 ) {
557
+
558
+ int * min = (int * ) malloc (sizeof (int ));
559
+ min = & (((Const * ) ((OpExpr * ) ((ExprState * ) linitial (qual ))-> expr )-> args -> tail -> data .ptr_value )-> constvalue );
560
+
561
+ // we always set the type to 8byte-integer because we don't need a detailed differentiation
562
+ columnData -> typid = 20 ;
563
+
564
+ SetStatisticValuesForUnequal (false, false, min , i , columnData );
565
+ }
566
+ // <=
567
+ else if (opno == 80 || opno == 414 || opno == 420 || opno == 522 || opno == 523 || opno == 540 || opno == 541 || opno == 1866 || opno == 1872 ) {
568
+
569
+ int * min = (int * ) malloc (sizeof (int ));
570
+ min = & (((Const * ) ((OpExpr * ) ((ExprState * ) linitial (qual ))-> expr )-> args -> tail -> data .ptr_value )-> constvalue );
571
+
572
+ // we always set the type to 8byte-integer because we don't need a detailed differentiation
573
+ columnData -> typid = 20 ;
574
+
575
+ SetStatisticValuesForUnequal (false, true, min , i , columnData );
576
+ }
577
+ // >
578
+ else if (opno == 76 || opno == 413 || opno == 419 || opno == 520 || opno == 521 || opno == 536 || opno == 1865 || opno == 1871 ) {
579
+
580
+ int * max = (int * ) malloc (sizeof (int ));
581
+ max = & (((Const * ) ((OpExpr * ) ((ExprState * ) linitial (qual ))-> expr )-> args -> tail -> data .ptr_value )-> constvalue );
582
+
583
+ // we always set the type to 8byte-integer because we don't need a detailed differentiation
584
+ columnData -> typid = 20 ;
585
+
586
+ SetStatisticValuesForUnequal (true, false, max , i , columnData );
587
+ }
588
+ // >=
589
+ else if (opno == 82 || opno == 415 || opno == 430 || opno == 524 || opno == 525 || opno == 537 || opno == 542 || opno == 543 || opno == 1867 || opno == 1873 ) {
590
+
591
+ int * max = (int * ) malloc (sizeof (int ));
592
+ max = & (((Const * ) ((OpExpr * ) ((ExprState * ) linitial (qual ))-> expr )-> args -> tail -> data .ptr_value )-> constvalue );
593
+
594
+ // we always set the type to 8byte-integer because we don't need a detailed differentiation
595
+ columnData -> typid = 20 ;
596
+
597
+ SetStatisticValuesForUnequal (true, true, max , i , columnData );
498
598
}
499
599
else {
500
- printf ("this opno is no equality : %d (for column id %d)\n" , opno , columnId );
600
+ printf ("this opno is no =, <, >, <= or >= : %d (for column id %d)\n" , opno , columnId );
501
601
// found a selection, therefore we cannot use old statistics
502
602
InvalidateStatisticsForTable (tableOid );
503
603
}
0 commit comments