diff options
Diffstat (limited to 'contrib/ltree/_ltree_op.c')
-rw-r--r-- | contrib/ltree/_ltree_op.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/contrib/ltree/_ltree_op.c b/contrib/ltree/_ltree_op.c index 3df2d962d4e..cc7a16c27e6 100644 --- a/contrib/ltree/_ltree_op.c +++ b/contrib/ltree/_ltree_op.c @@ -28,6 +28,8 @@ Datum _ltree_extract_risparent(PG_FUNCTION_ARGS); Datum _ltq_extract_regex(PG_FUNCTION_ARGS); Datum _ltxtq_extract_exec(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(_lca); +Datum _lca(PG_FUNCTION_ARGS); typedef Datum (*PGCALL2)(PG_FUNCTION_ARGS); #define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) ) @@ -210,3 +212,27 @@ _ltxtq_extract_exec(PG_FUNCTION_ARGS) { PG_RETURN_POINTER(item); } +Datum +_lca(PG_FUNCTION_ARGS) { + ArrayType *la = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); + int num=ArrayGetNItems( ARR_NDIM(la), ARR_DIMS(la)); + ltree *item = (ltree*)ARR_DATA_PTR(la); + ltree **a,*res; + + a=(ltree**)palloc( sizeof(ltree*) * num ); + while( num>0 ) { + num--; + a[num] = item; + item = NEXTVAL(item); + } + res = lca_inner(a, ArrayGetNItems( ARR_NDIM(la), ARR_DIMS(la))); + pfree(a); + + PG_FREE_IF_COPY(la,0); + + if ( res ) + PG_RETURN_POINTER(res); + else + PG_RETURN_NULL(); +} + |