Пример #1
0
static sql_rel *
drop_trigger(mvc *sql, dlist *qname)
{
	char *tname = qname_table(qname);
	sql_schema *ss = cur_schema(sql);

	if (!schema_privs(sql->role_id, ss)) 
		return sql_error(sql, 02, "DROP TRIGGER: access denied for %s to schema ;'%s'", stack_get_string(sql, "current_user"), ss->base.name);
	return rel_drop_trigger(sql, ss->base.name, tname);
}
Пример #2
0
char *
sql_revoke_table_privs( mvc *sql, char *grantee, int privs, char *sname, char *tname, char *cname, int grant, int grantor)
{
	sql_schema *s = NULL;
	sql_table *t = NULL;
	sql_column *c = NULL;
	int allowed, grantee_id;
	int all = PRIV_SELECT | PRIV_UPDATE | PRIV_INSERT | PRIV_DELETE;

 	if (sname)
		s = mvc_bind_schema(sql, sname);
	if (s)
 		t = mvc_bind_table(sql, s, tname);
	if (!t) 
		return sql_message("42S02!REVOKE: no such table '%s'", tname);

	allowed = schema_privs(grantor, t->s);
	if (!allowed)
		allowed = sql_grantable(sql, grantor, t->base.id, all, 0);

	if (!allowed) 
		return sql_message("0L000!REVOKE: grantor '%s' is not allowed to revoke privileges for table '%s'", stack_get_string(sql,"current_user"), tname);

	if (cname) { 
		c = mvc_bind_column(sql, t, cname);
		if (!c) 
			return sql_message("42S22!REVOKE: table %s has no column %s", tname, cname);
		/* allowed on column */
		if (!allowed)
			allowed = sql_grantable(sql, grantor, c->base.id, privs, 0);

		if (!allowed) 
			return sql_message("0L000!REVOKE: grantor %s is not allowed to revoke privilege %s for table %s", stack_get_string(sql, "current_user"), priv2string(privs), tname);
	}

	grantee_id = sql_find_auth(sql, grantee);
	if (grantee_id <= 0) 
		return sql_message("42M32!REVOKE: user/role '%s' unknown", grantee);
	if (privs == all) {
		sql_delete_priv(sql, grantee_id, t->base.id, PRIV_SELECT, grantor, grant);
		sql_delete_priv(sql, grantee_id, t->base.id, PRIV_UPDATE, grantor, grant);
		sql_delete_priv(sql, grantee_id, t->base.id, PRIV_INSERT, grantor, grant);
		sql_delete_priv(sql, grantee_id, t->base.id, PRIV_DELETE, grantor, grant);
	} else if (!c)
		sql_insert_priv(sql, grantee_id, t->base.id, privs, grantor, grant);
	else
		sql_insert_priv(sql, grantee_id, c->base.id, privs, grantor, grant);
	return NULL;
}
Пример #3
0
static sql_rel *
rel_create_func(mvc *sql, dlist *qname, dlist *params, symbol *res, dlist *ext_name, dlist *body, int type, int lang)
{
	char *fname = qname_table(qname);
	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 *F = is_aggr?"AGGREGATE":(is_func?"FUNCTION":"PROCEDURE");
	char *KF = type==F_FILT?"FILTER ": type==F_UNION?"UNION ": "";

	assert(res || type == F_PROC || type == F_FILT);

	if (is_table)
		type = F_UNION;

	if (STORE_READONLY && create) 
		return sql_error(sql, 06, "schema statements cannot be executed on a readonly database.");
			
	if (sname && !(s = mvc_bind_schema(sql, sname)))
		return sql_error(sql, 02, "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 (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) {
					arg_list = sql_message("%s, %s", arg_list, tpe);
					_DELETE(tpe);	
				} else {
					arg_list = tpe;
				}
			}
			(void)sql_error(sql, 02, "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, "CREATE %s%s: name '%s' already in use", KF, F, fname);
		}
	} else {
		list_destroy(type_list);
		if (create && !schema_privs(sql->role_id, s)) {
			return sql_error(sql, 02, "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,
							"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)?"capi":
						(lang == FUNC_LANG_J)?"japi":"unknown";
				sql->params = NULL;
				if (create) {
					f = mvc_create_func(sql, sql->sa, s, fname, l, restype, type, lang,  mod, fname, lang_body, FALSE, vararg);
				} else if (!sf) {
					return sql_error(sql, 01, "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; /* native */
					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);
	
				sql->session->schema = s;
				b = sequential_block(sql, (ra)?&ra->type:NULL, ra?NULL:restype, body, NULL, is_func);
				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,
							"CREATE %s%s: missing return statement", KF, F);
				}
				if (!is_func && !restype && has_return(b)) {
					return sql_error(sql, 01, "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 if (create) {
					f = mvc_create_func(sql, sql->sa, s, fname, l, restype, type, lang, "user", q, q, FALSE, vararg);
				}
			} else {
				char *fmod = qname_module(ext_name);
				char *fnme = qname_fname(ext_name);

				if (!fmod || !fnme)
					return NULL;
				sql->params = NULL;
				if (create) {
					f = mvc_create_func(sql, sql->sa, s, fname, l, restype, type, lang, fmod, fnme, q, FALSE, vararg);
				} else if (!sf) {
					return sql_error(sql, 01, "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;
					f->mod = _STRDUP(fmod);
					f->imp = _STRDUP(fnme);
					f->sql = 0; /* native */
					f->lang = FUNC_LANG_INT;
				}
			}
		}
	}
	return rel_create_function(sql->sa, s->base.name, f);
}
Пример #4
0
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;
}