Alvaro Herrera wrote: > Heikki Linnakangas wrote:
> > If you add a new datatype, and define b-tree operators for it, what > > is required to create a minmax opclass for it? Would it be possible > > to generalize the functions in brin_minmax.c so that they can be > > reused for any datatype (with b-tree operators) without writing any > > new C code? I think we're almost there; the only thing that differs > > between each data type is the opcinfo function. Let's pass the type > > OID as argument to the opcinfo function. You could then have just a > > single minmax_opcinfo function, instead of the macro to generate a > > separate function for each built-in datatype. > > Yeah, that's how I had that initially. I changed it to what it's now as > part of a plan to enable building cross-type opclasses, so you could > have "WHERE int8col=42" without requiring a cast of the constant to type > int8. This might have been a thinko, because AFAICS it's possible to > build them with a constant opcinfo as well (I changed several other > things to support this, as described in a previous email.) I will look > into this later. I found out that we don't really throw errors in such cases anymore; we insert casts instead. Maybe there's a performance argument that it might be better to use existing cross-type operators than casting, but justifying this work just turned a lot harder. Here's a patch that reverts opcinfo into a generic function that receives the type OID. I will look into adding some testing mechanism for the union support proc; with that I will just consider the patch ready for commit and will push. -- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
*** a/src/backend/access/brin/brin.c --- b/src/backend/access/brin/brin.c *************** *** 886,894 **** brin_build_desc(Relation rel) opcInfoFn = index_getprocinfo(rel, keyno + 1, BRIN_PROCNUM_OPCINFO); - /* actually FunctionCall0 but we don't have that */ opcinfo[keyno] = (BrinOpcInfo *) ! DatumGetPointer(FunctionCall1(opcInfoFn, InvalidOid)); totalstored += opcinfo[keyno]->oi_nstored; } --- 886,894 ---- opcInfoFn = index_getprocinfo(rel, keyno + 1, BRIN_PROCNUM_OPCINFO); opcinfo[keyno] = (BrinOpcInfo *) ! DatumGetPointer(FunctionCall1(opcInfoFn, ! tupdesc->attrs[keyno]->atttypid)); totalstored += opcinfo[keyno]->oi_nstored; } *** a/src/backend/access/brin/brin_minmax.c --- b/src/backend/access/brin/brin_minmax.c *************** *** 50,87 **** typedef struct MinmaxOpaque bool inited[MINMAX_NUM_PROCNUMS]; } MinmaxOpaque; ! #define OPCINFO(typname, typoid) \ ! PG_FUNCTION_INFO_V1(minmaxOpcInfo_##typname); \ ! Datum \ ! minmaxOpcInfo_##typname(PG_FUNCTION_ARGS) \ ! { \ ! BrinOpcInfo *result; \ ! \ ! /* \ ! * opaque->operators is initialized lazily, as indicated by 'inited' \ ! * which is initialized to all false by palloc0. \ ! */ \ ! \ ! result = palloc0(MAXALIGN(SizeofBrinOpcInfo(2)) + \ ! sizeof(MinmaxOpaque)); \ ! result->oi_nstored = 2; \ ! result->oi_opaque = (MinmaxOpaque *) \ ! MAXALIGN((char *) result + SizeofBrinOpcInfo(2)); \ ! result->oi_typids[0] = typoid; \ ! result->oi_typids[1] = typoid; \ ! \ ! PG_RETURN_POINTER(result); \ ! } ! OPCINFO(int4, INT4OID) ! OPCINFO(numeric, NUMERICOID) ! OPCINFO(text, TEXTOID) ! OPCINFO(time, TIMEOID) ! OPCINFO(timetz, TIMETZOID) ! OPCINFO(timestamp, TIMESTAMPOID) ! OPCINFO(timestamptz, TIMESTAMPTZOID) ! OPCINFO(date, DATEOID) ! OPCINFO(char, CHAROID) /* * Examine the given index tuple (which contains partial status of a certain --- 50,77 ---- bool inited[MINMAX_NUM_PROCNUMS]; } MinmaxOpaque; ! PG_FUNCTION_INFO_V1(minmaxOpcInfo); ! Datum ! minmaxOpcInfo(PG_FUNCTION_ARGS) ! { ! Oid typoid = PG_GETARG_OID(0); ! BrinOpcInfo *result; ! ! /* ! * opaque->operators is initialized lazily, as indicated by 'inited' ! * which is initialized to all false by palloc0. ! */ ! result = palloc0(MAXALIGN(SizeofBrinOpcInfo(2)) + ! sizeof(MinmaxOpaque)); ! result->oi_nstored = 2; ! result->oi_opaque = (MinmaxOpaque *) ! MAXALIGN((char *) result + SizeofBrinOpcInfo(2)); ! result->oi_typids[0] = typoid; ! result->oi_typids[1] = typoid; ! ! PG_RETURN_POINTER(result); ! } /* * Examine the given index tuple (which contains partial status of a certain *** a/src/include/catalog/pg_amproc.h --- b/src/include/catalog/pg_amproc.h *************** *** 436,514 **** DATA(insert ( 4017 25 25 5 4031 )); DATA(insert ( 4054 23 23 1 3383 )); DATA(insert ( 4054 23 23 2 3384 )); DATA(insert ( 4054 23 23 3 3385 )); ! DATA(insert ( 4054 23 23 4 3394 )); DATA(insert ( 4054 23 23 5 66 )); DATA(insert ( 4054 23 23 6 149 )); DATA(insert ( 4054 23 23 7 150 )); DATA(insert ( 4054 23 23 8 147 )); ! DATA(insert ( 4055 1700 1700 1 3386 )); DATA(insert ( 4055 1700 1700 2 3384 )); DATA(insert ( 4055 1700 1700 3 3385 )); ! DATA(insert ( 4055 1700 1700 4 3394 )); DATA(insert ( 4055 1700 1700 5 1722 )); DATA(insert ( 4055 1700 1700 6 1723 )); DATA(insert ( 4055 1700 1700 7 1721 )); DATA(insert ( 4055 1700 1700 8 1720 )); ! DATA(insert ( 4056 25 25 1 3387 )); DATA(insert ( 4056 25 25 2 3384 )); DATA(insert ( 4056 25 25 3 3385 )); ! DATA(insert ( 4056 25 25 4 3394 )); DATA(insert ( 4056 25 25 5 740 )); DATA(insert ( 4056 25 25 6 741 )); DATA(insert ( 4056 25 25 7 743 )); DATA(insert ( 4056 25 25 8 742 )); ! DATA(insert ( 4057 1083 1083 1 3388 )); DATA(insert ( 4057 1083 1083 2 3384 )); DATA(insert ( 4057 1083 1083 3 3385 )); ! DATA(insert ( 4057 1083 1083 4 3394 )); DATA(insert ( 4057 1083 1083 5 1102 )); DATA(insert ( 4057 1083 1083 6 1103 )); DATA(insert ( 4057 1083 1083 7 1105 )); DATA(insert ( 4057 1083 1083 8 1104 )); ! DATA(insert ( 4058 1266 1266 1 3389 )); DATA(insert ( 4058 1266 1266 2 3384 )); DATA(insert ( 4058 1266 1266 3 3385 )); ! DATA(insert ( 4058 1266 1266 4 3394 )); DATA(insert ( 4058 1266 1266 5 1354 )); DATA(insert ( 4058 1266 1266 6 1355 )); DATA(insert ( 4058 1266 1266 7 1356 )); DATA(insert ( 4058 1266 1266 8 1357 )); ! DATA(insert ( 4059 1114 1114 1 3390 )); DATA(insert ( 4059 1114 1114 2 3384 )); DATA(insert ( 4059 1114 1114 3 3385 )); ! DATA(insert ( 4059 1114 1114 4 3394 )); DATA(insert ( 4059 1114 1114 5 2054 )); DATA(insert ( 4059 1114 1114 6 2055 )); DATA(insert ( 4059 1114 1114 7 2056 )); DATA(insert ( 4059 1114 1114 8 2057 )); ! DATA(insert ( 4060 1184 1184 1 3391 )); DATA(insert ( 4060 1184 1184 2 3384 )); DATA(insert ( 4060 1184 1184 3 3385 )); ! DATA(insert ( 4060 1184 1184 4 3394 )); DATA(insert ( 4060 1184 1184 5 1154 )); DATA(insert ( 4060 1184 1184 6 1155 )); DATA(insert ( 4060 1184 1184 7 1156 )); DATA(insert ( 4060 1184 1184 8 1157 )); ! DATA(insert ( 4061 1082 1082 1 3392 )); DATA(insert ( 4061 1082 1082 2 3384 )); DATA(insert ( 4061 1082 1082 3 3385 )); ! DATA(insert ( 4061 1082 1082 4 3394 )); DATA(insert ( 4061 1082 1082 5 1087 )); DATA(insert ( 4061 1082 1082 6 1088 )); DATA(insert ( 4061 1082 1082 7 1090 )); DATA(insert ( 4061 1082 1082 8 1089 )); ! DATA(insert ( 4062 18 18 1 3393 )); DATA(insert ( 4062 18 18 2 3384 )); DATA(insert ( 4062 18 18 3 3385 )); ! DATA(insert ( 4062 18 18 4 3394 )); DATA(insert ( 4062 18 18 5 1246 )); DATA(insert ( 4062 18 18 6 72 )); DATA(insert ( 4062 18 18 7 74 )); --- 436,514 ---- DATA(insert ( 4054 23 23 1 3383 )); DATA(insert ( 4054 23 23 2 3384 )); DATA(insert ( 4054 23 23 3 3385 )); ! DATA(insert ( 4054 23 23 4 3386 )); DATA(insert ( 4054 23 23 5 66 )); DATA(insert ( 4054 23 23 6 149 )); DATA(insert ( 4054 23 23 7 150 )); DATA(insert ( 4054 23 23 8 147 )); ! DATA(insert ( 4055 1700 1700 1 3383 )); DATA(insert ( 4055 1700 1700 2 3384 )); DATA(insert ( 4055 1700 1700 3 3385 )); ! DATA(insert ( 4055 1700 1700 4 3386 )); DATA(insert ( 4055 1700 1700 5 1722 )); DATA(insert ( 4055 1700 1700 6 1723 )); DATA(insert ( 4055 1700 1700 7 1721 )); DATA(insert ( 4055 1700 1700 8 1720 )); ! DATA(insert ( 4056 25 25 1 3383 )); DATA(insert ( 4056 25 25 2 3384 )); DATA(insert ( 4056 25 25 3 3385 )); ! DATA(insert ( 4056 25 25 4 3386 )); DATA(insert ( 4056 25 25 5 740 )); DATA(insert ( 4056 25 25 6 741 )); DATA(insert ( 4056 25 25 7 743 )); DATA(insert ( 4056 25 25 8 742 )); ! DATA(insert ( 4057 1083 1083 1 3383 )); DATA(insert ( 4057 1083 1083 2 3384 )); DATA(insert ( 4057 1083 1083 3 3385 )); ! DATA(insert ( 4057 1083 1083 4 3386 )); DATA(insert ( 4057 1083 1083 5 1102 )); DATA(insert ( 4057 1083 1083 6 1103 )); DATA(insert ( 4057 1083 1083 7 1105 )); DATA(insert ( 4057 1083 1083 8 1104 )); ! DATA(insert ( 4058 1266 1266 1 3383 )); DATA(insert ( 4058 1266 1266 2 3384 )); DATA(insert ( 4058 1266 1266 3 3385 )); ! DATA(insert ( 4058 1266 1266 4 3386 )); DATA(insert ( 4058 1266 1266 5 1354 )); DATA(insert ( 4058 1266 1266 6 1355 )); DATA(insert ( 4058 1266 1266 7 1356 )); DATA(insert ( 4058 1266 1266 8 1357 )); ! DATA(insert ( 4059 1114 1114 1 3383 )); DATA(insert ( 4059 1114 1114 2 3384 )); DATA(insert ( 4059 1114 1114 3 3385 )); ! DATA(insert ( 4059 1114 1114 4 3386 )); DATA(insert ( 4059 1114 1114 5 2054 )); DATA(insert ( 4059 1114 1114 6 2055 )); DATA(insert ( 4059 1114 1114 7 2056 )); DATA(insert ( 4059 1114 1114 8 2057 )); ! DATA(insert ( 4060 1184 1184 1 3383 )); DATA(insert ( 4060 1184 1184 2 3384 )); DATA(insert ( 4060 1184 1184 3 3385 )); ! DATA(insert ( 4060 1184 1184 4 3386 )); DATA(insert ( 4060 1184 1184 5 1154 )); DATA(insert ( 4060 1184 1184 6 1155 )); DATA(insert ( 4060 1184 1184 7 1156 )); DATA(insert ( 4060 1184 1184 8 1157 )); ! DATA(insert ( 4061 1082 1082 1 3383 )); DATA(insert ( 4061 1082 1082 2 3384 )); DATA(insert ( 4061 1082 1082 3 3385 )); ! DATA(insert ( 4061 1082 1082 4 3386 )); DATA(insert ( 4061 1082 1082 5 1087 )); DATA(insert ( 4061 1082 1082 6 1088 )); DATA(insert ( 4061 1082 1082 7 1090 )); DATA(insert ( 4061 1082 1082 8 1089 )); ! DATA(insert ( 4062 18 18 1 3383 )); DATA(insert ( 4062 18 18 2 3384 )); DATA(insert ( 4062 18 18 3 3385 )); ! DATA(insert ( 4062 18 18 4 3386 )); DATA(insert ( 4062 18 18 5 1246 )); DATA(insert ( 4062 18 18 6 72 )); DATA(insert ( 4062 18 18 7 74 )); *** a/src/include/catalog/pg_proc.h --- b/src/include/catalog/pg_proc.h *************** *** 4106,4135 **** DATA(insert OID = 2747 ( arrayoverlap PGNSP PGUID 12 1 0 0 0 f f f f t f i DATA(insert OID = 2748 ( arraycontains PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2277 2277" _null_ _null_ _null_ _null_ arraycontains _null_ _null_ _null_ )); DATA(insert OID = 2749 ( arraycontained PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2277 2277" _null_ _null_ _null_ _null_ arraycontained _null_ _null_ _null_ )); ! /* Minmax */ ! DATA(insert OID = 3384 ( minmax_add_value PGNSP PGUID 12 1 0 0 0 f f f f t f i 5 0 16 "2281 2281 2281 2281 2281" _null_ _null_ _null_ _null_ minmaxAddValue _null_ _null_ _null_ )); DESCR("BRIN minmax support"); ! DATA(insert OID = 3385 ( minmax_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 16 "2281 2281 2281" _null_ _null_ _null_ _null_ minmaxConsistent _null_ _null_ _null_ )); DESCR("BRIN minmax support"); ! DATA(insert OID = 3394 ( minmax_union PGNSP PGUID 12 1 0 0 0 f f f f t f i 4 0 16 "2281 2281 2281 2281" _null_ _null_ _null_ _null_ minmaxUnion _null_ _null_ _null_ )); DESCR("BRIN minmax support"); ! DATA(insert OID = 3383 ( minmax_sortable_opcinfo_int4 PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ minmaxOpcInfo_int4 _null_ _null_ _null_ )); ! DESCR("BRIN minmax support"); ! DATA(insert OID = 3386 ( minmax_sortable_opcinfo_numeric PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ minmaxOpcInfo_numeric _null_ _null_ _null_ )); ! DESCR("BRIN minmax support"); ! DATA(insert OID = 3387 ( minmax_sortable_opcinfo_text PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ minmaxOpcInfo_text _null_ _null_ _null_ )); ! DESCR("BRIN minmax support"); ! DATA(insert OID = 3388 ( minmax_sortable_opcinfo_time PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ minmaxOpcInfo_time _null_ _null_ _null_ )); ! DESCR("BRIN minmax support"); ! DATA(insert OID = 3389 ( minmax_sortable_opcinfo_timetz PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ minmaxOpcInfo_timetz _null_ _null_ _null_ )); ! DESCR("BRIN minmax support"); ! DATA(insert OID = 3390 ( minmax_sortable_opcinfo_timestamp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ minmaxOpcInfo_timestamp _null_ _null_ _null_ )); ! DESCR("BRIN minmax support"); ! DATA(insert OID = 3391 ( minmax_sortable_opcinfo_timestamptz PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ minmaxOpcInfo_timestamptz _null_ _null_ _null_ )); ! DESCR("BRIN minmax support"); ! DATA(insert OID = 3392 ( minmax_sortable_opcinfo_date PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ minmaxOpcInfo_date _null_ _null_ _null_ )); ! DESCR("BRIN minmax support"); ! DATA(insert OID = 3393 ( minmax_sortable_opcinfo_char PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ minmaxOpcInfo_char _null_ _null_ _null_ )); DESCR("BRIN minmax support"); /* userlock replacements */ --- 4106,4119 ---- DATA(insert OID = 2748 ( arraycontains PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2277 2277" _null_ _null_ _null_ _null_ arraycontains _null_ _null_ _null_ )); DATA(insert OID = 2749 ( arraycontained PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2277 2277" _null_ _null_ _null_ _null_ arraycontained _null_ _null_ _null_ )); ! /* BRIN minmax */ ! DATA(insert OID = 3383 ( brin_minmax_opcinfo PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ minmaxOpcInfo _null_ _null_ _null_ )); DESCR("BRIN minmax support"); ! DATA(insert OID = 3384 ( brin_minmax_add_value PGNSP PGUID 12 1 0 0 0 f f f f t f i 4 0 16 "2281 2281 2281 2281" _null_ _null_ _null_ _null_ minmaxAddValue _null_ _null_ _null_ )); DESCR("BRIN minmax support"); ! DATA(insert OID = 3385 ( brin_minmax_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 16 "2281 2281 2281" _null_ _null_ _null_ _null_ minmaxConsistent _null_ _null_ _null_ )); DESCR("BRIN minmax support"); ! DATA(insert OID = 3386 ( brin_minmax_union PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 16 "2281 2281 2281" _null_ _null_ _null_ _null_ minmaxUnion _null_ _null_ _null_ )); DESCR("BRIN minmax support"); /* userlock replacements */
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers