io.odysz.transact.sql.parts.insert.ValueList Maven / Gradle / Ivy
package io.odysz.transact.sql.parts.insert;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
import io.odysz.semantics.ISemantext;
import io.odysz.transact.sql.parts.AbsPart;
import io.odysz.transact.x.TransException;
/**Support value list in update set value elem and insert values list:
* value can only be:
* subquery,
* expression,
* function_call: method_name '(' expression_list ')'
* reference:
*
https://github.com/antlr/grammars-v4/blob/master/tsql/TSqlParser.g4
// https://msdn.microsoft.com/en-us/library/ms174335.aspx
insert_statement
: with_expression?
INSERT (TOP '(' expression ')' PERCENT?)?
INTO? (ddl_object | rowset_function_limited)
insert_with_table_hints?
('(' column_name_list ')')?
output_clause?
insert_statement_value
for_clause? option_clause? ';'?
;
insert_statement_value
: table_value_constructor
| derived_table
| execute_statement
| DEFAULT VALUES
;
table_value_constructor
: VALUES '(' expression_list ')' (',' '(' expression_list ')')*
;
expression_list
: expression (',' expression)*
;
derived_table
: subquery
| '(' subquery ')'
| table_value_constructor
| '(' table_value_constructor ')'
;
// https://msdn.microsoft.com/en-us/library/ms177523.aspx
update_statement
: with_expression?
UPDATE (TOP '(' expression ')' PERCENT?)?
(ddl_object | rowset_function_limited)
with_table_hints?
SET update_elem (',' update_elem)*
output_clause?
(FROM table_sources)?
(WHERE (search_condition_list | CURRENT OF (GLOBAL? cursor_name | cursor_var=LOCAL_ID)))?
for_clause? option_clause? ';'?
;
update_elem
: (full_column_name | LOCAL_ID) ('=' | assignment_operator) expression
| udt_column_name=id '.' method_name=id '(' expression_list ')'
//| full_column_name '.' WRITE (expression, )
;
*
* @author [email protected]
*/
public class ValueList extends AbsPart {
protected ArrayList valst;
protected AbsPart[] valsArr;
/** This is also the flag of multi-row values */
private boolean valsArrIsnull;
/** values (one row) has beginning and ending parentheses. */
boolean withParens = true;
public ValueList withParentheses(boolean with) {
withParens = with;
return this;
}
public ValueList(int size) {
if (size > 0)
valsArr = new AbsPart[size];
valsArrIsnull = true;
}
public ValueList v(int idx, AbsPart v) throws TransException {
if (idx < 0 || v == null)
return this;
if (valst != null)
throw new TransException("Don't use both list and array mode in ValueList.");
// valsArr[idx] = new ExprPart("'" + v + "'");
valsArr[idx] = v;
valsArrIsnull = false;
return this;
}
/**Add value to the last column.
* @param v
* @return this
* @throws TransException
*/
public ValueList v(AbsPart v) throws TransException {
if (valsArr != null)
throw new TransException("Don't use both list and array mode in ValueList.");
if (valst == null)
valst = new ArrayList();
valst.add(v);
return this;
}
@Override
public String sql(ISemantext context) {
if (valst == null && valsArrIsnull) return "null";
else if (valst != null)
return valst.stream().map(v -> {
try {
return v == null ? "null" : v.sql(context);
} catch (TransException e) {
e.printStackTrace();
return "";
}
}).collect(Collectors.joining(", "));
else
return Arrays.stream(valsArr).map(v -> {
try {
return v == null ? "null" : v.sql(context);
} catch (TransException e) {
e.printStackTrace();
return null;
}
}).collect(Collectors.joining(", ", withParens ? "(" : "", withParens ? ")" : ""));
}
}