15 using impedance::matched;
 
   17 shared_ptr<value_expr> value_expr::factory(
prod *p, 
sqltype *type_constraint)
 
   20     if (1 == d20() && p->
level < d6() && window_function::allowed(p))
 
   21       return make_shared<window_function>(p, type_constraint);
 
   22     else if (1 == d42() && p->
level < d6())
 
   23       return make_shared<coalesce>(p, type_constraint);
 
   24     else if (1 == d42() && p->
level < d6())
 
   25       return make_shared<nullif>(p, type_constraint);
 
   26     else if (p->
level < d6() && d6() == 1)
 
   27       return make_shared<funcall>(p, type_constraint);
 
   29       return make_shared<atomic_subselect>(p, type_constraint);
 
   30     else if (p->
level< d6() && d9()==1)
 
   31       return make_shared<case_expr>(p, type_constraint);
 
   32     else if (p->
scope->
refs.size() && d20() > 1)
 
   33       return make_shared<column_reference>(p, type_constraint);
 
   35       return make_shared<const_expr>(p, type_constraint);
 
   36   } 
catch (runtime_error &e) {
 
   39   return factory(p, type_constraint);
 
   42 case_expr::case_expr(
prod *p, 
sqltype *type_constraint)
 
   45   condition = bool_expr::factory(
this);
 
   46   true_expr = value_expr::factory(
this, type_constraint);
 
   47   false_expr = value_expr::factory(
this, true_expr->type);
 
   49   if(false_expr->type != true_expr->type) {
 
   52        if (true_expr->type->consistent(false_expr->type))
 
   53             true_expr = value_expr::factory(
this, false_expr->type);
 
   55             false_expr = value_expr::factory(
this, true_expr->type);
 
   57   type = true_expr->type;
 
   62   out << 
"case when " << *condition;
 
   63   out << 
" then " << *true_expr;
 
   64   out << 
" else " << *true_expr;
 
   74   false_expr->accept(v);
 
   79   if (type_constraint) {
 
   80     auto pairs = 
scope->refs_of_type(type_constraint);
 
   81     auto picked = random_pick(pairs);
 
   82     reference += picked.first->ident()
 
   83       + 
"." + picked.second.name;
 
   84     type = picked.second.type;
 
   89     reference += r->ident() + 
".";
 
   90     column &c = random_pick(r->columns());
 
   96 shared_ptr<bool_expr> bool_expr::factory(
prod *p)
 
   99        if (p->
level > d100())
 
  100             return make_shared<truth_value>(p);
 
  102             return make_shared<comparison_op>(p);
 
  104             return make_shared<bool_term>(p);
 
  106             return make_shared<null_predicate>(p);
 
  108             return make_shared<truth_value>(p);
 
  110             return make_shared<exists_predicate>(p);
 
  112   } 
catch (runtime_error &e) {
 
  121   subquery = make_shared<query_spec>(
this, 
scope);
 
  134   out << *subquery << 
")";
 
  139   lhs = make_shared<column_reference>(
this);
 
  140   rhs = make_shared<column_reference>(
this, lhs->type);
 
  145   auto &idx = p->
scope->schema->operators_returning_type;
 
  147   auto iters = idx.equal_range(
scope->schema->booltype);
 
  148   oper = random_pick<>(iters)->second;
 
  150   lhs = value_expr::factory(
this, oper->left);
 
  151   rhs = value_expr::factory(
this, oper->right);
 
  153   if (oper->left == oper->right
 
  154          && lhs->type != rhs->type) {
 
  156     if (lhs->type->consistent(rhs->type))
 
  157       lhs = value_expr::factory(
this, rhs->type);
 
  159       rhs = value_expr::factory(
this, lhs->type);
 
  163 coalesce::coalesce(
prod *p, 
sqltype *type_constraint, 
const char *abbrev)
 
  166   auto first_expr = value_expr::factory(
this, type_constraint);
 
  167   auto second_expr = value_expr::factory(
this, first_expr->type);
 
  170   while(first_expr->type != second_expr->type) {
 
  172     if (first_expr->type->consistent(second_expr->type))
 
  173       first_expr = value_expr::factory(
this, second_expr->type);
 
  175       second_expr = value_expr::factory(
this, first_expr->type);
 
  177   type = second_expr->type;
 
  179   value_exprs.push_back(first_expr);
 
  180   value_exprs.push_back(second_expr);
 
  185   out << 
"cast(" << abbrev_ << 
"(";
 
  186   for (
auto expr = value_exprs.begin(); expr != value_exprs.end(); expr++) {
 
  188     if (expr+1 != value_exprs.end())
 
  192   out << 
" as " << type->name << 
")";
 
  195 const_expr::const_expr(
prod *p, 
sqltype *type_constraint)
 
  198   type = type_constraint ? type_constraint : 
scope->schema->inttype;
 
  200   if (type == 
scope->schema->inttype)
 
  201     expr = to_string(d100());
 
  202   else if (type == 
scope->schema->booltype)
 
  203     expr += (d6() > 3) ? 
scope->schema->true_literal : 
scope->schema->false_literal;
 
  204   else if (
dynamic_cast<insert_stmt*
>(p) && (d6() > 3))
 
  207     expr += 
"cast(null as " + type->name + 
")";
 
  210 funcall::funcall(
prod *p, 
sqltype *type_constraint, 
bool agg)
 
  213   if (type_constraint == 
scope->schema->internaltype)
 
  214     fail(
"cannot call functions involving internal type");
 
  216   auto &idx = agg ? p->
scope->schema->aggregates_returning_type
 
  218     p->
scope->schema->routines_returning_type
 
  219     : p->
scope->schema->parameterless_routines_returning_type;
 
  223   if (!type_constraint) {
 
  224     proc = random_pick(idx.begin(), idx.end())->second;
 
  226     auto iters = idx.equal_range(type_constraint);
 
  227     proc = random_pick<>(iters)->second;
 
  228     if (proc && !type_constraint->
consistent(proc->restype)) {
 
  240     type = type_constraint;
 
  242     type = proc->restype;
 
  244   if (type == 
scope->schema->internaltype) {
 
  249   for (
auto type : proc->argtypes)
 
  250     if (type == 
scope->schema->internaltype
 
  251         || type == 
scope->schema->arraytype) {
 
  256   for (
auto argtype : proc->argtypes) {
 
  258     auto expr = value_expr::factory(
this, argtype);
 
  259     parms.push_back(expr);
 
  265   out << proc->ident() << 
"(";
 
  266   for (
auto expr = parms.begin(); expr != parms.end(); expr++) {
 
  268     out << 
"cast(" << **expr << 
" as " << (*expr)->type->name << 
")";
 
  269     if (expr+1 != parms.end())
 
  273   if (is_aggregate && (parms.begin() == parms.end()))
 
  278 atomic_subselect::atomic_subselect(
prod *p, 
sqltype *type_constraint)
 
  279   : 
value_expr(p), offset((d6() == 6) ? d100() : d6())
 
  283     if (type_constraint) {
 
  284       auto idx = 
scope->schema->aggregates_returning_type;
 
  285       auto iters = idx.equal_range(type_constraint);
 
  286       agg = random_pick<>(iters)->second;
 
  288       agg = &random_pick<>(
scope->schema->aggregates);
 
  290     if (agg->argtypes.size() != 1)
 
  293       type_constraint = agg->argtypes[0];
 
  298   if (type_constraint) {
 
  299     auto idx = 
scope->schema->tables_with_columns_of_type;
 
  301     auto iters = idx.equal_range(type_constraint);
 
  302     tab = random_pick<>(iters)->second;
 
  304     for (
auto &cand : tab->columns()) {
 
  312     tab = &random_pick<>(
scope->schema->tables);
 
  313     col = &random_pick<>(tab->columns());
 
  316   type = agg ? agg->restype : col->type;
 
  324     out << agg->ident() << 
"(" << col->name << 
")";
 
  328   out << 
" from " << tab->ident();
 
  331     out << 
" limit 1 offset " << offset;
 
  340   out << *aggregate << 
" over (partition by ";
 
  342   for (
auto ref = partition_by.begin(); ref != partition_by.end(); ref++) {
 
  344     if (ref+1 != partition_by.end())
 
  350   for (
auto ref = order_by.begin(); ref != order_by.end(); ref++) {
 
  352     if (ref+1 != order_by.end())
 
  359 window_function::window_function(
prod *p, 
sqltype *type_constraint)
 
  363   aggregate = make_shared<funcall>(
this, type_constraint, 
true);
 
  364   type = aggregate->type;
 
  365   partition_by.push_back(make_shared<column_reference>(
this));
 
  367     partition_by.push_back(make_shared<column_reference>(
this));
 
  369   order_by.push_back(make_shared<column_reference>(
this));
 
  371     order_by.push_back(make_shared<column_reference>(
this));
 
  374 bool window_function::allowed(
prod *p)
 
  381     return allowed(p->
pprod);
 
grammar: Value expression productions
 
grammar: Top-level and unsorted grammar productions
 
feedback to the grammar about failed productions
 
supporting classes for the grammar
 
Base class providing schema information to grammar.
 
virtual void out(std::ostream &out)
Emit SQL for this production.
 
virtual void out(std::ostream &out)
Emit SQL for this production.
 
virtual void accept(prod_visitor *v)
Visitor pattern for walking the AST.
 
virtual void out(std::ostream &out)
Emit SQL for this production.
 
virtual void out(std::ostream &out)
Emit SQL for this production.
 
virtual void accept(prod_visitor *v)
Visitor pattern for walking the AST.
 
virtual void out(std::ostream &out)
Emit SQL for this production.
 
Base class for walking the AST.
 
Base class for AST nodes.
 
virtual void indent(std::ostream &out)
Newline and indent according to tree level.
 
void retry()
Increase the retry count and throw an exception when retry_limit is exceeded.
 
struct scope * scope
Scope object to model column/table reference visibility.
 
long retry_limit
Maximum number of retries allowed before reporting a failure to the Parent prod.
 
int level
Level of this production in the AST. 0 for root node.
 
struct prod * pprod
Parent production that instanciated this one.
 
virtual void fail(const char *reason)
Report a "failed to generate" error.
 
virtual void match()
Check with the impedance matching code whether this production has been blacklisted and throw an exce...
 
vector< named_relation * > refs
available to column_ref productions
 
virtual bool consistent(struct sqltype *rvalue)
This function is used to model postgres-style pseudotypes.
 
virtual void out(std::ostream &out)
Emit SQL for this production.