|
22 | 22 | #include"access/sysattr.h"
|
23 | 23 | #include"catalog/indexing.h"
|
24 | 24 | #include"catalog/pg_constraint.h"
|
| 25 | +#include"catalog/pg_extension.h" |
25 | 26 | #include"catalog/pg_inherits.h"
|
26 | 27 | #include"catalog/pg_inherits_fn.h"
|
27 | 28 | #include"catalog/pg_type.h"
|
@@ -62,6 +63,7 @@ PathmanInitState pg_pathman_init_state;
|
62 | 63 | /* Shall we install new relcache callback? */
|
63 | 64 | staticboolrelcache_callback_needed= true;
|
64 | 65 |
|
| 66 | + |
65 | 67 | /* Functions for various local caches */
|
66 | 68 | staticboolinit_pathman_relation_oids(void);
|
67 | 69 | staticvoidfini_pathman_relation_oids(void);
|
@@ -89,6 +91,11 @@ static bool read_opexpr_const(const OpExpr *opexpr,
|
89 | 91 | staticintoid_cmp(constvoid*p1,constvoid*p2);
|
90 | 92 |
|
91 | 93 |
|
| 94 | +/* Validate SQL facade */ |
| 95 | +staticuint32build_sql_facade_version(char*version_cstr); |
| 96 | +staticuint32get_sql_facade_version(void); |
| 97 | +staticvoidvalidate_sql_facade_version(uint32ver); |
| 98 | + |
92 | 99 | /*
|
93 | 100 | * Save and restore main init state.
|
94 | 101 | */
|
@@ -167,6 +174,9 @@ load_config(void)
|
167 | 174 | if (!init_pathman_relation_oids())
|
168 | 175 | return false;/* remain 'uninitialized', exit before creating main caches */
|
169 | 176 |
|
| 177 | +/* Validate pg_pathman's Pl/PgSQL facade (might be outdated) */ |
| 178 | +validate_sql_facade_version(get_sql_facade_version()); |
| 179 | + |
170 | 180 | init_local_cache();/* create 'partitioned_rels' hash table */
|
171 | 181 | read_pathman_config();/* read PATHMAN_CONFIG table & fill cache */
|
172 | 182 |
|
@@ -1098,3 +1108,89 @@ oid_cmp(const void *p1, const void *p2)
|
1098 | 1108 | return1;
|
1099 | 1109 | return0;
|
1100 | 1110 | }
|
| 1111 | + |
| 1112 | + |
| 1113 | +/* Parse cstring and build uint32 representing the version */ |
| 1114 | +staticuint32 |
| 1115 | +build_sql_facade_version(char*version_cstr) |
| 1116 | +{ |
| 1117 | +uint32version; |
| 1118 | + |
| 1119 | +/* expect to see x+.y+.z+ */ |
| 1120 | +version=strtol(version_cstr,&version_cstr,10)&0xFF; |
| 1121 | + |
| 1122 | +version <<=8; |
| 1123 | +if (strlen(version_cstr)>1) |
| 1124 | +version |= (strtol(version_cstr+1,&version_cstr,10)&0xFF); |
| 1125 | + |
| 1126 | +version <<=8; |
| 1127 | +if (strlen(version_cstr)>1) |
| 1128 | +version |= (strtol(version_cstr+1,&version_cstr,10)&0xFF); |
| 1129 | + |
| 1130 | +returnversion; |
| 1131 | +} |
| 1132 | + |
| 1133 | +/* Get version of pg_pathman's facade written in Pl/PgSQL */ |
| 1134 | +staticuint32 |
| 1135 | +get_sql_facade_version(void) |
| 1136 | +{ |
| 1137 | +Relationpg_extension_rel; |
| 1138 | +ScanKeyDataskey; |
| 1139 | +SysScanDescscan; |
| 1140 | +HeapTuplehtup; |
| 1141 | + |
| 1142 | +Datumdatum; |
| 1143 | +boolisnull; |
| 1144 | +char*version_cstr; |
| 1145 | + |
| 1146 | +/* Look up the extension */ |
| 1147 | +pg_extension_rel=heap_open(ExtensionRelationId,AccessShareLock); |
| 1148 | + |
| 1149 | +ScanKeyInit(&skey, |
| 1150 | +Anum_pg_extension_extname, |
| 1151 | +BTEqualStrategyNumber,F_NAMEEQ, |
| 1152 | +CStringGetDatum("pg_pathman")); |
| 1153 | + |
| 1154 | +scan=systable_beginscan(pg_extension_rel, |
| 1155 | +ExtensionNameIndexId, |
| 1156 | + true,NULL,1,&skey); |
| 1157 | + |
| 1158 | +htup=systable_getnext(scan); |
| 1159 | + |
| 1160 | +/* Exit if pg_pathman's missing */ |
| 1161 | +if (!HeapTupleIsValid(htup)) |
| 1162 | +return0; |
| 1163 | + |
| 1164 | +datum=heap_getattr(htup,Anum_pg_extension_extversion, |
| 1165 | +RelationGetDescr(pg_extension_rel),&isnull); |
| 1166 | +Assert(isnull== false);/* extversion should not be NULL */ |
| 1167 | + |
| 1168 | +/* Extract pg_pathman's version as cstring */ |
| 1169 | +version_cstr=text_to_cstring(DatumGetTextPP(datum)); |
| 1170 | + |
| 1171 | +systable_endscan(scan); |
| 1172 | +heap_close(pg_extension_rel,AccessShareLock); |
| 1173 | + |
| 1174 | +returnbuild_sql_facade_version(version_cstr); |
| 1175 | +} |
| 1176 | + |
| 1177 | +/* Check that current Pl/PgSQL facade is compatible with internals */ |
| 1178 | +staticvoid |
| 1179 | +validate_sql_facade_version(uint32ver) |
| 1180 | +{ |
| 1181 | +Assert(ver>0); |
| 1182 | + |
| 1183 | +/* Compare ver to 'lowest compatible frontend' version */ |
| 1184 | +if (ver<LOWEST_COMPATIBLE_FRONT) |
| 1185 | +{ |
| 1186 | +elog(DEBUG1,"current version: %x, lowest compatible: %x", |
| 1187 | +ver,LOWEST_COMPATIBLE_FRONT); |
| 1188 | + |
| 1189 | +DisablePathman();/* disable pg_pathman since config is broken */ |
| 1190 | +ereport(ERROR, |
| 1191 | +(errmsg("pg_pathman's Pl/PgSQL frontend is incompatible with " |
| 1192 | +"its shared library"), |
| 1193 | +errdetail("consider performing an update procedure"), |
| 1194 | +errhint(INIT_ERROR_HINT))); |
| 1195 | +} |
| 1196 | +} |