descriptor.c
来自「postgresql8.3.4源码,开源数据库」· C语言 代码 · 共 730 行 · 第 1/2 页
C
730 行
ecpg_log("ECPGget_desc: TYPE = %d\n", ecpg_dynamic_type_DDT(PQftype(ECPGresult, index))); break; case ECPGd_cardinality: if (!get_int_item(lineno, var, vartype, PQntuples(ECPGresult))) return (false); ecpg_log("ECPGget_desc: CARDINALITY = %d\n", PQntuples(ECPGresult)); break; case ECPGd_ret_length: case ECPGd_ret_octet: /* * this is like ECPGstore_result */ if (arrsize > 0 && ntuples > arrsize) { ecpg_log("ECPGget_desc line %d: Incorrect number of matches: %d don't fit into array of %d\n", lineno, ntuples, arrsize); ecpg_raise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL); return false; } /* allocate storage if needed */ if (arrsize == 0 && *(void **) var == NULL) { void *mem = (void *) ecpg_alloc(offset * ntuples, lineno); if (!mem) return false; *(void **) var = mem; ecpg_add_mem(mem, lineno); var = mem; } for (act_tuple = 0; act_tuple < ntuples; act_tuple++) { if (!get_int_item(lineno, var, vartype, PQgetlength(ECPGresult, act_tuple, index))) return (false); var = (char *) var + offset; ecpg_log("ECPGget_desc: RETURNED[%d] = %d\n", act_tuple, PQgetlength(ECPGresult, act_tuple, index)); } break; default: snprintf(type_str, sizeof(type_str), "%d", type); ecpg_raise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str); return (false); } type = va_arg(args, enum ECPGdtype); } if (data_var.type != ECPGt_EORT) { struct statement stmt; char *oldlocale; /* Make sure we do NOT honor the locale for numeric input */ /* since the database gives the standard decimal point */ oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno); setlocale(LC_NUMERIC, "C"); memset(&stmt, 0, sizeof stmt); stmt.lineno = lineno; /* desparate try to guess something sensible */ stmt.connection = ecpg_get_connection(NULL); ecpg_store_result(ECPGresult, index, &stmt, &data_var); setlocale(LC_NUMERIC, oldlocale); ecpg_free(oldlocale); } else if (data_var.ind_type != ECPGt_NO_INDICATOR && data_var.ind_pointer != NULL) /* * ind_type != NO_INDICATOR should always have ind_pointer != NULL but * since this might be changed manually in the .c file let's play it * safe */ { /* * this is like ECPGstore_result but since we don't have a data * variable at hand, we can't call it */ if (data_var.ind_arrsize > 0 && ntuples > data_var.ind_arrsize) { ecpg_log("ECPGget_desc line %d: Incorrect number of matches (indicator): %d don't fit into array of %d\n", lineno, ntuples, data_var.ind_arrsize); ecpg_raise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL); return false; } /* allocate storage if needed */ if (data_var.ind_arrsize == 0 && data_var.ind_value == NULL) { void *mem = (void *) ecpg_alloc(data_var.ind_offset * ntuples, lineno); if (!mem) return false; *(void **) data_var.ind_pointer = mem; ecpg_add_mem(mem, lineno); data_var.ind_value = mem; } for (act_tuple = 0; act_tuple < ntuples; act_tuple++) { if (!get_int_item(lineno, data_var.ind_value, data_var.ind_type, -PQgetisnull(ECPGresult, act_tuple, index))) return (false); data_var.ind_value = (char *) data_var.ind_value + data_var.ind_offset; ecpg_log("ECPGget_desc: INDICATOR[%d] = %d\n", act_tuple, -PQgetisnull(ECPGresult, act_tuple, index)); } } sqlca->sqlerrd[2] = ntuples; return (true);}boolECPGset_desc_header(int lineno, const char *desc_name, int count){ struct descriptor *desc = ecpg_find_desc(lineno, desc_name); if (desc == NULL) return false; desc->count = count; return true;}boolECPGset_desc(int lineno, const char *desc_name, int index,...){ va_list args; struct descriptor *desc; struct descriptor_item *desc_item; struct variable *var; desc = ecpg_find_desc(lineno, desc_name); if (desc == NULL) return false; for (desc_item = desc->items; desc_item; desc_item = desc_item->next) { if (desc_item->num == index) break; } if (desc_item == NULL) { desc_item = (struct descriptor_item *) ecpg_alloc(sizeof(*desc_item), lineno); if (!desc_item) return false; desc_item->num = index; if (desc->count < index) desc->count = index; desc_item->next = desc->items; desc->items = desc_item; } if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno))) return false; va_start(args, index); for (;;) { enum ECPGdtype itemtype; char *tobeinserted = NULL; itemtype = va_arg(args, enum ECPGdtype); if (itemtype == ECPGd_EODT) break; var->type = va_arg(args, enum ECPGttype); var->pointer = va_arg(args, char *); var->varcharsize = va_arg(args, long); var->arrsize = va_arg(args, long); var->offset = va_arg(args, long); if (var->arrsize == 0 || var->varcharsize == 0) var->value = *((char **) (var->pointer)); else var->value = var->pointer; /* * negative values are used to indicate an array without given bounds */ /* reset to zero for us */ if (var->arrsize < 0) var->arrsize = 0; if (var->varcharsize < 0) var->varcharsize = 0; var->next = NULL; switch (itemtype) { case ECPGd_data: { if (!ecpg_store_input(lineno, true, var, &tobeinserted, false)) { ecpg_free(var); return false; } ecpg_free(desc_item->data); /* free() takes care of a * potential NULL value */ desc_item->data = (char *) tobeinserted; tobeinserted = NULL; break; } case ECPGd_indicator: set_int_item(lineno, &desc_item->indicator, var->pointer, var->type); break; case ECPGd_length: set_int_item(lineno, &desc_item->length, var->pointer, var->type); break; case ECPGd_precision: set_int_item(lineno, &desc_item->precision, var->pointer, var->type); break; case ECPGd_scale: set_int_item(lineno, &desc_item->scale, var->pointer, var->type); break; case ECPGd_type: set_int_item(lineno, &desc_item->type, var->pointer, var->type); break; default: { char type_str[20]; snprintf(type_str, sizeof(type_str), "%d", itemtype); ecpg_raise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str); ecpg_free(var); return false; } } } ecpg_free(var); return true;}/* Free the descriptor and items in it. */static voiddescriptor_free(struct descriptor * desc){ struct descriptor_item *desc_item; for (desc_item = desc->items; desc_item;) { struct descriptor_item *di; ecpg_free(desc_item->data); di = desc_item; desc_item = desc_item->next; ecpg_free(di); } ecpg_free(desc->name); PQclear(desc->result); ecpg_free(desc);}boolECPGdeallocate_desc(int line, const char *name){ struct descriptor *desc; struct descriptor *prev; struct sqlca_t *sqlca = ECPGget_sqlca(); ecpg_init_sqlca(sqlca); for (desc = get_descriptors(), prev = NULL; desc; prev = desc, desc = desc->next) { if (!strcmp(name, desc->name)) { if (prev) prev->next = desc->next; else set_descriptors(desc->next); descriptor_free(desc); return true; } } ecpg_raise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, name); return false;}#ifdef ENABLE_THREAD_SAFETY/* Deallocate all descriptors in the list */static voiddescriptor_deallocate_all(struct descriptor * list){ while (list) { struct descriptor *next = list->next; descriptor_free(list); list = next; }}#endif /* ENABLE_THREAD_SAFETY */boolECPGallocate_desc(int line, const char *name){ struct descriptor *new; struct sqlca_t *sqlca = ECPGget_sqlca(); ecpg_init_sqlca(sqlca); new = (struct descriptor *) ecpg_alloc(sizeof(struct descriptor), line); if (!new) return false; new->next = get_descriptors(); new->name = ecpg_alloc(strlen(name) + 1, line); if (!new->name) { ecpg_free(new); return false; } new->count = -1; new->items = NULL; new->result = PQmakeEmptyPGresult(NULL, 0); if (!new->result) { ecpg_free(new->name); ecpg_free(new); ecpg_raise(line, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL); return false; } strcpy(new->name, name); set_descriptors(new); return true;}/* Find descriptor with name in the connection. */struct descriptor *ecpg_find_desc(int line, const char *name){ struct descriptor *desc; for (desc = get_descriptors(); desc; desc = desc->next) { if (strcmp(name, desc->name) == 0) return desc; } ecpg_raise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, name); return NULL; /* not found */}boolECPGdescribe(int line, bool input, const char *statement,...){ ecpg_log("ECPGdescribe called on line %d for %s in %s\n", line, (input) ? "input" : "output", statement); return false;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?