00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "postgres.h"
00016
00017 #include "access/heapam.h"
00018 #include "access/htup_details.h"
00019 #include "catalog/pg_type.h"
00020 #include "mb/pg_wchar.h"
00021 #include "nodes/makefuncs.h"
00022 #include "nodes/nodeFuncs.h"
00023 #include "parser/parsetree.h"
00024 #include "parser/parse_coerce.h"
00025 #include "parser/parse_expr.h"
00026 #include "parser/parse_relation.h"
00027 #include "utils/builtins.h"
00028 #include "utils/int8.h"
00029 #include "utils/lsyscache.h"
00030 #include "utils/syscache.h"
00031 #include "utils/varbit.h"
00032
00033
00034 static void pcb_error_callback(void *arg);
00035
00036
00037
00038
00039
00040
00041
00042
00043 ParseState *
00044 make_parsestate(ParseState *parentParseState)
00045 {
00046 ParseState *pstate;
00047
00048 pstate = palloc0(sizeof(ParseState));
00049
00050 pstate->parentParseState = parentParseState;
00051
00052
00053 pstate->p_next_resno = 1;
00054
00055 if (parentParseState)
00056 {
00057 pstate->p_sourcetext = parentParseState->p_sourcetext;
00058
00059 pstate->p_pre_columnref_hook = parentParseState->p_pre_columnref_hook;
00060 pstate->p_post_columnref_hook = parentParseState->p_post_columnref_hook;
00061 pstate->p_paramref_hook = parentParseState->p_paramref_hook;
00062 pstate->p_coerce_param_hook = parentParseState->p_coerce_param_hook;
00063 pstate->p_ref_hook_state = parentParseState->p_ref_hook_state;
00064 }
00065
00066 return pstate;
00067 }
00068
00069
00070
00071
00072
00073 void
00074 free_parsestate(ParseState *pstate)
00075 {
00076
00077
00078
00079
00080
00081 if (pstate->p_next_resno - 1 > MaxTupleAttributeNumber)
00082 ereport(ERROR,
00083 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
00084 errmsg("target lists can have at most %d entries",
00085 MaxTupleAttributeNumber)));
00086
00087 if (pstate->p_target_relation != NULL)
00088 heap_close(pstate->p_target_relation, NoLock);
00089
00090 pfree(pstate);
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 int
00108 parser_errposition(ParseState *pstate, int location)
00109 {
00110 int pos;
00111
00112
00113 if (location < 0)
00114 return 0;
00115
00116 if (pstate == NULL || pstate->p_sourcetext == NULL)
00117 return 0;
00118
00119 pos = pg_mbstrlen_with_len(pstate->p_sourcetext, location) + 1;
00120
00121 return errposition(pos);
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 void
00142 setup_parser_errposition_callback(ParseCallbackState *pcbstate,
00143 ParseState *pstate, int location)
00144 {
00145
00146 pcbstate->pstate = pstate;
00147 pcbstate->location = location;
00148 pcbstate->errcallback.callback = pcb_error_callback;
00149 pcbstate->errcallback.arg = (void *) pcbstate;
00150 pcbstate->errcallback.previous = error_context_stack;
00151 error_context_stack = &pcbstate->errcallback;
00152 }
00153
00154
00155
00156
00157 void
00158 cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
00159 {
00160
00161 error_context_stack = pcbstate->errcallback.previous;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171 static void
00172 pcb_error_callback(void *arg)
00173 {
00174 ParseCallbackState *pcbstate = (ParseCallbackState *) arg;
00175
00176 if (geterrcode() != ERRCODE_QUERY_CANCELED)
00177 (void) parser_errposition(pcbstate->pstate, pcbstate->location);
00178 }
00179
00180
00181
00182
00183
00184
00185 Var *
00186 make_var(ParseState *pstate, RangeTblEntry *rte, int attrno, int location)
00187 {
00188 Var *result;
00189 int vnum,
00190 sublevels_up;
00191 Oid vartypeid;
00192 int32 type_mod;
00193 Oid varcollid;
00194
00195 vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
00196 get_rte_attribute_type(rte, attrno, &vartypeid, &type_mod, &varcollid);
00197 result = makeVar(vnum, attrno, vartypeid, type_mod, varcollid, sublevels_up);
00198 result->location = location;
00199 return result;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 Oid
00213 transformArrayType(Oid *arrayType, int32 *arrayTypmod)
00214 {
00215 Oid origArrayType = *arrayType;
00216 Oid elementType;
00217 HeapTuple type_tuple_array;
00218 Form_pg_type type_struct_array;
00219
00220
00221
00222
00223
00224
00225
00226
00227 *arrayType = getBaseTypeAndTypmod(*arrayType, arrayTypmod);
00228
00229
00230 type_tuple_array = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*arrayType));
00231 if (!HeapTupleIsValid(type_tuple_array))
00232 elog(ERROR, "cache lookup failed for type %u", *arrayType);
00233 type_struct_array = (Form_pg_type) GETSTRUCT(type_tuple_array);
00234
00235
00236
00237 elementType = type_struct_array->typelem;
00238 if (elementType == InvalidOid)
00239 ereport(ERROR,
00240 (errcode(ERRCODE_DATATYPE_MISMATCH),
00241 errmsg("cannot subscript type %s because it is not an array",
00242 format_type_be(origArrayType))));
00243
00244 ReleaseSysCache(type_tuple_array);
00245
00246 return elementType;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 ArrayRef *
00278 transformArraySubscripts(ParseState *pstate,
00279 Node *arrayBase,
00280 Oid arrayType,
00281 Oid elementType,
00282 int32 arrayTypMod,
00283 List *indirection,
00284 Node *assignFrom)
00285 {
00286 bool isSlice = false;
00287 List *upperIndexpr = NIL;
00288 List *lowerIndexpr = NIL;
00289 ListCell *idx;
00290 ArrayRef *aref;
00291
00292
00293
00294
00295
00296
00297 if (!OidIsValid(elementType))
00298 elementType = transformArrayType(&arrayType, &arrayTypMod);
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 foreach(idx, indirection)
00309 {
00310 A_Indices *ai = (A_Indices *) lfirst(idx);
00311
00312 if (ai->lidx != NULL)
00313 {
00314 isSlice = true;
00315 break;
00316 }
00317 }
00318
00319
00320
00321
00322 foreach(idx, indirection)
00323 {
00324 A_Indices *ai = (A_Indices *) lfirst(idx);
00325 Node *subexpr;
00326
00327 Assert(IsA(ai, A_Indices));
00328 if (isSlice)
00329 {
00330 if (ai->lidx)
00331 {
00332 subexpr = transformExpr(pstate, ai->lidx, pstate->p_expr_kind);
00333
00334 subexpr = coerce_to_target_type(pstate,
00335 subexpr, exprType(subexpr),
00336 INT4OID, -1,
00337 COERCION_ASSIGNMENT,
00338 COERCE_IMPLICIT_CAST,
00339 -1);
00340 if (subexpr == NULL)
00341 ereport(ERROR,
00342 (errcode(ERRCODE_DATATYPE_MISMATCH),
00343 errmsg("array subscript must have type integer"),
00344 parser_errposition(pstate, exprLocation(ai->lidx))));
00345 }
00346 else
00347 {
00348
00349 subexpr = (Node *) makeConst(INT4OID,
00350 -1,
00351 InvalidOid,
00352 sizeof(int32),
00353 Int32GetDatum(1),
00354 false,
00355 true);
00356 }
00357 lowerIndexpr = lappend(lowerIndexpr, subexpr);
00358 }
00359 subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind);
00360
00361 subexpr = coerce_to_target_type(pstate,
00362 subexpr, exprType(subexpr),
00363 INT4OID, -1,
00364 COERCION_ASSIGNMENT,
00365 COERCE_IMPLICIT_CAST,
00366 -1);
00367 if (subexpr == NULL)
00368 ereport(ERROR,
00369 (errcode(ERRCODE_DATATYPE_MISMATCH),
00370 errmsg("array subscript must have type integer"),
00371 parser_errposition(pstate, exprLocation(ai->uidx))));
00372 upperIndexpr = lappend(upperIndexpr, subexpr);
00373 }
00374
00375
00376
00377
00378
00379 if (assignFrom != NULL)
00380 {
00381 Oid typesource = exprType(assignFrom);
00382 Oid typeneeded = isSlice ? arrayType : elementType;
00383 Node *newFrom;
00384
00385 newFrom = coerce_to_target_type(pstate,
00386 assignFrom, typesource,
00387 typeneeded, arrayTypMod,
00388 COERCION_ASSIGNMENT,
00389 COERCE_IMPLICIT_CAST,
00390 -1);
00391 if (newFrom == NULL)
00392 ereport(ERROR,
00393 (errcode(ERRCODE_DATATYPE_MISMATCH),
00394 errmsg("array assignment requires type %s"
00395 " but expression is of type %s",
00396 format_type_be(typeneeded),
00397 format_type_be(typesource)),
00398 errhint("You will need to rewrite or cast the expression."),
00399 parser_errposition(pstate, exprLocation(assignFrom))));
00400 assignFrom = newFrom;
00401 }
00402
00403
00404
00405
00406 aref = makeNode(ArrayRef);
00407 aref->refarraytype = arrayType;
00408 aref->refelemtype = elementType;
00409 aref->reftypmod = arrayTypMod;
00410
00411 aref->refupperindexpr = upperIndexpr;
00412 aref->reflowerindexpr = lowerIndexpr;
00413 aref->refexpr = (Expr *) arrayBase;
00414 aref->refassgnexpr = (Expr *) assignFrom;
00415
00416 return aref;
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 Const *
00438 make_const(ParseState *pstate, Value *value, int location)
00439 {
00440 Const *con;
00441 Datum val;
00442 int64 val64;
00443 Oid typeid;
00444 int typelen;
00445 bool typebyval;
00446 ParseCallbackState pcbstate;
00447
00448 switch (nodeTag(value))
00449 {
00450 case T_Integer:
00451 val = Int32GetDatum(intVal(value));
00452
00453 typeid = INT4OID;
00454 typelen = sizeof(int32);
00455 typebyval = true;
00456 break;
00457
00458 case T_Float:
00459
00460 if (scanint8(strVal(value), true, &val64))
00461 {
00462
00463
00464
00465
00466 int32 val32 = (int32) val64;
00467
00468 if (val64 == (int64) val32)
00469 {
00470 val = Int32GetDatum(val32);
00471
00472 typeid = INT4OID;
00473 typelen = sizeof(int32);
00474 typebyval = true;
00475 }
00476 else
00477 {
00478 val = Int64GetDatum(val64);
00479
00480 typeid = INT8OID;
00481 typelen = sizeof(int64);
00482 typebyval = FLOAT8PASSBYVAL;
00483 }
00484 }
00485 else
00486 {
00487
00488 setup_parser_errposition_callback(&pcbstate, pstate, location);
00489 val = DirectFunctionCall3(numeric_in,
00490 CStringGetDatum(strVal(value)),
00491 ObjectIdGetDatum(InvalidOid),
00492 Int32GetDatum(-1));
00493 cancel_parser_errposition_callback(&pcbstate);
00494
00495 typeid = NUMERICOID;
00496 typelen = -1;
00497 typebyval = false;
00498 }
00499 break;
00500
00501 case T_String:
00502
00503
00504
00505
00506
00507 val = CStringGetDatum(strVal(value));
00508
00509 typeid = UNKNOWNOID;
00510 typelen = -2;
00511 typebyval = false;
00512 break;
00513
00514 case T_BitString:
00515
00516 setup_parser_errposition_callback(&pcbstate, pstate, location);
00517 val = DirectFunctionCall3(bit_in,
00518 CStringGetDatum(strVal(value)),
00519 ObjectIdGetDatum(InvalidOid),
00520 Int32GetDatum(-1));
00521 cancel_parser_errposition_callback(&pcbstate);
00522 typeid = BITOID;
00523 typelen = -1;
00524 typebyval = false;
00525 break;
00526
00527 case T_Null:
00528
00529 con = makeConst(UNKNOWNOID,
00530 -1,
00531 InvalidOid,
00532 -2,
00533 (Datum) 0,
00534 true,
00535 false);
00536 con->location = location;
00537 return con;
00538
00539 default:
00540 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(value));
00541 return NULL;
00542 }
00543
00544 con = makeConst(typeid,
00545 -1,
00546 InvalidOid,
00547 typelen,
00548 val,
00549 false,
00550 typebyval);
00551 con->location = location;
00552
00553 return con;
00554 }