Skip to content

feat: add support SELECT all columns from function result #2207

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import net.sf.jsqlparser.statement.piped.FromQuery;
import net.sf.jsqlparser.statement.select.AllColumns;
import net.sf.jsqlparser.statement.select.AllTableColumns;
import net.sf.jsqlparser.statement.select.FunctionAllColumns;
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
import net.sf.jsqlparser.statement.select.Select;

Expand Down Expand Up @@ -585,6 +586,8 @@ default void visit(OracleNamedFunctionParameter oracleNamedFunctionParameter) {

<S> T visit(AllColumns allColumns, S context);

<S> T visit(FunctionAllColumns functionColumns, S context);

default void visit(AllColumns allColumns) {
this.visit(allColumns, null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import net.sf.jsqlparser.statement.piped.FromQuery;
import net.sf.jsqlparser.statement.select.AllColumns;
import net.sf.jsqlparser.statement.select.AllTableColumns;
import net.sf.jsqlparser.statement.select.FunctionAllColumns;
import net.sf.jsqlparser.statement.select.OrderByElement;
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
import net.sf.jsqlparser.statement.select.Pivot;
Expand Down Expand Up @@ -599,6 +600,11 @@ public <S> T visit(AllTableColumns allTableColumns, S context) {
return visitExpression(allTableColumns, context);
}

@Override
public <S> T visit(FunctionAllColumns functionAllColumns, S context) {
return visitExpression(functionAllColumns, context);
}

@Override
public <S> T visit(AllValue allValue, S context) {
return visitExpression(allValue, context);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2025 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/
package net.sf.jsqlparser.statement.select;

import net.sf.jsqlparser.expression.ExpressionVisitor;
import net.sf.jsqlparser.expression.Function;


public class FunctionAllColumns extends AllColumns {
private Function function;

public FunctionAllColumns(Function function) {
super(null, null, null);
this.function = function;
}

public Function getFunction() {
return function;
}

public FunctionAllColumns setFunction(Function function) {
this.function = function;
return this;
}

public StringBuilder appendTo(StringBuilder builder) {
builder.append("(");
builder.append(function);
builder.append(").*");
return builder;
}

@Override
public String toString() {
return appendTo(new StringBuilder()).toString();
}

@Override
public <T, S> T accept(ExpressionVisitor<T> expressionVisitor, S context) {
return expressionVisitor.visit(this, context);
}
}
7 changes: 7 additions & 0 deletions src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@
import net.sf.jsqlparser.statement.select.AllColumns;
import net.sf.jsqlparser.statement.select.AllTableColumns;
import net.sf.jsqlparser.statement.select.FromItemVisitor;
import net.sf.jsqlparser.statement.select.FunctionAllColumns;
import net.sf.jsqlparser.statement.select.Join;
import net.sf.jsqlparser.statement.select.LateralSubSelect;
import net.sf.jsqlparser.statement.select.OrderByElement;
Expand Down Expand Up @@ -948,6 +949,12 @@ public <S> Void visit(AllTableColumns allTableColumns, S context) {
return null;
}

@Override
public <S> Void visit(FunctionAllColumns functionAllColumns, S context) {

return null;
}

@Override
public <S> Void visit(AllValue allValue, S context) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
import net.sf.jsqlparser.statement.piped.FromQuery;
import net.sf.jsqlparser.statement.select.AllColumns;
import net.sf.jsqlparser.statement.select.AllTableColumns;
import net.sf.jsqlparser.statement.select.FunctionAllColumns;
import net.sf.jsqlparser.statement.select.OrderByElement;
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
import net.sf.jsqlparser.statement.select.Select;
Expand Down Expand Up @@ -1652,6 +1653,12 @@ public <S> StringBuilder visit(AllTableColumns allTableColumns, S context) {
return builder;
}

@Override
public <S> StringBuilder visit(FunctionAllColumns functionAllColumns, S context) {
builder.append(functionAllColumns.toString());
return builder;
}

@Override
public <S> StringBuilder visit(AllValue allValue, S context) {
builder.append(allValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
import net.sf.jsqlparser.statement.piped.FromQuery;
import net.sf.jsqlparser.statement.select.AllColumns;
import net.sf.jsqlparser.statement.select.AllTableColumns;
import net.sf.jsqlparser.statement.select.FunctionAllColumns;
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
Expand Down Expand Up @@ -1060,6 +1061,11 @@ public <S> Void visit(AllTableColumns allTableColumns, S context) {
return null;
}

@Override
public <S> Void visit(FunctionAllColumns functionColumns, S context) {
return null;
}

@Override
public <S> Void visit(AllValue allValue, S context) {
return null;
Expand Down
12 changes: 12 additions & 0 deletions src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -3273,6 +3273,16 @@ List<SelectItem<?>> SelectItemsList():
{ return selectItemsList; }
}

FunctionAllColumns FunctionAllColumns() #FunctionAllColumns:
{
Function function;
}
{
"(" ( "(" )* function=Function() ")" ( ")" )* "." "*"
{
return new FunctionAllColumns(function);
}
}

SelectItem<?> SelectItem() #SelectItem:
{
Expand Down Expand Up @@ -5332,6 +5342,8 @@ Expression PrimaryExpression() #PrimaryExpression:

| LOOKAHEAD(AllTableColumns()) retval=AllTableColumns()

| LOOKAHEAD(FunctionAllColumns()) retval=FunctionAllColumns()

// support timestamp expressions
| LOOKAHEAD(2, {!interrupted}) (token=<K_TIME_KEY_EXPR> | token=<K_CURRENT>) { retval = new TimeKeyExpression(token.image); }

Expand Down
37 changes: 37 additions & 0 deletions src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6173,4 +6173,41 @@ public void testSelectWithSkylineKeywords() throws JSQLParserException {
select.getPlainSelect().getSelectItems().toString());
}

@Test
public void testSelectAllColumnsFromFunctionReturn() throws JSQLParserException {
String sql = "SELECT (pg_stat_file('postgresql.conf')).*";
Statement statement = CCJSqlParserUtil.parse(sql);
assertNotNull(statement);
assertTrue(statement instanceof Select);

// Ensure the function is recognized correctly
Select select = (Select) statement;
PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
assertNotNull(plainSelect);
assertEquals(1, plainSelect.getSelectItems().size());
assertTrue(plainSelect.getSelectItems().get(0)
.getExpression() instanceof FunctionAllColumns);
assertEquals("(pg_stat_file('postgresql.conf')).*",
plainSelect.getSelectItems().get(0).toString());
}

@Test
public void testSelectAllColumnsFromFunctionReturnWithMultipleParentheses()
throws JSQLParserException {
String sql = "SELECT ( ( ( pg_stat_file('postgresql.conf') ) )) . *";
Statement statement = CCJSqlParserUtil.parse(sql);
assertNotNull(statement);
assertTrue(statement instanceof Select);

// Ensure the function is recognized correctly
Select select = (Select) statement;
PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
assertNotNull(plainSelect);
assertEquals(1, plainSelect.getSelectItems().size());
assertTrue(plainSelect.getSelectItems().get(0)
.getExpression() instanceof FunctionAllColumns);
assertEquals("(pg_stat_file('postgresql.conf')).*",
plainSelect.getSelectItems().get(0).toString());
}

}
Loading