00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "postgres.h"
00021
00022 #include <ctype.h>
00023
00024 #include "access/genam.h"
00025 #include "access/heapam.h"
00026 #include "access/htup_details.h"
00027 #include "catalog/indexing.h"
00028 #include "catalog/namespace.h"
00029 #include "catalog/pg_class.h"
00030 #include "catalog/pg_operator.h"
00031 #include "catalog/pg_proc.h"
00032 #include "catalog/pg_ts_config.h"
00033 #include "catalog/pg_ts_dict.h"
00034 #include "catalog/pg_type.h"
00035 #include "lib/stringinfo.h"
00036 #include "miscadmin.h"
00037 #include "parser/parse_type.h"
00038 #include "utils/builtins.h"
00039 #include "utils/fmgroids.h"
00040 #include "utils/lsyscache.h"
00041 #include "utils/syscache.h"
00042 #include "utils/tqual.h"
00043
00044 static char *format_operator_internal(Oid operator_oid, bool force_qualify);
00045 static char *format_procedure_internal(Oid procedure_oid, bool force_qualify);
00046 static void parseNameAndArgTypes(const char *string, bool allowNone,
00047 List **names, int *nargs, Oid *argtypes);
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 Datum
00063 regprocin(PG_FUNCTION_ARGS)
00064 {
00065 char *pro_name_or_oid = PG_GETARG_CSTRING(0);
00066 RegProcedure result = InvalidOid;
00067 List *names;
00068 FuncCandidateList clist;
00069
00070
00071 if (strcmp(pro_name_or_oid, "-") == 0)
00072 PG_RETURN_OID(InvalidOid);
00073
00074
00075 if (pro_name_or_oid[0] >= '0' &&
00076 pro_name_or_oid[0] <= '9' &&
00077 strspn(pro_name_or_oid, "0123456789") == strlen(pro_name_or_oid))
00078 {
00079 result = DatumGetObjectId(DirectFunctionCall1(oidin,
00080 CStringGetDatum(pro_name_or_oid)));
00081 PG_RETURN_OID(result);
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 if (IsBootstrapProcessingMode())
00093 {
00094 int matches = 0;
00095 Relation hdesc;
00096 ScanKeyData skey[1];
00097 SysScanDesc sysscan;
00098 HeapTuple tuple;
00099
00100 ScanKeyInit(&skey[0],
00101 Anum_pg_proc_proname,
00102 BTEqualStrategyNumber, F_NAMEEQ,
00103 CStringGetDatum(pro_name_or_oid));
00104
00105 hdesc = heap_open(ProcedureRelationId, AccessShareLock);
00106 sysscan = systable_beginscan(hdesc, ProcedureNameArgsNspIndexId, true,
00107 SnapshotNow, 1, skey);
00108
00109 while (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
00110 {
00111 result = (RegProcedure) HeapTupleGetOid(tuple);
00112 if (++matches > 1)
00113 break;
00114 }
00115
00116 systable_endscan(sysscan);
00117 heap_close(hdesc, AccessShareLock);
00118
00119 if (matches == 0)
00120 ereport(ERROR,
00121 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00122 errmsg("function \"%s\" does not exist", pro_name_or_oid)));
00123
00124 else if (matches > 1)
00125 ereport(ERROR,
00126 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
00127 errmsg("more than one function named \"%s\"",
00128 pro_name_or_oid)));
00129
00130 PG_RETURN_OID(result);
00131 }
00132
00133
00134
00135
00136
00137 names = stringToQualifiedNameList(pro_name_or_oid);
00138 clist = FuncnameGetCandidates(names, -1, NIL, false, false);
00139
00140 if (clist == NULL)
00141 ereport(ERROR,
00142 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00143 errmsg("function \"%s\" does not exist", pro_name_or_oid)));
00144 else if (clist->next != NULL)
00145 ereport(ERROR,
00146 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
00147 errmsg("more than one function named \"%s\"",
00148 pro_name_or_oid)));
00149
00150 result = clist->oid;
00151
00152 PG_RETURN_OID(result);
00153 }
00154
00155
00156
00157
00158 Datum
00159 regprocout(PG_FUNCTION_ARGS)
00160 {
00161 RegProcedure proid = PG_GETARG_OID(0);
00162 char *result;
00163 HeapTuple proctup;
00164
00165 if (proid == InvalidOid)
00166 {
00167 result = pstrdup("-");
00168 PG_RETURN_CSTRING(result);
00169 }
00170
00171 proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(proid));
00172
00173 if (HeapTupleIsValid(proctup))
00174 {
00175 Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
00176 char *proname = NameStr(procform->proname);
00177
00178
00179
00180
00181
00182
00183 if (IsBootstrapProcessingMode())
00184 result = pstrdup(proname);
00185 else
00186 {
00187 char *nspname;
00188 FuncCandidateList clist;
00189
00190
00191
00192
00193
00194 clist = FuncnameGetCandidates(list_make1(makeString(proname)),
00195 -1, NIL, false, false);
00196 if (clist != NULL && clist->next == NULL &&
00197 clist->oid == proid)
00198 nspname = NULL;
00199 else
00200 nspname = get_namespace_name(procform->pronamespace);
00201
00202 result = quote_qualified_identifier(nspname, proname);
00203 }
00204
00205 ReleaseSysCache(proctup);
00206 }
00207 else
00208 {
00209
00210 result = (char *) palloc(NAMEDATALEN);
00211 snprintf(result, NAMEDATALEN, "%u", proid);
00212 }
00213
00214 PG_RETURN_CSTRING(result);
00215 }
00216
00217
00218
00219
00220 Datum
00221 regprocrecv(PG_FUNCTION_ARGS)
00222 {
00223
00224 return oidrecv(fcinfo);
00225 }
00226
00227
00228
00229
00230 Datum
00231 regprocsend(PG_FUNCTION_ARGS)
00232 {
00233
00234 return oidsend(fcinfo);
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 Datum
00247 regprocedurein(PG_FUNCTION_ARGS)
00248 {
00249 char *pro_name_or_oid = PG_GETARG_CSTRING(0);
00250 RegProcedure result = InvalidOid;
00251 List *names;
00252 int nargs;
00253 Oid argtypes[FUNC_MAX_ARGS];
00254 FuncCandidateList clist;
00255
00256
00257 if (strcmp(pro_name_or_oid, "-") == 0)
00258 PG_RETURN_OID(InvalidOid);
00259
00260
00261 if (pro_name_or_oid[0] >= '0' &&
00262 pro_name_or_oid[0] <= '9' &&
00263 strspn(pro_name_or_oid, "0123456789") == strlen(pro_name_or_oid))
00264 {
00265 result = DatumGetObjectId(DirectFunctionCall1(oidin,
00266 CStringGetDatum(pro_name_or_oid)));
00267 PG_RETURN_OID(result);
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 parseNameAndArgTypes(pro_name_or_oid, false, &names, &nargs, argtypes);
00281
00282 clist = FuncnameGetCandidates(names, nargs, NIL, false, false);
00283
00284 for (; clist; clist = clist->next)
00285 {
00286 if (memcmp(clist->args, argtypes, nargs * sizeof(Oid)) == 0)
00287 break;
00288 }
00289
00290 if (clist == NULL)
00291 ereport(ERROR,
00292 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00293 errmsg("function \"%s\" does not exist", pro_name_or_oid)));
00294
00295 result = clist->oid;
00296
00297 PG_RETURN_OID(result);
00298 }
00299
00300
00301
00302
00303
00304
00305
00306 char *
00307 format_procedure(Oid procedure_oid)
00308 {
00309 return format_procedure_internal(procedure_oid, false);
00310 }
00311
00312 char *
00313 format_procedure_qualified(Oid procedure_oid)
00314 {
00315 return format_procedure_internal(procedure_oid, true);
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325 static char *
00326 format_procedure_internal(Oid procedure_oid, bool force_qualify)
00327 {
00328 char *result;
00329 HeapTuple proctup;
00330
00331 proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procedure_oid));
00332
00333 if (HeapTupleIsValid(proctup))
00334 {
00335 Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
00336 char *proname = NameStr(procform->proname);
00337 int nargs = procform->pronargs;
00338 int i;
00339 char *nspname;
00340 StringInfoData buf;
00341
00342
00343
00344 initStringInfo(&buf);
00345
00346
00347
00348
00349
00350 if (!force_qualify && FunctionIsVisible(procedure_oid))
00351 nspname = NULL;
00352 else
00353 nspname = get_namespace_name(procform->pronamespace);
00354
00355 appendStringInfo(&buf, "%s(",
00356 quote_qualified_identifier(nspname, proname));
00357 for (i = 0; i < nargs; i++)
00358 {
00359 Oid thisargtype = procform->proargtypes.values[i];
00360
00361 if (i > 0)
00362 appendStringInfoChar(&buf, ',');
00363 appendStringInfoString(&buf,
00364 force_qualify ?
00365 format_type_be_qualified(thisargtype) :
00366 format_type_be(thisargtype));
00367 }
00368 appendStringInfoChar(&buf, ')');
00369
00370 result = buf.data;
00371
00372 ReleaseSysCache(proctup);
00373 }
00374 else
00375 {
00376
00377 result = (char *) palloc(NAMEDATALEN);
00378 snprintf(result, NAMEDATALEN, "%u", procedure_oid);
00379 }
00380
00381 return result;
00382 }
00383
00384
00385
00386
00387 Datum
00388 regprocedureout(PG_FUNCTION_ARGS)
00389 {
00390 RegProcedure proid = PG_GETARG_OID(0);
00391 char *result;
00392
00393 if (proid == InvalidOid)
00394 result = pstrdup("-");
00395 else
00396 result = format_procedure(proid);
00397
00398 PG_RETURN_CSTRING(result);
00399 }
00400
00401
00402
00403
00404 Datum
00405 regprocedurerecv(PG_FUNCTION_ARGS)
00406 {
00407
00408 return oidrecv(fcinfo);
00409 }
00410
00411
00412
00413
00414 Datum
00415 regproceduresend(PG_FUNCTION_ARGS)
00416 {
00417
00418 return oidsend(fcinfo);
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 Datum
00431 regoperin(PG_FUNCTION_ARGS)
00432 {
00433 char *opr_name_or_oid = PG_GETARG_CSTRING(0);
00434 Oid result = InvalidOid;
00435 List *names;
00436 FuncCandidateList clist;
00437
00438
00439 if (strcmp(opr_name_or_oid, "0") == 0)
00440 PG_RETURN_OID(InvalidOid);
00441
00442
00443 if (opr_name_or_oid[0] >= '0' &&
00444 opr_name_or_oid[0] <= '9' &&
00445 strspn(opr_name_or_oid, "0123456789") == strlen(opr_name_or_oid))
00446 {
00447 result = DatumGetObjectId(DirectFunctionCall1(oidin,
00448 CStringGetDatum(opr_name_or_oid)));
00449 PG_RETURN_OID(result);
00450 }
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 if (IsBootstrapProcessingMode())
00461 {
00462 int matches = 0;
00463 Relation hdesc;
00464 ScanKeyData skey[1];
00465 SysScanDesc sysscan;
00466 HeapTuple tuple;
00467
00468 ScanKeyInit(&skey[0],
00469 Anum_pg_operator_oprname,
00470 BTEqualStrategyNumber, F_NAMEEQ,
00471 CStringGetDatum(opr_name_or_oid));
00472
00473 hdesc = heap_open(OperatorRelationId, AccessShareLock);
00474 sysscan = systable_beginscan(hdesc, OperatorNameNspIndexId, true,
00475 SnapshotNow, 1, skey);
00476
00477 while (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
00478 {
00479 result = HeapTupleGetOid(tuple);
00480 if (++matches > 1)
00481 break;
00482 }
00483
00484 systable_endscan(sysscan);
00485 heap_close(hdesc, AccessShareLock);
00486
00487 if (matches == 0)
00488 ereport(ERROR,
00489 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00490 errmsg("operator does not exist: %s", opr_name_or_oid)));
00491 else if (matches > 1)
00492 ereport(ERROR,
00493 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
00494 errmsg("more than one operator named %s",
00495 opr_name_or_oid)));
00496
00497 PG_RETURN_OID(result);
00498 }
00499
00500
00501
00502
00503
00504 names = stringToQualifiedNameList(opr_name_or_oid);
00505 clist = OpernameGetCandidates(names, '\0');
00506
00507 if (clist == NULL)
00508 ereport(ERROR,
00509 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00510 errmsg("operator does not exist: %s", opr_name_or_oid)));
00511 else if (clist->next != NULL)
00512 ereport(ERROR,
00513 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
00514 errmsg("more than one operator named %s",
00515 opr_name_or_oid)));
00516
00517 result = clist->oid;
00518
00519 PG_RETURN_OID(result);
00520 }
00521
00522
00523
00524
00525 Datum
00526 regoperout(PG_FUNCTION_ARGS)
00527 {
00528 Oid oprid = PG_GETARG_OID(0);
00529 char *result;
00530 HeapTuple opertup;
00531
00532 if (oprid == InvalidOid)
00533 {
00534 result = pstrdup("0");
00535 PG_RETURN_CSTRING(result);
00536 }
00537
00538 opertup = SearchSysCache1(OPEROID, ObjectIdGetDatum(oprid));
00539
00540 if (HeapTupleIsValid(opertup))
00541 {
00542 Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
00543 char *oprname = NameStr(operform->oprname);
00544
00545
00546
00547
00548
00549
00550 if (IsBootstrapProcessingMode())
00551 result = pstrdup(oprname);
00552 else
00553 {
00554 FuncCandidateList clist;
00555
00556
00557
00558
00559
00560 clist = OpernameGetCandidates(list_make1(makeString(oprname)),
00561 '\0');
00562 if (clist != NULL && clist->next == NULL &&
00563 clist->oid == oprid)
00564 result = pstrdup(oprname);
00565 else
00566 {
00567 const char *nspname;
00568
00569 nspname = get_namespace_name(operform->oprnamespace);
00570 nspname = quote_identifier(nspname);
00571 result = (char *) palloc(strlen(nspname) + strlen(oprname) + 2);
00572 sprintf(result, "%s.%s", nspname, oprname);
00573 }
00574 }
00575
00576 ReleaseSysCache(opertup);
00577 }
00578 else
00579 {
00580
00581
00582
00583 result = (char *) palloc(NAMEDATALEN);
00584 snprintf(result, NAMEDATALEN, "%u", oprid);
00585 }
00586
00587 PG_RETURN_CSTRING(result);
00588 }
00589
00590
00591
00592
00593 Datum
00594 regoperrecv(PG_FUNCTION_ARGS)
00595 {
00596
00597 return oidrecv(fcinfo);
00598 }
00599
00600
00601
00602
00603 Datum
00604 regopersend(PG_FUNCTION_ARGS)
00605 {
00606
00607 return oidsend(fcinfo);
00608 }
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 Datum
00620 regoperatorin(PG_FUNCTION_ARGS)
00621 {
00622 char *opr_name_or_oid = PG_GETARG_CSTRING(0);
00623 Oid result;
00624 List *names;
00625 int nargs;
00626 Oid argtypes[FUNC_MAX_ARGS];
00627
00628
00629 if (strcmp(opr_name_or_oid, "0") == 0)
00630 PG_RETURN_OID(InvalidOid);
00631
00632
00633 if (opr_name_or_oid[0] >= '0' &&
00634 opr_name_or_oid[0] <= '9' &&
00635 strspn(opr_name_or_oid, "0123456789") == strlen(opr_name_or_oid))
00636 {
00637 result = DatumGetObjectId(DirectFunctionCall1(oidin,
00638 CStringGetDatum(opr_name_or_oid)));
00639 PG_RETURN_OID(result);
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 parseNameAndArgTypes(opr_name_or_oid, true, &names, &nargs, argtypes);
00653 if (nargs == 1)
00654 ereport(ERROR,
00655 (errcode(ERRCODE_UNDEFINED_PARAMETER),
00656 errmsg("missing argument"),
00657 errhint("Use NONE to denote the missing argument of a unary operator.")));
00658 if (nargs != 2)
00659 ereport(ERROR,
00660 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
00661 errmsg("too many arguments"),
00662 errhint("Provide two argument types for operator.")));
00663
00664 result = OpernameGetOprid(names, argtypes[0], argtypes[1]);
00665
00666 if (!OidIsValid(result))
00667 ereport(ERROR,
00668 (errcode(ERRCODE_UNDEFINED_FUNCTION),
00669 errmsg("operator does not exist: %s", opr_name_or_oid)));
00670
00671 PG_RETURN_OID(result);
00672 }
00673
00674
00675
00676
00677
00678
00679
00680 static char *
00681 format_operator_internal(Oid operator_oid, bool force_qualify)
00682 {
00683 char *result;
00684 HeapTuple opertup;
00685
00686 opertup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operator_oid));
00687
00688 if (HeapTupleIsValid(opertup))
00689 {
00690 Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
00691 char *oprname = NameStr(operform->oprname);
00692 char *nspname;
00693 StringInfoData buf;
00694
00695
00696
00697 initStringInfo(&buf);
00698
00699
00700
00701
00702
00703 if (force_qualify || !OperatorIsVisible(operator_oid))
00704 {
00705 nspname = get_namespace_name(operform->oprnamespace);
00706 appendStringInfo(&buf, "%s.",
00707 quote_identifier(nspname));
00708 }
00709
00710 appendStringInfo(&buf, "%s(", oprname);
00711
00712 if (operform->oprleft)
00713 appendStringInfo(&buf, "%s,",
00714 force_qualify ?
00715 format_type_be_qualified(operform->oprleft) :
00716 format_type_be(operform->oprleft));
00717 else
00718 appendStringInfo(&buf, "NONE,");
00719
00720 if (operform->oprright)
00721 appendStringInfo(&buf, "%s)",
00722 force_qualify ?
00723 format_type_be_qualified(operform->oprright) :
00724 format_type_be(operform->oprright));
00725 else
00726 appendStringInfo(&buf, "NONE)");
00727
00728 result = buf.data;
00729
00730 ReleaseSysCache(opertup);
00731 }
00732 else
00733 {
00734
00735
00736
00737 result = (char *) palloc(NAMEDATALEN);
00738 snprintf(result, NAMEDATALEN, "%u", operator_oid);
00739 }
00740
00741 return result;
00742 }
00743
00744 char *
00745 format_operator(Oid operator_oid)
00746 {
00747 return format_operator_internal(operator_oid, false);
00748 }
00749
00750 char *
00751 format_operator_qualified(Oid operator_oid)
00752 {
00753 return format_operator_internal(operator_oid, true);
00754 }
00755
00756
00757
00758
00759 Datum
00760 regoperatorout(PG_FUNCTION_ARGS)
00761 {
00762 Oid oprid = PG_GETARG_OID(0);
00763 char *result;
00764
00765 if (oprid == InvalidOid)
00766 result = pstrdup("0");
00767 else
00768 result = format_operator(oprid);
00769
00770 PG_RETURN_CSTRING(result);
00771 }
00772
00773
00774
00775
00776 Datum
00777 regoperatorrecv(PG_FUNCTION_ARGS)
00778 {
00779
00780 return oidrecv(fcinfo);
00781 }
00782
00783
00784
00785
00786 Datum
00787 regoperatorsend(PG_FUNCTION_ARGS)
00788 {
00789
00790 return oidsend(fcinfo);
00791 }
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802 Datum
00803 regclassin(PG_FUNCTION_ARGS)
00804 {
00805 char *class_name_or_oid = PG_GETARG_CSTRING(0);
00806 Oid result = InvalidOid;
00807 List *names;
00808
00809
00810 if (strcmp(class_name_or_oid, "-") == 0)
00811 PG_RETURN_OID(InvalidOid);
00812
00813
00814 if (class_name_or_oid[0] >= '0' &&
00815 class_name_or_oid[0] <= '9' &&
00816 strspn(class_name_or_oid, "0123456789") == strlen(class_name_or_oid))
00817 {
00818 result = DatumGetObjectId(DirectFunctionCall1(oidin,
00819 CStringGetDatum(class_name_or_oid)));
00820 PG_RETURN_OID(result);
00821 }
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831 if (IsBootstrapProcessingMode())
00832 {
00833 Relation hdesc;
00834 ScanKeyData skey[1];
00835 SysScanDesc sysscan;
00836 HeapTuple tuple;
00837
00838 ScanKeyInit(&skey[0],
00839 Anum_pg_class_relname,
00840 BTEqualStrategyNumber, F_NAMEEQ,
00841 CStringGetDatum(class_name_or_oid));
00842
00843 hdesc = heap_open(RelationRelationId, AccessShareLock);
00844 sysscan = systable_beginscan(hdesc, ClassNameNspIndexId, true,
00845 SnapshotNow, 1, skey);
00846
00847 if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
00848 result = HeapTupleGetOid(tuple);
00849 else
00850 ereport(ERROR,
00851 (errcode(ERRCODE_UNDEFINED_TABLE),
00852 errmsg("relation \"%s\" does not exist", class_name_or_oid)));
00853
00854
00855
00856 systable_endscan(sysscan);
00857 heap_close(hdesc, AccessShareLock);
00858
00859 PG_RETURN_OID(result);
00860 }
00861
00862
00863
00864
00865
00866 names = stringToQualifiedNameList(class_name_or_oid);
00867
00868
00869 result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, false);
00870
00871 PG_RETURN_OID(result);
00872 }
00873
00874
00875
00876
00877 Datum
00878 regclassout(PG_FUNCTION_ARGS)
00879 {
00880 Oid classid = PG_GETARG_OID(0);
00881 char *result;
00882 HeapTuple classtup;
00883
00884 if (classid == InvalidOid)
00885 {
00886 result = pstrdup("-");
00887 PG_RETURN_CSTRING(result);
00888 }
00889
00890 classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(classid));
00891
00892 if (HeapTupleIsValid(classtup))
00893 {
00894 Form_pg_class classform = (Form_pg_class) GETSTRUCT(classtup);
00895 char *classname = NameStr(classform->relname);
00896
00897
00898
00899
00900
00901
00902 if (IsBootstrapProcessingMode())
00903 result = pstrdup(classname);
00904 else
00905 {
00906 char *nspname;
00907
00908
00909
00910
00911 if (RelationIsVisible(classid))
00912 nspname = NULL;
00913 else
00914 nspname = get_namespace_name(classform->relnamespace);
00915
00916 result = quote_qualified_identifier(nspname, classname);
00917 }
00918
00919 ReleaseSysCache(classtup);
00920 }
00921 else
00922 {
00923
00924 result = (char *) palloc(NAMEDATALEN);
00925 snprintf(result, NAMEDATALEN, "%u", classid);
00926 }
00927
00928 PG_RETURN_CSTRING(result);
00929 }
00930
00931
00932
00933
00934 Datum
00935 regclassrecv(PG_FUNCTION_ARGS)
00936 {
00937
00938 return oidrecv(fcinfo);
00939 }
00940
00941
00942
00943
00944 Datum
00945 regclasssend(PG_FUNCTION_ARGS)
00946 {
00947
00948 return oidsend(fcinfo);
00949 }
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 Datum
00967 regtypein(PG_FUNCTION_ARGS)
00968 {
00969 char *typ_name_or_oid = PG_GETARG_CSTRING(0);
00970 Oid result = InvalidOid;
00971 int32 typmod;
00972
00973
00974 if (strcmp(typ_name_or_oid, "-") == 0)
00975 PG_RETURN_OID(InvalidOid);
00976
00977
00978 if (typ_name_or_oid[0] >= '0' &&
00979 typ_name_or_oid[0] <= '9' &&
00980 strspn(typ_name_or_oid, "0123456789") == strlen(typ_name_or_oid))
00981 {
00982 result = DatumGetObjectId(DirectFunctionCall1(oidin,
00983 CStringGetDatum(typ_name_or_oid)));
00984 PG_RETURN_OID(result);
00985 }
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995 if (IsBootstrapProcessingMode())
00996 {
00997 Relation hdesc;
00998 ScanKeyData skey[1];
00999 SysScanDesc sysscan;
01000 HeapTuple tuple;
01001
01002 ScanKeyInit(&skey[0],
01003 Anum_pg_type_typname,
01004 BTEqualStrategyNumber, F_NAMEEQ,
01005 CStringGetDatum(typ_name_or_oid));
01006
01007 hdesc = heap_open(TypeRelationId, AccessShareLock);
01008 sysscan = systable_beginscan(hdesc, TypeNameNspIndexId, true,
01009 SnapshotNow, 1, skey);
01010
01011 if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
01012 result = HeapTupleGetOid(tuple);
01013 else
01014 ereport(ERROR,
01015 (errcode(ERRCODE_UNDEFINED_OBJECT),
01016 errmsg("type \"%s\" does not exist", typ_name_or_oid)));
01017
01018
01019
01020 systable_endscan(sysscan);
01021 heap_close(hdesc, AccessShareLock);
01022
01023 PG_RETURN_OID(result);
01024 }
01025
01026
01027
01028
01029
01030 parseTypeString(typ_name_or_oid, &result, &typmod);
01031
01032 PG_RETURN_OID(result);
01033 }
01034
01035
01036
01037
01038 Datum
01039 regtypeout(PG_FUNCTION_ARGS)
01040 {
01041 Oid typid = PG_GETARG_OID(0);
01042 char *result;
01043 HeapTuple typetup;
01044
01045 if (typid == InvalidOid)
01046 {
01047 result = pstrdup("-");
01048 PG_RETURN_CSTRING(result);
01049 }
01050
01051 typetup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
01052
01053 if (HeapTupleIsValid(typetup))
01054 {
01055 Form_pg_type typeform = (Form_pg_type) GETSTRUCT(typetup);
01056
01057
01058
01059
01060
01061
01062 if (IsBootstrapProcessingMode())
01063 {
01064 char *typname = NameStr(typeform->typname);
01065
01066 result = pstrdup(typname);
01067 }
01068 else
01069 result = format_type_be(typid);
01070
01071 ReleaseSysCache(typetup);
01072 }
01073 else
01074 {
01075
01076 result = (char *) palloc(NAMEDATALEN);
01077 snprintf(result, NAMEDATALEN, "%u", typid);
01078 }
01079
01080 PG_RETURN_CSTRING(result);
01081 }
01082
01083
01084
01085
01086 Datum
01087 regtyperecv(PG_FUNCTION_ARGS)
01088 {
01089
01090 return oidrecv(fcinfo);
01091 }
01092
01093
01094
01095
01096 Datum
01097 regtypesend(PG_FUNCTION_ARGS)
01098 {
01099
01100 return oidsend(fcinfo);
01101 }
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115 Datum
01116 regconfigin(PG_FUNCTION_ARGS)
01117 {
01118 char *cfg_name_or_oid = PG_GETARG_CSTRING(0);
01119 Oid result;
01120 List *names;
01121
01122
01123 if (strcmp(cfg_name_or_oid, "-") == 0)
01124 PG_RETURN_OID(InvalidOid);
01125
01126
01127 if (cfg_name_or_oid[0] >= '0' &&
01128 cfg_name_or_oid[0] <= '9' &&
01129 strspn(cfg_name_or_oid, "0123456789") == strlen(cfg_name_or_oid))
01130 {
01131 result = DatumGetObjectId(DirectFunctionCall1(oidin,
01132 CStringGetDatum(cfg_name_or_oid)));
01133 PG_RETURN_OID(result);
01134 }
01135
01136
01137
01138
01139
01140 names = stringToQualifiedNameList(cfg_name_or_oid);
01141
01142 result = get_ts_config_oid(names, false);
01143
01144 PG_RETURN_OID(result);
01145 }
01146
01147
01148
01149
01150 Datum
01151 regconfigout(PG_FUNCTION_ARGS)
01152 {
01153 Oid cfgid = PG_GETARG_OID(0);
01154 char *result;
01155 HeapTuple cfgtup;
01156
01157 if (cfgid == InvalidOid)
01158 {
01159 result = pstrdup("-");
01160 PG_RETURN_CSTRING(result);
01161 }
01162
01163 cfgtup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfgid));
01164
01165 if (HeapTupleIsValid(cfgtup))
01166 {
01167 Form_pg_ts_config cfgform = (Form_pg_ts_config) GETSTRUCT(cfgtup);
01168 char *cfgname = NameStr(cfgform->cfgname);
01169 char *nspname;
01170
01171
01172
01173
01174 if (TSConfigIsVisible(cfgid))
01175 nspname = NULL;
01176 else
01177 nspname = get_namespace_name(cfgform->cfgnamespace);
01178
01179 result = quote_qualified_identifier(nspname, cfgname);
01180
01181 ReleaseSysCache(cfgtup);
01182 }
01183 else
01184 {
01185
01186 result = (char *) palloc(NAMEDATALEN);
01187 snprintf(result, NAMEDATALEN, "%u", cfgid);
01188 }
01189
01190 PG_RETURN_CSTRING(result);
01191 }
01192
01193
01194
01195
01196 Datum
01197 regconfigrecv(PG_FUNCTION_ARGS)
01198 {
01199
01200 return oidrecv(fcinfo);
01201 }
01202
01203
01204
01205
01206 Datum
01207 regconfigsend(PG_FUNCTION_ARGS)
01208 {
01209
01210 return oidsend(fcinfo);
01211 }
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225 Datum
01226 regdictionaryin(PG_FUNCTION_ARGS)
01227 {
01228 char *dict_name_or_oid = PG_GETARG_CSTRING(0);
01229 Oid result;
01230 List *names;
01231
01232
01233 if (strcmp(dict_name_or_oid, "-") == 0)
01234 PG_RETURN_OID(InvalidOid);
01235
01236
01237 if (dict_name_or_oid[0] >= '0' &&
01238 dict_name_or_oid[0] <= '9' &&
01239 strspn(dict_name_or_oid, "0123456789") == strlen(dict_name_or_oid))
01240 {
01241 result = DatumGetObjectId(DirectFunctionCall1(oidin,
01242 CStringGetDatum(dict_name_or_oid)));
01243 PG_RETURN_OID(result);
01244 }
01245
01246
01247
01248
01249
01250 names = stringToQualifiedNameList(dict_name_or_oid);
01251
01252 result = get_ts_dict_oid(names, false);
01253
01254 PG_RETURN_OID(result);
01255 }
01256
01257
01258
01259
01260 Datum
01261 regdictionaryout(PG_FUNCTION_ARGS)
01262 {
01263 Oid dictid = PG_GETARG_OID(0);
01264 char *result;
01265 HeapTuple dicttup;
01266
01267 if (dictid == InvalidOid)
01268 {
01269 result = pstrdup("-");
01270 PG_RETURN_CSTRING(result);
01271 }
01272
01273 dicttup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictid));
01274
01275 if (HeapTupleIsValid(dicttup))
01276 {
01277 Form_pg_ts_dict dictform = (Form_pg_ts_dict) GETSTRUCT(dicttup);
01278 char *dictname = NameStr(dictform->dictname);
01279 char *nspname;
01280
01281
01282
01283
01284
01285 if (TSDictionaryIsVisible(dictid))
01286 nspname = NULL;
01287 else
01288 nspname = get_namespace_name(dictform->dictnamespace);
01289
01290 result = quote_qualified_identifier(nspname, dictname);
01291
01292 ReleaseSysCache(dicttup);
01293 }
01294 else
01295 {
01296
01297 result = (char *) palloc(NAMEDATALEN);
01298 snprintf(result, NAMEDATALEN, "%u", dictid);
01299 }
01300
01301 PG_RETURN_CSTRING(result);
01302 }
01303
01304
01305
01306
01307 Datum
01308 regdictionaryrecv(PG_FUNCTION_ARGS)
01309 {
01310
01311 return oidrecv(fcinfo);
01312 }
01313
01314
01315
01316
01317 Datum
01318 regdictionarysend(PG_FUNCTION_ARGS)
01319 {
01320
01321 return oidsend(fcinfo);
01322 }
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332 Datum
01333 text_regclass(PG_FUNCTION_ARGS)
01334 {
01335 text *relname = PG_GETARG_TEXT_P(0);
01336 Oid result;
01337 RangeVar *rv;
01338
01339 rv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
01340
01341
01342 result = RangeVarGetRelid(rv, NoLock, false);
01343
01344 PG_RETURN_OID(result);
01345 }
01346
01347
01348
01349
01350
01351 List *
01352 stringToQualifiedNameList(const char *string)
01353 {
01354 char *rawname;
01355 List *result = NIL;
01356 List *namelist;
01357 ListCell *l;
01358
01359
01360 rawname = pstrdup(string);
01361
01362 if (!SplitIdentifierString(rawname, '.', &namelist))
01363 ereport(ERROR,
01364 (errcode(ERRCODE_INVALID_NAME),
01365 errmsg("invalid name syntax")));
01366
01367 if (namelist == NIL)
01368 ereport(ERROR,
01369 (errcode(ERRCODE_INVALID_NAME),
01370 errmsg("invalid name syntax")));
01371
01372 foreach(l, namelist)
01373 {
01374 char *curname = (char *) lfirst(l);
01375
01376 result = lappend(result, makeString(pstrdup(curname)));
01377 }
01378
01379 pfree(rawname);
01380 list_free(namelist);
01381
01382 return result;
01383 }
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399 static void
01400 parseNameAndArgTypes(const char *string, bool allowNone, List **names,
01401 int *nargs, Oid *argtypes)
01402 {
01403 char *rawname;
01404 char *ptr;
01405 char *ptr2;
01406 char *typename;
01407 bool in_quote;
01408 bool had_comma;
01409 int paren_count;
01410 Oid typeid;
01411 int32 typmod;
01412
01413
01414 rawname = pstrdup(string);
01415
01416
01417 in_quote = false;
01418 for (ptr = rawname; *ptr; ptr++)
01419 {
01420 if (*ptr == '"')
01421 in_quote = !in_quote;
01422 else if (*ptr == '(' && !in_quote)
01423 break;
01424 }
01425 if (*ptr == '\0')
01426 ereport(ERROR,
01427 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
01428 errmsg("expected a left parenthesis")));
01429
01430
01431 *ptr++ = '\0';
01432 *names = stringToQualifiedNameList(rawname);
01433
01434
01435 ptr2 = ptr + strlen(ptr);
01436 while (--ptr2 > ptr)
01437 {
01438 if (!isspace((unsigned char) *ptr2))
01439 break;
01440 }
01441 if (*ptr2 != ')')
01442 ereport(ERROR,
01443 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
01444 errmsg("expected a right parenthesis")));
01445
01446 *ptr2 = '\0';
01447
01448
01449 *nargs = 0;
01450 had_comma = false;
01451
01452 for (;;)
01453 {
01454
01455 while (isspace((unsigned char) *ptr))
01456 ptr++;
01457 if (*ptr == '\0')
01458 {
01459
01460 if (had_comma)
01461 ereport(ERROR,
01462 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
01463 errmsg("expected a type name")));
01464 break;
01465 }
01466 typename = ptr;
01467
01468
01469 in_quote = false;
01470 paren_count = 0;
01471 for (; *ptr; ptr++)
01472 {
01473 if (*ptr == '"')
01474 in_quote = !in_quote;
01475 else if (*ptr == ',' && !in_quote && paren_count == 0)
01476 break;
01477 else if (!in_quote)
01478 {
01479 switch (*ptr)
01480 {
01481 case '(':
01482 case '[':
01483 paren_count++;
01484 break;
01485 case ')':
01486 case ']':
01487 paren_count--;
01488 break;
01489 }
01490 }
01491 }
01492 if (in_quote || paren_count != 0)
01493 ereport(ERROR,
01494 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
01495 errmsg("improper type name")));
01496
01497 ptr2 = ptr;
01498 if (*ptr == ',')
01499 {
01500 had_comma = true;
01501 *ptr++ = '\0';
01502 }
01503 else
01504 {
01505 had_comma = false;
01506 Assert(*ptr == '\0');
01507 }
01508
01509 while (--ptr2 >= typename)
01510 {
01511 if (!isspace((unsigned char) *ptr2))
01512 break;
01513 *ptr2 = '\0';
01514 }
01515
01516 if (allowNone && pg_strcasecmp(typename, "none") == 0)
01517 {
01518
01519 typeid = InvalidOid;
01520 typmod = -1;
01521 }
01522 else
01523 {
01524
01525 parseTypeString(typename, &typeid, &typmod);
01526 }
01527 if (*nargs >= FUNC_MAX_ARGS)
01528 ereport(ERROR,
01529 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
01530 errmsg("too many arguments")));
01531
01532 argtypes[*nargs] = typeid;
01533 (*nargs)++;
01534 }
01535
01536 pfree(rawname);
01537 }