8000 Improve handling of collations in contrib/postgres_fdw. · postgres/postgres@76f965f · GitHub
[go: up one dir, main page]

Skip to content
{"payload":{"commit":{"oid":"76f965ff1f2896d74812a1cad9158fb9f4a1aab9","url":"/postgres/postgres/commit/76f965ff1f2896d74812a1cad9158fb9f4a1aab9","authoredDate":"2015-09-24T12:47:29.000-04:00","committedDate":"2015-09-24T12:47:29.000-04:00","shortMessage":null,"shortMessageMarkdown":"\u003cdiv\u003eImprove handling of collations in contrib/postgres_fdw.\u003c/div\u003e","shortMessageMarkdownLink":null,"bodyMessageHtml":"If we have a local Var of say varchar type with default collation, and\nwe apply a RelabelType to convert that to text with default collation, we\ndon't want to consider that as creating an FDW_COLLATE_UNSAFE situation.\nIt should be okay to compare that to a remote Var, so long as the remote\nVar determines the comparison collation. (When we actually ship such an\nexpression to the remote side, the local Var would become a Param with\ndefault collation, meaning the remote Var would in fact control the\ncomparison collation, because non-default implicit collation overrides\ndefault implicit collation in parse_collate.c.) To fix, be more precise\nabout what FDW_COLLATE_NONE means: it applies either to a noncollatable\ndata type or to a collatable type with default collation, if that collation\ncan't be traced to a remote Var. (When it can, FDW_COLLATE_SAFE is\nappropriate.) We were essentially using that interpretation already at\nthe Var/Const/Param level, but we weren't bubbling it up properly.\n\nAn alternative fix would be to introduce a separate FDW_COLLATE_DEFAULT\nvalue to describe the second situation, but that would add more code\nwithout changing the actual behavior, so it didn't seem worthwhile.\n\nAlso, since we're clarifying the rule to be that we care about whether\noperator/function input collations match, there seems no need to fail\nimmediately upon seeing a Const/Param/non-foreign-Var with nondefault\ncollation. We only have to reject if it appears in a collation-sensitive\ncontext (for example, \"var IS NOT NULL\" is perfectly safe from a collation\nstandpoint, whatever collation the var has). So just set the state to\nUNSAFE rather than failing immediately.\n\nPer report from Jeevan Chalke. This essentially corrects some sloppy\nthinking in commit \u003ca class=\"commit-link\" data-hovercard-type=\"commit\" data-hovercard-url=\"https://github.com/postgres/postgres/commit/ed3ddf918b59545583a4b374566bc1148e75f593/hovercard\" href=\"https://github.com/postgres/postgres/commit/ed3ddf918b59545583a4b374566bc1148e75f593\"\u003e\u003ctt\u003eed3ddf9\u003c/tt\u003e\u003c/a\u003e, so back-patch\nto 9.3 where that logic appeared.","authors":[{"login":"tglsfdc","displayName":"Tom Lane","avatarUrl":"https://avatars.githubusercontent.com/u/8755309?v=4","path":"/tglsfdc","isGitHub":false}],"committerAttribution":false,"committer":{"login":"tglsfdc","displayName":"Tom Lane","avatarUrl":"https://avatars.githubusercontent.com/u/8755309?v=4","path":"/tglsfdc","isGitHub":false},"parents":["9f1255ac859364a86264a67729dbd1a36dd63ff2"],"globalRelayId":"MDY6Q29tbWl0OTI3NDQyOjc2Zjk2NWZmMWYyODk2ZDc0ODEyYTFjYWQ5MTU4ZmI5ZjRhMWFhYjk=","sha1":"9f1255ac859364a86264a67729dbd1a36dd63ff2","sha2":"76f965ff1f2896d74812a1cad9158fb9f4a1aab9"},"currentUser":null,"repo":{"id":927442,"defaultBranch":"master","name":"postgres","ownerLogin":"postgres","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2010-09-21T11:35:45.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/177543?v=4","public":true,"private":false,"isOrgOwned":true},"diffEntryData":[{"diffLines":[{"stylingDirective":null,"type":"HUNK","blobLineNumber":16,"text":"@@ -17,11 +17,12 @@","html":"@@ -17,11 +17,12 @@","displayNoNewLineWarning":false,"position":0,"left":16,"right":16},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":17,"text":" * We do not consider that it is ever safe to send COLLATE expressions to","html":" \u003cspan class=pl-c\u003e * We do not consider that it is ever safe to send COLLATE expressions to\u003c/span\u003e","displayNoNewLineWarning":false,"position":1,"left":17,"right":17},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":18,"text":" * the remote server: it might not have the same collation names we do.","html":" \u003cspan class=pl-c\u003e * the remote server: it might not have the same collation names we do.\u003c/span\u003e","displayNoNewLineWarning":false,"position":2,"left":18,"right":18},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":19,"text":" * (Later we might consider it safe to send COLLATE \"C\", but even that would","html":" \u003cspan class=pl-c\u003e * (Later we might consider it safe to send COLLATE \u0026quot;C\u0026quot;, but even that would\u003c/span\u003e","displayNoNewLineWarning":false,"position":3,"left":19,"right":19},{"stylingDirective":null,"type":"DELETION","blobLineNumber":20,"text":"- * fail on old remote servers.) An expression is considered safe to send only","html":"-\u003cspan class=pl-c\u003e * fail on old remote servers.) An expression is considered safe to send only\u003c/span\u003e","displayNoNewLineWarning":false,"position":4,"left":20,"right":19},{"stylingDirective":null,"type":"DELETION","blobLineNumber":21,"text":"- * if all collations used in it are traceable to Var(s) of the foreign table.","html":"-\u003cspan class=pl-c\u003e * if all collations used in it are traceable to Var(s) of the foreign table.\u003c/span\u003e","displayNoNewLineWarning":false,"position":5,"left":21,"right":19},{"stylingDirective":null,"type":"DELETION","blobLineNumber":22,"text":"- * That implies that if the remote server gets a different answer than we do,","html":"-\u003cspan class=pl-c\u003e * That implies that if the remote server gets a different answer than we do,\u003c/span\u003e","displayNoNewLineWarning":false,"position":6,"left":22,"right":19},{"stylingDirective":null,"type":"DELETION","blobLineNumber":23,"text":"- * the foreign table's columns are not marked with collations that match the","html":"-\u003cspan class=pl-c\u003e * the foreign table\u0026#39;s columns are not marked with collations that match the\u003c/span\u003e","displayNoNewLineWarning":false,"position":7,"left":23,"right":19},{"stylingDirective":null,"type":"DELETION","blobLineNumber":24,"text":"- * remote table's columns, which we can consider to be user error.","html":"-\u003cspan class=pl-c\u003e * remote table\u0026#39;s columns, which we can consider to be user error.\u003c/span\u003e","displayNoNewLineWarning":false,"position":8,"left":24,"right":19},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":20,"text":"+ * fail on old remote servers.) An expression is considered safe to send","html":"+\u003cspan class=pl-c\u003e * fail on old remote servers.) An expression is considered safe to send\u003c/span\u003e","displayNoNewLineWarning":false,"position":9,"left":24,"right":20},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":21,"text":"+ * only if all operator/function input collations used in it are traceable to","html":"+\u003cspan class=pl-c\u003e * only if all operator/function input collations used in it are traceable to\u003c/span\u003e","displayNoNewLineWarning":false,"position":10,"left":24,"right":21},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":22,"text":"+ * Var(s) of the foreign table. That implies that if the remote server gets","html":"+\u003cspan class=pl-c\u003e * Var(s) of the foreign table. That implies that if the remote server gets\u003c/span\u003e","displayNoNewLineWarning":false,"position":11,"left":24,"right":22},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":23,"text":"+ * a different answer than we do, the foreign table's columns are not marked","html":"+\u003cspan class=pl-c\u003e * a different answer than we do, the foreign table\u0026#39;s columns are not marked\u003c/span\u003e","displayNoNewLineWarning":false,"position":12,"left":24,"right":23},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":24,"text":"+ * with collations that match the remote table's columns, which we can","html":"+\u003cspan class=pl-c\u003e * with collations that match the remote table\u0026#39;s columns, which we can\u003c/span\u003e","displayNoNewLineWarning":false,"position":13,"left":24,"right":24},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":25,"text":"+ * consider to be user error.","html":"+\u003cspan class=pl-c\u003e * consider to be user error.\u003c/span\u003e","displayNoNewLineWarning":false,"position":14,"left":24,"right":25},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":26,"text":" *","html":" \u003cspan class=pl-c\u003e *\u003c/span\u003e","displayNoNewLineWarning":false,"position":15,"left":25,"right":26},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":27,"text":" * Portions Copyright (c) 2012-2015, PostgreSQL Global Development Group","html":" \u003cspan class=pl-c\u003e * Portions Copyright (c) 2012-2015, PostgreSQL Global Development Group\u003c/span\u003e","displayNoNewLineWarning":false,"position":16,"left":26,"right":27},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":28,"text":" *","html":" \u003cspan class=pl-c\u003e *\u003c/span\u003e","displayNoNewLineWarning":false,"position":17,"left":27,"right":28},{"stylingDirective":null,"type":"HUNK","blobLineNumber":69,"text":"@@ -69,9 +70,12 @@ typedef struct foreign_glob_cxt","html":"@@ -69,9 +70,12 @@ typedef struct foreign_glob_cxt","displayNoNewLineWarning":false,"position":18,"left":68,"right":69},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":70,"text":" */","html":" \u003cspan class=pl-c\u003e */\u003c/span\u003e","displayNoNewLineWarning":false,"position":19,"left":69,"right":70},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":71,"text":" typedef enum","html":" \u003cspan class=pl-k\u003etypedef\u003c/span\u003e \u003cspan class=pl-k\u003eenum\u003c/span\u003e","displayNoNewLineWarning":false,"position":20,"left":70,"right":71},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":72,"text":" {","html":" {","displayNoNewLineWarning":false,"position":21,"left":71,"right":72},{"stylingDirective":null,"type":"DELETION","blobLineNumber":72,"text":"-\tFDW_COLLATE_NONE,\t\t\t/* expression is of a noncollatable type */","html":"-\t\u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e,\t\t\t\u003cspan class=pl-c\u003e/* expression is of a noncollatable type */\u003c/span\u003e","displayNoNewLineWarning":false,"position":22,"left":72,"right":72},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":73,"text":"+\tFDW_COLLATE_NONE,\t\t\t/* expression is of a noncollatable type, or","html":"+\t\u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e,\t\t\t\u003cspan class=pl-c\u003e/* expression is of a noncollatable type, or\u003c/span\u003e","displayNoNewLineWarning":false,"position":23,"left":72,"right":73},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":74,"text":"+\t\t\t\t\t\t\t\t * it has default collation that is not","html":"+\u003cspan class=pl-c\u003e\t\t\t\t\t\t\t\t * it has default collation that is not\u003c/span\u003e","displayNoNewLineWarning":false,"position":24,"left":72,"right":74},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":75,"text":"+\t\t\t\t\t\t\t\t * traceable to a foreign Var */","html":"+\u003cspan class=pl-c\u003e\t\t\t\t\t\t\t\t * traceable to a foreign Var */\u003c/span\u003e","displayNoNewLineWarning":false,"position":25,"left":72,"right":75},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":76,"text":" \tFDW_COLLATE_SAFE,\t\t\t/* collation derives from a foreign Var */","html":" \t\u003cspan class=pl-c1\u003eFDW_COLLATE_SAFE\u003c/span\u003e,\t\t\t\u003cspan class=pl-c\u003e/* collation derives from a foreign Var */\u003c/span\u003e","displayNoNewLineWarning":false,"position":26,"left":73,"right":76},{"stylingDirective":null,"type":"DELETION","blobLineNumber":74,"text":"-\tFDW_COLLATE_UNSAFE\t\t\t/* collation derives from something else */","html":"-\t\u003cspan class=pl-c1\u003eFDW_COLLATE_UNSAFE\u003c/span\u003e\t\t\t\u003cspan class=pl-c\u003e/* collation derives from something else */\u003c/span\u003e","displayNoNewLineWarning":false,"position":27,"left":74,"right":76},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":77,"text":"+\tFDW_COLLATE_UNSAFE\t\t\t/* collation is non-default and derives from","html":"+\t\u003cspan class=pl-c1\u003eFDW_COLLATE_UNSAFE\u003c/span\u003e\t\t\t\u003cspan class=pl-c\u003e/* collation is non-default and derives from\u003c/span\u003e","displayNoNewLineWarning":false,"position":28,"left":74,"right":77},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":78,"text":"+\t\t\t\t\t\t\t\t * something other than a foreign Var */","html":"+\u003cspan class=pl-c\u003e\t\t\t\t\t\t\t\t * something other than a foreign Var */\u003c/span\u003e","displayNoNewLineWarning":false,"position":29,"left":74,"right":78},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":79,"text":" } FDWCollateState;","html":" } \u003cspan class=pl-smi\u003eFDWCollateState\u003c/span\u003e;","displayNoNewLineWarning":false,"position":30,"left":75,"right":79},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":80,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":31,"left":76,"right":80},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":81,"text":" typedef struct foreign_loc_cxt","html":" \u003cspan class=pl-k\u003etypedef\u003c/span\u003e \u003cspan class=pl-k\u003estruct\u003c/span\u003e \u003cspan class=pl-smi\u003eforeign_loc_cxt\u003c/span\u003e","displayNoNewLineWarning":false,"position":32,"left":77,"right":81},{"stylingDirective":null,"type":"HUNK","blobLineNumber":275,"text":"@@ -272,13 +276,24 @@ foreign_expr_walker(Node *node,","html":"@@ -272,13 +276,24 @@ foreign_expr_walker(Node *node,","displayNoNewLineWarning":false,"position":33,"left":271,"right":275},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":276,"text":" \t\t\t\telse","html":" \t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e","displayNoNewLineWarning":false,"position":34,"left":272,"right":276},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":277,"text":" \t\t\t\t{","html":" \t\t\t\t{","displayNoNewLineWarning":false,"position":35,"left":273,"right":277},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":278,"text":" \t\t\t\t\t/* Var belongs to some other table */","html":" \t\t\t\t\t\u003cspan class=pl-c\u003e/* Var belongs to some other table */\u003c/span\u003e","displayNoNewLineWarning":false,"position":36,"left":274,"right":278},{"stylingDirective":null,"type":"DELETION","blobLineNumber":275,"text":"-\t\t\t\t\tif (var-\u003evarcollid != InvalidOid \u0026\u0026","html":"-\t\t\t\t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003evar\u003c/span\u003e\u003cspan class=pl-c1\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=pl-c1\u003evarcollid\u003c/span\u003e \u003cspan class=pl-c1\u003e!=\u003c/span\u003e \u003cspan class=pl-s1\u003eInvalidOid\u003c/span\u003e \u003cspan class=pl-c1\u003e\u0026amp;\u0026amp;\u003c/span\u003e","displayNoNewLineWarning":false,"position":37,"left":275,"right":278},{"stylingDirective":null,"type":"DELETION","blobLineNumber":276,"text":"-\t\t\t\t\t\tvar-\u003evarcollid != DEFAULT_COLLATION_OID)","html":"-\t\t\t\t\t\t\u003cspan class=pl-s1\u003evar\u003c/span\u003e\u003cspan class=pl-c1\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=pl-c1\u003evarcollid\u003c/span\u003e \u003cspan class=pl-c1\u003e!=\u003c/span\u003e \u003cspan class=pl-c1\u003eDEFAULT_COLLATION_OID\u003c/span\u003e)","displayNoNewLineWarning":false,"position":38,"left":276,"right":278},{"stylingDirective":null,"type":"DELETION","blobLineNumber":277,"text":"-\t\t\t\t\t\treturn false;","html":"-\t\t\t\t\t\t\u003cspan class=pl-k\u003ereturn\u003c/span\u003e false;","displayNoNewLineWarning":false,"position":39,"left":277,"right":278},{"stylingDirective":null,"type":"DELETION","blobLineNumber":278,"text":"-","html":"-","displayNoNewLineWarning":false,"position":40,"left":278,"right":278},{"stylingDirective":null,"type":"DELETION","blobLineNumber":279,"text":"-\t\t\t\t\t/* We can consider that it doesn't set collation */","html":"-\t\t\t\t\t\u003cspan class=pl-c\u003e/* We can consider that it doesn\u0026#39;t set collation */\u003c/span\u003e","displayNoNewLineWarning":false,"position":41,"left":279,"right":278},{"stylingDirective":null,"type":"DELETION","blobLineNumber":280,"text":"-\t\t\t\t\tcollation = InvalidOid;","html":"-\t\t\t\t\t\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003eInvalidOid\u003c/span\u003e;","displayNoNewLineWarning":false,"position":42,"left":280,"right":278},{"stylingDirective":null,"type":"DELETION","blobLineNumber":281,"text":"-\t\t\t\t\tstate = FDW_COLLATE_NONE;","html":"-\t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":43,"left":281,"right":278},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":279,"text":"+\t\t\t\t\tcollation = var-\u003evarcollid;","html":"+\t\t\t\t\t\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003evar\u003c/span\u003e\u003cspan class=pl-c1\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=pl-c1\u003evarcollid\u003c/span\u003e;","displayNoNewLineWarning":false,"position":44,"left":281,"right":279},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":280,"text":"+\t\t\t\t\tif (collation == InvalidOid ||","html":"+\t\t\t\t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-s1\u003eInvalidOid\u003c/span\u003e \u003cspan class=pl-c1\u003e||\u003c/span\u003e","displayNoNewLineWarning":false,"position":45,"left":281,"right":280},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":281,"text":"+\t\t\t\t\t\tcollation == DEFAULT_COLLATION_OID)","html":"+\t\t\t\t\t\t\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eDEFAULT_COLLATION_OID\u003c/span\u003e)","displayNoNewLineWarning":false,"position":46,"left":281,"right":281},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":282,"text":"+\t\t\t\t\t{","html":"+\t\t\t\t\t{","displayNoNewLineWarning":false,"position":47,"left":281,"right":282},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":283,"text":"+\t\t\t\t\t\t/*","html":"+\t\t\t\t\t\t\u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":48,"left":281,"right":283},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":284,"text":"+\t\t\t\t\t\t * It's noncollatable, or it's safe to combine with a","html":"+\u003cspan class=pl-c\u003e\t\t\t\t\t\t * It\u0026#39;s noncollatable, or it\u0026#39;s safe to combine with a\u003c/span\u003e","displayNoNewLineWarning":false,"position":49,"left":281,"right":284},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":285,"text":"+\t\t\t\t\t\t * collatable foreign Var, so set state to NONE.","html":"+\u003cspan class=pl-c\u003e\t\t\t\t\t\t * collatable foreign Var, so set state to NONE.\u003c/span\u003e","displayNoNewLineWarning":false,"position":50,"left":281,"right":285},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":286,"text":"+\t\t\t\t\t\t */","html":"+\u003cspan class=pl-c\u003e\t\t\t\t\t\t */\u003c/span\u003e","displayNoNewLineWarning":false,"position":51,"left":281,"right":286},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":287,"text":"+\t\t\t\t\t\tstate = FDW_COLLATE_NONE;","html":"+\t\t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":52,"left":281,"right":287},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":288,"text":"+\t\t\t\t\t}","html":"+\t\t\t\t\t}","displayNoNewLineWarning":false,"position":53,"left":281,"right":288},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":289,"text":"+\t\t\t\t\telse","html":"+\t\t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e","displayNoNewLineWarning":false,"position":54,"left":281,"right":289},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":290,"text":"+\t\t\t\t\t{","html":"+\t\t\t\t\t{","displayNoNewLineWarning":false,"position":55,"left":281,"right":290},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":291,"text":"+\t\t\t\t\t\t/*","html":"+\t\t\t\t\t\t\u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":56,"left":281,"right":291},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":292,"text":"+\t\t\t\t\t\t * Do not fail right away, since the Var might appear","html":"+\u003cspan class=pl-c\u003e\t\t\t\t\t\t * Do not fail right away, since the Var might appear\u003c/span\u003e","displayNoNewLineWarning":false,"position":57,"left":281,"right":292},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":293,"text":"+\t\t\t\t\t\t * in a collation-insensitive context.","html":"+\u003cspan class=pl-c\u003e\t\t\t\t\t\t * in a collation-insensitive context.\u003c/span\u003e","displayNoNewLineWarning":false,"position":58,"left":281,"right":293},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":294,"text":"+\t\t\t\t\t\t */","html":"+\u003cspan class=pl-c\u003e\t\t\t\t\t\t */\u003c/span\u003e","displayNoNewLineWarning":false,"position":59,"left":281,"right":294},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":295,"text":"+\t\t\t\t\t\tstate = FDW_COLLATE_UNSAFE;","html":"+\t\t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_UNSAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":60,"left":281,"right":295},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":296,"text":"+\t\t\t\t\t}","html":"+\t\t\t\t\t}","displayNoNewLineWarning":false,"position":61,"left":281,"right":296},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":297,"text":" \t\t\t\t}","html":" \t\t\t\t}","displayNoNewLineWarning":false,"position":62,"left":282,"right":297},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":298,"text":" \t\t\t}","html":" \t\t\t}","displayNoNewLineWarning":false,"position":63,"left":283,"right":298},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":299,"text":" \t\t\tbreak;","html":" \t\t\t\u003cspan class=pl-k\u003ebreak\u003c/span\u003e;","displayNoNewLineWarning":false,"position":64,"left":284,"right":299},{"stylingDirective":null,"type":"HUNK","blobLineNumber":302,"text":"@@ -288,31 +303,31 @@ foreign_expr_walker(Node *node,","html":"@@ -288,31 +303,31 @@ foreign_expr_walker(Node *node,","displayNoNewLineWarning":false,"position":65,"left":287,"right":302},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":303,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":66,"left":288,"right":303},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":304,"text":" \t\t\t\t/*","html":" \t\t\t\t\u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":67,"left":289,"right":304},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":305,"text":" \t\t\t\t * If the constant has nondefault collation, either it's of a","html":" \u003cspan class=pl-c\u003e\t\t\t\t * If the constant has nondefault collation, either it\u0026#39;s of a\u003c/span\u003e","displayNoNewLineWarning":false,"position":68,"left":290,"right":305},{"stylingDirective":null,"type":"DELETION","blobLineNumber":291,"text":"-\t\t\t\t * non-builtin type, or it reflects folding of a CollateExpr;","html":"-\u003cspan class=pl-c\u003e\t\t\t\t * non-builtin type, or it reflects folding of a CollateExpr;\u003c/span\u003e","displayNoNewLineWarning":false,"position":69,"left":291,"right":305},{"stylingDirective":null,"type":"DELETION","blobLineNumber":292,"text":"-\t\t\t\t * either way, it's unsafe to send to the remote.","html":"-\u003cspan class=pl-c\u003e\t\t\t\t * either way, it\u0026#39;s unsafe to send to the remote.\u003c/span\u003e","displayNoNewLineWarning":false,"position":70,"left":292,"right":305},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":306,"text":"+\t\t\t\t * non-builtin type, or it reflects folding of a CollateExpr.","html":"+\u003cspan class=pl-c\u003e\t\t\t\t * non-builtin type, or it reflects folding of a CollateExpr.\u003c/span\u003e","displayNoNewLineWarning":false,"position":71,"left":292,"right":306},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":307,"text":"+\t\t\t\t * It's unsafe to send to the remote unless it's used in a","html":"+\u003cspan class=pl-c\u003e\t\t\t\t * It\u0026#39;s unsafe to send to the remote unless it\u0026#39;s used in a\u003c/span\u003e","displayNoNewLineWarning":false,"position":72,"left":292,"right":307},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":308,"text":"+\t\t\t\t * non-collation-sensitive context.","html":"+\u003cspan class=pl-c\u003e\t\t\t\t * non-collation-sensitive context.\u003c/span\u003e","displayNoNewLineWarning":false,"position":73,"left":292,"right":308},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":309,"text":" \t\t\t\t */","html":" \u003cspan class=pl-c\u003e\t\t\t\t */\u003c/span\u003e","displayNoNewLineWarning":false,"position":74,"left":293,"right":309},{"stylingDirective":null,"type":"DELETION","blobLineNumber":294,"text":"-\t\t\t\tif (c-\u003econstcollid != InvalidOid \u0026\u0026","html":"-\t\t\t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ec\u003c/span\u003e\u003cspan class=pl-c1\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=pl-c1\u003econstcollid\u003c/span\u003e \u003cspan class=pl-c1\u003e!=\u003c/span\u003e \u003cspan class=pl-s1\u003eInvalidOid\u003c/span\u003e \u003cspan class=pl-c1\u003e\u0026amp;\u0026amp;\u003c/span\u003e","displayNoNewLineWarning":false,"position":75,"left":294,"right":309},{"stylingDirective":null,"type":"DELETION","blobLineNumber":295,"text":"-\t\t\t\t\tc-\u003econstcollid != DEFAULT_COLLATION_OID)","html":"-\t\t\t\t\t\u003cspan class=pl-s1\u003ec\u003c/span\u003e\u003cspan class=pl-c1\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=pl-c1\u003econstcollid\u003c/span\u003e \u003cspan class=pl-c1\u003e!=\u003c/span\u003e \u003cspan class=pl-c1\u003eDEFAULT_COLLATION_OID\u003c/span\u003e)","displayNoNewLineWarning":false,"position":76,"left":295,"right":309},{"stylingDirective":null,"type":"DELETION","blobLineNumber":296,"text":"-\t\t\t\t\treturn false;","html":"-\t\t\t\t\t\u003cspan class=pl-k\u003ereturn\u003c/span\u003e false;","displayNoNewLineWarning":false,"position":77,"left":296,"right":309},{"stylingDirective":null,"type":"DELETION","blobLineNumber":297,"text":"-","html":"-","displayNoNewLineWarning":false,"position":78,"left":297,"right":309},{"stylingDirective":null,"type":"DELETION","blobLineNumber":298,"text":"-\t\t\t\t/* Otherwise, we can consider that it doesn't set collation */","html":"-\t\t\t\t\u003cspan class=pl-c\u003e/* Otherwise, we can consider that it doesn\u0026#39;t set collation */\u003c/span\u003e","displayNoNewLineWarning":false,"position":79,"left":298,"right":309},{"stylingDirective":null,"type":"DELETION","blobLineNumber":299,"text":"-\t\t\t\tcollation = InvalidOid;","html":"-\t\t\t\t\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003eInvalidOid\u003c/span\u003e;","displayNoNewLineWarning":false,"position":80,"left":299,"right":309},{"stylingDirective":null,"type":"DELETION","blobLineNumber":300,"text":"-\t\t\t\tstate = FDW_COLLATE_NONE;","html":"-\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":81,"left":300,"right":309},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":310,"text":"+\t\t\t\tcollation = c-\u003econstcollid;","html":"+\t\t\t\t\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003ec\u003c/span\u003e\u003cspan class=pl-c1\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=pl-c1\u003econstcollid\u003c/span\u003e;","displayNoNewLineWarning":false,"position":82,"left":300,"right":310},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":311,"text":"+\t\t\t\tif (collation == InvalidOid ||","html":"+\t\t\t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-s1\u003eInvalidOid\u003c/span\u003e \u003cspan class=pl-c1\u003e||\u003c/span\u003e","displayNoNewLineWarning":false,"position":83,"left":300,"right":311},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":312,"text":"+\t\t\t\t\tcollation == DEFAULT_COLLATION_OID)","html":"+\t\t\t\t\t\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eDEFAULT_COLLATION_OID\u003c/span\u003e)","displayNoNewLineWarning":false,"position":84,"left":300,"right":312},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":313,"text":"+\t\t\t\t\tstate = FDW_COLLATE_NONE;","html":"+\t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":85,"left":300,"right":313},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":314,"text":"+\t\t\t\telse","html":"+\t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e","displayNoNewLineWarning":false,"position":86,"left":300,"right":314},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":315,"text":"+\t\t\t\t\tstate = FDW_COLLATE_UNSAFE;","html":"+\t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_UNSAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":87,"left":300,"right":315},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":316,"text":" \t\t\t}","html":" \t\t\t}","displayNoNewLineWarning":false,"position":88,"left":301,"right":316},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":317,"text":" \t\t\tbreak;","html":" \t\t\t\u003cspan class=pl-k\u003ebreak\u003c/span\u003e;","displayNoNewLineWarning":false,"position":89,"left":302,"right":317},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":318,"text":" \t\tcase T_Param:","html":" \t\t\u003cspan class=pl-k\u003ecase\u003c/span\u003e \u003cspan class=pl-s1\u003eT_Param\u003c/span\u003e:","displayNoNewLineWarning":false,"position":90,"left":303,"right":318},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":319,"text":" \t\t\t{","html":" \t\t\t{","displayNoNewLineWarning":false,"position":91,"left":304,"right":319},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":320,"text":" \t\t\t\tParam\t *p = (Param *) node;","html":" \t\t\t\t\u003cspan class=pl-smi\u003eParam\u003c/span\u003e\t \u003cspan class=pl-c1\u003e*\u003c/span\u003e\u003cspan class=pl-s1\u003ep\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e (\u003cspan class=pl-smi\u003eParam\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e) \u003cspan class=pl-s1\u003enode\u003c/span\u003e;","displayNoNewLineWarning":false,"position":92,"left":305,"right":320},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":321,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":93,"left":306,"right":321},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":322,"text":" \t\t\t\t/*","html":" \t\t\t\t\u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":94,"left":307,"right":322},{"stylingDirective":null,"type":"DELETION","blobLineNumber":308,"text":"-\t\t\t\t * Collation handling is same as for Consts.","html":"-\u003cspan class=\"pl-c\"\u003e\t\t\t\t * Collation \u003cspan class=\"x x-first x-last\"\u003ehandling\u003c/span\u003e is same as for Consts.\u003c/span\u003e","displayNoNewLineWarning":false, 8000 "position":95,"left":308,"right":322},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":323,"text":"+\t\t\t\t * Collation rule is same as for Consts and non-foreign Vars.","html":"+\u003cspan class=\"pl-c\"\u003e\t\t\t\t * Collation \u003cspan class=\"x x-first x-last\"\u003erule\u003c/span\u003e is same as for Consts\u003cspan class=\"x x-first x-last\"\u003e and non-foreign Vars\u003c/span\u003e.\u003c/span\u003e","displayNoNewLineWarning":false,"position":96,"left":308,"right":323},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":324,"text":" \t\t\t\t */","html":" \u003cspan class=pl-c\u003e\t\t\t\t */\u003c/span\u003e","displayNoNewLineWarning":false,"position":97,"left":309,"right":324},{"stylingDirective":null,"type":"DELETION","blobLineNumber":310,"text":"-\t\t\t\tif (p-\u003eparamcollid != InvalidOid \u0026\u0026","html":"-\t\t\t\t\u003cspan class=\"pl-k x x-first\"\u003eif\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e (\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ep\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eparamcollid\u003c/span\u003e\u003cspan class=\"x x-first\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e!=\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003eInvalidOid\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x x-last\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e","displayNoNewLineWarning":false,"position":98,"left":310,"right":324},{"stylingDirective":null,"type":"DELETION","blobLineNumber":311,"text":"-\t\t\t\t\tp-\u003eparamcollid != DEFAULT_COLLATION_OID)","html":"-\t\t\t\t\u003cspan class=\"x x-first\"\u003e\t\u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003ep\u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003eparamcollid\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e!=\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003eDEFAULT_COLLATION_OID\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e)\u003c/span\u003e","displayNoNewLineWarning":false,"position":99,"left":311,"right":324},{"stylingDirective":null,"type":"DELETION","blobLineNumber":312,"text":"-\t\t\t\t\treturn false;","html":"-\t\t\t\t\t\u003cspan class=\"pl-k x x-first\"\u003ereturn\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e false;\u003c/span\u003e","displayNoNewLineWarning":false,"position":100,"left":312,"right":324},{"stylingDirective":null,"type":"DELETION","blobLineNumber":313,"text":"-","html":"-","displayNoNewLineWarning":false,"position":101,"left":313,"right":324},{"stylingDirective":null,"type":"DELETION","blobLineNumber":314,"text":"-\t\t\t\tcollation = InvalidOid;","html":"-\t\t\t\t\u003cspan class=\"pl-s1 x x-first\"\u003ecollation\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e=\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003eInvalidOid\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":102,"left":314,"right":324},{"stylingDirective":null,"type":"DELETION","blobLineNumber":315,"text":"-\t\t\t\tstate = FDW_COLLATE_NONE;","html":"-\t\t\t\t\u003cspan class=\"pl-s1\"\u003estate\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1 x x-first x-last\"\u003eFDW_COLLATE_NONE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":103,"left":315,"right":324},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":325,"text":"+\t\t\t\tcollation = p-\u003eparamcollid;","html":"+\t\t\t\t\u003cspan class=\"pl-s1 x x-first\"\u003ecollation\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e=\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e \u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ep\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eparamcollid\u003c/span\u003e\u003cspan class=\"x x-first x-last\"\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":104,"left":315,"right":325},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":326,"text":"+\t\t\t\tif (collation == InvalidOid ||","html":"+\t\t\t\t\u003cspan class=\"pl-k x x-first\"\u003eif\u003c/span\u003e\u003cspan class=\"x\"\u003e (\u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003ecollation\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e==\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003eInvalidOid\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x x-last\"\u003e||\u003c/span\u003e","displayNoNewLineWarning":false,"position":105,"left":315,"right":326},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":327,"text":"+\t\t\t\t\tcollation == DEFAULT_COLLATION_OID)","html":"+\t\t\t\t\t\u003cspan class=\"pl-s1 x x-first\"\u003ecollation\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e==\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003eDEFAULT_COLLATION_OID\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e)\u003c/span\u003e","displayNoNewLineWarning":false,"position":106,"left":315,"right":327},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":328,"text":"+\t\t\t\t\tstate = FDW_COLLATE_NONE;","html":"+\u003cspan class=\"x x-first\"\u003e\t\t\t\t\t\u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003estate\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e=\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003eFDW_COLLATE_NONE\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":107,"left":315,"right":328},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":329,"text":"+\t\t\t\telse","html":"+\t\t\t\t\u003cspan class=\"pl-k x x-first x-last\"\u003eelse\u003c/span\u003e","displayNoNewLineWarning":false,"position":108,"left":315,"right":329},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":330,"text":"+\t\t\t\t\tstate = FDW_COLLATE_UNSAFE;","html":"+\t\t\t\t\u003cspan class=\"x x-first x-last\"\u003e\t\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003estate\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1 x x-first x-last\"\u003eFDW_COLLATE_UNSAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":109,"left":315,"right":330},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":331,"text":" \t\t\t}","html":" \t\t\t}","displayNoNewLineWarning":false,"position":110,"left":316,"right":331},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":332,"text":" \t\t\tbreak;","html":" \t\t\t\u003cspan class=pl-k\u003ebreak\u003c/span\u003e;","displayNoNewLineWarning":false,"position":111,"left":317,"right":332},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":333,"text":" \t\tcase T_ArrayRef:","html":" \t\t\u003cspan class=pl-k\u003ecase\u003c/span\u003e \u003cspan class=pl-s1\u003eT_ArrayRef\u003c/span\u003e:","displayNoNewLineWarning":false,"position":112,"left":318,"right":333},{"stylingDirective":null,"type":"HUNK","blobLineNumber":362,"text":"@@ -348,6 +363,8 @@ foreign_expr_walker(Node *node,","html":"@@ -348,6 +363,8 @@ foreign_expr_walker(Node *node,","displayNoNewLineWarning":false,"position":113,"left":347,"right":362},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":363,"text":" \t\t\t\telse if (inner_cxt.state == FDW_COLLATE_SAFE \u0026\u0026","html":" \t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e \u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003einner_cxt\u003c/span\u003e.\u003cspan class=pl-c1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_SAFE\u003c/span\u003e \u003cspan class=pl-c1\u003e\u0026amp;\u0026amp;\u003c/span\u003e","displayNoNewLineWarning":false,"position":114,"left":348,"right":363},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":364,"text":" \t\t\t\t\t\t collation == inner_cxt.collation)","html":" \t\t\t\t\t\t \u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-s1\u003einner_cxt\u003c/span\u003e.\u003cspan class=pl-c1\u003ecollation\u003c/span\u003e)","displayNoNewLineWarning":false,"position":115,"left":349,"right":364},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":365,"text":" \t\t\t\t\tstate = FDW_COLLATE_SAFE;","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_SAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":116,"left":350,"right":365},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":366,"text":"+\t\t\t\telse if (collation == DEFAULT_COLLATION_OID)","html":"+\t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e \u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eDEFAULT_COLLATION_OID\u003c/span\u003e)","displayNoNewLineWarning":false,"position":117,"left":350,"right":366},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":367,"text":"+\t\t\t\t\tstate = FDW_COLLATE_NONE;","html":"+\t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":118,"left":350,"right":367},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":368,"text":" \t\t\t\telse","html":" \t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e","displayNoNewLineWarning":false,"position":119,"left":351,"right":368},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":369,"text":" \t\t\t\t\tstate = FDW_COLLATE_UNSAFE;","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_UNSAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":120,"left":352,"right":369},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":370,"text":" \t\t\t}","html":" \t\t\t}","displayNoNewLineWarning":false,"position":121,"left":353,"right":370},{"stylingDirective":null,"type":"HUNK","blobLineNumber":409,"text":"@@ -393,6 +410,8 @@ foreign_expr_walker(Node *node,","html":"@@ -393,6 +410,8 @@ foreign_expr_walker(Node *node,","displayNoNewLineWarning":false,"position":122,"left":392,"right":409},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":410,"text":" \t\t\t\telse if (inner_cxt.state == FDW_COLLATE_SAFE \u0026\u0026","html":" \t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e \u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003einner_cxt\u003c/span\u003e.\u003cspan class=pl-c1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_SAFE\u003c/span\u003e \u003cspan class=pl-c1\u003e\u0026amp;\u0026amp;\u003c/span\u003e","displayNoNewLineWarning":false,"position":123,"left":393,"right":410},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":411,"text":" \t\t\t\t\t\t collation == inner_cxt.collation)","html":" \t\t\t\t\t\t \u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-s1\u003einner_cxt\u003c/span\u003e.\u003cspan class=pl-c1\u003ecollation\u003c/span\u003e)","displayNoNewLineWarning":false,"position":124,"left":394,"right":411},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":412,"text":" \t\t\t\t\tstate = FDW_COLLATE_SAFE;","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_SAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":125,"left":395,"right":412},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":413,"text":"+\t\t\t\telse if (collation == DEFAULT_COLLATION_OID)","html":"+\t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e \u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eDEFAULT_COLLATION_OID\u003c/span\u003e)","displayNoNewLineWarning":false,"position":126,"left":395,"right":413},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":414,"text":"+\t\t\t\t\tstate = FDW_COLLATE_NONE;","html":"+\t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":127,"left":395,"right":414},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":415,"text":" \t\t\t\telse","html":" \t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e","displayNoNewLineWarning":false,"position":128,"left":396,"right":415},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":416,"text":" \t\t\t\t\tstate = FDW_COLLATE_UNSAFE;","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_UNSAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":129,"left":397,"right":416},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":417,"text":" \t\t\t}","html":" \t\t\t}","displayNoNewLineWarning":false,"position":130,"left":398,"right":417},{"stylingDirective":null,"type":"HUNK","blobLineNumber":452,"text":"@@ -434,6 +453,8 @@ foreign_expr_walker(Node *node,","html":"@@ -434,6 +453,8 @@ foreign_expr_walker(Node *node,","displayNoNewLineWarning":false,"position":131,"left":433,"right":452},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":453,"text":" \t\t\t\telse if (inner_cxt.state == FDW_COLLATE_SAFE \u0026\u0026","html":" \t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e \u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003einner_cxt\u003c/span\u003e.\u003cspan class=pl-c1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_SAFE\u003c/span\u003e \u003cspan class=pl-c1\u003e\u0026amp;\u0026amp;\u003c/span\u003e","displayNoNewLineWarning":false,"position":132,"left":434,"right":453},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":454,"text":" \t\t\t\t\t\t collation == inner_cxt.collation)","html":" \t\t\t\t\t\t \u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-s1\u003einner_cxt\u003c/span\u003e.\u003cspan class=pl-c1\u003ecollation\u003c/span\u003e)","displayNoNewLineWarning":false,"position":133,"left":435,"right":454},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":455,"text":" \t\t\t\t\tstate = FDW_COLLATE_SAFE;","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_SAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":134,"left":436,"right":455},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":456,"text":"+\t\t\t\telse if (collation == DEFAULT_COLLATION_OID)","html":"+\t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e \u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eDEFAULT_COLLATION_OID\u003c/span\u003e)","displayNoNewLineWarning":false,"position":135,"left":436,"right":456},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":457,"text":"+\t\t\t\t\tstate = FDW_COLLATE_NONE;","html":"+\t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":136,"left":436,"right":457},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":458,"text":" \t\t\t\telse","html":" \t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e","displayNoNewLineWarning":false,"position":137,"left":437,"right":458},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":459,"text":" \t\t\t\t\tstate = FDW_COLLATE_UNSAFE;","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_UNSAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":138,"left":438,"right":459},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":460,"text":" \t\t\t}","html":" \t\t\t}","displayNoNewLineWarning":false,"position":139,"left":439,"right":460},{"stylingDirective":null,"type":"HUNK","blobLineNumber":503,"text":"@@ -483,14 +504,16 @@ foreign_expr_walker(Node *node,","html":"@@ -483,14 +504,16 @@ foreign_expr_walker(Node *node,","displayNoNewLineWarning":false,"position":140,"left":482,"right":503},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":504,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":141,"left":483,"right":504},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":505,"text":" \t\t\t\t/*","html":" \t\t\t\t\u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":142,"left":484,"right":505},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":506,"text":" \t\t\t\t * RelabelType must not introduce a collation not derived from","html":" \u003cspan class=pl-c\u003e\t\t\t\t * RelabelType must not introduce a collation not derived from\u003c/span\u003e","displayNoNewLineWarning":false,"position":143,"left":485,"right":506},{"stylingDirective":null,"type":"DELETION","blobLineNumber":486,"text":"-\t\t\t\t * an input foreign Var.","html":"-\u003cspan class=\"pl-c\"\u003e\t\t\t\t * an input foreign Var.\u003c/span\u003e","displayNoNewLineWarning":false,"position":144,"left":486,"right":506},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":507,"text":"+\t\t\t\t * an input foreign Var (same logic as for a real function).","html":"+\u003cspan class=\"pl-c\"\u003e\t\t\t\t * an input foreign Var\u003cspan class=\"x x-first x-last\"\u003e (same logic as for a real function)\u003c/span\u003e.\u003c/span\u003e","displayNoNewLineWarning":false,"position":145,"left":486,"right":507},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":508,"text":" \t\t\t\t */","html":" \u003cspan class=pl-c\u003e\t\t\t\t */\u003c/span\u003e","displayNoNewLineWarning":false,"position":146,"left":487,"right":508},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":509,"text":" \t\t\t\tcollation = r-\u003eresultcollid;","html":" \t\t\t\t\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003er\u003c/span\u003e\u003cspan class=pl-c1\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=pl-c1\u003eresultcollid\u003c/span\u003e;","displayNoNewLineWarning":false,"position":147,"left":488,"right":509},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":510,"text":" \t\t\t\tif (collation == InvalidOid)","html":" \t\t\t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-s1\u003eInvalidOid\u003c/span\u003e)","displayNoNewLineWarning":false,"position":148,"left":489,"right":510},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":511,"text":" \t\t\t\t\tstate = FDW_COLLATE_NONE;","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":149,"left":490,"right":511},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":512,"text":" \t\t\t\telse if (inner_cxt.state == FDW_COLLATE_SAFE \u0026\u0026","html":" \t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e \u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003einner_cxt\u003c/span\u003e.\u003cspan class=pl-c1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_SAFE\u003c/span\u003e \u003cspan class=pl-c1\u003e\u0026amp;\u0026amp;\u003c/span\u003e","displayNoNewLineWarning":false,"position":150,"left":491,"right":512},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":513,"text":" \t\t\t\t\t\t collation == inner_cxt.collation)","html":" \t\t\t\t\t\t \u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-s1\u003einner_cxt\u003c/span\u003e.\u003cspan class=pl-c1\u003ecollation\u003c/span\u003e)","displayNoNewLineWarning":false,"position":151,"left":492,"right":513},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":514,"text":" \t\t\t\t\tstate = FDW_COLLATE_SAFE;","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_SAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":152,"left":493,"right":514},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":515,"text":"+\t\t\t\telse if (collation == DEFAULT_COLLATION_OID)","html":"+\t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e \u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eDEFAULT_COLLATION_OID\u003c/span\u003e)","displayNoNewLineWarning":false,"position":153,"left":493,"right":515},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":516,"text":"+\t\t\t\t\tstate = FDW_COLLATE_NONE;","html":"+\t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":154,"left":493,"right":516},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":517,"text":" \t\t\t\telse","html":" \t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e","displayNoNewLineWarning":false,"position":155,"left":494,"right":517},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":518,"text":" \t\t\t\t\tstate = FDW_COLLATE_UNSAFE;","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_UNSAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":156,"left":495,"right":518},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":519,"text":" \t\t\t}","html":" \t\t\t}","displayNoNewLineWarning":false,"position":157,"left":496,"right":519},{"stylingDirective":null,"type":"HUNK","blobLineNumber":562,"text":"@@ -540,14 +563,16 @@ foreign_expr_walker(Node *node,","html":"@@ -540,14 +563,16 @@ foreign_expr_walker(Node *node,","displayNoNewLineWarning":false,"position":158,"left":539,"right":562},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":563,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":159,"left":540,"right":563},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":564,"text":" \t\t\t\t/*","html":" \t\t\t\t\u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":160,"left":541,"right":564},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":565,"text":" \t\t\t\t * ArrayExpr must not introduce a collation not derived from","html":" \u003cspan class=pl-c\u003e\t\t\t\t * ArrayExpr must not introduce a collation not derived from\u003c/span\u003e","displayNoNewLineWarning":false,"position":161,"left":542,"right":565},{"stylingDirective":null,"type":"DELETION","blobLineNumber":543,"text":"-\t\t\t\t * an input foreign Var.","html":"-\u003cspan class=\"pl-c\"\u003e\t\t\t\t * an input foreign Var.\u003c/span\u003e","displayNoNewLineWarning":false,"position":162,"left":543,"right":565},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":566,"text":"+\t\t\t\t * an input foreign Var (same logic as for a function).","html":"+\u003cspan class=\"pl-c\"\u003e\t\t\t\t * an input foreign Var\u003cspan class=\"x x-first x-last\"\u003e (same logic as for a function)\u003c/span\u003e.\u003c/span\u003e","displayNoNewLineWarning":false,"position":163,"left":543,"right":566},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":567,"text":" \t\t\t\t */","html":" \u003cspan class=pl-c\u003e\t\t\t\t */\u003c/span\u003e","displayNoNewLineWarning":false,"position":164,"left":544,"right":567},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":568,"text":" \t\t\t\tcollation = a-\u003earray_collid;","html":" \t\t\t\t\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003ea\u003c/span\u003e\u003cspan class=pl-c1\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=pl-c1\u003earray_collid\u003c/span\u003e;","displayNoNewLineWarning":false,"position":165,"left":545,"right":568},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":569,"text":" \t\t\t\tif (collation == InvalidOid)","html":" \t\t\t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-s1\u003eInvalidOid\u003c/span\u003e)","displayNoNewLineWarning":false,"position":166,"left":546,"right":569},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":570,"text":" \t\t\t\t\tstate = FDW_COLLATE_NONE;","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":167,"left":547,"right":570},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":571,"text":" \t\t\t\telse if (inner_cxt.state == FDW_COLLATE_SAFE \u0026\u0026","html":" \t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e \u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003einner_cxt\u003c/span\u003e.\u003cspan class=pl-c1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_SAFE\u003c/span\u003e \u003cspan class=pl-c1\u003e\u0026amp;\u0026amp;\u003c/span\u003e","displayNoNewLineWarning":false,"position":168,"left":548,"right":571},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":572,"text":" \t\t\t\t\t\t collation == inner_cxt.collation)","html":" \t\t\t\t\t\t \u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-s1\u003einner_cxt\u003c/span\u003e.\u003cspan class=pl-c1\u003ecollation\u003c/span\u003e)","displayNoNewLineWarning":false,"position":169,"left":549,"right":572},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":573,"text":" \t\t\t\t\tstate = FDW_COLLATE_SAFE;","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_SAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":170,"left":550,"right":573},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":574,"text":"+\t\t\t\telse if (collation == DEFAULT_COLLATION_OID)","html":"+\t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e \u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ecollation\u003c/span\u003e \u003cspan class=pl-c1\u003e==\u003c/span\u003e \u003cspan class=pl-c1\u003eDEFAULT_COLLATION_OID\u003c/span\u003e)","displayNoNewLineWarning":false,"position":171,"left":550,"right":574},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":575,"text":"+\t\t\t\t\tstate = FDW_COLLATE_NONE;","html":"+\t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_NONE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":172,"left":550,"right":575},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":576,"text":" \t\t\t\telse","html":" \t\t\t\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e","displayNoNewLineWarning":false,"position":173,"left":551,"right":576},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":577,"text":" \t\t\t\t\tstate = FDW_COLLATE_UNSAFE;","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003estate\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-c1\u003eFDW_COLLATE_UNSAFE\u003c/span\u003e;","displayNoNewLineWarning":false,"position":174,"left":552,"right":577},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":578,"text":" \t\t\t}","html":" \t\t\t}","displayNoNewLineWarning":false,"position":175,"left":553,"right":578}],"diffNumber":0,"diffSize":"0 Bytes","isBinary":false,"isTooBig":false,"collapsed":false,"isSubmodule":false,"lineCount":1879,"linesChanged":89,"newTreeEntry":{"lineCount":1879,"path":"contrib/postgres_fdw/deparse.c","mode":100644,"isGenerated":false},"oldTreeEntry":{"lineCount":0,"path":"contrib/postgres_fdw/deparse.c","mode":100644},"linesAdded":57,"linesDeleted":32,"path":"contrib/postgres_fdw/deparse.c","pathDigest":"9ed7bda5944d72f1491da1c7311ee42afabee85028b71a3cfd978039877a2c2d","status":"MODIFIED","truncatedReason":null,"oldOid":"9f1255ac859364a86264a67729dbd1a36dd63ff2","newOid":"76f965ff1f2896d74812a1cad9158fb9f4a1aab9","copilotChatReference":null,"deletedSha":"9f1255ac859364a86264a67729dbd1a36dd63ff2","canToggleRichDiff":false,"defaultToRichDiff":false,"proseDifffHtml":null,"renderInfo":null,"dependencyDiffPath":null,"submodule":null},{"diffLines":[{"stylingDirective":null,"type":"HUNK","blobLineNumber":1004,"text":"@@ -1005,71 +1005,110 @@ COMMIT;","html":"@@ -1005,71 +1005,110 @@ COMMIT;","displayNoNewLineWarning":false,"position":0,"left":1004,"right":1004},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1005,"text":" -- ===================================================================","html":" -- ===================================================================","displayNoNewLineWarning":false,"position":1,"left":1005,"right":1005},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1006,"text":" -- test handling of collations","html":" -- test handling of collations","displayNoNewLineWarning":false,"position":2,"left":1006,"right":1006},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1007,"text":" -- ===================================================================","html":" -- ===================================================================","displayNoNewLineWarning":false,"position":3,"left":1007,"right":1007},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1008,"text":"-create table loct3 (f1 text collate \"C\", f2 text);","html":"-create table loct3 (f1 text collate \u0026quot;C\u0026quot;, f2 text);","displayNoNewLineWarning":false,"position":4,"left":1008,"right":1007},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1009,"text":"-create foreign table ft3 (f1 text collate \"C\", f2 text)","html":"-create foreign table ft3 (f1 text collate \u0026quot;C\u0026quot;, f2 text)","displayNoNewLineWarning":false,"position":5,"left":1009,"right":1007},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1010,"text":"- server loopback options (table_name 'loct3');","html":"- server loopback options (table_name \u0026#39;loct3\u0026#39;);","displayNoNewLineWarning":false,"position":6,"left":1010,"right":1007},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1008,"text":"+create table loct3 (f1 text collate \"C\" unique, f2 text, f3 varchar(10) unique);","html":"+create table loct3 (f1 text collate \u0026quot;C\u0026quot;\u003cspan class=\"x x-first x-last\"\u003e unique\u003c/span\u003e, f2 text\u003cspan class=\"x x-first x-last\"\u003e, f3 varchar(10) unique\u003c/span\u003e);","displayNoNewLineWarning":false,"position":7,"left":1010,"right":1008},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1009,"text":"+create foreign tab 8000 le ft3 (f1 text collate \"C\", f2 text, f3 varchar(10))","html":"+create foreign table ft3 (f1 text collate \u0026quot;C\u0026quot;, f2 text\u003cspan class=\"x x-first x-last\"\u003e, f3 varchar(10)\u003c/span\u003e)","displayNoNewLineWarning":false,"position":8,"left":1010,"right":1009},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1010,"text":"+ server loopback options (table_name 'loct3', use_remote_estimate 'true');","html":"+ server loopback options (table_name \u0026#39;loct3\u0026#39;\u003cspan class=\"x x-first x-last\"\u003e, use_remote_estimate \u0026#39;true\u0026#39;\u003c/span\u003e);","displayNoNewLineWarning":false,"position":9,"left":1010,"right":1010},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1011,"text":" -- can be sent to remote","html":" -- can be sent to remote","displayNoNewLineWarning":false,"position":10,"left":1011,"right":1011},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1012,"text":" explain (verbose, costs off) select * from ft3 where f1 = 'foo';","html":" explain (verbose, costs off) select * from ft3 where f1 = \u0026#39;foo\u0026#39;;","displayNoNewLineWarning":false,"position":11,"left":1012,"right":1012},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1013,"text":"- QUERY PLAN ","html":"- QUERY PLAN ","displayNoNewLineWarning":false,"position":12,"left":1013,"right":1012},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1014,"text":"---------------------------------------------------------------------------","html":"---------------------------------------------------------------------------","displayNoNewLineWarning":false,"position":13,"left":1014,"right":1012},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1013,"text":"+ QUERY PLAN ","html":"+ \u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003eQUERY PLAN\u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003e ","displayNoNewLineWarning":false,"position":14,"left":1014,"right":1013},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1014,"text":"+------------------------------------------------------------------------------","html":"+--------------------------------------------------------------------------\u003cspan class=\"x x-first x-last\"\u003e----\u003c/span\u003e","displayNoNewLineWarning":false,"position":15,"left":1014,"right":1014},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1015,"text":" Foreign Scan on public.ft3","html":" Foreign Scan on public.ft3","displayNoNewLineWarning":false,"position":16,"left":1015,"right":1015},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1016,"text":"- Output: f1, f2","html":"- Output: f1, f2","displayNoNewLineWarning":false,"position":17,"left":1016,"right":1015},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1017,"text":"- Remote SQL: SELECT f1, f2 FROM public.loct3 WHERE ((f1 = 'foo'::text))","html":"- Remote SQL: SELECT f1, f2 FROM public.loct3 WHERE ((f1 = \u0026#39;foo\u0026#39;::text))","displayNoNewLineWarning":false,"position":18,"left":1017,"right":1015},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1016,"text":"+ Output: f1, f2, f3","html":"+ Output: f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e","displayNoNewLineWarning":false,"position":19,"left":1017,"right":1016},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1017,"text":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f1 = 'foo'::text))","html":"+ Remote SQL: SELECT f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e FROM public.loct3 WHERE ((f1 = \u0026#39;foo\u0026#39;::text))","displayNoNewLineWarning":false,"position":20,"left":1017,"right":1017},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1018,"text":" (3 rows)","html":" (3 rows)","displayNoNewLineWarning":false,"position":21,"left":1018,"right":1018},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1019,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":22,"left":1019,"right":1019},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1020,"text":" explain (verbose, costs off) select * from ft3 where f1 COLLATE \"C\" = 'foo';","html":" explain (verbose, costs off) select * from ft3 where f1 COLLATE \u0026quot;C\u0026quot; = \u0026#39;foo\u0026#39;;","displayNoNewLineWarning":false,"position":23,"left":1020,"right":1020},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1021,"text":"- QUERY PLAN ","html":"- QUERY PLAN ","displayNoNewLineWarning":false,"position":24,"left":1021,"right":1020},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1022,"text":"---------------------------------------------------------------------------","html":"---------------------------------------------------------------------------","displayNoNewLineWarning":false,"position":25,"left":1022,"right":1020},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1021,"text":"+ QUERY PLAN ","html":"+ \u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003eQUERY PLAN\u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003e ","displayNoNewLineWarning":false,"position":26,"left":1022,"right":1021},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1022,"text":"+------------------------------------------------------------------------------","html":"+--------------------------------------------------------------------------\u003cspan class=\"x x-first x-last\"\u003e----\u003c/span\u003e","displayNoNewLineWarning":false,"position":27,"left":1022,"right":1022},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1023,"text":" Foreign Scan on public.ft3","html":" Foreign Scan on public.ft3","displayNoNewLineWarning":false,"position":28,"left":1023,"right":1023},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1024,"text":"- Output: f1, f2","html":"- Output: f1, f2","displayNoNewLineWarning":false,"position":29,"left":1024,"right":1023},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1025,"text":"- Remote SQL: SELECT f1, f2 FROM public.loct3 WHERE ((f1 = 'foo'::text))","html":"- Remote SQL: SELECT f1, f2 FROM public.loct3 WHERE ((f1 = \u0026#39;foo\u0026#39;::text))","displayNoNewLineWarning":false,"position":30,"left":1025,"right":1023},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1024,"text":"+ Output: f1, f2, f3","html":"+ Output: f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e","displayNoNewLineWarning":false,"position":31,"left":1025,"right":1024},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1025,"text":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f1 = 'foo'::text))","html":"+ Remote SQL: SELECT f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e FROM public.loct3 WHERE ((f1 = \u0026#39;foo\u0026#39;::text))","displayNoNewLineWarning":false,"position":32,"left":1025,"right":1025},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1026,"text":" (3 rows)","html":" (3 rows)","displayNoNewLineWarning":false,"position":33,"left":1026,"right":1026},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1027,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":34,"left":1027,"right":1027},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1028,"text":" explain (verbose, costs off) select * from ft3 where f2 = 'foo';","html":" explain (verbose, costs off) select * from ft3 where f2 = \u0026#39;foo\u0026#39;;","displayNoNewLineWarning":false,"position":35,"left":1028,"right":1028},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1029,"text":"- QUERY PLAN ","html":"- QUERY PLAN ","displayNoNewLineWarning":false,"position":36,"left":1029,"right":1028},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1030,"text":"---------------------------------------------------------------------------","html":"---------------------------------------------------------------------------","displayNoNewLineWarning":false,"position":37,"left":1030,"right":1028},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1029,"text":"+ QUERY PLAN ","html":"+ \u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003eQUERY PLAN\u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003e ","displayNoNewLineWarning":false,"position":38,"left":1030,"right":1029},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1030,"text":"+------------------------------------------------------------------------------","html":"+--------------------------------------------------------------------------\u003cspan class=\"x x-first x-last\"\u003e----\u003c/span\u003e","displayNoNewLineWarning":false,"position":39,"left":1030,"right":1030},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1031,"text":" Foreign Scan on public.ft3","html":" Foreign Scan on public.ft3","displayNoNewLineWarning":false,"position":40,"left":1031,"right":1031},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1032,"text":"- Output: f1, f2","html":"- Output: f1, f2","displayNoNewLineWarning":false,"position":41,"left":1032,"right":1031},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1033,"text":"- Remote SQL: SELECT f1, f2 FROM public.loct3 WHERE ((f2 = 'foo'::text))","html":"- Remote SQL: SELECT f1, f2 FROM public.loct3 WHERE ((f2 = \u0026#39;foo\u0026#39;::text))","displayNoNewLineWarning":false,"position":42,"left":1033,"right":1031},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1032,"text":"+ Output: f1, f2, f3","html":"+ Output: f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e","displayNoNewLineWarning":false,"position":43,"left":1033,"right":1032},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1033,"text":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f2 = 'foo'::text))","html":"+ Remote SQL: SELECT f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e FROM public.loct3 WHERE ((f2 = \u0026#39;foo\u0026#39;::text))","displayNoNewLineWarning":false,"position":44,"left":1033,"right":1033},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1034,"text":" (3 rows)","html":" (3 rows)","displayNoNewLineWarning":false,"position":45,"left":1034,"right":1034},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1035,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":46,"left":1035,"right":1035},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1036,"text":"+explain (verbose, costs off) select * from ft3 where f3 = 'foo';","html":"+explain (verbose, costs off) select * from ft3 where f3 = \u0026#39;foo\u0026#39;;","displayNoNewLineWarning":false,"position":47,"left":1035,"right":1036},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1037,"text":"+ QUERY PLAN ","html":"+ QUERY PLAN ","displayNoNewLineWarning":false,"position":48,"left":1035,"right":1037},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1038,"text":"+------------------------------------------------------------------------------","html":"+------------------------------------------------------------------------------","displayNoNewLineWarning":false,"position":49,"left":1035,"right":1038},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1039,"text":"+ Foreign Scan on public.ft3","html":"+ Foreign Scan on public.ft3","displayNoNewLineWarning":false,"position":50,"left":1035,"right":1039},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1040,"text":"+ Output: f1, f2, f3","html":"+ Output: f1, f2, f3","displayNoNewLineWarning":false,"position":51,"left":1035,"right":1040},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1041,"text":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f3 = 'foo'::text))","html":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f3 = \u0026#39;foo\u0026#39;::text))","displayNoNewLineWarning":false,"position":52,"left":1035,"right":1041},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1042,"text":"+(3 rows)","html":"+(3 rows)","displayNoNewLineWarning":false,"position":53,"left":1035,"right":1042},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1043,"text":"+","html":"+","displayNoNewLineWarning":false,"position":54,"left":1035,"right":1043},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1044,"text":"+explain (verbose, costs off) select * from ft3 f, loct3 l","html":"+explain (verbose, costs off) select * from ft3 f, loct3 l","displayNoNewLineWarning":false,"position":55,"left":1035,"right":1044},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1045,"text":"+ where f.f3 = l.f3 and l.f1 = 'foo';","html":"+ where f.f3 = l.f3 and l.f1 = \u0026#39;foo\u0026#39;;","displayNoNewLineWarning":false,"position":56,"left":1035,"right":1045},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1046,"text":"+ QUERY PLAN ","html":"+ QUERY PLAN ","displayNoNewLineWarning":false,"position":57,"left":1035,"right":1046},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1047,"text":"+--------------------------------------------------------------------------------------------------","html":"+--------------------------------------------------------------------------------------------------","displayNoNewLineWarning":false,"position":58,"left":1035,"right":1047},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1048,"text":"+ Nested Loop","html":"+ Nested Loop","displayNoNewLineWarning":false,"position":59,"left":1035,"right":1048},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1049,"text":"+ Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3","html":"+ Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3","displayNoNewLineWarning":false,"position":60,"left":1035,"right":1049},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1050,"text":"+ -\u003e Index Scan using loct3_f1_key on public.loct3 l","html":"+ -\u0026gt; Index Scan using loct3_f1_key on public.loct3 l","displayNoNewLineWarning":false,"position":61,"left":1035,"right":1050},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1051,"text":"+ Output: l.f1, l.f2, l.f3","html":"+ Output: l.f1, l.f2, l.f3","displayNoNewLineWarning":false,"position":62,"left":1035,"right":1051},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1052,"text":"+ Index Cond: (l.f1 = 'foo'::text)","html":"+ Index Cond: (l.f1 = \u0026#39;foo\u0026#39;::text)","displayNoNewLineWarning":false,"position":63,"left":1035,"right":1052},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1053,"text":"+ -\u003e Foreign Scan on public.ft3 f","html":"+ -\u0026gt; Foreign Scan on public.ft3 f","displayNoNewLineWarning":false,"position":64,"left":1035,"right":1053},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1054,"text":"+ Output: f.f1, f.f2, f.f3","html":"+ Output: f.f1, f.f2, f.f3","displayNoNewLineWarning":false,"position":65,"left":1035,"right":1054},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1055,"text":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE (($1::character varying(10) = f3))","html":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE (($1::character varying(10) = f3))","displayNoNewLineWarning":false,"position":66,"left":1035,"right":1055},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1056,"text":"+(8 rows)","html":"+(8 rows)","displayNoNewLineWarning":false,"position":67,"left":1035,"right":1056},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1057,"text":"+","html":"+","displayNoNewLineWarning":false,"position":68,"left":1035,"right":1057},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1058,"text":" -- can't be sent to remote","html":" -- can\u0026#39;t be sent to remote","displayNoNewLineWarning":false,"position":69,"left":1036,"right":1058},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1059,"text":" explain (verbose, costs off) select * from ft3 where f1 COLLATE \"POSIX\" = 'foo';","html":" explain (verbose, costs off) select * from ft3 where f1 COLLATE \u0026quot;POSIX\u0026quot; = \u0026#39;foo\u0026#39;;","displayNoNewLineWarning":false,"position":70,"left":1037,"right":1059},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1038,"text":"- QUERY PLAN ","html":"- QUERY PLAN ","displayNoNewLineWarning":false,"position":71,"left":1038,"right":1059},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1039,"text":"------------------------------------------------","html":"------------------------------------------------","displayNoNewLineWarning":false,"position":72,"left":1039,"right":1059},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1060,"text":"+ QUERY PLAN ","html":"+ \u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003eQUERY PLAN\u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003e ","displayNoNewLineWarning":false,"position":73,"left":1039,"right":1060},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1061,"text":"+---------------------------------------------------","html":"+-----------------------------------------------\u003cspan class=\"x x-first x-last\"\u003e----\u003c/span\u003e","displayNoNewLineWarning":false,"position":74,"left":1039,"right":1061},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1062,"text":" Foreign Scan on public.ft3","html":" Foreign Scan on public.ft3","displayNoNewLineWarning":false,"position":75,"left":1040,"right":1062},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1041,"text":"- Output: f1, f2","html":"- Output: f1, f2","displayNoNewLineWarning":false,"position":76,"left":1041,"right":1062},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1063,"text":"+ Output: f1, f2, f3","html":"+ Output: f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e","displayNoNewLineWarning":false,"position":77,"left":1041,"right":1063},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1064,"text":" Filter: ((ft3.f1)::text = 'foo'::text)","html":" Filter: ((ft3.f1)::text = \u0026#39;foo\u0026#39;::text)","displayNoNewLineWarning":false,"position":78,"left":1042,"right":1064},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1043,"text":"- Remote SQL: SELECT f1, f2 FROM public.loct3","html":"- Remote SQL: SELECT f1, f2 FROM public.loct3","displayNoNewLineWarning":false,"position":79,"left":1043,"right":1064},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1065,"text":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3","html":"+ Remote SQL: SELECT f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e FROM public.loct3","displayNoNewLineWarning":false,"position":80,"left":1043,"right":1065},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1066,"text":" (4 rows)","html":" (4 rows)","displayNoNewLineWarning":false,"position":81,"left":1044,"right":1066},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1067,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":82,"left":1045,"right":1067},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1068,"text":" explain (verbose, costs off) select * from ft3 where f1 = 'foo' COLLATE \"C\";","html":" explain (verbose, costs off) select * from ft3 where f1 = \u0026#39;foo\u0026#39; COLLATE \u0026quot;C\u0026quot;;","displayNoNewLineWarning":false,"position":83,"left":1046,"right":1068},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1047,"text":"- QUERY PLAN ","html":"- QUERY PLAN ","displayNoNewLineWarning":false,"position":84,"left":1047,"right":1068},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1048,"text":"------------------------------------------------","html":"------------------------------------------------","displayNoNewLineWarning":false,"position":85,"left":1048,"right":1068},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1069,"text":"+ QUERY PLAN ","html":"+ \u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003eQUERY PLAN\u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003e ","displayNoNewLineWarning":false,"position":86,"left":1048,"right":1069},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1070,"text":"+---------------------------------------------------","html":"+-----------------------------------------------\u003cspan class=\"x x-first x-last\"\u003e----\u003c/span\u003e","displayNoNewLineWarning":false,"position":87,"left":1048,"right":1070},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1071,"text":" Foreign Scan on public.ft3","html":" Foreign Scan on public.ft3","displayNoNewLineWarning":false,"position":88,"left":1049,"right":1071},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1050,"text":"- Output: f1, f2","html":"- Output: f1, f2","displayNoNewLineWarning":false,"position":89,"left":1050,"right":1071},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1072,"text":"+ Output: f1, f2, f3","html":"+ Output: f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e","displayNoNewLineWarning":false,"position":90,"left":1050,"right":1072},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1073,"text":" Filter: (ft3.f1 = 'foo'::text COLLATE \"C\")","html":" Filter: (ft3.f1 = \u0026#39;foo\u0026#39;::text COLLATE \u0026quot;C\u0026quot;)","displayNoNewLineWarning":false,"position":91,"left":1051,"right":1073},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1052,"text":"- Remote SQL: SELECT f1, f2 FROM public.loct3","html":"- Remote SQL: SELECT f1, f2 FROM public.loct3","displayNoNewLineWarning":false,"position":92,"left":1052,"right":1073},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1074,"text":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3","html":"+ Remote SQL: SELECT f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e FROM public.loct3","displayNoNewLineWarning":false,"position":93,"left":1052,"right":1074},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1075,"text":" (4 rows)","html":" (4 rows)","displayNoNewLineWarning":false,"position":94,"left":1053,"right":1075},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1076,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":95,"left":1054,"right":1076},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1077,"text":" explain (verbose, costs off) select * from ft3 where f2 COLLATE \"C\" = 'foo';","html":" explain (verbose, costs off) select * from ft3 where f2 COLLATE \u0026quot;C\u0026quot; = \u0026#39;foo\u0026#39;;","displayNoNewLineWarning":false,"position":96,"left":1055,"right":1077},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1056,"text":"- QUERY PLAN ","html":"- QUERY PLAN ","displayNoNewLineWarning":false,"position":97,"left":1056,"right":1077},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1057,"text":"------------------------------------------------","html":"------------------------------------------------","displayNoNewLineWarning":false,"position":98,"left":1057,"right":1077},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1078,"text":"+ QUERY PLAN ","html":"+ \u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003eQUERY PLAN\u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003e ","displayNoNewLineWarning":false,"position":99,"left":1057,"right":1078},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1079,"text":"+---------------------------------------------------","html":"+-----------------------------------------------\u003cspan class=\"x x-first x-last\"\u003e----\u003c/span\u003e","displayNoNewLineWarning":false,"position":100,"left":1057,"right":1079},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1080,"text":" Foreign Scan on public.ft3","html":" Foreign Scan on public.ft3","displayNoNewLineWarning":false,"position":101,"left":1058,"right":1080},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1059,"text":"- Output: f1, f2","html":"- Output: f1, f2","displayNoNewLineWarning":false,"position":102,"left":1059,"right":1080},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1081,"text":"+ Output: f1, f2, f3","html":"+ Output: f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e","displayNoNewLineWarning":false,"position":103,"left":1059,"right":1081},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1082,"text":" Filter: ((ft3.f2)::text = 'foo'::text)","html":" Filter: ((ft3.f2)::text = \u0026#39;foo\u0026#39;::text)","displayNoNewLineWarning":false,"position":104,"left":1060,"right":1082},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1061,"text":"- Remote SQL: SELECT f1, f2 FROM public.loct3","html":"- Remote SQL: SELECT f1, f2 FROM public.loct3","displayNoNewLineWarning":false,"position":105,"left":1061,"right":1082},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1083,"text":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3","html":"+ Remote SQL: SELECT f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e FROM public.loct3","displayNoNewLineWarning":false,"position":106,"left":1061,"right":1083},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1084,"text":" (4 rows)","html":" (4 rows)","displayNoNewLineWarning":false,"position":107,"left":1062,"right":1084},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1085,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":108,"left":1063,"right":1085},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1086,"text":" explain (verbose, costs off) select * from ft3 where f2 = 'foo' COLLATE \"C\";","html":" explain (verbose, costs off) select * from ft3 where f2 = \u0026#39;foo\u0026#39; COLLATE \u0026quot;C\u0026quot;;","displayNoNewLineWarning":false,"position":109,"left":1064,"right":1086},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1065,"text":"- QUERY PLAN ","html":"- QUERY PLAN ","displayNoNewLineWarning":false,"position":110,"left":1065,"right":1086},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1066,"text":"------------------------------------------------","html":"------------------------------------------------","displayNoNewLineWarning":false,"position":111,"left":1066,"right":1086},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1087,"text":"+ QUERY PLAN ","html":"+ \u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003eQUERY PLAN\u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003e ","displayNoNewLineWarning":false,"position":112,"left":1066,"right":1087},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1088,"text":"+---------------------------------------------------","html":"+-----------------------------------------------\u003cspan class=\"x x-first x-last\"\u003e----\u003c/span\u003e","displayNoNewLineWarning":false,"position":113,"left":1066,"right":1088},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1089,"text":" Foreign Scan on public.ft3","html":" Foreign Scan on public.ft3","displayNoNewLineWarning":false,"position":114,"left":1067,"right":1089},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1068,"text":"- Output: f1, f2","html":"- Output: f1, f2","displayNoNewLineWarning":false,"position":115,"left":1068,"right":1089},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1090,"text":"+ Output: f1, f2, f3","html":"+ Output: f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e","displayNoNewLineWarning":false,"position":116,"left":1068,"right":1090},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1091,"text":" Filter: (ft3.f2 = 'foo'::text COLLATE \"C\")","html":" Filter: (ft3.f2 = \u0026#39;foo\u0026#39;::text COLLATE \u0026quot;C\u0026quot;)","displayNoNewLineWarning":false,"position":117,"left":1069,"right":1091},{"stylingDirective":null,"type":"DELETION","blobLineNumber":1070,"text":"- Remote SQL: SELECT f1, f2 FROM public.loct3","html":"- Remote SQL: SELECT f1, f2 FROM public.loct3","displayNoNewLineWarning":false,"position":118,"left":1070,"right":1091},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1092,"text":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3","html":"+ Remote SQL: SELECT f1, f2\u003cspan class=\"x x-first x-last\"\u003e, f3\u003c/span\u003e FROM public.loct3","displayNoNewLineWarning":false,"position":119,"left":1070,"right":1092},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1093,"text":" (4 rows)","html":" (4 rows)","displayNoNewLineWarning":false,"position":120,"left":1071,"right":1093},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1094,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":121,"left":1072,"right":1094},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1095,"text":"+explain (verbose, costs off) select * from ft3 f, loct3 l","html":"+explain (verbose, costs off) select * from ft3 f, loct3 l","displayNoNewLineWarning":false,"position":122,"left":1072,"right":1095},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1096,"text":"+ where f.f3 = l.f3 COLLATE \"POSIX\" and l.f1 = 'foo';","html":"+ where f.f3 = l.f3 COLLATE \u0026quot;POSIX\u0026quot; and l.f1 = \u0026#39;foo\u0026#39;;","displayNoNewLineWarning":false,"position":123,"left":1072,"right":1096},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1097,"text":"+ QUERY PLAN ","html":"+ QUERY PLAN ","displayNoNewLineWarning":false,"position":124,"left":1072,"right":1097},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1098,"text":"+-------------------------------------------------------------","html":"+-------------------------------------------------------------","displayNoNewLineWarning":false,"position":125,"left":1072,"right":1098},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1099,"text":"+ Hash Join","html":"+ Hash Join","displayNoNewLineWarning":false,"position":126,"left":1072,"right":1099},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1100,"text":"+ Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3","html":"+ Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3","displayNoNewLineWarning":false,"position":127,"left":1072,"right":1100},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1101,"text":"+ Hash Cond: ((f.f3)::text = (l.f3)::text)","html":"+ Hash Cond: ((f.f3)::text = (l.f3)::text)","displayNoNewLineWarning":false,"position":128,"left":1072,"right":1101},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1102,"text":"+ -\u003e Foreign Scan on public.ft3 f","html":"+ -\u0026gt; Foreign 8000 Scan on public.ft3 f","displayNoNewLineWarning":false,"position":129,"left":1072,"right":1102},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1103,"text":"+ Output: f.f1, f.f2, f.f3","html":"+ Output: f.f1, f.f2, f.f3","displayNoNewLineWarning":false,"position":130,"left":1072,"right":1103},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1104,"text":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3","html":"+ Remote SQL: SELECT f1, f2, f3 FROM public.loct3","displayNoNewLineWarning":false,"position":131,"left":1072,"right":1104},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1105,"text":"+ -\u003e Hash","html":"+ -\u0026gt; Hash","displayNoNewLineWarning":false,"position":132,"left":1072,"right":1105},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1106,"text":"+ Output: l.f1, l.f2, l.f3","html":"+ Output: l.f1, l.f2, l.f3","displayNoNewLineWarning":false,"position":133,"left":1072,"right":1106},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1107,"text":"+ -\u003e Index Scan using loct3_f1_key on public.loct3 l","html":"+ -\u0026gt; Index Scan using loct3_f1_key on public.loct3 l","displayNoNewLineWarning":false,"position":134,"left":1072,"right":1107},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1108,"text":"+ Output: l.f1, l.f2, l.f3","html":"+ Output: l.f1, l.f2, l.f3","displayNoNewLineWarning":false,"position":135,"left":1072,"right":1108},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1109,"text":"+ Index Cond: (l.f1 = 'foo'::text)","html":"+ Index Cond: (l.f1 = \u0026#39;foo\u0026#39;::text)","displayNoNewLineWarning":false,"position":136,"left":1072,"right":1109},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1110,"text":"+(11 rows)","html":"+(11 rows)","displayNoNewLineWarning":false,"position":137,"left":1072,"right":1110},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":1111,"text":"+","html":"+","displayNoNewLineWarning":false,"position":138,"left":1072,"right":1111},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1112,"text":" -- ===================================================================","html":" -- ===================================================================","displayNoNewLineWarning":false,"position":139,"left":1073,"right":1112},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1113,"text":" -- test writable foreign table stuff","html":" -- test writable foreign table stuff","displayNoNewLineWarning":false,"position":140,"left":1074,"right":1113},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":1114,"text":" -- ===================================================================","html":" -- ===================================================================","displayNoNewLineWarning":false,"position":141,"left":1075,"right":1114}],"diffNumber":1,"diffSize":"0 Bytes","isBinary":false,"isTooBig":false,"collapsed":false,"isSubmodule":false,"lineCount":3682,"linesChanged":101,"newTreeEntry":{"lineCount":3682,"path":"contrib/postgres_fdw/expected/postgres_fdw.out","mode":100644,"isGenerated":false},"oldTreeEntry":{"lineCount":0,"path":"contrib/postgres_fdw/expected/postgres_fdw.out","mode":100644},"linesAdded":70,"linesDeleted":31,"path":"contrib/postgres_fdw/expected/postgres_fdw.out","pathDigest":"1ef7d46c1a4eef5486c3d5da93e2670b916462f38b052f0da9cd5080d7331242","status":"MODIFIED","truncatedReason":null,"oldOid":"9f1255ac859364a86264a67729dbd1a36dd63ff2","newOid":"76f965ff1f2896d74812a1cad9158fb9f4a1aab9","copilotChatReference":null,"deletedSha":"9f1255ac859364a86264a67729dbd1a36dd63ff2","canToggleRichDiff":false,"defaultToRichDiff":false,"proseDifffHtml":null,"renderInfo":null,"dependencyDiffPath":null,"submodule":null},{"diffLines":[{"stylingDirective":null,"type":"HUNK","blobLineNumber":315,"text":"@@ -316,19 +316,24 @@ COMMIT;","html":"@@ -316,19 +316,24 @@ COMMIT;","displayNoNewLineWarning":false,"position":0,"left":315,"right":315},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":316,"text":" -- ===================================================================","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e--\u003c/span\u003e ===================================================================\u003c/span\u003e","displayNoNewLineWarning":false,"position":1,"left":316,"right":316},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":317,"text":" -- test handling of collations","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e--\u003c/span\u003e test handling of collations\u003c/span\u003e","displayNoNewLineWarning":false,"position":2,"left":317,"right":317},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":318,"text":" -- ===================================================================","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e--\u003c/span\u003e ===================================================================\u003c/span\u003e","displayNoNewLineWarning":false,"position":3,"left":318,"right":318},{"stylingDirective":null,"type":"DELETION","blobLineNumber":319,"text":"-create table loct3 (f1 text collate \"C\", f2 text);","html":"-\u003cspan class=\"pl-k\"\u003ecreate\u003c/span\u003e \u003cspan class=\"pl-k\"\u003etable\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eloct3\u003c/span\u003e (f1 \u003cspan class=\"pl-k\"\u003etext\u003c/span\u003e collate \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eC\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, f2 \u003cspan class=\"pl-k\"\u003etext\u003c/span\u003e);","displayNoNewLineWarning":false,"position":4,"left":319,"right":318},{"stylingDirective":null,"type":"DELETION","blobLineNumber":320,"text":"-create foreign table ft3 (f1 text collate \"C\", f2 text)","html":"-create foreign table ft3 (f1 \u003cspan class=\"pl-k\"\u003etext\u003c/span\u003e collate \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eC\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, f2 \u003cspan class=\"pl-k\"\u003etext\u003c/span\u003e)","displayNoNewLineWarning":false,"position":5,"left":320,"right":318},{"stylingDirective":null,"type":"DELETION","blobLineNumber":321,"text":"- server loopback options (table_name 'loct3');","html":"- server loopback options (table_name \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003eloct3\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e);","displayNoNewLineWarning":false,"position":6,"left":321,"right":318},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":319,"text":"+create table loct3 (f1 text collate \"C\" unique, f2 text, f3 varchar(10) unique);","html":"+\u003cspan class=\"pl-k\"\u003ecreate\u003c/span\u003e \u003cspan class=\"pl-k\"\u003etable\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eloct3\u003c/span\u003e (f1 \u003cspan class=\"pl-k\"\u003etext\u003c/span\u003e collate \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eC\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"x x-first x-last\"\u003e unique\u003c/span\u003e, f2 \u003cspan class=\"pl-k\"\u003etext\u003c/span\u003e\u003cspan class=\"x x-first\"\u003e, f3 \u003c/span\u003e\u003cspan class=\"pl-k x\"\u003evarchar\u003c/span\u003e\u003cspan class=\"x\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e10\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e) unique\u003c/span\u003e);","displayNoNewLineWarning":false,"position":7,"left":321,"right":319},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":320,"text":"+create foreign table ft3 (f1 text collate \"C\", f2 text, f3 varchar(10))","html":"+create foreign table ft3 (f1 \u003cspan class=\"pl-k\"\u003etext\u003c/span\u003e collate \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eC\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, f2 \u003cspan class=\"pl-k\"\u003etext\u003c/span\u003e\u003cspan class=\"x x-first\"\u003e, f3 \u003c/span\u003e\u003cspan class=\"pl-k x\"\u003evarchar\u003c/span\u003e\u003cspan class=\"x\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e10\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e)\u003c/span\u003e)","displayNoNewLineWarning":false,"position":8,"left":321,"right":320},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":321,"text":"+ server loopback options (table_name 'loct3', use_remote_estimate 'true');","html":"+ server loopback options (table_name \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003eloct3\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"x x-first\"\u003e, use_remote_estimate \u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds x\"\u003e'\u003c/span\u003e\u003cspan class=\"x\"\u003etrue\u003c/span\u003e\u003cspan class=\"pl-pds x x-last\"\u003e'\u003c/span\u003e\u003c/span\u003e);","displayNoNewLineWarning":false,"position":9,"left":321,"right":321},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":322,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":10,"left":322,"right":322},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":323,"text":" -- can be sent to remote","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e--\u003c/span\u003e can be sent to remote\u003c/span\u003e","displayNoNewLineWarning":false,"position":11,"left":323,"right":323},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":324,"text":" explain (verbose, costs off) select * from ft3 where f1 = 'foo';","html":" explain (verbose, costs off) \u003cspan class=\"pl-k\"\u003eselect\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e \u003cspan class=\"pl-k\"\u003efrom\u003c/span\u003e ft3 \u003cspan class=\"pl-k\"\u003ewhere\u003c/span\u003e f1 \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003efoo\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e;","displayNoNewLineWarning":false,"position":12,"left":324,"right":324},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":325,"text":" explain (verbose, costs off) select * from ft3 where f1 COLLATE \"C\" = 'foo';","html":" explain (verbose, costs off) \u003cspan class=\"pl-k\"\u003eselect\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e \u003cspan class=\"pl-k\"\u003efrom\u003c/span\u003e ft3 \u003cspan class=\"pl-k\"\u003ewhere\u003c/span\u003e f1 COLLATE \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026quot;\u003c/span\u003eC\u003cspan class=\"pl-pds\"\u003e\u0026quot;\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003efoo\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e;","displayNoNewLineWarning":false,"position":13,"left":325,"right":325},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":326,"text":" explain (verbose, costs off) select * from ft3 where f2 = 'foo';","html":" explain (verbose, costs off) \u003cspan class=\"pl-k\"\u003eselect\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e \u003cspan class=\"pl-k\"\u003efrom\u003c/span\u003e ft3 \u003cspan class=\"pl-k\"\u003ewhere\u003c/span\u003e f2 \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003efoo\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e;","displayNoNewLineWarning":false,"position":14,"left":326,"right":326},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":327,"text":"+explain (verbose, costs off) select * from ft3 where f3 = 'foo';","html":"+explain (verbose, costs off) \u003cspan class=\"pl-k\"\u003eselect\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e \u003cspan class=\"pl-k\"\u003efrom\u003c/span\u003e ft3 \u003cspan class=\"pl-k\"\u003ewhere\u003c/span\u003e f3 \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003efoo\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e;","displayNoNewLineWarning":false,"position":15,"left":326,"right":327},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":328,"text":"+explain (verbose, costs off) select * from ft3 f, loct3 l","html":"+explain (verbose, costs off) \u003cspan class=\"pl-k\"\u003eselect\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e \u003cspan class=\"pl-k\"\u003efrom\u003c/span\u003e ft3 f, loct3 l","displayNoNewLineWarning":false,"position":16,"left":326,"right":328},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":329,"text":"+ where f.f3 = l.f3 and l.f1 = 'foo';","html":"+ \u003cspan class=\"pl-k\"\u003ewhere\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003ef\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003ef3\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003el\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003ef3\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eand\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003el\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003ef1\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003efoo\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e;","displayNoNewLineWarning":false,"position":17,"left":326,"right":329},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":330,"text":" -- can't be sent to remote","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e--\u003c/span\u003e can\u0026#39;t be sent to remote\u003c/span\u003e","displayNoNewLineWarning":false,"position":18,"left":327,"right":330},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":331,"text":" explain (verbose, costs off) select * from ft3 where f1 COLLATE \"POSIX\" = 'foo';","html":" explain (verbose, costs off) \u003cspan class=\"pl-k\"\u003eselect\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e \u003cspan class=\"pl-k\"\u003efrom\u003c/span\u003e ft3 \u003cspan class=\"pl-k\"\u003ewhere\u003c/span\u003e f1 COLLATE \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026quot;\u003c/span\u003ePOSIX\u003cspan class=\"pl-pds\"\u003e\u0026quot;\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003efoo\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e;","displayNoNewLineWarning":false,"position":19,"left":328,"right":331},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":332,"text":" explain (verbose, costs off) select * from ft3 where f1 = 'foo' COLLATE \"C\";","html":" explain (verbose, costs off) \u003cspan class=\"pl-k\"\u003eselect\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e \u003cspan class=\"pl-k\"\u003efrom\u003c/span\u003e ft3 \u003cspan class=\"pl-k\"\u003ewhere\u003c/span\u003e f1 \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003efoo\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e COLLATE \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026quot;\u003c/span\u003eC\u003cspan class=\"pl-pds\"\u003e\u0026quot;\u003c/span\u003e\u003c/span\u003e;","displayNoNewLineWarning":false,"position":20,"left":329,"right":332},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":333,"text":" explain (verbose, costs off) select * from ft3 where f2 COLLATE \"C\" = 'foo';","html":" explain (verbose, costs off) \u003cspan class=\"pl-k\"\u003eselect\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e \u003cspan class=\"pl-k\"\u003efrom\u003c/span\u003e ft3 \u003cspan class=\"pl-k\"\u003ewhere\u003c/span\u003e f2 COLLATE \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026quot;\u003c/span\u003eC\u003cspan class=\"pl-pds\"\u003e\u0026quot;\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003efoo\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e;","displayNoNewLineWarning":false,"position":21,"left":330,"right":333},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":334,"text":" explain (verbose, costs off) select * from ft3 where f2 = 'foo' COLLATE \"C\";","html":" explain (verbose, costs off) \u003cspan class=\"pl-k\"\u003eselect\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e \u003cspan class=\"pl-k\"\u003efrom\u003c/span\u003e ft3 \u003cspan class=\"pl-k\"\u003ewhere\u003c/span\u003e f2 \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003efoo\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e COLLATE \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026quot;\u003c/span\u003eC\u003cspan class=\"pl-pds\"\u003e\u0026quot;\u003c/span\u003e\u003c/span\u003e;","displayNoNewLineWarning":false,"position":22,"left":331,"right":334},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":335,"text":"+explain (verbose, costs off) select * from ft3 f, loct3 l","html":"+explain (verbose, costs off) \u003cspan class=\"pl-k\"\u003eselect\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e*\u003c/span\u003e \u003cspan class=\"pl-k\"\u003efrom\u003c/span\u003e ft3 f, loct3 l","displayNoNewLineWarning":false,"position":23,"left":331,"right":335},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":336,"text":"+ where f.f3 = l.f3 COLLATE \"POSIX\" and l.f1 = 'foo';","html":"+ \u003cspan class=\"pl-k\"\u003ewhere\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003ef\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003ef3\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003el\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003ef3\u003c/span\u003e COLLATE \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026quot;\u003c/span\u003ePOSIX\u003cspan class=\"pl-pds\"\u003e\u0026quot;\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eand\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003el\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003ef1\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003efoo\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e;","displayNoNewLineWarning":false,"position":24,"left":331,"right":336},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":337,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":25,"left":332,"right":337},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":338,"text":" -- ===================================================================","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e--\u003c/span\u003e ===================================================================\u003c/span\u003e","displayNoNewLineWarning":false,"position":26,"left":333,"right":338},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":339,"text":" -- test writable foreign table stuff","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e--\u003c/span\u003e test writable foreign table stuff\u003c/span\u003e","displayNoNewLineWarning":false,"position":27,"left":334,"right":339}],"diffNumber":2,"diffSize":"0 Bytes","isBinary":false,"isTooBig":false,"collapsed":false,"isSubmodule":false,"lineCount":841,"linesChanged":11,"newTreeEntry":{"lineCount":841,"path":"contrib/postgres_fdw/sql/postgres_fdw.sql","mode":100644,"isGenerated":false},"oldTreeEntry":{"lineCount":0,"path":"contrib/postgres_fdw/sql/postgres_fdw.sql","mode":100644},"linesAdded":8,"linesDeleted":3,"path":"contrib/postgres_fdw/sql/postgres_fdw.sql","pathDigest":"dc295236dc0d323d73652c5bbafe2b9b9ed3ddf9c72016d75033a2847fdae202","status":"MODIFIED","truncatedReason":null,"oldOid":"9f1255ac859364a86264a67729dbd1a36dd63ff2","newOid":"76f965ff1f2896d74812a1cad9158fb9f4a1aab9","copilotChatReference":null,"deletedSha":"9f1255ac859364a86264a67729dbd1a36dd63ff2","canToggleRichDiff":false,"defaultToRichDiff":false,"proseDifffHtml":null,"renderInfo":null,"dependencyDiffPath":null,"submodule":null}],"splitViewPreference":"unified","ignoreWhitespace":false,"repoOwnerGlobalRelayId":"MDEyOk9yZ2FuaXphdGlvbjE3NzU0Mw==","commentsPreference":"visible","diffLineSpacingPreference":"relaxed","useMonospaceFont":false,"pasteUrlLinkAsPlainText":false,"userNotices":[],"path":"/postgres/postgres/commit/76f965ff1f2896d74812a1cad9158fb9f4a1aab9","fileTreeExpanded":true,"headerInfo":{"additions":135,"deletions":66,"filesChanged":3,"filesChangedString":"3"},"moreDiffsToLoad":false,"asyncDiffLoadInfo":{"startIndex":3,"truncated":false,"byteCount":14204,"lineShownCount":346},"commentInfo":{"canComment":false,"locked":false,"canLock":false,"repoArchived":false},"csrf_tokens":{"/users/diffview?diff=split":{"post":"ZGRAcRFGXI7RtyQQ1DNoHBbEzs6v-tYCudNwgnKwjnd3RnvUZCtxHgRSPfRq8lKbEoveXxJ6eNhoS_3UKVzT3w"},"/users/diffview?diff=unified":{"post":"eMBYd-Ds0FF9-7WwIIJBPL9uQ07dCA3oHZPzoOSoeppr4mPSlYH9wagerFSeQ3u7uyFT32CIozLMC372v0QnMg"},"/notifications/thread":{"post":"BkflxhicJVLN_dyIuzl5lSXFfZm4F5WdLGdkebkLCafk0RsliXKJkzrZyq3qKFgaktu12kD6uNGN6WlV68O5YQ"}}},"title":"Improve handling of collations in contrib/postgres_fdw. · postgres/postgres@76f965f","appPayload":{"helpUrl":"https://docs.github.com","findInDiffWorkerPath":"/assets-cdn/worker/find-in-diff-worker-2bfe39677d14.js","enabled_features":{"diff_ux_refresh_beta":false,"diff_inline_comments":true,"diff_ux_refresh_ssr_five":false,"diff_ux_refresh_ssr_ten":false,"react_diff_line_type_character_correction":true}}}

Commit 76f965f

Browse files
committed
Improve handling of collations in contrib/postgres_fdw.
If we have a local Var of say varchar type with default collation, and we apply a RelabelType to convert that to text with default collation, we don't want to consider that as creating an FDW_COLLATE_UNSAFE situation. It should be okay to compare that to a remote Var, so long as the remote Var determines the comparison collation. (When we actually ship such an expression to the remote side, the local Var would become a Param with default collation, meaning the remote Var would in fact control the comparison collation, because non-default implicit collation overrides default implicit collation in parse_collate.c.) To fix, be more precise about what FDW_COLLATE_NONE means: it applies either to a noncollatable data type or to a collatable type with default collation, if that collation can't be traced to a remote Var. (When it can, FDW_COLLATE_SAFE is appropriate.) We were essentially using that interpretation already at the Var/Const/Param level, but we weren't bubbling it up properly. An alternative fix would be to introduce a separate FDW_COLLATE_DEFAULT value to describe the second situation, but that would add more code without changing the actual behavior, so it didn't seem worthwhile. Also, since we're clarifying the rule to be that we care about whether operator/function input collations match, there seems no need to fail immediately upon seeing a Const/Param/non-foreign-Var with nondefault collation. We only have to reject if it appears in a collation-sensitive context (for example, "var IS NOT NULL" is perfectly safe from a collation standpoint, whatever collation the var has). So just set the state to UNSAFE rather than failing immediately. Per report from Jeevan Chalke. This essentially corrects some sloppy thinking in commit ed3ddf9, so back-patch to 9.3 where that logic appeared.
1 parent 9f1255a commit 76f965f

File tree

3 files changed

+135
-66
lines changed

3 files changed

+135
-66
lines changed

contrib/postgres_fdw/deparse.c

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
* We do not consider that it is ever safe to send COLLATE expressions to
1818
* the remote server: it might not have the same collation names we do.
1919
* (Later we might consider it safe to send COLLATE "C", but even that would
20-
* fail on old remote servers.) An expression is considered safe to send only
21-
* if all collations used in it are traceable to Var(s) of the foreign table.
22-
* That implies that if the remote server gets a different answer than we do,
23-
* the foreign table's columns are not marked with collations that match the
24-
* remote table's columns, which we can consider to be user error.
20+
* fail on old remote servers.) An expression is considered safe to send
21+
* only if all operator/function input collations used in it are traceable to
22+
* Var(s) of the foreign table. That implies that if the remote server gets
23+
* a different answer than we do, the foreign table's columns are not marked
24+
* with collations that match the remote table's columns, which we can
25+
* consider to be user error.
2526
*
2627
* Portions Copyright (c) 2012-2015, PostgreSQL Global Development Group
2728
*
@@ -69,9 +70,12 @@ typedef struct foreign_glob_cxt
6970
*/
7071
typedef enum
7172
{
72-
FDW_COLLATE_NONE, /* expression is of a noncollatable type */
73+
FDW_COLLATE_NONE, /* expression is of a noncollatable type, or
74+
* it has default collation that is not
75+
* traceable to a foreign Var */
7376
FDW_COLLATE_SAFE, /* collation derives from a foreign Var */
74-
FDW_COLLATE_UNSAFE /* collation derives from something else */
77+
FDW_COLLATE_UNSAFE /* collation is non-default and derives from
78+
* something other than a foreign Var */
7579
} FDWCollateState;
7680

7781
typedef struct foreign_loc_cxt
@@ -272,13 +276,24 @@ foreign_expr_walker(Node *node,
272276
else
273277
{
274278
/* Var belongs to some other table */
275-
if (var->varcollid != InvalidOid &&
276-
var->varcollid != DEFAULT_COLLATION_OID)
277-
return false;
278-
279-
/* We can consider that it doesn't set collation */
280-
collation = InvalidOid;
281-
state = FDW_COLLATE_NONE;
279+
collation = var->varcollid;
280+
if (collation == InvalidOid ||
281+
collation == DEFAULT_COLLATION_OID)
282+
{
283+
/*
284+
* It's noncollatable, or it's safe to combine with a
285+
* collatable foreign Var, so set state to NONE.
286+
*/
287+
state = FDW_COLLATE_NONE;
288+
}
289+
else
290+
{
291+
/*
292+
* Do not fail right away, since the Var might appear
293+
* in a collation-insensitive context.
294+
*/
295+
state = FDW_COLLATE_UNSAFE;
296+
}
282297
}
283298
}
284299
break;
@@ -288,31 +303,31 @@ foreign_expr_walker(Node *node,
288303

289304
/*
290305
* If the constant has nondefault collation, either it's of a
291-
* non-builtin type, or it reflects folding of a CollateExpr;
292-
* either way, it's unsafe to send to the remote.
306+
* non-builtin type, or it reflects folding of a CollateExpr.
307+
* It's unsafe to send to the remote unless it's used in a
308+
* non-collation-sensitive context.
293309
*/
294-
if (c->constcollid != InvalidOid &&
295-
c->constcollid != DEFAULT_COLLATION_OID)
296-
return false;
297-
298-
/* Otherwise, we can consider that it doesn't set collation */
299-
collation = InvalidOid;
300-
state = FDW_COLLATE_NONE;
310+
collation = c->constcollid;
311+
if (collation == InvalidOid ||
312+
collation == DEFAULT_COLLATION_OID)
313+
state = FDW_COLLATE_NONE;
314+
else
315+
state = FDW_COLLATE_UNSAFE;
301316
}
302317
break;
303318
case T_Param:
304319
{
305320
Param *p = (Param *) node;
306321

307322
/*
308-
* Collation handling is same as for Consts.
323+
* Collation rule is same as for Consts and non-foreign Vars.
309324
*/
310-
if (p->paramcollid != InvalidOid &&
311-
p->paramcollid != DEFAULT_COLLATION_OID)
312-
return false;
313-
314-
collation = InvalidOid;
315-
state = FDW_COLLATE_NONE;
325+
collation = p->paramcollid;
326+
if (collation == InvalidOid ||
327+
collation == DEFAULT_COLLATION_OID)
328+
state = FDW_COLLATE_NONE;
329+
else
330+
state = FDW_COLLATE_UNSAFE;
316331
}
317332
break;
318333
case T_ArrayRef:
@@ -348,6 +363,8 @@ foreign_expr_walker(Node *node,
348363
else if (inner_cxt.state == FDW_COLLATE_SAFE &&
349364
collation == inner_cxt.collation)
350365
state = FDW_COLLATE_SAFE;
366+
else if (collation == DEFAULT_COLLATION_OID)
367+
state = FDW_COLLATE_NONE;
351368
else
352369
state = FDW_COLLATE_UNSAFE;
353370
}
@@ -393,6 +410,8 @@ foreign_expr_walker(Node *node,
393410
else if (inner_cxt.state == FDW_COLLATE_SAFE &&
394411
collation == inner_cxt.collation)
395412
state = FDW_COLLATE_SAFE;
413+
else if (collation == DEFAULT_COLLATION_OID)
414+
state = FDW_COLLATE_NONE;
396415
else
397416
state = FDW_COLLATE_UNSAFE;
398417
}
@@ -434,6 +453,8 @@ foreign_expr_walker(Node *node,
434453
else if (inner_cxt.state == FDW_COLLATE_SAFE &&
435454
collation == inner_cxt.collation)
436455
state = FDW_COLLATE_SAFE;
456+
else if (collation == DEFAULT_COLLATION_OID)
457+
state = FDW_COLLATE_NONE;
437458
else
438459
state = FDW_COLLATE_UNSAFE;
439460
}
@@ -483,14 +504,16 @@ foreign_expr_walker(Node *node,
483504

484505
/*
485506
* RelabelType must not introduce a collation not derived from
486-
* an input foreign Var.
507+
* an input foreign Var (same logic as for a real function).
487508
*/
488509
collation = r->resultcollid;
489510
if (collation == InvalidOid)
490511
state = FDW_COLLATE_NONE;
491512
else if (inner_cxt.state == FDW_COLLATE_SAFE &&
492513
collation == inner_cxt.collation)
493514
state = FDW_COLLATE_SAFE;
515+
else if (collation == DEFAULT_COLLATION_OID)
516+
state = FDW_COLLATE_NONE;
494517
else
495518
state = FDW_COLLATE_UNSAFE;
496519
}
@@ -540,14 +563,16 @@ foreign_expr_walker(Node *node,
540563

541564
/*
542565
* ArrayExpr must not introduce a collation not derived from
543-
* an input foreign Var.
566+
* an input foreign Var (same logic as for a function).
544567
*/
545568
collation = a->array_collid;
546569
if (collation == InvalidOid)
547570
state = FDW_COLLATE_NONE;
548571
else if (inner_cxt.state == FDW_COLLATE_SAFE &&
549572
collation == inner_cxt.collation)
550573
state = FDW_COLLATE_SAFE;
574+
else if (collation == DEFAULT_COLLATION_OID)
575+
state = FDW_COLLATE_NONE;
551576
else
552577
state = FDW_COLLATE_UNSAFE;
553578
}

contrib/postgres_fdw/expected/postgres_fdw.out

Lines changed: 70 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,71 +1005,110 @@ COMMIT;
10051005
-- ===================================================================
10061006
-- test handling of collations
10071007
-- ===================================================================
1008-
create table loct3 (f1 text collate "C", f2 text);
1009-
create foreign table ft3 (f1 text collate "C", f2 text)
1010-
server loopback options (table_name 'loct3');
1008+
create table loct3 (f1 text collate "C" unique, f2 text, f3 varchar(10) unique);
1009+
create foreign table ft3 (f1 text collate "C", f2 text, f3 varchar(10))
1010+
server loopback options (table_name 'loct3', use_remote_estimate 'true');
10111011
-- can be sent to remote
10121012
explain (verbose, costs off) select * from ft3 where f1 = 'foo';
1013-
QUERY PLAN
1014-
--------------------------------------------------------------------------
1013+
QUERY PLAN
1014+
------------------------------------------------------------------------------
10151015
Foreign Scan on public.ft3
1016-
Output: f1, f2
1017-
Remote SQL: SELECT f1, f2 FROM public.loct3 WHERE ((f1 = 'foo'::text))
1016+
Output: f1, f2, f3
1017+
Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f1 = 'foo'::text))
10181018
(3 rows)
10191019

10201020
explain (verbose, costs off) select * from ft3 where f1 COLLATE "C" = 'foo';
1021-
QUERY PLAN
1022-
--------------------------------------------------------------------------
1021+
QUERY PLAN
1022+
------------------------------------------------------------------------------
10231023
Foreign Scan on public.ft3
1024-
Output: f1, f2
1025-
Remote SQL: SELECT f1, f2 FROM public.loct3 WHERE ((f1 = 'foo'::text))
1024+
Output: f1, f2, f3
1025+
Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f1 = 'foo'::text))
10261026
(3 rows)
10271027

10281028
explain (verbose, costs off) select * from ft3 where f2 = 'foo';
1029-
QUERY PLAN
1030-
--------------------------------------------------------------------------
1029+
QUERY PLAN
1030+
------------------------------------------------------------------------------
10311031
Foreign Scan on public.ft3
1032-
Output: f1, f2
1033-
Remote SQL: SELECT f1, f2 FROM public.loct3 WHERE ((f2 = 'foo'::text))
1032+
Output: f1, f2, f3
1033+
Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f2 = 'foo'::text))
10341034
(3 rows)
10351035

1036+
explain (verbose, costs off) select * from ft3 where f3 = 'foo';
1037+
QUERY PLAN
1038+
------------------------------------------------------------------------------
1039+
Foreign Scan on public.ft3
1040+
Output: f1, f2, f3
1041+
Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f3 = 'foo'::text))
1042+
(3 rows)
1043+
1044+
explain (verbose, costs off) select * from ft3 f, loct3 l
1045+
where f.f3 = l.f3 and l.f1 = 'foo';
1046+
QUERY PLAN
1047+
--------------------------------------------------------------------------------------------------
1048+
Nested Loop
1049+
Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3
1050+
-> Index Scan using loct3_f1_key on public.loct3 l
1051+
Output: l.f1, l.f2, l.f3
1052+
Index Cond: (l.f1 = 'foo'::text)
1053+
-> Foreign Scan on public.ft3 f
1054+
Output: f.f1, f.f2, f.f3
1055+
Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE (($1::character varying(10) = f3))
1056+
(8 rows)
1057+
10361058
-- can't be sent to remote
10371059
explain (verbose, costs off) select * from ft3 where f1 COLLATE "POSIX" = 'foo';
1038-
QUERY PLAN
1039-
-----------------------------------------------
1060+
QUERY PLAN
1061+
---------------------------------------------------
10401062
Foreign Scan on public.ft3
1041-
Output: f1, f2
1063+
Output: f1, f2, f3
10421064
Filter: ((ft3.f1)::text = 'foo'::text)
1043-
Remote SQL: SELECT f1, f2 FROM public.loct3
1065+
Remote SQL: SELECT f1, f2, f3 FROM public.loct3
10441066
(4 rows)
10451067

10461068
explain (verbose, costs off) select * from ft3 where f1 = 'foo' COLLATE "C";
1047-
QUERY PLAN
1048-
-----------------------------------------------
1069+
QUERY PLAN
1070+
---------------------------------------------------
10491071
Foreign Scan on public.ft3
1050-
Output: f1, f2
1072+
Output: f1, f2, f3
10511073
Filter: (ft3.f1 = 'foo'::text COLLATE "C")
1052-
Remote SQL: SELECT f1, f2 FROM public.loct3
1074+
Remote SQL: SELECT f1, f2, f3 FROM public.loct3
10531075
(4 rows)
10541076

10551077
explain (verbose, costs off) select * from ft3 where f2 COLLATE "C" = 'foo';
1056-
QUERY PLAN
1057-
-----------------------------------------------
1078+
QUERY PLAN
1079+
---------------------------------------------------
10581080
Foreign Scan on public.ft3
1059-
Output: f1, f2
1081+
Output: f1, f2, f3
10601082
Filter: ((ft3.f2)::text = 'foo'::text)
1061-
Remote SQL: SELECT f1, f2 FROM public.loct3
1083+
Remote SQL: SELECT f1, f2, f3 FROM public.loct3
10621084
(4 rows)
10631085

10641086
explain (verbose, costs off) select * from ft3 where f2 = 'foo' COLLATE "C";
1065-
QUERY PLAN
1066-
-----------------------------------------------
1087+
QUERY PLAN
1088+
---------------------------------------------------
10671089
Foreign Scan on public.ft3
1068-
Output: f1, f2
1090+
Output: f1, f2, f3
10691091
Filter: (ft3.f2 = 'foo'::text COLLATE "C")
1070-
Remote SQL: SELECT f1, f2 FROM public.loct3
1092+
Remote SQL: SELECT f1, f2, f3 FROM public.loct3
10711093
(4 rows)
10721094

1095+
explain (verbose, costs off) select * from ft3 f, loct3 l
1096+
where f.f3 = l.f3 COLLATE "POSIX" and l.f1 = 'foo';
1097+
QUERY PLAN
1098+
-------------------------------------------------------------
1099+
Hash Join
1100+
Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3
1101+
Hash Cond: ((f.f3)::text = (l.f3)::text)
1102+
-> Foreign Scan on public.ft3 f
1103+
Output: f.f1, f.f2, f.f3
1104+
Remote SQL: SELECT f1, f2, f3 FROM public.loct3
1105+
-> Hash
1106+
Output: l.f1, l.f2, l.f3
1107+
-> Index Scan using loct3_f1_key on public.loct3 l
1108+
Output: l.f1, l.f2, l.f3
1109+
Index Cond: (l.f1 = 'foo'::text)
1110+
(11 rows)
1111+
10731112
-- ===================================================================
10741113
-- test writable foreign table stuff
10751114
-- ===================================================================

contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,19 +316,24 @@ COMMIT;
316316
-- ===================================================================
317317
-- test handling of collations
318318
-- ===================================================================
319-
create table loct3 (f1 text collate "C", f2 text);
320-
create foreign table ft3 (f1 text collate "C", f2 text)
321-
server loopback options (table_name 'loct3');
319+
create table loct3 (f1 text collate "C" unique, f2 text, f3 varchar(10) unique);
320+
create foreign table ft3 (f1 text collate "C", f2 text, f3 varchar(10))
321+
server loopback options (table_name 'loct3', use_remote_estimate 'true');
322322

323323
-- can be sent to remote
324324
explain (verbose, costs off) select * from ft3 where f1 = 'foo';
325325
explain (verbose, costs off) select * from ft3 where f1 COLLATE "C" = 'foo';
326326
explain (verbose, costs off) select * from ft3 where f2 = 'foo';
327+
explain (verbose, costs off) select * from ft3 where f3 = 'foo';
328+
explain (verbose, costs off) select * from ft3 f, loct3 l
329+
where f.f3 = l.f3 and l.f1 = 'foo';
327330
-- can't be sent to remote
328331
explain (verbose, costs off) select * from ft3 where f1 COLLATE "POSIX" = 'foo';
329332
explain (verbose, costs off) select * from ft3 where f1 = 'foo' COLLATE "C";
330333
explain (verbose, costs off) select * from ft3 where f2 COLLATE "C" = 'foo';
331334
explain (verbose, costs off) select * from ft3 where f2 = 'foo' COLLATE "C";
335+
explain (verbose, costs off) select * from ft3 f, loct3 l
336+
where f.f3 = l.f3 COLLATE "POSIX" and l.f1 = 'foo';
332337

333338
-- ===================================================================
334339
-- test writable foreign table stuff

0 commit comments

Comments
 (0)
0