LCOV - code coverage report
Current view: top level - src/test/modules/test_custom_types - test_custom_types.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 64 64
Test Date: 2026-05-15 07:16:35 Functions: 100.0 % 24 24
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*--------------------------------------------------------------------------
       2              :  *
       3              :  * test_custom_types.c
       4              :  *      Test module for a set of functions for custom types.
       5              :  *
       6              :  * The custom type used in this module is similar to int4 for simplicity,
       7              :  * except that it is able to use various typanalyze functions to enforce
       8              :  * check patterns with ANALYZE.
       9              :  *
      10              :  * Copyright (c) 1996-2026, PostgreSQL Global Development Group
      11              :  *
      12              :  * IDENTIFICATION
      13              :  *      src/test/modules/test_custom_types/test_custom_types.c
      14              :  *
      15              :  *--------------------------------------------------------------------------
      16              :  */
      17              : 
      18              : #include "postgres.h"
      19              : 
      20              : #include "fmgr.h"
      21              : #include "commands/vacuum.h"
      22              : #include "utils/builtins.h"
      23              : 
      24            1 : PG_MODULE_MAGIC;
      25              : 
      26              : /* Function declarations */
      27            2 : PG_FUNCTION_INFO_V1(int_custom_in);
      28            2 : PG_FUNCTION_INFO_V1(int_custom_out);
      29            2 : PG_FUNCTION_INFO_V1(int_custom_typanalyze_false);
      30            2 : PG_FUNCTION_INFO_V1(int_custom_typanalyze_invalid);
      31            2 : PG_FUNCTION_INFO_V1(int_custom_eq);
      32            2 : PG_FUNCTION_INFO_V1(int_custom_ne);
      33            2 : PG_FUNCTION_INFO_V1(int_custom_lt);
      34            2 : PG_FUNCTION_INFO_V1(int_custom_le);
      35            2 : PG_FUNCTION_INFO_V1(int_custom_gt);
      36            2 : PG_FUNCTION_INFO_V1(int_custom_ge);
      37            2 : PG_FUNCTION_INFO_V1(int_custom_cmp);
      38              : 
      39              : /*
      40              :  * int_custom_in - input function for int_custom type
      41              :  *
      42              :  * Converts a string to a int_custom (which is just an int32 internally).
      43              :  */
      44              : Datum
      45           15 : int_custom_in(PG_FUNCTION_ARGS)
      46              : {
      47           15 :     char       *num = PG_GETARG_CSTRING(0);
      48              : 
      49           15 :     PG_RETURN_INT32(pg_strtoint32_safe(num, fcinfo->context));
      50              : }
      51              : 
      52              : /*
      53              :  * int_custom_out - output function for int_custom type
      54              :  *
      55              :  * Converts a int_custom to a string.
      56              :  */
      57              : Datum
      58            3 : int_custom_out(PG_FUNCTION_ARGS)
      59              : {
      60            3 :     int32       arg1 = PG_GETARG_INT32(0);
      61            3 :     char       *result = (char *) palloc(12);   /* sign, 10 digits, '\0' */
      62              : 
      63            3 :     pg_ltoa(arg1, result);
      64            3 :     PG_RETURN_CSTRING(result);
      65              : }
      66              : 
      67              : /*
      68              :  * int_custom_typanalyze_false - typanalyze function that returns false
      69              :  *
      70              :  * This function returns false, to simulate a type that cannot be analyzed.
      71              :  */
      72              : Datum
      73            4 : int_custom_typanalyze_false(PG_FUNCTION_ARGS)
      74              : {
      75            4 :     PG_RETURN_BOOL(false);
      76              : }
      77              : 
      78              : /*
      79              :  * Callback used to compute invalid statistics.
      80              :  */
      81              : static void
      82            3 : int_custom_invalid_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
      83              :                          int samplerows, double totalrows)
      84              : {
      85              :     /* We are not valid, and do not want to be. */
      86            3 :     stats->stats_valid = false;
      87            3 : }
      88              : 
      89              : /*
      90              :  * int_custom_typanalyze_invalid
      91              :  *
      92              :  * This function sets some invalid stats data, letting the caller know that
      93              :  * we are safe for an analyze, returning true.
      94              :  */
      95              : Datum
      96            6 : int_custom_typanalyze_invalid(PG_FUNCTION_ARGS)
      97              : {
      98            6 :     VacAttrStats *stats = (VacAttrStats *) PG_GETARG_POINTER(0);
      99              : 
     100              :     /* If the attstattarget column is negative, use the default value */
     101            6 :     if (stats->attstattarget < 0)
     102            4 :         stats->attstattarget = default_statistics_target;
     103              : 
     104              :     /* Buggy number, no need to care as long as it is positive */
     105            6 :     stats->minrows = 300;
     106              : 
     107              :     /* Set callback to compute some invalid stats */
     108            6 :     stats->compute_stats = int_custom_invalid_stats;
     109              : 
     110            6 :     PG_RETURN_BOOL(true);
     111              : }
     112              : 
     113              : /*
     114              :  * Comparison functions for int_custom type
     115              :  */
     116              : Datum
     117            3 : int_custom_eq(PG_FUNCTION_ARGS)
     118              : {
     119            3 :     int32       arg1 = PG_GETARG_INT32(0);
     120            3 :     int32       arg2 = PG_GETARG_INT32(1);
     121              : 
     122            3 :     PG_RETURN_BOOL(arg1 == arg2);
     123              : }
     124              : 
     125              : Datum
     126            1 : int_custom_ne(PG_FUNCTION_ARGS)
     127              : {
     128            1 :     int32       arg1 = PG_GETARG_INT32(0);
     129            1 :     int32       arg2 = PG_GETARG_INT32(1);
     130              : 
     131            1 :     PG_RETURN_BOOL(arg1 != arg2);
     132              : }
     133              : 
     134              : Datum
     135            1 : int_custom_lt(PG_FUNCTION_ARGS)
     136              : {
     137            1 :     int32       arg1 = PG_GETARG_INT32(0);
     138            1 :     int32       arg2 = PG_GETARG_INT32(1);
     139              : 
     140            1 :     PG_RETURN_BOOL(arg1 < arg2);
     141              : }
     142              : 
     143              : Datum
     144            1 : int_custom_le(PG_FUNCTION_ARGS)
     145              : {
     146            1 :     int32       arg1 = PG_GETARG_INT32(0);
     147            1 :     int32       arg2 = PG_GETARG_INT32(1);
     148              : 
     149            1 :     PG_RETURN_BOOL(arg1 <= arg2);
     150              : }
     151              : 
     152              : Datum
     153            1 : int_custom_gt(PG_FUNCTION_ARGS)
     154              : {
     155            1 :     int32       arg1 = PG_GETARG_INT32(0);
     156            1 :     int32       arg2 = PG_GETARG_INT32(1);
     157              : 
     158            1 :     PG_RETURN_BOOL(arg1 > arg2);
     159              : }
     160              : 
     161              : Datum
     162            1 : int_custom_ge(PG_FUNCTION_ARGS)
     163              : {
     164            1 :     int32       arg1 = PG_GETARG_INT32(0);
     165            1 :     int32       arg2 = PG_GETARG_INT32(1);
     166              : 
     167            1 :     PG_RETURN_BOOL(arg1 >= arg2);
     168              : }
     169              : 
     170              : Datum
     171           46 : int_custom_cmp(PG_FUNCTION_ARGS)
     172              : {
     173           46 :     int32       arg1 = PG_GETARG_INT32(0);
     174           46 :     int32       arg2 = PG_GETARG_INT32(1);
     175              : 
     176           46 :     if (arg1 < arg2)
     177           30 :         PG_RETURN_INT32(-1);
     178           16 :     else if (arg1 > arg2)
     179            4 :         PG_RETURN_INT32(1);
     180              :     else
     181           12 :         PG_RETURN_INT32(0);
     182              : }
        

Generated by: LCOV version 2.0-1