static sql_rel * psm_analyze(mvc *sql, dlist *qname, dlist *columns, symbol *sample ) { exp_kind ek = {type_value, card_value, FALSE}; sql_exp *sample_exp = NULL, *call; char *sname = NULL, *tname = NULL; list *tl = sa_list(sql->sa); list *exps = sa_list(sql->sa), *analyze_calls = sa_list(sql->sa); sql_subfunc *f = NULL; if (sample) { sql_subtype *tpe = sql_bind_localtype("lng"); sample_exp = rel_value_exp( sql, NULL, sample, 0, ek); if (sample_exp) sample_exp = rel_check_type(sql, tpe, sample_exp, type_cast); } if (qname) { if (qname->h->next) sname = qname_schema(qname); else sname = qname_table(qname); if (!sname) sname = cur_schema(sql)->base.name; if (qname->h->next) tname = qname_table(qname); } /* call analyze( [schema, [ table ]], opt_sample_size ) */ if (sname) { sql_exp *sname_exp = exp_atom_clob(sql->sa, sname); append(exps, sname_exp); append(tl, exp_subtype(sname_exp)); } if (tname) { sql_exp *tname_exp = exp_atom_clob(sql->sa, tname); append(exps, tname_exp); append(tl, exp_subtype(tname_exp)); if (columns) append(tl, exp_subtype(tname_exp)); } if (!columns) { if (sample_exp) { append(exps, sample_exp); append(tl, exp_subtype(sample_exp)); } f = sql_bind_func_(sql->sa, mvc_bind_schema(sql, "sys"), "analyze", tl, F_PROC); if (!f) return sql_error(sql, 01, "Analyze procedure missing"); call = exp_op(sql->sa, exps, f); append(analyze_calls, call); } else { dnode *n; if (sample_exp) append(tl, exp_subtype(sample_exp)); f = sql_bind_func_(sql->sa, mvc_bind_schema(sql, "sys"), "analyze", tl, F_PROC); if (!f) return sql_error(sql, 01, "Analyze procedure missing"); for( n = columns->h; n; n = n->next) { char *cname = n->data.sval; list *nexps = list_dup(exps, NULL); sql_exp *cname_exp = exp_atom_clob(sql->sa, cname); append(nexps, cname_exp); if (sample_exp) append(nexps, sample_exp); /* call analyze( sname, tname, cname, opt_sample_size ) */ call = exp_op(sql->sa, nexps, f); append(analyze_calls, call); } } return rel_psm_block(sql->sa, analyze_calls); }
static BOOL kpc_bindparameter(ATOMID idfName, WORD h, LPFETCH lpFetch, int nParam, ATOMID idMode, WORD wType, OBJECTID idObj, ATOMID idSlot, BOOL bLive) { WORD wMode; WORD sqlType = SQL_LONGVARCHAR, scale = 0, nullable = SQL_NO_NULLS; DWORD colDef = RET_BUFFER_LEN - 1; LPPARAM lpParams, lpParam; LPDESC lpDesc; WORD wNumParams = 0; DWORD dwLen; RETCODE code; if (idMode == Symbol(INPUT)) wMode = SQL_PARAM_INPUT; else if (idMode == Symbol(OUTPUT)) wMode = SQL_PARAM_OUTPUT; else if (idMode == Symbol(INPUT_OUTPUT)) wMode = SQL_PARAM_INPUT_OUTPUT; code = SQLDescribeParam(lpFetch->hstmt, nParam, &sqlType, &colDef, &scale, &nullable); switch (code) { case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: break; case SQL_INVALID_HANDLE: return KPC_HANDLE_ERROR(IDE_INVALID_HANDLE, h); default: sql_error(idfName, SQL_NULL_HDBC, lpFetch->hstmt); if (!stricmp(sqlstate, "IM001")) { if (nParam < 1) return KPC_ERROR(IDE_OUTOF_RANGE, KppAddAtomInt(nParam)); if (!num_params(idfName, h, lpFetch->hstmt, &wNumParams)) return ERROR; if (nParam > wNumParams) return KPC_ERROR(IDE_OUTOF_RANGE, KppAddAtomInt(nParam)); sqlType = SQL_LONGVARCHAR; colDef = RET_BUFFER_LEN - 1; nullable = SQL_NO_NULLS; } else return ERROR; } if (!lpFetch->params) { if (!wNumParams && !num_params(idfName, h, lpFetch->hstmt, &wNumParams)) return ERROR; lpParams = calloc(sizeof(PARAM), wNumParams); if (!lpParams) return KPC_ERROR(IDE_OUTOF_MEMORY, NULLID); } else lpParams = lpFetch->params; lpParam = lpParams + nParam - 1; lpDesc = &lpParam->desc; lpDesc->sqlType = sqlType; lpDesc->colDef = colDef; lpDesc->scale = scale; lpDesc->nullable = nullable; if (lpFetch->wXParamRows) { lpDesc->pdwLen = calloc(sizeof(DWORD), lpFetch->wXParamRows + 1); if (!lpDesc->pdwLen) return KPC_ERROR(IDE_OUTOF_MEMORY, NULLID); } else lpDesc->pdwLen = &lpDesc->dwLen; if (!fill_bind(idfName, lpDesc, &lpParam->data, lpFetch->wXParamRows, &dwLen)) { free_params(lpParams, lpFetch->wNumParams); return ERROR; } else { lpParam->wMode = wMode; lpParam->wType = wType; lpParam->idObj = idObj; lpParam->idSlot = idSlot; lpDesc->colDef = dwLen; lpFetch->wNumParams = wNumParams; lpFetch->params = lpParams; if (bLive) { int i = -1; while (++i <= lpFetch->wXParamRows) lpDesc->pdwLen[i] = SQL_LEN_DATA_AT_EXEC(0); } else if (!set_parameter_value(idfName, lpParam, lpFetch->wXParamRows)) return ERROR; } code = SQLBindParameter(lpFetch->hstmt, nParam, wMode, lpDesc->cType, lpDesc->sqlType, lpDesc->colDef, lpDesc->scale, lpDesc->address, dwLen, lpDesc->pdwLen); switch (code) { case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: lpParam->bound = TRUE; return TRUE; case SQL_INVALID_HANDLE: return KPC_HANDLE_ERROR(IDE_INVALID_HANDLE, h); default: return sql_error(idfName, SQL_NULL_HDBC, lpFetch->hstmt); } }
static sql_rel * create_trigger(mvc *sql, dlist *qname, int time, symbol *trigger_event, char *table_name, dlist *opt_ref, dlist *triggered_action) { char *tname = qname_table(qname); sql_schema *ss = cur_schema(sql); sql_table *t = NULL; int instantiate = (sql->emode == m_instantiate); int create = (!instantiate && sql->emode != m_deps); list *sq = NULL; sql_rel *r = NULL; dlist *columns = trigger_event->data.lval; char *old_name = NULL, *new_name = NULL; dlist *stmts = triggered_action->h->next->next->data.lval; if (opt_ref) { dnode *dl = opt_ref->h; for ( ; dl; dl = dl->next) { /* list (new(1)/old(0)), char */ char *n = dl->data.lval->h->next->data.sval; assert(dl->data.lval->h->type == type_int); if (!dl->data.lval->h->data.i_val) /*?l_val?*/ old_name = n; else new_name = n; } } if (create && !schema_privs(sql->role_id, ss)) return sql_error(sql, 02, "CREATE TRIGGER: access denied for %s to schema ;'%s'", stack_get_string(sql, "current_user"), ss->base.name); if (create && mvc_bind_trigger(sql, ss, tname) != NULL) return sql_error(sql, 02, "CREATE TRIGGER: name '%s' already in use", tname); if (create && !(t = mvc_bind_table(sql, ss, table_name))) return sql_error(sql, 02, "CREATE TRIGGER: unknown table '%s'", table_name); if (create && isView(t)) return sql_error(sql, 02, "CREATE TRIGGER: cannot create trigger on view '%s'", table_name); if (create) { int event = (trigger_event->token == SQL_INSERT)?0: (trigger_event->token == SQL_DELETE)?1:2; int orientation = triggered_action->h->data.i_val; char *condition = triggered_action->h->next->data.sval; char *q = QUERY(sql->scanner); assert(triggered_action->h->type == type_int); return rel_create_trigger(sql, t->s->base.name, t->base.name, tname, time, orientation, event, old_name, new_name, condition, q); } t = mvc_bind_table(sql, ss, table_name); stack_push_frame(sql, "OLD-NEW"); /* we need to add the old and new tables */ if (new_name) _stack_push_table(sql, new_name, t); if (old_name) _stack_push_table(sql, old_name, t); sq = sequential_block(sql, NULL, NULL, stmts, NULL, 1); r = rel_psm_block(sql->sa, sq); /* todo trigger_columns */ (void)columns; return r; }
int check_for_db(sqlite3 ** db, const char * filename, int can_create, int readonly) { struct stat dbfile; int rc; int accessflags = R_OK | W_OK; if (readonly) accessflags = R_OK; // Check if DB exist. If it does not, initialize it if (access(filename, accessflags)) { printf("Database <%s> does not already exist, ", filename); if (can_create) { printf("creating it...\n"); rc = initDataBase(filename, db); if (rc) { printf("Error initializing database (return code: %d), exiting...\n", rc); return 1; } } else { printf("exiting ...\n"); return 1; } } else { if (stat(filename, &dbfile)) { perror("stat()"); return 1; } if ((S_ISREG(dbfile.st_mode) && !S_ISDIR(dbfile.st_mode)) == 0) { printf("\"%s\" does not appear to be a file.\n", filename); return 1; } } rc = sqlite3_open(filename, &(*db)); if(rc) { sql_error(*db); sqlite3_close(*db); return 1; } // TODO: Sanity check: Table definitions, index // register new functions to be used in SQL statements if (sqlite3_create_function(*db, "PMK", 2, SQLITE_ANY, 0, &sql_calcpmk,0,0) != SQLITE_OK) { printf("Failed creating PMK function.\n"); sql_error(*db); sqlite3_close(*db); return 1; } if (sqlite3_create_function(*db, "VERIFY_ESSID", 1, SQLITE_ANY, 0, &sql_verify_essid,0,0) != SQLITE_OK) { printf("Failed creating VERIFY_ESSID function.\n"); sql_error(*db); sqlite3_close(*db); return 1; } if (sqlite3_create_function(*db, "VERIFY_PASSWD", 1, SQLITE_ANY, 0, &sql_verify_passwd,0,0) != SQLITE_OK) { printf("Failed creating VERIFY_PASSWD function.\n"); sql_error(*db); sqlite3_close(*db); return 1; } #ifdef HAVE_REGEXP if (sqlite3_create_function(*db, "regexp", 2, SQLITE_ANY,0, &sqlite_regexp,0,0) != SQLITE_OK) { printf("Failed creating regexp() handler.\n"); sql_error(*db); sqlite3_close(*db); return 1; } #endif return 0; }
/************************************************************************* * * Function: sql_select_query * * Purpose: Issue a select query to the database * *************************************************************************/ static int sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char *querystr) { int x; int y; int colcount; OCIParam *param; OCIDefine *define; ub2 dtype; ub2 dsize; char **rowdata=NULL; sb2 *indicators; rlm_sql_oracle_conn_t *conn = handle->conn; if (conn->ctx == NULL) { radlog(L_ERR, "rlm_sql_oracle: Socket not connected"); return SQL_DOWN; } if (OCIStmtPrepare (conn->queryHandle, conn->errHandle, querystr, strlen(querystr), OCI_NTV_SYNTAX, OCI_DEFAULT)) { radlog(L_ERR,"rlm_sql_oracle: prepare failed in sql_select_query: %s",sql_error(handle, config)); return -1; } /* Query only one row by default (for now) */ x = OCIStmtExecute(conn->ctx, conn->queryHandle, conn->errHandle, (ub4) 0, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT); if (x == OCI_NO_DATA) { /* Nothing to fetch */ return 0; } if (x != OCI_SUCCESS) { radlog(L_ERR,"rlm_sql_oracle: query failed in sql_select_query: %s", sql_error(handle, config)); return sql_check_error(handle, config); } /* * Define where the output from fetch calls will go * * This is a gross hack, but it works - we convert * all data to strings for ease of use. Fortunately, most * of the data we deal with is already in string format. */ colcount = sql_num_fields(handle, config); /* DEBUG2("sql_select_query(): colcount=%d",colcount); */ /* * FIXME: These malloc's can probably go, as the schema * is fixed... */ rowdata=(char **)rad_malloc(sizeof(char *) * (colcount+1) ); memset(rowdata, 0, (sizeof(char *) * (colcount+1) )); indicators = (sb2 *) rad_malloc(sizeof(sb2) * (colcount+1) ); memset(indicators, 0, sizeof(sb2) * (colcount+1)); for (y=1; y <= colcount; y++) { x=OCIParamGet(conn->queryHandle, OCI_HTYPE_STMT, conn->errHandle, (dvoid **)¶m, (ub4) y); if (x != OCI_SUCCESS) { radlog(L_ERR,"rlm_sql_oracle: OCIParamGet() failed in sql_select_query: %s", sql_error(handle, config)); goto error; } x=OCIAttrGet((dvoid*)param, OCI_DTYPE_PARAM, (dvoid*)&dtype, (ub4*)0, OCI_ATTR_DATA_TYPE, conn->errHandle); if (x != OCI_SUCCESS) { radlog(L_ERR,"rlm_sql_oracle: OCIAttrGet() failed in sql_select_query: %s", sql_error(handle, config)); goto error; } dsize=MAX_DATASTR_LEN; /* * Use the retrieved length of dname to allocate an output * buffer, and then define the output variable (but only * for char/string type columns). */ switch(dtype) { #ifdef SQLT_AFC case SQLT_AFC: /* ansii fixed char */ #endif #ifdef SQLT_AFV case SQLT_AFV: /* ansii var char */ #endif case SQLT_VCS: /* var char */ case SQLT_CHR: /* char */ case SQLT_STR: /* string */ x=OCIAttrGet((dvoid*)param, (ub4) OCI_DTYPE_PARAM, (dvoid*) &dsize, (ub4 *)0, (ub4) OCI_ATTR_DATA_SIZE, conn->errHandle); if (x != OCI_SUCCESS) { radlog(L_ERR,"rlm_sql_oracle: OCIAttrGet() failed in sql_select_query: %s", sql_error(handle, config)); goto error; } rowdata[y-1]=rad_malloc(dsize+1); memset(rowdata[y-1], 0, dsize+1); break; case SQLT_DAT: case SQLT_INT: case SQLT_UIN: case SQLT_FLT: case SQLT_PDN: case SQLT_BIN: case SQLT_NUM: rowdata[y-1]=rad_malloc(dsize+1); memset(rowdata[y-1], 0, dsize+1); break; default: dsize=0; rowdata[y-1]=NULL; break; } indicators[y-1] = 0; x=OCIDefineByPos(conn->queryHandle, &define, conn->errHandle, y, (ub1 *) rowdata[y-1], dsize+1, SQLT_STR, &indicators[y-1], (dvoid *) 0, (dvoid *) 0, OCI_DEFAULT); if (x != OCI_SUCCESS) { radlog(L_ERR,"rlm_sql_oracle: OCIDefineByPos() failed in sql_select_query: %s", sql_error(handle, config)); goto error; } } conn->results=rowdata; conn->indicators=indicators; return 0; error: for (y=0; y < colcount; y++) { free(rowdata[y]); } free(rowdata); free(indicators); return -1; }
/* return val; */ static list * rel_psm_return( mvc *sql, sql_subtype *restype, list *restypelist, symbol *return_sym ) { exp_kind ek = {type_value, card_value, FALSE}; sql_exp *res; sql_rel *rel = NULL; int is_last = 0; list *l = sa_list(sql->sa); if (restypelist) ek.card = card_relation; res = rel_value_exp2(sql, &rel, return_sym, sql_sel, ek, &is_last); if (!res) return NULL; if (ek.card != card_relation && (!res || (res = rel_check_type(sql, restype, res, type_equal)) == NULL)) return NULL; else if (ek.card == card_relation && !rel) return NULL; if (rel && ek.card != card_relation) append(l, exp_rel(sql, rel)); else if (rel && !is_ddl(rel->op)) { list *exps = sa_list(sql->sa); node *n, *m; int isproject = (rel->op == op_project); list *oexps = rel->exps; sql_rel *l = rel->l; if (is_topn(rel->op)) oexps = l->exps; for (n = oexps->h, m = restypelist->h; n && m; n = n->next, m = m->next) { sql_exp *e = n->data; sql_arg *ce = m->data; char *cname = exp_name(e); char name[16]; if (!cname) cname = sa_strdup(sql->sa, number2name(name, 16, ++sql->label)); if (!isproject) e = exp_column(sql->sa, exp_relname(e), cname, exp_subtype(e), exp_card(e), has_nil(e), is_intern(e)); e = rel_check_type(sql, &ce->type, e, type_equal); if (!e) return NULL; append(exps, e); } if (isproject) rel -> exps = exps; else rel = rel_project(sql->sa, rel, exps); res = exp_rel(sql, rel); } else if (rel && restypelist){ /* handle return table-var */ list *exps = sa_list(sql->sa); sql_table *t = rel_ddl_table_get(rel); node *n, *m; char *tname = t->base.name; if (cs_size(&t->columns) != list_length(restypelist)) return sql_error(sql, 02, "RETURN: number of columns do not match"); for (n = t->columns.set->h, m = restypelist->h; n && m; n = n->next, m = m->next) { sql_column *c = n->data; sql_arg *ce = m->data; sql_exp *e = exp_alias(sql->sa, tname, c->base.name, tname, c->base.name, &c->type, CARD_MULTI, c->null, 0); e = rel_check_type(sql, &ce->type, e, type_equal); if (!e) return NULL; append(exps, e); } rel = rel_project(sql->sa, rel, exps); res = exp_rel(sql, rel); } append(l, exp_return(sql->sa, res, stack_nr_of_declared_tables(sql))); return l; }
gint alter_rtr1(class alter_rtr_data *data) { char strsql[1000]; //1 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); time(&data->vremn); iceb_printw(iceb_u_toutf("Открываем базу\n"),data->buffer,data->view); if(sql_openbaz(&bd,data->imabaz.ravno(),data->host.ravno(),"root",data->parol.ravno()) != 0) { iceb_eropbaz(data->imabaz.ravno(),0,"",1); gtk_label_set_text(GTK_LABEL(data->label),gettext("Расчет закончен")); gtk_widget_grab_focus(data->knopka); gtk_widget_show_all(data->window); return(FALSE); } iceb_start_rf(); //2 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку podr в таблицу Restdok.\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok add podr int not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонка в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } else { iceb_printw(iceb_u_toutf("Удаляем индексы mo и datd в таблице Restdok.\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok drop index mo, drop index datd"); if(sql_zap(&bd,strsql) != 0) { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } iceb_printw(iceb_u_toutf("Добавляем индексы mo,podr и datd,podr в таблицу Restdok.\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok add index mo (mo,podr), add index datd (datd,podr)"); if(sql_zap(&bd,strsql) != 0) { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } iceb_printw(iceb_u_toutf("Вставляем колонку podr в таблицу Restdok1.\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok1 add podr int not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонка в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //3 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку nz и mr в таблицу Restdok1.\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok1 add nz smallint not null, add mr smallint not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонки в таблице уже существуют.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } else { iceb_printw(iceb_u_toutf("Удаляем индекс datd в таблице Restdok1.\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok1 drop index datd"); if(sql_zap(&bd,strsql) != 0) { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } iceb_printw(iceb_u_toutf("Добавляем индекс datd в таблицу Restdok1.\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok1 add unique datd (datd,nomd,skl,mz,kodz,nz)"); if(sql_zap(&bd,strsql) != 0) { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //4 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонки vremz,vremo в таблицу Restdok.\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok add vremz int unsigned not null, add vremo int unsigned not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонки в таблице уже существуют.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //5 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонки ps (процент скидки) и grup (группа) в таблицу Taxiklient.\n"),data->buffer,data->view); sprintf(strsql,"alter table Taxiklient add ps float not null,add grup char(10) not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонкa в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //6 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Создаём таблицу групп клиентов Grupklient.\n"),data->buffer,data->view); memset(strsql,'\0',sizeof(strsql)); strcpy(strsql,"CREATE TABLE Grupklient \ (kod char(10) not null primary key,\ naik varchar(100) not null,\ ktoz smallint unsigned not null,\ vrem int unsigned not null)"); /* 0 kod код группы 1 naik наименование группы 2 ktoz кто записал 3 vrem время записи */ if(sql_zap(&bd,strsql) < 0) { sprintf(strsql,"%d %s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } else iceb_printw(iceb_u_toutf("Таблица создана !\n"),data->buffer,data->view); //7 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку ps (процент скидки) таблицу Restdok.\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok add ps float not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонкa в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //8 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку nds в таблицу Restdok1.\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok1 add nds tinyint not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонка в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //9 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку sp в таблицу Taxiklient.\n"),data->buffer,data->view); sprintf(strsql,"alter table Taxiklient add sp varchar(100) not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонка в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //10 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку ps в таблицу Restdok1.\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok1 add ps float not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонка в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //11 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку mk в таблицу Taxiklient.\n"),data->buffer,data->view); sprintf(strsql,"alter table Taxiklient add mk tinyint not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонка в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //12 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку dvk в таблицу Taxiklient.\n"),data->buffer,data->view); sprintf(strsql,"alter table Taxiklient add dvk DATETIME not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонка в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //13 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку pl в таблицу Taxiklient.\n"),data->buffer,data->view); sprintf(strsql,"alter table Taxiklient add pl tinyint not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонка в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //14 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку cdg в таблицу Restvi\n"),data->buffer,data->view); sprintf(strsql,"alter table Restvi add cdg float(7,2) not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонка в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //15 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку denrog в таблицу Taxiklient.\n"),data->buffer,data->view); sprintf(strsql,"alter table Taxiklient add denrog DATE not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонка в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //16 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку kom в таблицу Taxiklient.\n"),data->buffer,data->view); sprintf(strsql,"alter table Taxiklient add kom VARCHAR(100) NOT NULL"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонка в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //17 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Добавляем индекс nk,datz,kodz в таблицу Restkas.\n"),data->buffer,data->view); sprintf(strsql,"alter table Restkas add index nk1 (nk,kodz,datz)"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_KEYNAME) { iceb_printw(iceb_u_toutf("Индексы в таблице уже существуют.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //18 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Вставляем колонку mb в таблицу Taxiklient.\n"),data->buffer,data->view); sprintf(strsql,"alter table Taxiklient add mb tinyint not null"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_FIELDNAME) { iceb_printw(iceb_u_toutf("Колонка в таблице уже существует.\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //19 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Добавляем индекс в таблицу Restdok1\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok1 add index kodz (kodz,skl,mz,ms)"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_KEYNAME) { iceb_printw(iceb_u_toutf("Индекс уже существует\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } //20 iceb_pbar(data->bar,data->kolstr,++data->kolstr1); iceb_printw(iceb_u_toutf("Добавляем индекс в таблицу Restdok1\n"),data->buffer,data->view); sprintf(strsql,"alter table Restdok1 add index skl (skl,ms,mz)"); if(sql_zap(&bd,strsql) != 0) { if(sql_nerror(&bd) == ER_DUP_KEYNAME) { iceb_printw(iceb_u_toutf("Индекс уже существует\n"),data->buffer,data->view); } else { sprintf(strsql,"Ошибка ! %d\n%s\n",sql_nerror(&bd),sql_error(&bd)); iceb_printw(iceb_u_toutf(strsql),data->buffer,data->view); } } /*******************************/ sql_closebaz(&bd); iceb_printw_vr(data->vremn,data->buffer,data->view); gtk_label_set_text(GTK_LABEL(data->label),gettext("Расчет закончен")); gtk_widget_grab_focus(data->knopka); gtk_widget_show_all(data->window); return(FALSE); }
sql_rel * rel_psm(mvc *sql, symbol *s) { sql_rel *ret = NULL; switch (s->token) { case SQL_CREATE_FUNC: { dlist *l = s->data.lval; int type = l->h->next->next->next->next->next->data.i_val; int lang = l->h->next->next->next->next->next->next->data.i_val; int repl = l->h->next->next->next->next->next->next->next->data.i_val; ret = rel_create_func(sql, l->h->data.lval, l->h->next->data.lval, l->h->next->next->data.sym, l->h->next->next->next->data.lval, l->h->next->next->next->next->data.lval, type, lang, repl); sql->type = Q_SCHEMA; } break; case SQL_DROP_FUNC: { dlist *l = s->data.lval; dlist *qname = l->h->data.lval; dlist *typelist = l->h->next->data.lval; int type = l->h->next->next->data.i_val; int if_exists = l->h->next->next->next->data.i_val; int all = l->h->next->next->next->next->data.i_val; int drop_action = l->h->next->next->next->next->next->data.i_val; if (STORE_READONLY) return sql_error(sql, 06, SQLSTATE(42000) "Schema statements cannot be executed on a readonly database."); if (all) ret = rel_drop_all_func(sql, qname, drop_action, type); else { ret = rel_drop_func(sql, qname, typelist, drop_action, type, if_exists); } sql->type = Q_SCHEMA; } break; case SQL_SET: ret = rel_psm_stmt(sql->sa, psm_set_exp(sql, s->data.lval->h)); sql->type = Q_SCHEMA; break; case SQL_DECLARE: ret = rel_psm_block(sql->sa, rel_psm_declare(sql, s->data.lval->h)); sql->type = Q_SCHEMA; break; case SQL_CALL: ret = rel_psm_stmt(sql->sa, rel_psm_call(sql, s->data.sym)); sql->type = Q_UPDATE; break; case SQL_CREATE_TABLE_LOADER: { dlist *l = s->data.lval; dlist *qname = l->h->data.lval; symbol *sym = l->h->next->data.sym; ret = create_table_from_loader(sql, qname, sym); if (ret == NULL) return NULL; ret = rel_psm_stmt(sql->sa, exp_rel(sql, ret)); sql->type = Q_SCHEMA; } break; case SQL_CREATE_TRIGGER: { dlist *l = s->data.lval; assert(l->h->next->type == type_int); ret = create_trigger(sql, l->h->data.lval, l->h->next->data.i_val, l->h->next->next->data.sym, l->h->next->next->next->data.lval, l->h->next->next->next->next->data.lval, l->h->next->next->next->next->next->data.lval, l->h->next->next->next->next->next->next->data.i_val); sql->type = Q_SCHEMA; } break; case SQL_DROP_TRIGGER: { dlist *l = s->data.lval; dlist *qname = l->h->data.lval; int if_exists = l->h->next->data.i_val; ret = drop_trigger(sql, qname, if_exists); sql->type = Q_SCHEMA; } break; case SQL_ANALYZE: { dlist *l = s->data.lval; ret = psm_analyze(sql, "analyze", l->h->data.lval /* qualified table name */, l->h->next->data.lval /* opt list of column */, l->h->next->next->data.sym /* opt_sample_size */, l->h->next->next->next->data.i_val); sql->type = Q_UPDATE; } break; default: return sql_error(sql, 01, SQLSTATE(42000) "Schema statement unknown symbol(%p)->token = %s", s, token2string(s->token)); } return ret; }
/* SET variable = value and set (variable1, .., variableN) = (query) */ static sql_exp * psm_set_exp(mvc *sql, dnode *n) { symbol *val = n->next->data.sym; sql_exp *e = NULL; int level = 0, is_last = 0; sql_subtype *tpe = NULL; sql_rel *rel = NULL; sql_exp *res = NULL; int single = (n->type == type_string); if (single) { exp_kind ek = {type_value, card_value, FALSE}; const char *name = n->data.sval; /* name can be 'parameter of the function' (ie in the param list) or a local or global variable, declared earlier */ /* check if variable is known from the stack */ if (!stack_find_var(sql, name)) { sql_arg *a = sql_bind_param(sql, name); if (!a) /* not parameter, ie local var ? */ return sql_error(sql, 01, SQLSTATE(42000) "Variable %s unknown", name); tpe = &a->type; } else { tpe = stack_find_type(sql, name); } e = rel_value_exp2(sql, &rel, val, sql_sel, ek, &is_last); if (!e || (rel && e->card > CARD_AGGR)) return NULL; level = stack_find_frame(sql, name); e = rel_check_type(sql, tpe, e, type_cast); if (!e) return NULL; if (rel) { sql_exp *er = exp_rel(sql, rel); list *b = sa_list(sql->sa); append(b, er); append(b, exp_set(sql->sa, name, e, level)); res = exp_rel(sql, rel_psm_block(sql->sa, b)); } else { res = exp_set(sql->sa, name, e, level); } } else { /* multi assignment */ exp_kind ek = {type_value, (single)?card_column:card_relation, FALSE}; sql_rel *rel_val = rel_subquery(sql, NULL, val, ek, APPLY_JOIN); dlist *vars = n->data.lval; dnode *m; node *n; list *b; if (!rel_val || !is_project(rel_val->op) || dlist_length(vars) != list_length(rel_val->exps)) { return sql_error(sql, 02, SQLSTATE(42000) "SET: Number of variables not equal to number of supplied values"); } b = sa_list(sql->sa); if (rel_val) { sql_exp *er = exp_rel(sql, rel_val); append(b, er); } for(m = vars->h, n = rel_val->exps->h; n && m; n = n->next, m = m->next) { char *vname = m->data.sval; sql_exp *v = n->data; if (!stack_find_var(sql, vname)) { sql_arg *a = sql_bind_param(sql, vname); if (!a) /* not parameter, ie local var ? */ return sql_error(sql, 01, SQLSTATE(42000) "Variable %s unknown", vname); tpe = &a->type; } else { tpe = stack_find_type(sql, vname); } if (!exp_name(v)) exp_label(sql->sa, v, ++sql->label); v = exp_column(sql->sa, exp_relname(v), exp_name(v), exp_subtype(v), v->card, has_nil(v), is_intern(v)); level = stack_find_frame(sql, vname); v = rel_check_type(sql, tpe, v, type_cast); if (!v) return NULL; if (v->card > CARD_AGGR) { sql_subaggr *zero_or_one = sql_bind_aggr(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(v)); assert(zero_or_one); v = exp_aggr1(sql->sa, v, zero_or_one, 0, 0, CARD_ATOM, 0); } append(b, exp_set(sql->sa, vname, v, level)); } res = exp_rel(sql, rel_psm_block(sql->sa, b)); } return res; }
int mvc_commit(mvc *m, int chain, const char *name) { sql_trans *cur, *tr = m->session->tr; int ok = SQL_OK;//, wait = 0; assert(tr); assert(m->session->active); /* only commit an active transaction */ if (mvc_debug) fprintf(stderr, "#mvc_commit %s\n", (name) ? name : ""); if (m->session->status < 0) { (void)sql_error(m, 010, "40000!COMMIT: transaction is aborted, will ROLLBACK instead"); mvc_rollback(m, chain, name); return -1; } /* savepoint then simply make a copy of the current transaction */ if (name && name[0] != '\0') { sql_trans *tr = m->session->tr; if (mvc_debug) fprintf(stderr, "#mvc_savepoint\n"); store_lock(); m->session->tr = sql_trans_create(m->session->stk, tr, name); store_unlock(); m->type = Q_TRANS; if (m->qc) /* clean query cache, protect against concurrent access on the hash tables (when functions already exists, concurrent mal will build up the hash (not copied in the trans dup)) */ qc_clean(m->qc); m->session->schema = find_sql_schema(m->session->tr, m->session->schema_name); if (mvc_debug) fprintf(stderr, "#mvc_commit %s done\n", name); return 0; } /* first release all intermediate savepoints */ cur = tr; tr = tr->parent; if (tr->parent) { store_lock(); while (tr->parent != NULL && ok == SQL_OK) { tr = sql_trans_destroy(tr); } store_unlock(); } cur -> parent = tr; tr = cur; store_lock(); /* if there is nothing to commit reuse the current transaction */ if (tr->wtime == 0) { if (!chain) sql_trans_end(m->session); m->type = Q_TRANS; if (mvc_debug) fprintf(stderr, "#mvc_commit %s done\n", (name) ? name : ""); store_unlock(); return 0; } /* while (tr->schema_updates && store_nr_active > 1) { store_unlock(); MT_sleep_ms(100); wait += 100; if (wait > 1000) { (void)sql_error(m, 010, "40000!COMMIT: transaction is aborted because of DDL concurrency conflicts, will ROLLBACK instead"); mvc_rollback(m, chain, name); return -1; } store_lock(); } * */ /* validation phase */ if (sql_trans_validate(tr)) { if ((ok = sql_trans_commit(tr)) != SQL_OK) { char *msg = sql_message("40000!COMMIT: transaction commit failed (perhaps your disk is full?) exiting (kernel error: %s)", GDKerrbuf); GDKfatal("%s", msg); _DELETE(msg); } } else { store_unlock(); (void)sql_error(m, 010, "40000!COMMIT: transaction is aborted because of concurrency conflicts, will ROLLBACK instead"); mvc_rollback(m, chain, name); return -1; } sql_trans_end(m->session); if (chain) sql_trans_begin(m->session); store_unlock(); m->type = Q_TRANS; if (mvc_debug) fprintf(stderr, "#mvc_commit %s done\n", (name) ? name : ""); return ok; }
static sql_rel * create_trigger(mvc *sql, dlist *qname, int time, symbol *trigger_event, dlist *tqname, dlist *opt_ref, dlist *triggered_action, int replace) { const char *triggerschema = qname_schema(qname); const char *triggername = qname_table(qname); const char *sname = qname_schema(tqname); const char *tname = qname_table(tqname); sql_schema *ss = cur_schema(sql); sql_table *t = NULL; sql_trigger *st = NULL; int instantiate = (sql->emode == m_instantiate); int create = (!instantiate && sql->emode != m_deps), event, orientation; list *sq = NULL; sql_rel *r = NULL; char *q, *base = replace ? "CREATE OR REPLACE" : "CREATE"; dlist *columns = trigger_event->data.lval; const char *old_name = NULL, *new_name = NULL; dlist *stmts = triggered_action->h->next->next->data.lval; symbol *condition = triggered_action->h->next->data.sym; if (!sname) sname = ss->base.name; if (sname && !(ss = mvc_bind_schema(sql, sname))) return sql_error(sql, 02, SQLSTATE(3F000) "%s TRIGGER: no such schema '%s'", base, sname); if (opt_ref) { dnode *dl = opt_ref->h; for ( ; dl; dl = dl->next) { /* list (new(1)/old(0)), char */ char *n = dl->data.lval->h->next->data.sval; assert(dl->data.lval->h->type == type_int); if (!dl->data.lval->h->data.i_val) /*?l_val?*/ old_name = n; else new_name = n; } } if (create && !mvc_schema_privs(sql, ss)) return sql_error(sql, 02, SQLSTATE(42000) "%s TRIGGER: access denied for %s to schema ;'%s'", base, stack_get_string(sql, "current_user"), ss->base.name); if (create && !(t = mvc_bind_table(sql, ss, tname))) return sql_error(sql, 02, SQLSTATE(42000) "%s TRIGGER: unknown table '%s'", base, tname); if (create && isView(t)) return sql_error(sql, 02, SQLSTATE(42000) "%s TRIGGER: cannot create trigger on view '%s'", base, tname); if (triggerschema && strcmp(triggerschema, sname) != 0) return sql_error(sql, 02, SQLSTATE(42000) "%s TRIGGER: trigger and respective table must belong to the same schema", base); if (create && (st = mvc_bind_trigger(sql, ss, triggername)) != NULL) { if (replace) { if(mvc_drop_trigger(sql, ss, st)) return sql_error(sql, 02, SQLSTATE(HY001) "%s TRIGGER: %s", base, MAL_MALLOC_FAIL); } else { return sql_error(sql, 02, SQLSTATE(42000) "%s TRIGGER: name '%s' already in use", base, triggername); } } if (create) { switch (trigger_event->token) { case SQL_INSERT: event = 0; break; case SQL_DELETE: event = 1; break; case SQL_TRUNCATE: event = 3; break; default: event = 2; break; } orientation = triggered_action->h->data.i_val; q = query_cleaned(QUERY(sql->scanner)); assert(triggered_action->h->type == type_int); r = rel_create_trigger(sql, t->s->base.name, t->base.name, triggername, time, orientation, event, old_name, new_name, condition, q); GDKfree(q); return r; } if (!instantiate) { t = mvc_bind_table(sql, ss, tname); if(!stack_push_frame(sql, "OLD-NEW")) return sql_error(sql, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL); /* we need to add the old and new tables */ if (!instantiate && new_name) { if(!_stack_push_table(sql, new_name, t)) return sql_error(sql, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL); } if (!instantiate && old_name) { if(!_stack_push_table(sql, old_name, t)) return sql_error(sql, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL); } } if (condition) { sql_rel *rel = NULL; if (new_name) /* in case of updates same relations is available via both names */ rel = stack_find_rel_view(sql, new_name); if (!rel && old_name) rel = stack_find_rel_view(sql, old_name); if (rel) rel = rel_logical_exp(sql, rel, condition, sql_where); if (!rel) return NULL; /* transition tables */ /* insert: rel_select(table [new], searchcondition) */ /* delete: rel_select(table [old], searchcondition) */ /* update: rel_select(table [old,new]), searchcondition) */ if (new_name) stack_update_rel_view(sql, new_name, rel); if (old_name) stack_update_rel_view(sql, old_name, new_name?rel_dup(rel):rel); } sq = sequential_block(sql, NULL, NULL, stmts, NULL, 1); r = rel_psm_block(sql->sa, sq); /* todo trigger_columns */ (void)columns; return r; }
void main() { char username[10],password[10],server[10]; int typeNo; char typeName[40],typePrice[40]; // printf("请输入用户名:"); // gets(username); // printf("请输入密码:"); // gets(password); // printf("请输入网络连接名:"); // gets(server); strcpy(username,"scott"); strcpy(password,"hotel000"); strcpy(server,"hotelDB"); /* EXEC SQL WHENEVER SQLERROR DO sql_error(); */ #line 21 "main.pc" /* EXEC SQL WHENEVER NOT FOUND DO sql_error(); */ #line 22 "main.pc" /* EXEC SQL CONNECT :username IDENTIFIED BY :password USING :server ; */ #line 23 "main.pc" { #line 23 "main.pc" struct sqlexd sqlstm; #line 23 "main.pc" sqlstm.sqlvsn = 12; #line 23 "main.pc" sqlstm.arrsiz = 4; #line 23 "main.pc" sqlstm.sqladtp = &sqladt; #line 23 "main.pc" sqlstm.sqltdsp = &sqltds; #line 23 "main.pc" sqlstm.iters = (unsigned int )10; #line 23 "main.pc" sqlstm.offset = (unsigned int )5; #line 23 "main.pc" sqlstm.cud = sqlcud0; #line 23 "main.pc" sqlstm.sqlest = (unsigned char *)&sqlca; #line 23 "main.pc" sqlstm.sqlety = (unsigned short)4352; #line 23 "main.pc" sqlstm.occurs = (unsigned int )0; #line 23 "main.pc" sqlstm.sqhstv[0] = ( void *)username; #line 23 "main.pc" sqlstm.sqhstl[0] = (unsigned int )10; #line 23 "main.pc" sqlstm.sqhsts[0] = ( int )10; #line 23 "main.pc" sqlstm.sqindv[0] = ( void *)0; #line 23 "main.pc" sqlstm.sqinds[0] = ( int )0; #line 23 "main.pc" sqlstm.sqharm[0] = (unsigned int )0; #line 23 "main.pc" sqlstm.sqadto[0] = (unsigned short )0; #line 23 "main.pc" sqlstm.sqtdso[0] = (unsigned short )0; #line 23 "main.pc" sqlstm.sqhstv[1] = ( void *)password; #line 23 "main.pc" sqlstm.sqhstl[1] = (unsigned int )10; #line 23 "main.pc" sqlstm.sqhsts[1] = ( int )10; #line 23 "main.pc" sqlstm.sqindv[1] = ( void *)0; #line 23 "main.pc" sqlstm.sqinds[1] = ( int )0; #line 23 "main.pc" sqlstm.sqharm[1] = (unsigned int )0; #line 23 "main.pc" sqlstm.sqadto[1] = (unsigned short )0; #line 23 "main.pc" sqlstm.sqtdso[1] = (unsigned short )0; #line 23 "main.pc" sqlstm.sqhstv[2] = ( void *)server; #line 23 "main.pc" sqlstm.sqhstl[2] = (unsigned int )10; #line 23 "main.pc" sqlstm.sqhsts[2] = ( int )10; #line 23 "main.pc" sqlstm.sqindv[2] = ( void *)0; #line 23 "main.pc" sqlstm.sqinds[2] = ( int )0; #line 23 "main.pc" sqlstm.sqharm[2] = (unsigned int )0; #line 23 "main.pc" sqlstm.sqadto[2] = (unsigned short )0; #line 23 "main.pc" sqlstm.sqtdso[2] = (unsigned short )0; #line 23 "main.pc" sqlstm.sqphsv = sqlstm.sqhstv; #line 23 "main.pc" sqlstm.sqphsl = sqlstm.sqhstl; #line 23 "main.pc" sqlstm.sqphss = sqlstm.sqhsts; #line 23 "main.pc" sqlstm.sqpind = sqlstm.sqindv; #line 23 "main.pc" sqlstm.sqpins = sqlstm.sqinds; #line 23 "main.pc" sqlstm.sqparm = sqlstm.sqharm; #line 23 "main.pc" sqlstm.sqparc = sqlstm.sqharc; #line 23 "main.pc" sqlstm.sqpadto = sqlstm.sqadto; #line 23 "main.pc" sqlstm.sqptdso = sqlstm.sqtdso; #line 23 "main.pc" sqlstm.sqlcmax = (unsigned int )100; #line 23 "main.pc" sqlstm.sqlcmin = (unsigned int )2; #line 23 "main.pc" sqlstm.sqlcincr = (unsigned int )1; #line 23 "main.pc" sqlstm.sqlctimeout = (unsigned int )0; #line 23 "main.pc" sqlstm.sqlcnowait = (unsigned int )0; #line 23 "main.pc" sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn); #line 23 "main.pc" if (sqlca.sqlcode < 0) sql_error(); #line 23 "main.pc" } #line 23 "main.pc" if(sqlca.sqlcode==0) { printf("连接成功\n"); printf("请输入类型号:"); scanf("%d",&typeNo); fflush(stdin); /* EXEC SQL SELECT TYPE_NAME,TYPE_PRICE INTO :typeName , :typePrice FROM SCOTT.ROOMTYPE WHERE TYPE_ID=:typeNo; */ #line 30 "main.pc" { #line 30 "main.pc" struct sqlexd sqlstm; #line 30 "main.pc" sqlstm.sqlvsn = 12; #line 30 "main.pc" sqlstm.arrsiz = 4; #line 30 "main.pc" sqlstm.sqladtp = &sqladt; #line 30 "main.pc" sqlstm.sqltdsp = &sqltds; #line 30 "main.pc" sqlstm.stmt = "select TYPE_NAME ,TYPE_PRICE into :b0,:b1 from SCO\ TT.ROOMTYPE where TYPE_ID=:b2"; #line 30 "main.pc" sqlstm.iters = (unsigned int )1; #line 30 "main.pc" sqlstm.offset = (unsigned int )36; #line 30 "main.pc" sqlstm.selerr = (unsigned short)1; #line 30 "main.pc" sqlstm.cud = sqlcud0; #line 30 "main.pc" sqlstm.sqlest = (unsigned char *)&sqlca; #line 30 "main.pc" sqlstm.sqlety = (unsigned short)4352; #line 30 "main.pc" sqlstm.occurs = (unsigned int )0; #line 30 "main.pc" sqlstm.sqhstv[0] = ( void *)typeName; #line 30 "main.pc" sqlstm.sqhstl[0] = (unsigned int )40; #line 30 "main.pc" sqlstm.sqhsts[0] = ( int )0; #line 30 "main.pc" sqlstm.sqindv[0] = ( void *)0; #line 30 "main.pc" sqlstm.sqinds[0] = ( int )0; #line 30 "main.pc" sqlstm.sqharm[0] = (unsigned int )0; #line 30 "main.pc" sqlstm.sqadto[0] = (unsigned short )0; #line 30 "main.pc" sqlstm.sqtdso[0] = (unsigned short )0; #line 30 "main.pc" sqlstm.sqhstv[1] = ( void *)typePrice; #line 30 "main.pc" sqlstm.sqhstl[1] = (unsigned int )40; #line 30 "main.pc" sqlstm.sqhsts[1] = ( int )0; #line 30 "main.pc" sqlstm.sqindv[1] = ( void *)0; #line 30 "main.pc" sqlstm.sqinds[1] = ( int )0; #line 30 "main.pc" sqlstm.sqharm[1] = (unsigned int )0; #line 30 "main.pc" sqlstm.sqadto[1] = (unsigned short )0; #line 30 "main.pc" sqlstm.sqtdso[1] = (unsigned short )0; #line 30 "main.pc" sqlstm.sqhstv[2] = ( void *)&typeNo; #line 30 "main.pc" sqlstm.sqhstl[2] = (unsigned int )sizeof(int); #line 30 "main.pc" sqlstm.sqhsts[2] = ( int )0; #line 30 "main.pc" sqlstm.sqindv[2] = ( void *)0; #line 30 "main.pc" sqlstm.sqinds[2] = ( int )0; #line 30 "main.pc" sqlstm.sqharm[2] = (unsigned int )0; #line 30 "main.pc" sqlstm.sqadto[2] = (unsigned short )0; #line 30 "main.pc" sqlstm.sqtdso[2] = (unsigned short )0; #line 30 "main.pc" sqlstm.sqphsv = sqlstm.sqhstv; #line 30 "main.pc" sqlstm.sqphsl = sqlstm.sqhstl; #line 30 "main.pc" sqlstm.sqphss = sqlstm.sqhsts; #line 30 "main.pc" sqlstm.sqpind = sqlstm.sqindv; #line 30 "main.pc" sqlstm.sqpins = sqlstm.sqinds; #line 30 "main.pc" sqlstm.sqparm = sqlstm.sqharm; #line 30 "main.pc" sqlstm.sqparc = sqlstm.sqharc; #line 30 "main.pc" sqlstm.sqpadto = sqlstm.sqadto; #line 30 "main.pc" sqlstm.sqptdso = sqlstm.sqtdso; #line 30 "main.pc" sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn); #line 30 "main.pc" if (sqlca.sqlcode == 1403) sql_error(); #line 30 "main.pc" if (sqlca.sqlcode < 0) sql_error(); #line 30 "main.pc" } #line 30 "main.pc" if(sqlca.sqlcode==0) printf("房间类型:%s,价位:%s",typeName,typePrice); else printf("查询失败"); }
static void limit_report(struct pattern_rule *rule, const char *action, struct limit *limit, const char *line, regmatch_t *parens) { SMTP2 *smtp; Vector rcpts; int smtp_flags; const unsigned char *text; char **table, buffer[SMTP_PATH_LENGTH]; if (0 < debug) (void) fprintf( stdout, "/%s/ %s: limit exceeded (%d)\n", rule->pattern, action, limit->reported + limit->counter ); smtp = NULL; rcpts = NULL; if (report_to != NULL) { rcpts = TextSplit(rule->report != NULL ? strchr(rule->report, '=')+1 : report_to, ",; ", 0); if (VectorLength(rcpts) <= 0) { (void) fprintf(stderr, "no report-to mail addresses\n"); goto error0; } /* Try to connect to local smart host. */ smtp_flags = SMTP_FLAG_LOG | (1 < debug ? SMTP_FLAG_DEBUG : 0); smtp = smtp2Open(smtp_host, SMTP_CONNECT_TO * UNIT_MILLI, SMTP_COMMAND_TO * UNIT_MILLI, smtp_flags); if (smtp == NULL) { (void) fprintf(stderr, "%s: %s (%d)\n", smtp_host, strerror(errno), errno); goto error1; } if (smtp2Mail(smtp, report_from) != SMTP_OK) { (void) fprintf(stderr, "%s: null sender not accepted\n", smtp_host); goto error2; } for (table = (char **) VectorBase(rcpts); *table != NULL; table++) { if (smtp2Rcpt(smtp, *table) != SMTP_OK) goto error2; } TimeStamp(&smtp->start, buffer, sizeof (buffer)); (void) smtp2Printf(smtp, "Date: %s" CRLF, buffer); (void) smtp2Printf(smtp, "From: \"%s\" <%s>" CRLF, _NAME, smtp->sender); (void) smtp2Printf(smtp, "Message-ID: <%s@%s>" CRLF, smtp->id_string, smtp->local_ip); (void) smtp2Printf(smtp, "Subject: %s log limit exceeded %s" CRLF, _NAME, limit->token); (void) smtp2Print(smtp, CRLF, sizeof (CRLF)-1); (void) smtp2Printf( smtp, "/%s/ %s: limit exceeded (%d)" CRLF CRLF, rule->pattern, action, limit->reported + limit->counter ); } if (sqlite3_bind_int64(ctx.select_limit_to_log, 1, limit->id_limit) != SQLITE_OK) { sql_error(__FILE__, __LINE__, ctx.increment_limit); goto error2; } if (sqlite3_bind_int64(ctx.select_limit_to_log, 2, limit->updated) != SQLITE_OK) { sql_error(__FILE__, __LINE__, ctx.increment_limit); goto error2; } while (sql_step(ctx.db, ctx.select_limit_to_log) == SQLITE_ROW) { if ((text = sqlite3_column_text(ctx.select_limit_to_log, 0)) == NULL) continue; if (0 < debug) (void) fprintf(stdout, "\t%s" CRLF, text); if (smtp != NULL) (void) smtp2Printf(smtp, "%s" CRLF, text); } if (rule->on_exceed != NULL) do_command(rule, rule->on_exceed, line, parens); (void) sqlite3_clear_bindings(ctx.select_limit_to_log); sqlite3_reset(ctx.select_limit_to_log); if (smtp != NULL) (void) smtp2Dot(smtp); error2: smtp2Close(smtp); error1: VectorDestroy(rcpts); error0: ; }
/* * Pattern Rule Grammar * -------------------- * * line := blank | "#" comment | rule * * rule := pattern *[ whitespace ] actions * * whitespace := SPACE | TAB * * pattern := "/" extended_regex "/" * * actions := action [ ";" actions ] * * action := thread | limit | report | on_exceed | on_expire * * quote := "'" | '"' * * index := number | quote text quote * * indices := index [ "," index ] * * thread := "t=" indices * * limit := "l=" indices "," max "/" period [ unit ] * * report := "r=" mail *[ "," mail ] * * on_exceed := "c=" quoted_shell_command * * on_expire := "C=" quoted_shell_command * * quoted_shell_command := quote text quote */ static int init_rule(char *line) { Vector fields; const char *next; struct pattern_rule *rule; int i, rc = -1, err; char *field, error[128]; if (*line != '/') goto error0; if ((rule = calloc(1, sizeof (*rule))) == NULL) goto error0; if ((rule->pattern = TokenNext(line, &next, "/", TOKEN_KEEP_ASIS)) == NULL) goto error1; if ((fields = TextSplit(next, ";", TOKEN_KEEP_ASIS)) == NULL) goto error1; if ((err = regcomp(&rule->re, rule->pattern, REG_EXTENDED|REG_NEWLINE)) != 0) { (void) regerror(err, &rule->re, error, sizeof (error)); (void) fprintf(stderr, "pattern /%s/: %s (%d)\n", rule->pattern, error, err); goto error2; } /* Assume new previously unknown pattern. */ if ((err = sqlite3_bind_text(ctx.insert_pattern, 1, rule->pattern, -1, SQLITE_STATIC)) != SQLITE_OK) { sql_error(__FILE__, __LINE__, ctx.insert_pattern); goto error2; } if ((err = sql_step(ctx.db, ctx.insert_pattern)) != SQLITE_DONE) { sql_error(__FILE__, __LINE__, ctx.insert_pattern); goto error2; } rule->id_pattern = sqlite3_last_insert_rowid(ctx.db); (void) sqlite3_clear_bindings(ctx.insert_pattern); sqlite3_reset(ctx.insert_pattern); /* Last insert rowid is zero if no row was inserted, thus it * already exists and we need to find the pattern number (OID). */ if (rule->id_pattern == 0) { if ((err = sqlite3_bind_text(ctx.find_pattern, 1, rule->pattern, -1, SQLITE_STATIC)) != SQLITE_OK) { sql_error(__FILE__, __LINE__, ctx.find_pattern); goto error2; } if ((err = sql_step(ctx.db, ctx.find_pattern)) != SQLITE_ROW) { sql_error(__FILE__, __LINE__, ctx.find_pattern); goto error2; } if ((rule->id_pattern = sqlite3_column_int64(ctx.find_pattern, 0)) == 0) { sql_error(__FILE__, __LINE__, ctx.find_pattern); goto error2; } (void) sqlite3_clear_bindings(ctx.find_pattern); sqlite3_reset(ctx.find_pattern); } for (i = 0; i < VectorLength(fields); i++) { field = VectorGet(fields, i); field += strspn(field, " \t"); switch (*field) { case 'c': if (field[1] == '=') { free(rule->on_exceed); rule->on_exceed = VectorReplace(fields, i, NULL); } break; case 'C': if (field[1] == '=') { free(rule->on_expire); rule->on_expire = VectorReplace(fields, i, NULL); } break; case 'r': if (field[1] == '=') { free(rule->report); rule->report = VectorReplace(fields, i, NULL); } break; case 't': if (field[1] == '=') rule->thread = strtol(field+2, NULL, 10); break; case 'l': if (field[1] == '=') continue; } (void) VectorRemove(fields, i--); } field[strcspn(field, "\r\n")] = '\0'; /* What remains of fields should be an empty vector or an array of l= actions. */ rule->limits = (char **) VectorBase(fields); fields = NULL; rule->node.data = rule; rule->node.free = free_rule; listInsertAfter(&pattern_rules, NULL, &rule->node); rc = 0; error2: VectorDestroy(fields); error1: if (rc != 0) free_rule(rule); error0: return rc; }
sql_rel * rel_psm(mvc *sql, symbol *s) { sql_rel *ret = NULL; switch (s->token) { case SQL_CREATE_FUNC: { dlist *l = s->data.lval; int type = l->h->next->next->next->next->next->data.i_val; int lang = l->h->next->next->next->next->next->next->data.i_val; ret = rel_create_func(sql, l->h->data.lval, l->h->next->data.lval, l->h->next->next->data.sym, l->h->next->next->next->data.lval, l->h->next->next->next->next->data.lval, type, lang); sql->type = Q_SCHEMA; } break; case SQL_DROP_FUNC: { dlist *l = s->data.lval; int type = l->h->next->next->next->next->data.i_val; if (STORE_READONLY) return sql_error(sql, 06, "schema statements cannot be executed on a readonly database."); assert(l->h->next->type == type_int); assert(l->h->next->next->next->type == type_int); if (l->h->next->data.i_val) /*?l_val?*/ ret = rel_drop_all_func(sql, l->h->data.lval, l->h->next->next->next->data.i_val, type); else ret = rel_drop_func(sql, l->h->data.lval, l->h->next->next->data.lval, l->h->next->next->next->data.i_val, type); sql->type = Q_SCHEMA; } break; case SQL_SET: ret = rel_psm_stmt(sql->sa, psm_set_exp(sql, s->data.lval->h)); sql->type = Q_SCHEMA; break; case SQL_DECLARE: ret = rel_psm_block(sql->sa, rel_psm_declare(sql, s->data.lval->h)); sql->type = Q_SCHEMA; break; case SQL_CALL: ret = rel_psm_stmt(sql->sa, rel_psm_call(sql, s->data.sym)); sql->type = Q_UPDATE; break; case SQL_CREATE_TRIGGER: { dlist *l = s->data.lval; assert(l->h->next->type == type_int); ret = create_trigger(sql, l->h->data.lval, l->h->next->data.i_val, l->h->next->next->data.sym, l->h->next->next->next->data.sval, l->h->next->next->next->next->data.lval, l->h->next->next->next->next->next->data.lval); sql->type = Q_SCHEMA; } break; case SQL_DROP_TRIGGER: { dlist *l = s->data.lval; ret = drop_trigger(sql, l); sql->type = Q_SCHEMA; } break; case SQL_ANALYZE: { dlist *l = s->data.lval; ret = psm_analyze(sql, l->h->data.lval /* qualified table name */, l->h->next->data.lval /* opt list of column */, l->h->next->next->data.sym /* opt_sample_size */); sql->type = Q_UPDATE; } break; default: return sql_error(sql, 01, "schema statement unknown symbol(" PTRFMT ")->token = %s", PTRFMTCAST s, token2string(s->token)); } return ret; }
static sql_rel * rel_create_func(mvc *sql, dlist *qname, dlist *params, symbol *res, dlist *ext_name, dlist *body, int type, int lang, int replace) { const char *fname = qname_table(qname); const char *sname = qname_schema(qname); sql_schema *s = NULL; sql_func *f = NULL; sql_subfunc *sf; dnode *n; list *type_list = NULL, *restype = NULL; int instantiate = (sql->emode == m_instantiate); int deps = (sql->emode == m_deps); int create = (!instantiate && !deps); bit vararg = FALSE; char is_table = (res && res->token == SQL_TABLE); char is_aggr = (type == F_AGGR); char is_func = (type != F_PROC); char is_loader = (type == F_LOADER); char *F = is_loader?"LOADER":(is_aggr?"AGGREGATE":(is_func?"FUNCTION":"PROCEDURE")); char *fn = is_loader?"loader":(is_aggr ? "aggregate" : (is_func ? "function" : "procedure")); char *KF = type==F_FILT?"FILTER ": type==F_UNION?"UNION ": ""; char *kf = type == F_FILT ? "filter " : type == F_UNION ? "union " : ""; assert(res || type == F_PROC || type == F_FILT || type == F_LOADER); if (is_table) type = F_UNION; if (STORE_READONLY && create) return sql_error(sql, 06, SQLSTATE(42000) "Schema statements cannot be executed on a readonly database."); if (sname && !(s = mvc_bind_schema(sql, sname))) return sql_error(sql, 02, SQLSTATE(3F000) "CREATE %s%s: no such schema '%s'", KF, F, sname); if (s == NULL) s = cur_schema(sql); type_list = create_type_list(sql, params, 1); if ((sf = sql_bind_func_(sql->sa, s, fname, type_list, type)) != NULL && create) { if (replace) { sql_func *func = sf->func; int action = 0; if (!mvc_schema_privs(sql, s)) { return sql_error(sql, 02, SQLSTATE(42000) "CREATE OR REPLACE %s%s: access denied for %s to schema ;'%s'", KF, F, stack_get_string(sql, "current_user"), s->base.name); } if (mvc_check_dependency(sql, func->base.id, !IS_PROC(func) ? FUNC_DEPENDENCY : PROC_DEPENDENCY, NULL)) return sql_error(sql, 02, SQLSTATE(42000) "CREATE OR REPLACE %s%s: there are database objects dependent on %s%s %s;", KF, F, kf, fn, func->base.name); if (!func->s) { return sql_error(sql, 02, SQLSTATE(42000) "CREATE OR REPLACE %s%s: not allowed to replace system %s%s %s;", KF, F, kf, fn, func->base.name); } if(mvc_drop_func(sql, s, func, action)) return sql_error(sql, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL); sf = NULL; } else { if (params) { char *arg_list = NULL; node *n; for (n = type_list->h; n; n = n->next) { char *tpe = subtype2string((sql_subtype *) n->data); if (arg_list) { char *t = arg_list; arg_list = sql_message("%s, %s", arg_list, tpe); _DELETE(t); _DELETE(tpe); } else { arg_list = tpe; } } (void)sql_error(sql, 02, SQLSTATE(42000) "CREATE %s%s: name '%s' (%s) already in use", KF, F, fname, arg_list); _DELETE(arg_list); list_destroy(type_list); return NULL; } else { list_destroy(type_list); return sql_error(sql, 02, SQLSTATE(42000) "CREATE %s%s: name '%s' already in use", KF, F, fname); } } } list_destroy(type_list); if (create && !mvc_schema_privs(sql, s)) { return sql_error(sql, 02, SQLSTATE(42000) "CREATE %s%s: insufficient privileges " "for user '%s' in schema '%s'", KF, F, stack_get_string(sql, "current_user"), s->base.name); } else { char *q = QUERY(sql->scanner); list *l = NULL; if (params) { for (n = params->h; n; n = n->next) { dnode *an = n->data.lval->h; sql_add_param(sql, an->data.sval, &an->next->data.typeval); } l = sql->params; if (l && list_length(l) == 1) { sql_arg *a = l->h->data; if (strcmp(a->name, "*") == 0) { l = NULL; vararg = TRUE; } } } if (!l) l = sa_list(sql->sa); if (res) { restype = result_type(sql, res); if (!restype) return sql_error(sql, 01, SQLSTATE(42000) "CREATE %s%s: failed to get restype", KF, F); } if (body && lang > FUNC_LANG_SQL) { char *lang_body = body->h->data.sval; char *mod = (lang == FUNC_LANG_R)?"rapi": (lang == FUNC_LANG_C || lang == FUNC_LANG_CPP)?"capi": (lang == FUNC_LANG_J)?"japi": (lang == FUNC_LANG_PY)?"pyapi": (lang == FUNC_LANG_MAP_PY)?"pyapimap":"unknown"; sql->params = NULL; if (create) { f = mvc_create_func(sql, sql->sa, s, fname, l, restype, type, lang, mod, fname, lang_body, (type == F_LOADER)?TRUE:FALSE, vararg, FALSE); } else if (!sf) { return sql_error(sql, 01, SQLSTATE(42000) "CREATE %s%s: R function %s.%s not bound", KF, F, s->base.name, fname ); } /*else { sql_func *f = sf->func; f->mod = _STRDUP("rapi"); f->imp = _STRDUP("eval"); if (res && restype) f->res = restype; f->sql = 0; f->lang = FUNC_LANG_INT; }*/ } else if (body) { sql_arg *ra = (restype && !is_table)?restype->h->data:NULL; list *b = NULL; sql_schema *old_schema = cur_schema(sql); if (create) { /* needed for recursive functions */ q = query_cleaned(q); sql->forward = f = mvc_create_func(sql, sql->sa, s, fname, l, restype, type, lang, "user", q, q, FALSE, vararg, FALSE); GDKfree(q); } sql->session->schema = s; b = sequential_block(sql, (ra)?&ra->type:NULL, ra?NULL:restype, body, NULL, is_func); sql->forward = NULL; sql->session->schema = old_schema; sql->params = NULL; if (!b) return NULL; /* check if we have a return statement */ if (is_func && restype && !has_return(b)) { return sql_error(sql, 01, SQLSTATE(42000) "CREATE %s%s: missing return statement", KF, F); } if (!is_func && !restype && has_return(b)) { return sql_error(sql, 01, SQLSTATE(42000) "CREATE %s%s: procedures " "cannot have return statements", KF, F); } /* in execute mode we instantiate the function */ if (instantiate || deps) { return rel_psm_block(sql->sa, b); } } else { char *fmod = qname_module(ext_name); char *fnme = qname_fname(ext_name); if (!fmod || !fnme) return NULL; sql->params = NULL; if (create) { q = query_cleaned(q); f = mvc_create_func(sql, sql->sa, s, fname, l, restype, type, lang, fmod, fnme, q, FALSE, vararg, FALSE); GDKfree(q); } else if (!sf) { return sql_error(sql, 01, SQLSTATE(42000) "CREATE %s%s: external name %s.%s not bound (%s.%s)", KF, F, fmod, fnme, s->base.name, fname ); } else { sql_func *f = sf->func; if (!f->mod || strcmp(f->mod, fmod)) f->mod = _STRDUP(fmod); if (!f->imp || strcmp(f->imp, fnme)) f->imp = (f->sa)?sa_strdup(f->sa, fnme):_STRDUP(fnme); if(!f->mod || !f->imp) { _DELETE(f->mod); _DELETE(f->imp); return sql_error(sql, 02, SQLSTATE(HY001) "CREATE %s%s: could not allocate space", KF, F); } f->sql = 0; /* native */ f->lang = FUNC_LANG_INT; } } } return rel_create_function(sql->sa, s->base.name, f); }
/* 1 CASE WHEN search_condition THEN statements [ WHEN search_condition THEN statements ] [ ELSE statements ] END CASE 2 CASE case_value WHEN when_value THEN statements [ WHEN when_value THEN statements ] [ ELSE statements ] END CASE */ static list * rel_psm_case( mvc *sql, sql_subtype *res, dnode *case_when, int is_func ) { list *case_stmts = sa_list(sql->sa); if (!case_when) return NULL; /* case 1 */ if (case_when->type == type_symbol) { dnode *n = case_when; symbol *case_value = n->data.sym; dlist *when_statements = n->next->data.lval; dlist *else_statements = n->next->next->data.lval; list *else_stmt = NULL; sql_rel *rel = NULL; exp_kind ek = {type_value, card_value, FALSE}; sql_exp *v = rel_value_exp(sql, &rel, case_value, sql_sel, ek); if (!v) return NULL; if (rel) return sql_error(sql, 02, "CASE: No SELECT statements allowed within the CASE condition"); if (else_statements) { else_stmt = sequential_block( sql, res, NULL, else_statements, NULL, is_func); if (!else_stmt) return NULL; } n = when_statements->h; while(n) { dnode *m = n->data.sym->data.lval->h; sql_exp *cond=0, *when_value = rel_value_exp(sql, &rel, m->data.sym, sql_sel, ek); list *if_stmts = NULL; sql_exp *case_stmt = NULL; if (!when_value || rel || (cond = rel_binop_(sql, v, when_value, NULL, "=", card_value)) == NULL || (if_stmts = sequential_block( sql, res, NULL, m->next->data.lval, NULL, is_func)) == NULL ) { if (rel) return sql_error(sql, 02, "CASE: No SELECT statements allowed within the CASE condition"); return NULL; } case_stmt = exp_if(sql->sa, cond, if_stmts, NULL); list_append(case_stmts, case_stmt); n = n->next; } if (else_stmt) list_merge(case_stmts, else_stmt, NULL); return case_stmts; } else { /* case 2 */ dnode *n = case_when; dlist *whenlist = n->data.lval; dlist *else_statements = n->next->data.lval; list *else_stmt = NULL; if (else_statements) { else_stmt = sequential_block( sql, res, NULL, else_statements, NULL, is_func); if (!else_stmt) return NULL; } n = whenlist->h; while(n) { dnode *m = n->data.sym->data.lval->h; sql_rel *rel = NULL; sql_exp *cond = rel_logical_value_exp(sql, &rel, m->data.sym, sql_sel); list *if_stmts = NULL; sql_exp *case_stmt = NULL; if (!cond || rel || (if_stmts = sequential_block( sql, res, NULL, m->next->data.lval, NULL, is_func)) == NULL ) { if (rel) return sql_error(sql, 02, "CASE: No SELECT statements allowed within the CASE condition"); return NULL; } case_stmt = exp_if(sql->sa, cond, if_stmts, NULL); list_append(case_stmts, case_stmt); n = n->next; } if (else_stmt) list_merge(case_stmts, else_stmt, NULL); return case_stmts; } }
sql_func * resolve_func( mvc *sql, sql_schema *s, const char *name, dlist *typelist, int type, char *op, int if_exists) { sql_func *func = NULL; list *list_func = NULL, *type_list = NULL; char is_aggr = (type == F_AGGR); char is_func = (type != F_PROC && type != F_LOADER); char *F = is_aggr?"AGGREGATE":(is_func?"FUNCTION":"PROCEDURE"); char *f = is_aggr?"aggregate":(is_func?"function":"procedure"); char *KF = type==F_FILT?"FILTER ": type==F_UNION?"UNION ": ""; char *kf = type==F_FILT?"filter ": type==F_UNION?"union ": ""; if (typelist) { sql_subfunc *sub_func; type_list = create_type_list(sql, typelist, 0); sub_func = sql_bind_func_(sql->sa, s, name, type_list, type); if (!sub_func && type == F_FUNC) { sub_func = sql_bind_func_(sql->sa, s, name, type_list, F_UNION); type = sub_func?F_UNION:F_FUNC; } if ( sub_func && sub_func->func->type == type) func = sub_func->func; } else { list_func = schema_bind_func(sql, s, name, type); if (!list_func && type == F_FUNC) list_func = schema_bind_func(sql,s,name, F_UNION); if (list_func && list_func->cnt > 1) { list_destroy(list_func); return sql_error(sql, 02, SQLSTATE(42000) "%s %s%s: there are more than one %s%s called '%s', please use the full signature", op, KF, F, kf, f,name); } if (list_func && list_func->cnt == 1) func = (sql_func*) list_func->h->data; } if (!func) { void *e = NULL; if (typelist) { char *arg_list = NULL; node *n; if (type_list->cnt > 0) { for (n = type_list->h; n; n = n->next) { char *tpe = subtype2string((sql_subtype *) n->data); if (arg_list) { char *t = arg_list; arg_list = sql_message("%s, %s", arg_list, tpe); _DELETE(tpe); _DELETE(t); } else { arg_list = tpe; } } list_destroy(list_func); list_destroy(type_list); if(!if_exists) e = sql_error(sql, 02, SQLSTATE(42000) "%s %s%s: no such %s%s '%s' (%s)", op, KF, F, kf, f, name, arg_list); _DELETE(arg_list); return e; } list_destroy(list_func); list_destroy(type_list); if(!if_exists) e = sql_error(sql, 02, SQLSTATE(42000) "%s %s%s: no such %s%s '%s' ()", op, KF, F, kf, f, name); return e; } else { if(!if_exists) e = sql_error(sql, 02, SQLSTATE(42000) "%s %s%s: no such %s%s '%s'", op, KF, F, kf, f, name); return e; } } else if (((is_func && type != F_FILT) && !func->res) || (!is_func && func->res)) { list_destroy(list_func); list_destroy(type_list); return sql_error(sql, 02, SQLSTATE(42000) "%s %s%s: cannot drop %s '%s'", KF, F, is_func?"procedure":"function", op, name); } list_destroy(list_func); list_destroy(type_list); return func; }
static list * sequential_block (mvc *sql, sql_subtype *restype, list *restypelist, dlist *blk, char *opt_label, int is_func) { list *l=0; dnode *n; assert(!restype || !restypelist); if (THRhighwater()) return sql_error(sql, 10, "SELECT: too many nested operators"); if (blk->h) l = sa_list(sql->sa); stack_push_frame(sql, opt_label); for (n = blk->h; n; n = n->next ) { sql_exp *res = NULL; list *reslist = NULL; symbol *s = n->data.sym; switch (s->token) { case SQL_SET: res = psm_set_exp(sql, s->data.lval->h); break; case SQL_DECLARE: reslist = rel_psm_declare(sql, s->data.lval->h); break; case SQL_CREATE_TABLE: res = rel_psm_declare_table(sql, s->data.lval->h); break; case SQL_WHILE: res = rel_psm_while_do(sql, restype, s->data.lval->h, is_func); break; case SQL_IF: res = rel_psm_if_then_else(sql, restype, s->data.lval->h, is_func); break; case SQL_CASE: reslist = rel_psm_case(sql, restype, s->data.lval->h, is_func); break; case SQL_CALL: res = rel_psm_call(sql, s->data.sym); break; case SQL_RETURN: /*If it is not a function it cannot have a return statement*/ if (!is_func) res = sql_error(sql, 01, "Return statement in the procedure body"); else { /* should be last statement of a sequential_block */ if (n->next) { res = sql_error(sql, 01, "Statement after return"); } else { reslist = rel_psm_return(sql, restype, restypelist, s->data.sym); } } break; case SQL_SELECT: { /* row selections (into variables) */ exp_kind ek = {type_value, card_row, TRUE}; reslist = rel_select_into(sql, s, ek); } break; case SQL_COPYFROM: case SQL_BINCOPYFROM: case SQL_INSERT: case SQL_UPDATE: case SQL_DELETE: { sql_rel *r = rel_updates(sql, s); if (!r) return NULL; res = exp_rel(sql, r); } break; default: res = sql_error(sql, 01, "Statement '%s' is not a valid flow control statement", token2string(s->token)); } if (!res && !reslist) { l = NULL; break; } if (res) list_append(l, res); else list_merge(l, reslist, NULL); } stack_pop_frame(sql); return l; }
/************************************************************************* * * Function: sql_affected_rows * * Purpose: Return the number of rows affected by the query (update, * or insert) * *************************************************************************/ static int sql_affected_rows(SQLSOCK *sqlsocket, SQL_CONFIG *config) { int affected_rows=fb_affected_rows(sqlsocket->conn); if (affected_rows<0) radlog(L_ERR, "sql_affected_rows, rlm_sql_firebird. error:%s\n", sql_error(sqlsocket,config)); return affected_rows; }