public inbox for [email protected]help / color / mirror / Atom feed
Arrays of domains 38+ messages / 5 participants [nested] [flat]
* Arrays of domains @ 2017-07-11 16:44 Tom Lane <[email protected]> 0 siblings, 3 replies; 38+ messages in thread From: Tom Lane @ 2017-07-11 16:44 UTC (permalink / raw) To: pgsql-hackers Over in https://www.postgresql.org/message-id/[email protected] there's a gripe about array_agg() not working for a domain type. It fails because we don't create an array type over a domain type, so the parser can't identify a suitable output type for the polymorphic aggregate. We could imagine tweaking the polymorphic-function resolution rules so that a domain matched to ANYELEMENT is smashed to its base type, allowing ANYARRAY to be resolved as the base type's array type. While that would be a pretty localized fix, it seems like a kluge to me. Probably a better answer is to start supporting arrays over domain types. That was left unimplemented in the original domains patch, but AFAICS not for any better reason than lack of round tuits. I did find an argument here: https://www.postgresql.org/message-id/[email protected] that the SQL spec forbids domains over arrays, but that's the opposite case (and a restriction we long since ignored, anyway). Can anyone think of a reason not to pursue that? regards, tom lane -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: Arrays of domains @ 2017-07-11 17:45 David Fetter <[email protected]> parent: Tom Lane <[email protected]> 2 siblings, 0 replies; 38+ messages in thread From: David Fetter @ 2017-07-11 17:45 UTC (permalink / raw) To: Tom Lane <[email protected]>; +Cc: pgsql-hackers On Tue, Jul 11, 2017 at 12:44:33PM -0400, Tom Lane wrote: > Over in > https://www.postgresql.org/message-id/[email protected] > there's a gripe about array_agg() not working for a domain type. > It fails because we don't create an array type over a domain type, > so the parser can't identify a suitable output type for the polymorphic > aggregate. > > We could imagine tweaking the polymorphic-function resolution rules > so that a domain matched to ANYELEMENT is smashed to its base type, > allowing ANYARRAY to be resolved as the base type's array type. > While that would be a pretty localized fix, it seems like a kluge > to me. > > Probably a better answer is to start supporting arrays over domain > types. That was left unimplemented in the original domains patch, > but AFAICS not for any better reason than lack of round tuits. > I did find an argument here: > https://www.postgresql.org/message-id/[email protected] > that the SQL spec forbids domains over arrays, but that's the opposite > case (and a restriction we long since ignored, anyway). > > Can anyone think of a reason not to pursue that? +1 for pursuing it. When operations just compose, users get a more fun experience. Best, David. -- David Fetter <david(at)fetter(dot)org> http://fetter.org/ Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter Skype: davidfetter XMPP: david(dot)fetter(at)gmail(dot)com Remember to vote! Consider donating to Postgres: http://www.postgresql.org/about/donate -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: Arrays of domains @ 2017-07-11 17:58 Andrew Dunstan <[email protected]> parent: Tom Lane <[email protected]> 2 siblings, 0 replies; 38+ messages in thread From: Andrew Dunstan @ 2017-07-11 17:58 UTC (permalink / raw) To: Tom Lane <[email protected]>; pgsql-hackers On 07/11/2017 12:44 PM, Tom Lane wrote: > > Can anyone think of a reason not to pursue that? > > I'm all for it. cheers andrew -- Andrew Dunstan https://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: Arrays of domains @ 2017-08-11 17:17 Tom Lane <[email protected]> parent: Tom Lane <[email protected]> 2 siblings, 2 replies; 38+ messages in thread From: Tom Lane @ 2017-08-11 17:17 UTC (permalink / raw) To: pgsql-hackers I wrote: > Probably a better answer is to start supporting arrays over domain > types. That was left unimplemented in the original domains patch, > but AFAICS not for any better reason than lack of round tuits. Attached is a patch series that allows us to create arrays of domain types. I haven't tested this in great detail, so there might be some additional corners of the system that need work, but it passes basic sanity checks. I believe it's independent of the other patch I have in the commitfest for domains over composites, but I haven't tested for interactions there either. 01-rationalize-coercion-APIs.patch cleans up the APIs of coerce_to_domain() and some internal functions in parse_coerce.c so that we consistently pass around a CoercionContext along with CoercionForm. Previously, we sometimes passed an "isExplicit" boolean flag instead, which is strictly less information; and coerce_to_domain() didn't even get that, but instead had to reverse-engineer isExplicit from CoercionForm. That's contrary to the documentation in primnodes.h that says that CoercionForm only affects display and not semantics. I don't think this change fixes any live bugs, but it makes things more consistent. The main reason for doing it though is that now build_coercion_expression() receives ccontext, which it needs in order to be able to recursively invoke coerce_to_target_type(), as required by the next patch. 02-reimplement-ArrayCoerceExpr.patch is the core of the patch. It changes ArrayCoerceExpr so that the node does not directly know any details of what has to be done to the individual array elements while performing the array coercion. Instead, the per-element processing is represented by a sub-expression whose input is a source array element and whose output is a target array element. This simplifies life in parse_coerce.c, because it can build that sub-expression by a recursive invocation of coerce_to_target_type(), and it allows the executor to handle the per-element processing as a compiled expression instead of hard-wired code. This is probably about a wash or a small loss performance-wise for the simplest case where we just need to invoke one coercion function for each element. However, there are many cases where the existing code ends up generating two nested ArrayCoerceExprs, one to do the type conversion and one to apply a typmod (length) coercion function. In the new code there will be just one ArrayCoerceExpr, saving one deconstruction and reconstruction of the array. If I hadn't done it like this, adding domains into the mix could have produced as many as three ArrayCoerceExprs, where the top one would have only checked domain constraints; that did not sound nice performance-wise, and it would have required a lot of code duplication as well. Finally, 03-support-arrays-of-domains.patch simply turns on the spigot by creating an array type in DefineDomain(), and adds some test cases. Given the new method of handling ArrayCoerceExpr, everything Just Works. I'll add this to the next commitfest. regards, tom lane -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers Attachments: [text/x-diff] 01-rationalize-coercion-APIs.patch (14.3K, ../../[email protected]/2-01-rationalize-coercion-APIs.patch) download | inline diff: diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c index afc733f..277ca8b 100644 *** a/src/backend/optimizer/prep/preptlist.c --- b/src/backend/optimizer/prep/preptlist.c *************** expand_targetlist(List *tlist, int comma *** 306,314 **** new_expr = coerce_to_domain(new_expr, InvalidOid, -1, atttype, COERCE_IMPLICIT_CAST, -1, - false, false); } else --- 306,314 ---- new_expr = coerce_to_domain(new_expr, InvalidOid, -1, atttype, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } else diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index 0bc7dba..c406cea 100644 *** a/src/backend/parser/parse_coerce.c --- b/src/backend/parser/parse_coerce.c *************** *** 34,48 **** static Node *coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit, bool hideInputCoercion); static void hide_coercion_node(Node *node); static Node *build_coercion_expression(Node *node, CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit); static Node *coerce_record_to_complex(ParseState *pstate, Node *node, Oid targetTypeId, CoercionContext ccontext, --- 34,49 ---- static Node *coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location, ! bool hideInputCoercion); static void hide_coercion_node(Node *node); static Node *build_coercion_expression(Node *node, CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location); static Node *coerce_record_to_complex(ParseState *pstate, Node *node, Oid targetTypeId, CoercionContext ccontext, *************** coerce_to_target_type(ParseState *pstate *** 110,117 **** */ result = coerce_type_typmod(result, targettype, targettypmod, ! cformat, location, ! (cformat != COERCE_IMPLICIT_CAST), (result != expr && !IsA(result, Const))); if (expr != origexpr) --- 111,117 ---- */ result = coerce_type_typmod(result, targettype, targettypmod, ! ccontext, cformat, location, (result != expr && !IsA(result, Const))); if (expr != origexpr) *************** coerce_type(ParseState *pstate, Node *no *** 355,361 **** result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! cformat, location, false, false); ReleaseSysCache(baseType); --- 355,362 ---- result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! ccontext, cformat, location, ! false); ReleaseSysCache(baseType); *************** coerce_type(ParseState *pstate, Node *no *** 417,436 **** result = build_coercion_expression(node, pathtype, funcId, baseTypeId, baseTypeMod, ! cformat, location, ! (cformat != COERCE_IMPLICIT_CAST)); /* * If domain, coerce to the domain type and relabel with domain ! * type ID. We can skip the internal length-coercion step if the ! * selected coercion function was a type-and-length coercion. */ if (targetTypeId != baseTypeId) result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! cformat, location, true, ! exprIsLengthCoercion(result, ! NULL)); } else { --- 418,434 ---- result = build_coercion_expression(node, pathtype, funcId, baseTypeId, baseTypeMod, ! ccontext, cformat, location); /* * If domain, coerce to the domain type and relabel with domain ! * type ID, hiding the previous coercion node. */ if (targetTypeId != baseTypeId) result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! ccontext, cformat, location, ! true); } else { *************** coerce_type(ParseState *pstate, Node *no *** 444,450 **** * then we won't need a RelabelType node. */ result = coerce_to_domain(node, InvalidOid, -1, targetTypeId, ! cformat, location, false, false); if (result == node) { /* --- 442,449 ---- * then we won't need a RelabelType node. */ result = coerce_to_domain(node, InvalidOid, -1, targetTypeId, ! ccontext, cformat, location, ! false); if (result == node) { /* *************** can_coerce_type(int nargs, Oid *input_ty *** 636,654 **** * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller * has not bothered to look this up) * 'typeId': target type to coerce to ! * 'cformat': coercion format * 'location': coercion request location * 'hideInputCoercion': if true, hide the input coercion under this one. - * 'lengthCoercionDone': if true, caller already accounted for length, - * ie the input is already of baseTypMod as well as baseTypeId. * * If the target type isn't a domain, the given 'arg' is returned as-is. */ Node * coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionForm cformat, int location, ! bool hideInputCoercion, ! bool lengthCoercionDone) { CoerceToDomain *result; --- 635,651 ---- * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller * has not bothered to look this up) * 'typeId': target type to coerce to ! * 'ccontext': context indicator to control coercions ! * 'cformat': coercion display format * 'location': coercion request location * 'hideInputCoercion': if true, hide the input coercion under this one. * * If the target type isn't a domain, the given 'arg' is returned as-is. */ Node * coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionContext ccontext, CoercionForm cformat, int location, ! bool hideInputCoercion) { CoerceToDomain *result; *************** coerce_to_domain(Node *arg, Oid baseType *** 677,690 **** * would be safe to do anyway, without lots of knowledge about what the * base type thinks the typmod means. */ ! if (!lengthCoercionDone) ! { ! if (baseTypeMod >= 0) ! arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod, ! COERCE_IMPLICIT_CAST, location, ! (cformat != COERCE_IMPLICIT_CAST), ! false); ! } /* * Now build the domain coercion node. This represents run-time checking --- 674,682 ---- * would be safe to do anyway, without lots of knowledge about what the * base type thinks the typmod means. */ ! arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod, ! ccontext, COERCE_IMPLICIT_CAST, location, ! false); /* * Now build the domain coercion node. This represents run-time checking *************** coerce_to_domain(Node *arg, Oid baseType *** 714,724 **** * The caller must have already ensured that the value is of the correct * type, typically by applying coerce_type. * ! * cformat determines the display properties of the generated node (if any), ! * while isExplicit may affect semantics. If hideInputCoercion is true ! * *and* we generate a node, the input node is forced to IMPLICIT display ! * form, so that only the typmod coercion node will be visible when ! * displaying the expression. * * NOTE: this does not need to work on domain types, because any typmod * coercion for a domain is considered to be part of the type coercion --- 706,719 ---- * The caller must have already ensured that the value is of the correct * type, typically by applying coerce_type. * ! * ccontext may affect semantics, depending on whether the length coercion ! * function pays attention to the isExplicit flag it's passed. ! * ! * cformat determines the display properties of the generated node (if any). ! * ! * If hideInputCoercion is true *and* we generate a node, the input node is ! * forced to IMPLICIT display form, so that only the typmod coercion node will ! * be visible when displaying the expression. * * NOTE: this does not need to work on domain types, because any typmod * coercion for a domain is considered to be part of the type coercion *************** coerce_to_domain(Node *arg, Oid baseType *** 726,733 **** */ static Node * coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit, bool hideInputCoercion) { CoercionPathType pathtype; Oid funcId; --- 721,729 ---- */ static Node * coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location, ! bool hideInputCoercion) { CoercionPathType pathtype; Oid funcId; *************** coerce_type_typmod(Node *node, Oid targe *** 749,756 **** node = build_coercion_expression(node, pathtype, funcId, targetTypeId, targetTypMod, ! cformat, location, ! isExplicit); } return node; --- 745,751 ---- node = build_coercion_expression(node, pathtype, funcId, targetTypeId, targetTypMod, ! ccontext, cformat, location); } return node; *************** build_coercion_expression(Node *node, *** 799,806 **** CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit) { int nargs = 0; --- 794,801 ---- CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location) { int nargs = 0; *************** build_coercion_expression(Node *node, *** 865,871 **** -1, InvalidOid, sizeof(bool), ! BoolGetDatum(isExplicit), false, true); --- 860,866 ---- -1, InvalidOid, sizeof(bool), ! BoolGetDatum(ccontext == COERCION_EXPLICIT), false, true); *************** build_coercion_expression(Node *node, *** 893,899 **** */ acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1; /* resultcollid will be set by parse_collate.c */ ! acoerce->isExplicit = isExplicit; acoerce->coerceformat = cformat; acoerce->location = location; --- 888,894 ---- */ acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1; /* resultcollid will be set by parse_collate.c */ ! acoerce->isExplicit = (ccontext == COERCION_EXPLICIT); acoerce->coerceformat = cformat; acoerce->location = location; diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index 6b79c69..a2841d2 100644 *** a/src/backend/rewrite/rewriteHandler.c --- b/src/backend/rewrite/rewriteHandler.c *************** rewriteTargetListIU(List *targetList, *** 875,883 **** new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, COERCE_IMPLICIT_CAST, -1, - false, false); } } --- 875,883 ---- new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } } *************** rewriteValuesRTE(RangeTblEntry *rte, Rel *** 1271,1279 **** new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, COERCE_IMPLICIT_CAST, -1, - false, false); } newList = lappend(newList, new_expr); --- 1271,1279 ---- new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } newList = lappend(newList, new_expr); diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c index ba706b2..d962ae3 100644 *** a/src/backend/rewrite/rewriteManip.c --- b/src/backend/rewrite/rewriteManip.c *************** ReplaceVarsFromTargetList_callback(Var * *** 1429,1437 **** var->varcollid), InvalidOid, -1, var->vartype, COERCE_IMPLICIT_CAST, -1, - false, false); } elog(ERROR, "could not find replacement targetlist entry for attno %d", --- 1429,1437 ---- var->varcollid), InvalidOid, -1, var->vartype, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } elog(ERROR, "could not find replacement targetlist entry for attno %d", diff --git a/src/include/parser/parse_coerce.h b/src/include/parser/parse_coerce.h index 06f6529..e560f0c 100644 *** a/src/include/parser/parse_coerce.h --- b/src/include/parser/parse_coerce.h *************** extern Node *coerce_type(ParseState *pst *** 48,56 **** CoercionContext ccontext, CoercionForm cformat, int location); extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionForm cformat, int location, ! bool hideInputCoercion, ! bool lengthCoercionDone); extern Node *coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName); --- 48,55 ---- CoercionContext ccontext, CoercionForm cformat, int location); extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionContext ccontext, CoercionForm cformat, int location, ! bool hideInputCoercion); extern Node *coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName); [text/x-diff] 02-reimplement-ArrayCoerceExpr.patch (43.4K, ../../[email protected]/3-02-reimplement-ArrayCoerceExpr.patch) download | inline diff: diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index fa409d7..1776730 100644 *** a/contrib/pg_stat_statements/pg_stat_statements.c --- b/contrib/pg_stat_statements/pg_stat_statements.c *************** JumbleExpr(pgssJumbleState *jstate, Node *** 2631,2636 **** --- 2631,2637 ---- APP_JUMB(acexpr->resulttype); JumbleExpr(jstate, (Node *) acexpr->arg); + JumbleExpr(jstate, (Node *) acexpr->elemexpr); } break; case T_ConvertRowtypeExpr: diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 6fffc29..2668650 100644 *** a/src/backend/catalog/dependency.c --- b/src/backend/catalog/dependency.c *************** find_expr_references_walker(Node *node, *** 1738,1748 **** { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! if (OidIsValid(acoerce->elemfuncid)) ! add_object_address(OCLASS_PROC, acoerce->elemfuncid, 0, ! context->addrs); add_object_address(OCLASS_TYPE, acoerce->resulttype, 0, context->addrs); /* fall through to examine arguments */ } else if (IsA(node, ConvertRowtypeExpr)) --- 1738,1751 ---- { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! /* as above, depend on type */ add_object_address(OCLASS_TYPE, acoerce->resulttype, 0, context->addrs); + /* the collation might not be referenced anywhere else, either */ + if (OidIsValid(acoerce->resultcollid) && + acoerce->resultcollid != DEFAULT_COLLATION_OID) + add_object_address(OCLASS_COLLATION, acoerce->resultcollid, 0, + context->addrs); /* fall through to examine arguments */ } else if (IsA(node, ConvertRowtypeExpr)) diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index 7496189..6337bfa 100644 *** a/src/backend/executor/execExpr.c --- b/src/backend/executor/execExpr.c *************** ExecInitExprRec(Expr *node, PlanState *p *** 1225,1230 **** --- 1225,1231 ---- { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; Oid resultelemtype; + ExprState *elemstate; /* evaluate argument into step's result area */ ExecInitExprRec(acoerce->arg, parent, state, resv, resnull); *************** ExecInitExprRec(Expr *node, PlanState *p *** 1234,1275 **** ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("target type is not an array"))); - /* Arrays over domains aren't supported yet */ - Assert(getBaseType(resultelemtype) == resultelemtype); ! scratch.opcode = EEOP_ARRAYCOERCE; ! scratch.d.arraycoerce.coerceexpr = acoerce; ! scratch.d.arraycoerce.resultelemtype = resultelemtype; ! if (OidIsValid(acoerce->elemfuncid)) ! { ! AclResult aclresult; ! /* Check permission to call function */ ! aclresult = pg_proc_aclcheck(acoerce->elemfuncid, ! GetUserId(), ! ACL_EXECUTE); ! if (aclresult != ACLCHECK_OK) ! aclcheck_error(aclresult, ACL_KIND_PROC, ! get_func_name(acoerce->elemfuncid)); ! InvokeFunctionExecuteHook(acoerce->elemfuncid); ! /* Set up the primary fmgr lookup information */ ! scratch.d.arraycoerce.elemfunc = ! (FmgrInfo *) palloc0(sizeof(FmgrInfo)); ! fmgr_info(acoerce->elemfuncid, ! scratch.d.arraycoerce.elemfunc); ! fmgr_info_set_expr((Node *) acoerce, ! scratch.d.arraycoerce.elemfunc); /* Set up workspace for array_map */ scratch.d.arraycoerce.amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState)); } else { ! /* Don't need workspace if there's no conversion func */ ! scratch.d.arraycoerce.elemfunc = NULL; scratch.d.arraycoerce.amstate = NULL; } --- 1235,1283 ---- ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("target type is not an array"))); ! /* ! * Construct a sub-expression for the per-element expression; ! * but don't ready it until after we check it for triviality. ! * We assume it hasn't any Var references, but does have a ! * CaseTestExpr representing the source array element values. ! */ ! elemstate = makeNode(ExprState); ! elemstate->expr = acoerce->elemexpr; ! elemstate->innermost_caseval = (Datum *) palloc(sizeof(Datum)); ! elemstate->innermost_casenull = (bool *) palloc(sizeof(bool)); ! ExecInitExprRec(acoerce->elemexpr, parent, elemstate, ! &elemstate->resvalue, &elemstate->resnull); ! if (elemstate->steps_len == 1 && ! elemstate->steps[0].opcode == EEOP_CASE_TESTVAL) ! { ! /* Trivial, so we need no per-element work at runtime */ ! elemstate = NULL; ! } ! else ! { ! /* Not trivial, so append a DONE step */ ! scratch.opcode = EEOP_DONE; ! ExprEvalPushStep(elemstate, &scratch); ! /* and ready the subexpression */ ! ExecReadyExpr(elemstate); ! } ! scratch.opcode = EEOP_ARRAYCOERCE; ! scratch.d.arraycoerce.elemexprstate = elemstate; ! scratch.d.arraycoerce.resultelemtype = resultelemtype; + if (elemstate) + { /* Set up workspace for array_map */ scratch.d.arraycoerce.amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState)); } else { ! /* Don't need workspace if there's no subexpression */ scratch.d.arraycoerce.amstate = NULL; } diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index f2a52f6..98fa93e 100644 *** a/src/backend/executor/execExprInterp.c --- b/src/backend/executor/execExprInterp.c *************** ExecInterpExpr(ExprState *state, ExprCon *** 1252,1258 **** EEO_CASE(EEOP_ARRAYCOERCE) { /* too complex for an inline implementation */ ! ExecEvalArrayCoerce(state, op); EEO_NEXT(); } --- 1252,1258 ---- EEO_CASE(EEOP_ARRAYCOERCE) { /* too complex for an inline implementation */ ! ExecEvalArrayCoerce(state, op, econtext); EEO_NEXT(); } *************** ExecEvalArrayExpr(ExprState *state, Expr *** 2328,2338 **** * Source array is in step's result variable. */ void ! ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op) { - ArrayCoerceExpr *acoerce = op->d.arraycoerce.coerceexpr; Datum arraydatum; - FunctionCallInfoData locfcinfo; /* NULL array -> NULL result */ if (*op->resnull) --- 2328,2336 ---- * Source array is in step's result variable. */ void ! ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op, ExprContext *econtext) { Datum arraydatum; /* NULL array -> NULL result */ if (*op->resnull) *************** ExecEvalArrayCoerce(ExprState *state, Ex *** 2344,2350 **** * If it's binary-compatible, modify the element type in the array header, * but otherwise leave the array as we received it. */ ! if (!OidIsValid(acoerce->elemfuncid)) { /* Detoast input array if necessary, and copy in any case */ ArrayType *array = DatumGetArrayTypePCopy(arraydatum); --- 2342,2348 ---- * If it's binary-compatible, modify the element type in the array header, * but otherwise leave the array as we received it. */ ! if (op->d.arraycoerce.elemexprstate == NULL) { /* Detoast input array if necessary, and copy in any case */ ArrayType *array = DatumGetArrayTypePCopy(arraydatum); *************** ExecEvalArrayCoerce(ExprState *state, Ex *** 2355,2377 **** } /* ! * Use array_map to apply the function to each array element. ! * ! * We pass on the desttypmod and isExplicit flags whether or not the ! * function wants them. ! * ! * Note: coercion functions are assumed to not use collation. */ ! InitFunctionCallInfoData(locfcinfo, op->d.arraycoerce.elemfunc, 3, ! InvalidOid, NULL, NULL); ! locfcinfo.arg[0] = arraydatum; ! locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod); ! locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit); ! locfcinfo.argnull[0] = false; ! locfcinfo.argnull[1] = false; ! locfcinfo.argnull[2] = false; ! ! *op->resvalue = array_map(&locfcinfo, op->d.arraycoerce.resultelemtype, op->d.arraycoerce.amstate); } --- 2353,2364 ---- } /* ! * Use array_map to apply the sub-expression to each array element. */ ! *op->resvalue = array_map(arraydatum, ! op->d.arraycoerce.elemexprstate, ! econtext, ! op->d.arraycoerce.resultelemtype, op->d.arraycoerce.amstate); } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 45a04b0..9655f4a 100644 *** a/src/backend/nodes/copyfuncs.c --- b/src/backend/nodes/copyfuncs.c *************** _copyArrayCoerceExpr(const ArrayCoerceEx *** 1696,1706 **** ArrayCoerceExpr *newnode = makeNode(ArrayCoerceExpr); COPY_NODE_FIELD(arg); ! COPY_SCALAR_FIELD(elemfuncid); COPY_SCALAR_FIELD(resulttype); COPY_SCALAR_FIELD(resulttypmod); COPY_SCALAR_FIELD(resultcollid); - COPY_SCALAR_FIELD(isExplicit); COPY_SCALAR_FIELD(coerceformat); COPY_LOCATION_FIELD(location); --- 1696,1705 ---- ArrayCoerceExpr *newnode = makeNode(ArrayCoerceExpr); COPY_NODE_FIELD(arg); ! COPY_NODE_FIELD(elemexpr); COPY_SCALAR_FIELD(resulttype); COPY_SCALAR_FIELD(resulttypmod); COPY_SCALAR_FIELD(resultcollid); COPY_SCALAR_FIELD(coerceformat); COPY_LOCATION_FIELD(location); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 8d92c03..9fdc887 100644 *** a/src/backend/nodes/equalfuncs.c --- b/src/backend/nodes/equalfuncs.c *************** static bool *** 513,523 **** _equalArrayCoerceExpr(const ArrayCoerceExpr *a, const ArrayCoerceExpr *b) { COMPARE_NODE_FIELD(arg); ! COMPARE_SCALAR_FIELD(elemfuncid); COMPARE_SCALAR_FIELD(resulttype); COMPARE_SCALAR_FIELD(resulttypmod); COMPARE_SCALAR_FIELD(resultcollid); - COMPARE_SCALAR_FIELD(isExplicit); COMPARE_COERCIONFORM_FIELD(coerceformat); COMPARE_LOCATION_FIELD(location); --- 513,522 ---- _equalArrayCoerceExpr(const ArrayCoerceExpr *a, const ArrayCoerceExpr *b) { COMPARE_NODE_FIELD(arg); ! COMPARE_NODE_FIELD(elemexpr); COMPARE_SCALAR_FIELD(resulttype); COMPARE_SCALAR_FIELD(resulttypmod); COMPARE_SCALAR_FIELD(resultcollid); COMPARE_COERCIONFORM_FIELD(coerceformat); COMPARE_LOCATION_FIELD(location); diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index e3eb0c5..8e6f27e 100644 *** a/src/backend/nodes/nodeFuncs.c --- b/src/backend/nodes/nodeFuncs.c *************** check_functions_in_node(Node *node, chec *** 1717,1731 **** return true; } break; - case T_ArrayCoerceExpr: - { - ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; - - if (OidIsValid(expr->elemfuncid) && - checker(expr->elemfuncid, context)) - return true; - } - break; case T_RowCompareExpr: { RowCompareExpr *rcexpr = (RowCompareExpr *) node; --- 1717,1722 ---- *************** expression_tree_walker(Node *node, *** 2023,2029 **** case T_CoerceViaIO: return walker(((CoerceViaIO *) node)->arg, context); case T_ArrayCoerceExpr: ! return walker(((ArrayCoerceExpr *) node)->arg, context); case T_ConvertRowtypeExpr: return walker(((ConvertRowtypeExpr *) node)->arg, context); case T_CollateExpr: --- 2014,2028 ---- case T_CoerceViaIO: return walker(((CoerceViaIO *) node)->arg, context); case T_ArrayCoerceExpr: ! { ! ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! ! if (walker(acoerce->arg, context)) ! return true; ! if (walker(acoerce->elemexpr, context)) ! return true; ! } ! break; case T_ConvertRowtypeExpr: return walker(((ConvertRowtypeExpr *) node)->arg, context); case T_CollateExpr: *************** expression_tree_mutator(Node *node, *** 2705,2710 **** --- 2704,2710 ---- FLATCOPY(newnode, acoerce, ArrayCoerceExpr); MUTATE(newnode->arg, acoerce->arg, Expr *); + MUTATE(newnode->elemexpr, acoerce->elemexpr, Expr *); return (Node *) newnode; } break; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 379d92a..21cdf90 100644 *** a/src/backend/nodes/outfuncs.c --- b/src/backend/nodes/outfuncs.c *************** _outArrayCoerceExpr(StringInfo str, cons *** 1392,1402 **** WRITE_NODE_TYPE("ARRAYCOERCEEXPR"); WRITE_NODE_FIELD(arg); ! WRITE_OID_FIELD(elemfuncid); WRITE_OID_FIELD(resulttype); WRITE_INT_FIELD(resulttypmod); WRITE_OID_FIELD(resultcollid); - WRITE_BOOL_FIELD(isExplicit); WRITE_ENUM_FIELD(coerceformat, CoercionForm); WRITE_LOCATION_FIELD(location); } --- 1392,1401 ---- WRITE_NODE_TYPE("ARRAYCOERCEEXPR"); WRITE_NODE_FIELD(arg); ! WRITE_NODE_FIELD(elemexpr); WRITE_OID_FIELD(resulttype); WRITE_INT_FIELD(resulttypmod); WRITE_OID_FIELD(resultcollid); WRITE_ENUM_FIELD(coerceformat, CoercionForm); WRITE_LOCATION_FIELD(location); } diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 86c811d..76ba570 100644 *** a/src/backend/nodes/readfuncs.c --- b/src/backend/nodes/readfuncs.c *************** _readArrayCoerceExpr(void) *** 892,902 **** READ_LOCALS(ArrayCoerceExpr); READ_NODE_FIELD(arg); ! READ_OID_FIELD(elemfuncid); READ_OID_FIELD(resulttype); READ_INT_FIELD(resulttypmod); READ_OID_FIELD(resultcollid); - READ_BOOL_FIELD(isExplicit); READ_ENUM_FIELD(coerceformat, CoercionForm); READ_LOCATION_FIELD(location); --- 892,901 ---- READ_LOCALS(ArrayCoerceExpr); READ_NODE_FIELD(arg); ! READ_NODE_FIELD(elemexpr); READ_OID_FIELD(resulttype); READ_INT_FIELD(resulttypmod); READ_OID_FIELD(resultcollid); READ_ENUM_FIELD(coerceformat, CoercionForm); READ_LOCATION_FIELD(location); diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index b35acb7..3721a49 100644 *** a/src/backend/optimizer/path/costsize.c --- b/src/backend/optimizer/path/costsize.c *************** cost_qual_eval_walker(Node *node, cost_q *** 3607,3617 **** else if (IsA(node, ArrayCoerceExpr)) { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! Node *arraynode = (Node *) acoerce->arg; ! if (OidIsValid(acoerce->elemfuncid)) ! context->total.per_tuple += get_func_cost(acoerce->elemfuncid) * ! cpu_operator_cost * estimate_array_length(arraynode); } else if (IsA(node, RowCompareExpr)) { --- 3607,3620 ---- else if (IsA(node, ArrayCoerceExpr)) { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! QualCost perelemcost; ! cost_qual_eval_node(&perelemcost, (Node *) acoerce->elemexpr, ! context->root); ! context->total.startup += perelemcost.startup; ! if (perelemcost.per_tuple > 0) ! context->total.per_tuple += perelemcost.per_tuple * ! estimate_array_length((Node *) acoerce->arg); } else if (IsA(node, RowCompareExpr)) { diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index b0c9e94..dee4414 100644 *** a/src/backend/optimizer/plan/setrefs.c --- b/src/backend/optimizer/plan/setrefs.c *************** fix_expr_common(PlannerInfo *root, Node *** 1395,1406 **** record_plan_function_dependency(root, ((ScalarArrayOpExpr *) node)->opfuncid); } - else if (IsA(node, ArrayCoerceExpr)) - { - if (OidIsValid(((ArrayCoerceExpr *) node)->elemfuncid)) - record_plan_function_dependency(root, - ((ArrayCoerceExpr *) node)->elemfuncid); - } else if (IsA(node, Const)) { Const *con = (Const *) node; --- 1395,1400 ---- diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 8b4425d..e15f043 100644 *** a/src/backend/optimizer/util/clauses.c --- b/src/backend/optimizer/util/clauses.c *************** contain_nonstrict_functions_walker(Node *** 1361,1366 **** --- 1361,1377 ---- return true; if (IsA(node, FieldStore)) return true; + if (IsA(node, ArrayCoerceExpr)) + { + /* + * ArrayCoerceExpr is strict at the array level, regardless of what + * the per-element expression is; so we should ignore elemexpr and + * recurse only into the arg. + */ + return expression_tree_walker((Node *) ((ArrayCoerceExpr *) node)->arg, + contain_nonstrict_functions_walker, + context); + } if (IsA(node, CaseExpr)) return true; if (IsA(node, ArrayExpr)) *************** contain_nonstrict_functions_walker(Node *** 1380,1393 **** if (IsA(node, BooleanTest)) return true; ! /* ! * Check other function-containing nodes; but ArrayCoerceExpr is strict at ! * the array level, regardless of elemfunc. ! */ ! if (!IsA(node, ArrayCoerceExpr) && ! check_functions_in_node(node, contain_nonstrict_functions_checker, context)) return true; return expression_tree_walker(node, contain_nonstrict_functions_walker, context); } --- 1391,1401 ---- if (IsA(node, BooleanTest)) return true; ! /* Check other function-containing nodes */ ! if (check_functions_in_node(node, contain_nonstrict_functions_checker, context)) return true; + return expression_tree_walker(node, contain_nonstrict_functions_walker, context); } *************** find_nonnullable_rels_walker(Node *node, *** 1757,1763 **** } else if (IsA(node, ArrayCoerceExpr)) { ! /* ArrayCoerceExpr is strict at the array level */ ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; result = find_nonnullable_rels_walker((Node *) expr->arg, top_level); --- 1765,1771 ---- } else if (IsA(node, ArrayCoerceExpr)) { ! /* ArrayCoerceExpr is strict at the array level; ignore elemexpr */ ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; result = find_nonnullable_rels_walker((Node *) expr->arg, top_level); *************** find_nonnullable_vars_walker(Node *node, *** 1965,1971 **** } else if (IsA(node, ArrayCoerceExpr)) { ! /* ArrayCoerceExpr is strict at the array level */ ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; result = find_nonnullable_vars_walker((Node *) expr->arg, top_level); --- 1973,1979 ---- } else if (IsA(node, ArrayCoerceExpr)) { ! /* ArrayCoerceExpr is strict at the array level; ignore elemexpr */ ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; result = find_nonnullable_vars_walker((Node *) expr->arg, top_level); *************** eval_const_expressions_mutator(Node *nod *** 3005,3036 **** { ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; Expr *arg; ArrayCoerceExpr *newexpr; /* ! * Reduce constants in the ArrayCoerceExpr's argument, then ! * build a new ArrayCoerceExpr. */ arg = (Expr *) eval_const_expressions_mutator((Node *) expr->arg, context); newexpr = makeNode(ArrayCoerceExpr); newexpr->arg = arg; ! newexpr->elemfuncid = expr->elemfuncid; newexpr->resulttype = expr->resulttype; newexpr->resulttypmod = expr->resulttypmod; newexpr->resultcollid = expr->resultcollid; - newexpr->isExplicit = expr->isExplicit; newexpr->coerceformat = expr->coerceformat; newexpr->location = expr->location; /* ! * If constant argument and it's a binary-coercible or ! * immutable conversion, we can simplify it to a constant. */ if (arg && IsA(arg, Const) && ! (!OidIsValid(newexpr->elemfuncid) || ! func_volatile(newexpr->elemfuncid) == PROVOLATILE_IMMUTABLE)) return (Node *) evaluate_expr((Expr *) newexpr, newexpr->resulttype, newexpr->resulttypmod, --- 3013,3050 ---- { ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; Expr *arg; + Expr *elemexpr; ArrayCoerceExpr *newexpr; /* ! * Reduce constants in the ArrayCoerceExpr's argument and ! * per-element expressions, then build a new ArrayCoerceExpr. */ arg = (Expr *) eval_const_expressions_mutator((Node *) expr->arg, context); + elemexpr = (Expr *) eval_const_expressions_mutator((Node *) expr->elemexpr, + context); newexpr = makeNode(ArrayCoerceExpr); newexpr->arg = arg; ! newexpr->elemexpr = elemexpr; newexpr->resulttype = expr->resulttype; newexpr->resulttypmod = expr->resulttypmod; newexpr->resultcollid = expr->resultcollid; newexpr->coerceformat = expr->coerceformat; newexpr->location = expr->location; /* ! * If constant argument and per-element expression is ! * immutable, we can simplify the whole thing to a constant. ! * Exception: although contain_mutable_functions considers ! * CoerceToDomain immutable for historical reasons, let's not ! * do so here; this ensures coercion to an array-over-domain ! * does not apply the domain's constraints until runtime. */ if (arg && IsA(arg, Const) && ! elemexpr && !IsA(elemexpr, CoerceToDomain) && ! !contain_mutable_functions((Node *) elemexpr)) return (Node *) evaluate_expr((Expr *) newexpr, newexpr->resulttype, newexpr->resulttypmod, diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index c406cea..8fe5444 100644 *** a/src/backend/parser/parse_coerce.c --- b/src/backend/parser/parse_coerce.c *************** build_coercion_expression(Node *node, *** 876,894 **** { /* We need to build an ArrayCoerceExpr */ ArrayCoerceExpr *acoerce = makeNode(ArrayCoerceExpr); acoerce->arg = (Expr *) node; ! acoerce->elemfuncid = funcId; acoerce->resulttype = targetTypeId; /* ! * Label the output as having a particular typmod only if we are ! * really invoking a length-coercion function, ie one with more than ! * one argument. */ ! acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1; /* resultcollid will be set by parse_collate.c */ - acoerce->isExplicit = (ccontext == COERCION_EXPLICIT); acoerce->coerceformat = cformat; acoerce->location = location; --- 876,927 ---- { /* We need to build an ArrayCoerceExpr */ ArrayCoerceExpr *acoerce = makeNode(ArrayCoerceExpr); + CaseTestExpr *ctest = makeNode(CaseTestExpr); + Oid sourceBaseTypeId; + int32 sourceBaseTypeMod; + Oid targetElementType; + Node *elemexpr; + + /* + * Look through any domain over the source array type. Note we don't + * expect that the target type is a domain; it must be a plain array. + * (To get to a domain target type, we'll do coerce_to_domain later.) + */ + sourceBaseTypeMod = exprTypmod(node); + sourceBaseTypeId = getBaseTypeAndTypmod(exprType(node), + &sourceBaseTypeMod); + + /* Set up CaseTestExpr representing one element of source array */ + ctest->typeId = get_element_type(sourceBaseTypeId); + Assert(OidIsValid(ctest->typeId)); + ctest->typeMod = sourceBaseTypeMod; + ctest->collation = InvalidOid; /* Assume coercions don't care */ + + /* And coerce it to the target element type */ + targetElementType = get_element_type(targetTypeId); + Assert(OidIsValid(targetElementType)); + + elemexpr = coerce_to_target_type(NULL, + (Node *) ctest, + ctest->typeId, + targetElementType, + targetTypMod, + ccontext, + cformat, + location); + if (elemexpr == NULL) /* shouldn't happen */ + elog(ERROR, "failed to coerce array element type as expected"); acoerce->arg = (Expr *) node; ! acoerce->elemexpr = (Expr *) elemexpr; acoerce->resulttype = targetTypeId; /* ! * Label the output as having a particular element typmod only if we ! * ended up with a per-element expression that is labeled that way. */ ! acoerce->resulttypmod = exprTypmod(elemexpr); /* resultcollid will be set by parse_collate.c */ acoerce->coerceformat = cformat; acoerce->location = location; *************** IsBinaryCoercible(Oid srctype, Oid targe *** 2142,2149 **** * COERCION_PATH_RELABELTYPE: binary-compatible cast, no function needed * *funcid is set to InvalidOid * COERCION_PATH_ARRAYCOERCE: need an ArrayCoerceExpr node ! * *funcid is set to the element cast function, or InvalidOid ! * if the array elements are binary-compatible * COERCION_PATH_COERCEVIAIO: need a CoerceViaIO node * *funcid is set to InvalidOid * --- 2175,2181 ---- * COERCION_PATH_RELABELTYPE: binary-compatible cast, no function needed * *funcid is set to InvalidOid * COERCION_PATH_ARRAYCOERCE: need an ArrayCoerceExpr node ! * *funcid is set to InvalidOid * COERCION_PATH_COERCEVIAIO: need a CoerceViaIO node * *funcid is set to InvalidOid * *************** find_coercion_pathway(Oid targetTypeId, *** 2229,2239 **** { /* * If there's no pg_cast entry, perhaps we are dealing with a pair of ! * array types. If so, and if the element types have a suitable cast, ! * report that we can coerce with an ArrayCoerceExpr. ! * ! * Note that the source type can be a domain over array, but not the ! * target, because ArrayCoerceExpr won't check domain constraints. * * Hack: disallow coercions to oidvector and int2vector, which * otherwise tend to capture coercions that should go to "real" array --- 2261,2268 ---- { /* * If there's no pg_cast entry, perhaps we are dealing with a pair of ! * array types. If so, and if their element types have a conversion ! * pathway, report that we can coerce with an ArrayCoerceExpr. * * Hack: disallow coercions to oidvector and int2vector, which * otherwise tend to capture coercions that should go to "real" array *************** find_coercion_pathway(Oid targetTypeId, *** 2248,2254 **** Oid sourceElem; if ((targetElem = get_element_type(targetTypeId)) != InvalidOid && ! (sourceElem = get_base_element_type(sourceTypeId)) != InvalidOid) { CoercionPathType elempathtype; Oid elemfuncid; --- 2277,2283 ---- Oid sourceElem; if ((targetElem = get_element_type(targetTypeId)) != InvalidOid && ! (sourceElem = get_element_type(sourceTypeId)) != InvalidOid) { CoercionPathType elempathtype; Oid elemfuncid; *************** find_coercion_pathway(Oid targetTypeId, *** 2257,2270 **** sourceElem, ccontext, &elemfuncid); ! if (elempathtype != COERCION_PATH_NONE && ! elempathtype != COERCION_PATH_ARRAYCOERCE) { ! *funcid = elemfuncid; ! if (elempathtype == COERCION_PATH_COERCEVIAIO) ! result = COERCION_PATH_COERCEVIAIO; ! else ! result = COERCION_PATH_ARRAYCOERCE; } } } --- 2286,2294 ---- sourceElem, ccontext, &elemfuncid); ! if (elempathtype != COERCION_PATH_NONE) { ! result = COERCION_PATH_ARRAYCOERCE; } } } *************** find_coercion_pathway(Oid targetTypeId, *** 2305,2311 **** * If the given type is a varlena array type, we do not look for a coercion * function associated directly with the array type, but instead look for * one associated with the element type. An ArrayCoerceExpr node must be ! * used to apply such a function. * * We use the same result enum as find_coercion_pathway, but the only possible * result codes are: --- 2329,2337 ---- * If the given type is a varlena array type, we do not look for a coercion * function associated directly with the array type, but instead look for * one associated with the element type. An ArrayCoerceExpr node must be ! * used to apply such a function. (Note: currently, it's pointless to ! * return the funcid in this case, because it'll just get looked up again ! * in the recursive construction of the ArrayCoerceExpr's elemexpr.) * * We use the same result enum as find_coercion_pathway, but the only possible * result codes are: diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index 34dadd6..8287b39 100644 *** a/src/backend/utils/adt/arrayfuncs.c --- b/src/backend/utils/adt/arrayfuncs.c *************** array_set(ArrayType *array, int nSubscri *** 3091,3111 **** /* * array_map() * ! * Map an array through an arbitrary function. Return a new array with ! * same dimensions and each source element transformed by fn(). Each ! * source element is passed as the first argument to fn(); additional ! * arguments to be passed to fn() can be specified by the caller. ! * The output array can have a different element type than the input. * * Parameters are: ! * * fcinfo: a function-call data structure pre-constructed by the caller ! * to be ready to call the desired function, with everything except the ! * first argument position filled in. In particular, flinfo identifies ! * the function fn(), and if nargs > 1 then argument positions after the ! * first must be preset to the additional values to be passed. The ! * first argument position initially holds the input array value. * * retType: OID of element type of output array. This must be the same as, ! * or binary-compatible with, the result type of fn(). * * amstate: workspace for array_map. Must be zeroed by caller before * first call, and not touched after that. * --- 3091,3108 ---- /* * array_map() * ! * Map an array through an arbitrary expression. Return a new array with ! * the same dimensions and each source element transformed by the given, ! * already-compiled expression. Each source element is placed in the ! * innermost_caseval/innermost_casenull fields of the ExprState. * * Parameters are: ! * * arrayd: Datum representing array argument. ! * * exprstate: ExprState representing the per-element transformation. ! * * econtext: context for expression evaluation. * * retType: OID of element type of output array. This must be the same as, ! * or binary-compatible with, the result type of the expression. It might ! * be different from the input array's element type. * * amstate: workspace for array_map. Must be zeroed by caller before * first call, and not touched after that. * *************** array_set(ArrayType *array, int nSubscri *** 3115,3125 **** * * NB: caller must assure that input array is not NULL. NULL elements in * the array are OK however. */ Datum ! array_map(FunctionCallInfo fcinfo, Oid retType, ArrayMapState *amstate) { ! AnyArrayType *v; ArrayType *result; Datum *values; bool *nulls; --- 3112,3125 ---- * * NB: caller must assure that input array is not NULL. NULL elements in * the array are OK however. + * NB: caller should be running in econtext's per-tuple memory context. */ Datum ! array_map(Datum arrayd, ! ExprState *exprstate, ExprContext *econtext, ! Oid retType, ArrayMapState *amstate) { ! AnyArrayType *v = DatumGetAnyArray(arrayd); ArrayType *result; Datum *values; bool *nulls; *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3140,3152 **** array_iter iter; ArrayMetaState *inp_extra; ArrayMetaState *ret_extra; ! ! /* Get input array */ ! if (fcinfo->nargs < 1) ! elog(ERROR, "invalid nargs: %d", fcinfo->nargs); ! if (PG_ARGISNULL(0)) ! elog(ERROR, "null input array"); ! v = PG_GETARG_ANY_ARRAY(0); inpType = AARR_ELEMTYPE(v); ndim = AARR_NDIM(v); --- 3140,3147 ---- array_iter iter; ArrayMetaState *inp_extra; ArrayMetaState *ret_extra; ! Datum *transform_source = exprstate->innermost_caseval; ! bool *transform_source_isnull = exprstate->innermost_casenull; inpType = AARR_ELEMTYPE(v); ndim = AARR_NDIM(v); *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3157,3163 **** if (nitems <= 0) { /* Return empty array */ ! PG_RETURN_ARRAYTYPE_P(construct_empty_array(retType)); } /* --- 3152,3158 ---- if (nitems <= 0) { /* Return empty array */ ! return PointerGetDatum(construct_empty_array(retType)); } /* *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3202,3240 **** for (i = 0; i < nitems; i++) { - bool callit = true; - /* Get source element, checking for NULL */ ! fcinfo->arg[0] = array_iter_next(&iter, &fcinfo->argnull[0], i, ! inp_typlen, inp_typbyval, inp_typalign); ! ! /* ! * Apply the given function to source elt and extra args. ! */ ! if (fcinfo->flinfo->fn_strict) ! { ! int j; ! ! for (j = 0; j < fcinfo->nargs; j++) ! { ! if (fcinfo->argnull[j]) ! { ! callit = false; ! break; ! } ! } ! } ! if (callit) ! { ! fcinfo->isnull = false; ! values[i] = FunctionCallInvoke(fcinfo); ! } ! else ! fcinfo->isnull = true; ! nulls[i] = fcinfo->isnull; ! if (fcinfo->isnull) hasnulls = true; else { --- 3197,3211 ---- for (i = 0; i < nitems; i++) { /* Get source element, checking for NULL */ ! *transform_source = ! array_iter_next(&iter, transform_source_isnull, i, ! inp_typlen, inp_typbyval, inp_typalign); ! /* Apply the given expression to source element */ ! values[i] = ExecEvalExpr(exprstate, econtext, &nulls[i]); ! if (nulls[i]) hasnulls = true; else { *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3253,3259 **** } } ! /* Allocate and initialize the result array */ if (hasnulls) { dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nitems); --- 3224,3230 ---- } } ! /* Allocate and fill the result array */ if (hasnulls) { dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nitems); *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3272,3289 **** memcpy(ARR_DIMS(result), AARR_DIMS(v), ndim * sizeof(int)); memcpy(ARR_LBOUND(result), AARR_LBOUND(v), ndim * sizeof(int)); - /* - * Note: do not risk trying to pfree the results of the called function - */ CopyArrayEls(result, values, nulls, nitems, typlen, typbyval, typalign, false); pfree(values); pfree(nulls); ! PG_RETURN_ARRAYTYPE_P(result); } /* --- 3243,3260 ---- memcpy(ARR_DIMS(result), AARR_DIMS(v), ndim * sizeof(int)); memcpy(ARR_LBOUND(result), AARR_LBOUND(v), ndim * sizeof(int)); CopyArrayEls(result, values, nulls, nitems, typlen, typbyval, typalign, false); + /* + * Note: do not risk trying to pfree the results of the called expression + */ pfree(values); pfree(nulls); ! return PointerGetDatum(result); } /* diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index e103f5e..1bb0da1 100644 *** a/src/backend/utils/adt/selfuncs.c --- b/src/backend/utils/adt/selfuncs.c *************** strip_array_coercion(Node *node) *** 1752,1761 **** { for (;;) { ! if (node && IsA(node, ArrayCoerceExpr) && ! ((ArrayCoerceExpr *) node)->elemfuncid == InvalidOid) { ! node = (Node *) ((ArrayCoerceExpr *) node)->arg; } else if (node && IsA(node, RelabelType)) { --- 1752,1770 ---- { for (;;) { ! if (node && IsA(node, ArrayCoerceExpr)) { ! ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! ! /* ! * If the per-element expression is just a RelabelType on top of ! * CaseTestExpr, then we know it's a binary-compatible relabeling. ! */ ! if (IsA(acoerce->elemexpr, RelabelType) && ! IsA(((RelabelType *) acoerce->elemexpr)->arg, CaseTestExpr)) ! node = (Node *) acoerce->arg; ! else ! break; } else if (node && IsA(node, RelabelType)) { diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index a7b0782..9197335 100644 *** a/src/backend/utils/fmgr/fmgr.c --- b/src/backend/utils/fmgr/fmgr.c *************** get_call_expr_argtype(Node *expr, int ar *** 1941,1948 **** args = ((DistinctExpr *) expr)->args; else if (IsA(expr, ScalarArrayOpExpr)) args = ((ScalarArrayOpExpr *) expr)->args; - else if (IsA(expr, ArrayCoerceExpr)) - args = list_make1(((ArrayCoerceExpr *) expr)->arg); else if (IsA(expr, NullIfExpr)) args = ((NullIfExpr *) expr)->args; else if (IsA(expr, WindowFunc)) --- 1941,1946 ---- *************** get_call_expr_argtype(Node *expr, int ar *** 1956,1971 **** argtype = exprType((Node *) list_nth(args, argnum)); /* ! * special hack for ScalarArrayOpExpr and ArrayCoerceExpr: what the ! * underlying function will actually get passed is the element type of the ! * array. */ if (IsA(expr, ScalarArrayOpExpr) && argnum == 1) argtype = get_base_element_type(argtype); - else if (IsA(expr, ArrayCoerceExpr) && - argnum == 0) - argtype = get_base_element_type(argtype); return argtype; } --- 1954,1965 ---- argtype = exprType((Node *) list_nth(args, argnum)); /* ! * special hack for ScalarArrayOpExpr: what the underlying function will ! * actually get passed is the element type of the array. */ if (IsA(expr, ScalarArrayOpExpr) && argnum == 1) argtype = get_base_element_type(argtype); return argtype; } *************** get_call_expr_arg_stable(Node *expr, int *** 2012,2019 **** args = ((DistinctExpr *) expr)->args; else if (IsA(expr, ScalarArrayOpExpr)) args = ((ScalarArrayOpExpr *) expr)->args; - else if (IsA(expr, ArrayCoerceExpr)) - args = list_make1(((ArrayCoerceExpr *) expr)->arg); else if (IsA(expr, NullIfExpr)) args = ((NullIfExpr *) expr)->args; else if (IsA(expr, WindowFunc)) --- 2006,2011 ---- diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h index 8ee0496..78d2247 100644 *** a/src/include/executor/execExpr.h --- b/src/include/executor/execExpr.h *************** typedef struct ExprEvalStep *** 385,394 **** /* for EEOP_ARRAYCOERCE */ struct { ! ArrayCoerceExpr *coerceexpr; Oid resultelemtype; /* element type of result array */ - FmgrInfo *elemfunc; /* lookup info for element coercion - * function */ struct ArrayMapState *amstate; /* workspace for array_map */ } arraycoerce; --- 385,392 ---- /* for EEOP_ARRAYCOERCE */ struct { ! ExprState *elemexprstate; /* null if no per-element work */ Oid resultelemtype; /* element type of result array */ struct ArrayMapState *amstate; /* workspace for array_map */ } arraycoerce; *************** extern void ExecEvalRowNull(ExprState *s *** 621,627 **** extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext); extern void ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op); ! extern void ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op); extern void ExecEvalRow(ExprState *state, ExprEvalStep *op); extern void ExecEvalMinMax(ExprState *state, ExprEvalStep *op); extern void ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, --- 619,626 ---- extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext); extern void ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op); ! extern void ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op, ! ExprContext *econtext); extern void ExecEvalRow(ExprState *state, ExprEvalStep *op); extern void ExecEvalMinMax(ExprState *state, ExprEvalStep *op); extern void ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 8c536a8..ccb5123 100644 *** a/src/include/nodes/primnodes.h --- b/src/include/nodes/primnodes.h *************** typedef struct CoerceViaIO *** 820,830 **** * ArrayCoerceExpr * * ArrayCoerceExpr represents a type coercion from one array type to another, ! * which is implemented by applying the indicated element-type coercion ! * function to each element of the source array. If elemfuncid is InvalidOid ! * then the element types are binary-compatible, but the coercion still ! * requires some effort (we have to fix the element type ID stored in the ! * array header). * ---------------- */ --- 820,831 ---- * ArrayCoerceExpr * * ArrayCoerceExpr represents a type coercion from one array type to another, ! * which is implemented by applying the per-element coercion expression ! * "elemexpr" to each element of the source array. Within elemexpr, the ! * source element is represented by a CaseTestExpr node. Note that even if ! * elemexpr is a no-op (that is, just CaseTestExpr + RelabelType), the ! * coercion still requires some effort: we have to fix the element type OID ! * stored in the array header. * ---------------- */ *************** typedef struct ArrayCoerceExpr *** 832,842 **** { Expr xpr; Expr *arg; /* input expression (yields an array) */ ! Oid elemfuncid; /* OID of element coercion function, or 0 */ Oid resulttype; /* output type of coercion (an array type) */ int32 resulttypmod; /* output typmod (also element typmod) */ Oid resultcollid; /* OID of collation, or InvalidOid if none */ - bool isExplicit; /* conversion semantics flag to pass to func */ CoercionForm coerceformat; /* how to display this node */ int location; /* token location, or -1 if unknown */ } ArrayCoerceExpr; --- 833,842 ---- { Expr xpr; Expr *arg; /* input expression (yields an array) */ ! Expr *elemexpr; /* expression representing per-element work */ Oid resulttype; /* output type of coercion (an array type) */ int32 resulttypmod; /* output typmod (also element typmod) */ Oid resultcollid; /* OID of collation, or InvalidOid if none */ CoercionForm coerceformat; /* how to display this node */ int location; /* token location, or -1 if unknown */ } ArrayCoerceExpr; diff --git a/src/include/utils/array.h b/src/include/utils/array.h index 61a67a2..32833f0 100644 *** a/src/include/utils/array.h --- b/src/include/utils/array.h *************** *** 64,69 **** --- 64,73 ---- #include "fmgr.h" #include "utils/expandeddatum.h" + /* avoid including execnodes.h here */ + struct ExprState; + struct ExprContext; + /* * Arrays are varlena objects, so must meet the varlena convention that *************** extern ArrayType *array_set(ArrayType *a *** 360,367 **** Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign); ! extern Datum array_map(FunctionCallInfo fcinfo, Oid retType, ! ArrayMapState *amstate); extern void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, --- 364,372 ---- Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign); ! extern Datum array_map(Datum arrayd, ! struct ExprState *exprstate, struct ExprContext *econtext, ! Oid retType, ArrayMapState *amstate); extern void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index c98492b..eb584ac 100644 *** a/src/pl/plpgsql/src/pl_exec.c --- b/src/pl/plpgsql/src/pl_exec.c *************** exec_simple_check_node(Node *node) *** 6577,6583 **** return exec_simple_check_node((Node *) ((CoerceViaIO *) node)->arg); case T_ArrayCoerceExpr: ! return exec_simple_check_node((Node *) ((ArrayCoerceExpr *) node)->arg); case T_ConvertRowtypeExpr: return exec_simple_check_node((Node *) ((ConvertRowtypeExpr *) node)->arg); --- 6577,6592 ---- return exec_simple_check_node((Node *) ((CoerceViaIO *) node)->arg); case T_ArrayCoerceExpr: ! { ! ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; ! ! if (!exec_simple_check_node((Node *) expr->arg)) ! return FALSE; ! if (!exec_simple_check_node((Node *) expr->elemexpr)) ! return FALSE; ! ! return TRUE; ! } case T_ConvertRowtypeExpr: return exec_simple_check_node((Node *) ((ConvertRowtypeExpr *) node)->arg); [text/x-diff] 03-support-arrays-of-domains.patch (9.5K, ../../[email protected]/4-03-support-arrays-of-domains.patch) download | inline diff: diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 29ac5d5..c7bbe22 100644 *** a/src/backend/commands/typecmds.c --- b/src/backend/commands/typecmds.c *************** ObjectAddress *** 729,734 **** --- 729,735 ---- DefineDomain(CreateDomainStmt *stmt) { char *domainName; + char *domainArrayName; Oid domainNamespace; AclResult aclresult; int16 internalLength; *************** DefineDomain(CreateDomainStmt *stmt) *** 757,762 **** --- 758,764 ---- Oid basetypeoid; Oid old_type_oid; Oid domaincoll; + Oid domainArrayOid; Form_pg_type baseType; int32 basetypeMod; Oid baseColl; *************** DefineDomain(CreateDomainStmt *stmt) *** 1027,1032 **** --- 1029,1037 ---- } } + /* Allocate OID for array type */ + domainArrayOid = AssignTypeArrayOid(); + /* * Have TypeCreate do all the real work. */ *************** DefineDomain(CreateDomainStmt *stmt) *** 1051,1057 **** analyzeProcedure, /* analyze procedure */ InvalidOid, /* no array element type */ false, /* this isn't an array */ ! InvalidOid, /* no arrays for domains (yet) */ basetypeoid, /* base type ID */ defaultValue, /* default type value (text) */ defaultValueBin, /* default type value (binary) */ --- 1056,1062 ---- analyzeProcedure, /* analyze procedure */ InvalidOid, /* no array element type */ false, /* this isn't an array */ ! domainArrayOid, /* array type we are about to create */ basetypeoid, /* base type ID */ defaultValue, /* default type value (text) */ defaultValueBin, /* default type value (binary) */ *************** DefineDomain(CreateDomainStmt *stmt) *** 1064,1069 **** --- 1069,1116 ---- domaincoll); /* type's collation */ /* + * Create the array type that goes with it. + */ + domainArrayName = makeArrayTypeName(domainName, domainNamespace); + + /* alignment must be 'i' or 'd' for arrays */ + alignment = (alignment == 'd') ? 'd' : 'i'; + + TypeCreate(domainArrayOid, /* force assignment of this type OID */ + domainArrayName, /* type name */ + domainNamespace, /* namespace */ + InvalidOid, /* relation oid (n/a here) */ + 0, /* relation kind (ditto) */ + GetUserId(), /* owner's ID */ + -1, /* internal size (always varlena) */ + TYPTYPE_BASE, /* type-type (base type) */ + TYPCATEGORY_ARRAY, /* type-category (array) */ + false, /* array types are never preferred */ + delimiter, /* array element delimiter */ + F_ARRAY_IN, /* input procedure */ + F_ARRAY_OUT, /* output procedure */ + F_ARRAY_RECV, /* receive procedure */ + F_ARRAY_SEND, /* send procedure */ + InvalidOid, /* typmodin procedure - none */ + InvalidOid, /* typmodout procedure - none */ + F_ARRAY_TYPANALYZE, /* analyze procedure */ + address.objectId, /* element type ID */ + true, /* yes this is an array type */ + InvalidOid, /* no further array type */ + InvalidOid, /* base type ID */ + NULL, /* never a default type value */ + NULL, /* binary default isn't sent either */ + false, /* never passed by value */ + alignment, /* see above */ + 'x', /* ARRAY is always toastable */ + -1, /* typMod (Domains only) */ + 0, /* Array dimensions of typbasetype */ + false, /* Type NOT NULL */ + domaincoll); /* type's collation */ + + pfree(domainArrayName); + + /* * Process constraints which refer to the domain ID returned by TypeCreate */ foreach(listptr, schema) *************** DefineEnum(CreateEnumStmt *stmt) *** 1139,1144 **** --- 1186,1192 ---- errmsg("type \"%s\" already exists", enumName))); } + /* Allocate OID for array type */ enumArrayOid = AssignTypeArrayOid(); /* Create the pg_type entry */ diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out index 3acc696..1e62c57 100644 *** a/src/test/regress/expected/domain.out --- b/src/test/regress/expected/domain.out *************** Rules: *** 310,315 **** --- 310,410 ---- drop table dcomptable; drop type comptype cascade; NOTICE: drop cascades to type dcomptypea + -- Test arrays over domains + create domain posint as int check (value > 0); + create table pitable (f1 posint[]); + insert into pitable values(array[42]); + insert into pitable values(array[-1]); -- fail + ERROR: value for domain posint violates check constraint "posint_check" + insert into pitable values('{0}'); -- fail + ERROR: value for domain posint violates check constraint "posint_check" + LINE 1: insert into pitable values('{0}'); + ^ + update pitable set f1[1] = f1[1] + 1; + update pitable set f1[1] = 0; -- fail + ERROR: value for domain posint violates check constraint "posint_check" + select * from pitable; + f1 + ------ + {43} + (1 row) + + drop table pitable; + create domain vc4 as varchar(4); + create table vc4table (f1 vc4[]); + insert into vc4table values(array['too long']); -- fail + ERROR: value too long for type character varying(4) + insert into vc4table values(array['too long']::vc4[]); -- cast truncates + select * from vc4table; + f1 + ---------- + {"too "} + (1 row) + + drop table vc4table; + drop type vc4; + -- You can sort of fake arrays-of-arrays by putting a domain in between + create domain dposinta as posint[]; + create table dposintatable (f1 dposinta[]); + insert into dposintatable values(array[array[42]]); -- fail + ERROR: column "f1" is of type dposinta[] but expression is of type integer[] + LINE 1: insert into dposintatable values(array[array[42]]); + ^ + HINT: You will need to rewrite or cast the expression. + insert into dposintatable values(array[array[42]::posint[]]); -- still fail + ERROR: column "f1" is of type dposinta[] but expression is of type posint[] + LINE 1: insert into dposintatable values(array[array[42]::posint[]])... + ^ + HINT: You will need to rewrite or cast the expression. + insert into dposintatable values(array[array[42]::dposinta]); -- but this works + select f1, f1[1], (f1[1])[1] from dposintatable; + f1 | f1 | f1 + ----------+------+---- + {"{42}"} | {42} | 42 + (1 row) + + select pg_typeof(f1) from dposintatable; + pg_typeof + ------------ + dposinta[] + (1 row) + + select pg_typeof(f1[1]) from dposintatable; + pg_typeof + ----------- + dposinta + (1 row) + + select pg_typeof(f1[1][1]) from dposintatable; + pg_typeof + ----------- + dposinta + (1 row) + + select pg_typeof((f1[1])[1]) from dposintatable; + pg_typeof + ----------- + posint + (1 row) + + update dposintatable set f1[2] = array[99]; + select f1, f1[1], (f1[2])[1] from dposintatable; + f1 | f1 | f1 + -----------------+------+---- + {"{42}","{99}"} | {42} | 99 + (1 row) + + -- it'd be nice if you could do something like this, but for now you can't: + update dposintatable set f1[2][1] = array[97]; + ERROR: wrong number of array subscripts + -- maybe someday we can make this syntax work: + update dposintatable set (f1[2])[1] = array[98]; + ERROR: syntax error at or near "[" + LINE 1: update dposintatable set (f1[2])[1] = array[98]; + ^ + drop table dposintatable; + drop domain posint cascade; + NOTICE: drop cascades to type dposinta -- Test not-null restrictions create domain dnotnull varchar(15) NOT NULL; create domain dnull varchar(15); diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql index 0fd383e..8fb3e20 100644 *** a/src/test/regress/sql/domain.sql --- b/src/test/regress/sql/domain.sql *************** drop table dcomptable; *** 166,171 **** --- 166,214 ---- drop type comptype cascade; + -- Test arrays over domains + + create domain posint as int check (value > 0); + + create table pitable (f1 posint[]); + insert into pitable values(array[42]); + insert into pitable values(array[-1]); -- fail + insert into pitable values('{0}'); -- fail + update pitable set f1[1] = f1[1] + 1; + update pitable set f1[1] = 0; -- fail + select * from pitable; + drop table pitable; + + create domain vc4 as varchar(4); + create table vc4table (f1 vc4[]); + insert into vc4table values(array['too long']); -- fail + insert into vc4table values(array['too long']::vc4[]); -- cast truncates + select * from vc4table; + drop table vc4table; + drop type vc4; + + -- You can sort of fake arrays-of-arrays by putting a domain in between + create domain dposinta as posint[]; + create table dposintatable (f1 dposinta[]); + insert into dposintatable values(array[array[42]]); -- fail + insert into dposintatable values(array[array[42]::posint[]]); -- still fail + insert into dposintatable values(array[array[42]::dposinta]); -- but this works + select f1, f1[1], (f1[1])[1] from dposintatable; + select pg_typeof(f1) from dposintatable; + select pg_typeof(f1[1]) from dposintatable; + select pg_typeof(f1[1][1]) from dposintatable; + select pg_typeof((f1[1])[1]) from dposintatable; + update dposintatable set f1[2] = array[99]; + select f1, f1[1], (f1[2])[1] from dposintatable; + -- it'd be nice if you could do something like this, but for now you can't: + update dposintatable set f1[2][1] = array[97]; + -- maybe someday we can make this syntax work: + update dposintatable set (f1[2])[1] = array[98]; + + drop table dposintatable; + drop domain posint cascade; + + -- Test not-null restrictions create domain dnotnull varchar(15) NOT NULL; ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: Arrays of domains @ 2017-09-13 00:50 Tom Lane <[email protected]> parent: Tom Lane <[email protected]> 1 sibling, 1 reply; 38+ messages in thread From: Tom Lane @ 2017-09-13 00:50 UTC (permalink / raw) To: pgsql-hackers I wrote: > Attached is a patch series that allows us to create arrays of domain > types. Here's a rebased-up-to-HEAD version of this patch set. The only actual change is removal of a no-longer-needed hunk in pl_exec.c. regards, tom lane -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers Attachments: [text/x-diff] 01-rationalize-coercion-APIs-2.patch (14.3K, ../../[email protected]/2-01-rationalize-coercion-APIs-2.patch) download | inline diff: diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c index 9d75e86..d7db32e 100644 *** a/src/backend/optimizer/prep/preptlist.c --- b/src/backend/optimizer/prep/preptlist.c *************** expand_targetlist(List *tlist, int comma *** 306,314 **** new_expr = coerce_to_domain(new_expr, InvalidOid, -1, atttype, COERCE_IMPLICIT_CAST, -1, - false, false); } else --- 306,314 ---- new_expr = coerce_to_domain(new_expr, InvalidOid, -1, atttype, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } else diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index e79ad26..5a241bd 100644 *** a/src/backend/parser/parse_coerce.c --- b/src/backend/parser/parse_coerce.c *************** *** 34,48 **** static Node *coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit, bool hideInputCoercion); static void hide_coercion_node(Node *node); static Node *build_coercion_expression(Node *node, CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit); static Node *coerce_record_to_complex(ParseState *pstate, Node *node, Oid targetTypeId, CoercionContext ccontext, --- 34,49 ---- static Node *coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location, ! bool hideInputCoercion); static void hide_coercion_node(Node *node); static Node *build_coercion_expression(Node *node, CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location); static Node *coerce_record_to_complex(ParseState *pstate, Node *node, Oid targetTypeId, CoercionContext ccontext, *************** coerce_to_target_type(ParseState *pstate *** 110,117 **** */ result = coerce_type_typmod(result, targettype, targettypmod, ! cformat, location, ! (cformat != COERCE_IMPLICIT_CAST), (result != expr && !IsA(result, Const))); if (expr != origexpr) --- 111,117 ---- */ result = coerce_type_typmod(result, targettype, targettypmod, ! ccontext, cformat, location, (result != expr && !IsA(result, Const))); if (expr != origexpr) *************** coerce_type(ParseState *pstate, Node *no *** 355,361 **** result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! cformat, location, false, false); ReleaseSysCache(baseType); --- 355,362 ---- result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! ccontext, cformat, location, ! false); ReleaseSysCache(baseType); *************** coerce_type(ParseState *pstate, Node *no *** 417,436 **** result = build_coercion_expression(node, pathtype, funcId, baseTypeId, baseTypeMod, ! cformat, location, ! (cformat != COERCE_IMPLICIT_CAST)); /* * If domain, coerce to the domain type and relabel with domain ! * type ID. We can skip the internal length-coercion step if the ! * selected coercion function was a type-and-length coercion. */ if (targetTypeId != baseTypeId) result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! cformat, location, true, ! exprIsLengthCoercion(result, ! NULL)); } else { --- 418,434 ---- result = build_coercion_expression(node, pathtype, funcId, baseTypeId, baseTypeMod, ! ccontext, cformat, location); /* * If domain, coerce to the domain type and relabel with domain ! * type ID, hiding the previous coercion node. */ if (targetTypeId != baseTypeId) result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! ccontext, cformat, location, ! true); } else { *************** coerce_type(ParseState *pstate, Node *no *** 444,450 **** * then we won't need a RelabelType node. */ result = coerce_to_domain(node, InvalidOid, -1, targetTypeId, ! cformat, location, false, false); if (result == node) { /* --- 442,449 ---- * then we won't need a RelabelType node. */ result = coerce_to_domain(node, InvalidOid, -1, targetTypeId, ! ccontext, cformat, location, ! false); if (result == node) { /* *************** can_coerce_type(int nargs, Oid *input_ty *** 636,654 **** * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller * has not bothered to look this up) * 'typeId': target type to coerce to ! * 'cformat': coercion format * 'location': coercion request location * 'hideInputCoercion': if true, hide the input coercion under this one. - * 'lengthCoercionDone': if true, caller already accounted for length, - * ie the input is already of baseTypMod as well as baseTypeId. * * If the target type isn't a domain, the given 'arg' is returned as-is. */ Node * coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionForm cformat, int location, ! bool hideInputCoercion, ! bool lengthCoercionDone) { CoerceToDomain *result; --- 635,651 ---- * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller * has not bothered to look this up) * 'typeId': target type to coerce to ! * 'ccontext': context indicator to control coercions ! * 'cformat': coercion display format * 'location': coercion request location * 'hideInputCoercion': if true, hide the input coercion under this one. * * If the target type isn't a domain, the given 'arg' is returned as-is. */ Node * coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionContext ccontext, CoercionForm cformat, int location, ! bool hideInputCoercion) { CoerceToDomain *result; *************** coerce_to_domain(Node *arg, Oid baseType *** 677,690 **** * would be safe to do anyway, without lots of knowledge about what the * base type thinks the typmod means. */ ! if (!lengthCoercionDone) ! { ! if (baseTypeMod >= 0) ! arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod, ! COERCE_IMPLICIT_CAST, location, ! (cformat != COERCE_IMPLICIT_CAST), ! false); ! } /* * Now build the domain coercion node. This represents run-time checking --- 674,682 ---- * would be safe to do anyway, without lots of knowledge about what the * base type thinks the typmod means. */ ! arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod, ! ccontext, COERCE_IMPLICIT_CAST, location, ! false); /* * Now build the domain coercion node. This represents run-time checking *************** coerce_to_domain(Node *arg, Oid baseType *** 714,724 **** * The caller must have already ensured that the value is of the correct * type, typically by applying coerce_type. * ! * cformat determines the display properties of the generated node (if any), ! * while isExplicit may affect semantics. If hideInputCoercion is true ! * *and* we generate a node, the input node is forced to IMPLICIT display ! * form, so that only the typmod coercion node will be visible when ! * displaying the expression. * * NOTE: this does not need to work on domain types, because any typmod * coercion for a domain is considered to be part of the type coercion --- 706,719 ---- * The caller must have already ensured that the value is of the correct * type, typically by applying coerce_type. * ! * ccontext may affect semantics, depending on whether the length coercion ! * function pays attention to the isExplicit flag it's passed. ! * ! * cformat determines the display properties of the generated node (if any). ! * ! * If hideInputCoercion is true *and* we generate a node, the input node is ! * forced to IMPLICIT display form, so that only the typmod coercion node will ! * be visible when displaying the expression. * * NOTE: this does not need to work on domain types, because any typmod * coercion for a domain is considered to be part of the type coercion *************** coerce_to_domain(Node *arg, Oid baseType *** 726,733 **** */ static Node * coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit, bool hideInputCoercion) { CoercionPathType pathtype; Oid funcId; --- 721,729 ---- */ static Node * coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location, ! bool hideInputCoercion) { CoercionPathType pathtype; Oid funcId; *************** coerce_type_typmod(Node *node, Oid targe *** 749,756 **** node = build_coercion_expression(node, pathtype, funcId, targetTypeId, targetTypMod, ! cformat, location, ! isExplicit); } return node; --- 745,751 ---- node = build_coercion_expression(node, pathtype, funcId, targetTypeId, targetTypMod, ! ccontext, cformat, location); } return node; *************** build_coercion_expression(Node *node, *** 799,806 **** CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit) { int nargs = 0; --- 794,801 ---- CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location) { int nargs = 0; *************** build_coercion_expression(Node *node, *** 865,871 **** -1, InvalidOid, sizeof(bool), ! BoolGetDatum(isExplicit), false, true); --- 860,866 ---- -1, InvalidOid, sizeof(bool), ! BoolGetDatum(ccontext == COERCION_EXPLICIT), false, true); *************** build_coercion_expression(Node *node, *** 893,899 **** */ acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1; /* resultcollid will be set by parse_collate.c */ ! acoerce->isExplicit = isExplicit; acoerce->coerceformat = cformat; acoerce->location = location; --- 888,894 ---- */ acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1; /* resultcollid will be set by parse_collate.c */ ! acoerce->isExplicit = (ccontext == COERCION_EXPLICIT); acoerce->coerceformat = cformat; acoerce->location = location; diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index ef52dd5..7054d4f 100644 *** a/src/backend/rewrite/rewriteHandler.c --- b/src/backend/rewrite/rewriteHandler.c *************** rewriteTargetListIU(List *targetList, *** 875,883 **** new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, COERCE_IMPLICIT_CAST, -1, - false, false); } } --- 875,883 ---- new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } } *************** rewriteValuesRTE(RangeTblEntry *rte, Rel *** 1271,1279 **** new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, COERCE_IMPLICIT_CAST, -1, - false, false); } newList = lappend(newList, new_expr); --- 1271,1279 ---- new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } newList = lappend(newList, new_expr); diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c index 5c17213..c5773ef 100644 *** a/src/backend/rewrite/rewriteManip.c --- b/src/backend/rewrite/rewriteManip.c *************** ReplaceVarsFromTargetList_callback(Var * *** 1429,1437 **** var->varcollid), InvalidOid, -1, var->vartype, COERCE_IMPLICIT_CAST, -1, - false, false); } elog(ERROR, "could not find replacement targetlist entry for attno %d", --- 1429,1437 ---- var->varcollid), InvalidOid, -1, var->vartype, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } elog(ERROR, "could not find replacement targetlist entry for attno %d", diff --git a/src/include/parser/parse_coerce.h b/src/include/parser/parse_coerce.h index 06f6529..e560f0c 100644 *** a/src/include/parser/parse_coerce.h --- b/src/include/parser/parse_coerce.h *************** extern Node *coerce_type(ParseState *pst *** 48,56 **** CoercionContext ccontext, CoercionForm cformat, int location); extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionForm cformat, int location, ! bool hideInputCoercion, ! bool lengthCoercionDone); extern Node *coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName); --- 48,55 ---- CoercionContext ccontext, CoercionForm cformat, int location); extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionContext ccontext, CoercionForm cformat, int location, ! bool hideInputCoercion); extern Node *coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName); [text/x-diff] 02-reimplement-ArrayCoerceExpr-2.patch (42.4K, ../../[email protected]/3-02-reimplement-ArrayCoerceExpr-2.patch) download | inline diff: diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index fa409d7..1776730 100644 *** a/contrib/pg_stat_statements/pg_stat_statements.c --- b/contrib/pg_stat_statements/pg_stat_statements.c *************** JumbleExpr(pgssJumbleState *jstate, Node *** 2631,2636 **** --- 2631,2637 ---- APP_JUMB(acexpr->resulttype); JumbleExpr(jstate, (Node *) acexpr->arg); + JumbleExpr(jstate, (Node *) acexpr->elemexpr); } break; case T_ConvertRowtypeExpr: diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 6fffc29..2668650 100644 *** a/src/backend/catalog/dependency.c --- b/src/backend/catalog/dependency.c *************** find_expr_references_walker(Node *node, *** 1738,1748 **** { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! if (OidIsValid(acoerce->elemfuncid)) ! add_object_address(OCLASS_PROC, acoerce->elemfuncid, 0, ! context->addrs); add_object_address(OCLASS_TYPE, acoerce->resulttype, 0, context->addrs); /* fall through to examine arguments */ } else if (IsA(node, ConvertRowtypeExpr)) --- 1738,1751 ---- { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! /* as above, depend on type */ add_object_address(OCLASS_TYPE, acoerce->resulttype, 0, context->addrs); + /* the collation might not be referenced anywhere else, either */ + if (OidIsValid(acoerce->resultcollid) && + acoerce->resultcollid != DEFAULT_COLLATION_OID) + add_object_address(OCLASS_COLLATION, acoerce->resultcollid, 0, + context->addrs); /* fall through to examine arguments */ } else if (IsA(node, ConvertRowtypeExpr)) diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index be9d23b..e083961 100644 *** a/src/backend/executor/execExpr.c --- b/src/backend/executor/execExpr.c *************** ExecInitExprRec(Expr *node, PlanState *p *** 1225,1230 **** --- 1225,1231 ---- { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; Oid resultelemtype; + ExprState *elemstate; /* evaluate argument into step's result area */ ExecInitExprRec(acoerce->arg, parent, state, resv, resnull); *************** ExecInitExprRec(Expr *node, PlanState *p *** 1234,1275 **** ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("target type is not an array"))); - /* Arrays over domains aren't supported yet */ - Assert(getBaseType(resultelemtype) == resultelemtype); ! scratch.opcode = EEOP_ARRAYCOERCE; ! scratch.d.arraycoerce.coerceexpr = acoerce; ! scratch.d.arraycoerce.resultelemtype = resultelemtype; ! if (OidIsValid(acoerce->elemfuncid)) ! { ! AclResult aclresult; ! /* Check permission to call function */ ! aclresult = pg_proc_aclcheck(acoerce->elemfuncid, ! GetUserId(), ! ACL_EXECUTE); ! if (aclresult != ACLCHECK_OK) ! aclcheck_error(aclresult, ACL_KIND_PROC, ! get_func_name(acoerce->elemfuncid)); ! InvokeFunctionExecuteHook(acoerce->elemfuncid); ! /* Set up the primary fmgr lookup information */ ! scratch.d.arraycoerce.elemfunc = ! (FmgrInfo *) palloc0(sizeof(FmgrInfo)); ! fmgr_info(acoerce->elemfuncid, ! scratch.d.arraycoerce.elemfunc); ! fmgr_info_set_expr((Node *) acoerce, ! scratch.d.arraycoerce.elemfunc); /* Set up workspace for array_map */ scratch.d.arraycoerce.amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState)); } else { ! /* Don't need workspace if there's no conversion func */ ! scratch.d.arraycoerce.elemfunc = NULL; scratch.d.arraycoerce.amstate = NULL; } --- 1235,1283 ---- ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("target type is not an array"))); ! /* ! * Construct a sub-expression for the per-element expression; ! * but don't ready it until after we check it for triviality. ! * We assume it hasn't any Var references, but does have a ! * CaseTestExpr representing the source array element values. ! */ ! elemstate = makeNode(ExprState); ! elemstate->expr = acoerce->elemexpr; ! elemstate->innermost_caseval = (Datum *) palloc(sizeof(Datum)); ! elemstate->innermost_casenull = (bool *) palloc(sizeof(bool)); ! ExecInitExprRec(acoerce->elemexpr, parent, elemstate, ! &elemstate->resvalue, &elemstate->resnull); ! if (elemstate->steps_len == 1 && ! elemstate->steps[0].opcode == EEOP_CASE_TESTVAL) ! { ! /* Trivial, so we need no per-element work at runtime */ ! elemstate = NULL; ! } ! else ! { ! /* Not trivial, so append a DONE step */ ! scratch.opcode = EEOP_DONE; ! ExprEvalPushStep(elemstate, &scratch); ! /* and ready the subexpression */ ! ExecReadyExpr(elemstate); ! } ! scratch.opcode = EEOP_ARRAYCOERCE; ! scratch.d.arraycoerce.elemexprstate = elemstate; ! scratch.d.arraycoerce.resultelemtype = resultelemtype; + if (elemstate) + { /* Set up workspace for array_map */ scratch.d.arraycoerce.amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState)); } else { ! /* Don't need workspace if there's no subexpression */ scratch.d.arraycoerce.amstate = NULL; } diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index bd8a15d..f9244d8 100644 *** a/src/backend/executor/execExprInterp.c --- b/src/backend/executor/execExprInterp.c *************** ExecInterpExpr(ExprState *state, ExprCon *** 1252,1258 **** EEO_CASE(EEOP_ARRAYCOERCE) { /* too complex for an inline implementation */ ! ExecEvalArrayCoerce(state, op); EEO_NEXT(); } --- 1252,1258 ---- EEO_CASE(EEOP_ARRAYCOERCE) { /* too complex for an inline implementation */ ! ExecEvalArrayCoerce(state, op, econtext); EEO_NEXT(); } *************** ExecEvalArrayExpr(ExprState *state, Expr *** 2328,2338 **** * Source array is in step's result variable. */ void ! ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op) { - ArrayCoerceExpr *acoerce = op->d.arraycoerce.coerceexpr; Datum arraydatum; - FunctionCallInfoData locfcinfo; /* NULL array -> NULL result */ if (*op->resnull) --- 2328,2336 ---- * Source array is in step's result variable. */ void ! ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op, ExprContext *econtext) { Datum arraydatum; /* NULL array -> NULL result */ if (*op->resnull) *************** ExecEvalArrayCoerce(ExprState *state, Ex *** 2344,2350 **** * If it's binary-compatible, modify the element type in the array header, * but otherwise leave the array as we received it. */ ! if (!OidIsValid(acoerce->elemfuncid)) { /* Detoast input array if necessary, and copy in any case */ ArrayType *array = DatumGetArrayTypePCopy(arraydatum); --- 2342,2348 ---- * If it's binary-compatible, modify the element type in the array header, * but otherwise leave the array as we received it. */ ! if (op->d.arraycoerce.elemexprstate == NULL) { /* Detoast input array if necessary, and copy in any case */ ArrayType *array = DatumGetArrayTypePCopy(arraydatum); *************** ExecEvalArrayCoerce(ExprState *state, Ex *** 2355,2377 **** } /* ! * Use array_map to apply the function to each array element. ! * ! * We pass on the desttypmod and isExplicit flags whether or not the ! * function wants them. ! * ! * Note: coercion functions are assumed to not use collation. */ ! InitFunctionCallInfoData(locfcinfo, op->d.arraycoerce.elemfunc, 3, ! InvalidOid, NULL, NULL); ! locfcinfo.arg[0] = arraydatum; ! locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod); ! locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit); ! locfcinfo.argnull[0] = false; ! locfcinfo.argnull[1] = false; ! locfcinfo.argnull[2] = false; ! ! *op->resvalue = array_map(&locfcinfo, op->d.arraycoerce.resultelemtype, op->d.arraycoerce.amstate); } --- 2353,2364 ---- } /* ! * Use array_map to apply the sub-expression to each array element. */ ! *op->resvalue = array_map(arraydatum, ! op->d.arraycoerce.elemexprstate, ! econtext, ! op->d.arraycoerce.resultelemtype, op->d.arraycoerce.amstate); } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index f1bed14..b274af2 100644 *** a/src/backend/nodes/copyfuncs.c --- b/src/backend/nodes/copyfuncs.c *************** _copyArrayCoerceExpr(const ArrayCoerceEx *** 1698,1708 **** ArrayCoerceExpr *newnode = makeNode(ArrayCoerceExpr); COPY_NODE_FIELD(arg); ! COPY_SCALAR_FIELD(elemfuncid); COPY_SCALAR_FIELD(resulttype); COPY_SCALAR_FIELD(resulttypmod); COPY_SCALAR_FIELD(resultcollid); - COPY_SCALAR_FIELD(isExplicit); COPY_SCALAR_FIELD(coerceformat); COPY_LOCATION_FIELD(location); --- 1698,1707 ---- ArrayCoerceExpr *newnode = makeNode(ArrayCoerceExpr); COPY_NODE_FIELD(arg); ! COPY_NODE_FIELD(elemexpr); COPY_SCALAR_FIELD(resulttype); COPY_SCALAR_FIELD(resulttypmod); COPY_SCALAR_FIELD(resultcollid); COPY_SCALAR_FIELD(coerceformat); COPY_LOCATION_FIELD(location); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 8b56b91..5c839f4 100644 *** a/src/backend/nodes/equalfuncs.c --- b/src/backend/nodes/equalfuncs.c *************** static bool *** 513,523 **** _equalArrayCoerceExpr(const ArrayCoerceExpr *a, const ArrayCoerceExpr *b) { COMPARE_NODE_FIELD(arg); ! COMPARE_SCALAR_FIELD(elemfuncid); COMPARE_SCALAR_FIELD(resulttype); COMPARE_SCALAR_FIELD(resulttypmod); COMPARE_SCALAR_FIELD(resultcollid); - COMPARE_SCALAR_FIELD(isExplicit); COMPARE_COERCIONFORM_FIELD(coerceformat); COMPARE_LOCATION_FIELD(location); --- 513,522 ---- _equalArrayCoerceExpr(const ArrayCoerceExpr *a, const ArrayCoerceExpr *b) { COMPARE_NODE_FIELD(arg); ! COMPARE_NODE_FIELD(elemexpr); COMPARE_SCALAR_FIELD(resulttype); COMPARE_SCALAR_FIELD(resulttypmod); COMPARE_SCALAR_FIELD(resultcollid); COMPARE_COERCIONFORM_FIELD(coerceformat); COMPARE_LOCATION_FIELD(location); diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index e3eb0c5..8e6f27e 100644 *** a/src/backend/nodes/nodeFuncs.c --- b/src/backend/nodes/nodeFuncs.c *************** check_functions_in_node(Node *node, chec *** 1717,1731 **** return true; } break; - case T_ArrayCoerceExpr: - { - ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; - - if (OidIsValid(expr->elemfuncid) && - checker(expr->elemfuncid, context)) - return true; - } - break; case T_RowCompareExpr: { RowCompareExpr *rcexpr = (RowCompareExpr *) node; --- 1717,1722 ---- *************** expression_tree_walker(Node *node, *** 2023,2029 **** case T_CoerceViaIO: return walker(((CoerceViaIO *) node)->arg, context); case T_ArrayCoerceExpr: ! return walker(((ArrayCoerceExpr *) node)->arg, context); case T_ConvertRowtypeExpr: return walker(((ConvertRowtypeExpr *) node)->arg, context); case T_CollateExpr: --- 2014,2028 ---- case T_CoerceViaIO: return walker(((CoerceViaIO *) node)->arg, context); case T_ArrayCoerceExpr: ! { ! ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! ! if (walker(acoerce->arg, context)) ! return true; ! if (walker(acoerce->elemexpr, context)) ! return true; ! } ! break; case T_ConvertRowtypeExpr: return walker(((ConvertRowtypeExpr *) node)->arg, context); case T_CollateExpr: *************** expression_tree_mutator(Node *node, *** 2705,2710 **** --- 2704,2710 ---- FLATCOPY(newnode, acoerce, ArrayCoerceExpr); MUTATE(newnode->arg, acoerce->arg, Expr *); + MUTATE(newnode->elemexpr, acoerce->elemexpr, Expr *); return (Node *) newnode; } break; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index b83d919..2532edc 100644 *** a/src/backend/nodes/outfuncs.c --- b/src/backend/nodes/outfuncs.c *************** _outArrayCoerceExpr(StringInfo str, cons *** 1394,1404 **** WRITE_NODE_TYPE("ARRAYCOERCEEXPR"); WRITE_NODE_FIELD(arg); ! WRITE_OID_FIELD(elemfuncid); WRITE_OID_FIELD(resulttype); WRITE_INT_FIELD(resulttypmod); WRITE_OID_FIELD(resultcollid); - WRITE_BOOL_FIELD(isExplicit); WRITE_ENUM_FIELD(coerceformat, CoercionForm); WRITE_LOCATION_FIELD(location); } --- 1394,1403 ---- WRITE_NODE_TYPE("ARRAYCOERCEEXPR"); WRITE_NODE_FIELD(arg); ! WRITE_NODE_FIELD(elemexpr); WRITE_OID_FIELD(resulttype); WRITE_INT_FIELD(resulttypmod); WRITE_OID_FIELD(resultcollid); WRITE_ENUM_FIELD(coerceformat, CoercionForm); WRITE_LOCATION_FIELD(location); } diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index fbf8330..07ba691 100644 *** a/src/backend/nodes/readfuncs.c --- b/src/backend/nodes/readfuncs.c *************** _readArrayCoerceExpr(void) *** 892,902 **** READ_LOCALS(ArrayCoerceExpr); READ_NODE_FIELD(arg); ! READ_OID_FIELD(elemfuncid); READ_OID_FIELD(resulttype); READ_INT_FIELD(resulttypmod); READ_OID_FIELD(resultcollid); - READ_BOOL_FIELD(isExplicit); READ_ENUM_FIELD(coerceformat, CoercionForm); READ_LOCATION_FIELD(location); --- 892,901 ---- READ_LOCALS(ArrayCoerceExpr); READ_NODE_FIELD(arg); ! READ_NODE_FIELD(elemexpr); READ_OID_FIELD(resulttype); READ_INT_FIELD(resulttypmod); READ_OID_FIELD(resultcollid); READ_ENUM_FIELD(coerceformat, CoercionForm); READ_LOCATION_FIELD(location); diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 051a854..8fd49d6 100644 *** a/src/backend/optimizer/path/costsize.c --- b/src/backend/optimizer/path/costsize.c *************** cost_qual_eval_walker(Node *node, cost_q *** 3632,3642 **** else if (IsA(node, ArrayCoerceExpr)) { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! Node *arraynode = (Node *) acoerce->arg; ! if (OidIsValid(acoerce->elemfuncid)) ! context->total.per_tuple += get_func_cost(acoerce->elemfuncid) * ! cpu_operator_cost * estimate_array_length(arraynode); } else if (IsA(node, RowCompareExpr)) { --- 3632,3645 ---- else if (IsA(node, ArrayCoerceExpr)) { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! QualCost perelemcost; ! cost_qual_eval_node(&perelemcost, (Node *) acoerce->elemexpr, ! context->root); ! context->total.startup += perelemcost.startup; ! if (perelemcost.per_tuple > 0) ! context->total.per_tuple += perelemcost.per_tuple * ! estimate_array_length((Node *) acoerce->arg); } else if (IsA(node, RowCompareExpr)) { diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index b0c9e94..dee4414 100644 *** a/src/backend/optimizer/plan/setrefs.c --- b/src/backend/optimizer/plan/setrefs.c *************** fix_expr_common(PlannerInfo *root, Node *** 1395,1406 **** record_plan_function_dependency(root, ((ScalarArrayOpExpr *) node)->opfuncid); } - else if (IsA(node, ArrayCoerceExpr)) - { - if (OidIsValid(((ArrayCoerceExpr *) node)->elemfuncid)) - record_plan_function_dependency(root, - ((ArrayCoerceExpr *) node)->elemfuncid); - } else if (IsA(node, Const)) { Const *con = (Const *) node; --- 1395,1400 ---- diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 93add27..7961362 100644 *** a/src/backend/optimizer/util/clauses.c --- b/src/backend/optimizer/util/clauses.c *************** contain_nonstrict_functions_walker(Node *** 1361,1366 **** --- 1361,1377 ---- return true; if (IsA(node, FieldStore)) return true; + if (IsA(node, ArrayCoerceExpr)) + { + /* + * ArrayCoerceExpr is strict at the array level, regardless of what + * the per-element expression is; so we should ignore elemexpr and + * recurse only into the arg. + */ + return expression_tree_walker((Node *) ((ArrayCoerceExpr *) node)->arg, + contain_nonstrict_functions_walker, + context); + } if (IsA(node, CaseExpr)) return true; if (IsA(node, ArrayExpr)) *************** contain_nonstrict_functions_walker(Node *** 1380,1393 **** if (IsA(node, BooleanTest)) return true; ! /* ! * Check other function-containing nodes; but ArrayCoerceExpr is strict at ! * the array level, regardless of elemfunc. ! */ ! if (!IsA(node, ArrayCoerceExpr) && ! check_functions_in_node(node, contain_nonstrict_functions_checker, context)) return true; return expression_tree_walker(node, contain_nonstrict_functions_walker, context); } --- 1391,1401 ---- if (IsA(node, BooleanTest)) return true; ! /* Check other function-containing nodes */ ! if (check_functions_in_node(node, contain_nonstrict_functions_checker, context)) return true; + return expression_tree_walker(node, contain_nonstrict_functions_walker, context); } *************** find_nonnullable_rels_walker(Node *node, *** 1757,1763 **** } else if (IsA(node, ArrayCoerceExpr)) { ! /* ArrayCoerceExpr is strict at the array level */ ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; result = find_nonnullable_rels_walker((Node *) expr->arg, top_level); --- 1765,1771 ---- } else if (IsA(node, ArrayCoerceExpr)) { ! /* ArrayCoerceExpr is strict at the array level; ignore elemexpr */ ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; result = find_nonnullable_rels_walker((Node *) expr->arg, top_level); *************** find_nonnullable_vars_walker(Node *node, *** 1965,1971 **** } else if (IsA(node, ArrayCoerceExpr)) { ! /* ArrayCoerceExpr is strict at the array level */ ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; result = find_nonnullable_vars_walker((Node *) expr->arg, top_level); --- 1973,1979 ---- } else if (IsA(node, ArrayCoerceExpr)) { ! /* ArrayCoerceExpr is strict at the array level; ignore elemexpr */ ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; result = find_nonnullable_vars_walker((Node *) expr->arg, top_level); *************** eval_const_expressions_mutator(Node *nod *** 3005,3036 **** { ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; Expr *arg; ArrayCoerceExpr *newexpr; /* ! * Reduce constants in the ArrayCoerceExpr's argument, then ! * build a new ArrayCoerceExpr. */ arg = (Expr *) eval_const_expressions_mutator((Node *) expr->arg, context); newexpr = makeNode(ArrayCoerceExpr); newexpr->arg = arg; ! newexpr->elemfuncid = expr->elemfuncid; newexpr->resulttype = expr->resulttype; newexpr->resulttypmod = expr->resulttypmod; newexpr->resultcollid = expr->resultcollid; - newexpr->isExplicit = expr->isExplicit; newexpr->coerceformat = expr->coerceformat; newexpr->location = expr->location; /* ! * If constant argument and it's a binary-coercible or ! * immutable conversion, we can simplify it to a constant. */ if (arg && IsA(arg, Const) && ! (!OidIsValid(newexpr->elemfuncid) || ! func_volatile(newexpr->elemfuncid) == PROVOLATILE_IMMUTABLE)) return (Node *) evaluate_expr((Expr *) newexpr, newexpr->resulttype, newexpr->resulttypmod, --- 3013,3050 ---- { ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; Expr *arg; + Expr *elemexpr; ArrayCoerceExpr *newexpr; /* ! * Reduce constants in the ArrayCoerceExpr's argument and ! * per-element expressions, then build a new ArrayCoerceExpr. */ arg = (Expr *) eval_const_expressions_mutator((Node *) expr->arg, context); + elemexpr = (Expr *) eval_const_expressions_mutator((Node *) expr->elemexpr, + context); newexpr = makeNode(ArrayCoerceExpr); newexpr->arg = arg; ! newexpr->elemexpr = elemexpr; newexpr->resulttype = expr->resulttype; newexpr->resulttypmod = expr->resulttypmod; newexpr->resultcollid = expr->resultcollid; newexpr->coerceformat = expr->coerceformat; newexpr->location = expr->location; /* ! * If constant argument and per-element expression is ! * immutable, we can simplify the whole thing to a constant. ! * Exception: although contain_mutable_functions considers ! * CoerceToDomain immutable for historical reasons, let's not ! * do so here; this ensures coercion to an array-over-domain ! * does not apply the domain's constraints until runtime. */ if (arg && IsA(arg, Const) && ! elemexpr && !IsA(elemexpr, CoerceToDomain) && ! !contain_mutable_functions((Node *) elemexpr)) return (Node *) evaluate_expr((Expr *) newexpr, newexpr->resulttype, newexpr->resulttypmod, diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index 5a241bd..0355c02 100644 *** a/src/backend/parser/parse_coerce.c --- b/src/backend/parser/parse_coerce.c *************** build_coercion_expression(Node *node, *** 876,894 **** { /* We need to build an ArrayCoerceExpr */ ArrayCoerceExpr *acoerce = makeNode(ArrayCoerceExpr); acoerce->arg = (Expr *) node; ! acoerce->elemfuncid = funcId; acoerce->resulttype = targetTypeId; /* ! * Label the output as having a particular typmod only if we are ! * really invoking a length-coercion function, ie one with more than ! * one argument. */ ! acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1; /* resultcollid will be set by parse_collate.c */ - acoerce->isExplicit = (ccontext == COERCION_EXPLICIT); acoerce->coerceformat = cformat; acoerce->location = location; --- 876,927 ---- { /* We need to build an ArrayCoerceExpr */ ArrayCoerceExpr *acoerce = makeNode(ArrayCoerceExpr); + CaseTestExpr *ctest = makeNode(CaseTestExpr); + Oid sourceBaseTypeId; + int32 sourceBaseTypeMod; + Oid targetElementType; + Node *elemexpr; + + /* + * Look through any domain over the source array type. Note we don't + * expect that the target type is a domain; it must be a plain array. + * (To get to a domain target type, we'll do coerce_to_domain later.) + */ + sourceBaseTypeMod = exprTypmod(node); + sourceBaseTypeId = getBaseTypeAndTypmod(exprType(node), + &sourceBaseTypeMod); + + /* Set up CaseTestExpr representing one element of source array */ + ctest->typeId = get_element_type(sourceBaseTypeId); + Assert(OidIsValid(ctest->typeId)); + ctest->typeMod = sourceBaseTypeMod; + ctest->collation = InvalidOid; /* Assume coercions don't care */ + + /* And coerce it to the target element type */ + targetElementType = get_element_type(targetTypeId); + Assert(OidIsValid(targetElementType)); + + elemexpr = coerce_to_target_type(NULL, + (Node *) ctest, + ctest->typeId, + targetElementType, + targetTypMod, + ccontext, + cformat, + location); + if (elemexpr == NULL) /* shouldn't happen */ + elog(ERROR, "failed to coerce array element type as expected"); acoerce->arg = (Expr *) node; ! acoerce->elemexpr = (Expr *) elemexpr; acoerce->resulttype = targetTypeId; /* ! * Label the output as having a particular element typmod only if we ! * ended up with a per-element expression that is labeled that way. */ ! acoerce->resulttypmod = exprTypmod(elemexpr); /* resultcollid will be set by parse_collate.c */ acoerce->coerceformat = cformat; acoerce->location = location; *************** IsBinaryCoercible(Oid srctype, Oid targe *** 2143,2150 **** * COERCION_PATH_RELABELTYPE: binary-compatible cast, no function needed * *funcid is set to InvalidOid * COERCION_PATH_ARRAYCOERCE: need an ArrayCoerceExpr node ! * *funcid is set to the element cast function, or InvalidOid ! * if the array elements are binary-compatible * COERCION_PATH_COERCEVIAIO: need a CoerceViaIO node * *funcid is set to InvalidOid * --- 2176,2182 ---- * COERCION_PATH_RELABELTYPE: binary-compatible cast, no function needed * *funcid is set to InvalidOid * COERCION_PATH_ARRAYCOERCE: need an ArrayCoerceExpr node ! * *funcid is set to InvalidOid * COERCION_PATH_COERCEVIAIO: need a CoerceViaIO node * *funcid is set to InvalidOid * *************** find_coercion_pathway(Oid targetTypeId, *** 2230,2240 **** { /* * If there's no pg_cast entry, perhaps we are dealing with a pair of ! * array types. If so, and if the element types have a suitable cast, ! * report that we can coerce with an ArrayCoerceExpr. ! * ! * Note that the source type can be a domain over array, but not the ! * target, because ArrayCoerceExpr won't check domain constraints. * * Hack: disallow coercions to oidvector and int2vector, which * otherwise tend to capture coercions that should go to "real" array --- 2262,2269 ---- { /* * If there's no pg_cast entry, perhaps we are dealing with a pair of ! * array types. If so, and if their element types have a conversion ! * pathway, report that we can coerce with an ArrayCoerceExpr. * * Hack: disallow coercions to oidvector and int2vector, which * otherwise tend to capture coercions that should go to "real" array *************** find_coercion_pathway(Oid targetTypeId, *** 2249,2255 **** Oid sourceElem; if ((targetElem = get_element_type(targetTypeId)) != InvalidOid && ! (sourceElem = get_base_element_type(sourceTypeId)) != InvalidOid) { CoercionPathType elempathtype; Oid elemfuncid; --- 2278,2284 ---- Oid sourceElem; if ((targetElem = get_element_type(targetTypeId)) != InvalidOid && ! (sourceElem = get_element_type(sourceTypeId)) != InvalidOid) { CoercionPathType elempathtype; Oid elemfuncid; *************** find_coercion_pathway(Oid targetTypeId, *** 2258,2271 **** sourceElem, ccontext, &elemfuncid); ! if (elempathtype != COERCION_PATH_NONE && ! elempathtype != COERCION_PATH_ARRAYCOERCE) { ! *funcid = elemfuncid; ! if (elempathtype == COERCION_PATH_COERCEVIAIO) ! result = COERCION_PATH_COERCEVIAIO; ! else ! result = COERCION_PATH_ARRAYCOERCE; } } } --- 2287,2295 ---- sourceElem, ccontext, &elemfuncid); ! if (elempathtype != COERCION_PATH_NONE) { ! result = COERCION_PATH_ARRAYCOERCE; } } } *************** find_coercion_pathway(Oid targetTypeId, *** 2306,2312 **** * If the given type is a varlena array type, we do not look for a coercion * function associated directly with the array type, but instead look for * one associated with the element type. An ArrayCoerceExpr node must be ! * used to apply such a function. * * We use the same result enum as find_coercion_pathway, but the only possible * result codes are: --- 2330,2338 ---- * If the given type is a varlena array type, we do not look for a coercion * function associated directly with the array type, but instead look for * one associated with the element type. An ArrayCoerceExpr node must be ! * used to apply such a function. (Note: currently, it's pointless to ! * return the funcid in this case, because it'll just get looked up again ! * in the recursive construction of the ArrayCoerceExpr's elemexpr.) * * We use the same result enum as find_coercion_pathway, but the only possible * result codes are: diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index 2a4de41..4caff0b 100644 *** a/src/backend/utils/adt/arrayfuncs.c --- b/src/backend/utils/adt/arrayfuncs.c *************** array_set(ArrayType *array, int nSubscri *** 3092,3112 **** /* * array_map() * ! * Map an array through an arbitrary function. Return a new array with ! * same dimensions and each source element transformed by fn(). Each ! * source element is passed as the first argument to fn(); additional ! * arguments to be passed to fn() can be specified by the caller. ! * The output array can have a different element type than the input. * * Parameters are: ! * * fcinfo: a function-call data structure pre-constructed by the caller ! * to be ready to call the desired function, with everything except the ! * first argument position filled in. In particular, flinfo identifies ! * the function fn(), and if nargs > 1 then argument positions after the ! * first must be preset to the additional values to be passed. The ! * first argument position initially holds the input array value. * * retType: OID of element type of output array. This must be the same as, ! * or binary-compatible with, the result type of fn(). * * amstate: workspace for array_map. Must be zeroed by caller before * first call, and not touched after that. * --- 3092,3109 ---- /* * array_map() * ! * Map an array through an arbitrary expression. Return a new array with ! * the same dimensions and each source element transformed by the given, ! * already-compiled expression. Each source element is placed in the ! * innermost_caseval/innermost_casenull fields of the ExprState. * * Parameters are: ! * * arrayd: Datum representing array argument. ! * * exprstate: ExprState representing the per-element transformation. ! * * econtext: context for expression evaluation. * * retType: OID of element type of output array. This must be the same as, ! * or binary-compatible with, the result type of the expression. It might ! * be different from the input array's element type. * * amstate: workspace for array_map. Must be zeroed by caller before * first call, and not touched after that. * *************** array_set(ArrayType *array, int nSubscri *** 3116,3126 **** * * NB: caller must assure that input array is not NULL. NULL elements in * the array are OK however. */ Datum ! array_map(FunctionCallInfo fcinfo, Oid retType, ArrayMapState *amstate) { ! AnyArrayType *v; ArrayType *result; Datum *values; bool *nulls; --- 3113,3126 ---- * * NB: caller must assure that input array is not NULL. NULL elements in * the array are OK however. + * NB: caller should be running in econtext's per-tuple memory context. */ Datum ! array_map(Datum arrayd, ! ExprState *exprstate, ExprContext *econtext, ! Oid retType, ArrayMapState *amstate) { ! AnyArrayType *v = DatumGetAnyArray(arrayd); ArrayType *result; Datum *values; bool *nulls; *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3141,3153 **** array_iter iter; ArrayMetaState *inp_extra; ArrayMetaState *ret_extra; ! ! /* Get input array */ ! if (fcinfo->nargs < 1) ! elog(ERROR, "invalid nargs: %d", fcinfo->nargs); ! if (PG_ARGISNULL(0)) ! elog(ERROR, "null input array"); ! v = PG_GETARG_ANY_ARRAY(0); inpType = AARR_ELEMTYPE(v); ndim = AARR_NDIM(v); --- 3141,3148 ---- array_iter iter; ArrayMetaState *inp_extra; ArrayMetaState *ret_extra; ! Datum *transform_source = exprstate->innermost_caseval; ! bool *transform_source_isnull = exprstate->innermost_casenull; inpType = AARR_ELEMTYPE(v); ndim = AARR_NDIM(v); *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3158,3164 **** if (nitems <= 0) { /* Return empty array */ ! PG_RETURN_ARRAYTYPE_P(construct_empty_array(retType)); } /* --- 3153,3159 ---- if (nitems <= 0) { /* Return empty array */ ! return PointerGetDatum(construct_empty_array(retType)); } /* *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3203,3241 **** for (i = 0; i < nitems; i++) { - bool callit = true; - /* Get source element, checking for NULL */ ! fcinfo->arg[0] = array_iter_next(&iter, &fcinfo->argnull[0], i, ! inp_typlen, inp_typbyval, inp_typalign); ! ! /* ! * Apply the given function to source elt and extra args. ! */ ! if (fcinfo->flinfo->fn_strict) ! { ! int j; ! ! for (j = 0; j < fcinfo->nargs; j++) ! { ! if (fcinfo->argnull[j]) ! { ! callit = false; ! break; ! } ! } ! } ! if (callit) ! { ! fcinfo->isnull = false; ! values[i] = FunctionCallInvoke(fcinfo); ! } ! else ! fcinfo->isnull = true; ! nulls[i] = fcinfo->isnull; ! if (fcinfo->isnull) hasnulls = true; else { --- 3198,3212 ---- for (i = 0; i < nitems; i++) { /* Get source element, checking for NULL */ ! *transform_source = ! array_iter_next(&iter, transform_source_isnull, i, ! inp_typlen, inp_typbyval, inp_typalign); ! /* Apply the given expression to source element */ ! values[i] = ExecEvalExpr(exprstate, econtext, &nulls[i]); ! if (nulls[i]) hasnulls = true; else { *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3254,3260 **** } } ! /* Allocate and initialize the result array */ if (hasnulls) { dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nitems); --- 3225,3231 ---- } } ! /* Allocate and fill the result array */ if (hasnulls) { dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nitems); *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3273,3290 **** memcpy(ARR_DIMS(result), AARR_DIMS(v), ndim * sizeof(int)); memcpy(ARR_LBOUND(result), AARR_LBOUND(v), ndim * sizeof(int)); - /* - * Note: do not risk trying to pfree the results of the called function - */ CopyArrayEls(result, values, nulls, nitems, typlen, typbyval, typalign, false); pfree(values); pfree(nulls); ! PG_RETURN_ARRAYTYPE_P(result); } /* --- 3244,3261 ---- memcpy(ARR_DIMS(result), AARR_DIMS(v), ndim * sizeof(int)); memcpy(ARR_LBOUND(result), AARR_LBOUND(v), ndim * sizeof(int)); CopyArrayEls(result, values, nulls, nitems, typlen, typbyval, typalign, false); + /* + * Note: do not risk trying to pfree the results of the called expression + */ pfree(values); pfree(nulls); ! return PointerGetDatum(result); } /* diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 81b0bc3..7b3fdc9 100644 *** a/src/backend/utils/adt/selfuncs.c --- b/src/backend/utils/adt/selfuncs.c *************** strip_array_coercion(Node *node) *** 1753,1762 **** { for (;;) { ! if (node && IsA(node, ArrayCoerceExpr) && ! ((ArrayCoerceExpr *) node)->elemfuncid == InvalidOid) { ! node = (Node *) ((ArrayCoerceExpr *) node)->arg; } else if (node && IsA(node, RelabelType)) { --- 1753,1771 ---- { for (;;) { ! if (node && IsA(node, ArrayCoerceExpr)) { ! ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! ! /* ! * If the per-element expression is just a RelabelType on top of ! * CaseTestExpr, then we know it's a binary-compatible relabeling. ! */ ! if (IsA(acoerce->elemexpr, RelabelType) && ! IsA(((RelabelType *) acoerce->elemexpr)->arg, CaseTestExpr)) ! node = (Node *) acoerce->arg; ! else ! break; } else if (node && IsA(node, RelabelType)) { diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index a7b0782..9197335 100644 *** a/src/backend/utils/fmgr/fmgr.c --- b/src/backend/utils/fmgr/fmgr.c *************** get_call_expr_argtype(Node *expr, int ar *** 1941,1948 **** args = ((DistinctExpr *) expr)->args; else if (IsA(expr, ScalarArrayOpExpr)) args = ((ScalarArrayOpExpr *) expr)->args; - else if (IsA(expr, ArrayCoerceExpr)) - args = list_make1(((ArrayCoerceExpr *) expr)->arg); else if (IsA(expr, NullIfExpr)) args = ((NullIfExpr *) expr)->args; else if (IsA(expr, WindowFunc)) --- 1941,1946 ---- *************** get_call_expr_argtype(Node *expr, int ar *** 1956,1971 **** argtype = exprType((Node *) list_nth(args, argnum)); /* ! * special hack for ScalarArrayOpExpr and ArrayCoerceExpr: what the ! * underlying function will actually get passed is the element type of the ! * array. */ if (IsA(expr, ScalarArrayOpExpr) && argnum == 1) argtype = get_base_element_type(argtype); - else if (IsA(expr, ArrayCoerceExpr) && - argnum == 0) - argtype = get_base_element_type(argtype); return argtype; } --- 1954,1965 ---- argtype = exprType((Node *) list_nth(args, argnum)); /* ! * special hack for ScalarArrayOpExpr: what the underlying function will ! * actually get passed is the element type of the array. */ if (IsA(expr, ScalarArrayOpExpr) && argnum == 1) argtype = get_base_element_type(argtype); return argtype; } *************** get_call_expr_arg_stable(Node *expr, int *** 2012,2019 **** args = ((DistinctExpr *) expr)->args; else if (IsA(expr, ScalarArrayOpExpr)) args = ((ScalarArrayOpExpr *) expr)->args; - else if (IsA(expr, ArrayCoerceExpr)) - args = list_make1(((ArrayCoerceExpr *) expr)->arg); else if (IsA(expr, NullIfExpr)) args = ((NullIfExpr *) expr)->args; else if (IsA(expr, WindowFunc)) --- 2006,2011 ---- diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h index 8ee0496..78d2247 100644 *** a/src/include/executor/execExpr.h --- b/src/include/executor/execExpr.h *************** typedef struct ExprEvalStep *** 385,394 **** /* for EEOP_ARRAYCOERCE */ struct { ! ArrayCoerceExpr *coerceexpr; Oid resultelemtype; /* element type of result array */ - FmgrInfo *elemfunc; /* lookup info for element coercion - * function */ struct ArrayMapState *amstate; /* workspace for array_map */ } arraycoerce; --- 385,392 ---- /* for EEOP_ARRAYCOERCE */ struct { ! ExprState *elemexprstate; /* null if no per-element work */ Oid resultelemtype; /* element type of result array */ struct ArrayMapState *amstate; /* workspace for array_map */ } arraycoerce; *************** extern void ExecEvalRowNull(ExprState *s *** 621,627 **** extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext); extern void ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op); ! extern void ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op); extern void ExecEvalRow(ExprState *state, ExprEvalStep *op); extern void ExecEvalMinMax(ExprState *state, ExprEvalStep *op); extern void ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, --- 619,626 ---- extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext); extern void ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op); ! extern void ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op, ! ExprContext *econtext); extern void ExecEvalRow(ExprState *state, ExprEvalStep *op); extern void ExecEvalMinMax(ExprState *state, ExprEvalStep *op); extern void ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 8c536a8..ccb5123 100644 *** a/src/include/nodes/primnodes.h --- b/src/include/nodes/primnodes.h *************** typedef struct CoerceViaIO *** 820,830 **** * ArrayCoerceExpr * * ArrayCoerceExpr represents a type coercion from one array type to another, ! * which is implemented by applying the indicated element-type coercion ! * function to each element of the source array. If elemfuncid is InvalidOid ! * then the element types are binary-compatible, but the coercion still ! * requires some effort (we have to fix the element type ID stored in the ! * array header). * ---------------- */ --- 820,831 ---- * ArrayCoerceExpr * * ArrayCoerceExpr represents a type coercion from one array type to another, ! * which is implemented by applying the per-element coercion expression ! * "elemexpr" to each element of the source array. Within elemexpr, the ! * source element is represented by a CaseTestExpr node. Note that even if ! * elemexpr is a no-op (that is, just CaseTestExpr + RelabelType), the ! * coercion still requires some effort: we have to fix the element type OID ! * stored in the array header. * ---------------- */ *************** typedef struct ArrayCoerceExpr *** 832,842 **** { Expr xpr; Expr *arg; /* input expression (yields an array) */ ! Oid elemfuncid; /* OID of element coercion function, or 0 */ Oid resulttype; /* output type of coercion (an array type) */ int32 resulttypmod; /* output typmod (also element typmod) */ Oid resultcollid; /* OID of collation, or InvalidOid if none */ - bool isExplicit; /* conversion semantics flag to pass to func */ CoercionForm coerceformat; /* how to display this node */ int location; /* token location, or -1 if unknown */ } ArrayCoerceExpr; --- 833,842 ---- { Expr xpr; Expr *arg; /* input expression (yields an array) */ ! Expr *elemexpr; /* expression representing per-element work */ Oid resulttype; /* output type of coercion (an array type) */ int32 resulttypmod; /* output typmod (also element typmod) */ Oid resultcollid; /* OID of collation, or InvalidOid if none */ CoercionForm coerceformat; /* how to display this node */ int location; /* token location, or -1 if unknown */ } ArrayCoerceExpr; diff --git a/src/include/utils/array.h b/src/include/utils/array.h index 61a67a2..32833f0 100644 *** a/src/include/utils/array.h --- b/src/include/utils/array.h *************** *** 64,69 **** --- 64,73 ---- #include "fmgr.h" #include "utils/expandeddatum.h" + /* avoid including execnodes.h here */ + struct ExprState; + struct ExprContext; + /* * Arrays are varlena objects, so must meet the varlena convention that *************** extern ArrayType *array_set(ArrayType *a *** 360,367 **** Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign); ! extern Datum array_map(FunctionCallInfo fcinfo, Oid retType, ! ArrayMapState *amstate); extern void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, --- 364,372 ---- Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign); ! extern Datum array_map(Datum arrayd, ! struct ExprState *exprstate, struct ExprContext *econtext, ! Oid retType, ArrayMapState *amstate); extern void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, [text/x-diff] 03-support-arrays-of-domains-2.patch (9.5K, ../../[email protected]/4-03-support-arrays-of-domains-2.patch) download | inline diff: diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 7ed16ae..12d2cd6 100644 *** a/src/backend/commands/typecmds.c --- b/src/backend/commands/typecmds.c *************** ObjectAddress *** 729,734 **** --- 729,735 ---- DefineDomain(CreateDomainStmt *stmt) { char *domainName; + char *domainArrayName; Oid domainNamespace; AclResult aclresult; int16 internalLength; *************** DefineDomain(CreateDomainStmt *stmt) *** 757,762 **** --- 758,764 ---- Oid basetypeoid; Oid old_type_oid; Oid domaincoll; + Oid domainArrayOid; Form_pg_type baseType; int32 basetypeMod; Oid baseColl; *************** DefineDomain(CreateDomainStmt *stmt) *** 1027,1032 **** --- 1029,1037 ---- } } + /* Allocate OID for array type */ + domainArrayOid = AssignTypeArrayOid(); + /* * Have TypeCreate do all the real work. */ *************** DefineDomain(CreateDomainStmt *stmt) *** 1051,1057 **** analyzeProcedure, /* analyze procedure */ InvalidOid, /* no array element type */ false, /* this isn't an array */ ! InvalidOid, /* no arrays for domains (yet) */ basetypeoid, /* base type ID */ defaultValue, /* default type value (text) */ defaultValueBin, /* default type value (binary) */ --- 1056,1062 ---- analyzeProcedure, /* analyze procedure */ InvalidOid, /* no array element type */ false, /* this isn't an array */ ! domainArrayOid, /* array type we are about to create */ basetypeoid, /* base type ID */ defaultValue, /* default type value (text) */ defaultValueBin, /* default type value (binary) */ *************** DefineDomain(CreateDomainStmt *stmt) *** 1064,1069 **** --- 1069,1116 ---- domaincoll); /* type's collation */ /* + * Create the array type that goes with it. + */ + domainArrayName = makeArrayTypeName(domainName, domainNamespace); + + /* alignment must be 'i' or 'd' for arrays */ + alignment = (alignment == 'd') ? 'd' : 'i'; + + TypeCreate(domainArrayOid, /* force assignment of this type OID */ + domainArrayName, /* type name */ + domainNamespace, /* namespace */ + InvalidOid, /* relation oid (n/a here) */ + 0, /* relation kind (ditto) */ + GetUserId(), /* owner's ID */ + -1, /* internal size (always varlena) */ + TYPTYPE_BASE, /* type-type (base type) */ + TYPCATEGORY_ARRAY, /* type-category (array) */ + false, /* array types are never preferred */ + delimiter, /* array element delimiter */ + F_ARRAY_IN, /* input procedure */ + F_ARRAY_OUT, /* output procedure */ + F_ARRAY_RECV, /* receive procedure */ + F_ARRAY_SEND, /* send procedure */ + InvalidOid, /* typmodin procedure - none */ + InvalidOid, /* typmodout procedure - none */ + F_ARRAY_TYPANALYZE, /* analyze procedure */ + address.objectId, /* element type ID */ + true, /* yes this is an array type */ + InvalidOid, /* no further array type */ + InvalidOid, /* base type ID */ + NULL, /* never a default type value */ + NULL, /* binary default isn't sent either */ + false, /* never passed by value */ + alignment, /* see above */ + 'x', /* ARRAY is always toastable */ + -1, /* typMod (Domains only) */ + 0, /* Array dimensions of typbasetype */ + false, /* Type NOT NULL */ + domaincoll); /* type's collation */ + + pfree(domainArrayName); + + /* * Process constraints which refer to the domain ID returned by TypeCreate */ foreach(listptr, schema) *************** DefineEnum(CreateEnumStmt *stmt) *** 1139,1144 **** --- 1186,1192 ---- errmsg("type \"%s\" already exists", enumName))); } + /* Allocate OID for array type */ enumArrayOid = AssignTypeArrayOid(); /* Create the pg_type entry */ diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out index 3acc696..1e62c57 100644 *** a/src/test/regress/expected/domain.out --- b/src/test/regress/expected/domain.out *************** Rules: *** 310,315 **** --- 310,410 ---- drop table dcomptable; drop type comptype cascade; NOTICE: drop cascades to type dcomptypea + -- Test arrays over domains + create domain posint as int check (value > 0); + create table pitable (f1 posint[]); + insert into pitable values(array[42]); + insert into pitable values(array[-1]); -- fail + ERROR: value for domain posint violates check constraint "posint_check" + insert into pitable values('{0}'); -- fail + ERROR: value for domain posint violates check constraint "posint_check" + LINE 1: insert into pitable values('{0}'); + ^ + update pitable set f1[1] = f1[1] + 1; + update pitable set f1[1] = 0; -- fail + ERROR: value for domain posint violates check constraint "posint_check" + select * from pitable; + f1 + ------ + {43} + (1 row) + + drop table pitable; + create domain vc4 as varchar(4); + create table vc4table (f1 vc4[]); + insert into vc4table values(array['too long']); -- fail + ERROR: value too long for type character varying(4) + insert into vc4table values(array['too long']::vc4[]); -- cast truncates + select * from vc4table; + f1 + ---------- + {"too "} + (1 row) + + drop table vc4table; + drop type vc4; + -- You can sort of fake arrays-of-arrays by putting a domain in between + create domain dposinta as posint[]; + create table dposintatable (f1 dposinta[]); + insert into dposintatable values(array[array[42]]); -- fail + ERROR: column "f1" is of type dposinta[] but expression is of type integer[] + LINE 1: insert into dposintatable values(array[array[42]]); + ^ + HINT: You will need to rewrite or cast the expression. + insert into dposintatable values(array[array[42]::posint[]]); -- still fail + ERROR: column "f1" is of type dposinta[] but expression is of type posint[] + LINE 1: insert into dposintatable values(array[array[42]::posint[]])... + ^ + HINT: You will need to rewrite or cast the expression. + insert into dposintatable values(array[array[42]::dposinta]); -- but this works + select f1, f1[1], (f1[1])[1] from dposintatable; + f1 | f1 | f1 + ----------+------+---- + {"{42}"} | {42} | 42 + (1 row) + + select pg_typeof(f1) from dposintatable; + pg_typeof + ------------ + dposinta[] + (1 row) + + select pg_typeof(f1[1]) from dposintatable; + pg_typeof + ----------- + dposinta + (1 row) + + select pg_typeof(f1[1][1]) from dposintatable; + pg_typeof + ----------- + dposinta + (1 row) + + select pg_typeof((f1[1])[1]) from dposintatable; + pg_typeof + ----------- + posint + (1 row) + + update dposintatable set f1[2] = array[99]; + select f1, f1[1], (f1[2])[1] from dposintatable; + f1 | f1 | f1 + -----------------+------+---- + {"{42}","{99}"} | {42} | 99 + (1 row) + + -- it'd be nice if you could do something like this, but for now you can't: + update dposintatable set f1[2][1] = array[97]; + ERROR: wrong number of array subscripts + -- maybe someday we can make this syntax work: + update dposintatable set (f1[2])[1] = array[98]; + ERROR: syntax error at or near "[" + LINE 1: update dposintatable set (f1[2])[1] = array[98]; + ^ + drop table dposintatable; + drop domain posint cascade; + NOTICE: drop cascades to type dposinta -- Test not-null restrictions create domain dnotnull varchar(15) NOT NULL; create domain dnull varchar(15); diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql index 0fd383e..8fb3e20 100644 *** a/src/test/regress/sql/domain.sql --- b/src/test/regress/sql/domain.sql *************** drop table dcomptable; *** 166,171 **** --- 166,214 ---- drop type comptype cascade; + -- Test arrays over domains + + create domain posint as int check (value > 0); + + create table pitable (f1 posint[]); + insert into pitable values(array[42]); + insert into pitable values(array[-1]); -- fail + insert into pitable values('{0}'); -- fail + update pitable set f1[1] = f1[1] + 1; + update pitable set f1[1] = 0; -- fail + select * from pitable; + drop table pitable; + + create domain vc4 as varchar(4); + create table vc4table (f1 vc4[]); + insert into vc4table values(array['too long']); -- fail + insert into vc4table values(array['too long']::vc4[]); -- cast truncates + select * from vc4table; + drop table vc4table; + drop type vc4; + + -- You can sort of fake arrays-of-arrays by putting a domain in between + create domain dposinta as posint[]; + create table dposintatable (f1 dposinta[]); + insert into dposintatable values(array[array[42]]); -- fail + insert into dposintatable values(array[array[42]::posint[]]); -- still fail + insert into dposintatable values(array[array[42]::dposinta]); -- but this works + select f1, f1[1], (f1[1])[1] from dposintatable; + select pg_typeof(f1) from dposintatable; + select pg_typeof(f1[1]) from dposintatable; + select pg_typeof(f1[1][1]) from dposintatable; + select pg_typeof((f1[1])[1]) from dposintatable; + update dposintatable set f1[2] = array[99]; + select f1, f1[1], (f1[2])[1] from dposintatable; + -- it'd be nice if you could do something like this, but for now you can't: + update dposintatable set f1[2][1] = array[97]; + -- maybe someday we can make this syntax work: + update dposintatable set (f1[2])[1] = array[98]; + + drop table dposintatable; + drop domain posint cascade; + + -- Test not-null restrictions create domain dnotnull varchar(15) NOT NULL; ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: Arrays of domains @ 2017-09-21 19:49 Tom Lane <[email protected]> parent: Tom Lane <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Tom Lane @ 2017-09-21 19:49 UTC (permalink / raw) To: pgsql-hackers I wrote: > Here's a rebased-up-to-HEAD version of this patch set. The only > actual change is removal of a no-longer-needed hunk in pl_exec.c. I see the patch tester is complaining that this broke, due to commit 4bd199465. The fix is trivial (s/GETARG_ANY_ARRAY/GETARG_ANY_ARRAY_P/) but for convenience here's an updated patch set. regards, tom lane -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers Attachments: [text/x-diff] 01-rationalize-coercion-APIs-3.patch (14.3K, ../../[email protected]/2-01-rationalize-coercion-APIs-3.patch) download | inline diff: diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c index 9d75e86..d7db32e 100644 *** a/src/backend/optimizer/prep/preptlist.c --- b/src/backend/optimizer/prep/preptlist.c *************** expand_targetlist(List *tlist, int comma *** 306,314 **** new_expr = coerce_to_domain(new_expr, InvalidOid, -1, atttype, COERCE_IMPLICIT_CAST, -1, - false, false); } else --- 306,314 ---- new_expr = coerce_to_domain(new_expr, InvalidOid, -1, atttype, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } else diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index e79ad26..5a241bd 100644 *** a/src/backend/parser/parse_coerce.c --- b/src/backend/parser/parse_coerce.c *************** *** 34,48 **** static Node *coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit, bool hideInputCoercion); static void hide_coercion_node(Node *node); static Node *build_coercion_expression(Node *node, CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit); static Node *coerce_record_to_complex(ParseState *pstate, Node *node, Oid targetTypeId, CoercionContext ccontext, --- 34,49 ---- static Node *coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location, ! bool hideInputCoercion); static void hide_coercion_node(Node *node); static Node *build_coercion_expression(Node *node, CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location); static Node *coerce_record_to_complex(ParseState *pstate, Node *node, Oid targetTypeId, CoercionContext ccontext, *************** coerce_to_target_type(ParseState *pstate *** 110,117 **** */ result = coerce_type_typmod(result, targettype, targettypmod, ! cformat, location, ! (cformat != COERCE_IMPLICIT_CAST), (result != expr && !IsA(result, Const))); if (expr != origexpr) --- 111,117 ---- */ result = coerce_type_typmod(result, targettype, targettypmod, ! ccontext, cformat, location, (result != expr && !IsA(result, Const))); if (expr != origexpr) *************** coerce_type(ParseState *pstate, Node *no *** 355,361 **** result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! cformat, location, false, false); ReleaseSysCache(baseType); --- 355,362 ---- result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! ccontext, cformat, location, ! false); ReleaseSysCache(baseType); *************** coerce_type(ParseState *pstate, Node *no *** 417,436 **** result = build_coercion_expression(node, pathtype, funcId, baseTypeId, baseTypeMod, ! cformat, location, ! (cformat != COERCE_IMPLICIT_CAST)); /* * If domain, coerce to the domain type and relabel with domain ! * type ID. We can skip the internal length-coercion step if the ! * selected coercion function was a type-and-length coercion. */ if (targetTypeId != baseTypeId) result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! cformat, location, true, ! exprIsLengthCoercion(result, ! NULL)); } else { --- 418,434 ---- result = build_coercion_expression(node, pathtype, funcId, baseTypeId, baseTypeMod, ! ccontext, cformat, location); /* * If domain, coerce to the domain type and relabel with domain ! * type ID, hiding the previous coercion node. */ if (targetTypeId != baseTypeId) result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! ccontext, cformat, location, ! true); } else { *************** coerce_type(ParseState *pstate, Node *no *** 444,450 **** * then we won't need a RelabelType node. */ result = coerce_to_domain(node, InvalidOid, -1, targetTypeId, ! cformat, location, false, false); if (result == node) { /* --- 442,449 ---- * then we won't need a RelabelType node. */ result = coerce_to_domain(node, InvalidOid, -1, targetTypeId, ! ccontext, cformat, location, ! false); if (result == node) { /* *************** can_coerce_type(int nargs, Oid *input_ty *** 636,654 **** * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller * has not bothered to look this up) * 'typeId': target type to coerce to ! * 'cformat': coercion format * 'location': coercion request location * 'hideInputCoercion': if true, hide the input coercion under this one. - * 'lengthCoercionDone': if true, caller already accounted for length, - * ie the input is already of baseTypMod as well as baseTypeId. * * If the target type isn't a domain, the given 'arg' is returned as-is. */ Node * coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionForm cformat, int location, ! bool hideInputCoercion, ! bool lengthCoercionDone) { CoerceToDomain *result; --- 635,651 ---- * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller * has not bothered to look this up) * 'typeId': target type to coerce to ! * 'ccontext': context indicator to control coercions ! * 'cformat': coercion display format * 'location': coercion request location * 'hideInputCoercion': if true, hide the input coercion under this one. * * If the target type isn't a domain, the given 'arg' is returned as-is. */ Node * coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionContext ccontext, CoercionForm cformat, int location, ! bool hideInputCoercion) { CoerceToDomain *result; *************** coerce_to_domain(Node *arg, Oid baseType *** 677,690 **** * would be safe to do anyway, without lots of knowledge about what the * base type thinks the typmod means. */ ! if (!lengthCoercionDone) ! { ! if (baseTypeMod >= 0) ! arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod, ! COERCE_IMPLICIT_CAST, location, ! (cformat != COERCE_IMPLICIT_CAST), ! false); ! } /* * Now build the domain coercion node. This represents run-time checking --- 674,682 ---- * would be safe to do anyway, without lots of knowledge about what the * base type thinks the typmod means. */ ! arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod, ! ccontext, COERCE_IMPLICIT_CAST, location, ! false); /* * Now build the domain coercion node. This represents run-time checking *************** coerce_to_domain(Node *arg, Oid baseType *** 714,724 **** * The caller must have already ensured that the value is of the correct * type, typically by applying coerce_type. * ! * cformat determines the display properties of the generated node (if any), ! * while isExplicit may affect semantics. If hideInputCoercion is true ! * *and* we generate a node, the input node is forced to IMPLICIT display ! * form, so that only the typmod coercion node will be visible when ! * displaying the expression. * * NOTE: this does not need to work on domain types, because any typmod * coercion for a domain is considered to be part of the type coercion --- 706,719 ---- * The caller must have already ensured that the value is of the correct * type, typically by applying coerce_type. * ! * ccontext may affect semantics, depending on whether the length coercion ! * function pays attention to the isExplicit flag it's passed. ! * ! * cformat determines the display properties of the generated node (if any). ! * ! * If hideInputCoercion is true *and* we generate a node, the input node is ! * forced to IMPLICIT display form, so that only the typmod coercion node will ! * be visible when displaying the expression. * * NOTE: this does not need to work on domain types, because any typmod * coercion for a domain is considered to be part of the type coercion *************** coerce_to_domain(Node *arg, Oid baseType *** 726,733 **** */ static Node * coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit, bool hideInputCoercion) { CoercionPathType pathtype; Oid funcId; --- 721,729 ---- */ static Node * coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location, ! bool hideInputCoercion) { CoercionPathType pathtype; Oid funcId; *************** coerce_type_typmod(Node *node, Oid targe *** 749,756 **** node = build_coercion_expression(node, pathtype, funcId, targetTypeId, targetTypMod, ! cformat, location, ! isExplicit); } return node; --- 745,751 ---- node = build_coercion_expression(node, pathtype, funcId, targetTypeId, targetTypMod, ! ccontext, cformat, location); } return node; *************** build_coercion_expression(Node *node, *** 799,806 **** CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit) { int nargs = 0; --- 794,801 ---- CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location) { int nargs = 0; *************** build_coercion_expression(Node *node, *** 865,871 **** -1, InvalidOid, sizeof(bool), ! BoolGetDatum(isExplicit), false, true); --- 860,866 ---- -1, InvalidOid, sizeof(bool), ! BoolGetDatum(ccontext == COERCION_EXPLICIT), false, true); *************** build_coercion_expression(Node *node, *** 893,899 **** */ acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1; /* resultcollid will be set by parse_collate.c */ ! acoerce->isExplicit = isExplicit; acoerce->coerceformat = cformat; acoerce->location = location; --- 888,894 ---- */ acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1; /* resultcollid will be set by parse_collate.c */ ! acoerce->isExplicit = (ccontext == COERCION_EXPLICIT); acoerce->coerceformat = cformat; acoerce->location = location; diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index ef52dd5..7054d4f 100644 *** a/src/backend/rewrite/rewriteHandler.c --- b/src/backend/rewrite/rewriteHandler.c *************** rewriteTargetListIU(List *targetList, *** 875,883 **** new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, COERCE_IMPLICIT_CAST, -1, - false, false); } } --- 875,883 ---- new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } } *************** rewriteValuesRTE(RangeTblEntry *rte, Rel *** 1271,1279 **** new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, COERCE_IMPLICIT_CAST, -1, - false, false); } newList = lappend(newList, new_expr); --- 1271,1279 ---- new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } newList = lappend(newList, new_expr); diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c index 5c17213..c5773ef 100644 *** a/src/backend/rewrite/rewriteManip.c --- b/src/backend/rewrite/rewriteManip.c *************** ReplaceVarsFromTargetList_callback(Var * *** 1429,1437 **** var->varcollid), InvalidOid, -1, var->vartype, COERCE_IMPLICIT_CAST, -1, - false, false); } elog(ERROR, "could not find replacement targetlist entry for attno %d", --- 1429,1437 ---- var->varcollid), InvalidOid, -1, var->vartype, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } elog(ERROR, "could not find replacement targetlist entry for attno %d", diff --git a/src/include/parser/parse_coerce.h b/src/include/parser/parse_coerce.h index 06f6529..e560f0c 100644 *** a/src/include/parser/parse_coerce.h --- b/src/include/parser/parse_coerce.h *************** extern Node *coerce_type(ParseState *pst *** 48,56 **** CoercionContext ccontext, CoercionForm cformat, int location); extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionForm cformat, int location, ! bool hideInputCoercion, ! bool lengthCoercionDone); extern Node *coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName); --- 48,55 ---- CoercionContext ccontext, CoercionForm cformat, int location); extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionContext ccontext, CoercionForm cformat, int location, ! bool hideInputCoercion); extern Node *coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName); [text/x-diff] 02-reimplement-ArrayCoerceExpr-3.patch (42.4K, ../../[email protected]/3-02-reimplement-ArrayCoerceExpr-3.patch) download | inline diff: diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index fa409d7..1776730 100644 *** a/contrib/pg_stat_statements/pg_stat_statements.c --- b/contrib/pg_stat_statements/pg_stat_statements.c *************** JumbleExpr(pgssJumbleState *jstate, Node *** 2631,2636 **** --- 2631,2637 ---- APP_JUMB(acexpr->resulttype); JumbleExpr(jstate, (Node *) acexpr->arg); + JumbleExpr(jstate, (Node *) acexpr->elemexpr); } break; case T_ConvertRowtypeExpr: diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 6fffc29..2668650 100644 *** a/src/backend/catalog/dependency.c --- b/src/backend/catalog/dependency.c *************** find_expr_references_walker(Node *node, *** 1738,1748 **** { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! if (OidIsValid(acoerce->elemfuncid)) ! add_object_address(OCLASS_PROC, acoerce->elemfuncid, 0, ! context->addrs); add_object_address(OCLASS_TYPE, acoerce->resulttype, 0, context->addrs); /* fall through to examine arguments */ } else if (IsA(node, ConvertRowtypeExpr)) --- 1738,1751 ---- { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! /* as above, depend on type */ add_object_address(OCLASS_TYPE, acoerce->resulttype, 0, context->addrs); + /* the collation might not be referenced anywhere else, either */ + if (OidIsValid(acoerce->resultcollid) && + acoerce->resultcollid != DEFAULT_COLLATION_OID) + add_object_address(OCLASS_COLLATION, acoerce->resultcollid, 0, + context->addrs); /* fall through to examine arguments */ } else if (IsA(node, ConvertRowtypeExpr)) diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index be9d23b..e083961 100644 *** a/src/backend/executor/execExpr.c --- b/src/backend/executor/execExpr.c *************** ExecInitExprRec(Expr *node, PlanState *p *** 1225,1230 **** --- 1225,1231 ---- { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; Oid resultelemtype; + ExprState *elemstate; /* evaluate argument into step's result area */ ExecInitExprRec(acoerce->arg, parent, state, resv, resnull); *************** ExecInitExprRec(Expr *node, PlanState *p *** 1234,1275 **** ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("target type is not an array"))); - /* Arrays over domains aren't supported yet */ - Assert(getBaseType(resultelemtype) == resultelemtype); ! scratch.opcode = EEOP_ARRAYCOERCE; ! scratch.d.arraycoerce.coerceexpr = acoerce; ! scratch.d.arraycoerce.resultelemtype = resultelemtype; ! if (OidIsValid(acoerce->elemfuncid)) ! { ! AclResult aclresult; ! /* Check permission to call function */ ! aclresult = pg_proc_aclcheck(acoerce->elemfuncid, ! GetUserId(), ! ACL_EXECUTE); ! if (aclresult != ACLCHECK_OK) ! aclcheck_error(aclresult, ACL_KIND_PROC, ! get_func_name(acoerce->elemfuncid)); ! InvokeFunctionExecuteHook(acoerce->elemfuncid); ! /* Set up the primary fmgr lookup information */ ! scratch.d.arraycoerce.elemfunc = ! (FmgrInfo *) palloc0(sizeof(FmgrInfo)); ! fmgr_info(acoerce->elemfuncid, ! scratch.d.arraycoerce.elemfunc); ! fmgr_info_set_expr((Node *) acoerce, ! scratch.d.arraycoerce.elemfunc); /* Set up workspace for array_map */ scratch.d.arraycoerce.amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState)); } else { ! /* Don't need workspace if there's no conversion func */ ! scratch.d.arraycoerce.elemfunc = NULL; scratch.d.arraycoerce.amstate = NULL; } --- 1235,1283 ---- ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("target type is not an array"))); ! /* ! * Construct a sub-expression for the per-element expression; ! * but don't ready it until after we check it for triviality. ! * We assume it hasn't any Var references, but does have a ! * CaseTestExpr representing the source array element values. ! */ ! elemstate = makeNode(ExprState); ! elemstate->expr = acoerce->elemexpr; ! elemstate->innermost_caseval = (Datum *) palloc(sizeof(Datum)); ! elemstate->innermost_casenull = (bool *) palloc(sizeof(bool)); ! ExecInitExprRec(acoerce->elemexpr, parent, elemstate, ! &elemstate->resvalue, &elemstate->resnull); ! if (elemstate->steps_len == 1 && ! elemstate->steps[0].opcode == EEOP_CASE_TESTVAL) ! { ! /* Trivial, so we need no per-element work at runtime */ ! elemstate = NULL; ! } ! else ! { ! /* Not trivial, so append a DONE step */ ! scratch.opcode = EEOP_DONE; ! ExprEvalPushStep(elemstate, &scratch); ! /* and ready the subexpression */ ! ExecReadyExpr(elemstate); ! } ! scratch.opcode = EEOP_ARRAYCOERCE; ! scratch.d.arraycoerce.elemexprstate = elemstate; ! scratch.d.arraycoerce.resultelemtype = resultelemtype; + if (elemstate) + { /* Set up workspace for array_map */ scratch.d.arraycoerce.amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState)); } else { ! /* Don't need workspace if there's no subexpression */ scratch.d.arraycoerce.amstate = NULL; } diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index bd8a15d..f9244d8 100644 *** a/src/backend/executor/execExprInterp.c --- b/src/backend/executor/execExprInterp.c *************** ExecInterpExpr(ExprState *state, ExprCon *** 1252,1258 **** EEO_CASE(EEOP_ARRAYCOERCE) { /* too complex for an inline implementation */ ! ExecEvalArrayCoerce(state, op); EEO_NEXT(); } --- 1252,1258 ---- EEO_CASE(EEOP_ARRAYCOERCE) { /* too complex for an inline implementation */ ! ExecEvalArrayCoerce(state, op, econtext); EEO_NEXT(); } *************** ExecEvalArrayExpr(ExprState *state, Expr *** 2328,2338 **** * Source array is in step's result variable. */ void ! ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op) { - ArrayCoerceExpr *acoerce = op->d.arraycoerce.coerceexpr; Datum arraydatum; - FunctionCallInfoData locfcinfo; /* NULL array -> NULL result */ if (*op->resnull) --- 2328,2336 ---- * Source array is in step's result variable. */ void ! ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op, ExprContext *econtext) { Datum arraydatum; /* NULL array -> NULL result */ if (*op->resnull) *************** ExecEvalArrayCoerce(ExprState *state, Ex *** 2344,2350 **** * If it's binary-compatible, modify the element type in the array header, * but otherwise leave the array as we received it. */ ! if (!OidIsValid(acoerce->elemfuncid)) { /* Detoast input array if necessary, and copy in any case */ ArrayType *array = DatumGetArrayTypePCopy(arraydatum); --- 2342,2348 ---- * If it's binary-compatible, modify the element type in the array header, * but otherwise leave the array as we received it. */ ! if (op->d.arraycoerce.elemexprstate == NULL) { /* Detoast input array if necessary, and copy in any case */ ArrayType *array = DatumGetArrayTypePCopy(arraydatum); *************** ExecEvalArrayCoerce(ExprState *state, Ex *** 2355,2377 **** } /* ! * Use array_map to apply the function to each array element. ! * ! * We pass on the desttypmod and isExplicit flags whether or not the ! * function wants them. ! * ! * Note: coercion functions are assumed to not use collation. */ ! InitFunctionCallInfoData(locfcinfo, op->d.arraycoerce.elemfunc, 3, ! InvalidOid, NULL, NULL); ! locfcinfo.arg[0] = arraydatum; ! locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod); ! locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit); ! locfcinfo.argnull[0] = false; ! locfcinfo.argnull[1] = false; ! locfcinfo.argnull[2] = false; ! ! *op->resvalue = array_map(&locfcinfo, op->d.arraycoerce.resultelemtype, op->d.arraycoerce.amstate); } --- 2353,2364 ---- } /* ! * Use array_map to apply the sub-expression to each array element. */ ! *op->resvalue = array_map(arraydatum, ! op->d.arraycoerce.elemexprstate, ! econtext, ! op->d.arraycoerce.resultelemtype, op->d.arraycoerce.amstate); } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index f1bed14..b274af2 100644 *** a/src/backend/nodes/copyfuncs.c --- b/src/backend/nodes/copyfuncs.c *************** _copyArrayCoerceExpr(const ArrayCoerceEx *** 1698,1708 **** ArrayCoerceExpr *newnode = makeNode(ArrayCoerceExpr); COPY_NODE_FIELD(arg); ! COPY_SCALAR_FIELD(elemfuncid); COPY_SCALAR_FIELD(resulttype); COPY_SCALAR_FIELD(resulttypmod); COPY_SCALAR_FIELD(resultcollid); - COPY_SCALAR_FIELD(isExplicit); COPY_SCALAR_FIELD(coerceformat); COPY_LOCATION_FIELD(location); --- 1698,1707 ---- ArrayCoerceExpr *newnode = makeNode(ArrayCoerceExpr); COPY_NODE_FIELD(arg); ! COPY_NODE_FIELD(elemexpr); COPY_SCALAR_FIELD(resulttype); COPY_SCALAR_FIELD(resulttypmod); COPY_SCALAR_FIELD(resultcollid); COPY_SCALAR_FIELD(coerceformat); COPY_LOCATION_FIELD(location); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 8b56b91..5c839f4 100644 *** a/src/backend/nodes/equalfuncs.c --- b/src/backend/nodes/equalfuncs.c *************** static bool *** 513,523 **** _equalArrayCoerceExpr(const ArrayCoerceExpr *a, const ArrayCoerceExpr *b) { COMPARE_NODE_FIELD(arg); ! COMPARE_SCALAR_FIELD(elemfuncid); COMPARE_SCALAR_FIELD(resulttype); COMPARE_SCALAR_FIELD(resulttypmod); COMPARE_SCALAR_FIELD(resultcollid); - COMPARE_SCALAR_FIELD(isExplicit); COMPARE_COERCIONFORM_FIELD(coerceformat); COMPARE_LOCATION_FIELD(location); --- 513,522 ---- _equalArrayCoerceExpr(const ArrayCoerceExpr *a, const ArrayCoerceExpr *b) { COMPARE_NODE_FIELD(arg); ! COMPARE_NODE_FIELD(elemexpr); COMPARE_SCALAR_FIELD(resulttype); COMPARE_SCALAR_FIELD(resulttypmod); COMPARE_SCALAR_FIELD(resultcollid); COMPARE_COERCIONFORM_FIELD(coerceformat); COMPARE_LOCATION_FIELD(location); diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index e3eb0c5..8e6f27e 100644 *** a/src/backend/nodes/nodeFuncs.c --- b/src/backend/nodes/nodeFuncs.c *************** check_functions_in_node(Node *node, chec *** 1717,1731 **** return true; } break; - case T_ArrayCoerceExpr: - { - ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; - - if (OidIsValid(expr->elemfuncid) && - checker(expr->elemfuncid, context)) - return true; - } - break; case T_RowCompareExpr: { RowCompareExpr *rcexpr = (RowCompareExpr *) node; --- 1717,1722 ---- *************** expression_tree_walker(Node *node, *** 2023,2029 **** case T_CoerceViaIO: return walker(((CoerceViaIO *) node)->arg, context); case T_ArrayCoerceExpr: ! return walker(((ArrayCoerceExpr *) node)->arg, context); case T_ConvertRowtypeExpr: return walker(((ConvertRowtypeExpr *) node)->arg, context); case T_CollateExpr: --- 2014,2028 ---- case T_CoerceViaIO: return walker(((CoerceViaIO *) node)->arg, context); case T_ArrayCoerceExpr: ! { ! ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! ! if (walker(acoerce->arg, context)) ! return true; ! if (walker(acoerce->elemexpr, context)) ! return true; ! } ! break; case T_ConvertRowtypeExpr: return walker(((ConvertRowtypeExpr *) node)->arg, context); case T_CollateExpr: *************** expression_tree_mutator(Node *node, *** 2705,2710 **** --- 2704,2710 ---- FLATCOPY(newnode, acoerce, ArrayCoerceExpr); MUTATE(newnode->arg, acoerce->arg, Expr *); + MUTATE(newnode->elemexpr, acoerce->elemexpr, Expr *); return (Node *) newnode; } break; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index b83d919..2532edc 100644 *** a/src/backend/nodes/outfuncs.c --- b/src/backend/nodes/outfuncs.c *************** _outArrayCoerceExpr(StringInfo str, cons *** 1394,1404 **** WRITE_NODE_TYPE("ARRAYCOERCEEXPR"); WRITE_NODE_FIELD(arg); ! WRITE_OID_FIELD(elemfuncid); WRITE_OID_FIELD(resulttype); WRITE_INT_FIELD(resulttypmod); WRITE_OID_FIELD(resultcollid); - WRITE_BOOL_FIELD(isExplicit); WRITE_ENUM_FIELD(coerceformat, CoercionForm); WRITE_LOCATION_FIELD(location); } --- 1394,1403 ---- WRITE_NODE_TYPE("ARRAYCOERCEEXPR"); WRITE_NODE_FIELD(arg); ! WRITE_NODE_FIELD(elemexpr); WRITE_OID_FIELD(resulttype); WRITE_INT_FIELD(resulttypmod); WRITE_OID_FIELD(resultcollid); WRITE_ENUM_FIELD(coerceformat, CoercionForm); WRITE_LOCATION_FIELD(location); } diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index fbf8330..07ba691 100644 *** a/src/backend/nodes/readfuncs.c --- b/src/backend/nodes/readfuncs.c *************** _readArrayCoerceExpr(void) *** 892,902 **** READ_LOCALS(ArrayCoerceExpr); READ_NODE_FIELD(arg); ! READ_OID_FIELD(elemfuncid); READ_OID_FIELD(resulttype); READ_INT_FIELD(resulttypmod); READ_OID_FIELD(resultcollid); - READ_BOOL_FIELD(isExplicit); READ_ENUM_FIELD(coerceformat, CoercionForm); READ_LOCATION_FIELD(location); --- 892,901 ---- READ_LOCALS(ArrayCoerceExpr); READ_NODE_FIELD(arg); ! READ_NODE_FIELD(elemexpr); READ_OID_FIELD(resulttype); READ_INT_FIELD(resulttypmod); READ_OID_FIELD(resultcollid); READ_ENUM_FIELD(coerceformat, CoercionForm); READ_LOCATION_FIELD(location); diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 051a854..8fd49d6 100644 *** a/src/backend/optimizer/path/costsize.c --- b/src/backend/optimizer/path/costsize.c *************** cost_qual_eval_walker(Node *node, cost_q *** 3632,3642 **** else if (IsA(node, ArrayCoerceExpr)) { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! Node *arraynode = (Node *) acoerce->arg; ! if (OidIsValid(acoerce->elemfuncid)) ! context->total.per_tuple += get_func_cost(acoerce->elemfuncid) * ! cpu_operator_cost * estimate_array_length(arraynode); } else if (IsA(node, RowCompareExpr)) { --- 3632,3645 ---- else if (IsA(node, ArrayCoerceExpr)) { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! QualCost perelemcost; ! cost_qual_eval_node(&perelemcost, (Node *) acoerce->elemexpr, ! context->root); ! context->total.startup += perelemcost.startup; ! if (perelemcost.per_tuple > 0) ! context->total.per_tuple += perelemcost.per_tuple * ! estimate_array_length((Node *) acoerce->arg); } else if (IsA(node, RowCompareExpr)) { diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index b0c9e94..dee4414 100644 *** a/src/backend/optimizer/plan/setrefs.c --- b/src/backend/optimizer/plan/setrefs.c *************** fix_expr_common(PlannerInfo *root, Node *** 1395,1406 **** record_plan_function_dependency(root, ((ScalarArrayOpExpr *) node)->opfuncid); } - else if (IsA(node, ArrayCoerceExpr)) - { - if (OidIsValid(((ArrayCoerceExpr *) node)->elemfuncid)) - record_plan_function_dependency(root, - ((ArrayCoerceExpr *) node)->elemfuncid); - } else if (IsA(node, Const)) { Const *con = (Const *) node; --- 1395,1400 ---- diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 93add27..7961362 100644 *** a/src/backend/optimizer/util/clauses.c --- b/src/backend/optimizer/util/clauses.c *************** contain_nonstrict_functions_walker(Node *** 1361,1366 **** --- 1361,1377 ---- return true; if (IsA(node, FieldStore)) return true; + if (IsA(node, ArrayCoerceExpr)) + { + /* + * ArrayCoerceExpr is strict at the array level, regardless of what + * the per-element expression is; so we should ignore elemexpr and + * recurse only into the arg. + */ + return expression_tree_walker((Node *) ((ArrayCoerceExpr *) node)->arg, + contain_nonstrict_functions_walker, + context); + } if (IsA(node, CaseExpr)) return true; if (IsA(node, ArrayExpr)) *************** contain_nonstrict_functions_walker(Node *** 1380,1393 **** if (IsA(node, BooleanTest)) return true; ! /* ! * Check other function-containing nodes; but ArrayCoerceExpr is strict at ! * the array level, regardless of elemfunc. ! */ ! if (!IsA(node, ArrayCoerceExpr) && ! check_functions_in_node(node, contain_nonstrict_functions_checker, context)) return true; return expression_tree_walker(node, contain_nonstrict_functions_walker, context); } --- 1391,1401 ---- if (IsA(node, BooleanTest)) return true; ! /* Check other function-containing nodes */ ! if (check_functions_in_node(node, contain_nonstrict_functions_checker, context)) return true; + return expression_tree_walker(node, contain_nonstrict_functions_walker, context); } *************** find_nonnullable_rels_walker(Node *node, *** 1757,1763 **** } else if (IsA(node, ArrayCoerceExpr)) { ! /* ArrayCoerceExpr is strict at the array level */ ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; result = find_nonnullable_rels_walker((Node *) expr->arg, top_level); --- 1765,1771 ---- } else if (IsA(node, ArrayCoerceExpr)) { ! /* ArrayCoerceExpr is strict at the array level; ignore elemexpr */ ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; result = find_nonnullable_rels_walker((Node *) expr->arg, top_level); *************** find_nonnullable_vars_walker(Node *node, *** 1965,1971 **** } else if (IsA(node, ArrayCoerceExpr)) { ! /* ArrayCoerceExpr is strict at the array level */ ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; result = find_nonnullable_vars_walker((Node *) expr->arg, top_level); --- 1973,1979 ---- } else if (IsA(node, ArrayCoerceExpr)) { ! /* ArrayCoerceExpr is strict at the array level; ignore elemexpr */ ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; result = find_nonnullable_vars_walker((Node *) expr->arg, top_level); *************** eval_const_expressions_mutator(Node *nod *** 3005,3036 **** { ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; Expr *arg; ArrayCoerceExpr *newexpr; /* ! * Reduce constants in the ArrayCoerceExpr's argument, then ! * build a new ArrayCoerceExpr. */ arg = (Expr *) eval_const_expressions_mutator((Node *) expr->arg, context); newexpr = makeNode(ArrayCoerceExpr); newexpr->arg = arg; ! newexpr->elemfuncid = expr->elemfuncid; newexpr->resulttype = expr->resulttype; newexpr->resulttypmod = expr->resulttypmod; newexpr->resultcollid = expr->resultcollid; - newexpr->isExplicit = expr->isExplicit; newexpr->coerceformat = expr->coerceformat; newexpr->location = expr->location; /* ! * If constant argument and it's a binary-coercible or ! * immutable conversion, we can simplify it to a constant. */ if (arg && IsA(arg, Const) && ! (!OidIsValid(newexpr->elemfuncid) || ! func_volatile(newexpr->elemfuncid) == PROVOLATILE_IMMUTABLE)) return (Node *) evaluate_expr((Expr *) newexpr, newexpr->resulttype, newexpr->resulttypmod, --- 3013,3050 ---- { ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; Expr *arg; + Expr *elemexpr; ArrayCoerceExpr *newexpr; /* ! * Reduce constants in the ArrayCoerceExpr's argument and ! * per-element expressions, then build a new ArrayCoerceExpr. */ arg = (Expr *) eval_const_expressions_mutator((Node *) expr->arg, context); + elemexpr = (Expr *) eval_const_expressions_mutator((Node *) expr->elemexpr, + context); newexpr = makeNode(ArrayCoerceExpr); newexpr->arg = arg; ! newexpr->elemexpr = elemexpr; newexpr->resulttype = expr->resulttype; newexpr->resulttypmod = expr->resulttypmod; newexpr->resultcollid = expr->resultcollid; newexpr->coerceformat = expr->coerceformat; newexpr->location = expr->location; /* ! * If constant argument and per-element expression is ! * immutable, we can simplify the whole thing to a constant. ! * Exception: although contain_mutable_functions considers ! * CoerceToDomain immutable for historical reasons, let's not ! * do so here; this ensures coercion to an array-over-domain ! * does not apply the domain's constraints until runtime. */ if (arg && IsA(arg, Const) && ! elemexpr && !IsA(elemexpr, CoerceToDomain) && ! !contain_mutable_functions((Node *) elemexpr)) return (Node *) evaluate_expr((Expr *) newexpr, newexpr->resulttype, newexpr->resulttypmod, diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index 5a241bd..0355c02 100644 *** a/src/backend/parser/parse_coerce.c --- b/src/backend/parser/parse_coerce.c *************** build_coercion_expression(Node *node, *** 876,894 **** { /* We need to build an ArrayCoerceExpr */ ArrayCoerceExpr *acoerce = makeNode(ArrayCoerceExpr); acoerce->arg = (Expr *) node; ! acoerce->elemfuncid = funcId; acoerce->resulttype = targetTypeId; /* ! * Label the output as having a particular typmod only if we are ! * really invoking a length-coercion function, ie one with more than ! * one argument. */ ! acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1; /* resultcollid will be set by parse_collate.c */ - acoerce->isExplicit = (ccontext == COERCION_EXPLICIT); acoerce->coerceformat = cformat; acoerce->location = location; --- 876,927 ---- { /* We need to build an ArrayCoerceExpr */ ArrayCoerceExpr *acoerce = makeNode(ArrayCoerceExpr); + CaseTestExpr *ctest = makeNode(CaseTestExpr); + Oid sourceBaseTypeId; + int32 sourceBaseTypeMod; + Oid targetElementType; + Node *elemexpr; + + /* + * Look through any domain over the source array type. Note we don't + * expect that the target type is a domain; it must be a plain array. + * (To get to a domain target type, we'll do coerce_to_domain later.) + */ + sourceBaseTypeMod = exprTypmod(node); + sourceBaseTypeId = getBaseTypeAndTypmod(exprType(node), + &sourceBaseTypeMod); + + /* Set up CaseTestExpr representing one element of source array */ + ctest->typeId = get_element_type(sourceBaseTypeId); + Assert(OidIsValid(ctest->typeId)); + ctest->typeMod = sourceBaseTypeMod; + ctest->collation = InvalidOid; /* Assume coercions don't care */ + + /* And coerce it to the target element type */ + targetElementType = get_element_type(targetTypeId); + Assert(OidIsValid(targetElementType)); + + elemexpr = coerce_to_target_type(NULL, + (Node *) ctest, + ctest->typeId, + targetElementType, + targetTypMod, + ccontext, + cformat, + location); + if (elemexpr == NULL) /* shouldn't happen */ + elog(ERROR, "failed to coerce array element type as expected"); acoerce->arg = (Expr *) node; ! acoerce->elemexpr = (Expr *) elemexpr; acoerce->resulttype = targetTypeId; /* ! * Label the output as having a particular element typmod only if we ! * ended up with a per-element expression that is labeled that way. */ ! acoerce->resulttypmod = exprTypmod(elemexpr); /* resultcollid will be set by parse_collate.c */ acoerce->coerceformat = cformat; acoerce->location = location; *************** IsBinaryCoercible(Oid srctype, Oid targe *** 2143,2150 **** * COERCION_PATH_RELABELTYPE: binary-compatible cast, no function needed * *funcid is set to InvalidOid * COERCION_PATH_ARRAYCOERCE: need an ArrayCoerceExpr node ! * *funcid is set to the element cast function, or InvalidOid ! * if the array elements are binary-compatible * COERCION_PATH_COERCEVIAIO: need a CoerceViaIO node * *funcid is set to InvalidOid * --- 2176,2182 ---- * COERCION_PATH_RELABELTYPE: binary-compatible cast, no function needed * *funcid is set to InvalidOid * COERCION_PATH_ARRAYCOERCE: need an ArrayCoerceExpr node ! * *funcid is set to InvalidOid * COERCION_PATH_COERCEVIAIO: need a CoerceViaIO node * *funcid is set to InvalidOid * *************** find_coercion_pathway(Oid targetTypeId, *** 2230,2240 **** { /* * If there's no pg_cast entry, perhaps we are dealing with a pair of ! * array types. If so, and if the element types have a suitable cast, ! * report that we can coerce with an ArrayCoerceExpr. ! * ! * Note that the source type can be a domain over array, but not the ! * target, because ArrayCoerceExpr won't check domain constraints. * * Hack: disallow coercions to oidvector and int2vector, which * otherwise tend to capture coercions that should go to "real" array --- 2262,2269 ---- { /* * If there's no pg_cast entry, perhaps we are dealing with a pair of ! * array types. If so, and if their element types have a conversion ! * pathway, report that we can coerce with an ArrayCoerceExpr. * * Hack: disallow coercions to oidvector and int2vector, which * otherwise tend to capture coercions that should go to "real" array *************** find_coercion_pathway(Oid targetTypeId, *** 2249,2255 **** Oid sourceElem; if ((targetElem = get_element_type(targetTypeId)) != InvalidOid && ! (sourceElem = get_base_element_type(sourceTypeId)) != InvalidOid) { CoercionPathType elempathtype; Oid elemfuncid; --- 2278,2284 ---- Oid sourceElem; if ((targetElem = get_element_type(targetTypeId)) != InvalidOid && ! (sourceElem = get_element_type(sourceTypeId)) != InvalidOid) { CoercionPathType elempathtype; Oid elemfuncid; *************** find_coercion_pathway(Oid targetTypeId, *** 2258,2271 **** sourceElem, ccontext, &elemfuncid); ! if (elempathtype != COERCION_PATH_NONE && ! elempathtype != COERCION_PATH_ARRAYCOERCE) { ! *funcid = elemfuncid; ! if (elempathtype == COERCION_PATH_COERCEVIAIO) ! result = COERCION_PATH_COERCEVIAIO; ! else ! result = COERCION_PATH_ARRAYCOERCE; } } } --- 2287,2295 ---- sourceElem, ccontext, &elemfuncid); ! if (elempathtype != COERCION_PATH_NONE) { ! result = COERCION_PATH_ARRAYCOERCE; } } } *************** find_coercion_pathway(Oid targetTypeId, *** 2306,2312 **** * If the given type is a varlena array type, we do not look for a coercion * function associated directly with the array type, but instead look for * one associated with the element type. An ArrayCoerceExpr node must be ! * used to apply such a function. * * We use the same result enum as find_coercion_pathway, but the only possible * result codes are: --- 2330,2338 ---- * If the given type is a varlena array type, we do not look for a coercion * function associated directly with the array type, but instead look for * one associated with the element type. An ArrayCoerceExpr node must be ! * used to apply such a function. (Note: currently, it's pointless to ! * return the funcid in this case, because it'll just get looked up again ! * in the recursive construction of the ArrayCoerceExpr's elemexpr.) * * We use the same result enum as find_coercion_pathway, but the only possible * result codes are: diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index 2a4de41..4caff0b 100644 *** a/src/backend/utils/adt/arrayfuncs.c --- b/src/backend/utils/adt/arrayfuncs.c *************** array_set(ArrayType *array, int nSubscri *** 3092,3112 **** /* * array_map() * ! * Map an array through an arbitrary function. Return a new array with ! * same dimensions and each source element transformed by fn(). Each ! * source element is passed as the first argument to fn(); additional ! * arguments to be passed to fn() can be specified by the caller. ! * The output array can have a different element type than the input. * * Parameters are: ! * * fcinfo: a function-call data structure pre-constructed by the caller ! * to be ready to call the desired function, with everything except the ! * first argument position filled in. In particular, flinfo identifies ! * the function fn(), and if nargs > 1 then argument positions after the ! * first must be preset to the additional values to be passed. The ! * first argument position initially holds the input array value. * * retType: OID of element type of output array. This must be the same as, ! * or binary-compatible with, the result type of fn(). * * amstate: workspace for array_map. Must be zeroed by caller before * first call, and not touched after that. * --- 3092,3109 ---- /* * array_map() * ! * Map an array through an arbitrary expression. Return a new array with ! * the same dimensions and each source element transformed by the given, ! * already-compiled expression. Each source element is placed in the ! * innermost_caseval/innermost_casenull fields of the ExprState. * * Parameters are: ! * * arrayd: Datum representing array argument. ! * * exprstate: ExprState representing the per-element transformation. ! * * econtext: context for expression evaluation. * * retType: OID of element type of output array. This must be the same as, ! * or binary-compatible with, the result type of the expression. It might ! * be different from the input array's element type. * * amstate: workspace for array_map. Must be zeroed by caller before * first call, and not touched after that. * *************** array_set(ArrayType *array, int nSubscri *** 3116,3126 **** * * NB: caller must assure that input array is not NULL. NULL elements in * the array are OK however. */ Datum ! array_map(FunctionCallInfo fcinfo, Oid retType, ArrayMapState *amstate) { ! AnyArrayType *v; ArrayType *result; Datum *values; bool *nulls; --- 3113,3126 ---- * * NB: caller must assure that input array is not NULL. NULL elements in * the array are OK however. + * NB: caller should be running in econtext's per-tuple memory context. */ Datum ! array_map(Datum arrayd, ! ExprState *exprstate, ExprContext *econtext, ! Oid retType, ArrayMapState *amstate) { ! AnyArrayType *v = DatumGetAnyArray(arrayd); ArrayType *result; Datum *values; bool *nulls; *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3141,3153 **** array_iter iter; ArrayMetaState *inp_extra; ArrayMetaState *ret_extra; ! ! /* Get input array */ ! if (fcinfo->nargs < 1) ! elog(ERROR, "invalid nargs: %d", fcinfo->nargs); ! if (PG_ARGISNULL(0)) ! elog(ERROR, "null input array"); ! v = PG_GETARG_ANY_ARRAY_P(0); inpType = AARR_ELEMTYPE(v); ndim = AARR_NDIM(v); --- 3141,3148 ---- array_iter iter; ArrayMetaState *inp_extra; ArrayMetaState *ret_extra; ! Datum *transform_source = exprstate->innermost_caseval; ! bool *transform_source_isnull = exprstate->innermost_casenull; inpType = AARR_ELEMTYPE(v); ndim = AARR_NDIM(v); *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3158,3164 **** if (nitems <= 0) { /* Return empty array */ ! PG_RETURN_ARRAYTYPE_P(construct_empty_array(retType)); } /* --- 3153,3159 ---- if (nitems <= 0) { /* Return empty array */ ! return PointerGetDatum(construct_empty_array(retType)); } /* *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3203,3241 **** for (i = 0; i < nitems; i++) { - bool callit = true; - /* Get source element, checking for NULL */ ! fcinfo->arg[0] = array_iter_next(&iter, &fcinfo->argnull[0], i, ! inp_typlen, inp_typbyval, inp_typalign); ! ! /* ! * Apply the given function to source elt and extra args. ! */ ! if (fcinfo->flinfo->fn_strict) ! { ! int j; ! ! for (j = 0; j < fcinfo->nargs; j++) ! { ! if (fcinfo->argnull[j]) ! { ! callit = false; ! break; ! } ! } ! } ! if (callit) ! { ! fcinfo->isnull = false; ! values[i] = FunctionCallInvoke(fcinfo); ! } ! else ! fcinfo->isnull = true; ! nulls[i] = fcinfo->isnull; ! if (fcinfo->isnull) hasnulls = true; else { --- 3198,3212 ---- for (i = 0; i < nitems; i++) { /* Get source element, checking for NULL */ ! *transform_source = ! array_iter_next(&iter, transform_source_isnull, i, ! inp_typlen, inp_typbyval, inp_typalign); ! /* Apply the given expression to source element */ ! values[i] = ExecEvalExpr(exprstate, econtext, &nulls[i]); ! if (nulls[i]) hasnulls = true; else { *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3254,3260 **** } } ! /* Allocate and initialize the result array */ if (hasnulls) { dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nitems); --- 3225,3231 ---- } } ! /* Allocate and fill the result array */ if (hasnulls) { dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nitems); *************** array_map(FunctionCallInfo fcinfo, Oid r *** 3273,3290 **** memcpy(ARR_DIMS(result), AARR_DIMS(v), ndim * sizeof(int)); memcpy(ARR_LBOUND(result), AARR_LBOUND(v), ndim * sizeof(int)); - /* - * Note: do not risk trying to pfree the results of the called function - */ CopyArrayEls(result, values, nulls, nitems, typlen, typbyval, typalign, false); pfree(values); pfree(nulls); ! PG_RETURN_ARRAYTYPE_P(result); } /* --- 3244,3261 ---- memcpy(ARR_DIMS(result), AARR_DIMS(v), ndim * sizeof(int)); memcpy(ARR_LBOUND(result), AARR_LBOUND(v), ndim * sizeof(int)); CopyArrayEls(result, values, nulls, nitems, typlen, typbyval, typalign, false); + /* + * Note: do not risk trying to pfree the results of the called expression + */ pfree(values); pfree(nulls); ! return PointerGetDatum(result); } /* diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 81b0bc3..7b3fdc9 100644 *** a/src/backend/utils/adt/selfuncs.c --- b/src/backend/utils/adt/selfuncs.c *************** strip_array_coercion(Node *node) *** 1816,1825 **** { for (;;) { ! if (node && IsA(node, ArrayCoerceExpr) && ! ((ArrayCoerceExpr *) node)->elemfuncid == InvalidOid) { ! node = (Node *) ((ArrayCoerceExpr *) node)->arg; } else if (node && IsA(node, RelabelType)) { --- 1816,1834 ---- { for (;;) { ! if (node && IsA(node, ArrayCoerceExpr)) { ! ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ! ! /* ! * If the per-element expression is just a RelabelType on top of ! * CaseTestExpr, then we know it's a binary-compatible relabeling. ! */ ! if (IsA(acoerce->elemexpr, RelabelType) && ! IsA(((RelabelType *) acoerce->elemexpr)->arg, CaseTestExpr)) ! node = (Node *) acoerce->arg; ! else ! break; } else if (node && IsA(node, RelabelType)) { diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index a7b0782..9197335 100644 *** a/src/backend/utils/fmgr/fmgr.c --- b/src/backend/utils/fmgr/fmgr.c *************** get_call_expr_argtype(Node *expr, int ar *** 1941,1948 **** args = ((DistinctExpr *) expr)->args; else if (IsA(expr, ScalarArrayOpExpr)) args = ((ScalarArrayOpExpr *) expr)->args; - else if (IsA(expr, ArrayCoerceExpr)) - args = list_make1(((ArrayCoerceExpr *) expr)->arg); else if (IsA(expr, NullIfExpr)) args = ((NullIfExpr *) expr)->args; else if (IsA(expr, WindowFunc)) --- 1941,1946 ---- *************** get_call_expr_argtype(Node *expr, int ar *** 1956,1971 **** argtype = exprType((Node *) list_nth(args, argnum)); /* ! * special hack for ScalarArrayOpExpr and ArrayCoerceExpr: what the ! * underlying function will actually get passed is the element type of the ! * array. */ if (IsA(expr, ScalarArrayOpExpr) && argnum == 1) argtype = get_base_element_type(argtype); - else if (IsA(expr, ArrayCoerceExpr) && - argnum == 0) - argtype = get_base_element_type(argtype); return argtype; } --- 1954,1965 ---- argtype = exprType((Node *) list_nth(args, argnum)); /* ! * special hack for ScalarArrayOpExpr: what the underlying function will ! * actually get passed is the element type of the array. */ if (IsA(expr, ScalarArrayOpExpr) && argnum == 1) argtype = get_base_element_type(argtype); return argtype; } *************** get_call_expr_arg_stable(Node *expr, int *** 2012,2019 **** args = ((DistinctExpr *) expr)->args; else if (IsA(expr, ScalarArrayOpExpr)) args = ((ScalarArrayOpExpr *) expr)->args; - else if (IsA(expr, ArrayCoerceExpr)) - args = list_make1(((ArrayCoerceExpr *) expr)->arg); else if (IsA(expr, NullIfExpr)) args = ((NullIfExpr *) expr)->args; else if (IsA(expr, WindowFunc)) --- 2006,2011 ---- diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h index 8ee0496..78d2247 100644 *** a/src/include/executor/execExpr.h --- b/src/include/executor/execExpr.h *************** typedef struct ExprEvalStep *** 385,394 **** /* for EEOP_ARRAYCOERCE */ struct { ! ArrayCoerceExpr *coerceexpr; Oid resultelemtype; /* element type of result array */ - FmgrInfo *elemfunc; /* lookup info for element coercion - * function */ struct ArrayMapState *amstate; /* workspace for array_map */ } arraycoerce; --- 385,392 ---- /* for EEOP_ARRAYCOERCE */ struct { ! ExprState *elemexprstate; /* null if no per-element work */ Oid resultelemtype; /* element type of result array */ struct ArrayMapState *amstate; /* workspace for array_map */ } arraycoerce; *************** extern void ExecEvalRowNull(ExprState *s *** 621,627 **** extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext); extern void ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op); ! extern void ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op); extern void ExecEvalRow(ExprState *state, ExprEvalStep *op); extern void ExecEvalMinMax(ExprState *state, ExprEvalStep *op); extern void ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, --- 619,626 ---- extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext); extern void ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op); ! extern void ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op, ! ExprContext *econtext); extern void ExecEvalRow(ExprState *state, ExprEvalStep *op); extern void ExecEvalMinMax(ExprState *state, ExprEvalStep *op); extern void ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 8c536a8..ccb5123 100644 *** a/src/include/nodes/primnodes.h --- b/src/include/nodes/primnodes.h *************** typedef struct CoerceViaIO *** 820,830 **** * ArrayCoerceExpr * * ArrayCoerceExpr represents a type coercion from one array type to another, ! * which is implemented by applying the indicated element-type coercion ! * function to each element of the source array. If elemfuncid is InvalidOid ! * then the element types are binary-compatible, but the coercion still ! * requires some effort (we have to fix the element type ID stored in the ! * array header). * ---------------- */ --- 820,831 ---- * ArrayCoerceExpr * * ArrayCoerceExpr represents a type coercion from one array type to another, ! * which is implemented by applying the per-element coercion expression ! * "elemexpr" to each element of the source array. Within elemexpr, the ! * source element is represented by a CaseTestExpr node. Note that even if ! * elemexpr is a no-op (that is, just CaseTestExpr + RelabelType), the ! * coercion still requires some effort: we have to fix the element type OID ! * stored in the array header. * ---------------- */ *************** typedef struct ArrayCoerceExpr *** 832,842 **** { Expr xpr; Expr *arg; /* input expression (yields an array) */ ! Oid elemfuncid; /* OID of element coercion function, or 0 */ Oid resulttype; /* output type of coercion (an array type) */ int32 resulttypmod; /* output typmod (also element typmod) */ Oid resultcollid; /* OID of collation, or InvalidOid if none */ - bool isExplicit; /* conversion semantics flag to pass to func */ CoercionForm coerceformat; /* how to display this node */ int location; /* token location, or -1 if unknown */ } ArrayCoerceExpr; --- 833,842 ---- { Expr xpr; Expr *arg; /* input expression (yields an array) */ ! Expr *elemexpr; /* expression representing per-element work */ Oid resulttype; /* output type of coercion (an array type) */ int32 resulttypmod; /* output typmod (also element typmod) */ Oid resultcollid; /* OID of collation, or InvalidOid if none */ CoercionForm coerceformat; /* how to display this node */ int location; /* token location, or -1 if unknown */ } ArrayCoerceExpr; diff --git a/src/include/utils/array.h b/src/include/utils/array.h index 61a67a2..32833f0 100644 *** a/src/include/utils/array.h --- b/src/include/utils/array.h *************** *** 64,69 **** --- 64,73 ---- #include "fmgr.h" #include "utils/expandeddatum.h" + /* avoid including execnodes.h here */ + struct ExprState; + struct ExprContext; + /* * Arrays are varlena objects, so must meet the varlena convention that *************** extern ArrayType *array_set(ArrayType *a *** 360,367 **** Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign); ! extern Datum array_map(FunctionCallInfo fcinfo, Oid retType, ! ArrayMapState *amstate); extern void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, --- 364,372 ---- Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign); ! extern Datum array_map(Datum arrayd, ! struct ExprState *exprstate, struct ExprContext *econtext, ! Oid retType, ArrayMapState *amstate); extern void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, [text/x-diff] 03-support-arrays-of-domains-3.patch (9.5K, ../../[email protected]/4-03-support-arrays-of-domains-3.patch) download | inline diff: diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 7ed16ae..12d2cd6 100644 *** a/src/backend/commands/typecmds.c --- b/src/backend/commands/typecmds.c *************** ObjectAddress *** 729,734 **** --- 729,735 ---- DefineDomain(CreateDomainStmt *stmt) { char *domainName; + char *domainArrayName; Oid domainNamespace; AclResult aclresult; int16 internalLength; *************** DefineDomain(CreateDomainStmt *stmt) *** 757,762 **** --- 758,764 ---- Oid basetypeoid; Oid old_type_oid; Oid domaincoll; + Oid domainArrayOid; Form_pg_type baseType; int32 basetypeMod; Oid baseColl; *************** DefineDomain(CreateDomainStmt *stmt) *** 1027,1032 **** --- 1029,1037 ---- } } + /* Allocate OID for array type */ + domainArrayOid = AssignTypeArrayOid(); + /* * Have TypeCreate do all the real work. */ *************** DefineDomain(CreateDomainStmt *stmt) *** 1051,1057 **** analyzeProcedure, /* analyze procedure */ InvalidOid, /* no array element type */ false, /* this isn't an array */ ! InvalidOid, /* no arrays for domains (yet) */ basetypeoid, /* base type ID */ defaultValue, /* default type value (text) */ defaultValueBin, /* default type value (binary) */ --- 1056,1062 ---- analyzeProcedure, /* analyze procedure */ InvalidOid, /* no array element type */ false, /* this isn't an array */ ! domainArrayOid, /* array type we are about to create */ basetypeoid, /* base type ID */ defaultValue, /* default type value (text) */ defaultValueBin, /* default type value (binary) */ *************** DefineDomain(CreateDomainStmt *stmt) *** 1064,1069 **** --- 1069,1116 ---- domaincoll); /* type's collation */ /* + * Create the array type that goes with it. + */ + domainArrayName = makeArrayTypeName(domainName, domainNamespace); + + /* alignment must be 'i' or 'd' for arrays */ + alignment = (alignment == 'd') ? 'd' : 'i'; + + TypeCreate(domainArrayOid, /* force assignment of this type OID */ + domainArrayName, /* type name */ + domainNamespace, /* namespace */ + InvalidOid, /* relation oid (n/a here) */ + 0, /* relation kind (ditto) */ + GetUserId(), /* owner's ID */ + -1, /* internal size (always varlena) */ + TYPTYPE_BASE, /* type-type (base type) */ + TYPCATEGORY_ARRAY, /* type-category (array) */ + false, /* array types are never preferred */ + delimiter, /* array element delimiter */ + F_ARRAY_IN, /* input procedure */ + F_ARRAY_OUT, /* output procedure */ + F_ARRAY_RECV, /* receive procedure */ + F_ARRAY_SEND, /* send procedure */ + InvalidOid, /* typmodin procedure - none */ + InvalidOid, /* typmodout procedure - none */ + F_ARRAY_TYPANALYZE, /* analyze procedure */ + address.objectId, /* element type ID */ + true, /* yes this is an array type */ + InvalidOid, /* no further array type */ + InvalidOid, /* base type ID */ + NULL, /* never a default type value */ + NULL, /* binary default isn't sent either */ + false, /* never passed by value */ + alignment, /* see above */ + 'x', /* ARRAY is always toastable */ + -1, /* typMod (Domains only) */ + 0, /* Array dimensions of typbasetype */ + false, /* Type NOT NULL */ + domaincoll); /* type's collation */ + + pfree(domainArrayName); + + /* * Process constraints which refer to the domain ID returned by TypeCreate */ foreach(listptr, schema) *************** DefineEnum(CreateEnumStmt *stmt) *** 1139,1144 **** --- 1186,1192 ---- errmsg("type \"%s\" already exists", enumName))); } + /* Allocate OID for array type */ enumArrayOid = AssignTypeArrayOid(); /* Create the pg_type entry */ diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out index 3acc696..1e62c57 100644 *** a/src/test/regress/expected/domain.out --- b/src/test/regress/expected/domain.out *************** Rules: *** 310,315 **** --- 310,410 ---- drop table dcomptable; drop type comptype cascade; NOTICE: drop cascades to type dcomptypea + -- Test arrays over domains + create domain posint as int check (value > 0); + create table pitable (f1 posint[]); + insert into pitable values(array[42]); + insert into pitable values(array[-1]); -- fail + ERROR: value for domain posint violates check constraint "posint_check" + insert into pitable values('{0}'); -- fail + ERROR: value for domain posint violates check constraint "posint_check" + LINE 1: insert into pitable values('{0}'); + ^ + update pitable set f1[1] = f1[1] + 1; + update pitable set f1[1] = 0; -- fail + ERROR: value for domain posint violates check constraint "posint_check" + select * from pitable; + f1 + ------ + {43} + (1 row) + + drop table pitable; + create domain vc4 as varchar(4); + create table vc4table (f1 vc4[]); + insert into vc4table values(array['too long']); -- fail + ERROR: value too long for type character varying(4) + insert into vc4table values(array['too long']::vc4[]); -- cast truncates + select * from vc4table; + f1 + ---------- + {"too "} + (1 row) + + drop table vc4table; + drop type vc4; + -- You can sort of fake arrays-of-arrays by putting a domain in between + create domain dposinta as posint[]; + create table dposintatable (f1 dposinta[]); + insert into dposintatable values(array[array[42]]); -- fail + ERROR: column "f1" is of type dposinta[] but expression is of type integer[] + LINE 1: insert into dposintatable values(array[array[42]]); + ^ + HINT: You will need to rewrite or cast the expression. + insert into dposintatable values(array[array[42]::posint[]]); -- still fail + ERROR: column "f1" is of type dposinta[] but expression is of type posint[] + LINE 1: insert into dposintatable values(array[array[42]::posint[]])... + ^ + HINT: You will need to rewrite or cast the expression. + insert into dposintatable values(array[array[42]::dposinta]); -- but this works + select f1, f1[1], (f1[1])[1] from dposintatable; + f1 | f1 | f1 + ----------+------+---- + {"{42}"} | {42} | 42 + (1 row) + + select pg_typeof(f1) from dposintatable; + pg_typeof + ------------ + dposinta[] + (1 row) + + select pg_typeof(f1[1]) from dposintatable; + pg_typeof + ----------- + dposinta + (1 row) + + select pg_typeof(f1[1][1]) from dposintatable; + pg_typeof + ----------- + dposinta + (1 row) + + select pg_typeof((f1[1])[1]) from dposintatable; + pg_typeof + ----------- + posint + (1 row) + + update dposintatable set f1[2] = array[99]; + select f1, f1[1], (f1[2])[1] from dposintatable; + f1 | f1 | f1 + -----------------+------+---- + {"{42}","{99}"} | {42} | 99 + (1 row) + + -- it'd be nice if you could do something like this, but for now you can't: + update dposintatable set f1[2][1] = array[97]; + ERROR: wrong number of array subscripts + -- maybe someday we can make this syntax work: + update dposintatable set (f1[2])[1] = array[98]; + ERROR: syntax error at or near "[" + LINE 1: update dposintatable set (f1[2])[1] = array[98]; + ^ + drop table dposintatable; + drop domain posint cascade; + NOTICE: drop cascades to type dposinta -- Test not-null restrictions create domain dnotnull varchar(15) NOT NULL; create domain dnull varchar(15); diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql index 0fd383e..8fb3e20 100644 *** a/src/test/regress/sql/domain.sql --- b/src/test/regress/sql/domain.sql *************** drop table dcomptable; *** 166,171 **** --- 166,214 ---- drop type comptype cascade; + -- Test arrays over domains + + create domain posint as int check (value > 0); + + create table pitable (f1 posint[]); + insert into pitable values(array[42]); + insert into pitable values(array[-1]); -- fail + insert into pitable values('{0}'); -- fail + update pitable set f1[1] = f1[1] + 1; + update pitable set f1[1] = 0; -- fail + select * from pitable; + drop table pitable; + + create domain vc4 as varchar(4); + create table vc4table (f1 vc4[]); + insert into vc4table values(array['too long']); -- fail + insert into vc4table values(array['too long']::vc4[]); -- cast truncates + select * from vc4table; + drop table vc4table; + drop type vc4; + + -- You can sort of fake arrays-of-arrays by putting a domain in between + create domain dposinta as posint[]; + create table dposintatable (f1 dposinta[]); + insert into dposintatable values(array[array[42]]); -- fail + insert into dposintatable values(array[array[42]::posint[]]); -- still fail + insert into dposintatable values(array[array[42]::dposinta]); -- but this works + select f1, f1[1], (f1[1])[1] from dposintatable; + select pg_typeof(f1) from dposintatable; + select pg_typeof(f1[1]) from dposintatable; + select pg_typeof(f1[1][1]) from dposintatable; + select pg_typeof((f1[1])[1]) from dposintatable; + update dposintatable set f1[2] = array[99]; + select f1, f1[1], (f1[2])[1] from dposintatable; + -- it'd be nice if you could do something like this, but for now you can't: + update dposintatable set f1[2][1] = array[97]; + -- maybe someday we can make this syntax work: + update dposintatable set (f1[2])[1] = array[98]; + + drop table dposintatable; + drop domain posint cascade; + + -- Test not-null restrictions create domain dnotnull varchar(15) NOT NULL; ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: Arrays of domains @ 2017-09-28 01:11 Andrew Dunstan <[email protected]> parent: Tom Lane <[email protected]> 1 sibling, 1 reply; 38+ messages in thread From: Andrew Dunstan @ 2017-09-28 01:11 UTC (permalink / raw) To: Tom Lane <[email protected]>; pgsql-hackers On 08/11/2017 01:17 PM, Tom Lane wrote: > I wrote: >> Probably a better answer is to start supporting arrays over domain >> types. That was left unimplemented in the original domains patch, >> but AFAICS not for any better reason than lack of round tuits. > Attached is a patch series that allows us to create arrays of domain > types. I haven't tested this in great detail, so there might be some > additional corners of the system that need work, but it passes basic > sanity checks. I believe it's independent of the other patch I have > in the commitfest for domains over composites, but I haven't tested > for interactions there either. > > 01-rationalize-coercion-APIs.patch cleans up the APIs of > coerce_to_domain() and some internal functions in parse_coerce.c so that > we consistently pass around a CoercionContext along with CoercionForm. > Previously, we sometimes passed an "isExplicit" boolean flag instead, > which is strictly less information; and coerce_to_domain() didn't even get > that, but instead had to reverse-engineer isExplicit from CoercionForm. > That's contrary to the documentation in primnodes.h that says that > CoercionForm only affects display and not semantics. I don't think this > change fixes any live bugs, but it makes things more consistent. The > main reason for doing it though is that now build_coercion_expression() > receives ccontext, which it needs in order to be able to recursively > invoke coerce_to_target_type(), as required by the next patch. > > 02-reimplement-ArrayCoerceExpr.patch is the core of the patch. It changes > ArrayCoerceExpr so that the node does not directly know any details of > what has to be done to the individual array elements while performing the > array coercion. Instead, the per-element processing is represented by > a sub-expression whose input is a source array element and whose output > is a target array element. This simplifies life in parse_coerce.c, > because it can build that sub-expression by a recursive invocation of > coerce_to_target_type(), and it allows the executor to handle the > per-element processing as a compiled expression instead of hard-wired > code. This is probably about a wash or a small loss performance-wise > for the simplest case where we just need to invoke one coercion function > for each element. However, there are many cases where the existing code > ends up generating two nested ArrayCoerceExprs, one to do the type > conversion and one to apply a typmod (length) coercion function. In the > new code there will be just one ArrayCoerceExpr, saving one deconstruction > and reconstruction of the array. If I hadn't done it like this, adding > domains into the mix could have produced as many as three > ArrayCoerceExprs, where the top one would have only checked domain > constraints; that did not sound nice performance-wise, and it would have > required a lot of code duplication as well. > > Finally, 03-support-arrays-of-domains.patch simply turns on the spigot > by creating an array type in DefineDomain(), and adds some test cases. > Given the new method of handling ArrayCoerceExpr, everything Just Works. > > I'll add this to the next commitfest. > > > I've reviewed and tested the updated versions of these patches. The patches apply but there's an apparent typo in arrayfuncs.c - DatumGetAnyArray instead of DatumGetAnyArrayP Some of the line breaking in argument lists for some of the code affected by these patches is a bit bizarre. It hasn't been made worse by these patches but it hasn't been made better either. That's especially true of patch 1. Patch 1 is fairly straightforward, as is patch 3. Patch 2 is fairly complex, but it still does the one thing stated above - there's just a lot of housekeeping that goes along with that. I couldn't see any obvious problems with the implementation. I wonder if we need to do any benchmarking to assure ourselves that the changes to ArrayCoerceExpr don't have a significant performance impact? Apart from those concerns I think this is ready to be committed. cheers andrew -- Andrew Dunstan https://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: Arrays of domains @ 2017-09-28 17:11 Tom Lane <[email protected]> parent: Andrew Dunstan <[email protected]> 0 siblings, 1 reply; 38+ messages in thread From: Tom Lane @ 2017-09-28 17:11 UTC (permalink / raw) To: Andrew Dunstan <[email protected]>; +Cc: pgsql-hackers Andrew Dunstan <[email protected]> writes: > On 08/11/2017 01:17 PM, Tom Lane wrote: >> Attached is a patch series that allows us to create arrays of domain >> types. > I've reviewed and tested the updated versions of these patches. The > patches apply but there's an apparent typo in arrayfuncs.c - > DatumGetAnyArray instead of DatumGetAnyArrayP Thanks for reviewing! The DatumGetAnyArrayP thing is another artifact of 4bd199465 --- sorry for missing that. > Some of the line breaking in argument lists for some of the code > affected by these patches is a bit bizarre. It hasn't been made worse by > these patches but it hasn't been made better either. That's especially > true of patch 1. Yeah, perhaps. A lot of these argument lists are long enough that I'm not especially thrilled with the idea of making them one-arg-per-line; that seems like it would consume a lot of vertical space and make it harder to see context in a finite-size window. I think there's been some attempt at grouping the arguments into related groups on single lines, though I concede it's probably not very obvious nor 100% consistent. > I wonder if we need to do any benchmarking to assure ourselves that the > changes to ArrayCoerceExpr don't have a significant performance impact? That would likely be a good idea, though I'm not very sure what or how to benchmark. regards, tom lane -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: Arrays of domains @ 2017-09-28 18:45 Andrew Dunstan <[email protected]> parent: Tom Lane <[email protected]> 0 siblings, 1 reply; 38+ messages in thread From: Andrew Dunstan @ 2017-09-28 18:45 UTC (permalink / raw) To: Tom Lane <[email protected]>; +Cc: pgsql-hackers On 09/28/2017 01:11 PM, Tom Lane wrote: > >> I wonder if we need to do any benchmarking to assure ourselves that the >> changes to ArrayCoerceExpr don't have a significant performance impact? > That would likely be a good idea, though I'm not very sure what or > how to benchmark. > > Some case where we only expect the current code to produce a single ArrayCoerceExpr, I guess. say doing text[] -> int[] ? cheers andrew -- Andrew Dunstan https://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: Arrays of domains @ 2017-09-28 21:44 Tom Lane <[email protected]> parent: Andrew Dunstan <[email protected]> 0 siblings, 1 reply; 38+ messages in thread From: Tom Lane @ 2017-09-28 21:44 UTC (permalink / raw) To: Andrew Dunstan <[email protected]>; +Cc: pgsql-hackers; Andres Freund <[email protected]> Andrew Dunstan <[email protected]> writes: > On 09/28/2017 01:11 PM, Tom Lane wrote: >>> I wonder if we need to do any benchmarking to assure ourselves that the >>> changes to ArrayCoerceExpr don't have a significant performance impact? >> That would likely be a good idea, though I'm not very sure what or >> how to benchmark. > Some case where we only expect the current code to produce a single > ArrayCoerceExpr, I guess. say doing text[] -> int[] ? I spent some time looking into this. I settled on int4[] -> int8[] as the appropriate case to test, because int48() is about as cheap a cast function as we have. Q1 is the base case without a cast: select count(x) from (select array[i,i,i,i,i,i,i,i,i,i] as x from generate_series(1,10000000) i) ss; Q2 is same with a cast added: select count(x::int8[]) from (select array[i,i,i,i,i,i,i,i,i,i] as x from generate_series(1,10000000) i) ss; Q3 and Q4 are the same thing, but testing 100-element instead of 10-element arrays: select count(x) from (select array[ i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i ] as x from generate_series(1,10000000) i) ss; select count(x::int8[]) from (select array[ i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i, i,i,i,i,i,i,i,i,i,i ] as x from generate_series(1,10000000) i) ss; I get these query timings in a non-cassert build: HEAD Patch Q1 5453.235 ms 5440.876 ms Q2 9340.670 ms 10191.194 ms Q3 19078.457 ms 18967.279 ms Q4 48196.338 ms 58547.531 ms (Timings are reproducible to a few percent.) So that's a bit disappointing; the per-element overhead is clearly noticeably more than before. However, poking into it with "perf" gives some grounds for optimism; Q4's hotspots with the patch are Children Self Samples Command Shared Object Symbol + 33.44% 33.35% 81314 postmaster postgres [.] ExecInterpExpr + 21.88% 21.83% 53223 postmaster postgres [.] array_map + 15.19% 15.15% 36944 postmaster postgres [.] CopyArrayEls + 14.63% 14.60% 35585 postmaster postgres [.] ArrayCastAndSet + 6.07% 6.06% 14765 postmaster postgres [.] construct_md_array + 1.80% 1.79% 4370 postmaster postgres [.] palloc0 + 0.77% 0.77% 1883 postmaster postgres [.] AllocSetAlloc + 0.75% 0.74% 1815 postmaster postgres [.] int48 + 0.52% 0.52% 1276 postmaster postgres [.] advance_aggregates Surely we could get the amount of time spent in ExecInterpExpr down. One idea is to make a dedicated evalfunc for the case where the expression is just EEOP_CASE_TESTVAL + EEOP_FUNCEXPR[_STRICT], similar to the existing fast-path routines (ExecJust*). I've not actually tried to do that, but a reasonable guess is that it'd about halve that overhead, putting this case back on a par with the HEAD code. Also, I'd imagine that Andres' planned work on JIT-compiled expressions would put this back on par with HEAD, if not better, for installations using that. Also I believe that Andres has plans to revamp the CaseTestExpr mechanism, which might shave a few cycles as well. Right now there's an extra copy of each array datum + isnull value, because array_map sticks those into one pair of variables and then the EEOP_CASE_TESTVAL opcode just moves them somewhere else. It's reasonable to hope that we could redesign that so that array_map sticks the values straight into where they're needed, and then we need only the FUNCEXPR opcode, which'd be a great candidate for an ExecJust* fast-path. Assuming that that's going to happen for v11, I'm inclined to leave the optimization problem until the dust settles around CaseTestExpr. Does anyone feel that this can't be committed before that's addressed? regards, tom lane -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: Arrays of domains @ 2017-09-29 13:22 Andrew Dunstan <[email protected]> parent: Tom Lane <[email protected]> 0 siblings, 1 reply; 38+ messages in thread From: Andrew Dunstan @ 2017-09-29 13:22 UTC (permalink / raw) To: Tom Lane <[email protected]>; +Cc: pgsql-hackers; Andres Freund <[email protected]> On 09/28/2017 05:44 PM, Tom Lane wrote: > > I get these query timings in a non-cassert build: > > HEAD Patch > > Q1 5453.235 ms 5440.876 ms > Q2 9340.670 ms 10191.194 ms > Q3 19078.457 ms 18967.279 ms > Q4 48196.338 ms 58547.531 ms > > [ analysis elided] > > Assuming that that's going to happen for v11, I'm inclined to leave the > optimization problem until the dust settles around CaseTestExpr. > Does anyone feel that this can't be committed before that's addressed? > > I'm Ok with it as long as we don't forget to revisit this. cheers andrew -- Andrew Dunstan https://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: Arrays of domains @ 2017-09-29 17:10 Tom Lane <[email protected]> parent: Andrew Dunstan <[email protected]> 0 siblings, 1 reply; 38+ messages in thread From: Tom Lane @ 2017-09-29 17:10 UTC (permalink / raw) To: Andrew Dunstan <[email protected]>; +Cc: pgsql-hackers; Andres Freund <[email protected]> Andrew Dunstan <[email protected]> writes: > On 09/28/2017 05:44 PM, Tom Lane wrote: >> Assuming that that's going to happen for v11, I'm inclined to leave the >> optimization problem until the dust settles around CaseTestExpr. >> Does anyone feel that this can't be committed before that's addressed? > I'm Ok with it as long as we don't forget to revisit this. I decided to go ahead and build a quick optimization for this case, as per the attached patch that applies on top of what we previously discussed. It brings us back to almost par with HEAD: HEAD Patch + 04.patch Q1 5453.235 ms 5440.876 ms 5407.965 ms Q2 9340.670 ms 10191.194 ms 9407.093 ms Q3 19078.457 ms 18967.279 ms 19050.392 ms Q4 48196.338 ms 58547.531 ms 48696.809 ms Unless Andres feels this is too ugly to live, I'm inclined to commit the patch with this addition. If we don't get around to revisiting CaseTestExpr, I think this is OK, and if we do, this will make sure that we consider this case in the revisit. It's probably also worth pointing out that this test case is intentionally chosen to be about the worst possible case for the patch. A less-trivial coercion function would make the overhead proportionally less meaningful. There's also the point that the old code sometimes applies two layers of array coercion rather than one. As an example, coercing int4[] to varchar(10)[] will do that. If I replace "x::int8[]" with "x::varchar(10)[]" in Q2 and Q4 in this test, I get HEAD Patch (+04) Q2 46929.728 ms 20646.003 ms Q4 386200.286 ms 155917.572 ms regards, tom lane -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers Attachments: [text/x-diff] 04-buy-back-some-performance.patch (3.9K, ../../[email protected]/2-04-buy-back-some-performance.patch) download | inline diff: diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index e0a8998..c5e97ef 100644 *** a/src/backend/executor/execExprInterp.c --- b/src/backend/executor/execExprInterp.c *************** *** 34,43 **** * * For very simple instructions the overhead of the full interpreter * "startup", as minimal as it is, is noticeable. Therefore ! * ExecReadyInterpretedExpr will choose to implement simple scalar Var ! * and Const expressions using special fast-path routines (ExecJust*). ! * Benchmarking shows anything more complex than those may as well use the ! * "full interpreter". * * Complex or uncommon instructions are not implemented in-line in * ExecInterpExpr(), rather we call out to a helper function appearing later --- 34,41 ---- * * For very simple instructions the overhead of the full interpreter * "startup", as minimal as it is, is noticeable. Therefore ! * ExecReadyInterpretedExpr will choose to implement certain simple ! * opcode patterns using special fast-path routines (ExecJust*). * * Complex or uncommon instructions are not implemented in-line in * ExecInterpExpr(), rather we call out to a helper function appearing later *************** static Datum ExecJustConst(ExprState *st *** 149,154 **** --- 147,153 ---- static Datum ExecJustAssignInnerVar(ExprState *state, ExprContext *econtext, bool *isnull); static Datum ExecJustAssignOuterVar(ExprState *state, ExprContext *econtext, bool *isnull); static Datum ExecJustAssignScanVar(ExprState *state, ExprContext *econtext, bool *isnull); + static Datum ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull); /* *************** ExecReadyInterpretedExpr(ExprState *stat *** 184,193 **** /* * Select fast-path evalfuncs for very simple expressions. "Starting up" ! * the full interpreter is a measurable overhead for these. Plain Vars ! * and Const seem to be the only ones where the intrinsic cost is small ! * enough that the overhead of ExecInterpExpr matters. For more complex ! * expressions it's cheaper to use ExecInterpExpr always. */ if (state->steps_len == 3) { --- 183,190 ---- /* * Select fast-path evalfuncs for very simple expressions. "Starting up" ! * the full interpreter is a measurable overhead for these, and these ! * patterns occur often enough to be worth optimizing. */ if (state->steps_len == 3) { *************** ExecReadyInterpretedExpr(ExprState *stat *** 230,235 **** --- 227,239 ---- state->evalfunc = ExecJustAssignScanVar; return; } + else if (step0 == EEOP_CASE_TESTVAL && + step1 == EEOP_FUNCEXPR_STRICT && + state->steps[0].d.casetest.value) + { + state->evalfunc = ExecJustApplyFuncToCase; + return; + } } else if (state->steps_len == 2 && state->steps[0].opcode == EEOP_CONST) *************** ExecJustAssignScanVar(ExprState *state, *** 1811,1816 **** --- 1815,1857 ---- return 0; } + /* Evaluate CASE_TESTVAL and apply a strict function to it */ + static Datum + ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull) + { + ExprEvalStep *op = &state->steps[0]; + FunctionCallInfo fcinfo; + bool *argnull; + int argno; + Datum d; + + /* + * XXX with some redesign of the CaseTestExpr mechanism, maybe we could + * get rid of this data shuffling? + */ + *op->resvalue = *op->d.casetest.value; + *op->resnull = *op->d.casetest.isnull; + + op++; + + fcinfo = op->d.func.fcinfo_data; + argnull = fcinfo->argnull; + + /* strict function, so check for NULL args */ + for (argno = 0; argno < op->d.func.nargs; argno++) + { + if (argnull[argno]) + { + *isnull = true; + return (Datum) 0; + } + } + fcinfo->isnull = false; + d = op->d.func.fn_addr(fcinfo); + *isnull = fcinfo->isnull; + return d; + } + /* * Do one-time initialization of interpretation machinery. ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: Arrays of domains @ 2017-09-29 20:17 Andrew Dunstan <[email protected]> parent: Tom Lane <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Andrew Dunstan @ 2017-09-29 20:17 UTC (permalink / raw) To: Tom Lane <[email protected]>; +Cc: pgsql-hackers; Andres Freund <[email protected]> On 09/29/2017 01:10 PM, Tom Lane wrote: > Andrew Dunstan <[email protected]> writes: >> On 09/28/2017 05:44 PM, Tom Lane wrote: >>> Assuming that that's going to happen for v11, I'm inclined to leave the >>> optimization problem until the dust settles around CaseTestExpr. >>> Does anyone feel that this can't be committed before that's addressed? >> I'm Ok with it as long as we don't forget to revisit this. > I decided to go ahead and build a quick optimization for this case, > as per the attached patch that applies on top of what we previously > discussed. It brings us back to almost par with HEAD: > > HEAD Patch + 04.patch > > Q1 5453.235 ms 5440.876 ms 5407.965 ms > Q2 9340.670 ms 10191.194 ms 9407.093 ms > Q3 19078.457 ms 18967.279 ms 19050.392 ms > Q4 48196.338 ms 58547.531 ms 48696.809 ms Nice. > > Unless Andres feels this is too ugly to live, I'm inclined to commit > the patch with this addition. If we don't get around to revisiting > CaseTestExpr, I think this is OK, and if we do, this will make sure > that we consider this case in the revisit. > > It's probably also worth pointing out that this test case is intentionally > chosen to be about the worst possible case for the patch. A less-trivial > coercion function would make the overhead proportionally less meaningful. > There's also the point that the old code sometimes applies two layers of > array coercion rather than one. As an example, coercing int4[] to > varchar(10)[] will do that. If I replace "x::int8[]" with > "x::varchar(10)[]" in Q2 and Q4 in this test, I get > > HEAD Patch (+04) > > Q2 46929.728 ms 20646.003 ms > Q4 386200.286 ms 155917.572 ms > > Yeah, testing the worst case was the idea. This improvement in the non-worst case is pretty good. +1 for going ahead. cheers andrew -- Andrew Dunstan https://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX @ 2021-03-11 15:18 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Justin Pryzby @ 2021-03-11 15:18 UTC (permalink / raw) --- configure | 249 +++++++----------- configure.ac | 13 +- src/backend/access/common/toast_compression.c | 10 +- src/include/pg_config.h.in | 6 +- src/tools/msvc/Solution.pm | 2 +- 5 files changed, 118 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 87ed16060e..440d1e8ce5 100755 --- a/configure +++ b/configure @@ -654,8 +654,6 @@ UUID_LIBS LDAP_LIBS_BE LDAP_LIBS_FE with_ssl -LZ4_LIBS -LZ4_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC @@ -701,6 +699,8 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX +LZ4_LIBS +LZ4_CFLAGS with_lz4 with_zlib with_system_tzdata @@ -895,12 +895,12 @@ ICU_LIBS XML2_CONFIG XML2_CFLAGS XML2_LIBS +LZ4_CFLAGS +LZ4_LIBS LDFLAGS_EX LDFLAGS_SL PERL PYTHON -LZ4_CFLAGS -LZ4_LIBS MSGFMT TCLSH' @@ -1603,12 +1603,12 @@ Some influential environment variables: XML2_CONFIG path to xml2-config utility XML2_CFLAGS C compiler flags for XML2, overriding pkg-config XML2_LIBS linker flags for XML2, overriding pkg-config + LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config + LZ4_LIBS linker flags for LZ4, overriding pkg-config LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only PERL Perl program PYTHON Python program - LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config - LZ4_LIBS linker flags for LZ4, overriding pkg-config MSGFMT msgfmt program for NLS TCLSH Tcl interpreter program (tclsh) @@ -8607,6 +8607,102 @@ fi $as_echo "$with_lz4" >&6; } +if test "$with_lz4" = yes; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 +$as_echo_n "checking for liblz4... " >&6; } + +if test -n "$LZ4_CFLAGS"; then + pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LZ4_LIBS"; then + pkg_cv_LZ4_LIBS="$LZ4_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` + else + LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LZ4_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (liblz4) were not met: + +$LZ4_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LZ4_CFLAGS +and LZ4_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/;. +See \`config.log' for more details" "$LINENO" 5; } +else + LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS + LZ4_LIBS=$pkg_cv_LZ4_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -12154,147 +12250,6 @@ fi fi -if test "$with_lz4" = yes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblz4" >&5 -$as_echo_n "checking for liblz4... " >&6; } - -if test -n "$LZ4_CFLAGS"; then - pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LZ4_LIBS"; then - pkg_cv_LZ4_LIBS="$LZ4_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1` - else - LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LZ4_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (liblz4) were not met: - -$LZ4_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables LZ4_CFLAGS -and LZ4_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/;. -See \`config.log' for more details" "$LINENO" 5; } -else - LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS - LZ4_LIBS=$pkg_cv_LZ4_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4_compress in -llz4" >&5 -$as_echo_n "checking for LZ4_compress in -llz4... " >&6; } -if ${ac_cv_lib_lz4_LZ4_compress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char LZ4_compress (); -int -main () -{ -return LZ4_compress (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lz4_LZ4_compress=yes -else - ac_cv_lib_lz4_LZ4_compress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_compress" >&5 -$as_echo "$ac_cv_lib_lz4_LZ4_compress" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_compress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZ4 1 -_ACEOF - - LIBS="-llz4 $LIBS" - -else - as_fn_error $? "library 'lz4' is required for LZ4 support" "$LINENO" 5 -fi - -fi - if test "$enable_spinlocks" = yes; then $as_echo "#define HAVE_SPINLOCKS 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index c8f199dc5e..780791ae8a 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,12 @@ PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + LIBS="$LZ4_LIBS $LIBS" + CFLAGS="$LZ4_CFLAGS $CFLAGS" +fi + # # Assignments # @@ -1183,11 +1189,6 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi -if test "$with_lz4" = yes; then - PKG_CHECK_MODULES(LZ4, liblz4) - AC_CHECK_LIB(lz4, LZ4_compress, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) -fi - if test "$enable_spinlocks" = yes; then AC_DEFINE(HAVE_SPINLOCKS, 1, [Define to 1 if you have spinlocks.]) else @@ -1423,7 +1424,7 @@ fi if test "$with_lz4" = yes; then AC_CHECK_HEADERS(lz4/lz4.h, [], - [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) + [AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])])]) fi if test "$with_gssapi" = yes ; then diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 3463b42438..db4911ce43 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -13,7 +13,7 @@ */ #include "postgres.h" -#ifdef HAVE_LIBLZ4 +#ifdef USE_LZ4 #include <lz4.h> #endif @@ -168,7 +168,7 @@ pglz_cmdecompress_slice(const struct varlena *value, static struct varlena * lz4_cmcompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 valsize; @@ -212,7 +212,7 @@ lz4_cmcompress(const struct varlena *value) static struct varlena * lz4_cmdecompress(const struct varlena *value) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #else int32 rawsize; @@ -246,7 +246,7 @@ lz4_cmdecompress(const struct varlena *value) static struct varlena * lz4_cmdecompress_slice(const struct varlena *value, int32 slicelength) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #elif LZ4_VERSION_NUMBER < 10803 return lz4_cmdecompress(value); @@ -289,7 +289,7 @@ CompressionNameToMethod(char *compression) else if (strcmp(toast_compression[LZ4_COMPRESSION_ID].cmname, compression) == 0) { -#ifndef HAVE_LIBLZ4 +#ifndef USE_LZ4 NO_LZ4_SUPPORT(); #endif return LZ4_COMPRESSION; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 6007d72a73..0a6422da4f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -346,9 +346,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - /* Define to 1 if you have the `link' function. */ #undef HAVE_LINK @@ -902,6 +899,9 @@ /* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ #undef USE_LLVM +/* Define to 1 to build with LZ4 support (--with-lz4) */ +#undef USE_LZ4 + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 5f39a92111..14605371bb 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -307,7 +307,6 @@ sub GenerateFiles HAVE_LIBXML2 => undef, HAVE_LIBXSLT => undef, HAVE_LIBZ => $self->{options}->{zlib} ? 1 : undef, - HAVE_LIBLZ4 => undef, HAVE_LINK => undef, HAVE_LOCALE_T => 1, HAVE_LONG_INT_64 => undef, @@ -486,6 +485,7 @@ sub GenerateFiles USE_ICU => $self->{options}->{icu} ? 1 : undef, USE_LIBXML => undef, USE_LIBXSLT => undef, + USE_LZ4 => undef, USE_LDAP => $self->{options}->{ldap} ? 1 : undef, USE_LLVM => undef, USE_NAMED_POSIX_SEMAPHORES => undef, -- 2.17.0 --C94crkcyjafcjHxo Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0006-Add-default_toast_compression-GUC.patch" ^ permalink raw reply [nested|flat] 38+ messages in thread
* Re: [18] Fix a few issues with the collation cache @ 2024-09-21 00:28 Jeff Davis <[email protected]> 0 siblings, 0 replies; 38+ messages in thread From: Jeff Davis @ 2024-09-21 00:28 UTC (permalink / raw) To: pgsql-hackers On Wed, 2024-08-14 at 16:30 -0700, Jeff Davis wrote: > On Thu, 2024-08-08 at 12:24 -0700, Jeff Davis wrote: > > The collation cache, which maps collation oids to pg_locale_t > > objects, > > has a few longstanding issues: > > Here's a patch set v2. Updated and rebased. Regards, Jeff Davis Attachments: [text/x-patch] v4-0001-Tighten-up-make_libc_collator-and-make_icu_collat.patch (8.1K, ../../[email protected]/2-v4-0001-Tighten-up-make_libc_collator-and-make_icu_collat.patch) download | inline diff: From 224470bc4d0660dc11940f5595031eecb0319d62 Mon Sep 17 00:00:00 2001 From: Jeff Davis <[email protected]> Date: Wed, 7 Aug 2024 11:05:46 -0700 Subject: [PATCH v4 1/7] Tighten up make_libc_collator() and make_icu_collator(). Return the result rather than using an out parameter, and make it the caller's responsibility to copy it into the right context. Ensure that no paths leak a collator. The function make_icu_collator() doesn't have any external callers, so change it to be static. Also, when re-opening with rules, use a try/finally block to avoid leaking the collator. In make_libc_collator(), if the first newlocale() succeeds and the second one fails, close the first locale_t object. Discussion: https://postgr.es/m/[email protected] --- src/backend/utils/adt/pg_locale.c | 126 +++++++++++++++++++----------- src/include/utils/pg_locale.h | 4 - 2 files changed, 80 insertions(+), 50 deletions(-) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 5bef1b113a8..12ba5726f77 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1297,14 +1297,15 @@ report_newlocale_failure(const char *localename) } /* - * Initialize the locale_t field. + * Create a locale_t with the given collation and ctype. * - * The "C" and "POSIX" locales are not actually handled by libc, so set the - * locale_t to zero in that case. + * The "C" and "POSIX" locales are not actually handled by libc, so return + * NULL. + * + * Ensure that no path leaks a locale_t. */ -static void -make_libc_collator(const char *collate, const char *ctype, - pg_locale_t result) +static locale_t +make_libc_collator(const char *collate, const char *ctype) { locale_t loc = 0; @@ -1343,7 +1344,11 @@ make_libc_collator(const char *collate, const char *ctype, errno = 0; loc = newlocale(LC_CTYPE_MASK, ctype, loc1); if (!loc) + { + if (loc1) + freelocale(loc1); report_newlocale_failure(ctype); + } } else loc = loc1; @@ -1360,60 +1365,78 @@ make_libc_collator(const char *collate, const char *ctype, #endif } - result->info.lt = loc; + return loc; } -void -make_icu_collator(const char *iculocstr, - const char *icurules, - struct pg_locale_struct *resultp) -{ +/* + * Create a UCollator with the given locale string and rules. + * + * Ensure that no path leaks a UCollator. + */ #ifdef USE_ICU - UCollator *collator; - - collator = pg_ucol_open(iculocstr); - - /* - * If rules are specified, we extract the rules of the standard collation, - * add our own rules, and make a new collator with the combined rules. - */ - if (icurules) +static UCollator * +make_icu_collator(const char *iculocstr, const char *icurules) +{ + if (!icurules) { - const UChar *default_rules; - UChar *agg_rules; + /* simple case without rules */ + return pg_ucol_open(iculocstr); + } + else + { + UCollator *collator_std_rules; + UCollator *collator_all_rules; + const UChar *std_rules; UChar *my_rules; - UErrorCode status; + UChar *all_rules; int32_t length; + int32_t total; + UErrorCode status; - default_rules = ucol_getRules(collator, &length); + /* + * If rules are specified, we extract the rules of the standard + * collation, add our own rules, and make a new collator with the + * combined rules. + */ icu_to_uchar(&my_rules, icurules, strlen(icurules)); - agg_rules = palloc_array(UChar, u_strlen(default_rules) + u_strlen(my_rules) + 1); - u_strcpy(agg_rules, default_rules); - u_strcat(agg_rules, my_rules); + collator_std_rules = pg_ucol_open(iculocstr); - ucol_close(collator); + std_rules = ucol_getRules(collator_std_rules, &length); + + total = u_strlen(std_rules) + u_strlen(my_rules) + 1; + + /* avoid leaking collator on OOM */ + all_rules = palloc_extended(sizeof(UChar) * total, MCXT_ALLOC_NO_OOM); + if (!all_rules) + { + ucol_close(collator_std_rules); + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"))); + } + + u_strcpy(all_rules, std_rules); + u_strcat(all_rules, my_rules); + + ucol_close(collator_std_rules); status = U_ZERO_ERROR; - collator = ucol_openRules(agg_rules, u_strlen(agg_rules), - UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL, &status); + collator_all_rules = ucol_openRules(all_rules, u_strlen(all_rules), + UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, + NULL, &status); if (U_FAILURE(status)) + { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not open collator for locale \"%s\" with rules \"%s\": %s", iculocstr, icurules, u_errorName(status)))); - } + } - /* We will leak this string if the caller errors later :-( */ - resultp->info.icu.locale = MemoryContextStrdup(TopMemoryContext, iculocstr); - resultp->info.icu.ucol = collator; -#else /* not USE_ICU */ - /* could get here if a collation was created by a build with ICU */ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("ICU is not supported in this build"))); -#endif /* not USE_ICU */ + return collator_all_rules; + } } +#endif /* not USE_ICU */ /* * Initialize default_locale with database locale settings. @@ -1424,7 +1447,6 @@ init_database_collation(void) HeapTuple tup; Form_pg_database dbform; Datum datum; - bool isnull; /* Fetch our pg_database row normally, via syscache */ tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId)); @@ -1449,8 +1471,10 @@ init_database_collation(void) } else if (dbform->datlocprovider == COLLPROVIDER_ICU) { +#ifdef USE_ICU char *datlocale; char *icurules; + bool isnull; datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale); datlocale = TextDatumGetCString(datum); @@ -1464,7 +1488,14 @@ init_database_collation(void) else icurules = NULL; - make_icu_collator(datlocale, icurules, &default_locale); + default_locale.info.icu.locale = MemoryContextStrdup(TopMemoryContext, datlocale); + default_locale.info.icu.ucol = make_icu_collator(datlocale, icurules); +#else /* not USE_ICU */ + /* could get here if a collation was created by a build with ICU */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("ICU is not supported in this build"))); +#endif /* not USE_ICU */ } else { @@ -1483,7 +1514,7 @@ init_database_collation(void) default_locale.ctype_is_c = (strcmp(datctype, "C") == 0) || (strcmp(datctype, "POSIX") == 0); - make_libc_collator(datcollate, datctype, &default_locale); + default_locale.info.lt = make_libc_collator(datcollate, datctype); } default_locale.provider = dbform->datlocprovider; @@ -1572,7 +1603,7 @@ pg_newlocale_from_collation(Oid collid) result.ctype_is_c = (strcmp(collctype, "C") == 0) || (strcmp(collctype, "POSIX") == 0); - make_libc_collator(collcollate, collctype, &result); + result.info.lt = make_libc_collator(collcollate, collctype); } else if (collform->collprovider == COLLPROVIDER_ICU) { @@ -1591,7 +1622,8 @@ pg_newlocale_from_collation(Oid collid) else icurules = NULL; - make_icu_collator(iculocstr, icurules, &result); + result.info.icu.locale = MemoryContextStrdup(TopMemoryContext, iculocstr); + result.info.icu.ucol = make_icu_collator(iculocstr, icurules); } datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collversion, @@ -2500,6 +2532,8 @@ builtin_validate_locale(int encoding, const char *locale) /* * Wrapper around ucol_open() to handle API differences for older ICU * versions. + * + * Ensure that no path leaks a UCollator. */ static UCollator * pg_ucol_open(const char *loc_str) diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h index faae868bfcc..c2d95411e0a 100644 --- a/src/include/utils/pg_locale.h +++ b/src/include/utils/pg_locale.h @@ -104,10 +104,6 @@ struct pg_locale_struct typedef struct pg_locale_struct *pg_locale_t; -extern void make_icu_collator(const char *iculocstr, - const char *icurules, - struct pg_locale_struct *resultp); - extern void init_database_collation(void); extern pg_locale_t pg_newlocale_from_collation(Oid collid); -- 2.34.1 [text/x-patch] v4-0002-create_pg_locale.patch (12.6K, ../../[email protected]/3-v4-0002-create_pg_locale.patch) download | inline diff: From eccc4a4a83069c6a14465b4a9239a4d759aaa2a8 Mon Sep 17 00:00:00 2001 From: Jeff Davis <[email protected]> Date: Wed, 18 Sep 2024 15:53:56 -0700 Subject: [PATCH v4 2/7] create_pg_locale --- src/backend/utils/adt/pg_locale.c | 310 +++++++++++++++--------------- 1 file changed, 155 insertions(+), 155 deletions(-) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 12ba5726f77..1dec00b55ed 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1227,45 +1227,6 @@ IsoLocaleName(const char *winlocname) #endif /* WIN32 && LC_MESSAGES */ -/* - * Cache mechanism for collation information. - * - * Note that we currently lack any way to flush the cache. Since we don't - * support ALTER COLLATION, this is OK. The worst case is that someone - * drops a collation, and a useless cache entry hangs around in existing - * backends. - */ -static collation_cache_entry * -lookup_collation_cache(Oid collation) -{ - collation_cache_entry *cache_entry; - bool found; - - Assert(OidIsValid(collation)); - Assert(collation != DEFAULT_COLLATION_OID); - - if (CollationCache == NULL) - { - CollationCacheContext = AllocSetContextCreate(TopMemoryContext, - "collation cache", - ALLOCSET_DEFAULT_SIZES); - CollationCache = collation_cache_create(CollationCacheContext, - 16, NULL); - } - - cache_entry = collation_cache_insert(CollationCache, collation, &found); - if (!found) - { - /* - * Make sure cache entry is marked invalid, in case we fail before - * setting things. - */ - cache_entry->locale = 0; - } - - return cache_entry; -} - /* simple subroutine for reporting errors from newlocale() */ static void report_newlocale_failure(const char *localename) @@ -1530,153 +1491,192 @@ init_database_collation(void) } /* - * Create a pg_locale_t from a collation OID. Results are cached for the - * lifetime of the backend. Thus, do not free the result with freelocale(). - * - * For simplicity, we always generate COLLATE + CTYPE even though we - * might only need one of them. Since this is called only once per session, - * it shouldn't cost much. + * Create and initialize a pg_locale_t. Be careful to check for errors before + * allocating memory. */ -pg_locale_t -pg_newlocale_from_collation(Oid collid) +static pg_locale_t +create_pg_locale(Oid collid) { - collation_cache_entry *cache_entry; - - if (collid == DEFAULT_COLLATION_OID) - return &default_locale; + /* We haven't computed this yet in this session, so do it */ + HeapTuple tp; + Form_pg_collation collform; + pg_locale_t result; + Datum datum; + bool isnull; - if (!OidIsValid(collid)) + tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid)); + if (!HeapTupleIsValid(tp)) elog(ERROR, "cache lookup failed for collation %u", collid); + collform = (Form_pg_collation) GETSTRUCT(tp); - if (last_collation_cache_oid == collid) - return last_collation_cache_locale; - - cache_entry = lookup_collation_cache(collid); - - if (cache_entry->locale == 0) + /* compare version in catalog to version from provider */ + datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collversion, + &isnull); + if (!isnull) { - /* We haven't computed this yet in this session, so do it */ - HeapTuple tp; - Form_pg_collation collform; - struct pg_locale_struct result; - pg_locale_t resultp; - Datum datum; - bool isnull; + char *actual_versionstr; + char *collversionstr; - tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid)); - if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for collation %u", collid); - collform = (Form_pg_collation) GETSTRUCT(tp); + collversionstr = TextDatumGetCString(datum); - /* We'll fill in the result struct locally before allocating memory */ - memset(&result, 0, sizeof(result)); - result.provider = collform->collprovider; - result.deterministic = collform->collisdeterministic; + if (collform->collprovider == COLLPROVIDER_LIBC) + datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate); + else + datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale); - if (collform->collprovider == COLLPROVIDER_BUILTIN) + actual_versionstr = get_collation_actual_version(collform->collprovider, + TextDatumGetCString(datum)); + if (!actual_versionstr) { - const char *locstr; + /* + * This could happen when specifying a version in CREATE + * COLLATION but the provider does not support versioning, or + * manually creating a mess in the catalogs. + */ + ereport(ERROR, + (errmsg("collation \"%s\" has no actual version, but a version was recorded", + NameStr(collform->collname)))); + } - datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale); - locstr = TextDatumGetCString(datum); + if (strcmp(actual_versionstr, collversionstr) != 0) + ereport(WARNING, + (errmsg("collation \"%s\" has version mismatch", + NameStr(collform->collname)), + errdetail("The collation in the database was created using version %s, " + "but the operating system provides version %s.", + collversionstr, actual_versionstr), + errhint("Rebuild all objects affected by this collation and run " + "ALTER COLLATION %s REFRESH VERSION, " + "or build PostgreSQL with the right library version.", + quote_qualified_identifier(get_namespace_name(collform->collnamespace), + NameStr(collform->collname))))); + } - result.collate_is_c = true; - result.ctype_is_c = (strcmp(locstr, "C") == 0); + if (collform->collprovider == COLLPROVIDER_BUILTIN) + { + const char *locstr; - builtin_validate_locale(GetDatabaseEncoding(), locstr); + datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale); + locstr = TextDatumGetCString(datum); - result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext, - locstr); - } - else if (collform->collprovider == COLLPROVIDER_LIBC) - { - const char *collcollate; - const char *collctype; + builtin_validate_locale(GetDatabaseEncoding(), locstr); - datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate); - collcollate = TextDatumGetCString(datum); - datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collctype); - collctype = TextDatumGetCString(datum); + result = MemoryContextAllocZero(TopMemoryContext, + sizeof(struct pg_locale_struct)); - result.collate_is_c = (strcmp(collcollate, "C") == 0) || - (strcmp(collcollate, "POSIX") == 0); - result.ctype_is_c = (strcmp(collctype, "C") == 0) || - (strcmp(collctype, "POSIX") == 0); + result->provider = collform->collprovider; + result->deterministic = collform->collisdeterministic; + result->collate_is_c = true; + result->ctype_is_c = (strcmp(locstr, "C") == 0); + result->info.builtin.locale = MemoryContextStrdup(TopMemoryContext, + locstr); + } + else if (collform->collprovider == COLLPROVIDER_LIBC) + { + const char *collcollate; + const char *collctype; + locale_t locale; + + datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate); + collcollate = TextDatumGetCString(datum); + datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collctype); + collctype = TextDatumGetCString(datum); + + locale = make_libc_collator(collcollate, collctype); + + result = MemoryContextAllocZero(TopMemoryContext, + sizeof(struct pg_locale_struct)); + + result->provider = collform->collprovider; + result->deterministic = collform->collisdeterministic; + result->collate_is_c = (strcmp(collcollate, "C") == 0) || + (strcmp(collcollate, "POSIX") == 0); + result->ctype_is_c = (strcmp(collctype, "C") == 0) || + (strcmp(collctype, "POSIX") == 0); + result->info.lt = locale; + } + else if (collform->collprovider == COLLPROVIDER_ICU) + { + const char *iculocstr; + const char *icurules; + UCollator *collator; - result.info.lt = make_libc_collator(collcollate, collctype); - } - else if (collform->collprovider == COLLPROVIDER_ICU) - { - const char *iculocstr; - const char *icurules; + datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale); + iculocstr = TextDatumGetCString(datum); - datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale); - iculocstr = TextDatumGetCString(datum); + datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collicurules, &isnull); + if (!isnull) + icurules = TextDatumGetCString(datum); + else + icurules = NULL; - result.collate_is_c = false; - result.ctype_is_c = false; + collator = make_icu_collator(iculocstr, icurules); - datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collicurules, &isnull); - if (!isnull) - icurules = TextDatumGetCString(datum); - else - icurules = NULL; + result = MemoryContextAllocZero(TopMemoryContext, + sizeof(struct pg_locale_struct)); - result.info.icu.locale = MemoryContextStrdup(TopMemoryContext, iculocstr); - result.info.icu.ucol = make_icu_collator(iculocstr, icurules); - } + result->provider = collform->collprovider; + result->deterministic = collform->collisdeterministic; + result->collate_is_c = false; + result->ctype_is_c = false; + result->info.icu.locale = MemoryContextStrdup(TopMemoryContext, iculocstr); + result->info.icu.ucol = collator; + } - datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collversion, - &isnull); - if (!isnull) - { - char *actual_versionstr; - char *collversionstr; + ReleaseSysCache(tp); - collversionstr = TextDatumGetCString(datum); + return result; +} - if (collform->collprovider == COLLPROVIDER_LIBC) - datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate); - else - datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale); +/* + * Create or retrieve a pg_locale_t for the given collation OID. Results are + * cached for the lifetime of the backend. + */ +pg_locale_t +pg_newlocale_from_collation(Oid collid) +{ + collation_cache_entry *cache_entry; + bool found; - actual_versionstr = get_collation_actual_version(collform->collprovider, - TextDatumGetCString(datum)); - if (!actual_versionstr) - { - /* - * This could happen when specifying a version in CREATE - * COLLATION but the provider does not support versioning, or - * manually creating a mess in the catalogs. - */ - ereport(ERROR, - (errmsg("collation \"%s\" has no actual version, but a version was recorded", - NameStr(collform->collname)))); - } + if (collid == DEFAULT_COLLATION_OID) + return &default_locale; - if (strcmp(actual_versionstr, collversionstr) != 0) - ereport(WARNING, - (errmsg("collation \"%s\" has version mismatch", - NameStr(collform->collname)), - errdetail("The collation in the database was created using version %s, " - "but the operating system provides version %s.", - collversionstr, actual_versionstr), - errhint("Rebuild all objects affected by this collation and run " - "ALTER COLLATION %s REFRESH VERSION, " - "or build PostgreSQL with the right library version.", - quote_qualified_identifier(get_namespace_name(collform->collnamespace), - NameStr(collform->collname))))); - } + if (!OidIsValid(collid)) + elog(ERROR, "cache lookup failed for collation %u", collid); - ReleaseSysCache(tp); + if (last_collation_cache_oid == collid) + return last_collation_cache_locale; - /* We'll keep the pg_locale_t structures in TopMemoryContext */ - resultp = MemoryContextAlloc(TopMemoryContext, sizeof(*resultp)); - *resultp = result; + /* + * Cache mechanism for collation information. + * + * Note that we currently lack any way to flush the cache. Since we don't + * support ALTER COLLATION, this is OK. The worst case is that someone + * drops a collation, and a useless cache entry hangs around in existing + * backends. + */ + if (CollationCache == NULL) + { + CollationCacheContext = AllocSetContextCreate(TopMemoryContext, + "collation cache", + ALLOCSET_DEFAULT_SIZES); + CollationCache = collation_cache_create(CollationCacheContext, + 16, NULL); + } - cache_entry->locale = resultp; + cache_entry = collation_cache_insert(CollationCache, collid, &found); + if (!found) + { + /* + * Make sure cache entry is marked invalid, in case we fail before + * setting things. + */ + cache_entry->locale = 0; } + if (cache_entry->locale == 0) + cache_entry->locale = create_pg_locale(collid); + last_collation_cache_oid = collid; last_collation_cache_locale = cache_entry->locale; -- 2.34.1 [text/x-patch] v4-0003-CollationCacheContext.patch (2.6K, ../../[email protected]/4-v4-0003-CollationCacheContext.patch) download | inline diff: From fca0efa184971f9780b356039aa3ed08a7445524 Mon Sep 17 00:00:00 2001 From: Jeff Davis <[email protected]> Date: Wed, 18 Sep 2024 15:55:37 -0700 Subject: [PATCH v4 3/7] CollationCacheContext --- src/backend/utils/adt/pg_locale.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 1dec00b55ed..d3d9c3920e6 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1495,7 +1495,7 @@ init_database_collation(void) * allocating memory. */ static pg_locale_t -create_pg_locale(Oid collid) +create_pg_locale(MemoryContext context, Oid collid) { /* We haven't computed this yet in this session, so do it */ HeapTuple tp; @@ -1561,15 +1561,15 @@ create_pg_locale(Oid collid) builtin_validate_locale(GetDatabaseEncoding(), locstr); - result = MemoryContextAllocZero(TopMemoryContext, + result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct)); result->provider = collform->collprovider; result->deterministic = collform->collisdeterministic; result->collate_is_c = true; result->ctype_is_c = (strcmp(locstr, "C") == 0); - result->info.builtin.locale = MemoryContextStrdup(TopMemoryContext, - locstr); + result->info.builtin.locale = MemoryContextStrdup(context, + locstr); } else if (collform->collprovider == COLLPROVIDER_LIBC) { @@ -1584,7 +1584,7 @@ create_pg_locale(Oid collid) locale = make_libc_collator(collcollate, collctype); - result = MemoryContextAllocZero(TopMemoryContext, + result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct)); result->provider = collform->collprovider; @@ -1612,14 +1612,14 @@ create_pg_locale(Oid collid) collator = make_icu_collator(iculocstr, icurules); - result = MemoryContextAllocZero(TopMemoryContext, + result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct)); result->provider = collform->collprovider; result->deterministic = collform->collisdeterministic; result->collate_is_c = false; result->ctype_is_c = false; - result->info.icu.locale = MemoryContextStrdup(TopMemoryContext, iculocstr); + result->info.icu.locale = MemoryContextStrdup(context, iculocstr); result->info.icu.ucol = collator; } @@ -1675,7 +1675,7 @@ pg_newlocale_from_collation(Oid collid) } if (cache_entry->locale == 0) - cache_entry->locale = create_pg_locale(collid); + cache_entry->locale = create_pg_locale(CollationCacheContext, collid); last_collation_cache_oid = collid; last_collation_cache_locale = cache_entry->locale; -- 2.34.1 [text/x-patch] v4-0004-resource-owners.patch (5.1K, ../../[email protected]/5-v4-0004-resource-owners.patch) download | inline diff: From 5ae3b1be6489617a1639141749c31d2f4419a676 Mon Sep 17 00:00:00 2001 From: Jeff Davis <[email protected]> Date: Wed, 18 Sep 2024 16:55:42 -0700 Subject: [PATCH v4 4/7] resource owners --- src/backend/utils/adt/pg_locale.c | 74 ++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index d3d9c3920e6..9d1d71f1561 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -66,6 +66,7 @@ #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/pg_locale.h" +#include "utils/resowner.h" #include "utils/syscache.h" #ifdef USE_ICU @@ -148,6 +149,12 @@ typedef struct #define SH_DEFINE #include "lib/simplehash.h" +/* + * Collator objects (UCollator for ICU or locale_t for libc) are allocated in + * an external library, so track them using a resource owner. + */ +static ResourceOwner CollationCacheOwner = NULL; + static MemoryContext CollationCacheContext = NULL; static collation_cache_hash *CollationCache = NULL; @@ -179,8 +186,35 @@ static int32_t uchar_convert(UConverter *converter, const char *src, int32_t srclen); static void icu_set_collation_attributes(UCollator *collator, const char *loc, UErrorCode *status); + +static void ResourceOwnerRememberUCollator(ResourceOwner owner, + UCollator *collator); +static void ResOwnerReleaseUCollator(Datum val); + +static const ResourceOwnerDesc UCollatorResourceKind = +{ + .name = "UCollator reference", + .release_phase = RESOURCE_RELEASE_AFTER_LOCKS, + .release_priority = RELEASE_PRIO_LAST, + .ReleaseResource = ResOwnerReleaseUCollator, + .DebugPrint = NULL /* the default message is fine */ +}; #endif +static void ResourceOwnerRememberLocaleT(ResourceOwner owner, + locale_t locale); +static void ResOwnerReleaseLocaleT(Datum val); + +static const ResourceOwnerDesc LocaleTResourceKind = +{ + .name = "locale_t reference", + .release_phase = RESOURCE_RELEASE_AFTER_LOCKS, + .release_priority = RELEASE_PRIO_LAST, + .ReleaseResource = ResOwnerReleaseLocaleT, + .DebugPrint = NULL /* the default message is fine */ +}; + + /* * POSIX doesn't define _l-variants of these functions, but several systems * have them. We provide our own replacements here. @@ -1257,6 +1291,20 @@ report_newlocale_failure(const char *localename) localename) : 0))); } +static void +ResourceOwnerRememberLocaleT(ResourceOwner owner, locale_t locale) +{ + ResourceOwnerRemember(owner, PointerGetDatum(locale), + &LocaleTResourceKind); +} + +static void +ResOwnerReleaseLocaleT(Datum val) +{ + locale_t locale = (locale_t) DatumGetPointer(val); + freelocale(locale); +} + /* * Create a locale_t with the given collation and ctype. * @@ -1335,6 +1383,20 @@ make_libc_collator(const char *collate, const char *ctype) * Ensure that no path leaks a UCollator. */ #ifdef USE_ICU +static void +ResourceOwnerRememberUCollator(ResourceOwner owner, UCollator *collator) +{ + ResourceOwnerRemember(owner, PointerGetDatum(collator), + &UCollatorResourceKind); +} + +static void +ResOwnerReleaseUCollator(Datum val) +{ + UCollator *collator = (UCollator *) DatumGetPointer(val); + ucol_close(collator); +} + static UCollator * make_icu_collator(const char *iculocstr, const char *icurules) { @@ -1495,7 +1557,7 @@ init_database_collation(void) * allocating memory. */ static pg_locale_t -create_pg_locale(MemoryContext context, Oid collid) +create_pg_locale(MemoryContext context, ResourceOwner owner, Oid collid) { /* We haven't computed this yet in this session, so do it */ HeapTuple tp; @@ -1582,7 +1644,10 @@ create_pg_locale(MemoryContext context, Oid collid) datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collctype); collctype = TextDatumGetCString(datum); + ResourceOwnerEnlarge(owner); locale = make_libc_collator(collcollate, collctype); + if (locale) + ResourceOwnerRememberLocaleT(owner, locale); result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct)); @@ -1610,7 +1675,9 @@ create_pg_locale(MemoryContext context, Oid collid) else icurules = NULL; + ResourceOwnerEnlarge(owner); collator = make_icu_collator(iculocstr, icurules); + ResourceOwnerRememberUCollator(owner, collator); result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct)); @@ -1657,6 +1724,7 @@ pg_newlocale_from_collation(Oid collid) */ if (CollationCache == NULL) { + CollationCacheOwner = ResourceOwnerCreate(NULL, "collation cache"); CollationCacheContext = AllocSetContextCreate(TopMemoryContext, "collation cache", ALLOCSET_DEFAULT_SIZES); @@ -1675,7 +1743,9 @@ pg_newlocale_from_collation(Oid collid) } if (cache_entry->locale == 0) - cache_entry->locale = create_pg_locale(CollationCacheContext, collid); + cache_entry->locale = create_pg_locale(CollationCacheContext, + CollationCacheOwner, + collid); last_collation_cache_oid = collid; last_collation_cache_locale = cache_entry->locale; -- 2.34.1 [text/x-patch] v4-0005-invalidation.patch (2.7K, ../../[email protected]/6-v4-0005-invalidation.patch) download | inline diff: From 2f51247615a36dc257b700c2832f3d4aa32fce64 Mon Sep 17 00:00:00 2001 From: Jeff Davis <[email protected]> Date: Wed, 18 Sep 2024 17:49:57 -0700 Subject: [PATCH v4 5/7] invalidation --- src/backend/utils/adt/pg_locale.c | 41 +++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 9d1d71f1561..c89ac3b9e01 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -63,6 +63,7 @@ #include "utils/builtins.h" #include "utils/formatting.h" #include "utils/guc_hooks.h" +#include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/pg_locale.h" @@ -1695,6 +1696,34 @@ create_pg_locale(MemoryContext context, ResourceOwner owner, Oid collid) return result; } +static void +CollationCacheInvalidate(Datum arg, int cacheid, uint32 hashvalue) +{ + last_collation_cache_oid = InvalidOid; + + if (CollationCache == NULL) + return; + + ResourceOwnerRelease(CollationCacheOwner, + RESOURCE_RELEASE_BEFORE_LOCKS, + false, true); + ResourceOwnerRelease(CollationCacheOwner, + RESOURCE_RELEASE_LOCKS, + false, true); + ResourceOwnerRelease(CollationCacheOwner, + RESOURCE_RELEASE_AFTER_LOCKS, + false, true); + ResourceOwnerDelete(CollationCacheOwner); + CollationCacheOwner = ResourceOwnerCreate(NULL, "collation cache"); + + MemoryContextReset(CollationCacheContext); + + /* free all memory and reset hash table */ + CollationCache = collation_cache_create(CollationCacheContext, + 16, NULL); +} + + /* * Create or retrieve a pg_locale_t for the given collation OID. Results are * cached for the lifetime of the backend. @@ -1714,14 +1743,7 @@ pg_newlocale_from_collation(Oid collid) if (last_collation_cache_oid == collid) return last_collation_cache_locale; - /* - * Cache mechanism for collation information. - * - * Note that we currently lack any way to flush the cache. Since we don't - * support ALTER COLLATION, this is OK. The worst case is that someone - * drops a collation, and a useless cache entry hangs around in existing - * backends. - */ + /* cache mechanism for collation information */ if (CollationCache == NULL) { CollationCacheOwner = ResourceOwnerCreate(NULL, "collation cache"); @@ -1730,6 +1752,9 @@ pg_newlocale_from_collation(Oid collid) ALLOCSET_DEFAULT_SIZES); CollationCache = collation_cache_create(CollationCacheContext, 16, NULL); + CacheRegisterSyscacheCallback(COLLOID, + CollationCacheInvalidate, + (Datum) 0); } cache_entry = collation_cache_insert(CollationCache, collid, &found); -- 2.34.1 ^ permalink raw reply [nested|flat] 38+ messages in thread
end of thread, other threads:[~2024-09-21 00:28 UTC | newest] Thread overview: 38+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2017-07-11 16:44 Arrays of domains Tom Lane <[email protected]> 2017-07-11 17:45 ` David Fetter <[email protected]> 2017-07-11 17:58 ` Andrew Dunstan <[email protected]> 2017-08-11 17:17 ` Tom Lane <[email protected]> 2017-09-13 00:50 ` Tom Lane <[email protected]> 2017-09-21 19:49 ` Tom Lane <[email protected]> 2017-09-28 01:11 ` Andrew Dunstan <[email protected]> 2017-09-28 17:11 ` Tom Lane <[email protected]> 2017-09-28 18:45 ` Andrew Dunstan <[email protected]> 2017-09-28 21:44 ` Tom Lane <[email protected]> 2017-09-29 13:22 ` Andrew Dunstan <[email protected]> 2017-09-29 17:10 ` Tom Lane <[email protected]> 2017-09-29 20:17 ` Andrew Dunstan <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2021-03-11 15:18 [PATCH 5/8] f!3nd attempt to use pkgconfig to allow compiling on OSX Justin Pryzby <[email protected]> 2024-09-21 00:28 Re: [18] Fix a few issues with the collation cache Jeff Davis <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox