|
11 | 11 | #include <access/stratnum.h>
|
12 | 12 | #include <access/tupdesc.h>
|
13 | 13 | #include <catalog/pg_collation.h>
|
| 14 | +#include <executor/spi.h> |
14 | 15 | #include <executor/tuptable.h>
|
15 | 16 | #include <funcapi.h>
|
16 | 17 | #include <nodes/makefuncs.h>
|
|
22 | 23 | #include <rewrite/rewriteManip.h>
|
23 | 24 | #include <storage/lmgr.h>
|
24 | 25 | #include <storage/lockdefs.h>
|
| 26 | +#include <utils/datum.h> |
25 | 27 | #include <utils/syscache.h>
|
26 | 28 |
|
27 | 29 | #include "chunk.h"
|
@@ -781,6 +783,60 @@ ts_chunk_column_stats_lookup(int32 hypertable_id, int32 chunk_id, const char *co
|
781 | 783 | return form_range;
|
782 | 784 | }
|
783 | 785 |
|
| 786 | +static bool |
| 787 | +chunk_get_minmax(const Chunk *chunk, Oid col_type, const char *col_name, Datum *minmax) |
| 788 | +{ |
| 789 | + StringInfoData command; |
| 790 | + int res; |
| 791 | + |
| 792 | + /* Lock down search_path */ |
| 793 | + int save_nestlevel = NewGUCNestLevel(); |
| 794 | + RestrictSearchPath(); |
| 795 | + |
| 796 | + initStringInfo(&command); |
| 797 | + appendStringInfo(&command, |
| 798 | + "SELECT min(%s), max(%s) FROM %s.%s", |
| 799 | + quote_identifier(col_name), |
| 800 | + quote_identifier(col_name), |
| 801 | + quote_identifier(NameStr(chunk->fd.schema_name)), |
| 802 | + quote_identifier(NameStr(chunk->fd.table_name))); |
| 803 | + |
| 804 | + if (SPI_connect() != SPI_OK_CONNECT) |
| 805 | + elog(ERROR, "could not connect to SPI"); |
| 806 | + |
| 807 | + res = SPI_execute(command.data, true /* read_only */, 0 /*count*/); |
| 808 | + if (res < 0) |
| 809 | + ereport(ERROR, |
| 810 | + (errcode(ERRCODE_INTERNAL_ERROR), |
| 811 | + (errmsg("could not get the min/max values for column \"%s\" of chunk \"%s.%s\"", |
| 812 | + col_name, chunk->fd.schema_name.data,chunk->fd.table_name.data)))); |
| 813 | + |
| 814 | + pfree(command.data); |
| 815 | + |
| 816 | + bool isnull_min = false, isnull_max = false, ret = false; |
| 817 | + Datum min = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull_min); |
| 818 | + Datum max = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 2, &isnull_max); |
| 819 | + |
| 820 | + if (!isnull_min && !isnull_max) |
| 821 | + { |
| 822 | + bool typbyval; |
| 823 | + int16 typlen; |
| 824 | + get_typlenbyval(col_type, &typlen, &typbyval); |
| 825 | + minmax[0] = datumCopy(min, typbyval, typlen); |
| 826 | + minmax[1] = datumCopy(max, typbyval, typlen); |
| 827 | + ret = true; |
| 828 | + } |
| 829 | + |
| 830 | + /* Reset search path since this can be executed as part of a larger transaction */ |
| 831 | + AtEOXact_GUC(false, save_nestlevel); |
| 832 | + |
| 833 | + res = SPI_finish(); |
| 834 | + if (res != SPI_OK_FINISH) |
| 835 | + elog(ERROR, "SPI_finish failed: %s", SPI_result_code_string(res)); |
| 836 | + |
| 837 | + return ret; |
| 838 | +} |
| 839 | + |
784 | 840 | /*
|
785 | 841 | * Update column dimension ranges in the catalog for the
|
786 | 842 | * provided chunk (it's assumed that the chunk is locked
|
@@ -821,7 +877,7 @@ ts_chunk_column_stats_calculate(const Hypertable *ht, const Chunk *chunk)
|
821 | 877 | col_type = get_atttype(chunk->table_id, attno);
|
822 | 878 |
|
823 | 879 | /* calculate the min/max range for this column on this chunk */
|
824 |
| - if (ts_chunk_get_minmax(chunk->table_id, col_type, attno, "column range", minmax)) |
| 880 | + if (chunk_get_minmax(chunk, col_type, col_name, minmax)) |
825 | 881 | {
|
826 | 882 | Form_chunk_column_stats range;
|
827 | 883 | int64 min = ts_time_value_to_internal(minmax[0], col_type);
|
|
0 commit comments