-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature] Support security view #54458
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,15 +27,19 @@ public class CreateViewStmt extends DdlStmt { | |
private final boolean ifNotExists; | ||
private final boolean replace; | ||
private final String comment; | ||
private final boolean security; | ||
protected QueryStatement queryStatement; | ||
|
||
//Resolved by Analyzer | ||
protected List<Column> columns; | ||
private String inlineViewDef; | ||
|
||
public CreateViewStmt(boolean ifNotExists, boolean replace, | ||
TableName tableName, List<ColWithComment> colWithComments, | ||
public CreateViewStmt(boolean ifNotExists, | ||
boolean replace, | ||
TableName tableName, | ||
List<ColWithComment> colWithComments, | ||
String comment, | ||
boolean security, | ||
QueryStatement queryStmt, | ||
NodePosition pos) { | ||
super(pos); | ||
|
@@ -44,6 +48,7 @@ public CreateViewStmt(boolean ifNotExists, boolean replace, | |
this.tableName = tableName; | ||
this.colWithComments = colWithComments; | ||
this.comment = Strings.nullToEmpty(comment); | ||
this.security = security; | ||
this.queryStatement = queryStmt; | ||
} | ||
|
||
|
@@ -79,6 +84,10 @@ public String getComment() { | |
return comment; | ||
} | ||
|
||
public boolean isSecurity() { | ||
return security; | ||
} | ||
|
||
public QueryStatement getQueryStatement() { | ||
return queryStatement; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The most risky bug in this code is: You can modify the code like this: private final boolean security; to include a default value if private final boolean security = false; Furthermore, ensure that |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1616,12 +1616,23 @@ public ParseNode visitCreateViewStatement(StarRocksParser.CreateViewStatementCon | |
throw new ParsingException(PARSER_ERROR_MSG.conflictedOptions("if not exists", "or replace"), | ||
createPos(context)); | ||
} | ||
|
||
boolean isSecurity = false; | ||
if (context.SECURITY() != null) { | ||
if (context.NONE() != null) { | ||
isSecurity = false; | ||
} else if (context.INVOKER() != null) { | ||
isSecurity = true; | ||
} | ||
} | ||
|
||
return new CreateViewStmt( | ||
context.IF() != null, | ||
context.REPLACE() != null, | ||
targetTableName, | ||
colWithComments, | ||
context.comment() == null ? null : ((StringLiteral) visit(context.comment())).getStringValue(), | ||
isSecurity, | ||
(QueryStatement) visit(context.queryStatement()), createPos(context)); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The most risky bug in this code is: You can modify the code like this: boolean isSecurity = false;
if (context.SECURITY() != null) {
if (context.NONE() != null) {
isSecurity = false;
} else if (context.INVOKER() != null) {
isSecurity = true;
} else {
throw new ParsingException(PARSER_ERROR_MSG.invalidOption("SECURITY"), createPos(context));
}
} |
||
|
@@ -1631,13 +1642,25 @@ public ParseNode visitAlterViewStatement(StarRocksParser.AlterViewStatementConte | |
TableName targetTableName = qualifiedNameToTableName(qualifiedName); | ||
|
||
List<ColWithComment> colWithComments = null; | ||
if (context.columnNameWithComment().size() > 0) { | ||
if (!context.columnNameWithComment().isEmpty()) { | ||
colWithComments = visit(context.columnNameWithComment(), ColWithComment.class); | ||
} | ||
QueryStatement queryStatement = (QueryStatement) visit(context.queryStatement()); | ||
AlterClause alterClause = new AlterViewClause(colWithComments, queryStatement, createPos(context)); | ||
|
||
return new AlterViewStmt(targetTableName, alterClause, createPos(context)); | ||
boolean isSecurity = false; | ||
if (context.SECURITY() != null) { | ||
if (context.NONE() != null) { | ||
isSecurity = false; | ||
} else if (context.INVOKER() != null) { | ||
isSecurity = true; | ||
} | ||
|
||
return new AlterViewStmt(targetTableName, isSecurity, null, createPos(context)); | ||
} else { | ||
QueryStatement queryStatement = (QueryStatement) visit(context.queryStatement()); | ||
AlterClause alterClause = new AlterViewClause(colWithComments, queryStatement, createPos(context)); | ||
|
||
return new AlterViewStmt(targetTableName, isSecurity, alterClause, createPos(context)); | ||
} | ||
} | ||
|
||
@Override | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
-- name: test_security_view | ||
create table t1(c1 bigint, c2 bigint); | ||
-- result: | ||
-- !result | ||
create table t2(c3 bigint, c4 bigint); | ||
-- result: | ||
-- !result | ||
create view v1 as select * from t1, t2; | ||
-- result: | ||
-- !result | ||
create view v2 security invoker as select * from t1, t2; | ||
-- result: | ||
-- !result | ||
create user if not exists u1; | ||
-- result: | ||
-- !result | ||
grant impersonate on user root to u1; | ||
-- result: | ||
-- !result | ||
grant select on view v1 to user u1; | ||
-- result: | ||
-- !result | ||
grant select on view v2 to user u1; | ||
-- result: | ||
-- !result | ||
create user if not exists u2; | ||
-- result: | ||
-- !result | ||
grant impersonate on user root to u2; | ||
-- result: | ||
-- !result | ||
grant select on table t1 to user u2; | ||
-- result: | ||
-- !result | ||
grant select on table t2 to user u2; | ||
-- result: | ||
-- !result | ||
grant select on view v1 to user u2; | ||
-- result: | ||
-- !result | ||
grant select on view v2 to user u2; | ||
-- result: | ||
-- !result | ||
execute as u1 with no revert; | ||
-- result: | ||
-- !result | ||
select * from v1; | ||
-- result: | ||
-- !result | ||
select * from v2; | ||
-- result: | ||
E: (5203, 'Access denied; you need (at least one of) the SELECT privilege(s) on VIEW v2 for this operation. Please ask the admin to grant permission(s) or try activating existing roles using <set [default] role>. Current role(s): NONE. Inactivated role(s): NONE.') | ||
-- !result | ||
execute as root with no revert; | ||
-- result: | ||
-- !result | ||
execute as u2 with no revert; | ||
-- result: | ||
-- !result | ||
select * from v1; | ||
-- result: | ||
-- !result | ||
select * from v2; | ||
-- result: | ||
-- !result | ||
execute as root with no revert; | ||
-- result: | ||
-- !result | ||
alter view v1 set security invoker; | ||
-- result: | ||
-- !result | ||
alter view v2 set security none; | ||
-- result: | ||
-- !result | ||
execute as u1 with no revert; | ||
-- result: | ||
-- !result | ||
select * from v1; | ||
-- result: | ||
E: (5203, 'Access denied; you need (at least one of) the SELECT privilege(s) on VIEW v1 for this operation. Please ask the admin to grant permission(s) or try activating existing roles using <set [default] role>. Current role(s): NONE. Inactivated role(s): NONE.') | ||
-- !result | ||
select * from v2; | ||
-- result: | ||
-- !result | ||
execute as root with no revert; | ||
-- result: | ||
-- !result | ||
execute as u2 with no revert; | ||
-- result: | ||
-- !result | ||
select * from v1; | ||
-- result: | ||
-- !result | ||
select * from v2; | ||
-- result: | ||
-- !result | ||
execute as root with no revert; | ||
-- result: | ||
-- !result | ||
drop user u1; | ||
-- result: | ||
-- !result | ||
drop user u2; | ||
-- result: | ||
-- !result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The most risky bug in this code is:
Improper handling of
null
return value fromgetBasicTable
, which may lead to aNullPointerException
.You can modify the code like this: