00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "postgres.h"
00016
00017 #include <ctype.h>
00018 #include <limits.h>
00019
00020 #include "catalog/pg_type.h"
00021 #include "libpq/pqformat.h"
00022 #include "utils/array.h"
00023 #include "utils/builtins.h"
00024
00025
00026 #define OidVectorSize(n) (offsetof(oidvector, values) + (n) * sizeof(Oid))
00027
00028
00029
00030
00031
00032
00033 static Oid
00034 oidin_subr(const char *s, char **endloc)
00035 {
00036 unsigned long cvt;
00037 char *endptr;
00038 Oid result;
00039
00040 if (*s == '\0')
00041 ereport(ERROR,
00042 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00043 errmsg("invalid input syntax for type oid: \"%s\"",
00044 s)));
00045
00046 errno = 0;
00047 cvt = strtoul(s, &endptr, 10);
00048
00049
00050
00051
00052
00053
00054 if (errno && errno != ERANGE && errno != EINVAL)
00055 ereport(ERROR,
00056 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00057 errmsg("invalid input syntax for type oid: \"%s\"",
00058 s)));
00059
00060 if (endptr == s && *s != '\0')
00061 ereport(ERROR,
00062 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00063 errmsg("invalid input syntax for type oid: \"%s\"",
00064 s)));
00065
00066 if (errno == ERANGE)
00067 ereport(ERROR,
00068 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00069 errmsg("value \"%s\" is out of range for type oid", s)));
00070
00071 if (endloc)
00072 {
00073
00074 *endloc = endptr;
00075 }
00076 else
00077 {
00078
00079 while (*endptr && isspace((unsigned char) *endptr))
00080 endptr++;
00081 if (*endptr)
00082 ereport(ERROR,
00083 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00084 errmsg("invalid input syntax for type oid: \"%s\"",
00085 s)));
00086 }
00087
00088 result = (Oid) cvt;
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 #if OID_MAX != ULONG_MAX
00103 if (cvt != (unsigned long) result &&
00104 cvt != (unsigned long) ((int) result))
00105 ereport(ERROR,
00106 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00107 errmsg("value \"%s\" is out of range for type oid", s)));
00108 #endif
00109
00110 return result;
00111 }
00112
00113 Datum
00114 oidin(PG_FUNCTION_ARGS)
00115 {
00116 char *s = PG_GETARG_CSTRING(0);
00117 Oid result;
00118
00119 result = oidin_subr(s, NULL);
00120 PG_RETURN_OID(result);
00121 }
00122
00123 Datum
00124 oidout(PG_FUNCTION_ARGS)
00125 {
00126 Oid o = PG_GETARG_OID(0);
00127 char *result = (char *) palloc(12);
00128
00129 snprintf(result, 12, "%u", o);
00130 PG_RETURN_CSTRING(result);
00131 }
00132
00133
00134
00135
00136 Datum
00137 oidrecv(PG_FUNCTION_ARGS)
00138 {
00139 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
00140
00141 PG_RETURN_OID((Oid) pq_getmsgint(buf, sizeof(Oid)));
00142 }
00143
00144
00145
00146
00147 Datum
00148 oidsend(PG_FUNCTION_ARGS)
00149 {
00150 Oid arg1 = PG_GETARG_OID(0);
00151 StringInfoData buf;
00152
00153 pq_begintypsend(&buf);
00154 pq_sendint(&buf, arg1, sizeof(Oid));
00155 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00156 }
00157
00158
00159
00160
00161
00162
00163 oidvector *
00164 buildoidvector(const Oid *oids, int n)
00165 {
00166 oidvector *result;
00167
00168 result = (oidvector *) palloc0(OidVectorSize(n));
00169
00170 if (n > 0 && oids)
00171 memcpy(result->values, oids, n * sizeof(Oid));
00172
00173
00174
00175
00176
00177 SET_VARSIZE(result, OidVectorSize(n));
00178 result->ndim = 1;
00179 result->dataoffset = 0;
00180 result->elemtype = OIDOID;
00181 result->dim1 = n;
00182 result->lbound1 = 0;
00183
00184 return result;
00185 }
00186
00187
00188
00189
00190 Datum
00191 oidvectorin(PG_FUNCTION_ARGS)
00192 {
00193 char *oidString = PG_GETARG_CSTRING(0);
00194 oidvector *result;
00195 int n;
00196
00197 result = (oidvector *) palloc0(OidVectorSize(FUNC_MAX_ARGS));
00198
00199 for (n = 0; n < FUNC_MAX_ARGS; n++)
00200 {
00201 while (*oidString && isspace((unsigned char) *oidString))
00202 oidString++;
00203 if (*oidString == '\0')
00204 break;
00205 result->values[n] = oidin_subr(oidString, &oidString);
00206 }
00207 while (*oidString && isspace((unsigned char) *oidString))
00208 oidString++;
00209 if (*oidString)
00210 ereport(ERROR,
00211 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00212 errmsg("oidvector has too many elements")));
00213
00214 SET_VARSIZE(result, OidVectorSize(n));
00215 result->ndim = 1;
00216 result->dataoffset = 0;
00217 result->elemtype = OIDOID;
00218 result->dim1 = n;
00219 result->lbound1 = 0;
00220
00221 PG_RETURN_POINTER(result);
00222 }
00223
00224
00225
00226
00227 Datum
00228 oidvectorout(PG_FUNCTION_ARGS)
00229 {
00230 oidvector *oidArray = (oidvector *) PG_GETARG_POINTER(0);
00231 int num,
00232 nnums = oidArray->dim1;
00233 char *rp;
00234 char *result;
00235
00236
00237 rp = result = (char *) palloc(nnums * 12 + 1);
00238 for (num = 0; num < nnums; num++)
00239 {
00240 if (num != 0)
00241 *rp++ = ' ';
00242 sprintf(rp, "%u", oidArray->values[num]);
00243 while (*++rp != '\0')
00244 ;
00245 }
00246 *rp = '\0';
00247 PG_RETURN_CSTRING(result);
00248 }
00249
00250
00251
00252
00253 Datum
00254 oidvectorrecv(PG_FUNCTION_ARGS)
00255 {
00256 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
00257 FunctionCallInfoData locfcinfo;
00258 oidvector *result;
00259
00260
00261
00262
00263
00264
00265
00266 InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3,
00267 InvalidOid, NULL, NULL);
00268
00269 locfcinfo.arg[0] = PointerGetDatum(buf);
00270 locfcinfo.arg[1] = ObjectIdGetDatum(OIDOID);
00271 locfcinfo.arg[2] = Int32GetDatum(-1);
00272 locfcinfo.argnull[0] = false;
00273 locfcinfo.argnull[1] = false;
00274 locfcinfo.argnull[2] = false;
00275
00276 result = (oidvector *) DatumGetPointer(array_recv(&locfcinfo));
00277
00278 Assert(!locfcinfo.isnull);
00279
00280
00281 if (ARR_NDIM(result) != 1 ||
00282 ARR_HASNULL(result) ||
00283 ARR_ELEMTYPE(result) != OIDOID ||
00284 ARR_LBOUND(result)[0] != 0)
00285 ereport(ERROR,
00286 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
00287 errmsg("invalid oidvector data")));
00288
00289
00290 if (ARR_DIMS(result)[0] > FUNC_MAX_ARGS)
00291 ereport(ERROR,
00292 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00293 errmsg("oidvector has too many elements")));
00294
00295 PG_RETURN_POINTER(result);
00296 }
00297
00298
00299
00300
00301 Datum
00302 oidvectorsend(PG_FUNCTION_ARGS)
00303 {
00304 return array_send(fcinfo);
00305 }
00306
00307
00308
00309
00310 Oid
00311 oidparse(Node *node)
00312 {
00313 switch (nodeTag(node))
00314 {
00315 case T_Integer:
00316 return intVal(node);
00317 case T_Float:
00318
00319
00320
00321
00322
00323
00324 return oidin_subr(strVal(node), NULL);
00325 default:
00326 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
00327 }
00328 return InvalidOid;
00329 }
00330
00331
00332
00333
00334
00335
00336 Datum
00337 oideq(PG_FUNCTION_ARGS)
00338 {
00339 Oid arg1 = PG_GETARG_OID(0);
00340 Oid arg2 = PG_GETARG_OID(1);
00341
00342 PG_RETURN_BOOL(arg1 == arg2);
00343 }
00344
00345 Datum
00346 oidne(PG_FUNCTION_ARGS)
00347 {
00348 Oid arg1 = PG_GETARG_OID(0);
00349 Oid arg2 = PG_GETARG_OID(1);
00350
00351 PG_RETURN_BOOL(arg1 != arg2);
00352 }
00353
00354 Datum
00355 oidlt(PG_FUNCTION_ARGS)
00356 {
00357 Oid arg1 = PG_GETARG_OID(0);
00358 Oid arg2 = PG_GETARG_OID(1);
00359
00360 PG_RETURN_BOOL(arg1 < arg2);
00361 }
00362
00363 Datum
00364 oidle(PG_FUNCTION_ARGS)
00365 {
00366 Oid arg1 = PG_GETARG_OID(0);
00367 Oid arg2 = PG_GETARG_OID(1);
00368
00369 PG_RETURN_BOOL(arg1 <= arg2);
00370 }
00371
00372 Datum
00373 oidge(PG_FUNCTION_ARGS)
00374 {
00375 Oid arg1 = PG_GETARG_OID(0);
00376 Oid arg2 = PG_GETARG_OID(1);
00377
00378 PG_RETURN_BOOL(arg1 >= arg2);
00379 }
00380
00381 Datum
00382 oidgt(PG_FUNCTION_ARGS)
00383 {
00384 Oid arg1 = PG_GETARG_OID(0);
00385 Oid arg2 = PG_GETARG_OID(1);
00386
00387 PG_RETURN_BOOL(arg1 > arg2);
00388 }
00389
00390 Datum
00391 oidlarger(PG_FUNCTION_ARGS)
00392 {
00393 Oid arg1 = PG_GETARG_OID(0);
00394 Oid arg2 = PG_GETARG_OID(1);
00395
00396 PG_RETURN_OID((arg1 > arg2) ? arg1 : arg2);
00397 }
00398
00399 Datum
00400 oidsmaller(PG_FUNCTION_ARGS)
00401 {
00402 Oid arg1 = PG_GETARG_OID(0);
00403 Oid arg2 = PG_GETARG_OID(1);
00404
00405 PG_RETURN_OID((arg1 < arg2) ? arg1 : arg2);
00406 }
00407
00408 Datum
00409 oidvectoreq(PG_FUNCTION_ARGS)
00410 {
00411 int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
00412
00413 PG_RETURN_BOOL(cmp == 0);
00414 }
00415
00416 Datum
00417 oidvectorne(PG_FUNCTION_ARGS)
00418 {
00419 int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
00420
00421 PG_RETURN_BOOL(cmp != 0);
00422 }
00423
00424 Datum
00425 oidvectorlt(PG_FUNCTION_ARGS)
00426 {
00427 int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
00428
00429 PG_RETURN_BOOL(cmp < 0);
00430 }
00431
00432 Datum
00433 oidvectorle(PG_FUNCTION_ARGS)
00434 {
00435 int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
00436
00437 PG_RETURN_BOOL(cmp <= 0);
00438 }
00439
00440 Datum
00441 oidvectorge(PG_FUNCTION_ARGS)
00442 {
00443 int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
00444
00445 PG_RETURN_BOOL(cmp >= 0);
00446 }
00447
00448 Datum
00449 oidvectorgt(PG_FUNCTION_ARGS)
00450 {
00451 int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
00452
00453 PG_RETURN_BOOL(cmp > 0);
00454 }